modapi


Namemodapi JSON
Version 0.2.4 PyPI version JSON
download
home_pageNone
SummaryUnified API for Modbus communication with support for RTU, TCP, and REST APIs
upload_time2025-08-01 21:33:12
maintainerNone
docs_urlNone
authorTom Sapletta
requires_python<4.0,>=3.10
licenseApache-2.0
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # modapi

🚀 **Direct Modbus RTU Communication API** - Bezpośrednia komunikacja z urządzeniami Modbus przez port szeregowy.

## ✨ Kluczowe cechy

- **🔧 Direct RTU Module** - Bezpośrednia komunikacja Modbus RTU bez PyModbus
- **📡 Verified Hardware Support** - Przetestowane z rzeczywistym sprzętem `/dev/ttyACM0`
- **🔍 Smart Auto-detection** - Automatyczne wykrywanie działających urządzeń i konfiguracji
- **🌐 Web Interface** - Nowoczesny interfejs web do sterowania cewkami
- **💪 Enhanced CRC Handling** - Zaawansowana obsługa CRC dla urządzeń Waveshare
- **🔄 Robust Error Recovery** - Inteligentne odzyskiwanie po błędach komunikacji
- **⚡ Multiple APIs**:
  - **REST API** - HTTP API dla aplikacji web
  - **Direct RTU** - Bezpośrednia komunikacja szeregowa
  - **Shell CLI** - Interfejs linii poleceń
- **🧪 Fully Tested** - Kompletne testy jednostkowe i integracyjne
- **📋 Production Ready** - Gotowe do użycia produkcyjnego

## 🆚 Dlaczego nowa wersja?

| Aspekt | Stara wersja (PyModbus) | **Nowa wersja (RTU)** |
|--------|-------------------------|----------------------|
| **Komunikacja z sprzętem** | ❌ Nie działała | ✅ **Działa niezawodnie** |
| **Auto-detekcja** | ❌ Zwracała błędy | ✅ **Znajduje urządzenia** |
| **Odczyt/zapis cewek** | ❌ Błędy komunikacji | ✅ **100% sprawne** |
| **Obsługa CRC** | ❌ Tylko standardowa | ✅ **Zaawansowana dla Waveshare** |
| **Odporność na błędy** | ❌ Niska | ✅ **Wysoka z auto-korektą** |
| **Logowanie** | ❌ Niejasne błędy | ✅ **Szczegółowe logi** |
| **Testy** | ❌ Zawodne | ✅ **Wszystkie przechodzą** |
| **Dokumentacja** | ❌ Nieaktualna | ✅ **Kompletna + przykłady** |

## 🔧 Szybki start

### Wymagania
- Python 3.8+
- Urządzenie Modbus RTU podłączone do `/dev/ttyACM0` lub `/dev/ttyUSB0`
- Uprawnienia do portów szeregowych (dodaj użytkownika do grupy `dialout`)

### Instalacja

```bash
# Sklonuj repozytorium
git clone https://github.com/yourusername/modapi.git
cd modapi

# Utwórz środowisko wirtualne
python -m venv venv
source venv/bin/activate  # Linux/Mac
# lub: venv\Scripts\activate  # Windows

# Zainstaluj zależności
pip install -r requirements.txt
# lub użyj Poetry:
poetry install && poetry shell
```

### ⚡ Natychmiastowe uruchomienie

**1. Test komunikacji RTU:**
```bash
python -c "from api.rtu import ModbusRTU; client = ModbusRTU(); print('Config:', client.auto_detect())"
```

**2. Uruchom serwer web:**
```bash
python run_rtu_output.py
# Otwórz http://localhost:5005 w przeglądarce
```

**3. Przykłady użycia:**
```bash
python examples/rtu_usage.py
```

## 🧪 Development i testowanie

### Uruchom testy
```bash
# Wszystkie testy RTU
python -m pytest tests/test_rtu.py -v

# Z pokryciem kodu
python -m pytest tests/test_rtu.py --cov=api.rtu

# Test z rzeczywistym sprzętem (opcjonalny)
python -c "from tests.test_rtu import TestIntegration; TestIntegration().test_real_hardware_connection()"
```

