Python调用CANoe(1)(启动与停止,变量和信号读写)


📘前言

📗 引入库

导入 win32库,这个库是实现COM编程的:

ipip install pywin32

📗 打开关闭CANoe

  • 1️⃣ 首先我们先随便打开一个CANoe 工程,我这里打开的是一个Demo工程:

在这里插入图片描述


  • 2️⃣ 我们引入win32com 库 编写相关代码,创建一个类,名字就叫做CANoe ,并写了一个 init()函数,在这个函数中,我们就简单实现了两件事,一是打开CANoe软件,二十打印CANoe的软件版本。
# Standard library imports
import os
import sys
from win32com.client import *
from win32com.client.connect import *
# Vector Canoe Class
class CANoe:
    def __init__(self):
        self.application = None
        self.application = DispatchEx("CANoe.Application")
        self.ver = self.application.Version
        print('Loaded CANoe version ',
            self.ver.major, '.',
            self.ver.minor, '.',
            self.ver.Build, '...')#, sep,''
        self.Measurement = self.application.Measurement.Running
        
app = CANoe() #实例化对象

  • 3️⃣ 我们把上面打开的CANoe工程关闭,然后 实例化类 app = CANoe() ,运行看下结果:
    结果是CANoe再次打开了上面我们打开的CANoe工程,而且打印出来打开的CANoe的软件版本。

Loaded CANoe version 11 . 0 . 55 …

Process finished with exit code 0

📗 打开指定的cfg 文件

  • 4️⃣ 为了区别,我另存为了一个cfg文件,bmw2.cfg
    在这里插入图片描述

  • 5️⃣ 创建两个function,一个打开cfg,一个关闭cfg:
# coding: utf-8
"""API for setup/usage of Canoe COM Client interface.
"""
# --------------------------------------------------------------------------
# Standard library imports
import os
import sys
import time
from win32com.client import *
from win32com.client.connect import *

# Vector Canoe Class
class CANoe:
    def __init__(self):
        self.application = None
        self.application = DispatchEx("CANoe.Application")
        self.ver = self.application.Version
        print('Loaded CANoe version ',
            self.ver.major, '.',
            self.ver.minor, '.',
            self.ver.Build, '...')#, sep,''
        self.Measurement = self.application.Measurement.Running

    def open_cfg(self, cfgname):
        # open CANoe simulation
        if (self.application != None):
            # check for valid file and it is *.cfg file
            if os.path.isfile(cfgname) and (os.path.splitext(cfgname)[1] == ".cfg"):
                self.application.Open(cfgname)
                print("opening..."+cfgname)
            else:
                raise RuntimeError("Can't find CANoe cfg file")
        else:
            raise RuntimeError("CANoe Application is missing,unable to open simulation")

    def close_cfg(self):
        if (self.application != None):
            # self.stop_Measurement()
            self.application.Quit()
        	self.application = None


app = CANoe() #定义CANoe为app
app.open_cfg(r"C:/Users/Desktop/BMW/bmw2.cfg") #导入某个CANoe congif
time.sleep(2)
app.close_cfg()


  • 6️⃣ 执行脚本之后,我们会发现CANoe软件被打开,并且加载了bmw2.cfg,等待两秒之后,CANoe软件被关闭。

📗 RUN

  • 7️⃣ 在上面的两个步骤之后,我们就应该Run起来我们的工程了。
    在上面的代码基础上,我们再次添加了两个function.一个是开始Run start_Measurement ,一个是停止run stop_Measurement
# coding: utf-8
"""API for setup/usage of Canoe COM Client interface.
"""
# --------------------------------------------------------------------------
# Standard library imports
import os
import sys
import subprocess
import time
from win32com.client import *
from win32com.client.connect import *

