├── .coveragerc ├── .gitattributes ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .idea ├── coverage.bat └── vcs.xml ├── LICENSE ├── MANIFEST.in ├── README.md ├── appveyor.yml ├── docs ├── api.rst ├── cli.rst ├── conf.py ├── contents.rst ├── formats.rst ├── index.rst └── installation.rst ├── examples ├── BusmasterRestbus.py ├── cmTemplate.xlsx ├── compare.py ├── convert.py ├── createCMacros.py ├── createJ1939Dbc.py ├── createccl.py ├── decodeFrame.py ├── dissect_cannelloni.lua ├── encodeFrame.py ├── exampleJoin.py ├── exampleMerge.py ├── fr_dump.py └── j1939_test.py ├── mypy.ini ├── pyproject.toml ├── requirements_docs.txt ├── src └── canmatrix │ ├── __init__.py │ ├── cancluster.py │ ├── canmatrix.py │ ├── cli │ ├── __init__.py │ ├── compare.py │ └── convert.py │ ├── compare.py │ ├── convert.py │ ├── copy.py │ ├── formats │ ├── __init__.py │ ├── arxml.py │ ├── csv.py │ ├── dbc.py │ ├── dbf.py │ ├── eds.py │ ├── fibex.py │ ├── json.py │ ├── kcd.py │ ├── ldf.py │ ├── odx.py │ ├── scapy.py │ ├── sym.py │ ├── wireshark.py │ ├── xls.py │ ├── xls_common.py │ ├── xlsx.py │ └── yaml.py │ ├── j1939.dbc │ ├── j1939_decoder.py │ ├── join.py │ ├── log.py │ ├── py.typed │ ├── types.py │ └── utils.py ├── stubs ├── lxml │ ├── __init__.pyi │ ├── etree.pyi │ └── objectify.pyi ├── xlrd │ ├── __init__.pyi │ ├── biffh.pyi │ ├── book.pyi │ ├── compdoc.pyi │ ├── formatting.pyi │ ├── formula.pyi │ ├── info.pyi │ ├── sheet.pyi │ ├── timemachine.pyi │ ├── xldate.pyi │ └── xlsx.pyi └── xlwt │ ├── BIFFRecords.pyi │ ├── Bitmap.pyi │ ├── Cell.pyi │ ├── Column.pyi │ ├── CompoundDoc.pyi │ ├── ExcelFormula.pyi │ ├── ExcelFormulaLexer.pyi │ ├── ExcelFormulaParser.pyi │ ├── ExcelMagic.pyi │ ├── Formatting.pyi │ ├── Row.pyi │ ├── Style.pyi │ ├── UnicodeUtils.pyi │ ├── Utils.pyi │ ├── Workbook.pyi │ ├── Worksheet.pyi │ ├── __init__.pyi │ ├── antlr.pyi │ └── compat.pyi ├── tests ├── README ├── __init__.py ├── createTestFdMatrix.py ├── createTestMatrix.py ├── files │ ├── arxml │ │ ├── ARXMLCompuMethod1.arxml │ │ ├── ARXMLContainerTest.arxml │ │ ├── ARXMLSecuredPDUTest.arxml │ │ ├── ARXML_min_max.arxml │ │ ├── MyECU.ecuc.arxml │ │ └── test.arxml │ ├── dbc │ │ ├── aa.dbc │ │ ├── test.dbc │ │ └── test_frame_decoding.dbc │ ├── dbf │ │ └── test.dbf │ ├── json │ │ └── test.json │ ├── kcd │ │ └── test.kcd │ ├── sym │ │ └── test.sym │ └── xlsx │ │ ├── test.xls │ │ └── test.xlsx ├── reference │ ├── from_arxml │ │ ├── test.kcd │ │ ├── test_CAN.csv │ │ ├── test_CAN.dbc │ │ ├── test_CAN.dbf │ │ ├── test_CAN.json │ │ ├── test_CAN.sym │ │ ├── test_CAN.xls │ │ ├── test_CAN.xlsx │ │ ├── test_CAN.xml │ │ └── test_CAN.yaml │ ├── from_dbc │ │ ├── test.arxml │ │ ├── test.csv │ │ ├── test.dbf │ │ ├── test.json │ │ ├── test.kcd │ │ ├── test.sym │ │ ├── test.xls │ │ ├── test.xlsx │ │ ├── test.xml │ │ └── test.yaml │ ├── from_dbf │ │ ├── test.arxml │ │ ├── test.csv │ │ ├── test.dbc │ │ ├── test.json │ │ ├── test.kcd │ │ ├── test.sym │ │ ├── test.xls │ │ ├── test.xlsx │ │ ├── test.xml │ │ └── test.yaml │ ├── from_json │ │ ├── test.arxml │ │ ├── test.csv │ │ ├── test.dbc │ │ ├── test.dbf │ │ ├── test.kcd │ │ ├── test.sym │ │ ├── test.xls │ │ ├── test.xlsx │ │ ├── test.xml │ │ └── test.yaml │ ├── from_kcd │ │ ├── test.arxml │ │ ├── test_test.kcd.csv │ │ ├── test_test.kcd.dbc │ │ ├── test_test.kcd.dbf │ │ ├── test_test.kcd.json │ │ ├── test_test.kcd.sym │ │ ├── test_test.kcd.xls │ │ ├── test_test.kcd.xlsx │ │ ├── test_test.kcd.xml │ │ └── test_test.kcd.yaml │ ├── from_sym │ │ ├── test.arxml │ │ ├── test.csv │ │ ├── test.dbc │ │ ├── test.dbf │ │ ├── test.json │ │ ├── test.kcd │ │ ├── test.xls │ │ ├── test.xlsx │ │ ├── test.xml │ │ └── test.yaml │ ├── from_xls │ │ ├── test.arxml │ │ ├── test.csv │ │ ├── test.dbc │ │ ├── test.dbf │ │ ├── test.json │ │ ├── test.kcd │ │ ├── test.sym │ │ ├── test.xlsx │ │ ├── test.xml │ │ └── test.yaml │ └── from_xlsx │ │ ├── test.arxml │ │ ├── test.csv │ │ ├── test.dbc │ │ ├── test.dbf │ │ ├── test.json │ │ ├── test.kcd │ │ ├── test.sym │ │ ├── test.xls │ │ ├── test.xml │ │ └── test.yaml ├── test.py ├── test_arxml.py ├── test_arxml_gw.py ├── test_canmatrix.py ├── test_cli_compare.py ├── test_cli_convert.py ├── test_codec.py ├── test_copy.py ├── test_dbc.py ├── test_dbf.py ├── test_formats.py ├── test_frame_decoding.py ├── test_frame_encoding.py ├── test_j1939_decoder.py ├── test_json.py ├── test_scapy.py ├── test_sym.py ├── test_utils.py ├── test_wireshark.py └── test_xls.py └── tox.ini /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | branch = True 3 | source = 4 | canmatrix 5 | 6 | [report] 7 | show_missing = True 8 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | canmatrix/_version.py export-subst 2 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | release: 5 | types: [ published ] 6 | pull_request: 7 | push: 8 | 9 | env: 10 | PY_COLORS: "1" 11 | 12 | jobs: 13 | test: 14 | runs-on: ${{ matrix.os }} 15 | continue-on-error: ${{ matrix.experimental }} # See: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idcontinue-on-error 16 | strategy: 17 | matrix: 18 | # os: [ubuntu-latest, windows-latest] 19 | os: [ubuntu-latest, windows-latest, macos-latest] 20 | experimental: [false] 21 | # python-version: ["2.7","3.4","3.5","3.6","3.7","3.8","3.9","3.10","3.11","3.12"] 22 | python-version: ["3.8","3.9","3.10","3.11","3.12","3.13"] 23 | fail-fast: false 24 | steps: 25 | - uses: actions/checkout@v4 26 | - name: Set up Python ${{ matrix.python-version }} 27 | uses: actions/setup-python@v5 28 | with: 29 | python-version: ${{ matrix.python-version }} 30 | - name: Install dependencies 31 | run: | 32 | python -m pip install --upgrade pip 33 | pip install tox 34 | - name: Test with pytest via tox 35 | run: | 36 | tox -e gh 37 | - name: Coveralls 38 | uses: coverallsapp/github-action@v2.3.0 39 | with: 40 | github-token: ${{ secrets.github_token }} 41 | flag-name: Test_${{ matrix.os }}_${{ matrix.python-version }} 42 | parallel: true 43 | path-to-lcov: ./coverage.lcov 44 | 45 | coveralls: 46 | needs: test 47 | runs-on: ubuntu-latest 48 | steps: 49 | - name: Coveralls Finished 50 | uses: coverallsapp/github-action@v2.3.0 51 | with: 52 | github-token: ${{ secrets.github_token }} 53 | parallel-finished: true 54 | 55 | # static-code-analysis: 56 | # runs-on: ubuntu-latest 57 | # steps: 58 | # - uses: actions/checkout@v3 59 | # - name: Set up Python 60 | # uses: actions/setup-python@v4 61 | # with: 62 | # python-version: "3.10" 63 | # - name: Install dependencies 64 | # run: | 65 | # python -m pip install --upgrade pip 66 | # pip install -e .[lint] 67 | # - name: ruff 68 | # run: | 69 | # ruff check can 70 | # - name: pylint 71 | # run: | 72 | # pylint \ 73 | # src/**.py \ 74 | # can/io \ 75 | # doc/conf.py \ 76 | # examples/**.py \ 77 | 78 | # format: 79 | # runs-on: ubuntu-latest 80 | # steps: 81 | # - uses: actions/checkout@v3 82 | # - name: Set up Python 83 | # uses: actions/setup-python@v4 84 | # with: 85 | # python-version: "3.10" 86 | # - name: Install dependencies 87 | # run: | 88 | # python -m pip install --upgrade pip 89 | # pip install -e .[lint] 90 | # - name: Code Format Check with Black 91 | # run: | 92 | # black --check --verbose . 93 | 94 | # docs: 95 | # runs-on: ubuntu-latest 96 | # steps: 97 | # - uses: actions/checkout@v3 98 | # - name: Set up Python 99 | # uses: actions/setup-python@v4 100 | # with: 101 | # python-version: "3.10" 102 | # - name: Install dependencies 103 | # run: | 104 | # python -m pip install --upgrade pip 105 | # pip install -e .[canalystii,gs_usb,mf4] 106 | # pip install -r doc/doc-requirements.txt 107 | # - name: Build documentation 108 | # run: | 109 | # python -m sphinx -Wan --keep-going doc build 110 | # - name: Run doctest 111 | # run: | 112 | # python -m sphinx -b doctest -W --keep-going doc build 113 | # - uses: actions/upload-artifact@v3 114 | # with: 115 | # name: sphinx-out 116 | # path: ./build/ 117 | # retention-days: 5 118 | 119 | build: 120 | name: Packaging 121 | runs-on: ubuntu-latest 122 | steps: 123 | - uses: actions/checkout@v4 124 | with: 125 | fetch-depth: 0 126 | - name: Set up Python 127 | uses: actions/setup-python@v5 128 | with: 129 | python-version: "3.10" 130 | - name: Build wheel and sdist 131 | run: pipx run build 132 | - name: Check build artifacts 133 | run: pipx run twine check --strict dist/* 134 | - name: Save artifacts 135 | uses: actions/upload-artifact@v4 136 | with: 137 | name: canmatrix-dist 138 | path: ./dist 139 | 140 | upload_pypi: 141 | needs: [build] 142 | name: Release to PyPi 143 | runs-on: ubuntu-latest 144 | permissions: 145 | id-token: write 146 | attestations: write 147 | 148 | # upload to PyPI only on release 149 | if: github.event.release && github.event.action == 'published' 150 | steps: 151 | - uses: actions/download-artifact@v4 152 | with: 153 | path: dist 154 | merge-multiple: true 155 | 156 | - name: Publish release distributions to PyPI 157 | uses: pypa/gh-action-pypi-publish@release/v1 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | test/converted/ 2 | # Don't track backup files 3 | *.bak 4 | # https://github.com/github/gitignore/blob/da00310ccba9de9a988cc973ef5238ad2c1460e9/Python.gitignore 5 | 6 | # Byte-compiled / optimized / DLL files 7 | __pycache__/ 8 | *.py[cod] 9 | *$py.class 10 | 11 | # C extensions 12 | *.so 13 | 14 | # Distribution / packaging 15 | .Python 16 | env/ 17 | build/ 18 | develop-eggs/ 19 | dist/ 20 | downloads/ 21 | eggs/ 22 | .eggs/ 23 | lib/ 24 | lib64/ 25 | parts/ 26 | sdist/ 27 | var/ 28 | *.egg-info/ 29 | .installed.cfg 30 | *.egg 31 | 32 | # PyInstaller 33 | # Usually these files are written by a python script from a template 34 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 35 | *.manifest 36 | *.spec 37 | 38 | # Installer logs 39 | pip-log.txt 40 | pip-delete-this-directory.txt 41 | 42 | # Unit test / coverage reports 43 | htmlcov/ 44 | .tox/ 45 | .coverage 46 | .coverage.* 47 | .cache 48 | nosetests.xml 49 | coverage.xml 50 | *,cover 51 | .hypothesis/ 52 | 53 | # Translations 54 | *.mo 55 | *.pot 56 | 57 | # Django stuff: 58 | *.log 59 | 60 | # Sphinx documentation 61 | docs/_build/ 62 | 63 | # PyBuilder 64 | target/ 65 | /.mypy_cache 66 | /.idea 67 | -------------------------------------------------------------------------------- /.idea/coverage.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem ------------------------------------------------------------- 3 | rem In PyCharm create "external tool" pointing to this file, with 4 | rem Arguments: $PyInterpreterDirectory$ $FilePath$ 5 | rem WorkingDirectory $ProjectFileDir$ 6 | rem ------------------------------------------------------------- 7 | set python=%1\python.exe 8 | set arguments=%2 9 | 10 | 11 | %python% -m coverage run -m pytest %arguments% 12 | if %errorlevel% EQU 0 ( 13 | %python% -m coverage html 14 | cd htmlcov 15 | index.html 16 | ) 17 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2015, Eduard Broecker 2 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that 3 | the following conditions are met: 4 | 5 | Redistributions of source code must retain the above copyright notice, this list of conditions and the 6 | following disclaimer. 7 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 8 | following disclaimer in the documentation and/or other materials provided with the distribution. 9 | 10 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 11 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 12 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 13 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 14 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 15 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 16 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 17 | DAMAGE. 18 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE 2 | recursive-include tests *.py -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Canmatrix is a python package to read and write several CAN (Controller Area Network) database formats. 2 | 3 | [![PyPI](https://img.shields.io/pypi/v/canmatrix.svg)](https://pypi.org/project/canmatrix/) 4 | [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/canmatrix.svg)](https://pypi.org/project/canmatrix/) 5 | [![Coverall](https://coveralls.io/repos/github/ebroecker/canmatrix/badge.svg?branch=development)](https://coveralls.io/github/ebroecker/canmatrix?branch=development) 6 | [![GitHub issues](https://img.shields.io/github/issues-raw/ebroecker/canmatrix.svg)](https://github.com/ebroecker/canmatrix/issues) 7 | 8 | 9 | ## About 10 | 11 | ***Canmatrix*** implements a "Python Can Matrix Object" which describes the can-communication and the needed objects (Boardunits, Frames, Signals, Values, ...) 12 | ***Canmatrix*** also includes two **Tools** (canconvert and cancompare) for converting and comparing **CAN** databases. 13 | 14 | - Multiple formats automotive related communication matrix file parsing. 15 | - CAN message encoding and decoding. 16 | 17 | **Supported file formats for import:** 18 | 19 | .dbc candb / Vector 20 | .dbf Busmaster (open source!) 21 | .kcd kayak (open source!) 22 | .arxml autosar system description 23 | .yaml dump of the python object 24 | .xls(x) excel xls-import, works with .xls-file generated by this lib 25 | .sym peak pcan can description 26 | .xml (fibex or CANopen eds) 27 | .ldf (lin bus) 28 | .odx (diagnostic file) 29 | .eds 30 | 31 | **Supported file formats for export:** 32 | 33 | .dbc 34 | .dbf 35 | .kcd 36 | .xls(x) 37 | .json Canard (open source!) 38 | .arxml (very basic implementation) 39 | .yaml (dump of the python object) 40 | .sym 41 | .xml (fibex) 42 | .lua (wireshark script) 43 | .scapy 44 | 45 | Project Homepage: https://github.com/ebroecker/canmatrix 46 | 47 | Documentation: https://canmatrix.readthedocs.io 48 | 49 | 50 | ## Installation 51 | 52 | https://canmatrix.readthedocs.io/en/latest/installation.html 53 | 54 | [Chinese Translation / 安装中文方法解释及注意事项](https://github.com/ebroecker/canmatrix/wiki/%E5%AE%89%E8%A3%85%E4%B8%AD%E6%96%87%E6%96%B9%E6%B3%95%E8%A7%A3%E9%87%8A%E5%8F%8A%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9) 55 | 56 | 57 | ## Contributing 58 | 59 | Source Code, Documentation, Examples, Report issues and Any other contributions are **extremely appreciated**. 60 | 61 | 1. Fork the Project 62 | 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 63 | 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 64 | 4. Push to the Branch (`git push origin feature/AmazingFeature`) 65 | 5. Open a Pull Request -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # appveyor.yml - https://www.appveyor.com/docs/lang/python 2 | --- 3 | image: 4 | - Visual Studio 2022 5 | 6 | skip_branch_with_pr: true 7 | 8 | environment: 9 | matrix: 10 | - TOXENV: py38 11 | - TOXENV: py39 12 | - TOXENV: py310 13 | - TOXENV: py311 14 | - TOXENV: dist 15 | 16 | matrix: 17 | allow_failures: 18 | - TOXENV: pypy # until we get pypy in chocolatey 19 | - TOXENV: pypy3 # until we get pypy3 in chocolatey 20 | 21 | # https://www.appveyor.com/docs/how-to/rdp-to-build-worker/ 22 | init: 23 | - ps: if (Get-ChildItem Env:ENABLE_RDP -ErrorAction SilentlyContinue) {iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))} else {echo RDP not enabled} 24 | 25 | install: 26 | - if "%TOXENV%"=="pypy3" choco install python.pypy3 27 | - py -m pip install tox 28 | - ps: Update-AppveyorBuild -Version "v$(py get_version.py) b$Env:APPVEYOR_BUILD_NUMBER" 29 | 30 | build_script: 31 | - py -m tox 32 | - py -m tox -e codecov 33 | 34 | artifacts: 35 | - path: "dist\\*" 36 | 37 | # https://www.appveyor.com/docs/how-to/rdp-to-build-worker/ 38 | on_finish: 39 | - ps: if (Get-ChildItem Env:ENABLE_RDP -ErrorAction SilentlyContinue) {$blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))} else {echo RDP not enabled} 40 | -------------------------------------------------------------------------------- /docs/api.rst: -------------------------------------------------------------------------------- 1 | API 2 | === 3 | 4 | canmatrix.py 5 | ____________ 6 | 7 | .. automodule:: canmatrix.canmatrix 8 | :members: 9 | 10 | .. automodule:: canmatrix.Ecu 11 | :members: 12 | 13 | .. automodule:: canmatrix.Frame 14 | :members: 15 | 16 | .. automodule:: canmatrix.Signal 17 | :members: 18 | 19 | .. automodule:: canmatrix.SignalGroup 20 | :members: 21 | 22 | .. automodule:: canmatrix.DecodedSignal 23 | :members: 24 | 25 | .. automodule:: canmatrix.unpack_bitstring 26 | :members: 27 | 28 | .. automodule:: canmatrix.pack_bitstring 29 | :members: 30 | 31 | .. automodule:: canmatrix.ArbitrationId 32 | :members: 33 | 34 | .. automodule:: canmatrix.Define 35 | :members: 36 | 37 | cancluster.py 38 | _____________ 39 | 40 | .. automodule:: canmatrix.cancluster 41 | :members: 42 | 43 | compare.py 44 | __________ 45 | 46 | .. automodule:: canmatrix.compare 47 | :members: 48 | 49 | convert.py 50 | __________ 51 | 52 | .. automodule:: canmatrix.convert 53 | :members: 54 | 55 | 56 | copy.py 57 | _______ 58 | 59 | .. automodule:: canmatrix.copy 60 | :members: 61 | 62 | j1939_decoder.py 63 | ________________ 64 | 65 | .. automodule:: canmatrix.j1939_decoder 66 | :members: 67 | 68 | utils.py 69 | ________________ 70 | 71 | .. automodule:: canmatrix.j1939_decoder 72 | :members: 73 | 74 | 75 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # http://www.sphinx-doc.org/en/master/config 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | # import os 14 | # import sys 15 | # sys.path.insert(0, os.path.abspath('.')) 16 | 17 | 18 | # -- Project information ----------------------------------------------------- 19 | 20 | project = 'canmatrix' 21 | copyright = '2019, Eduard Bröcker' 22 | author = 'Eduard Bröcker' 23 | 24 | 25 | # -- General configuration --------------------------------------------------- 26 | 27 | # Add any Sphinx extension module names here, as strings. They can be 28 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 29 | # ones. 30 | extensions = ['sphinx.ext.autodoc' 31 | ] 32 | 33 | # Add any paths that contain templates here, relative to this directory. 34 | templates_path = ['_templates'] 35 | 36 | # List of patterns, relative to source directory, that match files and 37 | # directories to ignore when looking for source files. 38 | # This pattern also affects html_static_path and html_extra_path. 39 | exclude_patterns = [] 40 | 41 | 42 | # -- Options for HTML output ------------------------------------------------- 43 | 44 | # The theme to use for HTML and HTML Help pages. See the documentation for 45 | # a list of builtin themes. 46 | # 47 | html_theme = 'sphinx_rtd_theme' 48 | 49 | # Add any paths that contain custom static files (such as style sheets) here, 50 | # relative to this directory. They are copied after the builtin static files, 51 | # so a file named "default.css" will overwrite the builtin "default.css". 52 | html_static_path = ['_static'] 53 | -------------------------------------------------------------------------------- /docs/contents.rst: -------------------------------------------------------------------------------- 1 | Canmatrix Documentation 2 | ======================= 3 | 4 | 5 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. canmatrix documentation master file, created by 2 | sphinx-quickstart on Mon Apr 29 21:54:05 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to canmatrix's documentation! 7 | ===================================== 8 | *Canmatrix* implements a *Python Can Matrix Object* which describes the can-communication and the needed objects (Boardunits, Frames, Signals, Values, ...) 9 | *Canmatrix* also includes two **Command line tools** (*canconvert* and *cancompare*) for converting and comparing **CAN** databases. 10 | 11 | 12 | .. toctree:: 13 | :maxdepth: 2 14 | :caption: Contents: 15 | 16 | installation 17 | cli 18 | formats 19 | api 20 | 21 | 22 | Indices and tables 23 | ================== 24 | 25 | * :ref:`genindex` 26 | * :ref:`modindex` 27 | * :ref:`search` 28 | -------------------------------------------------------------------------------- /docs/installation.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | 5 | Install *canmatrix* with either 6 | :: 7 | 8 | $ pip install canmatrix 9 | 10 | or 11 | 12 | :: 13 | 14 | $ pip install . 15 | 16 | This installs the *canmatrix* package into your python installation. 17 | In addition to the *canmatrix* package there are 2 scripts installed with this package: 18 | 19 | 20 | for additional formats [arxml, kcd, fibex, xls, xlsx] use syntax like: 21 | :: 22 | 23 | $ pip install git+https://github.com/ebroecker/canmatrix#egg=canmatrix[kcd] 24 | 25 | 26 | If you are using a \*NIX-System, these scripts should be callable from command line 27 | 28 | If you are using a Windows system, these scripts are usually installed at the location of your python installation. 29 | For example `C:\\python3.4\\Scripts` or `C:\\python2.7\\Scripts` 30 | 31 | 32 | Dependencies 33 | ____________ 34 | 35 | * Canmatrix depends on: 36 | 37 | * xlrd (http://www.python-excel.org/) 38 | * xlwt-future (https://pypi.python.org/pypi/xlwt-future) 39 | * XlsxWriter (https://github.com/jmcnamara/XlsxWriter) 40 | * PyYAML (https://pypi.python.org/pypi/pyaml) 41 | * lxml (https://pypi.python.org/pypi/lxml) -------------------------------------------------------------------------------- /examples/cmTemplate.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/examples/cmTemplate.xlsx -------------------------------------------------------------------------------- /examples/compare.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | sys.path.append('..') 4 | 5 | import canmatrix.cli.compare 6 | canmatrix.cli.compare.cli_compare() 7 | -------------------------------------------------------------------------------- /examples/convert.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | sys.path.append('..') 4 | 5 | import canmatrix.cli.convert 6 | canmatrix.cli.convert.cli_convert() 7 | -------------------------------------------------------------------------------- /examples/createJ1939Dbc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import canmatrix.formats 3 | cm = canmatrix.CanMatrix() 4 | 5 | # 6 | # create frame Node604 7 | # 8 | frame1 = canmatrix.Frame("Node604", j1939_pgn = 0xff00, j1939_prio = 0x6, 9 | j1939_source = 0x80, 10 | comment = "J1939 packet containing >8 byte payload") 11 | for i in range(1,9): 12 | sig = canmatrix.Signal("ch%d" % i, size = 32, is_float = True, is_little_endian = False, startBit = (i-1)*32) 13 | frame1.add_signal(sig) 14 | cm.add_frame(frame1) 15 | 16 | # 17 | # create frame Node605 18 | # 19 | frame2 = canmatrix.Frame("Node605", j1939_pgn = 0xff01, j1939_prio = 0x6, 20 | j1939_source = 0x80, 21 | comment="J1939 packet containing 8 byte payload") 22 | 23 | sig = canmatrix.Signal("ch1", size=32, is_float=True, is_little_endian=False, startBit=0) 24 | sig2 = canmatrix.Signal("ch2", size=32, is_float=True, is_little_endian=False, startBit=32) 25 | frame2.add_signal(sig) 26 | frame2.add_signal(sig2) 27 | cm.add_frame(frame2) 28 | 29 | 30 | # 31 | # create frame Node606 32 | # 33 | frame3 = canmatrix.Frame("Node606", j1939_pgn = 0xff02, j1939_prio = 0x6, 34 | j1939_source = 0x80, 35 | comment="J1939 packet containing <8 byte payload") 36 | sig = canmatrix.Signal("ch1", size=32, is_float=True, is_little_endian=False, startBit=0) 37 | frame3.add_signal(sig) 38 | cm.add_frame(frame3) 39 | 40 | 41 | cm.recalc_dlc("force") 42 | 43 | # save dbc 44 | canmatrix.formats.dumpp({"":cm}, "example_j1939.dbc") 45 | -------------------------------------------------------------------------------- /examples/createccl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) 2016, Eduard Broecker 3 | # All rights reserved. 4 | # 5 | # Redistribution and use in source and binary forms, with or without modification, are permitted provided that 6 | # the following conditions are met: 7 | # 8 | # Redistributions of source code must retain the above copyright notice, this list of conditions and the 9 | # following disclaimer. 10 | # Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 11 | # following disclaimer in the documentation and/or other materials provided with the distribution. 12 | # 13 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 14 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 15 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 16 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 17 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 18 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 19 | # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 20 | # DAMAGE. 21 | 22 | import sys 23 | sys.path.append('..') 24 | import canmatrix.formats 25 | from createCMacros import * 26 | 27 | 28 | typedef = """ 29 | typedef struct Mailbox { 30 | uint8_t data[8]; 31 | } Mailbox_t; 32 | """ 33 | 34 | processFrame = """ 35 | void processFrame(uint32_t canId, uint8_t *framedata, uint8_t dlc) 36 | { 37 | Mailbox_t *mailbox; 38 | 39 | mailbox = getRxCanMailBox(canId); 40 | 41 | if (mailbox != NULL) 42 | { 43 | memcpy(mailbox->data, framedata, (dlc>8)?8:dlc); 44 | } 45 | } 46 | """ 47 | 48 | receiveIdArray = "uint32_t receiveFrameIds[COUNTRXMAILBOXES] = {%s};" 49 | rxMailboxStruct = "Mailbox_t RxCanMailboxes[COUNTRXMAILBOXES];" 50 | txMailboxStruct = "Mailbox_t TxCanMailboxes[COUNTTXMAILBOXES];" 51 | 52 | getRxCanMailBox = """ 53 | struct Mailbox *getRxCanMailBox(uint32_t canId) 54 | { 55 | uint32_t i; 56 | 57 | for(i = 0; i< COUNTRXMAILBOXES; i++) 58 | { 59 | if(canId == receiveFrameIds[i]) 60 | return &(RxCanMailboxes[i]); 61 | } 62 | return 0; 63 | } 64 | 65 | """ 66 | 67 | 68 | def main(): 69 | if len(sys.argv) <= 2: 70 | print "not yet working script for generating a communication layer for dedicated ECU out of can database" 71 | print "! missing support for sending cyclic messages" 72 | print "! missing any TEST ! " 73 | print " this code is just proofe of concept \n" 74 | print "Usage: createccl.py CanDatabaseFile ECU_Name " 75 | exit() 76 | 77 | ccl_h = "#ifndef __CCL_H__\n#define __CCL_H__\n\n" 78 | ccl_h += "typedef unsigned char uint8;\ntypedef unsigned int uint32;\n\n" 79 | 80 | ccl_c = "#include \n#include \n#include \"ccl.h\"\n\n" 81 | infile = sys.argv[1] 82 | ecu = sys.argv[2] 83 | 84 | dbs = canmatrix.formats.loadp(infile) 85 | db = next(iter(dbs.values())) 86 | 87 | receiveArray = [] 88 | receiveDict = {} 89 | receiveIndex = 0 90 | sendIndex = 0 91 | txDict = {} 92 | for frame in db.frames: 93 | if ecu in frame.receivers: 94 | receiveArray.append(frame.arbitration_id.id) 95 | receiveDict[frame] = receiveIndex 96 | receiveIndex += 1 97 | 98 | if ecu in frame.transmitters: 99 | txDict[frame] = sendIndex 100 | sendIndex += 1 101 | # print frame.name 102 | # if frame.effective_cycletime != 0: 103 | # print frame.name, 104 | # print frame.effective_cycletime 105 | # ccl_h += createStoreMacrosForFrame(frame, "_" + frame.name + "_") 106 | 107 | tempStr = "" 108 | for canid in receiveArray: 109 | tempStr += hex(canid) + ", " 110 | 111 | ccl_c += rxMailboxStruct + "\n" 112 | ccl_c += txMailboxStruct + "\n" 113 | ccl_c += receiveIdArray % (tempStr) + "\n" 114 | ccl_c += getRxCanMailBox + "\n" 115 | ccl_c += processFrame + "\n" 116 | 117 | ccl_h += "#define COUNTRXMAILBOXES %d" % (receiveArray.__len__()) + "\n" 118 | ccl_h += "#define COUNTTXMAILBOXES %d" % (txDict.__len__()) + "\n" 119 | ccl_h += typedef + "\n" 120 | ccl_h += "extern " + rxMailboxStruct + "\n" 121 | ccl_h += "extern " + txMailboxStruct + "\n" 122 | for frame in receiveDict: 123 | for signal in frame.signals: 124 | if ecu in signal.receivers: 125 | ccl_h += createDecodeMacro(signal, "_" + 126 | frame.name + 127 | "__", "", "RxCanMailboxes[%d].data" % 128 | (receiveDict[frame])) 129 | # for complete frame: 130 | # ccl_h += createDecodeMacrosForFrame(frame, "_" + frame.name + "__", "", "RxCanMailboxes[%d].data" % (receiveDict[frame])) 131 | for frame in txDict: 132 | ccl_h += createStoreMacrosForFrame(frame, "_" + 133 | frame.name + 134 | "_", framename="TxCanMailboxes[%d].data" % 135 | txDict[frame]) 136 | 137 | ccl_h += "\n\n#endif /* __CCL_H___ */" 138 | 139 | cfile = open("ccl.c", "w") 140 | cfile.write(ccl_c) 141 | cfile.close() 142 | 143 | hfile = open("ccl.h", "w") 144 | hfile.write(ccl_h) 145 | hfile.close() 146 | 147 | if __name__ == '__main__': 148 | sys.exit(main()) 149 | -------------------------------------------------------------------------------- /examples/decodeFrame.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import canmatrix.formats 4 | import sys 5 | 6 | # command line options... 7 | usage = """ 8 | %prog [options] matrix frame 9 | 10 | matrixX can be any of *.dbc|*.dbf|*.kcd|*.arxml 11 | frame is AAA#YYYYYYYYYYYYYYYY or 12 | BBBBB#YYYYYYYYYYYYYYYY or 13 | 14 | 15 | where AAA is standard ID and BBBBB is extended ID 16 | 17 | """ 18 | 19 | if len(sys.argv) < 3: 20 | print(usage) 21 | sys.exit(1) 22 | 23 | # load matrix 24 | db = canmatrix.formats.loadp_flat(sys.argv[1]) 25 | 26 | # load frame data from argv 27 | frame_string = sys.argv[2] 28 | (arbitration_id_string, hexdata) = frame_string.split('#') 29 | 30 | # set arbitration_id 31 | if len(arbitration_id_string) <= 3: 32 | arbitration_id = canmatrix.ArbitrationId(int(arbitration_id_string, 16), extended = False) 33 | else: 34 | # extended frame 35 | arbitration_id = canmatrix.ArbitrationId(int(arbitration_id_string, 16), extended = True) 36 | 37 | # find frame to given arbitration_id 38 | frame = db.frame_by_id(arbitration_id) 39 | can_data = bytearray.fromhex(hexdata) 40 | 41 | # decode frame 42 | decoded = frame.decode(can_data) 43 | 44 | #print decoded signals 45 | for (signal, value) in decoded.items(): 46 | print (signal + "\t" + hex(value.raw_value) + "\t(" + str(value.phys_value)+ ")") 47 | -------------------------------------------------------------------------------- /examples/dissect_cannelloni.lua: -------------------------------------------------------------------------------- 1 | --- dissects cannelloni packages 2 | --- https://github.com/mguentner/cannelloni 3 | --- https://github.com/PhilippFux/cannelloni 4 | --- 5 | --- canneloni frame 6 | cannelloni_protocol = Proto("Cannelloni", "Can over UPD Cannelloni") 7 | 8 | cannelloni_version = ProtoField.int8("canneloni.version", "version", base.DEC) 9 | cannelloni_opcode = ProtoField.int8("canneloni.opcode", "opcode", base.DEC) 10 | cannelloni_seq_no = ProtoField.int8("canneloni.seq_no", "seq_no", base.DEC) 11 | cannelloni_count = ProtoField.int16("canneloni.count", "count", base.DEC) 12 | cannelloni_protocol.fields = {cannelloni_version, cannelloni_opcode, cannelloni_seq_no, cannelloni_count} 13 | 14 | --- Can Frame 15 | can_frame = Proto("MyFrame", "My Can Frame") 16 | can_frame_id = ProtoField.uint32("can.frame.arbitration_id", "can_id", base.HEX) 17 | can_frame_is_extended = ProtoField.string("can.frame.is_extended", "is_extended") 18 | can_frame_dlc = ProtoField.uint8("can.frame.dlc", "dlc", base.DEC) 19 | can_frame_pdu = ProtoField.uint64("can.frame.pdu", "pdu", base.HEX) 20 | can_frame.fields = {can_frame_id, can_frame_is_extended, can_frame_dlc, can_frame_pdu} 21 | 22 | --- select your database - generated with canmatrix here [canconvert some.dbc can_database.lua] 23 | require "can_database" 24 | 25 | debug_example_protocol = false 26 | cannelloni_header_offset = 5 27 | 28 | function cannelloni_protocol.dissector(buffer, pinfo, tree) 29 | length = buffer:len() 30 | if length == 0 then return end 31 | 32 | pinfo.cols.protocol = cannelloni_protocol.name 33 | 34 | local subtree = tree:add(cannelloni_protocol, buffer(), "Cannelloni Protocol Data") 35 | subtree:add(cannelloni_version, buffer(0,1)) 36 | subtree:add(cannelloni_opcode, buffer(1,1)) 37 | subtree:add(cannelloni_seq_no, buffer(2,1)) 38 | subtree:add(cannelloni_count, buffer(3,2)) 39 | 40 | local count = buffer(3,2):uint() 41 | buffer_offset = cannelloni_header_offset 42 | 43 | --- each frame: 44 | for i=1,count do 45 | local framesubtree = subtree:add(can_frame, buffer(), "Can Frame" .. tostring(i)) 46 | 47 | can_id = buffer(buffer_offset,4) 48 | framesubtree:add(can_frame_id, can_id:bitfield(1,31)) 49 | if can_id:bitfield(0,1) == 1 then 50 | framesubtree:add(can_frame_is_extended, "True") 51 | else 52 | framesubtree:add(can_frame_is_extended, "False") 53 | end 54 | 55 | framesubtree:add(can_frame_dlc, buffer(buffer_offset+4,1)) 56 | local dlc = buffer(buffer_offset+4,1):uint() 57 | 58 | pdu = buffer(buffer_offset+5,dlc) 59 | framesubtree:add(can_frame_pdu, pdu) 60 | add_frame_info(can_id:uint(), pdu, dlc, framesubtree) 61 | 62 | buffer_offset = buffer_offset + 4 + 1 + dlc 63 | end 64 | end 65 | 66 | example_add_tree_info = true 67 | 68 | local udp_port = DissectorTable.get("udp.port") 69 | udp_port:add(3333, cannelloni_protocol) -------------------------------------------------------------------------------- /examples/encodeFrame.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import canmatrix.formats 4 | import sys 5 | import optparse 6 | 7 | # command line options... 8 | usage = """ 9 | %prog [options] matrix 10 | 11 | matrixX can be any of *.dbc|*.dbf|*.kcd|*.arxml 12 | """ 13 | 14 | parser = optparse.OptionParser(usage=usage) 15 | parser.add_option( 16 | "-f", "--frames", 17 | dest="frames", 18 | help="encode list of frames", 19 | default="*") 20 | 21 | (cmdlineOptions, args) = parser.parse_args() 22 | 23 | if len(args) < 1: 24 | parser.print_help() 25 | sys.exit(1) 26 | 27 | # load matrix 28 | db = canmatrix.formats.loadp_flat(args[0]) 29 | 30 | #get all frames which match the commandline 31 | frames = db.glob_frames(cmdlineOptions.frames) 32 | 33 | #helper to read physical value from user 34 | def read_signal_value_from_user(signal): 35 | a = input("Enter Value for " + signal.name + " ") 36 | 37 | if signal.is_float: 38 | return float(a) 39 | else: 40 | return int(a) 41 | 42 | # go through all frames 43 | for frame in frames: 44 | print (frame.name) 45 | 46 | if frame.is_complex_multiplexed: 47 | # ignore complex multiplexed signals 48 | continue 49 | if frame.is_multiplexed: 50 | # if multiplexed frame search for multiplexer 51 | multiplexer_signal = frame.get_multiplexer 52 | 53 | # read multiplexer value 54 | a = input("Enter Value for Multiplexer " + multiplexer_signal.name + " ") 55 | signalDict = dict() 56 | signalDict[multiplexer_signal.name] = int(a) 57 | 58 | # read signals for the given multiplexer value 59 | for signal in frame.get_signals_for_multiplexer_value(int(a)): 60 | signalDict[signal.name] = read_signal_value_from_user(signal) 61 | 62 | else: 63 | # not multiplexed frame 64 | signalDict = dict() 65 | # go through all signals 66 | for signal in frame.signals: 67 | signalDict[signal.name] = read_signal_value_from_user(signal) 68 | 69 | frame_data = frame.encode(signalDict) 70 | if frame.arbitration_id.extended: 71 | print("{:05X}#".format(frame.arbitration_id.id) + "".join(["%02X" % i for i in frame_data])) 72 | else: 73 | print("{:03X}#".format(frame.arbitration_id.id) + "".join(["%02X" % i for i in frame_data])) 74 | -------------------------------------------------------------------------------- /examples/exampleJoin.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import canmatrix.formats 4 | from canmatrix.join import join_frame_by_signal_start_bit 5 | 6 | files = ["../test/db_B.dbc", "../test/db_A.dbc"] 7 | 8 | target = join_frame_by_signal_start_bit(files) 9 | 10 | # 11 | # export the new (target)-Matrix for example as .dbc: 12 | # 13 | canmatrix.formats.dumpp(target, "target.dbc") 14 | canmatrix.formats.dumpp(target, "target.xlsx") 15 | -------------------------------------------------------------------------------- /examples/exampleMerge.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | sys.path.append('..') 5 | 6 | # importany loads all import filter 7 | import canmatrix 8 | import canmatrix.copy 9 | import canmatrix.formats 10 | # fuer Fileio: 11 | import sys 12 | 13 | # 14 | # read source Can-Matrixes 15 | # 16 | 17 | # import of one CAN-Matrix (*.dbc, *.dbf, *.kcd, *.arxml) 18 | db1 = canmatrix.formats.loadp_flat("first.dbc") 19 | # import of a second CAN-Matrix (*.dbc, *.dbf, *.kcd, *.arxml) 20 | db2 = canmatrix.formats.loadp_flat("second.dbc") 21 | 22 | # 23 | # create target Matrix 24 | # 25 | 26 | db3 = canmatrix.CanMatrix() 27 | 28 | # 29 | # Here a new Can-Matrix can be 'programmed': 30 | # ----------------------------------------------------- 31 | # 32 | 33 | # Copy Can-ID 1234 from second CAN-Matrix to target-Matrix 34 | canmatrix.copy.copy_frame(canmatrix.ArbitrationId(100), db2, db3) 35 | 36 | # Copy frame "Engine_123" from first CAN-Matrix to target-Matrix 37 | canmatrix.copy.copy_frame(canmatrix.ArbitrationId(200), db1, db3) 38 | 39 | # Copy ECU (with all Frames) "Gateway" from first CAN-Matrix to target-Matrix 40 | canmatrix.copy.copy_ecu_with_frames("Gateway", db1, db3) 41 | 42 | # 43 | # ----------------------------------------------------- 44 | # 45 | 46 | 47 | # 48 | # 49 | # export the new (target)-Matrix for example as .dbc: 50 | # 51 | 52 | canmatrix.formats.dumpp({"":db3}, "target.dbc") 53 | -------------------------------------------------------------------------------- /examples/fr_dump.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import canmatrix.formats 3 | import sys 4 | cluster = canmatrix.formats.loadp(sys.argv[1], decode_flexray = True) 5 | 6 | for cm in cluster: 7 | for frame in cluster[cm]: 8 | frame_info = "{}-{}-{}".format(frame.slot_id, frame.base_cycle, frame.repitition_cycle) 9 | for pdu in frame.pdus: 10 | for signal in pdu.signals: 11 | sig_group = pdu.get_signal_group_for_signal(signal) 12 | sig_group = "None" if sig_group is None else sig_group.name 13 | print("{}: {}, {}, {}, {}, {}".format(frame_info, frame.size, pdu.pdu_type, pdu.name, sig_group, signal.name)) 14 | 15 | -------------------------------------------------------------------------------- /examples/j1939_test.py: -------------------------------------------------------------------------------- 1 | import canmatrix.formats 2 | 3 | my_matrix = canmatrix.formats.loadp_flat(r"C:\Users\edu\Downloads\obd2-test\CSS-Electronics-OBD2-incl-extended-v2.0.dbc") 4 | 5 | for num, frame in enumerate(my_matrix.frames): 6 | print(f"Frame {num}: {frame}") 7 | print(f" is j1939: {frame.is_j1939}") 8 | print(f" id: {frame.arbitration_id}") 9 | print(f' Format: {frame.attributes["VFrameFormat"]}') 10 | if frame.is_j1939: 11 | print(f" pgn: {hex(frame.arbitration_id.pgn)}") 12 | -------------------------------------------------------------------------------- /mypy.ini: -------------------------------------------------------------------------------- 1 | # usage: 2 | # pythom -m pip intall mypy 3 | # python -m mypy ./src/canmatrix --config-file ./mypy.ini 4 | # 5 | # or configure "external tool" in pycharm: 6 | # program: $ModuleSdkPath$ 7 | # arguments: -m mypy $FilePath$ --config-file $ProjectFileDir$\mypy.ini 8 | # working directory: C:\tmp (whatever outside the project to force mypy write absolute paths) 9 | # with "output filter": $FILE_PATH$:$LINE$: 10 | 11 | [mypy] 12 | mypy_path = stubs 13 | show_column_numbers = True 14 | warn_unused_configs = True 15 | warn_unused_ignores = True 16 | check_untyped_defs = True 17 | # allow_redefinition = True 18 | 19 | # we want to delete this row later: 20 | strict_optional = False 21 | 22 | # for even later: 23 | # warn_return_any = True 24 | 25 | 26 | # per module settings: 27 | 28 | [mypy-canmatrix.tests.*] 29 | # check_untyped_defs = False 30 | ignore_missing_imports = True 31 | ignore_errors = True 32 | 33 | [mypy-canmatrix._version] 34 | ignore_errors = True 35 | 36 | # other settings: 37 | [mypy-xlsxwriter,pathlib2] 38 | ignore_missing_imports = True 39 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools >= 40.8.0"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "canmatrix" 7 | description = "Automotive Communication Matrix" 8 | readme = "README.md" 9 | license = { text = "BSD-2-Clause" } 10 | dynamic = ["version"] 11 | authors = [{ name="Eduard Bröcker", email = "eduard@gmx.de" }] 12 | maintainers = [{ name = "canmatrix contributors" }] 13 | dependencies = [ 14 | "attrs>=19.2.0", 15 | "click", 16 | "importlib-metadata; python_version < '3.8'", 17 | "typing; python_version < '3.5'", 18 | ] 19 | requires-python = ">=3.8" 20 | keywords = [ 21 | "CAN", 22 | "canbus", 23 | "dbc", 24 | "arxml", 25 | "kcd", 26 | "dbf", 27 | "sym", 28 | "fibex", 29 | "eds", 30 | "automotive", 31 | ] 32 | 33 | classifiers = [ 34 | "Development Status :: 5 - Production/Stable", 35 | "Environment :: Console", 36 | "Intended Audience :: Developers", 37 | "Intended Audience :: Education", 38 | "Intended Audience :: Information Technology", 39 | "Intended Audience :: Manufacturing", 40 | "Intended Audience :: Telecommunications Industry", 41 | "License :: OSI Approved :: BSD License", 42 | "Operating System :: Microsoft :: Windows", 43 | "Operating System :: POSIX :: Linux", 44 | "Operating System :: MacOS", 45 | "Programming Language :: Python", 46 | "Programming Language :: Python :: 3.8", 47 | "Programming Language :: Python :: 3.9", 48 | "Programming Language :: Python :: 3.10", 49 | "Programming Language :: Python :: 3.11", 50 | "Programming Language :: Python :: 3.12", 51 | "Programming Language :: Python :: 3.13", 52 | "Topic :: Software Development :: Embedded Systems :: Controller Area Network (CAN)", 53 | "Topic :: System :: Networking", 54 | "Topic :: Utilities", 55 | ] 56 | 57 | [project.scripts] 58 | cancompare = "canmatrix.cli.compare:cli_compare" 59 | canconvert = "canmatrix.cli.convert:cli_convert" 60 | 61 | [project.urls] 62 | homepage = "https://github.com/ebroecker/canmatrix" 63 | documentation = "https://canmatrix.readthedocs.io" 64 | repository = "https://github.com/ebroecker/canmatrix" 65 | 66 | [project.optional-dependencies] 67 | arxml = ["lxml"] 68 | csv = [] 69 | dbc = [] 70 | dbf = [] 71 | fibex = ["lxml"] 72 | json = [] 73 | kcd = ["lxml"] 74 | ldf = ["ldfparser"] 75 | odx = ["lxml"] 76 | scapy = [] 77 | sym = [] 78 | test = ["pathlib2; python_version < '3.4'", "pytest"] 79 | wireshark = [] 80 | xls = ["xlrd==1.2.0", "xlwt"] 81 | xlsx = ["openpyxl"] 82 | yaml = ["pyyaml"] 83 | eds = ["canopen"] 84 | 85 | [tool.setuptools.dynamic] 86 | version = {attr = "canmatrix.__version__"} 87 | 88 | [tool.setuptools.packages.find] 89 | where = ["src"] 90 | 91 | [tool.setuptools.package-data] 92 | canmatrix = ["j1939.dbc", "py.typed"] 93 | -------------------------------------------------------------------------------- /requirements_docs.txt: -------------------------------------------------------------------------------- 1 | lxml 2 | ldfparser 3 | xlrd 4 | xlwt 5 | openpyxl 6 | pyyaml -------------------------------------------------------------------------------- /src/canmatrix/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import logging 3 | 4 | import canmatrix.formats as formats 5 | import canmatrix.cancluster as cancluster 6 | 7 | from canmatrix.canmatrix import ( 8 | Ecu, 9 | Signal, 10 | SignalGroup, 11 | DecodedSignal, 12 | ArbitrationId, 13 | Frame, 14 | Define, 15 | CanMatrix, 16 | ) 17 | 18 | from canmatrix.canmatrix import ( 19 | StartbitLowerZero, 20 | EncodingComplexMultiplexed, 21 | MissingMuxSignal, 22 | DecodingComplexMultiplexed, 23 | DecodingFrameLength, 24 | ArbitrationIdOutOfRange 25 | ) 26 | 27 | # todo remove this later 28 | from canmatrix.canmatrix import * 29 | 30 | __version__ = "1.2.0" 31 | 32 | # Set default logging handler to avoid "No handler found" warnings in python 2. 33 | logging.getLogger(__name__).addHandler(logging.NullHandler()) 34 | 35 | -------------------------------------------------------------------------------- /src/canmatrix/cli/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/src/canmatrix/cli/__init__.py -------------------------------------------------------------------------------- /src/canmatrix/cli/compare.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | # Copyright (c) 2013, Eduard Broecker 5 | # All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without modification, are permitted provided that 8 | # the following conditions are met: 9 | # 10 | # Redistributions of source code must retain the above copyright notice, this list of conditions and the 11 | # following disclaimer. 12 | # Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 13 | # following disclaimer in the documentation and/or other materials provided with the distribution. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 16 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 17 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 18 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 21 | # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 22 | # DAMAGE. 23 | 24 | import logging 25 | import sys 26 | import typing 27 | from builtins import * 28 | 29 | import click 30 | 31 | import canmatrix.compare 32 | 33 | logger = logging.getLogger(__name__) 34 | 35 | 36 | @click.command() 37 | @click.option('-v', '--verbose', 'verbosity', help="Output verbosity", count=True, default=1) 38 | @click.option('-s', '--silent', is_flag=True, default=False, help="don't print status messages to stdout. (only errors)") 39 | @click.option('-f', '--frames', is_flag=True, default=False, help="show list of frames") 40 | @click.option('-c', '--comments', 'check_comments', is_flag=True, default=False, help="look for changed comments") 41 | @click.option('-a', '--attributes', 'check_attributes', is_flag=True, default=False, help="look for changed attributes") 42 | @click.option('-t', '--valueTable', 'ignore_valuetables', is_flag=True, default=False, help="ignore changed valuetables") 43 | @click.argument('matrix1', required=True) 44 | @click.argument('matrix2', required=True) 45 | def cli_compare(matrix1, matrix2, verbosity, silent, check_comments, check_attributes, ignore_valuetables, frames): 46 | """ 47 | canmatrix.cli.compare [options] matrix1 matrix2 48 | 49 | matrixX can be any of *.dbc|*.dbf|*.kcd|*.arxml|*.xls(x)|*.sym 50 | """ 51 | 52 | import canmatrix.log 53 | root_logger = canmatrix.log.setup_logger() 54 | 55 | if silent: 56 | # Only print ERROR messages (ignore import warnings) 57 | verbosity = -1 58 | canmatrix.log.set_log_level(root_logger, verbosity) 59 | 60 | # import only after setting log level, to also disable warning messages in silent mode. 61 | import canmatrix.formats # due this import we need the import alias for log module 62 | 63 | logger.info("Importing " + matrix1 + " ... ") 64 | db1 = canmatrix.formats.loadp_flat(matrix1) 65 | logger.info("%d Frames found" % (db1.frames.__len__())) 66 | 67 | logger.info("Importing " + matrix2 + " ... ") 68 | db2 = canmatrix.formats.loadp_flat(matrix2) 69 | logger.info("%d Frames found" % (db2.frames.__len__())) 70 | 71 | ignore = {} # type: typing.Dict[str, typing.Union[str, bool]] 72 | 73 | if not check_comments: 74 | ignore["comment"] = "*" 75 | 76 | if not check_attributes: 77 | ignore["ATTRIBUTE"] = "*" 78 | 79 | if ignore_valuetables: 80 | ignore["VALUETABLES"] = True 81 | 82 | if frames: 83 | only_in_matrix1 = [ 84 | frame.name 85 | for frame in db1.frames 86 | if db2.frame_by_name(frame.name) is None 87 | ] 88 | only_in_matrix2 = [ 89 | frame.name 90 | for frame in db2.frames 91 | if db1.frame_by_name(frame.name) is None 92 | ] 93 | print("Frames only in " + matrix1 + ": " + " ".join(only_in_matrix1)) 94 | print("Frames only in " + matrix2 + ": " + " ".join(only_in_matrix2)) 95 | 96 | else: 97 | # ignore["ATTRIBUTE"] = "*" 98 | # ignore["DEFINE"] = "*" 99 | obj = canmatrix.compare.compare_db(db1, db2, ignore) 100 | canmatrix.compare.dump_result(obj) 101 | return 0 102 | 103 | 104 | # to be run as module `python -m canmatrix.compare`, NOT as script with argument `canmatrix/compare.py` 105 | if __name__ == '__main__': 106 | sys.exit(cli_compare()) 107 | -------------------------------------------------------------------------------- /src/canmatrix/formats/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import importlib 4 | import logging 5 | import os 6 | import sys 7 | import typing 8 | from builtins import str 9 | from io import BytesIO 10 | 11 | import canmatrix 12 | import canmatrix.cancluster 13 | 14 | logger = logging.getLogger(__name__) 15 | moduleList = ["arxml", "csv", "dbc", "dbf", "json", "ldf", 16 | "kcd", "fibex", "sym", "xls", "xlsx", "yaml", "scapy", "wireshark", "odx", "eds"] 17 | 18 | loadedFormats = [] 19 | supportedFormats = {} # type: typing.MutableMapping[str, typing.MutableSequence[str]] 20 | extensionMapping = {} 21 | 22 | for module in moduleList: 23 | try: 24 | importlib.import_module("canmatrix.formats." + module) 25 | loadedFormats.append(module) 26 | except ImportError: 27 | logger.debug("%s is not supported", module) 28 | 29 | for loadedModule in loadedFormats: 30 | supportedFormats[loadedModule] = [] 31 | moduleInstance = sys.modules["canmatrix.formats." + loadedModule] 32 | if "load" in dir(moduleInstance): 33 | supportedFormats[loadedModule].append("load") 34 | if "dump" in dir(moduleInstance): 35 | supportedFormats[loadedModule].append("dump") 36 | if "clusterImporter" in dir(moduleInstance): 37 | supportedFormats[loadedModule].append("clusterImporter") 38 | if "clusterExporter" in dir(moduleInstance): 39 | supportedFormats[loadedModule].append("clusterExporter") 40 | if "extension" in dir(moduleInstance): 41 | supportedFormats[loadedModule].append("extension") 42 | extensionMapping[loadedModule] = moduleInstance.extension # type: ignore 43 | else: 44 | extensionMapping[loadedModule] = loadedModule 45 | 46 | 47 | def loads(string, import_type=None, key="", encoding="utf-8", **options): 48 | # type: (typing.Union[bytes,str], str, str, str, **str) -> typing.Union[typing.Dict[str, canmatrix.CanMatrix], None] 49 | bytes_str = string.encode(encoding=encoding) if isinstance(string, str) else string 50 | file_object = BytesIO(bytes_str) 51 | return load(file_object, import_type, key, **options) 52 | 53 | 54 | def loads_flat(string, import_type=None, key="", **options): 55 | # type: (str, str, typing.Optional[str], **str) -> typing.Union[canmatrix.CanMatrix, None] 56 | dbs = loads(string, import_type, key, **options) 57 | return dbs.popitem()[1] if dbs else None 58 | 59 | 60 | def loadp(path, import_type=None, key="", **options): 61 | # type: (str, str, str, **str) -> typing.Union[typing.Dict[str, canmatrix.CanMatrix], None] 62 | with open(path, "rb") as fileObject: 63 | if not import_type: 64 | for supportedImportType, extension in extensionMapping.items(): 65 | if path.lower().endswith(extension) and "load" in supportedFormats[supportedImportType]: 66 | import_type = supportedImportType 67 | break 68 | 69 | if import_type: 70 | return load(fileObject, import_type, key, **options) 71 | else: 72 | logger.error("This file format is not supported for reading") 73 | return None 74 | 75 | 76 | def loadp_flat(path, import_type=None, key="", **options): 77 | # type: (str, str, str, **str) -> typing.Union[canmatrix.CanMatrix, None] 78 | dbs = loadp(path, import_type, key, **options) 79 | return dbs.popitem()[1] if dbs else None 80 | 81 | 82 | def load(file_object, import_type, key="", **options): 83 | # type: (typing.BinaryIO, str, str, **str) -> typing.Union[typing.Dict[str, canmatrix.CanMatrix], None] 84 | dbs = {} # type: typing.Dict[str, canmatrix.CanMatrix] 85 | module_instance = sys.modules["canmatrix.formats." + import_type] 86 | if "clusterImporter" in supportedFormats[import_type]: 87 | dbs = module_instance.load(file_object, **options) # type: ignore 88 | else: 89 | dbs[key] = module_instance.load(file_object, **options) # type: ignore 90 | return dbs 91 | 92 | 93 | def load_flat(file_object, import_type, key="", **options): 94 | # type: (typing.BinaryIO, str, str, **str) -> typing.Union[canmatrix.CanMatrix, None] 95 | dbs = load(file_object, import_type, key, **options) 96 | return dbs.popitem()[1] if dbs else None 97 | 98 | 99 | def dump(can_matrix_or_cluster, file_object, export_type, **options): 100 | # type: (typing.Union[canmatrix.CanMatrix, typing.Mapping[str, canmatrix.CanMatrix]], typing.IO, str, **str) -> None 101 | module_instance = sys.modules["canmatrix.formats." + export_type] 102 | if isinstance(can_matrix_or_cluster, canmatrix.CanMatrix): 103 | module_instance.dump(can_matrix_or_cluster, file_object, **options) # type: ignore 104 | elif "clusterExporter" in supportedFormats[export_type]: 105 | module_instance.dump(can_matrix_or_cluster, file_object, **options) # type: ignore 106 | 107 | 108 | def dumpp(can_cluster, path, export_type=None, **options): 109 | # type: (typing.Mapping[str, canmatrix.CanMatrix], str, str, **str) -> None 110 | if not export_type: 111 | for key, extension in extensionMapping.items(): 112 | if path.lower().endswith("." + extension) and "dump" in supportedFormats[key]: 113 | export_type = key 114 | break 115 | if export_type: 116 | if "clusterExporter" in supportedFormats[export_type]: 117 | file_object = open(path, "wb") # type: typing.IO 118 | dump(can_cluster, file_object, export_type, **options) 119 | else: 120 | for name in can_cluster: 121 | if len(name) > 0: 122 | (file_path, ext) = os.path.splitext(path) 123 | outfile = file_path + "_" + name + ext 124 | else: 125 | outfile = path 126 | db = can_cluster[name] 127 | file_object = open(outfile, "wb") 128 | dump(db, file_object, export_type, **options) 129 | file_object.close() 130 | else: 131 | logger.error("This file format is not supported for writing") 132 | -------------------------------------------------------------------------------- /src/canmatrix/formats/ldf.py: -------------------------------------------------------------------------------- 1 | import ldfparser 2 | import canmatrix 3 | import ldfparser.encoding 4 | 5 | 6 | def load(f, **options): # type: (typing.IO, **typing.Any) -> canmatrix.CanMatrix 7 | ldf = ldfparser.parse_ldf(path=f.name) # using f.name is not nice, but works 8 | 9 | db = canmatrix.CanMatrix() 10 | db.baudrate = ldf.get_baudrate() 11 | 12 | for lin_frame in ldf.frames: 13 | cm_frame = canmatrix.Frame() 14 | cm_frame.name = lin_frame.name 15 | cm_frame.arbitration_id = cm_frame.arbitration_id.from_compound_integer(lin_frame.frame_id) 16 | cm_frame.add_transmitter(lin_frame.publisher.name) 17 | cm_frame.size = lin_frame.length 18 | 19 | for mapping in lin_frame.signal_map: 20 | lin_signal = mapping[1] 21 | cm_signal = canmatrix.Signal() 22 | cm_signal.is_signed = False 23 | if lin_signal.name in ldf.converters: 24 | for converter in ldf.converters[lin_signal.name]._converters: 25 | if isinstance(converter, ldfparser.encoding.LogicalValue): 26 | cm_signal.add_values(converter.phy_value, converter.info) 27 | if isinstance(converter, ldfparser.encoding.PhysicalValue): 28 | cm_signal.scale_ranges.append({ 29 | "min" : converter.phy_min, 30 | "max" : converter.phy_max, 31 | "factor" : converter.scale, 32 | "offset" : converter.offset, 33 | "unit" : converter.unit}) 34 | cm_signal.offset = converter.offset 35 | cm_signal.factor = converter.scale 36 | cm_signal.unit = converter.unit 37 | cm_signal.min = converter.phy_min 38 | cm_signal.max = converter.phy_max 39 | 40 | cm_signal.name = lin_signal.name 41 | cm_signal.size = lin_signal.width 42 | cm_signal.initial_value = lin_signal.init_value 43 | for subscriber in lin_signal.subscribers: 44 | cm_signal.add_receiver(subscriber.name) 45 | cm_signal.start_bit = mapping[0] 46 | cm_frame.add_signal(cm_signal) 47 | db.add_frame(cm_frame) 48 | return db 49 | -------------------------------------------------------------------------------- /src/canmatrix/formats/scapy.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2019, Eduard Broecker 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without modification, are permitted provided that 5 | # the following conditions are met: 6 | # 7 | # Redistributions of source code must retain the above copyright notice, this list of conditions and the 8 | # following disclaimer. 9 | # Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 10 | # following disclaimer in the documentation and/or other materials provided with the distribution. 11 | # 12 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 13 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 14 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 15 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 16 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 17 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 18 | # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 19 | # DAMAGE. 20 | 21 | # 22 | # this script exports scapy python files 23 | # https://scapy.readthedocs.io/en/latest/advanced_usage.html#automotive-usage 24 | 25 | import textwrap 26 | import typing 27 | from builtins import * 28 | 29 | import canmatrix 30 | 31 | extension = "py" 32 | 33 | 34 | def get_fmt(signal): # type: (canmatrix.Signal) -> str 35 | 36 | if signal.is_little_endian: 37 | fmt = "<" 38 | else: 39 | fmt = ">" 40 | 41 | if signal.is_float: 42 | fmt += "f" 43 | elif signal.is_signed: 44 | fmt += "b" 45 | else: 46 | fmt += "B" 47 | return fmt 48 | 49 | def signal_field_line(signal): 50 | return u'SignalField("{}", default=0, start={}, size={}, scaling={}, offset={}, unit="{}", fmt="{}"),'.format( 51 | signal.name, signal.get_startbit(bit_numbering=1), signal.size, signal.factor, signal.offset, 52 | signal.unit, get_fmt(signal)) 53 | 54 | def dump(db, f, **options): # type: (canmatrix.CanMatrix, typing.IO, **typing.Any) -> None 55 | scapy_decoder = textwrap.dedent(""" #!/usr/bin/env python 56 | # -*- coding: utf-8 -*- 57 | from scapy.packet import Packet 58 | from scapy.packet import bind_layers 59 | from scapy.fields import * 60 | from scapy.layers.can import * 61 | """) 62 | 63 | for frame in db.frames: 64 | scapy_decoder += "class " + frame.name + "(SignalPacket):\n" 65 | scapy_decoder += " fields_desc = [\n" 66 | 67 | if frame.is_multiplexed and not frame.is_complex_multiplexed: 68 | multiplexer = frame.get_multiplexer 69 | scapy_decoder += u' ' + signal_field_line(multiplexer) + '\n' 70 | for signal in frame.signals: 71 | if signal != multiplexer and signal.mux_val is not None: 72 | scapy_decoder += u' ConditionalField(' + signal_field_line(signal) + ' lambda p: p.{} == {}),\n'.format(multiplexer.name, signal.mux_val) 73 | elif signal != multiplexer: 74 | scapy_decoder += u' ' + signal_field_line(signal) + '\n' 75 | 76 | else: 77 | for signal in frame.signals: 78 | scapy_decoder += u' ' + signal_field_line(signal) + '\n' 79 | scapy_decoder += " ]\n\n" 80 | 81 | for frame in db.frames: 82 | if frame.arbitration_id.extended: 83 | scapy_decoder += "bind_layers(SignalHeader, " + frame.name + ", identifier = " + hex( 84 | frame.arbitration_id.id) + ", flags = \"extended\")\n" 85 | else: 86 | scapy_decoder += "bind_layers(SignalHeader, " + frame.name + ", identifier = " + hex( 87 | frame.arbitration_id.id) + ")\n" 88 | 89 | f.write(scapy_decoder.encode("utf8")) 90 | -------------------------------------------------------------------------------- /src/canmatrix/formats/xls_common.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (c) 2013, Eduard Broecker 3 | # All rights reserved. 4 | # 5 | # Redistribution and use in source and binary forms, with or without modification, are permitted provided that 6 | # the following conditions are met: 7 | # 8 | # Redistributions of source code must retain the above copyright notice, this list of conditions and the 9 | # following disclaimer. 10 | # Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 11 | # following disclaimer in the documentation and/or other materials provided with the distribution. 12 | # 13 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 14 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 15 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 16 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 17 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 18 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 19 | # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 20 | # DAMAGE. 21 | 22 | import typing 23 | from builtins import * 24 | 25 | import canmatrix 26 | 27 | 28 | def get_frame_info(db, frame): 29 | # type: (canmatrix.CanMatrix, canmatrix.Frame) -> typing.List[str] 30 | ret_array = [] # type: typing.List[str] 31 | 32 | if db.type == canmatrix.matrix_class.CAN: 33 | # frame-id 34 | if frame.arbitration_id.extended: 35 | ret_array.append("%3Xxh" % frame.arbitration_id.id) 36 | else: 37 | ret_array.append("%3Xh" % frame.arbitration_id.id) 38 | elif db.type == canmatrix.matrix_class.FLEXRAY: 39 | ret_array.append("TODO") 40 | elif db.type == canmatrix.matrix_class.SOMEIP: 41 | ret_array.append("%3Xh" % frame.header_id) 42 | 43 | # frame-Name 44 | ret_array.append(frame.name) 45 | 46 | ret_array.append(frame.effective_cycle_time) 47 | 48 | # determine send-type 49 | if "GenMsgSendType" in db.frame_defines: 50 | ret_array.append(frame.attribute("GenMsgSendType", db=db)) 51 | if "GenMsgDelayTime" in db.frame_defines: 52 | ret_array.append(frame.attribute("GenMsgDelayTime", db=db)) 53 | else: 54 | ret_array.append("") 55 | else: 56 | ret_array.append("") 57 | ret_array.append("") 58 | return ret_array 59 | 60 | 61 | def get_signal(db, frame, sig, motorola_bit_format): 62 | # type: (canmatrix.CanMatrix, canmatrix.Frame, canmatrix.Signal, str) -> typing.Tuple[typing.List, typing.List] 63 | front_array = [] # type: typing.List[typing.Union[str, float]] 64 | back_array = [] 65 | if motorola_bit_format == "msb": 66 | start_bit = sig.get_startbit(bit_numbering=1) 67 | elif motorola_bit_format == "msbreverse": 68 | start_bit = sig.get_startbit() 69 | else: # motorolaBitFormat == "lsb" 70 | start_bit = sig.get_startbit(bit_numbering=1, start_little=True) 71 | 72 | # start byte 73 | front_array.append(int(start_bit / 8) + 1) 74 | # start bit 75 | front_array.append(start_bit % 8) 76 | # signal name 77 | front_array.append(sig.name) 78 | 79 | # eval comment: 80 | comment = sig.comment if sig.comment else "" 81 | 82 | # eval multiplex-info 83 | if frame.is_complex_multiplexed: 84 | for signal in frame.signals: 85 | if signal.muxer_for_signal is not None: 86 | comment = "Mode {} = {}".format(sig.muxer_for_signal, sig.multiplex) 87 | else: 88 | if sig.multiplex == 'Multiplexor': 89 | comment = "Mode Signal: " + comment 90 | elif sig.multiplex is not None: 91 | comment = "Mode " + str(sig.multiplex) + ":" + comment 92 | 93 | # write comment and size of signal in sheet 94 | front_array.append(comment) 95 | front_array.append(sig.size) 96 | 97 | # start-value of signal available 98 | front_array.append(sig.initial_value) 99 | 100 | # SNA-value of signal available 101 | if "GenSigSNA" in db.signal_defines: 102 | sna = sig.attribute("GenSigSNA", db=db) 103 | if sna is not None: 104 | sna = sna[1:-1] 105 | front_array.append(sna) 106 | # no SNA-value of signal available / just for correct style: 107 | else: 108 | front_array.append(" ") 109 | 110 | # eval byteorder (little_endian: intel == True / motorola == 0) 111 | if sig.is_little_endian: 112 | front_array.append("i") 113 | else: 114 | front_array.append("m") 115 | 116 | # is a unit defined for signal? 117 | if sig.unit.strip(): 118 | # factor not 1.0 ? 119 | if float(sig.factor) != 1: 120 | back_array.append("%g" % float(sig.factor) + " " + sig.unit) 121 | # factor == 1.0 122 | else: 123 | back_array.append(sig.unit) 124 | # no unit defined 125 | else: 126 | # factor not 1.0 ? 127 | if float(sig.factor) != 1: 128 | back_array.append("%g -" % float(sig.factor)) 129 | # factor == 1.0 130 | else: 131 | back_array.append("") 132 | return front_array, back_array 133 | -------------------------------------------------------------------------------- /src/canmatrix/formats/yaml.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (c) 2013, Eduard Broecker 3 | # All rights reserved. 4 | # 5 | # Redistribution and use in source and binary forms, with or without modification, are permitted provided that 6 | # the following conditions are met: 7 | # 8 | # Redistributions of source code must retain the above copyright notice, this list of conditions and the 9 | # following disclaimer. 10 | # Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 11 | # following disclaimer in the documentation and/or other materials provided with the distribution. 12 | # 13 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 14 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 15 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 16 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 17 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 18 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 19 | # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 20 | # DAMAGE. 21 | # 22 | # this script exports yaml-files from a canmatrix-object 23 | # yaml-files are just object-dumps human readable. 24 | # This export is complete, no information lost 25 | 26 | import copy 27 | import typing 28 | from builtins import * 29 | 30 | import yaml 31 | 32 | import canmatrix 33 | 34 | try: 35 | from yaml.representer import SafeRepresenter 36 | except ImportError: 37 | yaml = None 38 | 39 | 40 | representers = False 41 | try: 42 | yaml.add_representer(int, SafeRepresenter.represent_int) 43 | yaml.add_representer(str, SafeRepresenter.represent_unicode) 44 | yaml.add_representer(list, SafeRepresenter.represent_list) 45 | representers = True 46 | except: 47 | representers = False 48 | # some error with representers ... continue anyway 49 | 50 | _yaml_initialized = False 51 | 52 | 53 | def dump(db, f, **options): # type: (canmatrix.CanMatrix, typing.IO, **typing.Any) -> None 54 | __init_yaml() 55 | new_db = copy.deepcopy(db) 56 | 57 | for i, frame in enumerate(new_db.frames): 58 | for j, signal in enumerate(frame.signals): 59 | if not signal.is_little_endian: 60 | signal.start_bit = signal.get_startbit(bit_numbering=1, start_little=True) 61 | # new_db.frames[i].signals[j].start_bit = signal.start_bit 62 | 63 | # f = open(filename, "w") 64 | if representers: 65 | f.write(yaml.dump(new_db)) 66 | else: 67 | f.write(yaml.dump(new_db).encode('utf8')) 68 | 69 | 70 | def load(f, **options): # type: (typing.IO, **typing.Any) -> canmatrix.CanMatrix 71 | __init_yaml() 72 | db = yaml.safe_load(f) 73 | return db 74 | 75 | 76 | T = typing.TypeVar('T') 77 | 78 | 79 | def _constructor(loader, node, cls, mapping=None): 80 | # type: (typing.Any, typing.Any, typing.Type[T], typing.Mapping) -> T 81 | d = {k.lstrip('_'): v for k, v in loader.construct_mapping(node).items()} 82 | name = d.pop('name') 83 | if mapping: 84 | for old, new in mapping.items(): 85 | d[new] = d.pop(old) 86 | return cls(name, **d) # type: ignore 87 | 88 | 89 | def _frame_constructor(loader, node): 90 | return _constructor( 91 | loader=loader, 92 | node=node, 93 | cls=canmatrix.Frame, 94 | mapping={ 95 | 'size': 'dlc', 96 | }, 97 | ) 98 | 99 | 100 | def _signal_constructor(loader, node): 101 | signal = _constructor( 102 | loader=loader, 103 | node=node, 104 | cls=canmatrix.Signal, 105 | mapping={ 106 | 'startbit': 'startBit', # todo shall probably be updated to match current names like start_bit 107 | 'signalsize': 'signalSize', 108 | }, 109 | ) 110 | 111 | if not signal.is_little_endian: 112 | signal.set_startbit( 113 | loader.construct_mapping(node)['_startbit'], 114 | bitNumbering=1, 115 | startLittle=False) 116 | 117 | return signal 118 | 119 | 120 | def _frame_representer(dumper, data): 121 | node = yaml.representer.Representer.represent_object(dumper, data) 122 | node.tag = '{}:Frame'.format(node.tag.partition(':python/object:')[0]) 123 | 124 | return node 125 | 126 | 127 | def __init_yaml(): 128 | """Lazy init yaml because canmatrix might not be fully loaded when loading this format.""" 129 | global _yaml_initialized 130 | if not _yaml_initialized: 131 | _yaml_initialized = True 132 | yaml.add_constructor(u'tag:yaml.org,2002:Frame', _frame_constructor) 133 | yaml.add_constructor(u'tag:yaml.org,2002:Signal', _signal_constructor) 134 | yaml.add_representer(canmatrix.Frame, _frame_representer) 135 | -------------------------------------------------------------------------------- /src/canmatrix/j1939_decoder.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from builtins import * 3 | 4 | import attr 5 | 6 | import canmatrix.formats 7 | 8 | try: 9 | from importlib.resources import read_binary 10 | except ImportError: 11 | from pkgutil import get_data as read_binary 12 | 13 | 14 | @attr.s 15 | class j1939_decoder(object): 16 | string = read_binary(__name__.rpartition('.')[0], "j1939.dbc") 17 | j1939_db = canmatrix.formats.loads_flat( 18 | string, import_type="dbc", dbcImportEncoding="utf8" 19 | ) 20 | length = attr.ib(default=0) # type: int 21 | count_succesive_frames = attr.ib(default=0) # type: int 22 | transfered_pgn = attr.ib(default=0) # type: int 23 | _data = attr.ib(init=False, default=bytearray()) 24 | 25 | def decode(self, arbitration_id, can_data, matrix = None): 26 | if matrix is not None: 27 | frame = matrix.frame_by_pgn(arbitration_id.pgn) 28 | else: 29 | frame = None 30 | if frame is not None: 31 | return ("regular " + frame.name, frame.decode(can_data)) 32 | elif self.j1939_db.frame_by_pgn(arbitration_id.pgn) is not None: 33 | signals = self.j1939_db.decode(arbitration_id,can_data) 34 | frame_name = self.j1939_db.frame_by_pgn(arbitration_id.pgn).name 35 | return ("J1939 known: " + frame_name, signals) 36 | 37 | elif arbitration_id.pgn == canmatrix.ArbitrationId.from_pgn(0xECFF).pgn and can_data[0] == 32: 38 | # BAM detected 39 | self.length = (int(can_data[2]) << 8) + int(can_data[1]) 40 | self.count_succesive_frames = int(can_data[3]) 41 | self.transfered_pgn = (int(can_data[7]) << 16) + (int(can_data[6]) << 8) + int(can_data[5]) 42 | self.bytes_left = self.length 43 | self._data = bytearray() 44 | return ("BAM ", {}) 45 | 46 | elif arbitration_id.pgn == canmatrix.ArbitrationId.from_pgn(0xECFF).pgn and can_data[0] == 16: 47 | # RTS detected 48 | self.length = (int(can_data[2]) << 8) + int(can_data[1]) 49 | self.count_of_packets = int(can_data[3]) 50 | self.total_count_of_packet_sent = int(can_data[4]) 51 | self.transfered_pgn = (int(can_data[7]) << 16) + (int(can_data[6]) << 8) + int(can_data[5]) 52 | return ("ERROR - decoding RTS not yet implemented") 53 | 54 | elif arbitration_id.pgn == canmatrix.ArbitrationId.from_pgn(0xECFF).pgn and can_data[0] == 17: 55 | # CTS detected 56 | self.max_packets_at_once = can_data[1] 57 | self.sequence_number_to_start = can_data[2] 58 | self.transfered_pgn = (int(can_data[7]) << 16) + (int(can_data[6]) << 8) + int(can_data[5]) 59 | return ("ERROR - decoding CTS not yet implemented") 60 | 61 | elif arbitration_id.pgn == canmatrix.ArbitrationId.from_pgn(0xECFF).pgn and can_data[0] == 19: 62 | # ACK detected 63 | self.message_size = (int(can_data[2]) << 8) + int(can_data[1]) 64 | self.count_of_packets = int(can_data[3]) 65 | self.transfered_pgn = (int(can_data[7]) << 16) + (int(can_data[6]) << 8) + int(can_data[5]) 66 | return ("ERROR - decoding ACK not yet implemented") 67 | 68 | elif arbitration_id.pgn == canmatrix.ArbitrationId.from_pgn(0xECFF).pgn and can_data[0] == 255: 69 | # Connection Abort 70 | self.abort_reason = can_data[1] 71 | self.transfered_pgn = (int(can_data[7]) << 16) + (int(can_data[6]) << 8) + int(can_data[5]) 72 | return ("ERROR - decoding Connection Abbort not yet implemented") 73 | 74 | 75 | elif arbitration_id.pgn == canmatrix.ArbitrationId.from_pgn(0xEEFF).pgn: 76 | #Address Claimed 77 | #arbitration_id.j1939_source 78 | #name in can_data[0:8] 79 | return ("ERROR - address claim detected not yet implemented") 80 | pass 81 | 82 | elif arbitration_id.pgn == canmatrix.ArbitrationId.from_pgn(0xEBFF).pgn: 83 | # transfer data 84 | self._data = self._data + can_data[1:min(8, self.bytes_left + 1)] 85 | self.bytes_left = max(self.bytes_left - 7, 0) 86 | 87 | if self.count_succesive_frames == 0: 88 | #print(self._data) 89 | frame = matrix.frame_by_pgn(self.transfered_pgn) 90 | if frame is not None: 91 | signals = frame.decode(self._data) 92 | return ("BAM last data", signals) 93 | return ("BAM last data", {}) 94 | else: 95 | self.count_succesive_frames -= 1 96 | return ("BAM data ", {}) 97 | return ("",{}) 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /src/canmatrix/join.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import typing 4 | from builtins import * 5 | 6 | import canmatrix 7 | import canmatrix.formats 8 | 9 | 10 | def list_pgn(db): 11 | # type: (canmatrix.CanMatrix) -> typing.Tuple[typing.List[int], typing.List[canmatrix.ArbitrationId]] 12 | """ 13 | Get all PGN values for given frame. 14 | 15 | :param db: CanMatrix database 16 | :return: tuple of [pgn] and [arbitration_id] 17 | """ 18 | id_list = [x.arbitration_id for x in db.frames] 19 | pgn_list = [arb_id.pgn for arb_id in id_list] 20 | return pgn_list, id_list 21 | 22 | 23 | def ids_sharing_same_pgn(id_x, pgn_x, id_y, pgn_y): 24 | # type: (typing.Sequence[canmatrix.ArbitrationId], typing.Sequence[int], typing.Sequence[canmatrix.ArbitrationId], typing.Sequence[int]) -> typing.Iterable[typing.Tuple[canmatrix.ArbitrationId, canmatrix.ArbitrationId]] 25 | """Yield arbitration ids which has the same pgn.""" 26 | for id_a, pgn_a in zip(id_x, pgn_x): 27 | for id_b, pgn_b in zip(id_y, pgn_y): 28 | if pgn_a == pgn_b: 29 | yield (id_a, id_b) 30 | 31 | 32 | def join_frame_by_signal_start_bit(files): # type: (typing.List[str]) -> canmatrix.CanMatrix 33 | target_db = next(iter(canmatrix.formats.loadp(files.pop(0)).values())) 34 | 35 | pgn_x, id_x = list_pgn(db=target_db) 36 | 37 | for f in files: 38 | source_db = next(iter(canmatrix.formats.loadp(f).values())) 39 | pgn_y, id_y = list_pgn(db=source_db) 40 | 41 | same_pgn = ids_sharing_same_pgn(id_x, pgn_x, id_y, pgn_y) 42 | 43 | for id_a, id_b in same_pgn: 44 | # print("{0:#x} {1:#x}".format(id_x, id_y)) 45 | target_fr = target_db.frame_by_id(id_a) 46 | source_fr = source_db.frame_by_id(id_b) 47 | 48 | signal_to_add = [] 49 | for sig_t in target_fr.signals: 50 | for sig_s in source_fr.signals: 51 | # print(sig.name) 52 | if sig_t.start_bit == sig_s.start_bit: 53 | # print("\t{0} {1}".format(sig_t.name, sig_s.name)) 54 | signal_to_add.append(sig_s) 55 | for s in signal_to_add: 56 | target_fr.add_signal(s) 57 | return target_db 58 | 59 | 60 | def rename_frame_with_id(source_db): # type: (canmatrix.CanMatrix) -> None 61 | for frameSc in source_db.frames: 62 | _, pgn, sa = frameSc.arbitration_id.j1939_tuple 63 | 64 | extension = "__{pgn:#04X}_{sa:#02X}_{sa:03d}d".format(pgn=pgn, sa=sa) 65 | new_name = frameSc.name + extension 66 | # print(new_name) 67 | frameSc.name = new_name 68 | 69 | 70 | def rename_frame_with_sae_acronym(source_db, target_db): # type: (canmatrix.CanMatrix, canmatrix.CanMatrix) -> None 71 | pgn_x, id_x = list_pgn(db=target_db) 72 | pgn_y, id_y = list_pgn(db=source_db) 73 | same_pgn = ids_sharing_same_pgn(id_x, pgn_x, id_y, pgn_y) 74 | 75 | for idx, idy in same_pgn: 76 | target_fr = target_db.frame_by_id(idx) 77 | source_fr = source_db.frame_by_id(idy) 78 | 79 | new_name = source_fr.name + "__" + target_fr.name 80 | target_fr.name = new_name 81 | 82 | 83 | def join_frame_for_manufacturer(db, files): # type: (canmatrix.CanMatrix, typing.Sequence[str]) -> None 84 | # target_db = next(iter(im.importany(files.pop(0)).values())) 85 | 86 | pgn_x, id_x = list_pgn(db=db) 87 | 88 | for f in files: 89 | source_db = next(iter(canmatrix.formats.loadp(f).values())) 90 | pgn_y, id_y = list_pgn(db=source_db) 91 | 92 | same_pgn = ids_sharing_same_pgn(id_x, pgn_x, id_y, pgn_y) 93 | 94 | for idx, idy in same_pgn: 95 | # print("{0:#x} {1:#x}".format(idx, idy)) 96 | target_fr = db.frame_by_id(idx) 97 | source_fr = source_db.frame_by_id(idy) 98 | 99 | _, pgn, sa = target_fr.arbitration_id.j1939_tuple 100 | if sa < 128: 101 | print('less', target_fr.name) 102 | to_add = [] 103 | for sig_s in source_fr.signals: 104 | new_name = "{name}_{pgn:#04x}_{sa:03}".format( 105 | name=sig_s.name, pgn=pgn, sa=sa) 106 | sig_s.name = new_name 107 | to_add.append(sig_s) 108 | for s in to_add: 109 | target_fr.add_signal(s) 110 | -------------------------------------------------------------------------------- /src/canmatrix/log.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (c) 2013, Eduard Broecker 3 | # All rights reserved. 4 | # 5 | # Redistribution and use in source and binary forms, with or without modification, are permitted provided that 6 | # the following conditions are met: 7 | # 8 | # Redistributions of source code must retain the above copyright notice, this list of conditions and the 9 | # following disclaimer. 10 | # Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 11 | # following disclaimer in the documentation and/or other materials provided with the distribution. 12 | # 13 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 14 | # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 15 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 16 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 17 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 18 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 19 | # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 20 | # DAMAGE. 21 | 22 | # Configurable logging 23 | # Author: Martin Hoffmann (m8ddin@gmail.com) 24 | 25 | import logging 26 | 27 | 28 | def setup_logger(): # type: () -> logging.Logger 29 | """Setup the root logger. Return the logger instance for possible further setting and use. 30 | 31 | To be used from CLI scripts only. 32 | """ 33 | formatter = logging.Formatter( 34 | fmt='%(levelname)s - %(module)s - %(message)s') 35 | 36 | handler = logging.StreamHandler() 37 | handler.setFormatter(formatter) 38 | 39 | logger = logging.getLogger() 40 | logger.setLevel(logging.DEBUG) 41 | logger.addHandler(handler) 42 | return logger 43 | 44 | def set_log_level(logger, level): # type: (logging.Logger, int) -> None 45 | """Dynamic reconfiguration of the log level""" 46 | if level > 2: 47 | level = 2 48 | elif level < -1: 49 | level = -1 50 | 51 | levels = { 52 | -1: logging.ERROR, 53 | 0: logging.WARN, 54 | 1: logging.INFO, 55 | 2: logging.DEBUG 56 | } 57 | 58 | logger.setLevel(levels[level]) 59 | -------------------------------------------------------------------------------- /src/canmatrix/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/src/canmatrix/py.typed -------------------------------------------------------------------------------- /src/canmatrix/types.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """Contains user defined types for more readable type hinting.""" 3 | import typing 4 | 5 | RawValue = typing.Union[int, float] 6 | PhysicalValue = typing.Any # more than typing.Union[int, decimal.Decimal, float] 7 | OptionalRawValue = typing.Optional[RawValue] 8 | OptionalPhysicalValue = typing.Optional[PhysicalValue] 9 | -------------------------------------------------------------------------------- /src/canmatrix/utils.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import csv 4 | import shlex 5 | import sys 6 | import typing 7 | from string import hexdigits 8 | from builtins import * 9 | 10 | if sys.version_info >= (3, 5): 11 | import math 12 | else: 13 | import fractions 14 | 15 | 16 | 17 | def quote_aware_space_split(in_line): # type: (str) -> typing.List[str] 18 | return shlex.split(in_line.strip()) 19 | 20 | 21 | # https://stackoverflow.com/questions/18092354/python-split-string-without-splitting-escaped-character 22 | def escape_aware_split(string, delimiter): 23 | if len(delimiter) != 1: 24 | raise ValueError('Invalid delimiter: ' + delimiter) 25 | ln = len(string) 26 | i = 0 27 | j = 0 28 | while j < ln: 29 | if string[j] == '\\': 30 | if j + 1 >= ln: 31 | yield string[i:j] 32 | return 33 | j += 1 34 | elif string[j] == delimiter: 35 | yield string[i:j] 36 | i = j + 1 37 | j += 1 38 | yield string[i:j] 39 | 40 | 41 | def quote_aware_comma_split(string): # type: (str) -> typing.List[str] 42 | """ 43 | Split a string containing comma separated list of fields. 44 | Removing surrounding whitespace, to allow fields to be separated by ", ". 45 | Preserves double quotes within fields, but not double quotes surrounding fields. 46 | Suppresses comma separators which are within double quoted sections. 47 | :param string: ('a, b", c", "d"', 48 | :return: ['a', 'b", c"', 'd']), 49 | """ 50 | fields = [] 51 | quoted = False 52 | field = "" 53 | # Separate string by unquoted commas 54 | for char in string: 55 | if char == ',': 56 | if not quoted: 57 | fields.append(field) 58 | field = "" 59 | continue 60 | if char == '"': 61 | quoted = not quoted 62 | field += char 63 | if field: 64 | fields.append(field) 65 | # Remove surrounding whitespace from fields 66 | fields = [f.strip() for f in fields] 67 | # Remove "" that surround entire fields 68 | for i, f in enumerate(fields): 69 | if len(f) > 1: 70 | if f.startswith('"') and f.endswith('"'): 71 | fields[i] = f[1:-1] 72 | return fields 73 | 74 | 75 | def guess_value(text_value): # type: (str) -> str 76 | """ 77 | Get string value for common strings. 78 | Method is far from complete but helping with odd arxml files. 79 | 80 | :param text_value: value in text like "true" 81 | :return: string for value like "1" 82 | """ 83 | if sys.version_info >= (3, 0): 84 | text_value = text_value.casefold() 85 | else: 86 | text_value = text_value.lower() 87 | if text_value in ["false", "off"]: 88 | return "0" 89 | elif text_value in ["true", "on"]: 90 | return "1" 91 | elif text_value[:2] == "0b": 92 | if text_value[2:].isdecimal(): 93 | return str(int(text_value[2:], 2)) 94 | elif text_value[:2] == "0x": 95 | if all([f in hexdigits for f in text_value[2:]]): 96 | return str(int(text_value[2:], 16)) 97 | return text_value 98 | 99 | 100 | def get_gcd(value1, value2): # type (int,int) -> (int) 101 | """ 102 | Get greatest common divisor of value1 and value2 103 | 104 | :param value1: int value 1 105 | :param value2: int value 2 106 | :return: cvt of value 1 and value 2 107 | """ 108 | 109 | if sys.version_info >= (3, 5): 110 | return math.gcd(value1, value2) 111 | else: 112 | return fractions.gcd(value1, value2) 113 | 114 | 115 | def decode_number(value, float_factory): # type(string) -> (int) 116 | """ 117 | Decode string to integer and guess correct base 118 | :param value: string input value 119 | :return: integer 120 | """ 121 | if value is None: 122 | return 0 123 | value = value.strip() 124 | 125 | if ('.' in value) or (value.lower() in ["inf", "+inf", "-inf"]): 126 | return float_factory(value) 127 | 128 | base = 10 129 | if len(value) > 1 and value[1] == 'b': # bin coded 130 | base = 2 131 | value = value[2:] 132 | if len(value) > 1 and value[1] == 'x': # hex coded 133 | base = 16 134 | value = value[2:] 135 | 136 | return int(value, base) 137 | -------------------------------------------------------------------------------- /stubs/lxml/__init__.pyi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/stubs/lxml/__init__.pyi -------------------------------------------------------------------------------- /stubs/lxml/objectify.pyi: -------------------------------------------------------------------------------- 1 | # Hand-written stub, incomplete 2 | 3 | from typing import Union 4 | 5 | from lxml.etree import ElementBase, XMLParser 6 | 7 | class ObjectifiedElement(ElementBase): 8 | pass 9 | 10 | def fromstring(text: Union[bytes, str], 11 | parser: XMLParser = ..., 12 | *, 13 | base_url: Union[bytes, str] = ...) -> ObjectifiedElement: ... 14 | -------------------------------------------------------------------------------- /stubs/xlrd/__init__.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlrd (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from .biffh import XLRDError, XL_CELL_BLANK, XL_CELL_BOOLEAN, XL_CELL_DATE, XL_CELL_EMPTY, XL_CELL_ERROR, XL_CELL_NUMBER, XL_CELL_TEXT, biff_text_from_num, error_text_from_code 6 | from .book import Book as Book, colname as colname 7 | from .sheet import empty_cell as empty_cell 8 | from .xldate import XLDateError, xldate_as_datetime, xldate_as_tuple 9 | from .xlsx import X12Book as X12Book 10 | from typing import Any, Optional 11 | 12 | MMAP_AVAILABLE: int 13 | USE_MMAP = MMAP_AVAILABLE 14 | 15 | def open_workbook(filename: Optional[Any] = ..., logfile: Any = ..., verbosity: int = ..., use_mmap: Any = ..., file_contents: Optional[Any] = ..., encoding_override: Optional[Any] = ..., formatting_info: bool = ..., on_demand: bool = ..., ragged_rows: bool = ...): ... 16 | def dump(filename: Any, outfile: Any = ..., unnumbered: bool = ...) -> None: ... 17 | def count_records(filename: Any, outfile: Any = ...) -> None: ... 18 | -------------------------------------------------------------------------------- /stubs/xlrd/biffh.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlrd.biffh (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from .timemachine import * 6 | from typing import Any, Optional 7 | 8 | DEBUG: int 9 | 10 | class XLRDError(Exception): ... 11 | 12 | class BaseObject: 13 | def dump(self, f: Optional[Any] = ..., header: Optional[Any] = ..., footer: Optional[Any] = ..., indent: int = ...) -> None: ... 14 | 15 | FUN: Any 16 | FDT: Any 17 | FNU: Any 18 | FGE: Any 19 | FTX: Any 20 | DATEFORMAT = FDT 21 | NUMBERFORMAT = FNU 22 | XL_CELL_EMPTY: Any 23 | XL_CELL_TEXT: Any 24 | XL_CELL_NUMBER: Any 25 | XL_CELL_DATE: Any 26 | XL_CELL_BOOLEAN: Any 27 | XL_CELL_ERROR: Any 28 | XL_CELL_BLANK: Any 29 | biff_text_from_num: Any 30 | error_text_from_code: Any 31 | BIFF_FIRST_UNICODE: int 32 | XL_WORKBOOK_GLOBALS: int 33 | WBKBLOBAL: int 34 | XL_WORKBOOK_GLOBALS_4W: int 35 | XL_WORKSHEET: int 36 | WRKSHEET: int 37 | XL_BOUNDSHEET_WORKSHEET: int 38 | XL_BOUNDSHEET_CHART: int 39 | XL_BOUNDSHEET_VB_MODULE: int 40 | XL_ARRAY: int 41 | XL_ARRAY2: int 42 | XL_BLANK: int 43 | XL_BLANK_B2: int 44 | XL_BOF: int 45 | XL_BOOLERR: int 46 | XL_BOOLERR_B2: int 47 | XL_BOUNDSHEET: int 48 | XL_BUILTINFMTCOUNT: int 49 | XL_CF: int 50 | XL_CODEPAGE: int 51 | XL_COLINFO: int 52 | XL_COLUMNDEFAULT: int 53 | XL_COLWIDTH: int 54 | XL_CONDFMT: int 55 | XL_CONTINUE: int 56 | XL_COUNTRY: int 57 | XL_DATEMODE: int 58 | XL_DEFAULTROWHEIGHT: int 59 | XL_DEFCOLWIDTH: int 60 | XL_DIMENSION: int 61 | XL_DIMENSION2: int 62 | XL_EFONT: int 63 | XL_EOF: int 64 | XL_EXTERNNAME: int 65 | XL_EXTERNSHEET: int 66 | XL_EXTSST: int 67 | XL_FEAT11: int 68 | XL_FILEPASS: int 69 | XL_FONT: int 70 | XL_FONT_B3B4: int 71 | XL_FORMAT: int 72 | XL_FORMAT2: int 73 | XL_FORMULA: int 74 | XL_FORMULA3: int 75 | XL_FORMULA4: int 76 | XL_GCW: int 77 | XL_HLINK: int 78 | XL_QUICKTIP: int 79 | XL_HORIZONTALPAGEBREAKS: int 80 | XL_INDEX: int 81 | XL_INTEGER: int 82 | XL_IXFE: int 83 | XL_LABEL: int 84 | XL_LABEL_B2: int 85 | XL_LABELRANGES: int 86 | XL_LABELSST: int 87 | XL_LEFTMARGIN: int 88 | XL_TOPMARGIN: int 89 | XL_RIGHTMARGIN: int 90 | XL_BOTTOMMARGIN: int 91 | XL_HEADER: int 92 | XL_FOOTER: int 93 | XL_HCENTER: int 94 | XL_VCENTER: int 95 | XL_MERGEDCELLS: int 96 | XL_MSO_DRAWING: int 97 | XL_MSO_DRAWING_GROUP: int 98 | XL_MSO_DRAWING_SELECTION: int 99 | XL_MULRK: int 100 | XL_MULBLANK: int 101 | XL_NAME: int 102 | XL_NOTE: int 103 | XL_NUMBER: int 104 | XL_NUMBER_B2: int 105 | XL_OBJ: int 106 | XL_PAGESETUP: int 107 | XL_PALETTE: int 108 | XL_PANE: int 109 | XL_PRINTGRIDLINES: int 110 | XL_PRINTHEADERS: int 111 | XL_RK: int 112 | XL_ROW: int 113 | XL_ROW_B2: int 114 | XL_RSTRING: int 115 | XL_SCL: int 116 | XL_SHEETHDR: int 117 | XL_SHEETPR: int 118 | XL_SHEETSOFFSET: int 119 | XL_SHRFMLA: int 120 | XL_SST: int 121 | XL_STANDARDWIDTH: int 122 | XL_STRING: int 123 | XL_STRING_B2: int 124 | XL_STYLE: int 125 | XL_SUPBOOK: int 126 | XL_TABLEOP: int 127 | XL_TABLEOP2: int 128 | XL_TABLEOP_B2: int 129 | XL_TXO: int 130 | XL_UNCALCED: int 131 | XL_UNKNOWN: int 132 | XL_VERTICALPAGEBREAKS: int 133 | XL_WINDOW2: int 134 | XL_WINDOW2_B2: int 135 | XL_WRITEACCESS: int 136 | XL_WSBOOL = XL_SHEETPR 137 | XL_XF: int 138 | XL_XF2: int 139 | XL_XF3: int 140 | XL_XF4: int 141 | boflen: Any 142 | bofcodes: Any 143 | XL_FORMULA_OPCODES: Any 144 | 145 | def is_cell_opcode(c: Any): ... 146 | def upkbits(tgt_obj: Any, src: Any, manifest: Any, local_setattr: Any = ...) -> None: ... 147 | def upkbitsL(tgt_obj: Any, src: Any, manifest: Any, local_setattr: Any = ..., local_int: Any = ...) -> None: ... 148 | def unpack_string(data: Any, pos: Any, encoding: Any, lenlen: int = ...): ... 149 | def unpack_string_update_pos(data: Any, pos: Any, encoding: Any, lenlen: int = ..., known_len: Optional[Any] = ...): ... 150 | def unpack_unicode(data: Any, pos: Any, lenlen: int = ...): ... 151 | def unpack_unicode_update_pos(data: Any, pos: Any, lenlen: int = ..., known_len: Optional[Any] = ...): ... 152 | def unpack_cell_range_address_list_update_pos(output_list: Any, data: Any, pos: Any, biff_version: Any, addr_size: int = ...): ... 153 | 154 | biff_rec_name_dict: Any 155 | 156 | def hex_char_dump(strg: Any, ofs: Any, dlen: Any, base: int = ..., fout: Any = ..., unnumbered: bool = ...) -> None: ... 157 | def biff_dump(mem: Any, stream_offset: Any, stream_len: Any, base: int = ..., fout: Any = ..., unnumbered: bool = ...) -> None: ... 158 | def biff_count_records(mem: Any, stream_offset: Any, stream_len: Any, fout: Any = ...) -> None: ... 159 | 160 | encoding_from_codepage: Any 161 | -------------------------------------------------------------------------------- /stubs/xlrd/book.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlrd.book (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | import struct 6 | from typing import Any, Optional 7 | from .biffh import BaseObject 8 | 9 | unpack = struct.unpack 10 | empty_cell: Any 11 | DEBUG: int 12 | USE_FANCY_CD: int 13 | TOGGLE_GC: int 14 | MMAP_AVAILABLE: int 15 | USE_MMAP = MMAP_AVAILABLE 16 | MY_EOF: int 17 | SUPBOOK_UNK: Any 18 | SUPBOOK_INTERNAL: Any 19 | SUPBOOK_EXTERNAL: Any 20 | SUPBOOK_ADDIN: Any 21 | SUPBOOK_DDEOLE: Any 22 | SUPPORTED_VERSIONS: Any 23 | builtin_name_from_code: Any 24 | code_from_builtin_name: Any 25 | 26 | def open_workbook_xls(filename: Optional[Any] = ..., logfile: Any = ..., verbosity: int = ..., use_mmap: Any = ..., file_contents: Optional[Any] = ..., encoding_override: Optional[Any] = ..., formatting_info: bool = ..., on_demand: bool = ..., ragged_rows: bool = ...): ... 27 | 28 | class Name(BaseObject): 29 | book: Any = ... 30 | hidden: int = ... 31 | func: int = ... 32 | vbasic: int = ... 33 | macro: int = ... 34 | complex: int = ... 35 | builtin: int = ... 36 | funcgroup: int = ... 37 | binary: int = ... 38 | name_index: int = ... 39 | name: Any = ... 40 | raw_formula: bytes = ... 41 | scope: int = ... 42 | result: Any = ... 43 | def cell(self): ... 44 | def area2d(self, clipped: bool = ...): ... 45 | 46 | class Book(BaseObject): 47 | nsheets: int = ... 48 | datemode: int = ... 49 | biff_version: int = ... 50 | name_obj_list: Any = ... 51 | codepage: Any = ... 52 | encoding: Any = ... 53 | countries: Any = ... 54 | user_name: Any = ... 55 | font_list: Any = ... 56 | xf_list: Any = ... 57 | format_list: Any = ... 58 | format_map: Any = ... 59 | style_name_map: Any = ... 60 | colour_map: Any = ... 61 | palette_record: Any = ... 62 | load_time_stage_1: Any = ... 63 | load_time_stage_2: Any = ... 64 | def sheets(self): ... 65 | def sheet_by_index(self, sheetx: Any): ... 66 | def sheet_by_name(self, sheet_name: Any): ... 67 | def sheet_names(self): ... 68 | def sheet_loaded(self, sheet_name_or_index: Any): ... 69 | def unload_sheet(self, sheet_name_or_index: Any) -> None: ... 70 | mem: Any = ... 71 | filestr: Any = ... 72 | def release_resources(self) -> None: ... 73 | def __enter__(self): ... 74 | def __exit__(self, exc_type: Any, exc_value: Any, exc_tb: Any) -> None: ... 75 | name_and_scope_map: Any = ... 76 | name_map: Any = ... 77 | raw_user_name: bool = ... 78 | builtinfmtcount: int = ... 79 | addin_func_names: Any = ... 80 | def __init__(self) -> None: ... 81 | logfile: Any = ... 82 | verbosity: Any = ... 83 | use_mmap: Any = ... 84 | encoding_override: Any = ... 85 | formatting_info: Any = ... 86 | on_demand: Any = ... 87 | ragged_rows: Any = ... 88 | stream_len: Any = ... 89 | base: int = ... 90 | def biff2_8_load(self, filename: Optional[Any] = ..., file_contents: Optional[Any] = ..., logfile: Any = ..., verbosity: int = ..., use_mmap: Any = ..., encoding_override: Optional[Any] = ..., formatting_info: bool = ..., on_demand: bool = ..., ragged_rows: bool = ...) -> None: ... 91 | xfcount: int = ... 92 | actualfmtcount: int = ... 93 | def initialise_format_info(self) -> None: ... 94 | def get2bytes(self): ... 95 | def get_record_parts(self): ... 96 | def get_record_parts_conditional(self, reqd_record: Any): ... 97 | def get_sheet(self, sh_number: Any, update_pos: bool = ...): ... 98 | def get_sheets(self) -> None: ... 99 | def fake_globals_get_sheet(self) -> None: ... 100 | def handle_boundsheet(self, data: Any) -> None: ... 101 | def handle_builtinfmtcount(self, data: Any) -> None: ... 102 | def derive_encoding(self): ... 103 | def handle_codepage(self, data: Any) -> None: ... 104 | def handle_country(self, data: Any) -> None: ... 105 | def handle_datemode(self, data: Any) -> None: ... 106 | def handle_externname(self, data: Any) -> None: ... 107 | def handle_externsheet(self, data: Any) -> None: ... 108 | def handle_filepass(self, data: Any) -> None: ... 109 | def handle_name(self, data: Any) -> None: ... 110 | def names_epilogue(self) -> None: ... 111 | def handle_obj(self, data: Any) -> None: ... 112 | def handle_supbook(self, data: Any) -> None: ... 113 | def handle_sheethdr(self, data: Any) -> None: ... 114 | def handle_sheetsoffset(self, data: Any) -> None: ... 115 | def handle_sst(self, data: Any) -> None: ... 116 | def handle_writeaccess(self, data: Any) -> None: ... 117 | def parse_globals(self) -> None: ... 118 | def read(self, pos: Any, length: Any): ... 119 | def getbof(self, rqd_stream: Any): ... 120 | 121 | def expand_cell_address(inrow: Any, incol: Any): ... 122 | def colname(colx: Any, _A2Z: str = ...): ... 123 | def display_cell_address(rowx: Any, colx: Any, relrow: Any, relcol: Any): ... 124 | def unpack_SST_table(datatab: Any, nstrings: Any): ... 125 | -------------------------------------------------------------------------------- /stubs/xlrd/compdoc.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlrd.compdoc (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from .timemachine import * 6 | from typing import Any 7 | 8 | SIGNATURE: bytes 9 | EOCSID: int 10 | FREESID: int 11 | SATSID: int 12 | MSATSID: int 13 | EVILSID: int 14 | 15 | class CompDocError(Exception): ... 16 | 17 | class DirNode: 18 | DID: Any = ... 19 | logfile: Any = ... 20 | name: Any = ... 21 | children: Any = ... 22 | parent: int = ... 23 | tsinfo: Any = ... 24 | def __init__(self, DID: Any, dent: Any, DEBUG: int = ..., logfile: Any = ...) -> None: ... 25 | def dump(self, DEBUG: int = ...) -> None: ... 26 | 27 | class CompDoc: 28 | logfile: Any = ... 29 | DEBUG: Any = ... 30 | mem: Any = ... 31 | sec_size: Any = ... 32 | short_sec_size: Any = ... 33 | mem_data_secs: Any = ... 34 | mem_data_len: Any = ... 35 | SAT: Any = ... 36 | dirlist: Any = ... 37 | SSCS: str = ... 38 | SSAT: Any = ... 39 | def __init__(self, mem: Any, logfile: Any = ..., DEBUG: int = ...) -> None: ... 40 | def get_named_stream(self, qname: Any): ... 41 | def locate_named_stream(self, qname: Any): ... 42 | 43 | def x_dump_line(alist: Any, stride: Any, f: Any, dpos: Any, equal: int = ...) -> None: ... 44 | def dump_list(alist: Any, stride: Any, f: Any = ...) -> None: ... 45 | -------------------------------------------------------------------------------- /stubs/xlrd/formatting.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlrd.formatting (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from .timemachine import * 6 | from .biffh import BaseObject 7 | from typing import Any 8 | 9 | DEBUG: int 10 | excel_default_palette_b5: Any 11 | excel_default_palette_b2: Any 12 | excel_default_palette_b8: Any 13 | default_palette: Any 14 | built_in_style_names: Any 15 | 16 | def initialise_colour_map(book: Any) -> None: ... 17 | def nearest_colour_index(colour_map: Any, rgb: Any, debug: int = ...): ... 18 | 19 | class EqNeAttrs: 20 | def __eq__(self, other: Any): ... 21 | def __ne__(self, other: Any): ... 22 | 23 | class Font(BaseObject, EqNeAttrs): 24 | bold: int = ... 25 | character_set: int = ... 26 | colour_index: int = ... 27 | escapement: int = ... 28 | family: int = ... 29 | font_index: int = ... 30 | height: int = ... 31 | italic: int = ... 32 | name: Any = ... 33 | struck_out: int = ... 34 | underline_type: int = ... 35 | underlined: int = ... 36 | weight: int = ... 37 | outline: int = ... 38 | shadow: int = ... 39 | 40 | def handle_efont(book: Any, data: Any) -> None: ... 41 | def handle_font(book: Any, data: Any) -> None: ... 42 | 43 | class Format(BaseObject, EqNeAttrs): 44 | format_key: int = ... 45 | type: Any = ... 46 | format_str: Any = ... 47 | def __init__(self, format_key: Any, ty: Any, format_str: Any) -> None: ... 48 | 49 | std_format_strings: Any 50 | fmt_code_ranges: Any 51 | std_format_code_types: Any 52 | date_chars: Any 53 | date_char_dict: Any 54 | skip_char_dict: Any 55 | num_char_dict: Any 56 | non_date_formats: Any 57 | fmt_bracketed_sub: Any 58 | 59 | def is_date_format_string(book: Any, fmt: Any): ... 60 | def handle_format(self, data: Any, rectype: Any = ...) -> None: ... 61 | def handle_palette(book: Any, data: Any) -> None: ... 62 | def palette_epilogue(book: Any) -> None: ... 63 | def handle_style(book: Any, data: Any) -> None: ... 64 | def check_colour_indexes_in_obj(book: Any, obj: Any, orig_index: Any) -> None: ... 65 | def fill_in_standard_formats(book: Any) -> None: ... 66 | def handle_xf(self, data: Any) -> None: ... 67 | def xf_epilogue(self) -> None: ... 68 | def initialise_book(book: Any) -> None: ... 69 | 70 | class XFBorder(BaseObject, EqNeAttrs): 71 | top_colour_index: int = ... 72 | bottom_colour_index: int = ... 73 | left_colour_index: int = ... 74 | right_colour_index: int = ... 75 | diag_colour_index: int = ... 76 | top_line_style: int = ... 77 | bottom_line_style: int = ... 78 | left_line_style: int = ... 79 | right_line_style: int = ... 80 | diag_line_style: int = ... 81 | diag_down: int = ... 82 | diag_up: int = ... 83 | 84 | class XFBackground(BaseObject, EqNeAttrs): 85 | fill_pattern: int = ... 86 | background_colour_index: int = ... 87 | pattern_colour_index: int = ... 88 | 89 | class XFAlignment(BaseObject, EqNeAttrs): 90 | hor_align: int = ... 91 | vert_align: int = ... 92 | rotation: int = ... 93 | text_wrapped: int = ... 94 | indent_level: int = ... 95 | shrink_to_fit: int = ... 96 | text_direction: int = ... 97 | 98 | class XFProtection(BaseObject, EqNeAttrs): 99 | cell_locked: int = ... 100 | formula_hidden: int = ... 101 | 102 | class XF(BaseObject): 103 | is_style: int = ... 104 | parent_style_index: int = ... 105 | xf_index: int = ... 106 | font_index: int = ... 107 | format_key: int = ... 108 | protection: Any = ... 109 | background: Any = ... 110 | alignment: Any = ... 111 | border: Any = ... 112 | -------------------------------------------------------------------------------- /stubs/xlrd/formula.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlrd.formula (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from .timemachine import * 6 | from typing import Any, Optional 7 | 8 | FMLA_TYPE_CELL: int 9 | FMLA_TYPE_SHARED: int 10 | FMLA_TYPE_ARRAY: int 11 | FMLA_TYPE_COND_FMT: int 12 | FMLA_TYPE_DATA_VAL: int 13 | FMLA_TYPE_NAME: int 14 | oBOOL: int 15 | oERR: int 16 | oNUM: int 17 | oREF: int 18 | oREL: int 19 | oSTRG: int 20 | oUNK: int 21 | okind_dict: Any 22 | 23 | class FormulaError(Exception): ... 24 | 25 | class Operand: 26 | value: Any = ... 27 | kind: Any = ... 28 | text: str = ... 29 | rank: Any = ... 30 | def __init__(self, akind: Optional[Any] = ..., avalue: Optional[Any] = ..., arank: int = ..., atext: str = ...) -> None: ... 31 | 32 | class Ref3D(tuple): 33 | coords: Any = ... 34 | relflags: Any = ... 35 | def __init__(self, atuple: Any) -> None: ... 36 | 37 | def evaluate_name_formula(bk: Any, nobj: Any, namex: Any, blah: int = ..., level: int = ...) -> None: ... 38 | def decompile_formula(bk: Any, fmla: Any, fmlalen: Any, fmlatype: Optional[Any] = ..., browx: Optional[Any] = ..., bcolx: Optional[Any] = ..., blah: int = ..., level: int = ..., r1c1: int = ...): ... 39 | def dump_formula(bk: Any, data: Any, fmlalen: Any, bv: Any, reldelta: Any, blah: int = ..., isname: int = ...) -> None: ... 40 | def cellname(rowx: Any, colx: Any): ... 41 | def cellnameabs(rowx: Any, colx: Any, r1c1: int = ...): ... 42 | def colname(colx: Any): ... 43 | def rangename3d(book: Any, ref3d: Any): ... 44 | def rangename3drel(book: Any, ref3d: Any, browx: Optional[Any] = ..., bcolx: Optional[Any] = ..., r1c1: int = ...): ... 45 | -------------------------------------------------------------------------------- /stubs/xlrd/info.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlrd.info (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | __VERSION__: str 6 | -------------------------------------------------------------------------------- /stubs/xlrd/sheet.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlrd.sheet (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from .biffh import * 6 | from .timemachine import * 7 | from typing import Any, Optional 8 | 9 | DEBUG: int 10 | OBJ_MSO_DEBUG: int 11 | 12 | class Sheet(BaseObject): 13 | name: str = ... 14 | book: Any = ... 15 | nrows: int = ... 16 | ncols: int = ... 17 | colinfo_map: Any = ... 18 | rowinfo_map: Any = ... 19 | col_label_ranges: Any = ... 20 | row_label_ranges: Any = ... 21 | merged_cells: Any = ... 22 | rich_text_runlist_map: Any = ... 23 | defcolwidth: Any = ... 24 | standardwidth: Any = ... 25 | default_row_height: Any = ... 26 | default_row_height_mismatch: Any = ... 27 | default_row_hidden: Any = ... 28 | default_additional_space_above: Any = ... 29 | default_additional_space_below: Any = ... 30 | visibility: int = ... 31 | gcw: Any = ... 32 | hyperlink_list: Any = ... 33 | hyperlink_map: Any = ... 34 | cell_note_map: Any = ... 35 | vert_split_pos: int = ... 36 | horz_split_pos: int = ... 37 | horz_split_first_visible: int = ... 38 | vert_split_first_visible: int = ... 39 | split_active_pane: int = ... 40 | has_pane_record: int = ... 41 | horizontal_page_breaks: Any = ... 42 | vertical_page_breaks: Any = ... 43 | biff_version: Any = ... 44 | logfile: Any = ... 45 | bt: Any = ... 46 | bf: Any = ... 47 | number: Any = ... 48 | verbosity: Any = ... 49 | formatting_info: Any = ... 50 | ragged_rows: Any = ... 51 | put_cell: Any = ... 52 | first_visible_rowx: int = ... 53 | first_visible_colx: int = ... 54 | gridline_colour_index: int = ... 55 | gridline_colour_rgb: Any = ... 56 | cooked_page_break_preview_mag_factor: int = ... 57 | cooked_normal_view_mag_factor: int = ... 58 | cached_page_break_preview_mag_factor: int = ... 59 | cached_normal_view_mag_factor: int = ... 60 | scl_mag_factor: Any = ... 61 | utter_max_rows: int = ... 62 | utter_max_cols: int = ... 63 | def __init__(self, book: Any, position: Any, name: Any, number: Any) -> None: ... 64 | def cell(self, rowx: Any, colx: Any): ... 65 | def cell_value(self, rowx: Any, colx: Any): ... 66 | def cell_type(self, rowx: Any, colx: Any): ... 67 | def cell_xf_index(self, rowx: Any, colx: Any): ... 68 | def row_len(self, rowx: Any): ... 69 | def row(self, rowx: Any): ... 70 | def get_rows(self): ... 71 | def row_types(self, rowx: Any, start_colx: int = ..., end_colx: Optional[Any] = ...): ... 72 | def row_values(self, rowx: Any, start_colx: int = ..., end_colx: Optional[Any] = ...): ... 73 | def row_slice(self, rowx: Any, start_colx: int = ..., end_colx: Optional[Any] = ...): ... 74 | def col_slice(self, colx: Any, start_rowx: int = ..., end_rowx: Optional[Any] = ...): ... 75 | def col_values(self, colx: Any, start_rowx: int = ..., end_rowx: Optional[Any] = ...): ... 76 | def col_types(self, colx: Any, start_rowx: int = ..., end_rowx: Optional[Any] = ...): ... 77 | col: Any = ... 78 | def tidy_dimensions(self) -> None: ... 79 | def put_cell_ragged(self, rowx: Any, colx: Any, ctype: Any, value: Any, xf_index: Any) -> None: ... 80 | def put_cell_unragged(self, rowx: Any, colx: Any, ctype: Any, value: Any, xf_index: Any) -> None: ... 81 | def read(self, bk: Any): ... 82 | def string_record_contents(self, data: Any): ... 83 | def update_cooked_mag_factors(self) -> None: ... 84 | def fixed_BIFF2_xfindex(self, cell_attr: Any, rowx: Any, colx: Any, true_xfx: Optional[Any] = ...): ... 85 | def insert_new_BIFF20_xf(self, cell_attr: Any, style: int = ...): ... 86 | def fake_XF_from_BIFF20_cell_attr(self, cell_attr: Any, style: int = ...): ... 87 | def req_fmt_info(self) -> None: ... 88 | def computed_column_width(self, colx: Any): ... 89 | def handle_hlink(self, data: Any): ... 90 | def handle_quicktip(self, data: Any) -> None: ... 91 | def handle_msodrawingetc(self, recid: Any, data_len: Any, data: Any) -> None: ... 92 | def handle_obj(self, data: Any): ... 93 | def handle_note(self, data: Any, txos: Any) -> None: ... 94 | def handle_txo(self, data: Any): ... 95 | def handle_feat11(self, data: Any) -> None: ... 96 | 97 | class MSODrawing(BaseObject): ... 98 | class MSObj(BaseObject): ... 99 | class MSTxo(BaseObject): ... 100 | 101 | class Note(BaseObject): 102 | author: Any = ... 103 | col_hidden: int = ... 104 | colx: int = ... 105 | rich_text_runlist: Any = ... 106 | row_hidden: int = ... 107 | rowx: int = ... 108 | show: int = ... 109 | text: Any = ... 110 | 111 | class Hyperlink(BaseObject): 112 | frowx: Any = ... 113 | lrowx: Any = ... 114 | fcolx: Any = ... 115 | lcolx: Any = ... 116 | type: Any = ... 117 | url_or_path: Any = ... 118 | desc: Any = ... 119 | target: Any = ... 120 | textmark: Any = ... 121 | quicktip: Any = ... 122 | 123 | def unpack_RK(rk_str: Any): ... 124 | 125 | cellty_from_fmtty: Any 126 | ctype_text: Any 127 | 128 | class Cell(BaseObject): 129 | ctype: Any = ... 130 | value: Any = ... 131 | xf_index: Any = ... 132 | def __init__(self, ctype: Any, value: Any, xf_index: Optional[Any] = ...) -> None: ... 133 | 134 | empty_cell: Any 135 | 136 | class Colinfo(BaseObject): 137 | width: int = ... 138 | xf_index: int = ... 139 | hidden: int = ... 140 | bit1_flag: int = ... 141 | outline_level: int = ... 142 | collapsed: int = ... 143 | 144 | class Rowinfo(BaseObject): 145 | height: Any = ... 146 | has_default_height: Any = ... 147 | outline_level: Any = ... 148 | outline_group_starts_ends: Any = ... 149 | hidden: Any = ... 150 | height_mismatch: Any = ... 151 | has_default_xf_index: Any = ... 152 | xf_index: Any = ... 153 | additional_space_above: Any = ... 154 | additional_space_below: Any = ... 155 | def __init__(self) -> None: ... 156 | -------------------------------------------------------------------------------- /stubs/xlrd/timemachine.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlrd.timemachine (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from typing import Any 6 | 7 | python_version: Any 8 | BYTES_LITERAL: Any 9 | UNICODE_LITERAL: Any 10 | BYTES_ORD: Any 11 | 12 | def fprintf(f: Any, fmt: Any, *vargs: Any) -> None: ... 13 | 14 | EXCEL_TEXT_TYPES: Any 15 | REPR = ascii 16 | xrange = range 17 | unicode: Any 18 | ensure_unicode: Any 19 | unichr = chr 20 | -------------------------------------------------------------------------------- /stubs/xlrd/xldate.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlrd.xldate (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from typing import Any 6 | 7 | epoch_1904: Any 8 | epoch_1900: Any 9 | epoch_1900_minus_1: Any 10 | 11 | class XLDateError(ValueError): ... 12 | class XLDateNegative(XLDateError): ... 13 | class XLDateAmbiguous(XLDateError): ... 14 | class XLDateTooLarge(XLDateError): ... 15 | class XLDateBadDatemode(XLDateError): ... 16 | class XLDateBadTuple(XLDateError): ... 17 | 18 | def xldate_as_tuple(xldate: Any, datemode: Any): ... 19 | def xldate_as_datetime(xldate: Any, datemode: Any): ... 20 | def xldate_from_date_tuple(date_tuple: Any, datemode: Any): ... 21 | def xldate_from_time_tuple(time_tuple: Any): ... 22 | def xldate_from_datetime_tuple(datetime_tuple: Any, datemode: Any): ... 23 | -------------------------------------------------------------------------------- /stubs/xlrd/xlsx.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlrd.xlsx (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from .timemachine import * 6 | from typing import Any, Optional 7 | 8 | DEBUG: int 9 | DLF: Any 10 | ET: Any 11 | ET_has_iterparse: bool 12 | Element_has_iter: bool 13 | 14 | def ensure_elementtree_imported(verbosity: Any, logfile: Any) -> None: ... 15 | def split_tag(tag: Any): ... 16 | def augment_keys(adict: Any, uri: Any) -> None: ... 17 | def cell_name_to_rowx_colx(cell_name: Any, letter_value: Any = ..., allow_no_col: bool = ...): ... 18 | 19 | error_code_from_text: Any 20 | U_SSML12: str 21 | U_ODREL: str 22 | U_PKGREL: str 23 | U_CP: str 24 | U_DC: str 25 | U_DCTERMS: str 26 | XML_SPACE_ATTR: str 27 | XML_WHITESPACE: str 28 | X12_MAX_ROWS: Any 29 | X12_MAX_COLS: Any 30 | V_TAG: Any 31 | F_TAG: Any 32 | IS_TAG: Any 33 | 34 | def unescape(s: Any, subber: Any = ..., repl: Any = ...): ... 35 | def cooked_text(self, elem: Any): ... 36 | def get_text_from_si_or_is(self, elem: Any, r_tag: Any = ..., t_tag: Any = ...): ... 37 | def map_attributes(amap: Any, elem: Any, obj: Any) -> None: ... 38 | def cnv_ST_Xstring(s: Any): ... 39 | def cnv_xsd_unsignedInt(s: Any): ... 40 | def cnv_xsd_boolean(s: Any): ... 41 | def make_name_access_maps(bk: Any) -> None: ... 42 | 43 | class X12General: 44 | tree: Any = ... 45 | def process_stream(self, stream: Any, heading: Optional[Any] = ...) -> None: ... 46 | def finish_off(self) -> None: ... 47 | def dump_elem(self, elem: Any) -> None: ... 48 | def dumpout(self, fmt: Any, *vargs: Any) -> None: ... 49 | 50 | class X12Book(X12General): 51 | bk: Any = ... 52 | logfile: Any = ... 53 | verbosity: Any = ... 54 | relid2path: Any = ... 55 | relid2reltype: Any = ... 56 | sheet_targets: Any = ... 57 | sheetIds: Any = ... 58 | def __init__(self, bk: Any, logfile: Any = ..., verbosity: bool = ...) -> None: ... 59 | core_props_menu: Any = ... 60 | tree: Any = ... 61 | def process_coreprops(self, stream: Any) -> None: ... 62 | @staticmethod 63 | def convert_filename(name: Any): ... 64 | def process_rels(self, stream: Any) -> None: ... 65 | def do_defined_name(self, elem: Any) -> None: ... 66 | def do_defined_names(self, elem: Any) -> None: ... 67 | def do_sheet(self, elem: Any) -> None: ... 68 | def do_workbookpr(self, elem: Any) -> None: ... 69 | tag2meth: Any = ... 70 | 71 | class X12SST(X12General): 72 | bk: Any = ... 73 | logfile: Any = ... 74 | verbosity: Any = ... 75 | process_stream: Any = ... 76 | def __init__(self, bk: Any, logfile: Any = ..., verbosity: int = ...) -> None: ... 77 | def process_stream_iterparse(self, stream: Any, heading: Optional[Any] = ...) -> None: ... 78 | tree: Any = ... 79 | def process_stream_findall(self, stream: Any, heading: Optional[Any] = ...) -> None: ... 80 | 81 | class X12Styles(X12General): 82 | bk: Any = ... 83 | logfile: Any = ... 84 | verbosity: Any = ... 85 | xf_counts: Any = ... 86 | xf_type: Any = ... 87 | fmt_is_date: Any = ... 88 | def __init__(self, bk: Any, logfile: Any = ..., verbosity: int = ...) -> None: ... 89 | def do_cellstylexfs(self, elem: Any) -> None: ... 90 | def do_cellxfs(self, elem: Any) -> None: ... 91 | def do_numfmt(self, elem: Any) -> None: ... 92 | def do_xf(self, elem: Any) -> None: ... 93 | tag2meth: Any = ... 94 | 95 | class X12Sheet(X12General): 96 | sheet: Any = ... 97 | logfile: Any = ... 98 | verbosity: Any = ... 99 | rowx: int = ... 100 | bk: Any = ... 101 | sst: Any = ... 102 | relid2path: Any = ... 103 | relid2reltype: Any = ... 104 | merged_cells: Any = ... 105 | warned_no_cell_name: int = ... 106 | warned_no_row_num: int = ... 107 | process_stream: Any = ... 108 | def __init__(self, sheet: Any, logfile: Any = ..., verbosity: int = ...) -> None: ... 109 | def own_process_stream(self, stream: Any, heading: Optional[Any] = ...) -> None: ... 110 | def process_rels(self, stream: Any) -> None: ... 111 | def process_comments_stream(self, stream: Any) -> None: ... 112 | def do_dimension(self, elem: Any) -> None: ... 113 | def do_merge_cell(self, elem: Any) -> None: ... 114 | def do_row(self, row_elem: Any) -> None: ... 115 | tag2meth: Any = ... 116 | 117 | def open_workbook_2007_xml(zf: Any, component_names: Any, logfile: Any = ..., verbosity: int = ..., use_mmap: int = ..., formatting_info: int = ..., on_demand: int = ..., ragged_rows: int = ...): ... 118 | -------------------------------------------------------------------------------- /stubs/xlwt/Bitmap.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlwt.Bitmap (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from .BIFFRecords import BiffRecord 6 | from typing import Any 7 | 8 | class ObjBmpRecord(BiffRecord): 9 | def __init__(self, row: Any, col: Any, sheet: Any, im_data_bmp: Any, x: Any, y: Any, scale_x: Any, scale_y: Any) -> None: ... 10 | 11 | class ImRawDataBmpRecord(BiffRecord): 12 | def __init__(self, data: Any) -> None: ... 13 | 14 | class ImDataBmpRecord(ImRawDataBmpRecord): 15 | def __init__(self, filename: Any) -> None: ... 16 | -------------------------------------------------------------------------------- /stubs/xlwt/Cell.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlwt.Cell (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from typing import Any 6 | 7 | class StrCell: 8 | rowx: Any = ... 9 | colx: Any = ... 10 | xf_idx: Any = ... 11 | sst_idx: Any = ... 12 | def __init__(self, rowx: Any, colx: Any, xf_idx: Any, sst_idx: Any) -> None: ... 13 | def get_biff_data(self): ... 14 | 15 | class BlankCell: 16 | rowx: Any = ... 17 | colx: Any = ... 18 | xf_idx: Any = ... 19 | def __init__(self, rowx: Any, colx: Any, xf_idx: Any) -> None: ... 20 | def get_biff_data(self): ... 21 | 22 | class MulBlankCell: 23 | rowx: Any = ... 24 | colx1: Any = ... 25 | colx2: Any = ... 26 | xf_idx: Any = ... 27 | def __init__(self, rowx: Any, colx1: Any, colx2: Any, xf_idx: Any) -> None: ... 28 | def get_biff_data(self): ... 29 | 30 | class NumberCell: 31 | rowx: Any = ... 32 | colx: Any = ... 33 | xf_idx: Any = ... 34 | number: Any = ... 35 | def __init__(self, rowx: Any, colx: Any, xf_idx: Any, number: Any) -> None: ... 36 | def get_encoded_data(self): ... 37 | def get_biff_data(self): ... 38 | 39 | class BooleanCell: 40 | rowx: Any = ... 41 | colx: Any = ... 42 | xf_idx: Any = ... 43 | number: Any = ... 44 | def __init__(self, rowx: Any, colx: Any, xf_idx: Any, number: Any) -> None: ... 45 | def get_biff_data(self): ... 46 | 47 | error_code_map: Any 48 | 49 | class ErrorCell: 50 | rowx: Any = ... 51 | colx: Any = ... 52 | xf_idx: Any = ... 53 | number: Any = ... 54 | def __init__(self, rowx: Any, colx: Any, xf_idx: Any, error_string_or_code: Any) -> None: ... 55 | def get_biff_data(self): ... 56 | 57 | class FormulaCell: 58 | rowx: Any = ... 59 | colx: Any = ... 60 | xf_idx: Any = ... 61 | frmla: Any = ... 62 | calc_flags: Any = ... 63 | def __init__(self, rowx: Any, colx: Any, xf_idx: Any, frmla: Any, calc_flags: int = ...) -> None: ... 64 | def get_biff_data(self): ... 65 | -------------------------------------------------------------------------------- /stubs/xlwt/Column.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlwt.Column (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from typing import Any 6 | 7 | class Column: 8 | width: int = ... 9 | hidden: int = ... 10 | level: int = ... 11 | collapse: int = ... 12 | user_set: int = ... 13 | best_fit: int = ... 14 | unused: int = ... 15 | def __init__(self, colx: Any, parent_sheet: Any) -> None: ... 16 | def set_width(self, width: Any) -> None: ... 17 | def get_width(self): ... 18 | def set_style(self, style: Any) -> None: ... 19 | def width_in_pixels(self): ... 20 | def get_biff_record(self): ... 21 | -------------------------------------------------------------------------------- /stubs/xlwt/CompoundDoc.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlwt.CompoundDoc (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from typing import Any 6 | 7 | class XlsDoc: 8 | SECTOR_SIZE: int = ... 9 | MIN_LIMIT: int = ... 10 | SID_FREE_SECTOR: int = ... 11 | SID_END_OF_CHAIN: int = ... 12 | SID_USED_BY_SAT: int = ... 13 | SID_USED_BY_MSAT: int = ... 14 | book_stream_sect: Any = ... 15 | dir_stream: str = ... 16 | dir_stream_sect: Any = ... 17 | packed_SAT: str = ... 18 | SAT_sect: Any = ... 19 | packed_MSAT_1st: str = ... 20 | packed_MSAT_2nd: str = ... 21 | MSAT_sect_2nd: Any = ... 22 | header: str = ... 23 | def __init__(self) -> None: ... 24 | book_stream_len: Any = ... 25 | def save(self, file_name_or_filelike_obj: Any, stream: Any) -> None: ... 26 | -------------------------------------------------------------------------------- /stubs/xlwt/ExcelFormula.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlwt.ExcelFormula (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from typing import Any 6 | 7 | class Formula: 8 | def __init__(self, s: Any) -> None: ... 9 | def get_references(self): ... 10 | def patch_references(self, patches: Any) -> None: ... 11 | def text(self): ... 12 | def rpn(self): ... 13 | -------------------------------------------------------------------------------- /stubs/xlwt/ExcelFormulaLexer.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlwt.ExcelFormulaLexer (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from .antlr import TokenStream 6 | from typing import Any 7 | 8 | int_const_pattern: str 9 | flt_const_pattern: str 10 | str_const_pattern: str 11 | ref2d_r1c1_pattern: str 12 | ref2d_pattern: str 13 | true_pattern: str 14 | false_pattern: str 15 | if_pattern: str 16 | choose_pattern: str 17 | name_pattern: str 18 | quotename_pattern: str 19 | ne_pattern: str 20 | ge_pattern: str 21 | le_pattern: str 22 | pattern_type_tuples: Any 23 | single_char_lookup: Any 24 | 25 | class Lexer(TokenStream): 26 | def __init__(self, text: Any) -> None: ... 27 | def isEOF(self): ... 28 | def curr_ch(self): ... 29 | def next_ch(self, n: int = ...) -> None: ... 30 | def is_whitespace(self): ... 31 | def match_pattern(self): ... 32 | def nextToken(self): ... 33 | -------------------------------------------------------------------------------- /stubs/xlwt/ExcelFormulaParser.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlwt.ExcelFormulaParser (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from .ExcelMagic import * 6 | from . import antlr 7 | from typing import Any 8 | 9 | class FormulaParseException(Exception): ... 10 | 11 | SKIP: Any 12 | INVALID_TYPE: Any 13 | EOF_TYPE: Any 14 | EOF: Any 15 | NULL_TREE_LOOKAHEAD: Any 16 | MIN_USER_TYPE: Any 17 | TRUE_CONST: int 18 | FALSE_CONST: int 19 | STR_CONST: int 20 | NUM_CONST: int 21 | INT_CONST: int 22 | FUNC_IF: int 23 | FUNC_CHOOSE: int 24 | NAME: int 25 | QUOTENAME: int 26 | EQ: int 27 | NE: int 28 | GT: int 29 | LT: int 30 | GE: int 31 | LE: int 32 | ADD: int 33 | SUB: int 34 | MUL: int 35 | DIV: int 36 | POWER: int 37 | PERCENT: int 38 | LP: int 39 | RP: int 40 | LB: int 41 | RB: int 42 | COLON: int 43 | COMMA: int 44 | SEMICOLON: int 45 | REF2D: int 46 | REF2D_R1C1: int 47 | BANG: int 48 | CONCAT: int 49 | 50 | class Parser(antlr.LLkParser): 51 | tokenNames: Any = ... 52 | rpn: bytes = ... 53 | sheet_references: Any = ... 54 | xcall_references: Any = ... 55 | def __init__(self, *args: Any, **kwargs: Any) -> None: ... 56 | def formula(self) -> None: ... 57 | def expr(self, arg_type: Any) -> None: ... 58 | def prec0_expr(self, arg_type: Any) -> None: ... 59 | def prec1_expr(self, arg_type: Any) -> None: ... 60 | def prec2_expr(self, arg_type: Any) -> None: ... 61 | def prec3_expr(self, arg_type: Any) -> None: ... 62 | def prec4_expr(self, arg_type: Any) -> None: ... 63 | def prec5_expr(self, arg_type: Any) -> None: ... 64 | def primary(self, arg_type: Any) -> None: ... 65 | def sheet(self): ... 66 | def expr_list(self, arg_type_list: Any, min_argc: Any, max_argc: Any): ... 67 | 68 | def mk_tokenSet_0(): ... 69 | -------------------------------------------------------------------------------- /stubs/xlwt/ExcelMagic.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlwt.ExcelMagic (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from typing import Any 6 | 7 | MAX_ROW: int 8 | MAX_COL: int 9 | biff_records: Any 10 | all_funcs_by_name: Any 11 | ptgExp: int 12 | ptgTbl: int 13 | ptgAdd: int 14 | ptgSub: int 15 | ptgMul: int 16 | ptgDiv: int 17 | ptgPower: int 18 | ptgConcat: int 19 | ptgLT: int 20 | ptgLE: int 21 | ptgEQ: int 22 | ptgGE: int 23 | ptgGT: int 24 | ptgNE: int 25 | ptgIsect: int 26 | ptgUnion: int 27 | ptgRange: int 28 | ptgUplus: int 29 | ptgUminus: int 30 | ptgPercent: int 31 | ptgParen: int 32 | ptgMissArg: int 33 | ptgStr: int 34 | ptgExtend: int 35 | ptgAttr: int 36 | ptgSheet: int 37 | ptgEndSheet: int 38 | ptgErr: int 39 | ptgBool: int 40 | ptgInt: int 41 | ptgNum: int 42 | ptgArrayR: int 43 | ptgFuncR: int 44 | ptgFuncVarR: int 45 | ptgNameR: int 46 | ptgRefR: int 47 | ptgAreaR: int 48 | ptgMemAreaR: int 49 | ptgMemErrR: int 50 | ptgMemNoMemR: int 51 | ptgMemFuncR: int 52 | ptgRefErrR: int 53 | ptgAreaErrR: int 54 | ptgRefNR: int 55 | ptgAreaNR: int 56 | ptgMemAreaNR: int 57 | ptgMemNoMemNR: int 58 | ptgNameXR: int 59 | ptgRef3dR: int 60 | ptgArea3dR: int 61 | ptgRefErr3dR: int 62 | ptgAreaErr3dR: int 63 | ptgArrayV: int 64 | ptgFuncV: int 65 | ptgFuncVarV: int 66 | ptgNameV: int 67 | ptgRefV: int 68 | ptgAreaV: int 69 | ptgMemAreaV: int 70 | ptgMemErrV: int 71 | ptgMemNoMemV: int 72 | ptgMemFuncV: int 73 | ptgRefErrV: int 74 | ptgAreaErrV: int 75 | ptgRefNV: int 76 | ptgAreaNV: int 77 | ptgMemAreaNV: int 78 | ptgMemNoMemNV: int 79 | ptgFuncCEV: int 80 | ptgNameXV: int 81 | ptgRef3dV: int 82 | ptgArea3dV: int 83 | ptgRefErr3dV: int 84 | ptgAreaErr3dV: int 85 | ptgArrayA: int 86 | ptgFuncA: int 87 | ptgFuncVarA: int 88 | ptgNameA: int 89 | ptgRefA: int 90 | ptgAreaA: int 91 | ptgMemAreaA: int 92 | ptgMemErrA: int 93 | ptgMemNoMemA: int 94 | ptgMemFuncA: int 95 | ptgRefErrA: int 96 | ptgAreaErrA: int 97 | ptgRefNA: int 98 | ptgAreaNA: int 99 | ptgMemAreaNA: int 100 | ptgMemNoMemNA: int 101 | ptgFuncCEA: int 102 | ptgNameXA: int 103 | ptgRef3dA: int 104 | ptgArea3dA: int 105 | ptgRefErr3dA: int 106 | ptgAreaErr3dA: int 107 | PtgNames: Any 108 | error_msg_by_code: Any 109 | -------------------------------------------------------------------------------- /stubs/xlwt/Formatting.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlwt.Formatting (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from typing import Any 6 | 7 | class Font: 8 | ESCAPEMENT_NONE: int = ... 9 | ESCAPEMENT_SUPERSCRIPT: int = ... 10 | ESCAPEMENT_SUBSCRIPT: int = ... 11 | UNDERLINE_NONE: int = ... 12 | UNDERLINE_SINGLE: int = ... 13 | UNDERLINE_SINGLE_ACC: int = ... 14 | UNDERLINE_DOUBLE: int = ... 15 | UNDERLINE_DOUBLE_ACC: int = ... 16 | FAMILY_NONE: int = ... 17 | FAMILY_ROMAN: int = ... 18 | FAMILY_SWISS: int = ... 19 | FAMILY_MODERN: int = ... 20 | FAMILY_SCRIPT: int = ... 21 | FAMILY_DECORATIVE: int = ... 22 | CHARSET_ANSI_LATIN: int = ... 23 | CHARSET_SYS_DEFAULT: int = ... 24 | CHARSET_SYMBOL: int = ... 25 | CHARSET_APPLE_ROMAN: int = ... 26 | CHARSET_ANSI_JAP_SHIFT_JIS: int = ... 27 | CHARSET_ANSI_KOR_HANGUL: int = ... 28 | CHARSET_ANSI_KOR_JOHAB: int = ... 29 | CHARSET_ANSI_CHINESE_GBK: int = ... 30 | CHARSET_ANSI_CHINESE_BIG5: int = ... 31 | CHARSET_ANSI_GREEK: int = ... 32 | CHARSET_ANSI_TURKISH: int = ... 33 | CHARSET_ANSI_VIETNAMESE: int = ... 34 | CHARSET_ANSI_HEBREW: int = ... 35 | CHARSET_ANSI_ARABIC: int = ... 36 | CHARSET_ANSI_BALTIC: int = ... 37 | CHARSET_ANSI_CYRILLIC: int = ... 38 | CHARSET_ANSI_THAI: int = ... 39 | CHARSET_ANSI_LATIN_II: int = ... 40 | CHARSET_OEM_LATIN_I: int = ... 41 | height: int = ... 42 | italic: bool = ... 43 | struck_out: bool = ... 44 | outline: bool = ... 45 | shadow: bool = ... 46 | colour_index: int = ... 47 | bold: bool = ... 48 | escapement: Any = ... 49 | underline: Any = ... 50 | family: Any = ... 51 | charset: Any = ... 52 | name: str = ... 53 | def __init__(self) -> None: ... 54 | def get_biff_record(self): ... 55 | 56 | class Alignment: 57 | HORZ_GENERAL: int = ... 58 | HORZ_LEFT: int = ... 59 | HORZ_CENTER: int = ... 60 | HORZ_RIGHT: int = ... 61 | HORZ_FILLED: int = ... 62 | HORZ_JUSTIFIED: int = ... 63 | HORZ_CENTER_ACROSS_SEL: int = ... 64 | HORZ_DISTRIBUTED: int = ... 65 | VERT_TOP: int = ... 66 | VERT_CENTER: int = ... 67 | VERT_BOTTOM: int = ... 68 | VERT_JUSTIFIED: int = ... 69 | VERT_DISTRIBUTED: int = ... 70 | DIRECTION_GENERAL: int = ... 71 | DIRECTION_LR: int = ... 72 | DIRECTION_RL: int = ... 73 | ORIENTATION_NOT_ROTATED: int = ... 74 | ORIENTATION_STACKED: int = ... 75 | ORIENTATION_90_CC: int = ... 76 | ORIENTATION_90_CW: int = ... 77 | ROTATION_0_ANGLE: int = ... 78 | ROTATION_STACKED: int = ... 79 | WRAP_AT_RIGHT: int = ... 80 | NOT_WRAP_AT_RIGHT: int = ... 81 | SHRINK_TO_FIT: int = ... 82 | NOT_SHRINK_TO_FIT: int = ... 83 | horz: Any = ... 84 | vert: Any = ... 85 | dire: Any = ... 86 | orie: Any = ... 87 | rota: Any = ... 88 | wrap: Any = ... 89 | shri: Any = ... 90 | inde: int = ... 91 | merg: int = ... 92 | def __init__(self) -> None: ... 93 | 94 | class Borders: 95 | NO_LINE: int = ... 96 | THIN: int = ... 97 | MEDIUM: int = ... 98 | DASHED: int = ... 99 | DOTTED: int = ... 100 | THICK: int = ... 101 | DOUBLE: int = ... 102 | HAIR: int = ... 103 | MEDIUM_DASHED: int = ... 104 | THIN_DASH_DOTTED: int = ... 105 | MEDIUM_DASH_DOTTED: int = ... 106 | THIN_DASH_DOT_DOTTED: int = ... 107 | MEDIUM_DASH_DOT_DOTTED: int = ... 108 | SLANTED_MEDIUM_DASH_DOTTED: int = ... 109 | NEED_DIAG1: int = ... 110 | NEED_DIAG2: int = ... 111 | NO_NEED_DIAG1: int = ... 112 | NO_NEED_DIAG2: int = ... 113 | left: Any = ... 114 | right: Any = ... 115 | top: Any = ... 116 | bottom: Any = ... 117 | diag: Any = ... 118 | left_colour: int = ... 119 | right_colour: int = ... 120 | top_colour: int = ... 121 | bottom_colour: int = ... 122 | diag_colour: int = ... 123 | need_diag1: Any = ... 124 | need_diag2: Any = ... 125 | def __init__(self) -> None: ... 126 | 127 | class Pattern: 128 | NO_PATTERN: int = ... 129 | SOLID_PATTERN: int = ... 130 | pattern: Any = ... 131 | pattern_fore_colour: int = ... 132 | pattern_back_colour: int = ... 133 | def __init__(self) -> None: ... 134 | 135 | class Protection: 136 | cell_locked: int = ... 137 | formula_hidden: int = ... 138 | def __init__(self) -> None: ... 139 | -------------------------------------------------------------------------------- /stubs/xlwt/Row.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlwt.Row (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from typing import Any 6 | 7 | class Row: 8 | height: int = ... 9 | has_default_height: int = ... 10 | height_mismatch: int = ... 11 | level: int = ... 12 | collapse: int = ... 13 | hidden: int = ... 14 | space_above: int = ... 15 | space_below: int = ... 16 | def __init__(self, rowx: Any, parent_sheet: Any) -> None: ... 17 | def get_height_in_pixels(self): ... 18 | def set_style(self, style: Any) -> None: ... 19 | def get_xf_index(self): ... 20 | def get_cells_count(self): ... 21 | def get_min_col(self): ... 22 | def get_max_col(self): ... 23 | def get_row_biff_data(self): ... 24 | def insert_cell(self, col_index: Any, cell_obj: Any) -> None: ... 25 | def insert_mulcells(self, colx1: Any, colx2: Any, cell_obj: Any) -> None: ... 26 | def get_cells_biff_data(self): ... 27 | def get_index(self): ... 28 | def set_cell_text(self, colx: Any, value: Any, style: Any = ...) -> None: ... 29 | def set_cell_blank(self, colx: Any, style: Any = ...) -> None: ... 30 | def set_cell_mulblanks(self, first_colx: Any, last_colx: Any, style: Any = ...) -> None: ... 31 | def set_cell_number(self, colx: Any, number: Any, style: Any = ...) -> None: ... 32 | def set_cell_date(self, colx: Any, datetime_obj: Any, style: Any = ...) -> None: ... 33 | def set_cell_formula(self, colx: Any, formula: Any, style: Any = ..., calc_flags: int = ...) -> None: ... 34 | def set_cell_boolean(self, colx: Any, value: Any, style: Any = ...) -> None: ... 35 | def set_cell_error(self, colx: Any, error_string_or_code: Any, style: Any = ...) -> None: ... 36 | def write(self, col: Any, label: Any, style: Any = ...) -> None: ... 37 | def set_cell_rich_text(self, col: Any, rich_text_list: Any, style: Any = ...) -> None: ... 38 | write_blanks: Any = ... 39 | write_rich_text: Any = ... 40 | -------------------------------------------------------------------------------- /stubs/xlwt/Style.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlwt.Style (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from .Formatting import Font 6 | from typing import Any, Optional 7 | 8 | FIRST_USER_DEFINED_NUM_FORMAT_IDX: int 9 | 10 | class XFStyle: 11 | num_format_str: str = ... 12 | font: Any = ... 13 | alignment: Any = ... 14 | borders: Any = ... 15 | pattern: Any = ... 16 | protection: Any = ... 17 | def __init__(self) -> None: ... 18 | 19 | default_style: Any 20 | 21 | class StyleCollection: 22 | style_compression: Any = ... 23 | stats: Any = ... 24 | default_style: Any = ... 25 | def __init__(self, style_compression: int = ...) -> None: ... 26 | def add(self, style: Any): ... 27 | def add_font(self, font: Any): ... 28 | def get_biff_data(self): ... 29 | 30 | class EasyXFException(Exception): ... 31 | class EasyXFCallerError(EasyXFException): ... 32 | class EasyXFAuthorError(EasyXFException): ... 33 | 34 | class IntULim: 35 | limit: Any = ... 36 | def __init__(self, limit: Any) -> None: ... 37 | def __call__(self, astring: Any): ... 38 | 39 | bool_map: Any 40 | border_line_map: Any 41 | charset_map: Any 42 | colour_map: Any 43 | 44 | def add_palette_colour(colour_str: Any, colour_index: Any) -> None: ... 45 | 46 | excel_default_palette_b8: Any 47 | pattern_map: Any 48 | 49 | def any_str_func(s: Any): ... 50 | def colour_index_func(s: Any, maxval: int = ...): ... 51 | colour_index_func_7 = colour_index_func 52 | 53 | def colour_index_func_15(s: Any): ... 54 | def rotation_func(s: Any): ... 55 | 56 | xf_dict: Any 57 | 58 | def easyxf(strg_to_parse: str = ..., num_format_str: Optional[Any] = ..., field_sep: str = ..., line_sep: str = ..., intro_sep: str = ..., esc_char: str = ..., debug: bool = ...) -> XFStyle: ... 59 | def easyfont(strg_to_parse: str = ..., field_sep: str = ..., esc_char: str = ..., debug: bool = ...) -> Font: ... 60 | -------------------------------------------------------------------------------- /stubs/xlwt/UnicodeUtils.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlwt.UnicodeUtils (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from typing import Any 6 | 7 | def upack2(s: Any, encoding: str = ...): ... 8 | def upack2rt(rt: Any, encoding: str = ...): ... 9 | def upack1(s: Any, encoding: str = ...): ... 10 | -------------------------------------------------------------------------------- /stubs/xlwt/Utils.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlwt.Utils (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from typing import Any 6 | 7 | def col_by_name(colname: Any): ... 8 | def cell_to_rowcol(cell: Any): ... 9 | def cell_to_rowcol2(cell: Any): ... 10 | def rowcol_to_cell(row: Any, col: Any, row_abs: bool = ..., col_abs: bool = ...): ... 11 | def rowcol_pair_to_cellrange(row1: Any, col1: Any, row2: Any, col2: Any, row1_abs: bool = ..., col1_abs: bool = ..., row2_abs: bool = ..., col2_abs: bool = ...): ... 12 | def cellrange_to_rowcol_pair(cellrange: Any): ... 13 | def cell_to_packed_rowcol(cell: Any): ... 14 | def valid_sheet_name(sheet_name: Any): ... 15 | def quote_sheet_name(unquoted_sheet_name: Any): ... 16 | -------------------------------------------------------------------------------- /stubs/xlwt/Workbook.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlwt.Workbook (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from typing import Any 6 | from .Worksheet import Worksheet 7 | 8 | class Workbook: 9 | encoding: Any = ... 10 | def __init__(self, encoding: str = ..., style_compression: int = ...) -> None: ... 11 | def get_style_stats(self): ... 12 | def set_owner(self, value: Any) -> None: ... 13 | def get_owner(self): ... 14 | owner: Any = ... 15 | def set_country_code(self, value: Any) -> None: ... 16 | def get_country_code(self): ... 17 | country_code: Any = ... 18 | def set_wnd_protect(self, value: Any) -> None: ... 19 | def get_wnd_protect(self): ... 20 | wnd_protect: Any = ... 21 | def set_obj_protect(self, value: Any) -> None: ... 22 | def get_obj_protect(self): ... 23 | obj_protect: Any = ... 24 | def set_protect(self, value: Any) -> None: ... 25 | def get_protect(self): ... 26 | protect: Any = ... 27 | def set_backup_on_save(self, value: Any) -> None: ... 28 | def get_backup_on_save(self): ... 29 | backup_on_save: Any = ... 30 | def set_hpos(self, value: Any) -> None: ... 31 | def get_hpos(self): ... 32 | hpos: Any = ... 33 | def set_vpos(self, value: Any) -> None: ... 34 | def get_vpos(self): ... 35 | vpos: Any = ... 36 | def set_width(self, value: Any) -> None: ... 37 | def get_width(self): ... 38 | width: Any = ... 39 | def set_height(self, value: Any) -> None: ... 40 | def get_height(self): ... 41 | height: Any = ... 42 | def set_active_sheet(self, value: Any) -> None: ... 43 | def get_active_sheet(self): ... 44 | active_sheet: Any = ... 45 | def set_tab_width(self, value: Any) -> None: ... 46 | def get_tab_width(self): ... 47 | tab_width: Any = ... 48 | def set_wnd_visible(self, value: Any) -> None: ... 49 | def get_wnd_visible(self): ... 50 | wnd_visible: Any = ... 51 | def set_wnd_mini(self, value: Any) -> None: ... 52 | def get_wnd_mini(self): ... 53 | wnd_mini: Any = ... 54 | def set_hscroll_visible(self, value: Any) -> None: ... 55 | def get_hscroll_visible(self): ... 56 | hscroll_visible: Any = ... 57 | def set_vscroll_visible(self, value: Any) -> None: ... 58 | def get_vscroll_visible(self): ... 59 | vscroll_visible: Any = ... 60 | def set_tabs_visible(self, value: Any) -> None: ... 61 | def get_tabs_visible(self): ... 62 | tabs_visible: Any = ... 63 | def set_dates_1904(self, value: Any) -> None: ... 64 | def get_dates_1904(self): ... 65 | dates_1904: Any = ... 66 | def set_use_cell_values(self, value: Any) -> None: ... 67 | def get_use_cell_values(self): ... 68 | use_cell_values: Any = ... 69 | def get_default_style(self): ... 70 | default_style: Any = ... 71 | def set_colour_RGB(self, colour_index: Any, red: Any, green: Any, blue: Any) -> None: ... 72 | def add_style(self, style: Any): ... 73 | def add_font(self, font: Any): ... 74 | def add_str(self, s: Any): ... 75 | def del_str(self, sst_idx: Any) -> None: ... 76 | def str_index(self, s: Any): ... 77 | def add_rt(self, rt: Any): ... 78 | def rt_index(self, rt: Any): ... 79 | def add_sheet(self, sheetname: str, cell_overwrite_ok: bool = ...) -> Worksheet: ... 80 | def get_sheet(self, sheet: Any): ... 81 | def sheet_index(self, sheetname: Any): ... 82 | def raise_bad_sheetname(self, sheetname: Any) -> None: ... 83 | def convert_sheetindex(self, strg_ref: Any, n_sheets: Any): ... 84 | def setup_ownbook(self) -> None: ... 85 | def setup_xcall(self) -> None: ... 86 | def add_sheet_reference(self, formula: Any) -> None: ... 87 | def get_biff_data(self): ... 88 | def save(self, filename_or_stream: Any) -> None: ... 89 | -------------------------------------------------------------------------------- /stubs/xlwt/__init__.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlwt (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from .Column import Column as Column 6 | from .Formatting import Alignment, Borders, Font, Pattern, Protection 7 | from .Row import Row as Row 8 | from .Style import XFStyle as XFStyle, easyfont as easyfont, easyxf as easyxf 9 | from .Workbook import Workbook as Workbook 10 | from .Worksheet import Worksheet as Worksheet 11 | 12 | 13 | __VERSION__: str 14 | -------------------------------------------------------------------------------- /stubs/xlwt/compat.pyi: -------------------------------------------------------------------------------- 1 | # Stubs for xlwt.compat (Python 3) 2 | # 3 | # NOTE: This dynamically typed stub was automatically generated by stubgen. 4 | 5 | from typing import Any 6 | 7 | PY3: Any 8 | unicode: Any 9 | unicode_type = str 10 | basestring = str 11 | xrange = range 12 | int_types: Any 13 | long = int 14 | 15 | -------------------------------------------------------------------------------- /tests/README: -------------------------------------------------------------------------------- 1 | The .sym file is the only original source at present. All others were 2 | generated from it by canmatrix itself. As they become available, original 3 | files of each formatted that exercise as many features as possible should 4 | be used to replace these dubious test files. 5 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/__init__.py -------------------------------------------------------------------------------- /tests/createTestFdMatrix.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | import codecs 4 | import sys 5 | sys.path.append('..') 6 | 7 | import canmatrix 8 | # 9 | # create target Matrix 10 | # 11 | 12 | db = canmatrix.CanMatrix() 13 | 14 | db.ecus.add(canmatrix.Ecu("testBU")) 15 | db.ecus.add(canmatrix.Ecu("recBU")) 16 | 17 | myFrame1 = canmatrix.Frame("canFdStandard1",Id=1, dlc=24, is_fd = True, transmitter=["testBU"]) 18 | myFrame2 = canmatrix.Frame("CanFdExtended2",Id=2, dlc=16, extended = True, is_fd = True, transmitter=["testBU"]) 19 | myFrame3 = canmatrix.Frame("CanExtended3", Id=3, dlc=8, extended = True, transmitter=["testBU"]) 20 | myFrame4 = canmatrix.Frame("CanStandard4", Id=4, dlc=8) 21 | 22 | mySignal1 = canmatrix.Signal("signal1", signalSize=64, startBit=0, is_little_endian=True, min=0, max=0, is_signed=True, receiver=["recBU"]) 23 | mySignal2 = canmatrix.Signal("signal2", signalSize=64, startBit=64, is_little_endian=True, min=0, max=0, is_signed=True, receiver=["recBU"]) 24 | mySignal3 = canmatrix.Signal("signal3", signalSize=64, startBit=128, is_little_endian=True, min=0, max=0, is_signed=True) 25 | 26 | myFrame1.add_signal(mySignal3) 27 | myFrame1.add_signal(mySignal2) 28 | myFrame1.add_signal(mySignal1) 29 | 30 | 31 | myFrame2.add_signal(mySignal2) 32 | myFrame2.add_signal(mySignal1) 33 | 34 | 35 | db.frames.add_frame(myFrame1) 36 | db.frames.add_frame(myFrame2) 37 | db.frames.add_frame(myFrame3) 38 | db.frames.add_frame(myFrame4) 39 | 40 | 41 | # 42 | # 43 | # export the new (target)-Matrix for example as .dbc: 44 | # 45 | 46 | canmatrix.formats.dumpp({"": db}, "testfd.dbc", dbcExportEncoding='iso-8859-1', 47 | dbcExportCommentEncoding='iso-8859-1') 48 | -------------------------------------------------------------------------------- /tests/createTestMatrix.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | import codecs 4 | import sys 5 | sys.path.append('..') 6 | 7 | import canmatrix.formats 8 | from canmatrix.canmatrix import * 9 | # 10 | # create target Matrix 11 | # 12 | 13 | db = CanMatrix() 14 | 15 | db.ecus.add(Ecu("testBU")) 16 | db.ecus.add(Ecu("recBU")) 17 | 18 | myFrame = Frame("testFrame1", Id=0x123, dlc=8, transmitter="testBU") 19 | 20 | unit = "specialCharUnit°$" 21 | comment = "Multi \n Line \n Signal comment with a-umlaut: ä" 22 | 23 | mySignal = Signal("someTestSignal", 24 | signalSize=11, 25 | is_little_endian=False, 26 | is_signed=False, 27 | factor=5.0, 28 | offset=1.0, 29 | min=0, 30 | max=500, 31 | unit=u"specialCharUnit°$", #.decode("utf-8"), 32 | receiver=["recBU"]) 33 | mySignal.set_startbit(9, bitNumbering=1, startLittle=True) 34 | mySignal2 = Signal("Signal", 35 | startBit=20, 36 | signalSize=3, 37 | is_little_endian=True, 38 | is_signed=False, 39 | factor=1.0, 40 | offset=0.0, 41 | min=0, 42 | max=6, 43 | unit="someUnit", 44 | receiver=["recBU"]) 45 | 46 | mySignal2.add_values(1, "one") 47 | mySignal2.add_values(2, "two") 48 | mySignal2.add_values(3, "three") 49 | 50 | mySignal.add_comment(comment) 51 | myFrame.add_comment("Multi \n Line \n Frame comment") 52 | 53 | myFrame.add_signal(mySignal) 54 | myFrame.add_signal(mySignal2) 55 | 56 | myFrame2 = Frame("extendedFrame", Id=0x12, dlc=8, transmitter="testBU") 57 | myFrame2.extended = 1 58 | 59 | db.frames.add_frame(myFrame) 60 | db.frames.add_frame(myFrame2) 61 | 62 | db.ecu_by_name("testBU").add_comment("sender ECU") 63 | db.ecu_by_name("testBU").add_attribute("NetworkNode", 0x111) 64 | db.ecu_by_name("recBU").add_comment("receiver ECU") 65 | 66 | db.frame_by_name("testFrame1").cycle_time = 100 67 | 68 | 69 | db.add_ecu_defines("NetworkNode", 'INT 0 65535') 70 | 71 | 72 | # 73 | # 74 | # export the new (target)-Matrix for example as .dbc: 75 | # 76 | 77 | canmatrix.formats.dumpp({"myMatrix": db}, "test.dbc", dbcExportEncoding='iso-8859-1', 78 | dbcExportCommentEncoding='iso-8859-1') 79 | -------------------------------------------------------------------------------- /tests/files/arxml/ARXMLCompuMethod1.arxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | New_Frame_NewPDU_NewSignal_Encoding 6 | SCALE_LINEAR_AND_TEXTTABLE 7 | 8 | 9 | 10 | 11 | 0 12 | 0 13 | 14 | no trailer detected 15 | 16 | 17 | 18 | 1 19 | 1 20 | 21 | trailer detected 22 | 23 | 24 | 25 | TrailerPresence 26 | 0 27 | 0 28 | 29 | 30 | 17 31 | 42 32 | 33 | 34 | 1 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /tests/files/dbc/aa.dbc: -------------------------------------------------------------------------------- 1 | VERSION "created by canmatrix" 2 | 3 | 4 | NS_ : 5 | 6 | BS_: 7 | 8 | BU_: PLC MotorValve 9 | 10 | 11 | BO_ 0 NMT_Out_Request: 2 PLC 12 | SG_ nmt_CMD : 0|8@1- (1,0) [-128|127] "" MotorValve 13 | SG_ Node_ID : 8|8@1- (1,0) [-128|127] "" MotorValve 14 | 15 | BO_ 1793 NMT_Response_Frame_In: 8 MotorValve 16 | SG_ NMT_Response_10 : 0|32@1- (1,0) [-2147483648|2147483647] "" PLC 17 | SG_ NMT_Response_11 : 32|32@1- (1,0) [-2147483648|2147483647] "" PLC 18 | 19 | BO_ 128 SYNC: 0 PLC 20 | 21 | BO_ 129 EMCY: 8 MotorValve 22 | SG_ EMCY_Error_Code : 0|16@1- (1,0) [-32768|32767] "" PLC 23 | SG_ E_Reg : 16|8@1- (1,0) [-128|127] "" PLC 24 | SG_ E_Number : 24|8@1- (1,0) [-128|127] "" PLC 25 | 26 | BO_ 1537 SDO_download: 8 MotorValve 27 | SG_ sdo_down_CMD M : 0|8@1- (1,0) [-128|127] "" PLC 28 | SG_ sdo_down_IDX : 8|16@1- (1,0) [-32768|32767] "" PLC 29 | SG_ sdo_down_SUBIDX : 24|8@1- (1,0) [-128|127] "" PLC 30 | SG_ data8 m47 : 32|8@1- (1,0) [-128|127] "" PLC 31 | SG_ data16 m43 : 32|16@1- (1,0) [-32768|32767] "" PLC 32 | SG_ data24 m39 : 32|24@1- (1,0) [-8388608|8388607] "" PLC 33 | SG_ data320 m35 : 32|32@1- (1,0) [-2147483648|2147483647] "" PLC 34 | SG_ data321 m67 : 32|32@1- (1,0) [-2147483648|2147483647] "" PLC 35 | 36 | BO_ 1409 SDO_upload: 8 PLC 37 | SG_ sdo_state M : 0|8@1- (1,0) [-128|127] "" MotorValve 38 | SG_ sdo_uo_IDX : 8|16@1- (1,0) [-32768|32767] "" MotorValve 39 | SG_ sdo_up_SUBIDX : 24|8@1- (1,0) [-128|127] "" MotorValve 40 | SG_ error_code m128 : 32|32@1- (1,0) [-2147483648|2147483647] "" MotorValve 41 | SG_ data8 m79 : 32|8@1- (1,0) [-128|127] "" PLC 42 | SG_ data16 m75 : 32|16@1- (1,0) [-32768|32767] "" PLC 43 | SG_ data24 m71 : 32|24@1- (1,0) [-8388608|8388607] "" PLC 44 | 45 | BO_ 513 Receive_PDO_Mapping_Parameter_0: 8 PLC 46 | SG_ CMDDigital : 0|32@1+ (1,0) [0|4294967295] "" MotorValve 47 | SG_ PVDigital : 32|32@1+ (1,0) [0|4294967295] "" MotorValve 48 | 49 | BO_ 769 Receive_PDO_Mapping_Parameter_1: 8 PLC 50 | SG_ SPDigital : 0|32@1+ (1,0) [0|4294967295] "" MotorValve 51 | 52 | BO_ 385 Receive_PDO_Mapping_Parameter_1: 8 MotorValve 53 | SG_ CMD_Raw : 0|32@1+ (1,0) [0|4294967295] "" PLC 54 | SG_ CMD_Display : 32|32@1+ (1,0) [0|4294967295] "" PLC 55 | 56 | BO_ 641 Transmit_PDO_Mapping_Parameter_0: 8 MotorValve 57 | SG_ POS_Measured : 0|32@1+ (1,0) [0|4294967295] "" PLC 58 | SG_ NamurStatus : 32|32@1+ (1,0) [0|4294967295] "" PLC 59 | 60 | BO_ 897 Transmit_PDO_Mapping_Parameter_1: 8 MotorValve 61 | SG_ SP : 0|32@1+ (1,0) [0|4294967295] "" PLC 62 | SG_ PV : 32|32@1+ (1,0) [0|4294967295] "" PLC 63 | 64 | BO_ 1153 Transmit_PDO_Mapping_Parameter_2: 8 MotorValve 65 | SG_ PDO_Mapping_Entry : 0|32@1+ (1,0) [0|4294967295] "" PLC 66 | SG_ PDO_Mapping_Entry_2 : 32|32@1+ (1,0) [0|4294967295] "" PLC 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | VAL_ 0 nmt_CMD 1 "switch to state \"Operational\"" 2 "switch to state \"Stop\"" 128 "switch to state \"Pre-Operational\"" 129 "Reset Node" 130 "Reset Communication"; 77 | VAL_ 1537 sdo_down_CMD 35 "4_bytes" 39 "3_bytes" 43 "16_bytes" 47 "8_bytes" 64 "upload_request"; 78 | VAL_ 1409 sdo_state 35 "4_bytes" 39 "3_bytes" 43 "16_bytes" 47 "8_bytes" 128 "upload_error"; 79 | -------------------------------------------------------------------------------- /tests/files/dbc/test.dbc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/files/dbc/test.dbc -------------------------------------------------------------------------------- /tests/files/dbc/test_frame_decoding.dbc: -------------------------------------------------------------------------------- 1 | VERSION "created by canmatrix" 2 | 3 | 4 | NS_ : 5 | 6 | 7 | BS_: 8 | 9 | BU_: CCL_TEST TEST_ECU 10 | 11 | 12 | BO_ 4 muxTestFrame: 7 TEST_ECU 13 | SG_ myMuxer M : 53|3@1+ (1,0) [0|0] "" CCL_TEST 14 | SG_ muxSig4 m0 : 25|7@1- (1,0) [0|0] "" CCL_TEST 15 | SG_ muxSig3 m0 : 16|9@1+ (1,0) [0|0] "" CCL_TEST 16 | SG_ muxSig2 m0 : 15|8@0- (1,0) [0|0] "" CCL_TEST 17 | SG_ muxSig1 m0 : 0|8@1- (1,0) [0|0] "" CCL_TEST 18 | SG_ muxSig5 m1 : 22|7@1- (1,0) [0|0] "" CCL_TEST 19 | SG_ muxSig6 m1 : 32|9@1+ (1,0) [0|0] "" CCL_TEST 20 | SG_ muxSig7 m1 : 2|8@0- (1,0) [0|0] "" CCL_TEST 21 | SG_ muxSig8 m1 : 0|6@1- (1,0) [0|0] "" CCL_TEST 22 | SG_ muxSig9 : 40|8@1- (1,0) [0|0] "" CCL_TEST 23 | 24 | BO_ 3 testFrameFloat: 8 TEST_ECU 25 | SG_ floatSignal2 : 32|32@1- (1,0) [0|0] "" CCL_TEST 26 | SG_ floatSignal1 : 7|32@0- (1,0) [0|0] "" CCL_TEST 27 | 28 | BO_ 1 testFrame1: 8 TEST_ECU 29 | SG_ sig0 : 1|2@0+ (1,0) [0|0] "" CCL_TEST 30 | SG_ sig1 : 7|6@0+ (1,0) [0|0] "" CCL_TEST 31 | SG_ sig2 : 15|11@0+ (1,0) [0|0] "" CCL_TEST 32 | SG_ sig3 : 20|12@0+ (1,0) [0|0] "" CCL_TEST 33 | SG_ sig4 : 24|9@0+ (1,0) [0|0] "" CCL_TEST 34 | SG_ sig5 : 50|3@0+ (1,0) [0|0] "" CCL_TEST 35 | SG_ sig6 : 53|3@0+ (1,0) [0|0] "" CCL_TEST 36 | SG_ sig7 : 47|10@0+ (1,0) [0|0] "" CCL_TEST 37 | SG_ sig8 : 58|3@0+ (1,0) [0|0] "" CCL_TEST 38 | SG_ sig9 : 61|3@0+ (1,0) [0|0] "" CCL_TEST 39 | SG_ sig10 : 63|2@0+ (1,0) [0|0] "" CCL_TEST 40 | 41 | BO_ 2 testFrame2: 8 TEST_ECU 42 | SG_ secSig1 : 60|2@1+ (1,0) [0|0] "" CCL_TEST 43 | SG_ secSig2 : 55|1@1+ (1,0) [0|0] "" CCL_TEST 44 | SG_ secSig3 : 20|4@1+ (1,0) [0|0] "" CCL_TEST 45 | SG_ secSig4 : 62|2@1+ (1,0) [0|0] "" CCL_TEST 46 | SG_ secSig5 : 34|3@1+ (1,0) [0|0] "" CCL_TEST 47 | SG_ secSig6 : 37|3@1+ (1,0) [0|0] "" CCL_TEST 48 | SG_ secSig7 : 59|1@1- (1,0) [0|0] "" CCL_TEST 49 | SG_ secSig8 : 56|3@1+ (1,0) [0|0] "" CCL_TEST 50 | SG_ secSig9 : 52|3@1+ (1,0) [0|0] "" CCL_TEST 51 | SG_ secSig10 : 8|12@1+ (1,0) [0|0] "" CCL_TEST 52 | SG_ secSig11 : 24|10@1- (1,0) [0|0] "" CCL_TEST 53 | SG_ secSig12 : 0|8@1+ (1,0) [0|0] "" CCL_TEST 54 | 55 | 56 | 57 | SIG_VALTYPE_ 3 floatSignal2 : 1; 58 | SIG_VALTYPE_ 3 floatSignal1 : 1; 59 | -------------------------------------------------------------------------------- /tests/files/dbf/test.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/files/dbf/test.dbf -------------------------------------------------------------------------------- /tests/files/json/test.json: -------------------------------------------------------------------------------- 1 | { 2 | "messages": [ 3 | { 4 | "attributes": { 5 | "GenMsgCycleTime": "100" 6 | }, 7 | "comment": "Multi\nLine\nFrame comment", 8 | "id": 291, 9 | "is_extended_frame": false, 10 | "name": "testFrame1", 11 | "signals": [ 12 | { 13 | "attributes": {}, 14 | "bit_length": 11, 15 | "comment": "Multi\nLine\nSignal comment with a-umlaut: \u00e4", 16 | "factor": 5.0, 17 | "is_big_endian": true, 18 | "is_float": false, 19 | "is_signed": false, 20 | "name": "someTestSignal", 21 | "offset": 1.0, 22 | "start_bit": 9, 23 | "unit": "specialCharUnit\u00b0$" 24 | }, 25 | { 26 | "attributes": {}, 27 | "bit_length": 3, 28 | "comment": null, 29 | "factor": 1.0, 30 | "is_big_endian": false, 31 | "is_float": false, 32 | "is_signed": false, 33 | "name": "Signal", 34 | "offset": 0.0, 35 | "start_bit": 20, 36 | "unit": "someUnit" 37 | } 38 | ] 39 | }, 40 | { 41 | "attributes": { 42 | "GenMsgCycleTime": null 43 | }, 44 | "comment": null, 45 | "id": 18, 46 | "is_extended_frame": true, 47 | "name": "extendedFrame", 48 | "signals": [] 49 | } 50 | ] 51 | } -------------------------------------------------------------------------------- /tests/files/xlsx/test.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/files/xlsx/test.xls -------------------------------------------------------------------------------- /tests/files/xlsx/test.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/files/xlsx/test.xlsx -------------------------------------------------------------------------------- /tests/reference/from_arxml/test_CAN.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_arxml/test_CAN.xls -------------------------------------------------------------------------------- /tests/reference/from_arxml/test_CAN.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_arxml/test_CAN.xlsx -------------------------------------------------------------------------------- /tests/reference/from_dbc/test.csv: -------------------------------------------------------------------------------- 1 | ID,Frame Name,Cycle Time [ms],Launch Type,Launch Parameter,Signal Byte No.,Signal Bit No.,Signal Name,Signal Function,Signal Length [Bit],Signal Default, Signal Not Available,Byteorder,is signed,testBU,recBU,Name / Phys. Range,Function / Increment Unit,Value 2 | 123h,testFrame1,100,,,1,4,someTestSignal,"Multi 3 | Line 4 | Signal comment with a-umlaut: ä",11, , ,m,u,s,r,5 specialCharUnit°$,0.0..500.0 5 | 123h,testFrame1,100,,,3,4,Signal,,3, , ,i,u,s,r,someUnit,1,one 6 | 123h,testFrame1,100,,,3,4,Signal,,3, , ,i,u,s,r,someUnit,2,two 7 | 123h,testFrame1,100,,,3,4,Signal,,3, , ,i,u,s,r,someUnit,3,three 8 | -------------------------------------------------------------------------------- /tests/reference/from_dbc/test.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_dbc/test.dbf -------------------------------------------------------------------------------- /tests/reference/from_dbc/test.json: -------------------------------------------------------------------------------- 1 | { 2 | "messages": [ 3 | { 4 | "id": 291, 5 | "is_extended_frame": false, 6 | "name": "testFrame1", 7 | "signals": [ 8 | { 9 | "bit_length": 11, 10 | "factor": 5.0, 11 | "is_big_endian": true, 12 | "is_float": false, 13 | "is_signed": false, 14 | "name": "someTestSignal", 15 | "offset": 1.0, 16 | "start_bit": 9 17 | }, 18 | { 19 | "bit_length": 3, 20 | "factor": 1.0, 21 | "is_big_endian": false, 22 | "is_float": false, 23 | "is_signed": false, 24 | "name": "Signal", 25 | "offset": 0.0, 26 | "start_bit": 20 27 | } 28 | ] 29 | }, 30 | { 31 | "id": 18, 32 | "is_extended_frame": true, 33 | "name": "extendedFrame", 34 | "signals": [] 35 | } 36 | ] 37 | } -------------------------------------------------------------------------------- /tests/reference/from_dbc/test.kcd: -------------------------------------------------------------------------------- 1 | 2 | some text 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Multi 11 | Line 12 | Frame comment 13 | 14 | Multi 15 | Line 16 | Signal comment with a-umlaut: ä 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /tests/reference/from_dbc/test.sym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_dbc/test.sym -------------------------------------------------------------------------------- /tests/reference/from_dbc/test.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_dbc/test.xls -------------------------------------------------------------------------------- /tests/reference/from_dbc/test.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_dbc/test.xlsx -------------------------------------------------------------------------------- /tests/reference/from_dbc/test.yaml: -------------------------------------------------------------------------------- 1 | !!python/object:canmatrix.canmatrix.CanMatrix 2 | attributes: {} 3 | boardUnits: !!python/object:canmatrix.canmatrix.BoardUnitList 4 | _list: 5 | - !!python/object:canmatrix.canmatrix.BoardUnit 6 | attributes: {NetworkNode: '273'} 7 | comment: sender ECU 8 | name: testBU 9 | - !!python/object:canmatrix.canmatrix.BoardUnit 10 | attributes: {} 11 | comment: receiver ECU 12 | name: recBU 13 | buDefines: 14 | NetworkNode: !!python/object:canmatrix.canmatrix.Define {defaultValue: null, definition: INT 15 | 0 65535, max: 65535, min: 0, type: INT} 16 | envVars: {} 17 | frameDefines: 18 | GenMsgCycleTime: !!python/object:canmatrix.canmatrix.Define {defaultValue: null, 19 | definition: INT 0 65535, max: 65535, min: 0, type: INT} 20 | frames: !!python/object:canmatrix.canmatrix.FrameList 21 | _list: 22 | - !!Frame 23 | _Id: 291 24 | _j1939_pgn: null 25 | _j1939_prio: 0 26 | _j1939_source: 0 27 | attributes: {GenMsgCycleTime: '100'} 28 | comment: 'Multi 29 | 30 | Line 31 | 32 | Frame comment' 33 | extended: false 34 | is_complex_multiplexed: false 35 | is_fd: false 36 | is_j1939: false 37 | mux_names: {} 38 | name: testFrame1 39 | receiver: [recBU] 40 | signalGroups: [] 41 | signals: 42 | - !!python/object:canmatrix.canmatrix.Signal 43 | _values: {} 44 | attributes: {} 45 | calc_max_for_none: true 46 | calc_min_for_none: true 47 | comment: "Multi\nLine\nSignal comment with a-umlaut: \xE4" 48 | comments: {} 49 | enumeration: null 50 | factor: 5.0 51 | is_float: false 52 | is_little_endian: false 53 | is_multiplexer: false 54 | is_signed: false 55 | max: 500.0 56 | min: 0.0 57 | multiplex: null 58 | muxValMax: 0 59 | muxValMin: 0 60 | mux_val: null 61 | mux_value: null 62 | muxerForSignal: null 63 | name: someTestSignal 64 | offset: 1.0 65 | receiver: [recBU] 66 | signalsize: 11 67 | startbit: 9 68 | unit: "specialCharUnit\xB0$" 69 | - !!python/object:canmatrix.canmatrix.Signal 70 | _values: {1: one, 2: two, 3: three} 71 | attributes: {} 72 | calc_max_for_none: true 73 | calc_min_for_none: true 74 | comment: null 75 | comments: {} 76 | enumeration: null 77 | factor: 1.0 78 | is_float: false 79 | is_little_endian: true 80 | is_multiplexer: false 81 | is_signed: false 82 | max: 6.0 83 | min: 0.0 84 | multiplex: null 85 | muxValMax: 0 86 | muxValMin: 0 87 | mux_val: null 88 | mux_value: null 89 | muxerForSignal: null 90 | name: Signal 91 | offset: 0.0 92 | receiver: [recBU] 93 | signalsize: 3 94 | startbit: 20 95 | unit: someUnit 96 | size: 8 97 | transmitter: [testBU] 98 | - !!Frame 99 | _Id: 18 100 | _j1939_pgn: null 101 | _j1939_prio: 0 102 | _j1939_source: 0 103 | attributes: {} 104 | comment: null 105 | extended: 1 106 | is_complex_multiplexed: false 107 | is_fd: false 108 | is_j1939: false 109 | mux_names: {} 110 | name: extendedFrame 111 | receiver: [] 112 | signalGroups: [] 113 | signals: [] 114 | size: 8 115 | transmitter: [testBU] 116 | globalDefines: {} 117 | signalDefines: {} 118 | valueTables: {} 119 | -------------------------------------------------------------------------------- /tests/reference/from_dbf/test.csv: -------------------------------------------------------------------------------- 1 | ID,Frame Name,Cycle Time [ms],Launch Type,Launch Parameter,Signal Byte No.,Signal Bit No.,Signal Name,Signal Function,Signal Length [Bit],Signal Default, Signal Not Available,Byteorder,is signed,testBU,recBU,Name / Phys. Range,Function / Increment Unit,Value 2 | 123h,testFrame1,100,,,1,4,someTestSignal,Multi Line Signal comment with a-umlaut: ä,11, , ,m,u,s,r,5 specialCharUnit°$,0.0..500.0 3 | 123h,testFrame1,100,,,3,4,Signal,,3, , ,i,u,s,r,someUnit,1,one 4 | 123h,testFrame1,100,,,3,4,Signal,,3, , ,i,u,s,r,someUnit,2,two 5 | 123h,testFrame1,100,,,3,4,Signal,,3, , ,i,u,s,r,someUnit,3,three 6 | -------------------------------------------------------------------------------- /tests/reference/from_dbf/test.dbc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_dbf/test.dbc -------------------------------------------------------------------------------- /tests/reference/from_dbf/test.json: -------------------------------------------------------------------------------- 1 | { 2 | "messages": [ 3 | { 4 | "id": 291, 5 | "is_extended_frame": false, 6 | "name": "testFrame1", 7 | "signals": [ 8 | { 9 | "bit_length": 11, 10 | "factor": 5.0, 11 | "is_big_endian": true, 12 | "is_float": false, 13 | "is_signed": false, 14 | "name": "someTestSignal", 15 | "offset": 1.0, 16 | "start_bit": 9 17 | }, 18 | { 19 | "bit_length": 3, 20 | "factor": 1.0, 21 | "is_big_endian": false, 22 | "is_float": false, 23 | "is_signed": false, 24 | "name": "Signal", 25 | "offset": 0.0, 26 | "start_bit": 20 27 | } 28 | ] 29 | }, 30 | { 31 | "id": 18, 32 | "is_extended_frame": true, 33 | "name": "extendedFrame", 34 | "signals": [] 35 | } 36 | ] 37 | } -------------------------------------------------------------------------------- /tests/reference/from_dbf/test.kcd: -------------------------------------------------------------------------------- 1 | 2 | some text 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Multi Line Frame comment 11 | 12 | Multi Line Signal comment with a-umlaut: ä 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /tests/reference/from_dbf/test.sym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_dbf/test.sym -------------------------------------------------------------------------------- /tests/reference/from_dbf/test.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_dbf/test.xls -------------------------------------------------------------------------------- /tests/reference/from_dbf/test.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_dbf/test.xlsx -------------------------------------------------------------------------------- /tests/reference/from_dbf/test.yaml: -------------------------------------------------------------------------------- 1 | !!python/object:canmatrix.canmatrix.CanMatrix 2 | attributes: {} 3 | boardUnits: !!python/object:canmatrix.canmatrix.BoardUnitList 4 | _list: 5 | - !!python/object:canmatrix.canmatrix.BoardUnit 6 | attributes: {NetworkNode: '7'} 7 | comment: sender ECU 8 | name: testBU 9 | - !!python/object:canmatrix.canmatrix.BoardUnit 10 | attributes: {} 11 | comment: receiver ECU 12 | name: recBU 13 | buDefines: 14 | NetworkNode: !!python/object:canmatrix.canmatrix.Define {defaultValue: '65535', 15 | definition: INT 0 0, max: 0, min: 0, type: INT} 16 | envVars: {} 17 | frameDefines: 18 | GenMsgCycleTime: !!python/object:canmatrix.canmatrix.Define {defaultValue: '65535', 19 | definition: INT 0 0, max: 0, min: 0, type: INT} 20 | frames: !!python/object:canmatrix.canmatrix.FrameList 21 | _list: 22 | - !!Frame 23 | _Id: 291 24 | _j1939_pgn: null 25 | _j1939_prio: 0 26 | _j1939_source: 0 27 | attributes: {GenMsgCycleTime: '100'} 28 | comment: ' Multi Line Frame comment' 29 | extended: false 30 | is_complex_multiplexed: false 31 | is_fd: false 32 | is_j1939: false 33 | mux_names: {} 34 | name: testFrame1 35 | receiver: [recBU] 36 | signalGroups: [] 37 | signals: 38 | - !!python/object:canmatrix.canmatrix.Signal 39 | _values: {} 40 | attributes: {} 41 | calc_max_for_none: true 42 | calc_min_for_none: true 43 | comment: "Multi Line Signal comment with a-umlaut: \xE4" 44 | comments: {} 45 | enumeration: null 46 | factor: 5.0 47 | is_float: false 48 | is_little_endian: false 49 | is_multiplexer: false 50 | is_signed: false 51 | max: 500.0 52 | min: 0.0 53 | multiplex: null 54 | muxValMax: 0 55 | muxValMin: 0 56 | mux_val: null 57 | mux_value: null 58 | muxerForSignal: null 59 | name: someTestSignal 60 | offset: 1.0 61 | receiver: [recBU] 62 | signalsize: 11 63 | startbit: 9 64 | unit: "specialCharUnit\xB0$" 65 | - !!python/object:canmatrix.canmatrix.Signal 66 | _values: {1: one, 2: two, 3: three} 67 | attributes: {} 68 | calc_max_for_none: true 69 | calc_min_for_none: true 70 | comment: null 71 | comments: {} 72 | enumeration: null 73 | factor: 1.0 74 | is_float: false 75 | is_little_endian: true 76 | is_multiplexer: false 77 | is_signed: false 78 | max: 6.0 79 | min: 0.0 80 | multiplex: null 81 | muxValMax: 0 82 | muxValMin: 0 83 | mux_val: null 84 | mux_value: null 85 | muxerForSignal: null 86 | name: Signal 87 | offset: 0.0 88 | receiver: [recBU] 89 | signalsize: 3 90 | startbit: 20 91 | unit: someUnit 92 | size: 8 93 | transmitter: [testBU] 94 | - !!Frame 95 | _Id: 18 96 | _j1939_pgn: null 97 | _j1939_prio: 0 98 | _j1939_source: 0 99 | attributes: {} 100 | comment: null 101 | extended: 1 102 | is_complex_multiplexed: false 103 | is_fd: false 104 | is_j1939: false 105 | mux_names: {} 106 | name: extendedFrame 107 | receiver: [] 108 | signalGroups: [] 109 | signals: [] 110 | size: 8 111 | transmitter: [testBU] 112 | globalDefines: {} 113 | signalDefines: {} 114 | valueTables: {} 115 | -------------------------------------------------------------------------------- /tests/reference/from_json/test.csv: -------------------------------------------------------------------------------- 1 | ID,Frame Name,Cycle Time [ms],Launch Type,Launch Parameter,Signal Byte No.,Signal Bit No.,Signal Name,Signal Function,Signal Length [Bit],Signal Default, Signal Not Available,Byteorder,is signed,Name / Phys. Range,Function / Increment Unit,Value 2 | 123h,testFrame1,,,1,4,someTestSignal,,11, , ,m,u,5 specialCharUnit°$,1.0..10236.0 3 | 123h,testFrame1,,,3,4,Signal,,3, , ,i,u,someUnit,0.0..7.0 4 | -------------------------------------------------------------------------------- /tests/reference/from_json/test.dbc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_json/test.dbc -------------------------------------------------------------------------------- /tests/reference/from_json/test.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_json/test.dbf -------------------------------------------------------------------------------- /tests/reference/from_json/test.kcd: -------------------------------------------------------------------------------- 1 | 2 | some text 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/reference/from_json/test.sym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_json/test.sym -------------------------------------------------------------------------------- /tests/reference/from_json/test.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_json/test.xls -------------------------------------------------------------------------------- /tests/reference/from_json/test.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_json/test.xlsx -------------------------------------------------------------------------------- /tests/reference/from_json/test.yaml: -------------------------------------------------------------------------------- 1 | !!python/object:canmatrix.canmatrix.CanMatrix 2 | attributes: {} 3 | boardUnits: !!python/object:canmatrix.canmatrix.BoardUnitList 4 | _list: [] 5 | buDefines: {} 6 | envVars: {} 7 | frameDefines: {} 8 | frames: !!python/object:canmatrix.canmatrix.FrameList 9 | _list: 10 | - !!Frame 11 | _Id: 291 12 | _j1939_pgn: null 13 | _j1939_prio: 0 14 | _j1939_source: 0 15 | attributes: {} 16 | comment: null 17 | extended: 0 18 | is_complex_multiplexed: false 19 | is_fd: false 20 | is_j1939: false 21 | mux_names: {} 22 | name: testFrame1 23 | receiver: [] 24 | signalGroups: [] 25 | signals: 26 | - !!python/object:canmatrix.canmatrix.Signal 27 | _values: {} 28 | attributes: {} 29 | calc_max_for_none: true 30 | calc_min_for_none: true 31 | comment: null 32 | comments: {} 33 | enumeration: null 34 | factor: 5.0 35 | is_float: false 36 | is_little_endian: false 37 | is_multiplexer: false 38 | is_signed: false 39 | max: 10236.0 40 | min: 1.0 41 | multiplex: null 42 | muxValMax: 0 43 | muxValMin: 0 44 | mux_val: null 45 | mux_value: null 46 | muxerForSignal: null 47 | name: someTestSignal 48 | offset: 1.0 49 | receiver: [] 50 | signalsize: 11 51 | startbit: 9 52 | unit: "specialCharUnit\xB0$" 53 | - !!python/object:canmatrix.canmatrix.Signal 54 | _values: {} 55 | attributes: {} 56 | calc_max_for_none: true 57 | calc_min_for_none: true 58 | comment: null 59 | comments: {} 60 | enumeration: null 61 | factor: 1.0 62 | is_float: false 63 | is_little_endian: true 64 | is_multiplexer: false 65 | is_signed: false 66 | max: 7.0 67 | min: 0.0 68 | multiplex: null 69 | muxValMax: 0 70 | muxValMin: 0 71 | mux_val: null 72 | mux_value: null 73 | muxerForSignal: null 74 | name: Signal 75 | offset: 0.0 76 | receiver: [] 77 | signalsize: 3 78 | startbit: 20 79 | unit: someUnit 80 | size: 8 81 | transmitter: [] 82 | - !!Frame 83 | _Id: 18 84 | _j1939_pgn: null 85 | _j1939_prio: 0 86 | _j1939_source: 0 87 | attributes: {} 88 | comment: null 89 | extended: 1 90 | is_complex_multiplexed: false 91 | is_fd: false 92 | is_j1939: false 93 | mux_names: {} 94 | name: extendedFrame 95 | receiver: [] 96 | signalGroups: [] 97 | signals: [] 98 | size: 8 99 | transmitter: [] 100 | globalDefines: {} 101 | signalDefines: {} 102 | valueTables: {} 103 | -------------------------------------------------------------------------------- /tests/reference/from_kcd/test_test.kcd.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_kcd/test_test.kcd.xls -------------------------------------------------------------------------------- /tests/reference/from_kcd/test_test.kcd.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_kcd/test_test.kcd.xlsx -------------------------------------------------------------------------------- /tests/reference/from_sym/test.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_sym/test.xls -------------------------------------------------------------------------------- /tests/reference/from_sym/test.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_sym/test.xlsx -------------------------------------------------------------------------------- /tests/reference/from_xls/test.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_xls/test.xlsx -------------------------------------------------------------------------------- /tests/reference/from_xlsx/test.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ebroecker/canmatrix/8421688ac1d18301c3c6080c8dd3d10cd6a3f8ae/tests/reference/from_xlsx/test.xls -------------------------------------------------------------------------------- /tests/test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import copy 4 | import os 5 | import shutil 6 | import subprocess 7 | import sys 8 | 9 | sys.path.append('../src') 10 | import canmatrix.convert 11 | import canmatrix.formats 12 | import canmatrix.log 13 | 14 | 15 | if sys.version_info > (3, 2): 16 | if shutil.which("diff") is None: 17 | print("ERROR: this test needs the tool 'diff' in your path to work") 18 | sys.exit() 19 | 20 | logger = canmatrix.log.setup_logger() 21 | canmatrix.log.set_log_level(logger, -1) 22 | 23 | 24 | def run_tests(): 25 | export_types = [] 26 | import_types = [] 27 | 28 | for canFormat, features in canmatrix.formats.supportedFormats.items(): 29 | if "dump" in features: 30 | export_types.append(canmatrix.formats.extensionMapping[canFormat]) 31 | if "load" in features: 32 | import_types.append(canmatrix.formats.extensionMapping[canFormat]) 33 | 34 | # for f in os.listdir('../canmatrix'): 35 | # m = re.match('^export(.*).py$', f) 36 | # if m is not None and m.group(1) != 'all': 37 | # export_types.append(m.group(1)) 38 | # m = re.match('^import(.*).py$', f) 39 | # if m is not None and m.group(1) != 'all' and m.group(1) != 'any': 40 | # import_types.append(m.group(1)) 41 | 42 | export_types.sort() 43 | # TODO: support testing of xlsx 44 | # export_types.remove('xlsx') 45 | if "xlsx" in import_types: 46 | # todo issue #541 47 | import_types.remove("xlsx") 48 | if "fibex" in export_types: 49 | export_types.remove('fibex') 50 | 51 | import_types.sort() 52 | 53 | test_file_base = 'test' 54 | converted_path = 'converted' 55 | try: 56 | shutil.rmtree(converted_path) 57 | except OSError: 58 | # it's already not there... 59 | pass 60 | 61 | for i in import_types: 62 | in_file = test_file_base + '.' + i.lower() 63 | if not os.path.isfile(in_file): 64 | print('Skipping conversion from missing file ' + in_file) 65 | else: 66 | to = copy.copy(export_types) 67 | try: 68 | to.remove(i) 69 | except ValueError: 70 | # TODO: support testing of xlsx 71 | pass 72 | print('{} -> {}'.format(i, to)) 73 | 74 | for t in to: 75 | out_file = os.path.basename(test_file_base) 76 | # out_file = os.path.splitext(out_file)[0] 77 | out_file += '.' + t.lower() 78 | directory = os.path.join(converted_path, 'from_' + i) 79 | try: 80 | os.makedirs(directory) 81 | except OSError: 82 | # TODO: be more specific: OSError: [Errno 17] File exists: 83 | # 'converted/from_arxml' 84 | pass 85 | out_file = os.path.join(directory, out_file) 86 | canmatrix.convert.convert(in_file, out_file) 87 | 88 | exit_code = subprocess.call(['diff', '-qr', 'reference', 'converted']) 89 | 90 | if exit_code: 91 | # difference found 92 | message = 'difference found' 93 | else: 94 | # no difference found 95 | message = 'no difference' 96 | 97 | print('\n\n Testing completed: {message}'.format(**locals())) 98 | 99 | 100 | if __name__ == "__main__": 101 | run_tests() 102 | -------------------------------------------------------------------------------- /tests/test_arxml.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import canmatrix.formats.arxml 3 | import decimal 4 | 5 | try: 6 | from pathlib import Path 7 | except ImportError: 8 | from pathlib2 import Path 9 | 10 | 11 | def test_ecu_extract(): 12 | test_file = "tests/files/arxml/MyECU.ecuc.arxml" 13 | db = canmatrix.formats.arxml.load(test_file)[''] 14 | assert db.frames is not None 15 | assert len(db.frames) == 2 16 | assert len(db.frames[0].signals) == 3 17 | assert len(db.frames[1].signals) == 1 18 | 19 | 20 | def test_get_signals_from_container_i_pdu(): 21 | test_file = "tests/files/arxml/ARXMLContainerTest.arxml" 22 | matrix = canmatrix.formats.arxml.load(test_file) 23 | assert matrix["New_CanCluster"].frames[0].signals[0].name == 'Header_ID' 24 | assert matrix["New_CanCluster"].frames[0].signals[1].name == 'Header_DLC' 25 | assert matrix["New_CanCluster"].frames[0].pdus[0].name == 'PDU_Contained_1' 26 | assert matrix["New_CanCluster"].frames[0].pdus[0].signals[0].name == 'PDU_Contained_1_Signal1' 27 | assert matrix["New_CanCluster"].frames[0].pdus[0].signals[0].attributes["SysSignalName"] == 'PDU_Contained_1_Signal1_905db81da40081cb' 28 | 29 | 30 | def test_get_signals_from_secured_pdu(): 31 | test_file = "tests/files/arxml/ARXMLSecuredPDUTest.arxml" 32 | matrix = canmatrix.formats.arxml.load(test_file) 33 | assert matrix["CAN"].frames[0].signals[0].name == 'someTestSignal' 34 | assert matrix["CAN"].frames[0].signals[1].name == 'Signal' 35 | 36 | 37 | def test_min_max(): 38 | test_file = "tests/files/arxml/ARXML_min_max.arxml" 39 | matrix = canmatrix.formats.arxml.load(test_file) 40 | assert matrix["New_CanCluster"].frames[0].signals[0].is_signed is False 41 | 42 | 43 | def test_decode_compu_method_1(): 44 | test_file = "tests/files/arxml/ARXMLCompuMethod1.arxml" 45 | ea = canmatrix.formats.arxml.Earxml() 46 | ea.open(test_file) 47 | compu_method = ea.find("COMPU-METHOD") 48 | # default_float_factory = decimal.Decimal 49 | values, factor, offset, unit, const = canmatrix.formats.arxml.decode_compu_method(compu_method, ea, float) 50 | assert values == {'0': 'no trailer detected', '1': 'trailer detected'} 51 | assert factor == 42 52 | assert offset == 17 53 | -------------------------------------------------------------------------------- /tests/test_arxml_gw.py: -------------------------------------------------------------------------------- 1 | import canmatrix.formats.arxml 2 | import textwrap 3 | import io 4 | 5 | 6 | def test_pdu_gateway(): 7 | arxml = io.BytesIO(textwrap.dedent(u'''\ 8 | 9 | 10 | 11 | Cluster 12 | 13 | 14 | someCluster 15 | 16 | 17 | 18 | 19 | CHNL 20 | 21 | 22 | SomeFrameTriggering 23 | 24 | 25 | /Cluster/someCluster/CHNL/somePDUTriggering 26 | 27 | 28 | 29 | 30 | 31 | 32 | someSignalTriggering 33 | /ISignal/someSignal 34 | 35 | 36 | 37 | 38 | somePduTriggering 39 | /PDU/somePdu 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | someOtherCluster 50 | 51 | 52 | 53 | 54 | CHNL 55 | 56 | 57 | SomeOtherFrameTriggering 58 | 59 | 60 | /Cluster/someCluster/CHNL/someOtherPDUTrigering 61 | 62 | 63 | 64 | 65 | 66 | 67 | someOtherSignalTriggering 68 | /ISignal/someOtherSignal 69 | 70 | 71 | 72 | 73 | someOtherPduTriggering 74 | /PDU/someOtherPdu 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | Gateway 88 | 89 | 90 | someECU 91 | /ECU/someECU 92 | 93 | 94 | /Cluster/someCluster/CHNL/somePduTriggering 95 | 96 | /Cluster/someOtherCluster/CHNL/someOtherPduTriggering 97 | 98 | 99 | 100 | 101 | 102 | /Cluster/someCluster/CHNL/someSignalTriggering 103 | /Cluster/someOtherCluster/CHNL/someOtherSignalTriggering 104 | 105 | 106 | 107 | 108 | 109 | ''').encode('utf-8')) 110 | 111 | cluster = canmatrix.formats.arxml.load(arxml) 112 | 113 | assert cluster.get_pdu_routing_info("someOtherPdu")["target"][0]["pdu"] == "/PDU/somePdu" 114 | assert cluster.get_pdu_routing_info("/PDU/somePdu", strict_search=True)["source"][0]["pdu"] == "/PDU/someOtherPdu" 115 | assert cluster.get_signal_routing_info("someSignal")["source"][0]["signal"] == '/ISignal/someOtherSignal' 116 | assert cluster.get_signal_routing_info("/ISignal/someOtherSignal")["target"][0]["signal"] == '/ISignal/someSignal' 117 | -------------------------------------------------------------------------------- /tests/test_cli_compare.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import tempfile 4 | 5 | import pytest 6 | 7 | import canmatrix.formats 8 | 9 | try: 10 | from pathlib import Path 11 | except ImportError: 12 | from pathlib2 import Path 13 | 14 | pytest_plugins = ["pytester"] 15 | here = Path(__file__).parent / "files" 16 | tmp_dir = tempfile.mkdtemp() 17 | 18 | 19 | @pytest.fixture 20 | def run(testdir): 21 | def do_run(*args): 22 | args = [sys.executable, "-m", "canmatrix.cli.compare"] + list(args) 23 | return testdir.run(*args) 24 | return do_run 25 | 26 | def test_silent(tmpdir, run): 27 | inputFile1 = str(here / "dbc" / "test_frame_decoding.dbc") 28 | inputFile2 = str(here / "arxml" / "ARXML_min_max.arxml") 29 | 30 | normal_result = run(inputFile1, inputFile2) 31 | silent_result = run("-s", inputFile1, inputFile2) 32 | assert len(normal_result.errlines) > len(silent_result.errlines) 33 | assert len(normal_result.outlines) == len(silent_result.outlines) 34 | 35 | def test_verbose(tmpdir, run): 36 | inputFile1 = str(here / "dbc" / "test_frame_decoding.dbc") 37 | inputFile2 = str(here / "arxml" / "ARXML_min_max.arxml") 38 | 39 | normal_result = run(inputFile1, inputFile2) 40 | verbose_result = run("-vv", inputFile1, inputFile2) 41 | assert len(normal_result.errlines) + len(normal_result.outlines) < len(verbose_result.errlines) + len(verbose_result.outlines) 42 | 43 | def create_dbc(): 44 | outFile1 = tmp_dir + "/output_cli_compare_tmpa.dbc" 45 | outFile2 = tmp_dir + "/output_cli_compare_tmpb.dbc" 46 | 47 | myFrame = canmatrix.Frame("testFrame3", arbitration_id=canmatrix.arbitration_id_converter(0x124), size=8, transmitters=["testBU"]) 48 | mySignal = canmatrix.Signal("someTestSignal", 49 | size=11, 50 | is_little_endian=False, 51 | is_signed=False, 52 | factor=5.0, 53 | offset=1.0, 54 | min=0, 55 | max=500, 56 | receivers=["recBU"]) 57 | myFrame.add_signal(mySignal) 58 | mySignal.add_values(1, "one") 59 | db = canmatrix.CanMatrix() 60 | db.add_frame(myFrame) 61 | canmatrix.formats.dumpp({"": db}, outFile1, dbcExportEncoding='iso-8859-1', 62 | dbcExportCommentEncoding='iso-8859-1') 63 | 64 | db.add_frame_defines("myAttribute", "INT -5 10") 65 | db.add_signal_defines("mySignalAttribute", 'INT 0 65535') 66 | mySignal.add_attribute("mySignalAttribute", "7") 67 | myFrame.add_attribute("myAttribute", "42") 68 | mySignal.add_values(2, "two") 69 | myFrame.comment = "my Frame Comment" 70 | mySignal.comment = "my Signal Comment" 71 | canmatrix.formats.dumpp({"": db}, outFile2, dbcExportEncoding='iso-8859-1', 72 | dbcExportCommentEncoding='iso-8859-1') 73 | return outFile1, outFile2 74 | 75 | def test_frames(tmpdir, run): 76 | (inputFile1, inputFile2) = create_dbc() 77 | 78 | result = run("--frames", inputFile1, inputFile2) 79 | for line in result.outlines: 80 | assert line.startswith("Frames") 81 | 82 | def test_attributes(tmpdir, run): 83 | (inputFile1, inputFile2) = create_dbc() 84 | 85 | reference = run(inputFile1, inputFile2) 86 | result = run("--attributes", inputFile1, inputFile2) 87 | assert len(reference.errlines) + len(reference.outlines) < len(result.errlines) + len(result.outlines) 88 | assert "ATTRIBUTES" not in "".join(reference.outlines) 89 | assert "ATTRIBUTES" in "".join(result.outlines) 90 | 91 | def test_value_tables(tmpdir, run): 92 | (inputFile1, inputFile2) = create_dbc() 93 | 94 | reference = run(inputFile1, inputFile2) 95 | result = run("--valueTable", inputFile1, inputFile2) 96 | assert len(reference.errlines) + len(reference.outlines) > len(result.errlines) + len(result.outlines) 97 | assert "Valuetable" in "".join(reference.outlines) 98 | assert "Valuetable" not in "".join(result.outlines) 99 | 100 | def test_comments(tmpdir, run): 101 | (inputFile1, inputFile2) = create_dbc() 102 | reference = run(inputFile1, inputFile2) 103 | result = run("--comments", inputFile1, inputFile2) 104 | assert len(reference.errlines) + len(reference.outlines) < len(result.errlines) + len(result.outlines) 105 | assert "comment:" not in "".join(reference.outlines) 106 | assert "comment:" in "".join(result.outlines) 107 | 108 | -------------------------------------------------------------------------------- /tests/test_codec.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """Tests for `canmatrix` package.""" 5 | import os 6 | import unittest 7 | import tempfile 8 | 9 | from canmatrix import formats 10 | from canmatrix.canmatrix import Signal, ArbitrationId 11 | 12 | 13 | class TestCanmatrixCodec(unittest.TestCase): 14 | """Tests for `canmatrix` package.""" 15 | 16 | def setUp(self): 17 | """Set up test fixtures, if any.""" 18 | 19 | def tearDown(self): 20 | """Tear down test fixtures, if any.""" 21 | 22 | # def test_bitstruct_format(self): 23 | # """""" 24 | # s1 = Signal('signal') 25 | # self.assertEqual(s1.bitstruct_format(), 's8') 35 | 36 | def test_encode_by_signal_raw_value(self): 37 | test_file = "tests/files/dbc/test.dbc" 38 | for bus in formats.loadp(test_file).values(): 39 | test_frame1 = ArbitrationId(0x123) 40 | data = { 41 | 'Signal': 2, 42 | 'someTestSignal': 101, 43 | } 44 | data_bytes = tuple(bytearray(bus.encode(test_frame1, data))) 45 | assert data_bytes == (0, 0xCA, 0x20, 0, 0, 0, 0, 0) 46 | 47 | def test_encode_by_signal_physical_value(self): 48 | test_file = "tests/files/dbc/test.dbc" 49 | for bus in formats.loadp(test_file).values(): 50 | test_frame1 = ArbitrationId(0x123) 51 | data = { 52 | 'someTestSignal': "101", 53 | 'Signal': u'two' 54 | } 55 | data_bytes = tuple(bytearray(bus.encode(test_frame1, data))) 56 | assert data_bytes == (0, 0x28, 0x20, 0, 0, 0, 0, 0) 57 | 58 | def test_encode_decode_signal_value(self): 59 | test_file = "tests/files/dbc/test.dbc" 60 | for bus in formats.loadp(test_file).values(): 61 | test_frame1 = ArbitrationId(0x123) 62 | 63 | data = { 64 | 'Signal': 2, 65 | 'someTestSignal': 101, 66 | } 67 | data_bytes = tuple(bytearray(bus.encode(test_frame1, data))) 68 | decoded = bus.decode(test_frame1, data_bytes) 69 | 70 | for k, v in data.items(): 71 | assert decoded[k].raw_value == v 72 | 73 | def test_encode_decode_signal_value_choice_unicode(self): 74 | test_file = "tests/files/dbc/test.dbc" 75 | for bus in formats.loadp(test_file).values(): 76 | test_frame1 = ArbitrationId(0x123) 77 | 78 | data = { 79 | 'Signal': u'two' 80 | } 81 | data_bytes = tuple(bytearray(bus.encode(test_frame1, data))) 82 | 83 | decoded = bus.decode(test_frame1, data_bytes) 84 | 85 | for k, v in data.items(): 86 | assert decoded[k].signal.values[decoded[k].raw_value] == v 87 | 88 | def test_encode_decode_signal_value_choice_str(self): 89 | test_file = "tests/files/dbc/test.dbc" 90 | for bus in formats.loadp(test_file).values(): 91 | test_frame1 = ArbitrationId(0x123) 92 | 93 | data = { 94 | 'Signal': 'two' 95 | } 96 | data_bytes = tuple(bytearray(bus.encode(test_frame1, data))) 97 | 98 | decoded = bus.decode(test_frame1, data_bytes) 99 | 100 | for k, v in data.items(): 101 | assert decoded[k].signal.values[decoded[k].raw_value] == v 102 | 103 | def test_import_export_additional_frame_info(self): 104 | test_file = "tests/files/dbc/test.dbc" 105 | dbs = formats.loadp(test_file) 106 | tmp_dir = tempfile.mkdtemp() 107 | # for extension in ['csv', 'json']: # json will not export None type 108 | for extension in ['csv']: 109 | out_file_name = tmp_dir + "/output." + extension 110 | formats.dumpp(dbs, out_file_name, additionalFrameAttributes="UserFrameAttr") 111 | with open(out_file_name, "r") as file: 112 | data = file.read() 113 | self.assertIn("UserFrameAttr", data) 114 | 115 | 116 | if __name__ == "__main__": 117 | unittest.main() 118 | -------------------------------------------------------------------------------- /tests/test_copy.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import canmatrix.canmatrix 3 | import canmatrix.copy 4 | 5 | 6 | def test_merge(): 7 | matrix1 = canmatrix.canmatrix.CanMatrix() 8 | frame1 = canmatrix.canmatrix.Frame("Frame1", arbitration_id=1) 9 | frame1.add_signal(canmatrix.canmatrix.Signal("SomeSignal")) 10 | matrix1.add_frame(frame1) 11 | 12 | matrix2 = canmatrix.canmatrix.CanMatrix() 13 | frame2 = canmatrix.canmatrix.Frame("Frame2", arbitration_id=2) 14 | matrix2.add_frame(frame2) 15 | 16 | matrix1.merge([matrix2]) 17 | assert len(matrix1.frames) == 2 18 | 19 | 20 | def test_copy_ecu_with_frames(): 21 | matrix1 = canmatrix.canmatrix.CanMatrix() 22 | frame1 = canmatrix.canmatrix.Frame("Frame1", arbitration_id=1) 23 | frame1.add_signal(canmatrix.canmatrix.Signal("SomeSignal")) 24 | matrix1.add_frame(frame1) 25 | 26 | matrix2 = canmatrix.canmatrix.CanMatrix() 27 | frame2 = canmatrix.canmatrix.Frame("Frame2", arbitration_id=2, transmitters= ["ECU"]) 28 | matrix2.add_frame(frame2) 29 | matrix2.update_ecu_list() 30 | 31 | canmatrix.copy.copy_ecu_with_frames("ECU", matrix2, matrix1) 32 | 33 | assert len(matrix1.frames) == 2 34 | assert len(matrix1.ecus) == 1 35 | 36 | 37 | def test_copy_ecu_without_frames(): 38 | matrix1 = canmatrix.canmatrix.CanMatrix() 39 | frame1 = canmatrix.canmatrix.Frame("Frame1", arbitration_id=1) 40 | frame1.add_signal(canmatrix.canmatrix.Signal("SomeSignal")) 41 | matrix1.add_frame(frame1) 42 | 43 | matrix2 = canmatrix.canmatrix.CanMatrix() 44 | frame2 = canmatrix.canmatrix.Frame("Frame2", arbitration_id=2, transmitters= ["ECU"]) 45 | matrix2.add_frame(frame2) 46 | matrix2.update_ecu_list() 47 | matrix2.add_ecu_defines("attrib", "STRING") 48 | matrix2.ecu_by_name("ECU").add_attribute("attrib", "attribValue") 49 | 50 | canmatrix.copy.copy_ecu("ECU", matrix2, matrix1) 51 | 52 | assert len(matrix1.frames) == 1 53 | assert len(matrix1.ecus) == 1 54 | assert matrix1.ecu_by_name("ECU") is not None 55 | 56 | 57 | def test_copy_ecu_with_attributes(): 58 | matrix1 = canmatrix.canmatrix.CanMatrix() 59 | frame1 = canmatrix.canmatrix.Frame("Frame1", arbitration_id=1) 60 | frame1.add_signal(canmatrix.canmatrix.Signal("SomeSignal")) 61 | matrix1.add_frame(frame1) 62 | matrix1.add_ecu_defines("some_ecu_define", "STRING") 63 | 64 | matrix2 = canmatrix.canmatrix.CanMatrix() 65 | frame2 = canmatrix.canmatrix.Frame("Frame2", arbitration_id=2, transmitters= ["ECU"]) 66 | matrix2.add_frame(frame2) 67 | matrix2.update_ecu_list() 68 | matrix2.add_ecu_defines("Node Address", "INT 0 255") 69 | matrix2.add_ecu_defines("attrib", "STRING") 70 | matrix2.add_ecu_defines("some_ecu_define", "STRING") 71 | matrix2.add_define_default("some_ecu_define", "default_value") 72 | matrix2.ecu_by_name("ECU").add_attribute("attrib", "attribValue") 73 | matrix2.ecu_by_name("ECU").add_attribute("Node Address", 42) 74 | 75 | canmatrix.copy.copy_ecu("ECU", matrix2, matrix1) 76 | 77 | assert len(matrix1.frames) == 1 78 | assert len(matrix1.ecus) == 1 79 | assert matrix1.ecu_by_name("ECU") is not None 80 | assert matrix1.ecu_by_name("ECU").attribute("Node Address") == '42' 81 | assert matrix1.ecu_by_name("ECU").attribute("some_ecu_define", matrix1) == "default_value" 82 | 83 | 84 | def test_copy_frame_default_attributes(): 85 | source = canmatrix.canmatrix.CanMatrix() 86 | frame1 = canmatrix.canmatrix.Frame("Frame1", arbitration_id=1) 87 | signal = canmatrix.canmatrix.Signal("Signal1") 88 | frame1.add_signal(canmatrix.canmatrix.Signal("SomeSignal")) 89 | frame1.add_signal(signal) 90 | source.add_frame(frame1) 91 | source.add_frame_defines("some_attribute", "STRING") 92 | source.add_define_default("some_attribute", "source_frame_default") 93 | source.add_signal_defines("some_signal_attribute", "STRING") 94 | source.add_define_default("some_signal_attribute", "source_sig_default") 95 | source.add_frame_defines("some_attribute_without_default", "STRING") 96 | 97 | #test if default value only defined in source and copied to target 98 | target = canmatrix.canmatrix.CanMatrix() 99 | target.add_frame_defines("some_attribute_without_default", "STRING") 100 | target.add_define_default("some_attribute_without_default", "0") 101 | canmatrix.copy.copy_frame(frame1.arbitration_id, source, target) 102 | assert target.frames[0].attribute("some_attribute", target) == "source_frame_default" 103 | assert target.frames[0].signals[0].attribute("some_signal_attribute", target) == "source_sig_default" 104 | assert target.frames[0].attribute("some_attribute_without_default", target) == "0" 105 | 106 | # test if define already exists, but has another default value: 107 | target2 = canmatrix.canmatrix.CanMatrix() 108 | target2.add_frame_defines("some_attribute", "STRING") 109 | target2.add_define_default("some_attribute", "target_frame_default") 110 | target2.add_signal_defines("some_signal_attribute", "STRING") 111 | target2.add_define_default("some_signal_attribute", "target_sig_default") 112 | canmatrix.copy.copy_frame(frame1.arbitration_id, source, target2) 113 | assert target2.frames[0].attribute("some_attribute", target2) == "source_frame_default" 114 | assert target2.frames[0].signals[0].attribute("some_signal_attribute", target2) == "source_sig_default" 115 | -------------------------------------------------------------------------------- /tests/test_dbf.py: -------------------------------------------------------------------------------- 1 | import canmatrix.formats.dbc 2 | import io 3 | 4 | 5 | def test_empty_matrix_export(): 6 | db = canmatrix.CanMatrix() 7 | outdbf = io.BytesIO() 8 | canmatrix.formats.dump(db, outdbf, "dbf") 9 | 10 | -------------------------------------------------------------------------------- /tests/test_formats.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import io 3 | import textwrap 4 | 5 | import canmatrix.formats 6 | 7 | 8 | def test_dump_matrix(): 9 | matrix = canmatrix.CanMatrix() 10 | 11 | codec = 'utf-8' 12 | 13 | f = io.BytesIO() 14 | canmatrix.formats.dump(matrix, f, 'sym', symExportEncoding=codec) 15 | 16 | result = f.getvalue() 17 | 18 | expected = textwrap.dedent(u'''\ 19 | FormatVersion=5.0 // Do not edit this line! 20 | Title="canmatrix-Export" 21 | {ENUMS} 22 | 23 | 24 | ''').encode(codec) 25 | 26 | assert result == expected 27 | -------------------------------------------------------------------------------- /tests/test_j1939_decoder.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import io 3 | import canmatrix.j1939_decoder 4 | import textwrap 5 | import collections 6 | 7 | def test_j1939_decoder(): 8 | dbc = io.BytesIO(textwrap.dedent(u'''\ 9 | BO_ 2566856834 CM_Requests: 9 CGW 10 | SG_ CM_Inlet_MotorRequest : 50|2@0+ (1,0) [0|3] "" CM 11 | SG_ CM_ChargeUnit_Request : 52|2@0+ (1,0) [0|3] "" CM 12 | SG_ CM_RTC_TimerValue : 47|8@0+ (1,0) [0|254] "min" CM 13 | SG_ CM_RTC_TimerRequest : 37|2@0+ (1,0) [0|3] "" CM 14 | SG_ CM_PlugLock_MotorRequest : 35|3@0+ (1,0) [0|7] "" CM 15 | SG_ CM_LED2_Request : 23|8@0+ (0.5,0) [0|100] "%" CM 16 | SG_ CM_LED1_Request : 15|8@0+ (0.5,0) [0|100] "%" CM 17 | SG_ CM_LED0_Request : 7|8@0+ (0.5,0) [0|100] "%" CM 18 | SG_ CM_HighSideOut4_Request : 39|2@0+ (1,0) [0|3] "" CM 19 | SG_ CM_HighSideOut3_Request : 25|2@0+ (1,0) [0|3] "" CM 20 | SG_ CM_HighSideOut2_Request : 27|2@0+ (1,0) [0|3] "" CM 21 | SG_ CM_HighSideOut1_Request : 29|2@0+ (1,0) [0|3] "" CM 22 | SG_ CM_HighSideOut0_Request : 31|2@0+ (1,0) [0|3] "" CM 23 | SG_ CM_ControlPilot_ChargeModeRe : 55|3@0+ (1,0) [0|7] "" CM 24 | ''').encode('utf-8')) 25 | matrix = canmatrix.formats.dbc.load(dbc, dbcImportEncoding="utf8") 26 | 27 | t = canmatrix.j1939_decoder.j1939_decoder() 28 | 29 | # BAM 30 | (type, signals) = t.decode(canmatrix.ArbitrationId(id = 0xecFF00, extended= True), 31 | bytearray([0x20,10,0,1,0xff,0x66,0x1,0]), matrix) 32 | assert "BAM " in type 33 | # print (type, signals) 34 | 35 | # data 1 36 | (type, signals) = t.decode(canmatrix.ArbitrationId(id = 0xebFF00, extended= True), 37 | bytearray([0x0,1,1,1,1,1,1,1]), matrix) 38 | assert "BAM data" in type 39 | #print (type, signals) 40 | 41 | # data 2 42 | (type, signals) = t.decode(canmatrix.ArbitrationId(id = 0xebFF00, extended= True), 43 | bytearray([0x1,1,1,1,1,1,1,1]), matrix) 44 | assert "BAM last data" in type 45 | # print (type, signals) 46 | 47 | 48 | can_ids = [0x18ECFF82, 0x18EBFF82, 0x18EBFF82] 49 | can_data = [bytearray([0x20, 9, 0, 2, 0xff, 0x20, 0xff, 0]),bytearray([0x1, 0, 0, 0, 0, 0x80, 0x0, 0x80]),bytearray([0x2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])] 50 | # BA0x20, M 51 | 52 | for i in range(0,len(can_ids)): 53 | (type, signals) = t.decode(canmatrix.ArbitrationId(id=can_ids[i], extended=True), 54 | can_data[i], matrix) 55 | 56 | print ("-------- test data -------- ") 57 | test_frames = collections.OrderedDict([ 58 | (0xcef27fd, ("fffae1ff00ffff", "")), 59 | (0xcffcafd, ("c0fffffffffff800", "")), 60 | (0xcf00203, ("cc00000000b812ff", "J1939 known: ETC1")), 61 | (0xfe4a03, ("fffcffffffffffff", "J1939 known: ETC7")), 62 | (0xc010305, ("ccfffaffff204e0a", "J1939 known: TC1")), 63 | (0x0CF00400, ("F4DEDE3028FFF0FF", "J1939 known: EEC1"))]) 64 | 65 | for arb_id, (asc_data, expected) in test_frames.items(): 66 | (type, signals) = t.decode(canmatrix.ArbitrationId(id=arb_id, extended=True), 67 | bytearray.fromhex(asc_data), matrix) 68 | assert expected in type -------------------------------------------------------------------------------- /tests/test_scapy.py: -------------------------------------------------------------------------------- 1 | import os 2 | import io 3 | 4 | import canmatrix.formats.scapy 5 | 6 | 7 | def test_scapy_frame_exists(): 8 | db = canmatrix.CanMatrix() 9 | db.add_frame(canmatrix.Frame("some_frame")) 10 | outscapy = io.BytesIO() 11 | canmatrix.formats.dump(db, outscapy, "scapy") 12 | 13 | assert "class some_frame(SignalPacket):" in outscapy.getvalue().decode("utf8") 14 | 15 | 16 | def test_scapy_muliplexed_frame(): 17 | # here = os.path.dirname(os.path.realpath(__file__)) 18 | test_file = "tests/files/dbc/test_frame_decoding.dbc" 19 | db = canmatrix.formats.loadp_flat(test_file) 20 | outscapy = io.BytesIO() 21 | canmatrix.formats.dump(db, outscapy, "scapy") 22 | assert "ConditionalField" in outscapy.getvalue().decode("utf8") 23 | assert "myMuxer == 0" in outscapy.getvalue().decode("utf8") 24 | assert "myMuxer == 1" in outscapy.getvalue().decode("utf8") 25 | 26 | 27 | def test_scapy_signal_exists(): 28 | db = canmatrix.CanMatrix() 29 | 30 | db.add_frame(canmatrix.Frame("some_frame")) 31 | db.frame_by_name("some_frame").add_signal(canmatrix.Signal("some_signal", start_bit=3, size=11, factor=1.5, offset=42, unit="cm" )) 32 | 33 | outscapy = io.BytesIO() 34 | canmatrix.formats.dump(db, outscapy, "scapy") 35 | assert 'SignalField("some_signal", default=0, start=3, size=11, scaling=1.5, offset=42, unit="cm", fmt="