ethercat-master 0.1.0__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.
- ethercat_master-0.1.0/PKG-INFO +265 -0
- ethercat_master-0.1.0/README.md +235 -0
- ethercat_master-0.1.0/ethercat_master/__init__.py +47 -0
- ethercat_master-0.1.0/ethercat_master/bus.py +786 -0
- ethercat_master-0.1.0/ethercat_master/exceptions.py +23 -0
- ethercat_master-0.1.0/ethercat_master/network_test.py +148 -0
- ethercat_master-0.1.0/ethercat_master/pdo.py +129 -0
- ethercat_master-0.1.0/ethercat_master/pdo_mapping.json +29 -0
- ethercat_master-0.1.0/ethercat_master/slave.py +105 -0
- ethercat_master-0.1.0/ethercat_master/webgui/index.html +421 -0
- ethercat_master-0.1.0/ethercat_master/webgui/style.css +57 -0
- ethercat_master-0.1.0/ethercat_master/webserver.py +379 -0
- ethercat_master-0.1.0/ethercat_master.egg-info/PKG-INFO +265 -0
- ethercat_master-0.1.0/ethercat_master.egg-info/SOURCES.txt +18 -0
- ethercat_master-0.1.0/ethercat_master.egg-info/dependency_links.txt +1 -0
- ethercat_master-0.1.0/ethercat_master.egg-info/entry_points.txt +2 -0
- ethercat_master-0.1.0/ethercat_master.egg-info/requires.txt +5 -0
- ethercat_master-0.1.0/ethercat_master.egg-info/top_level.txt +1 -0
- ethercat_master-0.1.0/pyproject.toml +60 -0
- ethercat_master-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ethercat-master
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Generic EtherCAT master library built on PySOEM — bus management, PDO mapping, slave discovery
|
|
5
|
+
Author-email: Henschel Robotics GmbH <info@henschel-robotics.ch>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://henschel-robotics.ch
|
|
8
|
+
Project-URL: Repository, https://github.com/henschel-robotics/python-ethercat-master
|
|
9
|
+
Keywords: ethercat,pysoem,fieldbus,motion-control,industrial,automation
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
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: Topic :: Scientific/Engineering
|
|
23
|
+
Classifier: Topic :: System :: Hardware :: Hardware Drivers
|
|
24
|
+
Requires-Python: >=3.8
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
Requires-Dist: pysoem>=1.1.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
29
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
30
|
+
|
|
31
|
+
# EtherCAT Master
|
|
32
|
+
|
|
33
|
+
Generic EtherCAT master library built on [PySOEM](https://github.com/bnjmnp/pysoem). Provides bus management, slave discovery, configurable PDO mapping, automatic reconnection, and a built-in web interface for configuration.
|
|
34
|
+
|
|
35
|
+
Developed by [Henschel Robotics GmbH](https://henschel-robotics.ch).
|
|
36
|
+
|
|
37
|
+
## Features
|
|
38
|
+
|
|
39
|
+
- **Bus management** -- connect, configure, and run an EtherCAT bus with one or more slaves
|
|
40
|
+
- **Generic slave handle** -- read/write raw PDO bytes for any device (Beckhoff terminals, servos, I/O modules, ...)
|
|
41
|
+
- **PDO mapping** -- configure SyncManager assignments per slave via a JSON file or SDO writes
|
|
42
|
+
- **Bus discovery** -- scan the bus and inspect each slave's identity, I/O sizes, and available PDOs
|
|
43
|
+
- **Auto-reconnect** -- background health monitoring with automatic recovery on cable disconnect
|
|
44
|
+
- **Web interface** -- built-in browser GUI for adapter selection, bus scanning, PDO configuration, and going OP
|
|
45
|
+
- **Extensible** -- subclass `GenericSlave` or implement the slave handle interface to build device-specific drivers (see [python-hdrive-etc](https://github.com/henschel-robotics/python-hdrive-etc))
|
|
46
|
+
|
|
47
|
+
## Prerequisites
|
|
48
|
+
|
|
49
|
+
### Windows
|
|
50
|
+
|
|
51
|
+
| Dependency | Purpose | License |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| [Npcap](https://npcap.com/) | Raw Ethernet packet capture | **Free for personal use** (up to 5 systems). Commercial / redistribution requires an [Npcap OEM license](https://npcap.com/oem/). |
|
|
54
|
+
|
|
55
|
+
Install Npcap with **WinPcap API-compatible mode** enabled (checkbox during setup).
|
|
56
|
+
|
|
57
|
+
### Linux
|
|
58
|
+
|
|
59
|
+
| Dependency | Purpose | License |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| `libpcap` | Raw Ethernet packet capture | BSD (free for any use) |
|
|
62
|
+
|
|
63
|
+
Install via your package manager:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Debian / Ubuntu
|
|
67
|
+
sudo apt install libpcap-dev
|
|
68
|
+
|
|
69
|
+
# Fedora / RHEL
|
|
70
|
+
sudo dnf install libpcap-devel
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
On Linux you must run as **root** or grant the `CAP_NET_RAW` capability:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
sudo setcap cap_net_raw=ep $(which python3)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
> Npcap is **not** needed on Linux -- `libpcap` provides the same functionality and is BSD-licensed.
|
|
80
|
+
|
|
81
|
+
### Python
|
|
82
|
+
|
|
83
|
+
- **Python 3.8+**
|
|
84
|
+
- **PySOEM >= 1.1.0** -- Cython wrapper around [SOEM](https://github.com/OpenEtherCATsociety/SOEM) (installed automatically by pip)
|
|
85
|
+
|
|
86
|
+
## Installation
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
pip install ethercat-master
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Or install from source:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
git clone https://github.com/henschel-robotics/python-ethercat-master.git
|
|
96
|
+
cd python-ethercat-master
|
|
97
|
+
pip install -e .
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Quickstart
|
|
101
|
+
|
|
102
|
+
### 1. Find your network adapter
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from ethercat_master import EtherCATBus
|
|
106
|
+
|
|
107
|
+
for a in EtherCATBus.list_adapters():
|
|
108
|
+
print(f"{a.desc} -> {a.name}")
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Copy the adapter `name` (e.g. `\Device\NPF_{GUID}` on Windows, `eth0` on Linux).
|
|
112
|
+
|
|
113
|
+
### 2. Connect and read PDO data
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
from ethercat_master import EtherCATBus, GenericSlave
|
|
117
|
+
import time
|
|
118
|
+
|
|
119
|
+
bus = EtherCATBus(adapter=r"\Device\NPF_{...}", cycle_time_ms=1)
|
|
120
|
+
|
|
121
|
+
slave = GenericSlave(0)
|
|
122
|
+
bus.register_slave(slave)
|
|
123
|
+
bus.open()
|
|
124
|
+
|
|
125
|
+
# Read inputs
|
|
126
|
+
print(slave.input.hex())
|
|
127
|
+
|
|
128
|
+
# Write outputs
|
|
129
|
+
slave.output = bytes([0xFF])
|
|
130
|
+
|
|
131
|
+
time.sleep(2)
|
|
132
|
+
bus.close()
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 3. Discover slaves on the bus
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
slaves = EtherCATBus.discover(adapter=r"\Device\NPF_{...}")
|
|
139
|
+
for s in slaves:
|
|
140
|
+
print(f"[{s['index']}] {s['device_name']} "
|
|
141
|
+
f"In={s['input_bytes']}B Out={s['output_bytes']}B")
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## PDO Configuration
|
|
145
|
+
|
|
146
|
+
Create a `pdo_mapping.json` to control which PDOs are assigned per slave:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"network": {
|
|
151
|
+
"adapter": "\\Device\\NPF_{...}",
|
|
152
|
+
"cycle_ms": 1.0
|
|
153
|
+
},
|
|
154
|
+
"default": {},
|
|
155
|
+
"slaves": {
|
|
156
|
+
"0": {
|
|
157
|
+
"rx_pdo": ["0x1600", "0x1605"],
|
|
158
|
+
"tx_pdo": ["0x1A00", "0x1A05"]
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Pass it when creating the bus:
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
bus = EtherCATBus(adapter=..., cycle_time_ms=1, pdo_config_path="pdo_mapping.json")
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Or use the web interface to scan the bus, select PDOs with checkboxes, and save.
|
|
171
|
+
|
|
172
|
+
## Web Interface
|
|
173
|
+
|
|
174
|
+
Start the built-in web server:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
ecmaster-web
|
|
178
|
+
ecmaster-web --port 8080
|
|
179
|
+
ecmaster-web --pdo-config /path/to/pdo_mapping.json
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Then open `http://localhost:8080` in your browser. The web GUI lets you:
|
|
183
|
+
|
|
184
|
+
- Select a network adapter
|
|
185
|
+
- Scan the bus and view all slaves with their identity and I/O sizes
|
|
186
|
+
- Configure PDO assignments per slave
|
|
187
|
+
- Set the cycle time and go to OP state
|
|
188
|
+
|
|
189
|
+
## Project Structure
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
python-ethercat-master/
|
|
193
|
+
├── ethercat_master/
|
|
194
|
+
│ ├── __init__.py # Public API
|
|
195
|
+
│ ├── bus.py # EtherCATBus — core bus management
|
|
196
|
+
│ ├── slave.py # GenericSlave — universal slave handle
|
|
197
|
+
│ ├── pdo.py # PDO mapping configuration
|
|
198
|
+
│ ├── exceptions.py # Custom exceptions
|
|
199
|
+
│ ├── webserver.py # Built-in web server
|
|
200
|
+
│ └── webgui/
|
|
201
|
+
│ ├── index.html # Web GUI frontend
|
|
202
|
+
│ └── style.css # Stylesheet
|
|
203
|
+
├── examples/
|
|
204
|
+
│ ├── connect.py # Minimal single-slave example
|
|
205
|
+
│ ├── beckhoff.py # Beckhoff EK1100 + terminals
|
|
206
|
+
│ └── mixed_bus.py # HDrive motor + Beckhoff terminals
|
|
207
|
+
├── pdo_mapping.json # Example PDO config
|
|
208
|
+
└── pyproject.toml
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## API Overview
|
|
212
|
+
|
|
213
|
+
### `EtherCATBus`
|
|
214
|
+
|
|
215
|
+
| Method | Description |
|
|
216
|
+
|---|---|
|
|
217
|
+
| `EtherCATBus(adapter, cycle_time_ms, pdo_config_path)` | Create a bus instance |
|
|
218
|
+
| `list_adapters()` | List available network adapters |
|
|
219
|
+
| `discover(adapter, pdo_config_path)` | Scan the bus without going to OP |
|
|
220
|
+
| `register_slave(handle)` | Register a slave handle |
|
|
221
|
+
| `open()` | Configure slaves, map PDOs, start threads, go to OP |
|
|
222
|
+
| `close()` | Stop all slaves and close the connection |
|
|
223
|
+
|
|
224
|
+
### `GenericSlave`
|
|
225
|
+
|
|
226
|
+
| Property / Method | Description |
|
|
227
|
+
|---|---|
|
|
228
|
+
| `GenericSlave(slave_index, use_default_pdo)` | Create a handle for slave at the given index |
|
|
229
|
+
| `slave.input` | Read-only bytes of the last received input PDO |
|
|
230
|
+
| `slave.output` | Read/write bytes for the output PDO |
|
|
231
|
+
|
|
232
|
+
### Exceptions
|
|
233
|
+
|
|
234
|
+
| Exception | When |
|
|
235
|
+
|---|---|
|
|
236
|
+
| `ConnectionError` | Adapter not found, no slaves, state transition failed |
|
|
237
|
+
| `CommunicationError` | Bus communication lost or timed out |
|
|
238
|
+
| `ConfigurationError` | PDO mapping or `config_map()` failed |
|
|
239
|
+
|
|
240
|
+
## Background Threads
|
|
241
|
+
|
|
242
|
+
When `bus.open()` is called, three background threads are started:
|
|
243
|
+
|
|
244
|
+
| Thread | Interval | Purpose |
|
|
245
|
+
|---|---|---|
|
|
246
|
+
| ProcessData | 1 ms | Raw EtherCAT frame send/receive |
|
|
247
|
+
| PDO Update | configurable | Decode RX / encode TX per slave |
|
|
248
|
+
| State Check | 300 ms | Health monitoring, auto-reconnect |
|
|
249
|
+
|
|
250
|
+
## License
|
|
251
|
+
|
|
252
|
+
This project is MIT-licensed -- see [pyproject.toml](pyproject.toml).
|
|
253
|
+
|
|
254
|
+
Copyright (c) Henschel Robotics GmbH
|
|
255
|
+
|
|
256
|
+
### Third-party license notice
|
|
257
|
+
|
|
258
|
+
| Component | License | Notes |
|
|
259
|
+
|---|---|---|
|
|
260
|
+
| [PySOEM](https://github.com/bnjmnp/pysoem) | MIT | Cython wrapper (installed via pip) |
|
|
261
|
+
| [SOEM](https://github.com/OpenEtherCATsociety/SOEM) | **GPLv3 / Commercial** | Bundled inside PySOEM. As of SOEM 2.0 the license is GPLv3 or a commercial license from [rt-labs](https://rt-labs.com/). If GPLv3 is incompatible with your product, contact rt-labs for a commercial SOEM license. |
|
|
262
|
+
| [Npcap](https://npcap.com/) (Windows only) | **Proprietary** | Free for personal use (≤ 5 installs). Commercial use or redistribution requires an [Npcap OEM license](https://npcap.com/oem/). |
|
|
263
|
+
| [libpcap](https://www.tcpdump.org/) (Linux only) | BSD | Free for any use, no restrictions. |
|
|
264
|
+
|
|
265
|
+
> **Important for commercial products:** If you ship a product that includes this library, you need to consider the SOEM (GPLv3) and Npcap (proprietary) license obligations. On Linux, only the SOEM license applies since libpcap is BSD.
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# EtherCAT Master
|
|
2
|
+
|
|
3
|
+
Generic EtherCAT master library built on [PySOEM](https://github.com/bnjmnp/pysoem). Provides bus management, slave discovery, configurable PDO mapping, automatic reconnection, and a built-in web interface for configuration.
|
|
4
|
+
|
|
5
|
+
Developed by [Henschel Robotics GmbH](https://henschel-robotics.ch).
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Bus management** -- connect, configure, and run an EtherCAT bus with one or more slaves
|
|
10
|
+
- **Generic slave handle** -- read/write raw PDO bytes for any device (Beckhoff terminals, servos, I/O modules, ...)
|
|
11
|
+
- **PDO mapping** -- configure SyncManager assignments per slave via a JSON file or SDO writes
|
|
12
|
+
- **Bus discovery** -- scan the bus and inspect each slave's identity, I/O sizes, and available PDOs
|
|
13
|
+
- **Auto-reconnect** -- background health monitoring with automatic recovery on cable disconnect
|
|
14
|
+
- **Web interface** -- built-in browser GUI for adapter selection, bus scanning, PDO configuration, and going OP
|
|
15
|
+
- **Extensible** -- subclass `GenericSlave` or implement the slave handle interface to build device-specific drivers (see [python-hdrive-etc](https://github.com/henschel-robotics/python-hdrive-etc))
|
|
16
|
+
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
### Windows
|
|
20
|
+
|
|
21
|
+
| Dependency | Purpose | License |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| [Npcap](https://npcap.com/) | Raw Ethernet packet capture | **Free for personal use** (up to 5 systems). Commercial / redistribution requires an [Npcap OEM license](https://npcap.com/oem/). |
|
|
24
|
+
|
|
25
|
+
Install Npcap with **WinPcap API-compatible mode** enabled (checkbox during setup).
|
|
26
|
+
|
|
27
|
+
### Linux
|
|
28
|
+
|
|
29
|
+
| Dependency | Purpose | License |
|
|
30
|
+
|---|---|---|
|
|
31
|
+
| `libpcap` | Raw Ethernet packet capture | BSD (free for any use) |
|
|
32
|
+
|
|
33
|
+
Install via your package manager:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Debian / Ubuntu
|
|
37
|
+
sudo apt install libpcap-dev
|
|
38
|
+
|
|
39
|
+
# Fedora / RHEL
|
|
40
|
+
sudo dnf install libpcap-devel
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
On Linux you must run as **root** or grant the `CAP_NET_RAW` capability:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
sudo setcap cap_net_raw=ep $(which python3)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
> Npcap is **not** needed on Linux -- `libpcap` provides the same functionality and is BSD-licensed.
|
|
50
|
+
|
|
51
|
+
### Python
|
|
52
|
+
|
|
53
|
+
- **Python 3.8+**
|
|
54
|
+
- **PySOEM >= 1.1.0** -- Cython wrapper around [SOEM](https://github.com/OpenEtherCATsociety/SOEM) (installed automatically by pip)
|
|
55
|
+
|
|
56
|
+
## Installation
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install ethercat-master
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Or install from source:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
git clone https://github.com/henschel-robotics/python-ethercat-master.git
|
|
66
|
+
cd python-ethercat-master
|
|
67
|
+
pip install -e .
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Quickstart
|
|
71
|
+
|
|
72
|
+
### 1. Find your network adapter
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
from ethercat_master import EtherCATBus
|
|
76
|
+
|
|
77
|
+
for a in EtherCATBus.list_adapters():
|
|
78
|
+
print(f"{a.desc} -> {a.name}")
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Copy the adapter `name` (e.g. `\Device\NPF_{GUID}` on Windows, `eth0` on Linux).
|
|
82
|
+
|
|
83
|
+
### 2. Connect and read PDO data
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from ethercat_master import EtherCATBus, GenericSlave
|
|
87
|
+
import time
|
|
88
|
+
|
|
89
|
+
bus = EtherCATBus(adapter=r"\Device\NPF_{...}", cycle_time_ms=1)
|
|
90
|
+
|
|
91
|
+
slave = GenericSlave(0)
|
|
92
|
+
bus.register_slave(slave)
|
|
93
|
+
bus.open()
|
|
94
|
+
|
|
95
|
+
# Read inputs
|
|
96
|
+
print(slave.input.hex())
|
|
97
|
+
|
|
98
|
+
# Write outputs
|
|
99
|
+
slave.output = bytes([0xFF])
|
|
100
|
+
|
|
101
|
+
time.sleep(2)
|
|
102
|
+
bus.close()
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 3. Discover slaves on the bus
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
slaves = EtherCATBus.discover(adapter=r"\Device\NPF_{...}")
|
|
109
|
+
for s in slaves:
|
|
110
|
+
print(f"[{s['index']}] {s['device_name']} "
|
|
111
|
+
f"In={s['input_bytes']}B Out={s['output_bytes']}B")
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## PDO Configuration
|
|
115
|
+
|
|
116
|
+
Create a `pdo_mapping.json` to control which PDOs are assigned per slave:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"network": {
|
|
121
|
+
"adapter": "\\Device\\NPF_{...}",
|
|
122
|
+
"cycle_ms": 1.0
|
|
123
|
+
},
|
|
124
|
+
"default": {},
|
|
125
|
+
"slaves": {
|
|
126
|
+
"0": {
|
|
127
|
+
"rx_pdo": ["0x1600", "0x1605"],
|
|
128
|
+
"tx_pdo": ["0x1A00", "0x1A05"]
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Pass it when creating the bus:
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
bus = EtherCATBus(adapter=..., cycle_time_ms=1, pdo_config_path="pdo_mapping.json")
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Or use the web interface to scan the bus, select PDOs with checkboxes, and save.
|
|
141
|
+
|
|
142
|
+
## Web Interface
|
|
143
|
+
|
|
144
|
+
Start the built-in web server:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
ecmaster-web
|
|
148
|
+
ecmaster-web --port 8080
|
|
149
|
+
ecmaster-web --pdo-config /path/to/pdo_mapping.json
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Then open `http://localhost:8080` in your browser. The web GUI lets you:
|
|
153
|
+
|
|
154
|
+
- Select a network adapter
|
|
155
|
+
- Scan the bus and view all slaves with their identity and I/O sizes
|
|
156
|
+
- Configure PDO assignments per slave
|
|
157
|
+
- Set the cycle time and go to OP state
|
|
158
|
+
|
|
159
|
+
## Project Structure
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
python-ethercat-master/
|
|
163
|
+
├── ethercat_master/
|
|
164
|
+
│ ├── __init__.py # Public API
|
|
165
|
+
│ ├── bus.py # EtherCATBus — core bus management
|
|
166
|
+
│ ├── slave.py # GenericSlave — universal slave handle
|
|
167
|
+
│ ├── pdo.py # PDO mapping configuration
|
|
168
|
+
│ ├── exceptions.py # Custom exceptions
|
|
169
|
+
│ ├── webserver.py # Built-in web server
|
|
170
|
+
│ └── webgui/
|
|
171
|
+
│ ├── index.html # Web GUI frontend
|
|
172
|
+
│ └── style.css # Stylesheet
|
|
173
|
+
├── examples/
|
|
174
|
+
│ ├── connect.py # Minimal single-slave example
|
|
175
|
+
│ ├── beckhoff.py # Beckhoff EK1100 + terminals
|
|
176
|
+
│ └── mixed_bus.py # HDrive motor + Beckhoff terminals
|
|
177
|
+
├── pdo_mapping.json # Example PDO config
|
|
178
|
+
└── pyproject.toml
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## API Overview
|
|
182
|
+
|
|
183
|
+
### `EtherCATBus`
|
|
184
|
+
|
|
185
|
+
| Method | Description |
|
|
186
|
+
|---|---|
|
|
187
|
+
| `EtherCATBus(adapter, cycle_time_ms, pdo_config_path)` | Create a bus instance |
|
|
188
|
+
| `list_adapters()` | List available network adapters |
|
|
189
|
+
| `discover(adapter, pdo_config_path)` | Scan the bus without going to OP |
|
|
190
|
+
| `register_slave(handle)` | Register a slave handle |
|
|
191
|
+
| `open()` | Configure slaves, map PDOs, start threads, go to OP |
|
|
192
|
+
| `close()` | Stop all slaves and close the connection |
|
|
193
|
+
|
|
194
|
+
### `GenericSlave`
|
|
195
|
+
|
|
196
|
+
| Property / Method | Description |
|
|
197
|
+
|---|---|
|
|
198
|
+
| `GenericSlave(slave_index, use_default_pdo)` | Create a handle for slave at the given index |
|
|
199
|
+
| `slave.input` | Read-only bytes of the last received input PDO |
|
|
200
|
+
| `slave.output` | Read/write bytes for the output PDO |
|
|
201
|
+
|
|
202
|
+
### Exceptions
|
|
203
|
+
|
|
204
|
+
| Exception | When |
|
|
205
|
+
|---|---|
|
|
206
|
+
| `ConnectionError` | Adapter not found, no slaves, state transition failed |
|
|
207
|
+
| `CommunicationError` | Bus communication lost or timed out |
|
|
208
|
+
| `ConfigurationError` | PDO mapping or `config_map()` failed |
|
|
209
|
+
|
|
210
|
+
## Background Threads
|
|
211
|
+
|
|
212
|
+
When `bus.open()` is called, three background threads are started:
|
|
213
|
+
|
|
214
|
+
| Thread | Interval | Purpose |
|
|
215
|
+
|---|---|---|
|
|
216
|
+
| ProcessData | 1 ms | Raw EtherCAT frame send/receive |
|
|
217
|
+
| PDO Update | configurable | Decode RX / encode TX per slave |
|
|
218
|
+
| State Check | 300 ms | Health monitoring, auto-reconnect |
|
|
219
|
+
|
|
220
|
+
## License
|
|
221
|
+
|
|
222
|
+
This project is MIT-licensed -- see [pyproject.toml](pyproject.toml).
|
|
223
|
+
|
|
224
|
+
Copyright (c) Henschel Robotics GmbH
|
|
225
|
+
|
|
226
|
+
### Third-party license notice
|
|
227
|
+
|
|
228
|
+
| Component | License | Notes |
|
|
229
|
+
|---|---|---|
|
|
230
|
+
| [PySOEM](https://github.com/bnjmnp/pysoem) | MIT | Cython wrapper (installed via pip) |
|
|
231
|
+
| [SOEM](https://github.com/OpenEtherCATsociety/SOEM) | **GPLv3 / Commercial** | Bundled inside PySOEM. As of SOEM 2.0 the license is GPLv3 or a commercial license from [rt-labs](https://rt-labs.com/). If GPLv3 is incompatible with your product, contact rt-labs for a commercial SOEM license. |
|
|
232
|
+
| [Npcap](https://npcap.com/) (Windows only) | **Proprietary** | Free for personal use (≤ 5 installs). Commercial use or redistribution requires an [Npcap OEM license](https://npcap.com/oem/). |
|
|
233
|
+
| [libpcap](https://www.tcpdump.org/) (Linux only) | BSD | Free for any use, no restrictions. |
|
|
234
|
+
|
|
235
|
+
> **Important for commercial products:** If you ship a product that includes this library, you need to consider the SOEM (GPLv3) and Npcap (proprietary) license obligations. On Linux, only the SOEM license applies since libpcap is BSD.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""
|
|
2
|
+
EtherCAT Master
|
|
3
|
+
~~~~~~~~~~~~~~~
|
|
4
|
+
|
|
5
|
+
Generic EtherCAT master library built on PySOEM. Provides bus management,
|
|
6
|
+
slave discovery, PDO mapping configuration, and automatic reconnection.
|
|
7
|
+
|
|
8
|
+
Basic usage::
|
|
9
|
+
|
|
10
|
+
from ethercat_master import EtherCATBus, GenericSlave
|
|
11
|
+
|
|
12
|
+
bus = EtherCATBus(adapter=r"\\Device\\NPF_{...}", cycle_time_ms=1)
|
|
13
|
+
slave = GenericSlave(0)
|
|
14
|
+
bus.register_slave(slave)
|
|
15
|
+
bus.open()
|
|
16
|
+
print(slave.input.hex())
|
|
17
|
+
bus.close()
|
|
18
|
+
|
|
19
|
+
Bus discovery::
|
|
20
|
+
|
|
21
|
+
from ethercat_master import EtherCATBus
|
|
22
|
+
slaves = EtherCATBus.discover(adapter=r"\\Device\\NPF_{...}")
|
|
23
|
+
|
|
24
|
+
:copyright: (c) Henschel Robotics GmbH
|
|
25
|
+
:license: MIT
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from .bus import EtherCATBus
|
|
29
|
+
from .slave import GenericSlave
|
|
30
|
+
from .pdo import load_pdo_config, get_slave_pdo, configure_pdo_mapping
|
|
31
|
+
from .exceptions import EtherCATError, ConnectionError, CommunicationError, ConfigurationError
|
|
32
|
+
from .network_test import NetworkLatencyTest
|
|
33
|
+
|
|
34
|
+
__version__ = "0.1.0"
|
|
35
|
+
__all__ = [
|
|
36
|
+
"EtherCATBus",
|
|
37
|
+
"GenericSlave",
|
|
38
|
+
"NetworkLatencyTest",
|
|
39
|
+
"load_pdo_config",
|
|
40
|
+
"get_slave_pdo",
|
|
41
|
+
"configure_pdo_mapping",
|
|
42
|
+
"EtherCATError",
|
|
43
|
+
"ConnectionError",
|
|
44
|
+
"CommunicationError",
|
|
45
|
+
"ConfigurationError",
|
|
46
|
+
"__version__",
|
|
47
|
+
]
|