# Vector Canoe Class
class CANoe:
    def __init__(self):
        self.application = None
        self.application = DispatchEx("CANoe.Application")
        self.ver = self.application.Version
        print('Loaded CANoe version ',
            self.ver.major, '.',
            self.ver.minor, '.',
            self.ver.Build, '...')#, sep,''

        self.Measurement = self.application.Measurement.Running

    def open_cfg(self, cfgname):
        # open CANoe simulation
        if (self.application != None):
            # check for valid file and it is *.cfg file
            if os.path.isfile(cfgname) and (os.path.splitext(cfgname)[1] == ".cfg"):
                self.application.Open(cfgname)
                print("opening..."+cfgname)
            else:
                raise RuntimeError("Can't find CANoe cfg file")
        else:
            raise RuntimeError("CANoe Application is missing,unable to open simulation")

    def close_cfg(self):
        # close CANoe simulation
        if (self.application != None):
            print("close cfg ...")
            # self.stop_Measurement()
            self.application.Quit()
            self.application = None
    def start_Measurement(self):
        retry = 0
        retry_counter = 5
        # try to establish measurement within 5s timeout
        while not self.application.Measurement.Running and (retry < retry_counter):
            self.application.Measurement.Start()
            time.sleep(1)
            retry += 1
        if (retry == retry_counter):
            raise RuntimeWarning("CANoe start measuremet failed, Please Check Connection!")
    def stop_Measurement(self):
        if self.application.Measurement.Running:
            self.application.Measurement.Stop()
        else:
            pass
app = CANoe() #定义CANoe为app
app.open_cfg(r"C:/Users/Desktop/BMW/bmw2.cfg") #导入某个CANoe congif
time.sleep(5)
app.start_Measurement()

📗 数据交互——读写信号

  • 8️⃣ 在上面的步骤中,我们已经能够打开响应的cfg工程,并且能够RUN起来,接下开我们实现读写CANoe中的信号
    在下面代码中,我新建了两个function:

  • get_SigVal() :获取指定的信号,返回值

  • DoEvents():纯粹为了堵塞进程

# coding: utf-8
"""API for setup/usage of Canoe COM Client interface.
"""
# --------------------------------------------------------------------------
# Standard library imports
import os
import sys
import subprocess
import time
import msvcrt
from win32com.client import *
from win32com.client.connect import *

# Vector Canoe Class
class CANoe:
    def __init__(self):
        self.application = None
        self.application = DispatchEx("CANoe.Application")
        self.ver = self.application.Version
        print('Loaded CANoe version ',
            self.ver.major, '.',
            self.ver.minor, '.',
            self.ver.Build, '...')#, sep,''

        self.Measurement = self.application.Measurement.Running

    def open_cfg(self, cfgname):
        # open CANoe simulation
        if (self.application != None):
            # check for valid file and it is *.cfg file
            if os.path.isfile(cfgname) and (os.path.splitext(cfgname)[1] == ".cfg"):
                self.application.Open(cfgname)
                print("opening..."+cfgname)
            else:
                raise RuntimeError("Can't find CANoe cfg file")
        else:
            raise RuntimeError("CANoe Application is missing,unable to open simulation")

    def close_cfg(self):
        # close CANoe simulation
        if (self.application != None):
            print("close cfg ...")
            # self.stop_Measurement()
            self.application.Quit()
            self.application = None
    def start_Measurement(self):
        retry = 0
        retry_counter = 5
        # try to establish measurement within 5s timeout
        while not self.application.Measurement.Running and (retry < retry_counter):
            self.application.Measurement.Start()
            time.sleep(1)
            retry += 1
        if (retry == retry_counter):
            raise RuntimeWarning("CANoe start measuremet failed, Please Check Connection!")

    def stop_Measurement(self):
        if self.application.Measurement.Running:
            self.application.Measurement.Stop()
        else:
            pass
    def get_SigVal(self, channel_num, msg_name, sig_name, bus_type="CAN"):
        """
        @summary Get the value of a raw CAN signal on the CAN simulation bus
        @param channel_num - Integer value to indicate from which channel we will read the signal, usually start from 1,
                             Check with CANoe can channel setup.
        @param msg_name - String value that indicate the message name to which the signal belong. Check DBC setup.
        @param sig_name - String value of the signal to be read
        @param bus_type - String value of the bus type - e.g. "CAN", "LIN" and etc.
        @return The CAN signal value in floating point value.
                Even if the signal is of integer type, we will still return by
                floating point value.
        @exception None
        """
        if (self.application != None):
            result = self.application.GetBus(bus_type).GetSignal(channel_num, msg_name, sig_name)
            return result.Value
        else:
            raise RuntimeError("CANoe is not open,unable to GetVariable")
   def set_SigVal(self, channel_num, msg_name, sig_name, bus_type,setValue):
        if (self.application != None):
            result = self.application.GetBus(bus_type).GetSignal(channel_num, msg_name, sig_name)
            result.Value = setValue
        else:
            raise RuntimeError("CANoe is not open,unable to GetVariable")
    def DoEvents(self):
        pythoncom.PumpWaitingMessages()
        time.sleep(1)

