canopen-bench 1.0.170__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. canopen_bench-1.0.170/LICENSE +21 -0
  2. canopen_bench-1.0.170/PKG-INFO +243 -0
  3. canopen_bench-1.0.170/README.md +198 -0
  4. canopen_bench-1.0.170/THIRD-PARTY-NOTICES.md +117 -0
  5. canopen_bench-1.0.170/canopen_bench/__init__.py +43 -0
  6. canopen_bench-1.0.170/canopen_bench/__main__.py +173 -0
  7. canopen_bench-1.0.170/canopen_bench/app.py +288 -0
  8. canopen_bench-1.0.170/canopen_bench/bus/__init__.py +3 -0
  9. canopen_bench-1.0.170/canopen_bench/bus/canopen_bus.py +830 -0
  10. canopen_bench-1.0.170/canopen_bench/bus/demo.py +583 -0
  11. canopen_bench-1.0.170/canopen_bench/bus/interface.py +252 -0
  12. canopen_bench-1.0.170/canopen_bench/core.py +7983 -0
  13. canopen_bench-1.0.170/canopen_bench/data.py +171 -0
  14. canopen_bench-1.0.170/canopen_bench/db.py +192 -0
  15. canopen_bench-1.0.170/canopen_bench/eds_od.py +228 -0
  16. canopen_bench-1.0.170/canopen_bench/flows/lss_standard.yaml +27 -0
  17. canopen_bench-1.0.170/canopen_bench/instruments/__init__.py +265 -0
  18. canopen_bench-1.0.170/canopen_bench/instruments/owon.py +175 -0
  19. canopen_bench-1.0.170/canopen_bench/instruments/toellner.py +238 -0
  20. canopen_bench-1.0.170/canopen_bench/lss.py +172 -0
  21. canopen_bench-1.0.170/canopen_bench/panels/DemoDevice.panel.yaml +35 -0
  22. canopen_bench-1.0.170/canopen_bench/panels/standard.panel.yaml +25 -0
  23. canopen_bench-1.0.170/canopen_bench/panelspec.py +454 -0
  24. canopen_bench-1.0.170/canopen_bench/plugin.py +782 -0
  25. canopen_bench-1.0.170/canopen_bench/report.py +870 -0
  26. canopen_bench-1.0.170/canopen_bench/seed/CiA301Base.eds +139 -0
  27. canopen_bench-1.0.170/canopen_bench/seed/DemoDevice.eds +261 -0
  28. canopen_bench-1.0.170/canopen_bench/static/app.js +2939 -0
  29. canopen_bench-1.0.170/canopen_bench/static/fonts/IBMPlexMono-Medium.woff2 +0 -0
  30. canopen_bench-1.0.170/canopen_bench/static/fonts/IBMPlexMono-Regular.woff2 +0 -0
  31. canopen_bench-1.0.170/canopen_bench/static/fonts/IBMPlexMono-SemiBold.woff2 +0 -0
  32. canopen_bench-1.0.170/canopen_bench/static/fonts/IBMPlexSans-Bold.woff2 +0 -0
  33. canopen_bench-1.0.170/canopen_bench/static/fonts/IBMPlexSans-Medium.woff2 +0 -0
  34. canopen_bench-1.0.170/canopen_bench/static/fonts/IBMPlexSans-Regular.woff2 +0 -0
  35. canopen_bench-1.0.170/canopen_bench/static/fonts/IBMPlexSans-SemiBold.woff2 +0 -0
  36. canopen_bench-1.0.170/canopen_bench/static/fonts/LICENSE.txt +93 -0
  37. canopen_bench-1.0.170/canopen_bench/static/index.html +14 -0
  38. canopen_bench-1.0.170/canopen_bench/static/styles.css +75 -0
  39. canopen_bench-1.0.170/canopen_bench/static/vendor/preact-htm.module.js +16 -0
  40. canopen_bench-1.0.170/canopen_bench/symbols.py +317 -0
  41. canopen_bench-1.0.170/canopen_bench/testReportStyle.css +57 -0
  42. canopen_bench-1.0.170/canopen_bench/testcases.py +700 -0
  43. canopen_bench-1.0.170/canopen_bench/usersettings.py +58 -0
  44. canopen_bench-1.0.170/canopen_bench/values.py +353 -0
  45. canopen_bench-1.0.170/canopen_bench.egg-info/PKG-INFO +243 -0
  46. canopen_bench-1.0.170/canopen_bench.egg-info/SOURCES.txt +74 -0
  47. canopen_bench-1.0.170/canopen_bench.egg-info/dependency_links.txt +1 -0
  48. canopen_bench-1.0.170/canopen_bench.egg-info/entry_points.txt +2 -0
  49. canopen_bench-1.0.170/canopen_bench.egg-info/requires.txt +16 -0
  50. canopen_bench-1.0.170/canopen_bench.egg-info/top_level.txt +1 -0
  51. canopen_bench-1.0.170/pyproject.toml +104 -0
  52. canopen_bench-1.0.170/setup.cfg +4 -0
  53. canopen_bench-1.0.170/tests/test_app.py +331 -0
  54. canopen_bench-1.0.170/tests/test_canopen_bus.py +824 -0
  55. canopen_bench-1.0.170/tests/test_core.py +4960 -0
  56. canopen_bench-1.0.170/tests/test_demo.py +611 -0
  57. canopen_bench-1.0.170/tests/test_demo_bus.py +63 -0
  58. canopen_bench-1.0.170/tests/test_dev_commands.py +232 -0
  59. canopen_bench-1.0.170/tests/test_executor.py +2731 -0
  60. canopen_bench-1.0.170/tests/test_frontend.py +635 -0
  61. canopen_bench-1.0.170/tests/test_instruments.py +561 -0
  62. canopen_bench-1.0.170/tests/test_lss.py +234 -0
  63. canopen_bench-1.0.170/tests/test_object_info.py +296 -0
  64. canopen_bench-1.0.170/tests/test_object_units.py +238 -0
  65. canopen_bench-1.0.170/tests/test_panels.py +1050 -0
  66. canopen_bench-1.0.170/tests/test_plugins.py +2265 -0
  67. canopen_bench-1.0.170/tests/test_production.py +235 -0
  68. canopen_bench-1.0.170/tests/test_repo_hygiene.py +258 -0
  69. canopen_bench-1.0.170/tests/test_report.py +966 -0
  70. canopen_bench-1.0.170/tests/test_shutdown_lets_go.py +76 -0
  71. canopen_bench-1.0.170/tests/test_single_instance.py +70 -0
  72. canopen_bench-1.0.170/tests/test_symbols.py +338 -0
  73. canopen_bench-1.0.170/tests/test_teach.py +493 -0
  74. canopen_bench-1.0.170/tests/test_testcases.py +537 -0
  75. canopen_bench-1.0.170/tests/test_usersettings.py +155 -0
  76. canopen_bench-1.0.170/tests/test_values.py +270 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 NobseVomBerg
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,243 @@
1
+ Metadata-Version: 2.4
2
+ Name: canopen-bench
3
+ Version: 1.0.170
4
+ Summary: CANopen Bench — web-based test bench and machine control for CANopen devices: scan, SDO access from EDS files, YAML test cases, firmware download, live CAN trace (IXXAT, PCAN, Vector, demo mode without hardware; vendor devices via plugins)
5
+ Author: NobseVomBerg
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/NobseVomBerg/CANopen-Bench
8
+ Project-URL: Issues, https://github.com/NobseVomBerg/CANopen-Bench/issues
9
+ Project-URL: Changelog, https://github.com/NobseVomBerg/CANopen-Bench/blob/main/CHANGELOG.md
10
+ Project-URL: Author, https://unsix.de/projekte.html
11
+ Keywords: canopen,can,can-bus,cia301,eds,test-bench,test-automation,machine-control,sdo,pdo,nmt,lss,firmware-update,python-can,ixxat,pcan,vector
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Web Environment
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Manufacturing
16
+ Classifier: Operating System :: Microsoft :: Windows
17
+ Classifier: Operating System :: POSIX :: Linux
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
23
+ Classifier: Topic :: Software Development :: Embedded Systems
24
+ Classifier: Topic :: Software Development :: Testing
25
+ Classifier: Topic :: System :: Hardware
26
+ Requires-Python: >=3.10
27
+ Description-Content-Type: text/markdown
28
+ License-File: LICENSE
29
+ License-File: THIRD-PARTY-NOTICES.md
30
+ Requires-Dist: starlette>=0.37
31
+ Requires-Dist: uvicorn>=0.29
32
+ Requires-Dist: websockets>=12
33
+ Requires-Dist: python-can>=4.4
34
+ Requires-Dist: canopen>=2.3
35
+ Requires-Dist: packaging>=23
36
+ Requires-Dist: pyyaml>=6
37
+ Provides-Extra: serial
38
+ Requires-Dist: pyserial>=3.5; extra == "serial"
39
+ Provides-Extra: dev
40
+ Requires-Dist: pytest>=8; extra == "dev"
41
+ Requires-Dist: pytest-cov>=5; extra == "dev"
42
+ Requires-Dist: httpx>=0.27; extra == "dev"
43
+ Requires-Dist: ruff>=0.5; extra == "dev"
44
+ Dynamic: license-file
45
+
46
+ # CANopen Bench
47
+
48
+ Web tool to test and control CANopen devices on a hardware bench — scan,
49
+ object access, system tests, firmware download and a live CAN trace,
50
+ driven by the devices' EDS files. Python backend (Starlette +
51
+ canopen/python-can), no-build frontend (Preact/HTM), one self-contained
52
+ workspace folder per bench.
53
+
54
+ ![Live CAN trace (dark mode): SDO transfers decoded against the EDS, heartbeats, state log](https://raw.githubusercontent.com/NobseVomBerg/CANopen-Bench/main/docs/img/trace.png)
55
+
56
+ ## Try it — no hardware needed
57
+
58
+ ```bash
59
+ pip install canopen-bench
60
+ canopen-bench # → http://127.0.0.1:8000
61
+ ```
62
+
63
+ No virtualenv needed to just run it. From a clone, `pip install .`
64
+ installs the same thing from the checkout — without `-e`, which installs
65
+ the package for editing, and that is what `## Development` below is for.
66
+
67
+ `canopen-bench` is a shortcut the install writes; the module runs just as
68
+ well by itself, and from a clone's root it runs that checkout:
69
+
70
+ ```bash
71
+ python -m canopen_bench # same thing, same options
72
+ python -m canopen_bench --port 8001 --host 0.0.0.0
73
+ ```
74
+
75
+ Two reasons to prefer it. It runs *this* directory rather than whatever
76
+ `canopen-bench` happens to point at, which matters as soon as a second
77
+ copy or a second virtualenv is around. And it needs only the
78
+ dependencies, not the package itself: `pip install starlette uvicorn
79
+ websockets canopen python-can pyyaml` (the `dependencies` list in
80
+ `pyproject.toml`) and a clone is enough — worth knowing on a bench
81
+ machine where you would rather not install anything.
82
+
83
+ Note the underscore: the distribution is `canopen-bench`, the module is
84
+ `canopen_bench`. `python -m canopen-bench` cannot work — a hyphen is not
85
+ valid in a Python module name.
86
+
87
+ Pick **Demo mode** on the Setup page, **Connect**, **Scan**: virtual
88
+ devices are generated from the bundled `canopen_bench/seed/DemoDevice.eds`
89
+ (installed into
90
+ the workspace on first run). SDO reads/writes are answered from the EDS
91
+ object dictionary — including realistic aborts on out-of-range writes —
92
+ and every access shows up in the Trace like real bus traffic.
93
+
94
+ ![Setup page: bus interface, EDS registry with identity matching, machine control](https://raw.githubusercontent.com/NobseVomBerg/CANopen-Bench/main/docs/img/setup.png)
95
+
96
+ ## Features
97
+
98
+ - **Setup** — adapter/bitrate/scan-range, EDS registry with identity
99
+ matching (0x1018), machine control: adopt the bench's expected state,
100
+ scan & verify against it, re-address via exchangeable flow files.
101
+ - **Production view**: a switch to a reduced bench for the end of a line,
102
+ showing the procedures a vendor package ships (flows marked
103
+ `grade: production`, e.g. flash a board) with their firmware choices,
104
+ a Start button, instructions and progress.
105
+ - **Objects** — EDS object browser with read/write, favorites
106
+ (auto-saved), typed RAW rows (SDO / PDO / NMT with per-row node-id),
107
+ last-known values per device serial number.
108
+ - **Tests** — declarative YAML test cases
109
+ (`docs/ablaeufe/testfall-format.md`, examples in
110
+ `examples/testcases/`) executed for real against the selected device.
111
+ A run leaves HTML behind: one file per case, one summary, and a JSON
112
+ sibling. From those, "Overview by variant" folds the last so many days
113
+ into one collapsible section per hardware variant — runs, successes
114
+ and last verdict per case — which is how you tell one broken variant
115
+ from a broken device family.
116
+ - **Bench instruments** — a remote-controllable lab power supply is set
117
+ from the Setup page and from a test case (`psu` step), which is what
118
+ keeps an under-voltage case automated instead of asking an operator to
119
+ turn a knob. Serial port, `pip install ".[serial]"`; drivers in
120
+ `canopen_bench/instruments/`.
121
+ - **SWDL** — firmware download; the files come from a folder you point at
122
+ (often the firmware project's build output, drag & drop works too), and
123
+ what each one is comes from the extension that knows the format.
124
+ Download protocols are manufacturer-specific and ship as vendor
125
+ extension packages (see the note on the page).
126
+ - **Trace** — live monitor, newest frame at the top, scrollable back
127
+ through the whole 200k-frame ring buffer or an opened capture rather
128
+ than a screenful. Class + device filters, ms/µs timestamps, capture
129
+ save/load, and autosave — every recorded frame written to a capture
130
+ file as it arrives, kept for two weeks, for the endurance runs that are
131
+ longer than the ring is deep.
132
+
133
+ ## Hardware
134
+
135
+ Which adapters the tool talks to, via python-can. Names are the
136
+ manufacturers' — see the trademark note in `THIRD-PARTY-NOTICES.md`;
137
+ this project is not affiliated with any of them, and the table says what
138
+ has been exercised, not what is warranted.
139
+
140
+ | Adapter | Driver | State |
141
+ |---|---|---|
142
+ | IXXAT USB-to-CAN | VCI4 (Windows) | in regular use on the author's bench |
143
+ | PCAN-USB | PCANBasic | wired up, never run — no such adapter here |
144
+ | Vector VN1600 (VN1610/VN1630) | XL driver (Windows) | run against a VN1630 |
145
+ | Demo mode | — | no hardware, EDS-driven simulation |
146
+ | other adapters (e.g. CPC-USB) | via plugin packages | separate install |
147
+
148
+ Everything above demo mode goes through python-can's own backends, so
149
+ adapter support tracks python-can. The Vector entry exists because plain
150
+ CAN on a VN1600 needs only Vector's freely downloadable XL driver — the
151
+ CANoe/CANalyzer licences are for their applications, not for talking to
152
+ the hardware — and a lot of that hardware outlives the software budget
153
+ it was bought with. Bring-up checklists live in
154
+ `docs/ablaeufe/A-01-verbinden.md` and `A-02-scan.md`.
155
+
156
+ ## Workspaces
157
+
158
+ Every subfolder of the data folder is one workspace: its own sqlite db,
159
+ EDS files, trace captures and flow files. Create and switch workspaces on
160
+ the Setup page; copy a folder to clone or back up a bench. The data folder
161
+ is chosen under Setup > Folders and kept per user (`%APPDATA%\CANopen-Bench`,
162
+ `~/.config/canopen-bench`), so the bench finds it wherever it is started
163
+ from; on the first start it is `./data` where there is one, else
164
+ `~/CANopen-Bench`. `--data <folder>` names it for one start (a second bench
165
+ beside the everyday one, a mounted Docker volume). `--db <path>` remains as an expert override for a
166
+ single explicit database file.
167
+
168
+ Flows and EDS files a package ships are written over in the workspace on
169
+ every start, like its test cases: an update arrives without anybody
170
+ looking for the old copy. A file of one's own goes in under another name.
171
+
172
+ ## Docker
173
+
174
+ ```bash
175
+ docker build -t canopen-bench .
176
+ docker run -p 8000:8000 -v canopen-bench:/data canopen-bench
177
+ ```
178
+
179
+ All workspaces live on the `/data` volume. Demo mode works out of the
180
+ box; USB CAN adapters need the device passed through
181
+ (`--device=/dev/bus/usb`). The tool has no authentication — keep the
182
+ port on a trusted network (see `SECURITY.md`).
183
+
184
+ ## Extending
185
+
186
+ Vendor- and device-specific functionality (adapter cards, EDS seeds,
187
+ firmware catalogs, addressing procedures with session identities, demo
188
+ protocol simulations, trace decoders, EMCY code tables, custom
189
+ test-step primitives, SWDL strategies) lives in separate pip packages
190
+ registered under the
191
+ `canopen_bench.plugins` entry-point group — installing one activates it.
192
+ In multi-workspace mode this needs no shell at all: Setup > Extensions
193
+ installs a plugin package (`.whl`) straight from the browser, active
194
+ immediately — its own dependencies are not installed with it, and the
195
+ state log names any this Python lacks, with the pip command that adds
196
+ them. Guide with hook table and a minimal example:
197
+ `docs/extending.md`; API: `canopen_bench/plugin.py`. A complete worked
198
+ example ships in this repo under
199
+ [`plugins/cob-cpcusb/`](https://github.com/NobseVomBerg/CANopen-Bench/tree/main/plugins/cob-cpcusb) — python-can driver plus
200
+ adapter card, its own tests, MIT. It is a separate distribution, not part
201
+ of the `canopen-bench` package: install it only if you have that
202
+ adapter.
203
+
204
+ ## Documentation
205
+
206
+ - `IMPLEMENTATION.md` — architecture and design decisions
207
+ - `CONTRIBUTING.md` — dev setup, test conventions, what goes where
208
+ - `docs/extending.md` — plugin guide
209
+ - `docs/ablaeufe/` — operational sequence specs (German)
210
+ - `docs/ablaeufe/testfall-format.md` — YAML test-case format
211
+
212
+ ## Development
213
+
214
+ ```bash
215
+ python -m venv .venv && . .venv/bin/activate
216
+ pip install -e ".[dev]" # editable + pytest/ruff
217
+ pytest # core suite
218
+ ```
219
+
220
+ `CONTRIBUTING.md` has the rest: what CI checks, where things belong, the
221
+ versioning rule.
222
+
223
+ Behind a TLS-inspecting corporate proxy, pip fails with
224
+ `CERTIFICATE_VERIFY_FAILED` on pypi.org: the proxy's CA is trusted by the
225
+ operating system but not by the certificate bundle Python ships. On
226
+ pip 23.2+, `--use-feature=truststore` makes pip use the OS store
227
+ instead. On older pip that route is closed — it needs the `truststore`
228
+ package, which also comes from pypi.org — so export the OS root
229
+ certificates to a PEM and point pip at it with `--cert`, or set it once
230
+ with `pip config set global.cert <file>`. Either way certificate
231
+ verification stays on.
232
+
233
+ ## License & author
234
+
235
+ Core application: MIT (`LICENSE`). Plugin packages are licensed
236
+ independently — vendor plugins proprietary, `cob-cpcusb` MIT.
237
+ Bundled and depended-on third-party components, and the trademark note
238
+ (CANopen® and CiA® belong to CAN in Automation e.V.; this is not a
239
+ CiA-certified or CiA-affiliated tool), are listed in
240
+ [`THIRD-PARTY-NOTICES.md`](https://github.com/NobseVomBerg/CANopen-Bench/blob/main/THIRD-PARTY-NOTICES.md).
241
+
242
+ Created by NobseVomBerg · [unsix.de](https://unsix.de) ·
243
+ [GitHub](https://github.com/NobseVomBerg/CANopen-Bench)
@@ -0,0 +1,198 @@
1
+ # CANopen Bench
2
+
3
+ Web tool to test and control CANopen devices on a hardware bench — scan,
4
+ object access, system tests, firmware download and a live CAN trace,
5
+ driven by the devices' EDS files. Python backend (Starlette +
6
+ canopen/python-can), no-build frontend (Preact/HTM), one self-contained
7
+ workspace folder per bench.
8
+
9
+ ![Live CAN trace (dark mode): SDO transfers decoded against the EDS, heartbeats, state log](https://raw.githubusercontent.com/NobseVomBerg/CANopen-Bench/main/docs/img/trace.png)
10
+
11
+ ## Try it — no hardware needed
12
+
13
+ ```bash
14
+ pip install canopen-bench
15
+ canopen-bench # → http://127.0.0.1:8000
16
+ ```
17
+
18
+ No virtualenv needed to just run it. From a clone, `pip install .`
19
+ installs the same thing from the checkout — without `-e`, which installs
20
+ the package for editing, and that is what `## Development` below is for.
21
+
22
+ `canopen-bench` is a shortcut the install writes; the module runs just as
23
+ well by itself, and from a clone's root it runs that checkout:
24
+
25
+ ```bash
26
+ python -m canopen_bench # same thing, same options
27
+ python -m canopen_bench --port 8001 --host 0.0.0.0
28
+ ```
29
+
30
+ Two reasons to prefer it. It runs *this* directory rather than whatever
31
+ `canopen-bench` happens to point at, which matters as soon as a second
32
+ copy or a second virtualenv is around. And it needs only the
33
+ dependencies, not the package itself: `pip install starlette uvicorn
34
+ websockets canopen python-can pyyaml` (the `dependencies` list in
35
+ `pyproject.toml`) and a clone is enough — worth knowing on a bench
36
+ machine where you would rather not install anything.
37
+
38
+ Note the underscore: the distribution is `canopen-bench`, the module is
39
+ `canopen_bench`. `python -m canopen-bench` cannot work — a hyphen is not
40
+ valid in a Python module name.
41
+
42
+ Pick **Demo mode** on the Setup page, **Connect**, **Scan**: virtual
43
+ devices are generated from the bundled `canopen_bench/seed/DemoDevice.eds`
44
+ (installed into
45
+ the workspace on first run). SDO reads/writes are answered from the EDS
46
+ object dictionary — including realistic aborts on out-of-range writes —
47
+ and every access shows up in the Trace like real bus traffic.
48
+
49
+ ![Setup page: bus interface, EDS registry with identity matching, machine control](https://raw.githubusercontent.com/NobseVomBerg/CANopen-Bench/main/docs/img/setup.png)
50
+
51
+ ## Features
52
+
53
+ - **Setup** — adapter/bitrate/scan-range, EDS registry with identity
54
+ matching (0x1018), machine control: adopt the bench's expected state,
55
+ scan & verify against it, re-address via exchangeable flow files.
56
+ - **Production view**: a switch to a reduced bench for the end of a line,
57
+ showing the procedures a vendor package ships (flows marked
58
+ `grade: production`, e.g. flash a board) with their firmware choices,
59
+ a Start button, instructions and progress.
60
+ - **Objects** — EDS object browser with read/write, favorites
61
+ (auto-saved), typed RAW rows (SDO / PDO / NMT with per-row node-id),
62
+ last-known values per device serial number.
63
+ - **Tests** — declarative YAML test cases
64
+ (`docs/ablaeufe/testfall-format.md`, examples in
65
+ `examples/testcases/`) executed for real against the selected device.
66
+ A run leaves HTML behind: one file per case, one summary, and a JSON
67
+ sibling. From those, "Overview by variant" folds the last so many days
68
+ into one collapsible section per hardware variant — runs, successes
69
+ and last verdict per case — which is how you tell one broken variant
70
+ from a broken device family.
71
+ - **Bench instruments** — a remote-controllable lab power supply is set
72
+ from the Setup page and from a test case (`psu` step), which is what
73
+ keeps an under-voltage case automated instead of asking an operator to
74
+ turn a knob. Serial port, `pip install ".[serial]"`; drivers in
75
+ `canopen_bench/instruments/`.
76
+ - **SWDL** — firmware download; the files come from a folder you point at
77
+ (often the firmware project's build output, drag & drop works too), and
78
+ what each one is comes from the extension that knows the format.
79
+ Download protocols are manufacturer-specific and ship as vendor
80
+ extension packages (see the note on the page).
81
+ - **Trace** — live monitor, newest frame at the top, scrollable back
82
+ through the whole 200k-frame ring buffer or an opened capture rather
83
+ than a screenful. Class + device filters, ms/µs timestamps, capture
84
+ save/load, and autosave — every recorded frame written to a capture
85
+ file as it arrives, kept for two weeks, for the endurance runs that are
86
+ longer than the ring is deep.
87
+
88
+ ## Hardware
89
+
90
+ Which adapters the tool talks to, via python-can. Names are the
91
+ manufacturers' — see the trademark note in `THIRD-PARTY-NOTICES.md`;
92
+ this project is not affiliated with any of them, and the table says what
93
+ has been exercised, not what is warranted.
94
+
95
+ | Adapter | Driver | State |
96
+ |---|---|---|
97
+ | IXXAT USB-to-CAN | VCI4 (Windows) | in regular use on the author's bench |
98
+ | PCAN-USB | PCANBasic | wired up, never run — no such adapter here |
99
+ | Vector VN1600 (VN1610/VN1630) | XL driver (Windows) | run against a VN1630 |
100
+ | Demo mode | — | no hardware, EDS-driven simulation |
101
+ | other adapters (e.g. CPC-USB) | via plugin packages | separate install |
102
+
103
+ Everything above demo mode goes through python-can's own backends, so
104
+ adapter support tracks python-can. The Vector entry exists because plain
105
+ CAN on a VN1600 needs only Vector's freely downloadable XL driver — the
106
+ CANoe/CANalyzer licences are for their applications, not for talking to
107
+ the hardware — and a lot of that hardware outlives the software budget
108
+ it was bought with. Bring-up checklists live in
109
+ `docs/ablaeufe/A-01-verbinden.md` and `A-02-scan.md`.
110
+
111
+ ## Workspaces
112
+
113
+ Every subfolder of the data folder is one workspace: its own sqlite db,
114
+ EDS files, trace captures and flow files. Create and switch workspaces on
115
+ the Setup page; copy a folder to clone or back up a bench. The data folder
116
+ is chosen under Setup > Folders and kept per user (`%APPDATA%\CANopen-Bench`,
117
+ `~/.config/canopen-bench`), so the bench finds it wherever it is started
118
+ from; on the first start it is `./data` where there is one, else
119
+ `~/CANopen-Bench`. `--data <folder>` names it for one start (a second bench
120
+ beside the everyday one, a mounted Docker volume). `--db <path>` remains as an expert override for a
121
+ single explicit database file.
122
+
123
+ Flows and EDS files a package ships are written over in the workspace on
124
+ every start, like its test cases: an update arrives without anybody
125
+ looking for the old copy. A file of one's own goes in under another name.
126
+
127
+ ## Docker
128
+
129
+ ```bash
130
+ docker build -t canopen-bench .
131
+ docker run -p 8000:8000 -v canopen-bench:/data canopen-bench
132
+ ```
133
+
134
+ All workspaces live on the `/data` volume. Demo mode works out of the
135
+ box; USB CAN adapters need the device passed through
136
+ (`--device=/dev/bus/usb`). The tool has no authentication — keep the
137
+ port on a trusted network (see `SECURITY.md`).
138
+
139
+ ## Extending
140
+
141
+ Vendor- and device-specific functionality (adapter cards, EDS seeds,
142
+ firmware catalogs, addressing procedures with session identities, demo
143
+ protocol simulations, trace decoders, EMCY code tables, custom
144
+ test-step primitives, SWDL strategies) lives in separate pip packages
145
+ registered under the
146
+ `canopen_bench.plugins` entry-point group — installing one activates it.
147
+ In multi-workspace mode this needs no shell at all: Setup > Extensions
148
+ installs a plugin package (`.whl`) straight from the browser, active
149
+ immediately — its own dependencies are not installed with it, and the
150
+ state log names any this Python lacks, with the pip command that adds
151
+ them. Guide with hook table and a minimal example:
152
+ `docs/extending.md`; API: `canopen_bench/plugin.py`. A complete worked
153
+ example ships in this repo under
154
+ [`plugins/cob-cpcusb/`](https://github.com/NobseVomBerg/CANopen-Bench/tree/main/plugins/cob-cpcusb) — python-can driver plus
155
+ adapter card, its own tests, MIT. It is a separate distribution, not part
156
+ of the `canopen-bench` package: install it only if you have that
157
+ adapter.
158
+
159
+ ## Documentation
160
+
161
+ - `IMPLEMENTATION.md` — architecture and design decisions
162
+ - `CONTRIBUTING.md` — dev setup, test conventions, what goes where
163
+ - `docs/extending.md` — plugin guide
164
+ - `docs/ablaeufe/` — operational sequence specs (German)
165
+ - `docs/ablaeufe/testfall-format.md` — YAML test-case format
166
+
167
+ ## Development
168
+
169
+ ```bash
170
+ python -m venv .venv && . .venv/bin/activate
171
+ pip install -e ".[dev]" # editable + pytest/ruff
172
+ pytest # core suite
173
+ ```
174
+
175
+ `CONTRIBUTING.md` has the rest: what CI checks, where things belong, the
176
+ versioning rule.
177
+
178
+ Behind a TLS-inspecting corporate proxy, pip fails with
179
+ `CERTIFICATE_VERIFY_FAILED` on pypi.org: the proxy's CA is trusted by the
180
+ operating system but not by the certificate bundle Python ships. On
181
+ pip 23.2+, `--use-feature=truststore` makes pip use the OS store
182
+ instead. On older pip that route is closed — it needs the `truststore`
183
+ package, which also comes from pypi.org — so export the OS root
184
+ certificates to a PEM and point pip at it with `--cert`, or set it once
185
+ with `pip config set global.cert <file>`. Either way certificate
186
+ verification stays on.
187
+
188
+ ## License & author
189
+
190
+ Core application: MIT (`LICENSE`). Plugin packages are licensed
191
+ independently — vendor plugins proprietary, `cob-cpcusb` MIT.
192
+ Bundled and depended-on third-party components, and the trademark note
193
+ (CANopen® and CiA® belong to CAN in Automation e.V.; this is not a
194
+ CiA-certified or CiA-affiliated tool), are listed in
195
+ [`THIRD-PARTY-NOTICES.md`](https://github.com/NobseVomBerg/CANopen-Bench/blob/main/THIRD-PARTY-NOTICES.md).
196
+
197
+ Created by NobseVomBerg · [unsix.de](https://unsix.de) ·
198
+ [GitHub](https://github.com/NobseVomBerg/CANopen-Bench)
@@ -0,0 +1,117 @@
1
+ # Third-party notices
2
+
3
+ CANopen Bench itself is MIT-licensed (see `LICENSE`). It bundles and
4
+ depends on the components below, which keep their own licenses. This
5
+ file is the attribution required by those licenses; it travels with the
6
+ wheel, the sdist and the Docker image.
7
+
8
+ ## Bundled in this repository
9
+
10
+ Shipped as source inside the package (`canopen_bench/static/vendor/`),
11
+ so these notices apply to every copy of CANopen Bench:
12
+
13
+ | Component | License | Copyright |
14
+ |---|---|---|
15
+ | [Preact](https://preactjs.com) | MIT | © 2015-present Jason Miller |
16
+ | [htm](https://github.com/developit/htm) | Apache-2.0 | © 2018 Jason Miller |
17
+ | [IBM Plex](https://github.com/IBM/plex) | OFL-1.1 | © 2017 IBM Corp. |
18
+
19
+ Preact and htm are combined into the single bundle
20
+ `canopen_bench/static/vendor/preact-htm.module.js`, which carries the
21
+ same notices in its file header. The bundle is unmodified upstream
22
+ output — CANopen Bench adds no code to it.
23
+
24
+ ### OFL-1.1 (IBM Plex)
25
+
26
+ `canopen_bench/static/fonts/` holds seven woff2 files, IBM's own
27
+ unmodified builds taken from the `@ibm/plex-sans` (1.1.0) and
28
+ `@ibm/plex-mono` (2.5.0) packages. The full license text ships beside
29
+ them as `fonts/LICENSE.txt`, as the OFL requires.
30
+
31
+ The copyright line reserves the font name: *"Copyright © 2017 IBM Corp.
32
+ with Reserved Font Name 'Plex'"*. Bundling the fonts with software of any
33
+ license is explicitly allowed, so shipping them inside this MIT package
34
+ is fine and does not affect its license. What the reserved name does
35
+ forbid is calling a **modified** version Plex — which is why these files
36
+ are shipped whole rather than subsetted to save bandwidth. Anyone
37
+ subsetting or otherwise rebuilding them has to rename the result.
38
+
39
+ ### MIT (Preact)
40
+
41
+ > Permission is hereby granted, free of charge, to any person obtaining a
42
+ > copy of this software and associated documentation files (the
43
+ > "Software"), to deal in the Software without restriction, including
44
+ > without limitation the rights to use, copy, modify, merge, publish,
45
+ > distribute, sublicense, and/or sell copies of the Software, and to
46
+ > permit persons to whom the Software is furnished to do so, subject to
47
+ > the following conditions:
48
+ >
49
+ > The above copyright notice and this permission notice shall be included
50
+ > in all copies or substantial portions of the Software.
51
+ >
52
+ > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
53
+ > OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
54
+ > MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
55
+ > IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
56
+ > CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
57
+ > TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
58
+ > SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
59
+
60
+ ### Apache-2.0 (htm)
61
+
62
+ Licensed under the Apache License, Version 2.0. You may obtain a copy of
63
+ the License at <http://www.apache.org/licenses/LICENSE-2.0>. Unless
64
+ required by applicable law or agreed to in writing, software distributed
65
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
66
+ OR CONDITIONS OF ANY KIND, either express or implied. See the License for
67
+ the specific language governing permissions and limitations under it.
68
+
69
+ ## Runtime dependencies
70
+
71
+ Installed by pip, not vendored — but a Docker image built from this
72
+ repository contains them, and distributing that image distributes them:
73
+
74
+ | Package | License |
75
+ |---|---|
76
+ | [python-can](https://github.com/hardbyte/python-can) | **LGPL-3.0-only** |
77
+ | [canopen](https://github.com/christiansandberg/canopen) | MIT |
78
+ | [Starlette](https://github.com/encode/starlette) | BSD-3-Clause |
79
+ | [Uvicorn](https://github.com/encode/uvicorn) | BSD-3-Clause |
80
+ | [websockets](https://github.com/python-websockets/websockets) | BSD-3-Clause |
81
+ | [PyYAML](https://github.com/yaml/pyyaml) | MIT |
82
+ | [packaging](https://github.com/pypa/packaging) | Apache-2.0 OR BSD-2-Clause |
83
+
84
+ **python-can is LGPL-3.0.** CANopen Bench imports it as an unmodified
85
+ library and neither copies nor modifies its source, so the LGPL's
86
+ obligations attach to python-can alone, not to CANopen Bench. If you
87
+ redistribute a Docker image or any other bundle built from this
88
+ repository, you are conveying python-can and must pass on its license
89
+ text and let recipients replace it with a modified version — with a
90
+ pip-installed package that is already the case, since it can simply be
91
+ reinstalled.
92
+
93
+ ## Plugin packages
94
+
95
+ Plugins are separate distributions with their own licensing; installing
96
+ one does not change the license of this package. The public
97
+ [`cob-cpcusb`](plugins/cob-cpcusb/)
98
+ is MIT. Check each plugin's own `LICENSE` before redistributing an
99
+ environment that contains it — a copyleft or proprietary plugin puts its
100
+ own obligations on that environment.
101
+
102
+ ## Trademarks
103
+
104
+ CANopen® and CiA® are registered trademarks of
105
+ [CAN in Automation e.V.](https://www.can-cia.org/) CANopen Bench is an
106
+ independent project and is neither affiliated with, endorsed by, nor
107
+ certified by CAN in Automation. References to CiA specifications
108
+ (CiA 301, CiA 305, CiA 402, …) describe which published behaviour this
109
+ tool implements; they are not a claim of conformance, and this tool is
110
+ not a CiA conformance test tool.
111
+
112
+ IXXAT® is a trademark of HMS Networks. PCAN® is a trademark of
113
+ PEAK-System Technik GmbH. CPC-USB is a product of EMS Dr. Thomas Wünsche.
114
+ All other product names are the property of their respective owners and
115
+ are used here solely to state which hardware this software interoperates
116
+ with. Their use implies no affiliation with or endorsement by those
117
+ companies.
@@ -0,0 +1,43 @@
1
+ """CANopen Bench — web tool to test and control CANopen devices."""
2
+ import re
3
+ from importlib.metadata import PackageNotFoundError
4
+ from importlib.metadata import version as _pkg_version
5
+ from pathlib import Path
6
+
7
+
8
+ def _read_version() -> str:
9
+ """The one place the version is read from.
10
+
11
+ pyproject.toml first: this project bumps the version on every commit
12
+ and does not tag releases, so a source checkout is the normal way to
13
+ run it — and the installed metadata of an editable install goes stale
14
+ until the next `pip install -e`, happily reporting an old number.
15
+ Wheel installs have no pyproject next to the package and fall through
16
+ to the (then correct) metadata.
17
+
18
+ The file is scanned for the version line rather than parsed as TOML:
19
+ ``tomllib`` only exists from Python 3.11, and on 3.10 falling back to
20
+ the metadata would quietly reintroduce exactly the staleness this
21
+ function exists to avoid. Adding a ``tomli`` dependency to read one
22
+ line is not worth it.
23
+
24
+ Kept in this module rather than in ``core`` so that reading the
25
+ version costs no imports beyond the standard library.
26
+ """
27
+ try:
28
+ pp = Path(__file__).resolve().parent.parent / "pyproject.toml"
29
+ for line in pp.read_text(encoding="utf-8").splitlines():
30
+ # first `version = "..."` in the file; [project] declares it
31
+ # before any other table can (build-system has no version key)
32
+ match = re.match(r'\s*version\s*=\s*["\'](?P<v>[^"\']+)["\']', line)
33
+ if match:
34
+ return match.group("v")
35
+ except OSError:
36
+ pass
37
+ try:
38
+ return _pkg_version("canopen-bench")
39
+ except PackageNotFoundError: # bare checkout without install
40
+ return "dev"
41
+
42
+
43
+ __version__ = _read_version()