├── .gitignore ├── LICENSE ├── README.md ├── python_canalyzer ├── __init__.py └── python_canalyzer.py ├── setup.py └── test.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 sgnes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PythonCanalyzer 2 | 3 | A python implementation to control Vector Canalyzer via Win32Com interface. 4 | 5 | ## Getting Started 6 | 7 | These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system. 8 | 9 | ### Prerequisites 10 | 11 | What things you need to install the software and how to install them 12 | 13 | ``` 14 | Win32Com 15 | ``` 16 | 17 | ### Installing 18 | 19 | 20 | ``` 21 | pip install pywin32 22 | pip install pypiwin32 23 | ``` 24 | 25 | ## What this tool can do 26 | 27 | This tool will open a CANalyzer configuration(To minimum the code size, this tool will not create this configuration, user has to create it manually), and provide below functionlity: 28 | 29 | 1. Call CAPL functions; 30 | 2. Get CAN bus signal value; 31 | 3. Send CAN bus signal value(via CAPL functionlity) 32 | 33 | ## Why this tool 34 | 35 | You should already know that Canalyzer support CAPL script, so why create this new tool? 36 | 37 | This tool is part of [EcuAutoTest](https://github.com/sgnes/EcuAutoTest), EcuAutoTest is used to control Vector CANalyzer and CANape in one script, to do some ECU auto test. 38 | 39 | ### A demo: 40 | 41 | ```python 42 | from python_canalyzer import PythonCanalyzer 43 | 44 | canalyzer = PythonCanalyzer(r"E:\test\j1939.cfg", capl_path = r"E:\test\Config\Canalyzer\capl.can") 45 | canalyzer.call_capl('CCVS1_RX_SA_232_EngShutdownOverrideSwitch', 3) 46 | canalyzer.get_can_bus_signal_value(0, "DM01_T1", "DTC1") 47 | canalyzer.send_can_bus_signal_value(0, "CCVS1_RX_SA_232", "EngShutdownOverrideSwitch",3) 48 | ``` 49 | 50 | 51 | ## Versioning 52 | 53 | We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/sgnes/PythonCanalyzer/tags). 54 | 55 | ## Authors 56 | 57 | * **[Sgnes](sgnes0514@gmail.com)** - *Initial work* - 58 | 59 | See also the list of [contributors](https://github.com/sgnes/PythonCanalyzer/contributors) who participated in this project. 60 | 61 | ## License 62 | 63 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details 64 | 65 | ## Acknowledgments 66 | 67 | * Hat tip to anyone whose code was used 68 | * Inspiration 69 | * etc 70 | -------------------------------------------------------------------------------- /python_canalyzer/__init__.py: -------------------------------------------------------------------------------- 1 | from .python_canalyzer import * -------------------------------------------------------------------------------- /python_canalyzer/python_canalyzer.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from win32com.client import DispatchEx 3 | import win32com 4 | import time 5 | import re 6 | import sys 7 | 8 | CANalyzer = None 9 | 10 | class MeasEvents: 11 | 12 | def OnInit(self): 13 | global CANalyzer 14 | CANalyzer.update_capl_funs() 15 | 16 | 17 | class PythonCanalyzer(object): 18 | """ 19 | 20 | """ 21 | 22 | def __init__(self, canalyzer_config_path, capl_path=None, logger=None): 23 | self.logger = logger or logging.getLogger(__name__) 24 | self._capl_funcs = {} 25 | self._capl_path = capl_path 26 | self._CANalyzer = DispatchEx('CANalyzer.Application') 27 | self._CANalyzer.Open(canalyzer_config_path) 28 | if self._capl_path is not None: 29 | PythonCanalyzer._capl_names = self._get_capl_fun_names() 30 | self._CANalyzer.CAPL.Compile() 31 | global CANalyzer 32 | CANalyzer = self 33 | self._event_handler = win32com.client.WithEvents(self._CANalyzer.Measurement, MeasEvents) 34 | self._CANalyzer.UI.Write.Output('measurement starting...') 35 | self._CANalyzer.Measurement.Start() 36 | while (not self._CANalyzer.Measurement.Running): 37 | time.sleep(1) 38 | self._CANalyzer.UI.Write.Output('measurement started...') 39 | self.logger.info("Canalyzer measurement started.") 40 | 41 | 42 | def close(self): 43 | self._CANalyzer.Quit() 44 | 45 | 46 | 47 | def _get_capl_fun_names(self): 48 | re_exp = "^(void|int|byte|word|dword|long|int64|qword)\s+([a-zA-Z0-9_]+)\s*\((void|int|byte|word|dword|long|int64|qword|float)\s*" 49 | names = [] 50 | with open(self._capl_path) as capl: 51 | text = capl.read() 52 | res = re.findall(re_exp, text, re.M) 53 | names = [i[1] for i in res] 54 | self.logger.debug("CAPL functions:{0}".format(names)) 55 | return names 56 | 57 | def get_capl_names(self): 58 | return self._capl_names 59 | 60 | def update_capl_funs(self): 61 | for name in PythonCanalyzer._capl_names: 62 | obj = self._CANalyzer.CAPL.GetFunction(name) 63 | self._capl_funcs[name] = obj 64 | 65 | def get_capl_func(self, name): 66 | if name in self._capl_funcs: 67 | return self._capl_funcs[name] 68 | else: 69 | return None 70 | 71 | def get_can_bus_signal_value(self, ch, msg, signal): 72 | res = float(str(self._CANalyzer.Bus.GetSignal(ch, msg, signal))) 73 | return res 74 | 75 | 76 | def send_can_bus_signal_value(self, ch, msg, sig, value): 77 | """ 78 | """ 79 | ret_value = 0 80 | name = msg + "_" + sig 81 | if name in self._capl_funcs: 82 | func = self._capl_funcs[name] 83 | if value: 84 | func.Call(value) 85 | else: 86 | func.Call() 87 | ret_value = 1 88 | else: 89 | ret_value = 0 90 | self.logger.error("{} CAPL function:{} not founded.".format(sys._getframe().f_code.co_name, name)) 91 | raise NameError 92 | return ret_value 93 | 94 | def call_capl(self, name, value): 95 | ret_value = 0 96 | if name in self._capl_funcs: 97 | func = self._capl_funcs[name] 98 | if value: 99 | func.Call(value) 100 | else: 101 | func.Call() 102 | ret_value = 1 103 | else: 104 | ret_value = 0 105 | self.logger.error("{} CAPL function:{} not founded.".format(sys._getframe().f_code.co_name, name)) 106 | raise NameError 107 | return ret_value 108 | 109 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | with open("README.md", "r") as fh: 4 | long_description = fh.read() 5 | 6 | setuptools.setup( 7 | name="python_canalyzer", # Replace with your own username 8 | version="0.0.3", 9 | author="Guopeng Sun", 10 | author_email="sgnes0514@gmai.com", 11 | description="Vector CANalyzer Win32Com", 12 | long_description=long_description, 13 | long_description_content_type="text/markdown", 14 | url="https://github.com/sgnes/PythonCanalyzer", 15 | packages=setuptools.find_packages(), 16 | classifiers=[ 17 | "Programming Language :: Python :: 3", 18 | "License :: OSI Approved :: MIT License", 19 | "Operating System :: OS Independent", 20 | ], 21 | install_requires=[ 22 | 'pywin32', 23 | 'pypiwin32', 24 | ], 25 | python_requires='>=3.6', 26 | ) -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | from python_canalyzer import PythonCanalyzer 2 | 3 | canalyzer = PythonCanalyzer(r"E:\proj3115_vector_auto_test\Config\Canalyzer\j1939.cfg", capl_path = r"E:\proj3115_vector_auto_test\Config\Canalyzer\J1939sendmsg.can") 4 | pass --------------------------------------------------------------------------------