### Debugowanie komunikacji
```bash
# Szczegółowe logi komunikacji
python -c "
import logging
logging.basicConfig(level=logging.DEBUG)
from api.rtu import ModbusRTU
client = ModbusRTU()
config = client.auto_detect()
print('Debug config:', config)
"
```

### Budowanie i publikacja
```bash
# Budowa pakietu
poetry build

# Publikacja do PyPI
poetry publish --build
```

## 🔍 Troubleshooting

### Problem: Nie można znaleźć urządzenia
```bash
# Sprawdź dostępne porty szeregowe
ls -la /dev/tty{ACM,USB}*

# Sprawdź uprawnienia (dodaj użytkownika do grupy dialout)
sudo usermod -a -G dialout $USER
# Wyloguj się i zaloguj ponownie

# Test ręczny z różnymi prędkościami
python -c "
from api.rtu import ModbusRTU
for baud in [9600, 19200, 38400]:
    client = ModbusRTU('/dev/ttyACM0', baud)
    if client.connect():
        success, result = client.test_connection(1)
        print(f'{baud} baud: {success} - {result}')
        client.disconnect()
"
```

### Problem: Błędy komunikacji i CRC
```bash
# Sprawdź parametry szeregowe urządzenia w dokumentacji
# Typowe ustawienia: 8N1 (8 bitów danych, bez parzystości, 1 bit stopu)
# Może wymagać innych ustawień: 8E1, 8O1, itp.

# Włącz szczegółowe logowanie dla debugowania CRC
python -c "
import logging
logging.basicConfig(level=logging.DEBUG)
from api.rtu import ModbusRTU
client = ModbusRTU('/dev/ttyACM0')
client.connect()
# Dla urządzeń Waveshare - moduł automatycznie obsługuje alternatywne CRC
result = client.read_coils(1, 0, 8)
print(f'Odczyt cewek z obsługą alternatywnego CRC: {result}')
client.disconnect()
"
```

### Problem: Urządzenia Waveshare zwracają błędy funkcji
```bash
# Moduł RTU zawiera specjalną obsługę dla urządzeń Waveshare
# Automatycznie obsługuje:
# - Alternatywne obliczenia CRC
# - Niezgodności ID jednostki (broadcast, exception responses)
# - Mapowanie kodów funkcji
# - Szczegółowe komunikaty błędów dla wyjątków Modbus

# Test z włączonym debugowaniem
python -c "
import logging
logging.basicConfig(level=logging.DEBUG)
from api.rtu import ModbusRTU
client = ModbusRTU('/dev/ttyACM0')
client.connect()
# Próba odczytu rejestrów wejściowych (może zwrócić wyjątek na niektórych urządzeniach)
result = client.read_input_registers(1, 0, 4)
print(f'Wynik z obsługą wyjątków Waveshare: {result}')
client.disconnect()
"
```

   The simulator will start with these test values:
   - Coils 0-3: `[1, 0, 1, 0]`
   - Holding Registers 0-2: `[1234, 5678, 9012]`

4. Configure your `.env` file to use the virtual port:
   ```ini
   MODBUS_PORT=/tmp/ttyp0
   MODBUS_BAUDRATE=9600
   MODBUS_TIMEOUT=0.1
   ```

5. You can now run the API server or CLI commands to interact with the simulator.

## Usage

### Command Line Interface

The modapi CLI supports multiple subcommands:

```bash
# Direct command execution
modapi cmd wc 0 1       # Write value 1 to coil at address 0
modapi cmd rc 0 8       # Read 8 coils starting at address 0
modapi cmd rh 0 5       # Read 5 holding registers starting at address 0
modapi cmd wh 0 42      # Write value 42 to holding register at address 0

# Interactive shell
modapi shell

# REST API server
modapi rest --host 0.0.0.0 --port 5005

# MQTT client
modapi mqtt --broker localhost --port 1883

# Scan for Modbus devices
modapi scan

# With options
modapi cmd --verbose rc 0 8    # Verbose mode
modapi cmd --modbus-port /dev/ttyACM0 wc 0 1  # Specify port
```