app = CANoe() #定义CANoe为app
app.open_cfg(r"C:/Users/Desktop/BMW/bmw2.cfg") #导入某个CANoe congif
time.sleep(5)
app.start_Measurement()

while not msvcrt.kbhit():
    EngineSpeed = app.get_SigVal(channel_num=1, msg_name="EngineState", sig_name="EngineSpeed", bus_type="CAN")
    print(EngineSpeed)
    app.DoEvents()

  • 9️⃣ 执行上面的代码可以得到下面的输入结果:

在这里插入图片描述


- 🔟 如何设置信号呢 ;通过set_SigVal 可以设置signal.
while not msvcrt.kbhit():
    EngineSpeed = app.get_SigVal(channel_num=1, msg_name="EngineState", sig_name="EngineSpeed", bus_type="CAN")
    print(EngineSpeed)
   app.set_SigVal(channel_num=1, msg_name="EngineState", sig_name="EngineSpeed", bus_type="CAN", setValue=1)
    app.DoEvents()

📗 数据交互——读写环境变量

  • 1️⃣ 新建了两个function:

  • get_EnvVar() :获取指定的环境变量,返回值

  • set_EnvVar():设置指定的环境变量值。

# coding: utf-8
"""API for setup/usage of Canoe COM Client interface.
"""
# --------------------------------------------------------------------------
# Standard library imports
import os
import sys
import subprocess
import time
import msvcrt
from win32com.client import *
from win32com.client.connect import *

# Vector Canoe Class
class CANoe:
    def __init__(self):
        self.application = None
        self.application = DispatchEx("CANoe.Application")
        self.ver = self.application.Version
        print('Loaded CANoe version ',
            self.ver.major, '.',
            self.ver.minor, '.',
            self.ver.Build, '...')#, sep,''

        self.Measurement = self.application.Measurement.Running

    def open_cfg(self, cfgname):
        # open CANoe simulation
        if (self.application != None):
            # check for valid file and it is *.cfg file
            if os.path.isfile(cfgname) and (os.path.splitext(cfgname)[1] == ".cfg"):
                self.application.Open(cfgname)
                print("opening..."+cfgname)
            else:
                raise RuntimeError("Can't find CANoe cfg file")
        else:
            raise RuntimeError("CANoe Application is missing,unable to open simulation")

    def close_cfg(self):
        # close CANoe simulation
        if (self.application != None):
            print("close cfg ...")
            # self.stop_Measurement()
            self.application.Quit()
            self.application = None
    def start_Measurement(self):
        retry = 0
        retry_counter = 5
        # try to establish measurement within 5s timeout
        while not self.application.Measurement.Running and (retry < retry_counter):
            self.application.Measurement.Start()
            time.sleep(1)
            retry += 1
        if (retry == retry_counter):
            raise RuntimeWarning("CANoe start measuremet failed, Please Check Connection!")

    def stop_Measurement(self):
        if self.application.Measurement.Running:
            self.application.Measurement.Stop()
        else:
            pass
    def get_SigVal(self, channel_num, msg_name, sig_name, bus_type="CAN"):
        """
        @summary Get the value of a raw CAN signal on the CAN simulation bus
        @param channel_num - Integer value to indicate from which channel we will read the signal, usually start from 1,
                             Check with CANoe can channel setup.
        @param msg_name - String value that indicate the message name to which the signal belong. Check DBC setup.
        @param sig_name - String value of the signal to be read
        @param bus_type - String value of the bus type - e.g. "CAN", "LIN" and etc.
        @return The CAN signal value in floating point value.
                Even if the signal is of integer type, we will still return by
                floating point value.
        @exception None
        """
        if (self.application != None):
            result = self.application.GetBus(bus_type).GetSignal(channel_num, msg_name, sig_name)
            return result.Value
        else:
            raise RuntimeError("CANoe is not open,unable to GetVariable")
    def get_EnvVar(self, var):
        if (self.application != None):
            result = self.application.Environment.GetVariable(var)
            return result.Value
        else:
            raise RuntimeError("CANoe is not open,unable to GetVariable")

    def set_EnvVar(self, var, value):
        result = None
        if (self.application != None):
            # set the environment varible
            result = self.application.Environment.GetVariable(var)
            result.Value = value
            checker = self.get_EnvVar(var)
            # check the environment varible is set properly?
            while (checker != value):
                checker = self.get_EnvVar(var)
        else:
            raise RuntimeError("CANoe is not open,unable to SetVariable")
    def DoEvents(self):
        pythoncom.PumpWaitingMessages()
        time.sleep(1)

