soemx 0.1.0.dev0__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 (69) hide show
  1. soemx-0.1.0.dev0/MANIFEST.in +10 -0
  2. soemx-0.1.0.dev0/PKG-INFO +88 -0
  3. soemx-0.1.0.dev0/README.md +80 -0
  4. soemx-0.1.0.dev0/pyproject.toml +15 -0
  5. soemx-0.1.0.dev0/setup.cfg +4 -0
  6. soemx-0.1.0.dev0/setup.py +59 -0
  7. soemx-0.1.0.dev0/soemx/__init__.py +70 -0
  8. soemx-0.1.0.dev0/soemx/adapters.py +18 -0
  9. soemx-0.1.0.dev0/soemx/errors.py +75 -0
  10. soemx-0.1.0.dev0/soemx/soemx.c +74971 -0
  11. soemx-0.1.0.dev0/soemx/soemx.pyx +1615 -0
  12. soemx-0.1.0.dev0/soemx/soemx_native.c +265 -0
  13. soemx-0.1.0.dev0/soemx/soemx_native.h +76 -0
  14. soemx-0.1.0.dev0/soemx/status.py +19 -0
  15. soemx-0.1.0.dev0/soemx.egg-info/PKG-INFO +88 -0
  16. soemx-0.1.0.dev0/soemx.egg-info/SOURCES.txt +79 -0
  17. soemx-0.1.0.dev0/soemx.egg-info/dependency_links.txt +1 -0
  18. soemx-0.1.0.dev0/soemx.egg-info/top_level.txt +1 -0
  19. soemx-0.1.0.dev0/tests/test_status.py +66 -0
  20. soemx-0.1.0.dev0/vendor/SOEM/build/include/soem/ec_options.h +128 -0
  21. soemx-0.1.0.dev0/vendor/SOEM/include/soem/ec_base.h +42 -0
  22. soemx-0.1.0.dev0/vendor/SOEM/include/soem/ec_coe.h +73 -0
  23. soemx-0.1.0.dev0/vendor/SOEM/include/soem/ec_config.h +31 -0
  24. soemx-0.1.0.dev0/vendor/SOEM/include/soem/ec_dc.h +27 -0
  25. soemx-0.1.0.dev0/vendor/SOEM/include/soem/ec_eoe.h +213 -0
  26. soemx-0.1.0.dev0/vendor/SOEM/include/soem/ec_foe.h +27 -0
  27. soemx-0.1.0.dev0/vendor/SOEM/include/soem/ec_main.h +624 -0
  28. soemx-0.1.0.dev0/vendor/SOEM/include/soem/ec_options.h.in +128 -0
  29. soemx-0.1.0.dev0/vendor/SOEM/include/soem/ec_print.h +30 -0
  30. soemx-0.1.0.dev0/vendor/SOEM/include/soem/ec_soe.h +121 -0
  31. soemx-0.1.0.dev0/vendor/SOEM/include/soem/ec_type.h +551 -0
  32. soemx-0.1.0.dev0/vendor/SOEM/include/soem/soem.h +28 -0
  33. soemx-0.1.0.dev0/vendor/SOEM/osal/linux/osal.c +154 -0
  34. soemx-0.1.0.dev0/vendor/SOEM/osal/linux/osal_defs.h +46 -0
  35. soemx-0.1.0.dev0/vendor/SOEM/osal/win32/osal.c +176 -0
  36. soemx-0.1.0.dev0/vendor/SOEM/osal/win32/osal_defs.h +51 -0
  37. soemx-0.1.0.dev0/vendor/SOEM/oshw/linux/nicdrv.c +636 -0
  38. soemx-0.1.0.dev0/vendor/SOEM/oshw/linux/nicdrv.h +108 -0
  39. soemx-0.1.0.dev0/vendor/SOEM/oshw/linux/oshw.c +116 -0
  40. soemx-0.1.0.dev0/vendor/SOEM/oshw/linux/oshw.h +31 -0
  41. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/nicdrv.c +599 -0
  42. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/nicdrv.h +111 -0
  43. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/oshw.c +120 -0
  44. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/oshw.h +31 -0
  45. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/wpcap/Include/Packet32.h +359 -0
  46. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/wpcap/Include/Win32-Extensions.h +113 -0
  47. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/wpcap/Include/bittypes.h +137 -0
  48. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/wpcap/Include/ip6_misc.h +163 -0
  49. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/wpcap/Include/pcap/bluetooth.h +48 -0
  50. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/wpcap/Include/pcap/bpf.h +934 -0
  51. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/wpcap/Include/pcap/namedb.h +89 -0
  52. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/wpcap/Include/pcap/pcap.h +407 -0
  53. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/wpcap/Include/pcap/sll.h +129 -0
  54. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/wpcap/Include/pcap/usb.h +90 -0
  55. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/wpcap/Include/pcap/vlan.h +46 -0
  56. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/wpcap/Include/pcap-bpf.h +47 -0
  57. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/wpcap/Include/pcap-namedb.h +42 -0
  58. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/wpcap/Include/pcap-stdinc.h +93 -0
  59. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/wpcap/Include/pcap.h +45 -0
  60. soemx-0.1.0.dev0/vendor/SOEM/oshw/win32/wpcap/Include/remote-ext.h +444 -0
  61. soemx-0.1.0.dev0/vendor/SOEM/src/ec_base.c +534 -0
  62. soemx-0.1.0.dev0/vendor/SOEM/src/ec_coe.c +1380 -0
  63. soemx-0.1.0.dev0/vendor/SOEM/src/ec_config.c +1653 -0
  64. soemx-0.1.0.dev0/vendor/SOEM/src/ec_dc.c +428 -0
  65. soemx-0.1.0.dev0/vendor/SOEM/src/ec_eoe.c +665 -0
  66. soemx-0.1.0.dev0/vendor/SOEM/src/ec_foe.c +416 -0
  67. soemx-0.1.0.dev0/vendor/SOEM/src/ec_main.c +2705 -0
  68. soemx-0.1.0.dev0/vendor/SOEM/src/ec_print.c +378 -0
  69. soemx-0.1.0.dev0/vendor/SOEM/src/ec_soe.c +379 -0