For backward compatibility, you can also use the direct command format:
```bash
# These are automatically converted to the new format
./run_cli.py wc 0 1       # Equivalent to: modapi cmd wc 0 1
./run_cli.py rc 0 8       # Equivalent to: modapi cmd rc 0 8
```

### REST API

```python
from modapi.api.rest import create_rest_app

# Create and run Flask app
app = create_rest_app(port='/dev/ttyACM0', api_port=5005)
```

### 🌐 REST API Server

```bash
# Uruchom serwer RTU
python run_rtu_output.py

# API endpoints:
# GET  /status              - status połączenia RTU
# GET  /coil/<address>      - odczyt cewki
# POST /coil/<address>      - zapis cewki (JSON: {"state": true})
# GET  /coils               - odczyt wszystkich cewek 0-15
# GET  /registers/<address> - odczyt rejestru
```

### 📁 Przykłady curl

```bash
# Sprawdź status
curl http://localhost:5005/status

# Odczytaj cewkę 0
curl http://localhost:5005/coil/0

# Ustaw cewkę 0 na TRUE
curl -X POST http://localhost:5005/coil/0 \
     -H "Content-Type: application/json" \
     -d '{"state": true}'

# Odczytaj wszystkie cewki
curl http://localhost:5005/coils
```

### 🔧 Zaawansowane użycie

```python
from api.rtu import ModbusRTU
import time

# Niestandardowa konfiguracja
client = ModbusRTU(
    port='/dev/ttyACM0',
    baudrate=19200,
    timeout=2.0,
    parity='E',  # Even parity
    stopbits=1
)

if client.connect():
    # Monitorowanie zmian cewek
    previous_states = None
    
    for _ in range(10):  # Monitoruj przez 10 iteracji
        current_states = client.read_coils(1, 0, 4)
        
        if current_states and current_states != previous_states:
            print(f"{time.strftime('%H:%M:%S')} - Zmiana: {current_states}")
            previous_states = current_states
            
        time.sleep(1)
    
    client.disconnect()
```

### MQTT API

```python
from modapi.api.mqtt import start_mqtt_broker

# Start MQTT client
start_mqtt_broker(
    port='/dev/ttyACM0',
    broker='localhost',
    mqtt_port=1883,
    topic_prefix='modbus'
)
```

#### MQTT Topics

- Subscribe to `modbus/command/#` to send commands
- Subscribe to `modbus/request/#` to send requests
- Publish to `modbus/command/write_coil` with payload `{"address": 0, "value": true}` to write to a coil
- Publish to `modbus/request/read_coils` with payload `{"address": 0, "count": 8}` to read coils
- Results are published to `modbus/result/<command>` and `modbus/response/<request>`

### Direct API Usage

```python
from modapi.api.cmd import execute_command
from modapi.api.shell import interactive_mode

# Execute a command directly
success, response = execute_command('wc', ['0', '1'], port='/dev/ttyACM0')
print(response)

# Start interactive mode
interactive_mode(port='/dev/ttyACM0', verbose=True)
```

## Project Structure

```
modapi/
├── api/
│   ├── __init__.py    # Exports main API functions
│   ├── cmd.py         # Direct command execution
│   ├── mqtt.py        # MQTT broker client
│   ├── rest.py        # REST API Flask app
│   └── shell.py       # Interactive shell
├── client.py          # Modbus client implementation
├── __main__.py        # CLI entry point
└── ...
```



## Output Moduł [output.py]

Moduł [output](modapi/output.py:296:4-332:54) odpowiada za wizualizację i przetwarzanie stanów wyjść cyfrowych (cewek) w systemie Modbus. Zapewnia funkcje do parsowania i wyświetlania stanów wyjść w formie interaktywnego widżetu SVG.