app = CANoe() #定义CANoe为app
app.open_cfg(r"C:/Users/Desktop/BMW/bmw2.cfg") #导入某个CANoe congif
time.sleep(5)
app.start_Measurement()

while not msvcrt.kbhit():
    bmw_test = app.get_EnvVar("en_bmw_test")
    print(bmw_test)
    if(bmw_test==2):
        app.set_EnvVar("en_bmw_test",10)

    app.DoEvents()

  • 2️⃣ while 循环中我们先读取环境变量en_bmw_test的值,如果这个值等于2,则我们把它设置成10。
    我们先在CANoe中的Data的面板中设置环境变量en_bmw_test = 1 ,pythonz中读到的是1,然后设置成2,读到了2,紧接着可以看到变量编程了10。

📗 数据交互——读写系统变量

  • 1️⃣ CANoe工程中有定义的系统变量如下图,我们就以读写 Engine::EngineSpeedDspMeter为例。

在这里插入图片描述


  • 2️⃣新建了两个function:

  • get_SysVar() :获取指定的系统变量,返回值

  • set_SysVar():设置指定的系统变量值。

# coding: utf-8
"""API for setup/usage of Canoe COM Client interface.
"""
# --------------------------------------------------------------------------
# Standard library imports
import os
import sys
import subprocess
import time
import msvcrt
from win32com.client import *
from win32com.client.connect import *