@@ -0,0 +1,10 @@
1
+ include README.md pyproject.toml setup.py
2
+ recursive-include soemx *.py *.pyx *.c *.h
3
+ recursive-include tests *.py
4
+ recursive-include vendor/SOEM/include *.h *.in
5
+ recursive-include vendor/SOEM/src *.c *.h
6
+ recursive-include vendor/SOEM/osal/linux *.c *.h
7
+ recursive-include vendor/SOEM/osal/win32 *.c *.h
8
+ recursive-include vendor/SOEM/oshw/linux *.c *.h
9
+ recursive-include vendor/SOEM/oshw/win32 *.c *.h
10
+ recursive-include vendor/SOEM/build/include *.h
@@ -0,0 +1,88 @@
1
+ Metadata-Version: 2.4
2
+ Name: soemx
3
+ Version: 0.1.0.dev0
4
+ Summary: Cython bindings for SOEM with EoE support
5
+ Author: soemx contributors
6
+ Requires-Python: >=3.9
7
+ Description-Content-Type: text/markdown
8
+
9
+ # soemx
10
+
11
+ Python bindings for the [Simple Open EtherCAT Master (SOEM)](https://github.com/OpenEtherCATsociety/SOEM), implemented with Cython.
12
+
13
+ The project is intended to provide a complete, Python-friendly API for EtherCAT master operations, including EoE (Ethernet over EtherCAT), which is not currently exposed by PySOEM.
14
+
15
+ ## Current API
16
+
17
+ The Cython extension currently provides:
18
+
19
+ - `Master.open()` / `close()` and context-manager support, including optional redundancy
20
+ - `find_adapters()` returning `Adapter` objects with `name` and `desc` attributes
21
+ - slave discovery, state control, AL diagnostics and EEPROM access
22
+ - mapped process data through `Master.io_map`, `Slave.inputs` and `Slave.outputs`
23
+ - cyclic and grouped process-data exchange, one-shot `exchange_processdata()` /
24
+ `exchange_processdata_group()`, direct `rxpdo()` / `txpdo()` access
25
+ - actual PDO map length through `Master.mapped_size`, plus writable memory views
26
+ - SDO / CoE, SDO information discovery, FoE and SoE
27
+ - configurable default SDO read/write timeouts through `Master`
28
+ - consistent GIL release for blocking native operations through
29
+ `Master.always_release_gil` and `Master.check_release_gil()`
30
+ - EoE frame send/receive and raw mailbox transport
31
+ - distributed clocks, DC sync0, overlap/packed mapping and queued errors
32
+ - parsed slave mailbox parameters (`mailbox_out_address`, `mailbox_out_size`,
33
+ `mailbox_in_address`, `mailbox_in_size`) for diagnostics
34
+ - mailbox layout updates through `Slave.amend_mbx()` before mailbox use
35
+
36
+ PySOEM is used as a practical API reference, but `soemx` is free to improve the
37
+ interface where a clearer or safer design is possible. Raw byte-oriented methods
38
+ are used where Python cannot know a device's object data type. In addition to
39
+ normal slave-indexed EEPROM access, the master exposes direct AP and FP EEPROM
40
+ operations for diagnostics.
41
+
42
+ EoE channels accept any bytes-like frame buffer and expose IPv4 configuration
43
+ through `set_ip()` / `get_ip()`. Emergency mailbox notifications are delivered
44
+ as structured `Emergency` objects through Master-level or per-slave callbacks.
45
+ Raw records from `pop_error()` retain the associated register and auxiliary
46
+ word fields for diagnostics.
47
+
48
+ ## Build and runtime
49
+
50
+ Build the extension on Windows with Visual Studio and Cython:
51
+
52
+ ```powershell
53
+ python setup.py build_ext --inplace
54
+ python -m pytest -q
55
+ ```
56
+
57
+ Linux builds use SOEM's raw-socket backend and require the system `libpcap`
58
+ development package and a compiler.
59
+
60
+ The Windows backend links against Npcap/WinPcap's `wpcap.dll` and `Packet.dll`.
61
+ These DLLs are required when opening a network adapter, but pure Python modules
62
+ and the test suite can be used without EtherCAT hardware or the packet runtime.
63
+
64
+ Physical EtherCAT, PDO, mailbox and EoE behavior still requires a compatible
65
+ network adapter and at least one EtherCAT slave.
66
+
67
+ ## Minimal EoE example
68
+
69
+ ```python
70
+ import soemx
71
+
72
+ for adapter in soemx.find_adapters():
73
+ print(adapter.name, adapter.desc)
74
+
75
+ with soemx.open("YOUR_INTERFACE") as master:
76
+ if master.config_init() <= 0:
77
+ raise RuntimeError("no EtherCAT slaves found")
78
+ channel = master.slaves[0].eoe()
79
+ channel.set_ip(b"192.168.1.20", b"255.255.255.0", b"192.168.1.1")
80
+ ethernet_frame = b"replace with a complete Ethernet frame"
81
+ channel.send(ethernet_frame)
82
+ frame = channel.receive()
83
+ ```
84
+
85
+ The example requires an EoE-capable slave and a WinPcap-compatible Npcap
86
+ installation on Windows (or the Linux packet-capture development package).
87
+
88
+ SOEM is included under `vendor/SOEM` for development and is licensed separately. See its `LICENSE.md`.
@@ -0,0 +1,80 @@
1
+ # soemx
2
+
3
+ Python bindings for the [Simple Open EtherCAT Master (SOEM)](https://github.com/OpenEtherCATsociety/SOEM), implemented with Cython.
4
+
5
+ The project is intended to provide a complete, Python-friendly API for EtherCAT master operations, including EoE (Ethernet over EtherCAT), which is not currently exposed by PySOEM.
6
+
7
+ ## Current API
8
+
9
+ The Cython extension currently provides:
10
+
11
+ - `Master.open()` / `close()` and context-manager support, including optional redundancy
12
+ - `find_adapters()` returning `Adapter` objects with `name` and `desc` attributes
13
+ - slave discovery, state control, AL diagnostics and EEPROM access
14
+ - mapped process data through `Master.io_map`, `Slave.inputs` and `Slave.outputs`
15
+ - cyclic and grouped process-data exchange, one-shot `exchange_processdata()` /
16
+ `exchange_processdata_group()`, direct `rxpdo()` / `txpdo()` access
17
+ - actual PDO map length through `Master.mapped_size`, plus writable memory views
18
+ - SDO / CoE, SDO information discovery, FoE and SoE
19
+ - configurable default SDO read/write timeouts through `Master`
20
+ - consistent GIL release for blocking native operations through
21
+ `Master.always_release_gil` and `Master.check_release_gil()`
22
+ - EoE frame send/receive and raw mailbox transport
23
+ - distributed clocks, DC sync0, overlap/packed mapping and queued errors
24
+ - parsed slave mailbox parameters (`mailbox_out_address`, `mailbox_out_size`,
25
+ `mailbox_in_address`, `mailbox_in_size`) for diagnostics
26
+ - mailbox layout updates through `Slave.amend_mbx()` before mailbox use
27
+
28
+ PySOEM is used as a practical API reference, but `soemx` is free to improve the
29
+ interface where a clearer or safer design is possible. Raw byte-oriented methods
30
+ are used where Python cannot know a device's object data type. In addition to
31
+ normal slave-indexed EEPROM access, the master exposes direct AP and FP EEPROM
32
+ operations for diagnostics.
33
+
34
+ EoE channels accept any bytes-like frame buffer and expose IPv4 configuration
35
+ through `set_ip()` / `get_ip()`. Emergency mailbox notifications are delivered
36
+ as structured `Emergency` objects through Master-level or per-slave callbacks.
37
+ Raw records from `pop_error()` retain the associated register and auxiliary
38
+ word fields for diagnostics.
39
+
40
+ ## Build and runtime
41
+
42
+ Build the extension on Windows with Visual Studio and Cython:
43
+
44
+ ```powershell
45
+ python setup.py build_ext --inplace
46
+ python -m pytest -q
47
+ ```
48
+
49
+ Linux builds use SOEM's raw-socket backend and require the system `libpcap`
50
+ development package and a compiler.
51
+
52
+ The Windows backend links against Npcap/WinPcap's `wpcap.dll` and `Packet.dll`.
53
+ These DLLs are required when opening a network adapter, but pure Python modules
54
+ and the test suite can be used without EtherCAT hardware or the packet runtime.
55
+
56
+ Physical EtherCAT, PDO, mailbox and EoE behavior still requires a compatible
57
+ network adapter and at least one EtherCAT slave.
58
+
59
+ ## Minimal EoE example
60
+
61
+ ```python
62
+ import soemx
63
+
64
+ for adapter in soemx.find_adapters():
65
+ print(adapter.name, adapter.desc)
66
+
67
+ with soemx.open("YOUR_INTERFACE") as master:
68
+ if master.config_init() <= 0:
69
+ raise RuntimeError("no EtherCAT slaves found")
70
+ channel = master.slaves[0].eoe()
71
+ channel.set_ip(b"192.168.1.20", b"255.255.255.0", b"192.168.1.1")
72
+ ethernet_frame = b"replace with a complete Ethernet frame"
73
+ channel.send(ethernet_frame)
74
+ frame = channel.receive()
75
+ ```
76
+
77
+ The example requires an EoE-capable slave and a WinPcap-compatible Npcap
78
+ installation on Windows (or the Linux packet-capture development package).
79
+
80
+ SOEM is included under `vendor/SOEM` for development and is licensed separately. See its `LICENSE.md`.
@@ -0,0 +1,15 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel", "Cython>=3.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "soemx"
7
+ version = "0.1.0.dev0"
8
+ description = "Cython bindings for SOEM with EoE support"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ authors = [{name = "soemx contributors"}]
12
+ dependencies = []
13
+
14
+ [tool.setuptools]
15
+ packages = ["soemx"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,59 @@
1
+ from pathlib import Path
2
+ import os
3
+ import sys
4
+ from setuptools import Extension, setup
5
+ from Cython.Build import cythonize
6
+
7
+ root = Path(__file__).parent.resolve()
8
+ soem = root / "vendor" / "SOEM"
9
+ sources = ["soemx/soemx.pyx", "soemx/soemx_native.c"]
10
+ sources += [f"vendor/SOEM/src/{name}" for name in [
11
+ "ec_base.c", "ec_coe.c", "ec_config.c", "ec_dc.c", "ec_eoe.c",
12
+ "ec_foe.c", "ec_main.c", "ec_print.c", "ec_soe.c"]]
13
+ if sys.platform == "win32":
14
+ platform_sources = [
15
+ "vendor/SOEM/osal/win32/osal.c",
16
+ "vendor/SOEM/oshw/win32/nicdrv.c",
17
+ "vendor/SOEM/oshw/win32/oshw.c",
18
+ ]
19
+ platform_includes = [
20
+ soem / "osal" / "win32",
21
+ soem / "oshw" / "win32",
22
+ soem / "oshw" / "win32" / "wpcap" / "Include",
23
+ ]
24
+ platform_libraries = ["wpcap", "Packet", "winmm", "ws2_32"]
25
+ platform_library_dirs = [soem / "oshw" / "win32" / "wpcap" / "Lib" / "x64"]
26
+ elif sys.platform.startswith("linux"):
27
+ platform_sources = [
28
+ "vendor/SOEM/osal/linux/osal.c",
29
+ "vendor/SOEM/oshw/linux/nicdrv.c",
30
+ "vendor/SOEM/oshw/linux/oshw.c",
31
+ ]
32
+ platform_includes = [soem / "osal" / "linux", soem / "oshw" / "linux"]
33
+ platform_libraries = ["pcap", "pthread"]
34
+ platform_library_dirs = []
35
+ else:
36
+ raise RuntimeError("soemx currently supports Windows and Linux builds")
37
+ sources += platform_sources
38
+ # setuptools requires source entries to be relative to setup.py. The vendored
39
+ # SOEM paths are normalized to POSIX separators for manifest generation.
40
+ sources = [path.replace("\\", "/") for path in sources]
41
+
42
+ extension = Extension(
43
+ "soemx._soemx",
44
+ sources=sources,
45
+ include_dirs=[str(soem / "include"), str(soem / "build" / "include"), str(soem / "osal"), *(str(path) for path in platform_includes), str(root / "soemx")],
46
+ library_dirs=[str(path) for path in platform_library_dirs],
47
+ libraries=platform_libraries,
48
+ )
49
+
50
+ extensions = cythonize([extension], language_level=3)
51
+ for ext in extensions:
52
+ ext.sources = [os.path.relpath(source, root).replace("\\", "/")
53
+ for source in ext.sources]
54
+
55
+ setup(
56
+ ext_modules=extensions,
57
+ include_package_data=False,
58
+ exclude_package_data={"soemx": ["*.c", "*.h"]},
59
+ )
@@ -0,0 +1,70 @@
1
+ """Python interface for SOEM, under active development."""
2
+
3
+ from .errors import (SoemxError, SdoError, SdoInfoError, MailboxError,
4
+ PacketError, ConfigMapError, EepromError, WkcError,
5
+ NetworkInterfaceNotOpenError, Emergency)
6
+ from .status import al_status_code_to_string
7
+ from .adapters import Adapter
8
+
9
+ NONE_STATE = 0x00
10
+ INIT_STATE = 0x01
11
+ PREOP_STATE = 0x02
12
+ BOOT_STATE = 0x03
13
+ SAFEOP_STATE = 0x04
14
+ OP_STATE = 0x08
15
+ STATE_ACK = 0x10
16
+ STATE_ERROR = 0x10
17
+
18
+ # Common EtherCAT register and CoE capability constants exposed by PySOEM.
19
+ ECT_REG_WD_DIV = 0x0400
20
+ ECT_REG_WD_TIME_PDI = 0x0410
21
+ ECT_REG_WD_TIME_PROCESSDATA = 0x0420
22
+ ECT_REG_SM0 = 0x0800
23
+ ECT_REG_SM1 = ECT_REG_SM0 + 0x08
24
+ ECT_COEDET_SDO = 0x01
25
+ ECT_COEDET_SDOINFO = 0x02
26
+ ECT_COEDET_PDOASSIGN = 0x04
27
+ ECT_COEDET_PDOCONFIG = 0x08
28
+ ECT_COEDET_UPLOAD = 0x10
29
+ ECT_COEDET_SDOCA = 0x20
30
+
31
+ __version__ = "0.1.0.dev0"
32
+
33
+
34
+ def _load_native():
35
+ try:
36
+ from . import _soemx
37
+ except ImportError as exc:
38
+ raise RuntimeError(
39
+ "unable to load the soemx native extension; install Npcap "
40
+ "with WinPcap API-compatible mode on Windows"
41
+ ) from exc
42
+ return _soemx
43
+
44
+
45
+ def __getattr__(name):
46
+ if name in ("Master", "find_adapters"):
47
+ native = _load_native()
48
+ return native.Master if name == "Master" else native.find_adapters
49
+ raise AttributeError(name)
50
+
51
+
52
+ def open(interface: str, interface2=None):
53
+ """Open an EtherCAT master and optionally configure a redundant interface."""
54
+ Master = _load_native().Master
55
+ master = Master()
56
+ try:
57
+ master.open(interface, interface2)
58
+ except Exception:
59
+ master.close()
60
+ raise
61
+ return master
62
+
63
+ __all__ = ["Master", "find_adapters", "open", "Adapter", "__version__", "al_status_code_to_string", "SoemxError", "SdoError", "SdoInfoError", "Emergency",
64
+ "MailboxError", "PacketError", "ConfigMapError", "EepromError",
65
+ "WkcError", "NetworkInterfaceNotOpenError", "NONE_STATE", "INIT_STATE",
66
+ "PREOP_STATE", "BOOT_STATE", "SAFEOP_STATE", "OP_STATE",
67
+ "STATE_ACK", "STATE_ERROR", "ECT_REG_WD_DIV", "ECT_REG_WD_TIME_PDI",
68
+ "ECT_REG_WD_TIME_PROCESSDATA", "ECT_REG_SM0", "ECT_REG_SM1",
69
+ "ECT_COEDET_SDO", "ECT_COEDET_SDOINFO", "ECT_COEDET_PDOASSIGN",
70
+ "ECT_COEDET_PDOCONFIG", "ECT_COEDET_UPLOAD", "ECT_COEDET_SDOCA"]
@@ -0,0 +1,18 @@
1
+ """Network adapter discovery helpers."""
2
+
3
+
4
+ class Adapter:
5
+ """Description of a network adapter returned by :func:`find_adapters`."""
6
+
7
+ __slots__ = ("name", "desc")
8
+
9
+ def __init__(self, name, desc):
10
+ self.name = str(name)
11
+ self.desc = str(desc)
12
+
13
+ def __repr__(self):
14
+ return f"Adapter(name={self.name!r}, desc={self.desc!r})"
15
+
16
+
17
+ def _decode(value: bytes) -> str:
18
+ return value.split(b"\0", 1)[0].decode("utf-8", errors="replace")
@@ -0,0 +1,75 @@
1
+ class SoemxError(Exception):
2
+ """Base class for soemx errors."""
3
+
4
+
5
+ class SdoError(SoemxError):
6
+ def __init__(self, slave_pos=None, index=None, subindex=None,
7
+ abort_code=None, desc=""):
8
+ self.slave_pos = slave_pos
9
+ self.index = index
10
+ self.subindex = subindex
11
+ self.abort_code = abort_code
12
+ self.desc = desc
13
+ super().__init__(desc)
14
+
15
+
16
+ class SdoInfoError(SoemxError):
17
+ def __init__(self, message=""):
18
+ self.message = message
19
+ super().__init__(message)
20
+
21
+
22
+ class MailboxError(SoemxError):
23
+ def __init__(self, slave_pos=None, error_code=None, desc=""):
24
+ self.slave_pos = slave_pos
25
+ self.error_code = error_code
26
+ self.desc = desc
27
+ super().__init__(desc)
28
+
29
+
30
+ class PacketError(SoemxError):
31
+ def __init__(self, slave_pos=None, error_code=None, message="", desc=""):
32
+ self.slave_pos = slave_pos
33
+ self.error_code = error_code
34
+ self.message = message
35
+ self.desc = desc
36
+ super().__init__(message or desc)
37
+
38
+
39
+ class ConfigMapError(SoemxError):
40
+ def __init__(self, error_list=None):
41
+ self.error_list = [] if error_list is None else list(error_list)
42
+ super().__init__(self.error_list)
43
+
44
+
45
+ class EepromError(SoemxError):
46
+ def __init__(self, message=""):
47
+ self.message = message
48
+ super().__init__(message)
49
+
50
+
51
+ class WkcError(SoemxError): pass
52
+ class NetworkInterfaceNotOpenError(SoemxError): pass
53
+
54
+
55
+ class Emergency(SoemxError):
56
+ """Emergency mailbox notification compatible with PySOEM."""
57
+
58
+ def __init__(self, slave, error_code, error_reg, b1=0, w1=0, w2=0):
59
+ self.slave_pos = slave
60
+ self.slave = slave
61
+ self.error_code = error_code
62
+ self.error_reg = error_reg
63
+ self.error_register = error_reg
64
+ self.b1 = b1
65
+ self.w1 = w1
66
+ self.w2 = w2
67
+
68
+ def __repr__(self):
69
+ return (f"Emergency(slave_pos={self.slave_pos}, error_code={self.error_code}, "
70
+ f"error_reg={self.error_reg})")
71
+
72
+ def __str__(self):
73
+ payload = bytes([self.b1]) + self.w1.to_bytes(2, "little") + self.w2.to_bytes(2, "little")
74
+ return (f"Slave {self.slave_pos}: {self.error_code:04x}, "
75
+ f"{self.error_reg:02x}, ({','.join(f'{x:02x}' for x in payload)})")