### [parse_coil_status(text: str) -> Tuple[Optional[int], Optional[bool]]](modapi/output.py:18:0-33:21)
**Opis**:  
Parsuje wiadomość o stanie cewki i zwraca jej adres oraz status.

**Parametry**:
- `text` - Tekst wiadomości (np. 'Coil 0 set to ON' lub 'Coil 5 set to OFF')

**Zwraca**:
- Krotkę zawierającą:
  - `address` (int) - Adres cewki
  - [status](modapi/output.py:18:0-33:21) (bool) - Stan cewki (True = WŁĄCZONA, False = WYŁĄCZONA)

- [(None, None)](modapi/output.py:403:4-405:54) w przypadku błędu parsowania

**Przykład użycia**:
```python
address, status = parse_coil_status("Coil 3 set to ON")
# address = 3, status = True



## License

This project is licensed under the Apache 2.0 License - see the LICENSE file for details.
python -m modapi scan --ports /dev/ttyACM0 --baudrates 9600,19200 --unit-ids 0,1,2,247 --debug
modapi scan --ports /dev/ttyACM0 --baudrates 9600,19200 --unit-ids 0,1,247 --debug
            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "modapi",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.10",
    "maintainer_email": null,
    "keywords": null,
    "author": "Tom Sapletta",
    "author_email": "info@softreck.dev",
    "download_url": "https://files.pythonhosted.org/packages/65/b3/6d91176a2a818db34da95c1c5bcfaaf4436f1b2bc8929db710660a7bbd12/modapi-0.2.4.tar.gz",
    "platform": null,
    "description": "# modapi\n\n\ud83d\ude80 **Direct Modbus RTU Communication API** - Bezpo\u015brednia komunikacja z urz\u0105dzeniami Modbus przez port szeregowy.\n\n## \u2728 Kluczowe cechy\n\n- **\ud83d\udd27 Direct RTU Module** - Bezpo\u015brednia komunikacja Modbus RTU bez PyModbus\n- **\ud83d\udce1 Verified Hardware Support** - Przetestowane z rzeczywistym sprz\u0119tem `/dev/ttyACM0`\n- **\ud83d\udd0d Smart Auto-detection** - Automatyczne wykrywanie dzia\u0142aj\u0105cych urz\u0105dze\u0144 i konfiguracji\n- **\ud83c\udf10 Web Interface** - Nowoczesny interfejs web do sterowania cewkami\n- **\ud83d\udcaa Enhanced CRC Handling** - Zaawansowana obs\u0142uga CRC dla urz\u0105dze\u0144 Waveshare\n- **\ud83d\udd04 Robust Error Recovery** - Inteligentne odzyskiwanie po b\u0142\u0119dach komunikacji\n- **\u26a1 Multiple APIs**:\n  - **REST API** - HTTP API dla aplikacji web\n  - **Direct RTU** - Bezpo\u015brednia komunikacja szeregowa\n  - **Shell CLI** - Interfejs linii polece\u0144\n- **\ud83e\uddea Fully Tested** - Kompletne testy jednostkowe i integracyjne\n- **\ud83d\udccb Production Ready** - Gotowe do u\u017cycia produkcyjnego\n\n## \ud83c\udd9a Dlaczego nowa wersja?\n\n| Aspekt | Stara wersja (PyModbus) | **Nowa wersja (RTU)** |\n|--------|-------------------------|----------------------|\n| **Komunikacja z sprz\u0119tem** | \u274c Nie dzia\u0142a\u0142a | \u2705 **Dzia\u0142a niezawodnie** |\n| **Auto-detekcja** | \u274c Zwraca\u0142a b\u0142\u0119dy | \u2705 **Znajduje urz\u0105dzenia** |\n| **Odczyt/zapis cewek** | \u274c B\u0142\u0119dy komunikacji | \u2705 **100% sprawne** |\n| **Obs\u0142uga CRC** | \u274c Tylko standardowa | \u2705 **Zaawansowana dla Waveshare** |\n| **Odporno\u015b\u0107 na b\u0142\u0119dy** | \u274c Niska | \u2705 **Wysoka z auto-korekt\u0105** |\n| **Logowanie** | \u274c Niejasne b\u0142\u0119dy | \u2705 **Szczeg\u00f3\u0142owe logi** |\n| **Testy** | \u274c Zawodne | \u2705 **Wszystkie przechodz\u0105** |\n| **Dokumentacja** | \u274c Nieaktualna | \u2705 **Kompletna + przyk\u0142ady** |\n\n## \ud83d\udd27 Szybki start\n\n### Wymagania\n- Python 3.8+\n- Urz\u0105dzenie Modbus RTU pod\u0142\u0105czone do `/dev/ttyACM0` lub `/dev/ttyUSB0`\n- Uprawnienia do port\u00f3w szeregowych (dodaj u\u017cytkownika do grupy `dialout`)\n\n### Instalacja\n\n```bash\n# Sklonuj repozytorium\ngit clone https://github.com/yourusername/modapi.git\ncd modapi\n\n# Utw\u00f3rz \u015brodowisko wirtualne\npython -m venv venv\nsource venv/bin/activate  # Linux/Mac\n# lub: venv\\Scripts\\activate  # Windows\n\n# Zainstaluj zale\u017cno\u015bci\npip install -r requirements.txt\n# lub u\u017cyj Poetry:\npoetry install && poetry shell\n```\n\n### \u26a1 Natychmiastowe uruchomienie\n\n**1. Test komunikacji RTU:**\n```bash\npython -c \"from api.rtu import ModbusRTU; client = ModbusRTU(); print('Config:', client.auto_detect())\"\n```\n\n**2. Uruchom serwer web:**\n```bash\npython run_rtu_output.py\n# Otw\u00f3rz http://localhost:5005 w przegl\u0105darce\n```\n\n**3. Przyk\u0142ady u\u017cycia:**\n```bash\npython examples/rtu_usage.py\n```\n\n## \ud83e\uddea Development i testowanie\n\n### Uruchom testy\n```bash\n# Wszystkie testy RTU\npython -m pytest tests/test_rtu.py -v\n\n# Z pokryciem kodu\npython -m pytest tests/test_rtu.py --cov=api.rtu\n\n# Test z rzeczywistym sprz\u0119tem (opcjonalny)\npython -c \"from tests.test_rtu import TestIntegration; TestIntegration().test_real_hardware_connection()\"\n```\n\n### Debugowanie komunikacji\n```bash\n# Szczeg\u00f3\u0142owe logi komunikacji\npython -c \"\nimport logging\nlogging.basicConfig(level=logging.DEBUG)\nfrom api.rtu import ModbusRTU\nclient = ModbusRTU()\nconfig = client.auto_detect()\nprint('Debug config:', config)\n\"\n```\n\n### Budowanie i publikacja\n```bash\n# Budowa pakietu\npoetry build\n\n# Publikacja do PyPI\npoetry publish --build\n```\n\n## \ud83d\udd0d Troubleshooting\n\n### Problem: Nie mo\u017cna znale\u017a\u0107 urz\u0105dzenia\n```bash\n# Sprawd\u017a dost\u0119pne porty szeregowe\nls -la /dev/tty{ACM,USB}*\n\n# Sprawd\u017a uprawnienia (dodaj u\u017cytkownika do grupy dialout)\nsudo usermod -a -G dialout $USER\n# Wyloguj si\u0119 i zaloguj ponownie\n\n# Test r\u0119czny z r\u00f3\u017cnymi pr\u0119dko\u015bciami\npython -c \"\nfrom api.rtu import ModbusRTU\nfor baud in [9600, 19200, 38400]:\n    client = ModbusRTU('/dev/ttyACM0', baud)\n    if client.connect():\n        success, result = client.test_connection(1)\n        print(f'{baud} baud: {success} - {result}')\n        client.disconnect()\n\"\n```\n\n### Problem: B\u0142\u0119dy komunikacji i CRC\n```bash\n# Sprawd\u017a parametry szeregowe urz\u0105dzenia w dokumentacji\n# Typowe ustawienia: 8N1 (8 bit\u00f3w danych, bez parzysto\u015bci, 1 bit stopu)\n# Mo\u017ce wymaga\u0107 innych ustawie\u0144: 8E1, 8O1, itp.\n\n# W\u0142\u0105cz szczeg\u00f3\u0142owe logowanie dla debugowania CRC\npython -c \"\nimport logging\nlogging.basicConfig(level=logging.DEBUG)\nfrom api.rtu import ModbusRTU\nclient = ModbusRTU('/dev/ttyACM0')\nclient.connect()\n# Dla urz\u0105dze\u0144 Waveshare - modu\u0142 automatycznie obs\u0142uguje alternatywne CRC\nresult = client.read_coils(1, 0, 8)\nprint(f'Odczyt cewek z obs\u0142ug\u0105 alternatywnego CRC: {result}')\nclient.disconnect()\n\"\n```\n\n### Problem: Urz\u0105dzenia Waveshare zwracaj\u0105 b\u0142\u0119dy funkcji\n```bash\n# Modu\u0142 RTU zawiera specjaln\u0105 obs\u0142ug\u0119 dla urz\u0105dze\u0144 Waveshare\n# Automatycznie obs\u0142uguje:\n# - Alternatywne obliczenia CRC\n# - Niezgodno\u015bci ID jednostki (broadcast, exception responses)\n# - Mapowanie kod\u00f3w funkcji\n# - Szczeg\u00f3\u0142owe komunikaty b\u0142\u0119d\u00f3w dla wyj\u0105tk\u00f3w Modbus\n\n# Test z w\u0142\u0105czonym debugowaniem\npython -c \"\nimport logging\nlogging.basicConfig(level=logging.DEBUG)\nfrom api.rtu import ModbusRTU\nclient = ModbusRTU('/dev/ttyACM0')\nclient.connect()\n# Pr\u00f3ba odczytu rejestr\u00f3w wej\u015bciowych (mo\u017ce zwr\u00f3ci\u0107 wyj\u0105tek na niekt\u00f3rych urz\u0105dzeniach)\nresult = client.read_input_registers(1, 0, 4)\nprint(f'Wynik z obs\u0142ug\u0105 wyj\u0105tk\u00f3w Waveshare: {result}')\nclient.disconnect()\n\"\n```\n\n   The simulator will start with these test values:\n   - Coils 0-3: `[1, 0, 1, 0]`\n   - Holding Registers 0-2: `[1234, 5678, 9012]`\n\n4. Configure your `.env` file to use the virtual port:\n   ```ini\n   MODBUS_PORT=/tmp/ttyp0\n   MODBUS_BAUDRATE=9600\n   MODBUS_TIMEOUT=0.1\n   ```\n\n5. You can now run the API server or CLI commands to interact with the simulator.\n\n## Usage\n\n### Command Line Interface\n\nThe modapi CLI supports multiple subcommands:\n\n```bash\n# Direct command execution\nmodapi cmd wc 0 1       # Write value 1 to coil at address 0\nmodapi cmd rc 0 8       # Read 8 coils starting at address 0\nmodapi cmd rh 0 5       # Read 5 holding registers starting at address 0\nmodapi cmd wh 0 42      # Write value 42 to holding register at address 0\n\n# Interactive shell\nmodapi shell\n\n# REST API server\nmodapi rest --host 0.0.0.0 --port 5005\n\n# MQTT client\nmodapi mqtt --broker localhost --port 1883\n\n# Scan for Modbus devices\nmodapi scan\n\n# With options\nmodapi cmd --verbose rc 0 8    # Verbose mode\nmodapi cmd --modbus-port /dev/ttyACM0 wc 0 1  # Specify port\n```\n\nFor backward compatibility, you can also use the direct command format:\n```bash\n# These are automatically converted to the new format\n./run_cli.py wc 0 1       # Equivalent to: modapi cmd wc 0 1\n./run_cli.py rc 0 8       # Equivalent to: modapi cmd rc 0 8\n```\n\n### REST API\n\n```python\nfrom modapi.api.rest import create_rest_app\n\n# Create and run Flask app\napp = create_rest_app(port='/dev/ttyACM0', api_port=5005)\n```\n\n### \ud83c\udf10 REST API Server\n\n```bash\n# Uruchom serwer RTU\npython run_rtu_output.py\n\n# API endpoints:\n# GET  /status              - status po\u0142\u0105czenia RTU\n# GET  /coil/<address>      - odczyt cewki\n# POST /coil/<address>      - zapis cewki (JSON: {\"state\": true})\n# GET  /coils               - odczyt wszystkich cewek 0-15\n# GET  /registers/<address> - odczyt rejestru\n```\n\n### \ud83d\udcc1 Przyk\u0142ady curl\n\n```bash\n# Sprawd\u017a status\ncurl http://localhost:5005/status\n\n# Odczytaj cewk\u0119 0\ncurl http://localhost:5005/coil/0\n\n# Ustaw cewk\u0119 0 na TRUE\ncurl -X POST http://localhost:5005/coil/0 \\\n     -H \"Content-Type: application/json\" \\\n     -d '{\"state\": true}'\n\n# Odczytaj wszystkie cewki\ncurl http://localhost:5005/coils\n```\n\n### \ud83d\udd27 Zaawansowane u\u017cycie\n\n```python\nfrom api.rtu import ModbusRTU\nimport time\n\n# Niestandardowa konfiguracja\nclient = ModbusRTU(\n    port='/dev/ttyACM0',\n    baudrate=19200,\n    timeout=2.0,\n    parity='E',  # Even parity\n    stopbits=1\n)\n\nif client.connect():\n    # Monitorowanie zmian cewek\n    previous_states = None\n    \n    for _ in range(10):  # Monitoruj przez 10 iteracji\n        current_states = client.read_coils(1, 0, 4)\n        \n        if current_states and current_states != previous_states:\n            print(f\"{time.strftime('%H:%M:%S')} - Zmiana: {current_states}\")\n            previous_states = current_states\n            \n        time.sleep(1)\n    \n    client.disconnect()\n```\n\n### MQTT API\n\n```python\nfrom modapi.api.mqtt import start_mqtt_broker\n\n# Start MQTT client\nstart_mqtt_broker(\n    port='/dev/ttyACM0',\n    broker='localhost',\n    mqtt_port=1883,\n    topic_prefix='modbus'\n)\n```\n\n#### MQTT Topics\n\n- Subscribe to `modbus/command/#` to send commands\n- Subscribe to `modbus/request/#` to send requests\n- Publish to `modbus/command/write_coil` with payload `{\"address\": 0, \"value\": true}` to write to a coil\n- Publish to `modbus/request/read_coils` with payload `{\"address\": 0, \"count\": 8}` to read coils\n- Results are published to `modbus/result/<command>` and `modbus/response/<request>`\n\n### Direct API Usage\n\n```python\nfrom modapi.api.cmd import execute_command\nfrom modapi.api.shell import interactive_mode\n\n# Execute a command directly\nsuccess, response = execute_command('wc', ['0', '1'], port='/dev/ttyACM0')\nprint(response)\n\n# Start interactive mode\ninteractive_mode(port='/dev/ttyACM0', verbose=True)\n```\n\n## Project Structure\n\n```\nmodapi/\n\u251c\u2500\u2500 api/\n\u2502   \u251c\u2500\u2500 __init__.py    # Exports main API functions\n\u2502   \u251c\u2500\u2500 cmd.py         # Direct command execution\n\u2502   \u251c\u2500\u2500 mqtt.py        # MQTT broker client\n\u2502   \u251c\u2500\u2500 rest.py        # REST API Flask app\n\u2502   \u2514\u2500\u2500 shell.py       # Interactive shell\n\u251c\u2500\u2500 client.py          # Modbus client implementation\n\u251c\u2500\u2500 __main__.py        # CLI entry point\n\u2514\u2500\u2500 ...\n```\n\n\n\n## Output Modu\u0142 [output.py]\n\nModu\u0142 [output](modapi/output.py:296:4-332:54) odpowiada za wizualizacj\u0119 i przetwarzanie stan\u00f3w wyj\u015b\u0107 cyfrowych (cewek) w systemie Modbus. Zapewnia funkcje do parsowania i wy\u015bwietlania stan\u00f3w wyj\u015b\u0107 w formie interaktywnego wid\u017cetu SVG.\n\n\n### [parse_coil_status(text: str) -> Tuple[Optional[int], Optional[bool]]](modapi/output.py:18:0-33:21)\n**Opis**:  \nParsuje wiadomo\u015b\u0107 o stanie cewki i zwraca jej adres oraz status.\n\n**Parametry**:\n- `text` - Tekst wiadomo\u015bci (np. 'Coil 0 set to ON' lub 'Coil 5 set to OFF')\n\n**Zwraca**:\n- Krotk\u0119 zawieraj\u0105c\u0105:\n  - `address` (int) - Adres cewki\n  - [status](modapi/output.py:18:0-33:21) (bool) - Stan cewki (True = W\u0141\u0104CZONA, False = WY\u0141\u0104CZONA)\n\n- [(None, None)](modapi/output.py:403:4-405:54) w przypadku b\u0142\u0119du parsowania\n\n**Przyk\u0142ad u\u017cycia**:\n```python\naddress, status = parse_coil_status(\"Coil 3 set to ON\")\n# address = 3, status = True\n\n\n\n## License\n\nThis project is licensed under the Apache 2.0 License - see the LICENSE file for details.\npython -m modapi scan --ports /dev/ttyACM0 --baudrates 9600,19200 --unit-ids 0,1,2,247 --debug\nmodapi scan --ports /dev/ttyACM0 --baudrates 9600,19200 --unit-ids 0,1,247 --debug",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "Unified API for Modbus communication with support for RTU, TCP, and REST APIs",
    "version": "0.2.4",
    "project_urls": null,
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f5e7c21d921517714985ff2185d275fdc457da05d496b6397c3336a0a25257ab",
                "md5": "28bc52848a28f0272d242dd351aa3e4a",
                "sha256": "4cd2beb872c59d618903e5fb57a9efddc5f49ca344aef58ec57014d59dc24f55"
            },
            "downloads": -1,
            "filename": "modapi-0.2.4-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "28bc52848a28f0272d242dd351aa3e4a",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.10",
            "size": 75520,
            "upload_time": "2025-08-01T21:33:10",
            "upload_time_iso_8601": "2025-08-01T21:33:10.878068Z",
            "url": "https://files.pythonhosted.org/packages/f5/e7/c21d921517714985ff2185d275fdc457da05d496b6397c3336a0a25257ab/modapi-0.2.4-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "65b36d91176a2a818db34da95c1c5bcfaaf4436f1b2bc8929db710660a7bbd12",
                "md5": "cdc1b25e195151acd8c3c8745cecd6d9",
                "sha256": "42b22455c8b7e735609da5c54d439859050a5ece7c9cedc2ae1b7809883c30f4"
            },
            "downloads": -1,
            "filename": "modapi-0.2.4.tar.gz",
            "has_sig": false,
            "md5_digest": "cdc1b25e195151acd8c3c8745cecd6d9",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.10",
            "size": 66574,
            "upload_time": "2025-08-01T21:33:12",
            "upload_time_iso_8601": "2025-08-01T21:33:12.571963Z",
            "url": "https://files.pythonhosted.org/packages/65/b3/6d91176a2a818db34da95c1c5bcfaaf4436f1b2bc8929db710660a7bbd12/modapi-0.2.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-01 21:33:12",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "modapi"
}
        
Elapsed time: 1.60874s