# Vector Canoe Class
class CANoe:
    def __init__(self):
        self.application = None
        self.application = DispatchEx("CANoe.Application")
        self.ver = self.application.Version
        print('Loaded CANoe version ',
            self.ver.major, '.',
            self.ver.minor, '.',
            self.ver.Build, '...')#, sep,''

        self.Measurement = self.application.Measurement.Running

    def open_cfg(self, cfgname):
        # open CANoe simulation
        if (self.application != None):
            # check for valid file and it is *.cfg file
            if os.path.isfile(cfgname) and (os.path.splitext(cfgname)[1] == ".cfg"):
                self.application.Open(cfgname)
                print("opening..."+cfgname)
            else:
                raise RuntimeError("Can't find CANoe cfg file")
        else:
            raise RuntimeError("CANoe Application is missing,unable to open simulation")

    def close_cfg(self):
        # close CANoe simulation
        if (self.application != None):
            print("close cfg ...")
            # self.stop_Measurement()
            self.application.Quit()
            self.application = None
    def start_Measurement(self):
        retry = 0
        retry_counter = 5
        # try to establish measurement within 5s timeout
        while not self.application.Measurement.Running and (retry < retry_counter):
            self.application.Measurement.Start()
            time.sleep(1)
            retry += 1
        if (retry == retry_counter):
            raise RuntimeWarning("CANoe start measuremet failed, Please Check Connection!")

    def stop_Measurement(self):
        if self.application.Measurement.Running:
            self.application.Measurement.Stop()
        else:
            pass
    def get_SigVal(self, channel_num, msg_name, sig_name, bus_type="CAN"):
        """
        @summary Get the value of a raw CAN signal on the CAN simulation bus
        @param channel_num - Integer value to indicate from which channel we will read the signal, usually start from 1,
                             Check with CANoe can channel setup.
        @param msg_name - String value that indicate the message name to which the signal belong. Check DBC setup.
        @param sig_name - String value of the signal to be read
        @param bus_type - String value of the bus type - e.g. "CAN", "LIN" and etc.
        @return The CAN signal value in floating point value.
                Even if the signal is of integer type, we will still return by
                floating point value.
        @exception None
        """
        if (self.application != None):
            result = self.application.GetBus(bus_type).GetSignal(channel_num, msg_name, sig_name)
            return result.Value
        else:
            raise RuntimeError("CANoe is not open,unable to GetVariable")
    def get_EnvVar(self, var):
        if (self.application != None):
            result = self.application.Environment.GetVariable(var)
            return result.Value
        else:
            raise RuntimeError("CANoe is not open,unable to GetVariable")

    def set_EnvVar(self, var, value):
        result = None
        if (self.application != None):
            # set the environment varible
            result = self.application.Environment.GetVariable(var)
            result.Value = value
            checker = self.get_EnvVar(var)
            # check the environment varible is set properly?
            while (checker != value):
                checker = self.get_EnvVar(var)
        else:
            raise RuntimeError("CANoe is not open,unable to SetVariable")

    def get_SysVar(self, ns_name, sysvar_name):
        if (self.application != None):
            systemCAN = self.application.System.Namespaces
            sys_namespace = systemCAN(ns_name)
            sys_value = sys_namespace.Variables(sysvar_name)
            return sys_value.Value
        else:
            raise RuntimeError("CANoe is not open,unable to GetVariable")

    def set_SysVar(self, ns_name, sysvar_name, var):
        if (self.application != None):
            systemCAN = self.application.System.Namespaces
            sys_namespace = systemCAN(ns_name)
            sys_value = sys_namespace.Variables(sysvar_name)
            sys_value.Value = var
        else:
            raise RuntimeError("CANoe is not open,unable to GetVariable")
    def DoEvents(self):
        pythoncom.PumpWaitingMessages()
        time.sleep(1)

app = CANoe() #定义CANoe为app
app.open_cfg(r"C:/Users/Desktop/BMW/bmw2.cfg") #导入某个CANoe congif
time.sleep(5)
app.start_Measurement()

while not msvcrt.kbhit():
    EngineSpeedDspMeter = app.get_SysVar("Engine","EngineSpeedDspMeter")
    print(EngineSpeedDspMeter)
    if(EngineSpeedDspMeter==2):
        #app.set_SysVar("Engine","EngineSpeedDspMeter",3)  #这里曾将出现问题许久没解决
        app.set_SysVar("Engine","EngineSpeedDspMeter",3.0)
    app.DoEvents()

  • 3️⃣运行结果,根据下图可以看出 get_SysVar 是没问题的,可以正常得到环境变量的值,但是在设置环境变量的时候,报了如下的错误,我看了Vector的 VB代码,是允许设置系统变量的值的,但是我没有去执行测试,这个问题暂时先搁置,后面有缘再解决吧。

这个问题解决了@2021/12/10 因为我看评论区大家对这个问题很感兴趣额,然后,我就再花些时间琢磨下这个问题出在哪里。 把
app.set_SysVar(“Engine”,“EngineSpeedDspMeter”,3) 中的 数值改成 浮点数就行了, 改成3.0
为什么呢?因为我们的系统变量定义的就是浮点型,这一点在开始写这个博客的时候是万万没想到那么严格的。
在这里插入图片描述

23

🌎总结

请添加图片描述

🚩 如上就是这篇博客的内容了,COM口编程很丰富且负责,本文主要简单阐述了Python 如何启动CANoe,以及信号,变量的交互;但这对我们想要用Python实现自动话测试还远远不够,接下来博主将继续通过Python 如何加载TestSetup ,tse ,生成报告,以及UI设计来实现Python 与CANoe更精彩的交互

  • 103
    点赞
  • 457
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 105
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 105
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蚂蚁小兵

慢慢长夜磨一章好文章,费烟!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值