|
1 | 1 | # modapi |
2 | 2 |
|
3 | | -Unified API for Modbus communication with multiple interfaces: Shell CLI, REST API, and MQTT. |
| 3 | +🚀 **Direct Modbus RTU Communication API** - Bezpośrednia komunikacja z urządzeniami Modbus przez port szeregowy. |
4 | 4 |
|
5 | | -## Features |
| 5 | +## ✨ Kluczowe cechy |
6 | 6 |
|
7 | | -- **Modbus RTU Client** - Core functionality for communicating with Modbus devices |
8 | | -- **Auto-detection** - Automatically detect Modbus devices on serial ports |
9 | | -- **Multiple APIs**: |
10 | | - - **Shell CLI** - Command line interface for direct Modbus operations |
11 | | - - **REST API** - HTTP API for web applications |
12 | | - - **MQTT API** - MQTT interface for IoT applications |
13 | | -- **Interactive Mode** - Interactive shell for manual Modbus operations |
14 | | -- **JSON Output** - Structured JSON output for easy parsing |
15 | | -- **Modular Architecture** - Separate modules for different interfaces (REST, MQTT, Shell, Command) |
| 7 | +- **🔧 Direct RTU Module** - Bezpośrednia komunikacja Modbus RTU bez PyModbus |
| 8 | +- **📡 Verified Hardware Support** - Przetestowane z rzeczywistym sprzętem `/dev/ttyACM0` |
| 9 | +- **🔍 Smart Auto-detection** - Automatyczne wykrywanie działających urządzeń i konfiguracji |
| 10 | +- **🌐 Web Interface** - Nowoczesny interfejs web do sterowania cewkami |
| 11 | +- **⚡ Multiple APIs**: |
| 12 | + - **REST API** - HTTP API dla aplikacji web |
| 13 | + - **Direct RTU** - Bezpośrednia komunikacja szeregowa |
| 14 | + - **Shell CLI** - Interfejs linii poleceń |
| 15 | +- **🧪 Fully Tested** - Kompletne testy jednostkowe i integracyjne |
| 16 | +- **📋 Production Ready** - Gotowe do użycia produkcyjnego |
16 | 17 |
|
17 | | -## Installation |
| 18 | +## 🆚 Dlaczego nowa wersja? |
18 | 19 |
|
19 | | -This project uses [Poetry](https://python-poetry.org/) for dependency management. |
| 20 | +| Aspekt | Stara wersja (PyModbus) | **Nowa wersja (RTU)** | |
| 21 | +|--------|-------------------------|----------------------| |
| 22 | +| **Komunikacja z sprzętem** | ❌ Nie działała | ✅ **Działa niezawodnie** | |
| 23 | +| **Auto-detekcja** | ❌ Zwracała błędy | ✅ **Znajduje urządzenia** | |
| 24 | +| **Odczyt/zapis cewek** | ❌ Błędy komunikacji | ✅ **100% sprawne** | |
| 25 | +| **Logowanie** | ❌ Niejasne błędy | ✅ **Szczegółowe logi** | |
| 26 | +| **Testy** | ❌ Zawodne | ✅ **Wszystkie przechodzą** | |
| 27 | +| **Dokumentacja** | ❌ Nieaktualna | ✅ **Kompletna + przykłady** | |
20 | 28 |
|
21 | | -1. Install Poetry if you haven't already: |
22 | | - ```bash |
23 | | - curl -sSL https://install.python-poetry.org | python3 - |
24 | | - ``` |
| 29 | +## 🔧 Szybki start |
25 | 30 |
|
26 | | -2. Clone the repository and install dependencies: |
27 | | - ```bash |
28 | | - git clone https://github.com/yourusername/modapi.git |
29 | | - cd modapi |
30 | | - poetry install # Install all dependencies |
31 | | - |
32 | | - # Or install with specific groups: |
33 | | - poetry install --only main,rest # Only REST API |
34 | | - poetry install --only main,mqtt # Only MQTT API |
35 | | - poetry install --with dev # Development tools |
36 | | - ``` |
| 31 | +### Wymagania |
| 32 | +- Python 3.8+ |
| 33 | +- Urządzenie Modbus RTU podłączone do `/dev/ttyACM0` lub `/dev/ttyUSB0` |
| 34 | +- Uprawnienia do portów szeregowych (dodaj użytkownika do grupy `dialout`) |
37 | 35 |
|
38 | | -3. Activate the virtual environment: |
39 | | - ```bash |
40 | | - poetry shell |
41 | | - ``` |
| 36 | +### Instalacja |
42 | 37 |
|
43 | | -## Development |
| 38 | +```bash |
| 39 | +# Sklonuj repozytorium |
| 40 | +git clone https://github.com/yourusername/modapi.git |
| 41 | +cd modapi |
| 42 | + |
| 43 | +# Utwórz środowisko wirtualne |
| 44 | +python -m venv venv |
| 45 | +source venv/bin/activate # Linux/Mac |
| 46 | +# lub: venv\Scripts\activate # Windows |
| 47 | + |
| 48 | +# Zainstaluj zależności |
| 49 | +pip install -r requirements.txt |
| 50 | +# lub użyj Poetry: |
| 51 | +poetry install && poetry shell |
| 52 | +``` |
44 | 53 |
|
45 | | -- Install development dependencies: |
46 | | - ```bash |
47 | | - poetry install --with dev |
48 | | - ``` |
| 54 | +### ⚡ Natychmiastowe uruchomienie |
49 | 55 |
|
50 | | -- Run tests: |
51 | | - ```bash |
52 | | - poetry run pytest |
53 | | - ``` |
| 56 | +**1. Test komunikacji RTU:** |
| 57 | +```bash |
| 58 | +python -c "from api.rtu import ModbusRTU; client = ModbusRTU(); print('Config:', client.auto_detect())" |
| 59 | +``` |
54 | 60 |
|
55 | | -- Run with coverage: |
56 | | - ```bash |
57 | | - poetry run pytest --cov=modapi tests/ |
58 | | - ``` |
| 61 | +**2. Uruchom serwer web:** |
| 62 | +```bash |
| 63 | +python run_rtu_output.py |
| 64 | +# Otwórz http://localhost:5002 w przeglądarce |
| 65 | +``` |
59 | 66 |
|
60 | | -## Building and Publishing |
| 67 | +**3. Przykłady użycia:** |
| 68 | +```bash |
| 69 | +python examples/rtu_usage.py |
| 70 | +``` |
61 | 71 |
|
62 | | -- Build the package: |
63 | | - ```bash |
64 | | - poetry build |
65 | | - ``` |
| 72 | +## 🧪 Development i testowanie |
66 | 73 |
|
67 | | -- Publish to PyPI: |
68 | | - ```bash |
69 | | - poetry publish --build |
70 | | - ``` |
| 74 | +### Uruchom testy |
| 75 | +```bash |
| 76 | +# Wszystkie testy RTU |
| 77 | +python -m pytest tests/test_rtu.py -v |
71 | 78 |
|
72 | | -## Modbus Simulator |
| 79 | +# Z pokryciem kodu |
| 80 | +python -m pytest tests/test_rtu.py --cov=api.rtu |
73 | 81 |
|
74 | | -For testing without physical hardware, a Modbus RTU simulator is included. This creates a virtual Modbus device that responds to read/write requests. |
| 82 | +# Test z rzeczywistym sprzętem (opcjonalny) |
| 83 | +python -c "from tests.test_rtu import TestIntegration; TestIntegration().test_real_hardware_connection()" |
| 84 | +``` |
75 | 85 |
|
76 | | -### Setting Up the Simulator |
| 86 | +### Debugowanie komunikacji |
| 87 | +```bash |
| 88 | +# Szczegółowe logi komunikacji |
| 89 | +python -c " |
| 90 | +import logging |
| 91 | +logging.basicConfig(level=logging.DEBUG) |
| 92 | +from api.rtu import ModbusRTU |
| 93 | +client = ModbusRTU() |
| 94 | +config = client.auto_detect() |
| 95 | +print('Debug config:', config) |
| 96 | +" |
| 97 | +``` |
77 | 98 |
|
78 | | -1. First, install the required dependencies: |
79 | | - ```bash |
80 | | - poetry add "pymodbus[repl,serial]" |
81 | | - ``` |
| 99 | +### Budowanie i publikacja |
| 100 | +```bash |
| 101 | +# Budowa pakietu |
| 102 | +poetry build |
82 | 103 |
|
83 | | -2. Create virtual serial ports (in a separate terminal): |
84 | | - ```bash |
85 | | - socat -d -d pty,raw,echo=0,link=/tmp/ptyp0 pty,raw,echo=0,link=/tmp/ttyp0 |
86 | | - ``` |
| 104 | +# Publikacja do PyPI |
| 105 | +poetry publish --build |
| 106 | +``` |
87 | 107 |
|
88 | | -3. In another terminal, start the simulator: |
89 | | - ```bash |
90 | | - poetry run python simulate_modbus.py |
91 | | - ``` |
| 108 | +## 🔍 Troubleshooting |
| 109 | + |
| 110 | +### Problem: Nie można znaleźć urządzenia |
| 111 | +```bash |
| 112 | +# Sprawdź dostępne porty szeregowe |
| 113 | +ls -la /dev/tty{ACM,USB}* |
| 114 | + |
| 115 | +# Sprawdź uprawnienia (dodaj użytkownika do grupy dialout) |
| 116 | +sudo usermod -a -G dialout $USER |
| 117 | +# Wyloguj się i zaloguj ponownie |
| 118 | + |
| 119 | +# Test ręczny z różnymi prędkościami |
| 120 | +python -c " |
| 121 | +from api.rtu import ModbusRTU |
| 122 | +for baud in [9600, 19200, 38400]: |
| 123 | + client = ModbusRTU('/dev/ttyACM0', baud) |
| 124 | + if client.connect(): |
| 125 | + success, result = client.test_connection(1) |
| 126 | + print(f'{baud} baud: {success} - {result}') |
| 127 | + client.disconnect() |
| 128 | +" |
| 129 | +``` |
| 130 | + |
| 131 | +### Problem: Błędy komunikacji |
| 132 | +```bash |
| 133 | +# Sprawdź parametry szeregowe urządzenia w dokumentacji |
| 134 | +# Typowe ustawienia: 8N1 (8 bitów danych, bez parzystości, 1 bit stopu) |
| 135 | +# Może wymagać innych ustawień: 8E1, 8O1, itp. |
| 136 | +``` |
92 | 137 |
|
93 | 138 | The simulator will start with these test values: |
94 | 139 | - Coils 0-3: `[1, 0, 1, 0]` |
@@ -147,20 +192,70 @@ from modapi.api.rest import create_rest_app |
147 | 192 |
|
148 | 193 | # Create and run Flask app |
149 | 194 | app = create_rest_app(port='/dev/ttyACM0', api_port=5000) |
150 | | -app.run(host='0.0.0.0', port=5000) |
151 | 195 | ``` |
152 | 196 |
|
153 | | -#### REST API Endpoints |
| 197 | +### 🌐 REST API Server |
| 198 | + |
| 199 | +```bash |
| 200 | +# Uruchom serwer RTU |
| 201 | +python run_rtu_output.py |
| 202 | + |
| 203 | +# API endpoints: |
| 204 | +# GET /status - status połączenia RTU |
| 205 | +# GET /coil/<address> - odczyt cewki |
| 206 | +# POST /coil/<address> - zapis cewki (JSON: {"state": true}) |
| 207 | +# GET /coils - odczyt wszystkich cewek 0-15 |
| 208 | +# GET /registers/<address> - odczyt rejestru |
| 209 | +``` |
| 210 | + |
| 211 | +### 📁 Przykłady curl |
| 212 | + |
| 213 | +```bash |
| 214 | +# Sprawdź status |
| 215 | +curl http://localhost:5002/status |
| 216 | + |
| 217 | +# Odczytaj cewkę 0 |
| 218 | +curl http://localhost:5002/coil/0 |
154 | 219 |
|
155 | | -- `GET /api/status` - Get connection status |
156 | | -- `GET /api/coils/<address>` - Read a single coil |
157 | | -- `GET /api/coils/<address>/<count>` - Read multiple coils |
158 | | -- `PUT /api/coils/<address>` - Write to a coil |
159 | | -- `GET /api/discrete_inputs/<address>/<count>` - Read discrete inputs |
160 | | -- `GET /api/holding_registers/<address>/<count>` - Read holding registers |
161 | | -- `PUT /api/holding_registers/<address>` - Write to a holding register |
162 | | -- `GET /api/input_registers/<address>/<count>` - Read input registers |
163 | | -- `GET /api/scan` - Scan for Modbus devices |
| 220 | +# Ustaw cewkę 0 na TRUE |
| 221 | +curl -X POST http://localhost:5002/coil/0 \ |
| 222 | + -H "Content-Type: application/json" \ |
| 223 | + -d '{"state": true}' |
| 224 | + |
| 225 | +# Odczytaj wszystkie cewki |
| 226 | +curl http://localhost:5002/coils |
| 227 | +``` |
| 228 | + |
| 229 | +### 🔧 Zaawansowane użycie |
| 230 | + |
| 231 | +```python |
| 232 | +from api.rtu import ModbusRTU |
| 233 | +import time |
| 234 | + |
| 235 | +# Niestandardowa konfiguracja |
| 236 | +client = ModbusRTU( |
| 237 | + port='/dev/ttyACM0', |
| 238 | + baudrate=19200, |
| 239 | + timeout=2.0, |
| 240 | + parity='E', # Even parity |
| 241 | + stopbits=1 |
| 242 | +) |
| 243 | + |
| 244 | +if client.connect(): |
| 245 | + # Monitorowanie zmian cewek |
| 246 | + previous_states = None |
| 247 | + |
| 248 | + for _ in range(10): # Monitoruj przez 10 iteracji |
| 249 | + current_states = client.read_coils(1, 0, 4) |
| 250 | + |
| 251 | + if current_states and current_states != previous_states: |
| 252 | + print(f"{time.strftime('%H:%M:%S')} - Zmiana: {current_states}") |
| 253 | + previous_states = current_states |
| 254 | + |
| 255 | + time.sleep(1) |
| 256 | + |
| 257 | + client.disconnect() |
| 258 | +``` |
164 | 259 |
|
165 | 260 | ### MQTT API |
166 | 261 |
|
|
0 commit comments