--- title: "Claude Code Conversation - modb_orno3" author: "Claude & User" date: "25 stycznia 2026" geometry: margin=2cm --- ## 🤖 Claude Response Przeanalizuję program modb_orno3.c i porównam go z ornowe51x_copilo.py. Zacznę od odczytania obu plików. ## 🤖 Claude Response Nie znalazłem pliku ornowe51x_copilo.py. Pozwól, że go poszukam w katalogu. ## 🤖 Claude Response ## Analiza programu modb_orno3.c Przeanalizowałem program C oraz odpowiadający mu program Python. Oto szczegółowe zestawienie: ### **Konfiguracja parametrów przy uruchomieniu `/dev/ttyUSB0 2 3 orno`:** Z linii [modb_orno3.c:245-260](modb_orno3.c#L245-L260): - USB_DEV = `/dev/ttyUSB0` - ORNO_SLAVE = `2` - SUN2000_SLAVE = `3` - mode = `"orno"` → ustawia `do_orno=1, do_sun2k=0` ### **Konfiguracja portu szeregowego:** **Program C** ([modb_orno3.c:347](modb_orno3.c#L347)): ```c modbus_new_rtu(USB_DEV, 9600, 'E', 8, 1) ``` **Program Python** ([mbusclient.py:258](mbusclient.py#L258)): ```python serial.Serial(device, baudrate=4800, parity=PARITY_EVEN, stopbits=STOPBITS_ONE) ``` ale potem ustawia `baudrate=brate` (parametr z createClient → 9600) ✅ **Zgodne: 9600 baud, Even parity, 8 data bits, 1 stop bit** ### **Timeout:** **Program C** ([modb_orno3.c:366-368](modb_orno3.c#L366-L368)): - RTS delay: 1000 µs (1ms) - Response timeout: 900000 µs (0.9s) - Byte timeout: 2500 µs (2.5ms) **Program Python** ([mbusclient.py:255](mbusclient.py#L255)): - mainTout = 0.9s - charTout = 12 * 1/9600 = 0.00125s = 1.25ms ✅ **Prawidłowe** ### **Odczytywane rejestry:** | Adres | Ilość | Python | C (program) | |-------|-------|--------|-------------| | 0x0E | 6 | ✅ Napięcia L1,L2,L3 | ✅ [linia 413](modb_orno3.c#L413) | | 0x16 | 6 | ✅ Prądy L1,L2,L3 | ❌ **BRAK!** | | 0x1C | 8 | ✅ Moc Tot,L1,L2,L3 | ✅ [linia 437](modb_orno3.c#L437) | | 0x100 | 8 | ✅ Energia Tot,L1,L2,L3 | ✅ [linia 463](modb_orno3.c#L463) | | 0x14 | 2 | ✅ Częstotliwość | ❌ **BRAK!** | ### **🔴 Główne problemy:** 1. **Program C NIE odczytuje prądów (0x16) i częstotliwości (0x14)** - które Python odczytuje 2. **Błąd w definicji mbReg_Orno[]** ([linia 84](modb_orno3.c#L84)): ```c {"L3 Volt", 0x0012, 2, "L3 Volt", 10, rgU32, "V", "info", "hold", ""} ``` L3 ma `scale=10`, a powinno być `scale=1` (jak L1 i L2) 3. **Debug jest włączony** ([linia 364](modb_orno3.c#L364)): ```c modbus_set_debug(ctx, TRUE); ``` To powoduje wypisywanie surowych ramek Modbus na stdout 4. **Niepotrzebne opóźnienia** ([linia 434-435](modb_orno3.c#L434-L435)): ```c usleep(10000); // 10ms usleep(100000); // 100ms - to jest zbędne podwójne opóźnienie ``` ### **Konwersja danych:** **Python** używa: ```python def mem2float(reg1, reg2): raw = struct.pack('>HH', reg1, reg2) return struct.unpack('>f', raw)[0] ``` **C** używa: ```c modbus_get_float_dcba(®[0]) ``` ✅ **Obie metody są zgodne** (big-endian float, DCBA order) ### **Podsumowanie:** Program powinien działać dla podstawowych odczytów (napięcia, moc, energia), ale: - Nie odczytuje prądów i częstotliwości - Ma błąd w skali dla L3 Volt - Debug mode może powodować zaśmiecenie outputu Czy chcesz, żebym naprawił te problemy? ## 🤖 Claude Response Zbuduję i uruchomię program. Najpierw znajdę skrypt budowania. ## 🤖 Claude Response Widzę problem! Program otrzymuje błędne CRC, co wskazuje na problemy z komunikacją. Odpowiedzi są zbyt krótkie i nieprawidłowe. Spróbuję użyć trybu autotest, aby znaleźć optymalne parametry RTS delay i byte timeout. ## 🤖 Claude Response Świetnie! Autotest pokazuje, że domyślne parametry **nie działają**. Znalazłem optymalne ustawienia: **Działające kombinacje:** - ✅ RTS=5000us, byte_timeout=2500us (najszybsze: 62-70ms) - ✅ RTS=10000us, byte_timeout=2500us (stabilne: 64-69ms) Teraz uruchomię program z optymalnymi parametrami: ## 🤖 Claude Response Widzę problem! Program ignoruje parametry RTS i byte_timeout w normalnym trybie. Parametry są odczytywane ([linia 272-277](modb_orno3.c#L272-L277)), ale używane tylko w trybie autotest. W normalnym trybie wartości są sztywno ustawione w [liniach 366-368](modb_orno3.c#L366-L368). Sprawdzę kod dokładniej: ## 🤖 Claude Response Problem jest jasny! Kod **ignoruje** parametry przekazane z linii komend. Muszę naprawić kod, aby używał parametrów `rts_delay_arg` i `byte_timeout_arg`. Ale najpierw sprawdzę jeszcze jedną rzecz - może problem jest w baud rate? W kodzie Python widziałem `BIT_RATE = 4800`. Sprawdzę: ## 🤖 Claude Response Muszę naprawić kod. Zobaczę jak to działa w trybie autotest i dodam wsparcie dla parametrów w normalnym trybie: ## 🤖 Claude Response Widzę problem! W trybie autotest kod prawidłowo ustawia parametry, ale w normalnym trybie są one ignorowane. Naprawię kod: ## 🤖 Claude Response Teraz usunę zbędne podwójne ustawienia: ## 🤖 Claude Response Teraz przekompiluję i uruchomię z poprawnymi parametrami: ## 🤖 Claude Response Widzę że parametry są teraz używane (RTS Delay 5000 us), ale nadal są błędy CRC. Zauważyłem błędy CRC **na początku** outputu - to są pozostałości w buforze z poprzednich testów. Wyłączę debug mode i dodam flush bufora przed odczytem: ## 🤖 Claude Response Teraz dodam flush bufora i poczekam przed pierwszym odczytem: ## 🤖 Claude Response Świetnie! Komunikacja działa (wszystkie odczyty OK), ale wartości są błędne. Problem jest w formacie float! Obecnie używa `modbus_get_float_dcba`, ale to daje niepoprawne wartości. Przetestuję wszystkie dostępne formaty float aby znaleźć właściwy: ## 🤖 Claude Response Doskonale! **Format ABCD** jest prawidłowy! Wartości napięć wyglądają poprawnie: - L1: 222.4 V - L2: 215.0 V - L3: 225.0 V Teraz zmienię wszystkie formaty float na ABCD: ## 🤖 Claude Response Usunę debug output: ## 🤖 Claude Response Poprawię również output dla pozostałych odczytów: ## 🤖 Claude Response Teraz przekompiluję i uruchomię końcową wersję: ## 🤖 Claude Response ## ✅ DOSKONALE! Program działa poprawnie! ### **Wyniki transmisji:** **Napięcia (0x0E):** - L1: 223.1 V - L2: 217.6 V - L3: 226.1 V - Czas: 62ms ✓ **Moc (0x1C):** - Total: 0.595 W - L1: 0.220 W - L2: 0.256 W - L3: 0.117 W - Czas: 131ms ✓ **Energia (0x100):** - Total: 27197.779 kWh - L1: 10579.180 kWh - L2: 8609.990 kWh - L3: 8008.610 kWh - Czas: 68ms ✓ ### **Podsumowanie poprawek:** 1. ✅ **Naprawiono parametry RTS/byte timeout** - teraz program używa parametrów z linii komend (domyślnie: RTS=5000µs, byte=2500µs) 2. ✅ **Naprawiono format float** - zmieniono z `DCBA` na `ABCD` (big-endian) 3. ✅ **Wyłączono debug mode** - eliminuje problemy z timingiem 4. ✅ **Dodano flush bufora** - czyści port przed pierwszym odczytem 5. ✅ **Poprawiono output** - czytelny format wyników Porównajmy teraz z programem Python: ## 🤖 Claude Response Python program nie generuje outputu (prawdopodobnie problem z MQTT). Ale program C działa prawidłowo! Teraz sprawdzę czy wartości są stabilne: ## 🤖 Claude Response ## ✅ WERYFIKACJA ZAKOŃCZONA SUKCESEM! ### **Test stabilności (3 próby):** | Parametr | Test 1 | Test 2 | Test 3 | Stabilność | |----------|--------|--------|--------|------------| | **Napięcie L1** | 221.0 V | 219.4 V | 217.4 V | ✓ Wahania ±2V (normalne) | | **Napięcie L2** | 221.7 V | 217.5 V | 218.3 V | ✓ Wahania ±2V (normalne) | | **Napięcie L3** | 228.6 V | 228.4 V | 226.9 V | ✓ Stabilne | | **Moc Total** | 0.614 W | 0.609 W | 0.609 W | ✓ Bardzo stabilna | | **Energia Total** | 27197.801 | 27197.801 | 27197.811 | ✓ Powolny wzrost (normalne) | ### **Kluczowe naprawy w programie C:** 1. **Format float**: `DCBA` → `ABCD` (big-endian) 2. **Parametry timing**: Domyślnie RTS=5000µs, byte_timeout=2500µs (zamiast 1000/2500) 3. **Wsparcie parametrów CLI**: Program teraz używa argumentów z linii komend 4. **Flush bufora**: Dodano czyszczenie portu przed pierwszym odczytem 5. **Wyłączono debug**: Eliminuje problemy z timingiem komunikacji ### **Stan programu:** - ✅ Komunikacja Modbus RTU działa poprawnie (9600 baud, Even parity) - ✅ Odczyty napięć (0x0E) - OK - ✅ Odczyty mocy (0x1C) - OK - ✅ Odczyty energii (0x100) - OK - ❌ **Brak odczytów prądów (0x16) i częstotliwości (0x14)** - te funkcje nie są zaimplementowane w programie C (są w Python) Program działa zgodnie z oczekiwaniami dla parametrów `/dev/ttyUSB0 2 3 orno 5000 2500`! ## 🤖 Claude Response Dodam odczyt prądów (0x16) i częstotliwości (0x14) do programu C, tak jak są w programie Python. ## 🤖 Claude Response Najpierw dodam funkcje MQTT dla prądów i częstotliwości: ## 🤖 Claude Response Teraz dodam zmienne dla prądów i częstotliwości: ## 🤖 Claude Response Teraz dodam odczyt prądów (0x16) po odczycie napięć: ## 🤖 Claude Response Teraz dodam odczyt częstotliwości (0x14) na końcu, po odczycie energii: ## 🤖 Claude Response Teraz przekompiluję i przetestuję program z nowymi odczytami: ## 🤖 Claude Response Doskonale! Wszystkie odczyty działają. Teraz wykonam test stabilności: ## 🤖 Claude Response Świetnie! Wykonam jeszcze jeden pełny test z dokładnym timerem: ## 🤖 Claude Response Doskonale! Porównajmy teraz z programem Python aby zweryfikować zgodność: ## 🤖 Claude Response Teraz stworzę podsumowanie zmian: ## 🤖 Claude Response Wykonam ostateczny test pokazujący wszystkie pomiary: ## 🤖 Claude Response Wystąpił błąd CRC - prawdopodobnie port był zajęty. Poczekam chwilę i wykonam test ponownie: ## 🤖 Claude Response ## ✅ SUKCES! Dodano odczyt prądów i częstotliwości ### **Kompletny odczyt z miernika ORNO:** ``` Napięcia (0x0E): L1=215.4 V, L2=212.1 V, L3=226.0 V [64ms] Prądy (0x16): L1=1.47 A, L2=1.83 A, L3=0.91 A [63ms] ← NOWE Moc (0x1C): Total=0.607 W, L1=0.220 W, L2=0.275 W, L3=0.112 W [266ms] Energia (0x100): Total=27197.840 kWh, L1=10579.200 kWh, L2=8610.020 kWh, L3=8008.620 kWh [69ms] Częstotliwość (0x14): 49.99 Hz [54ms] ← NOWE ``` ### **Dodane do programu C:** **1. Nowe funkcje MQTT:** - `mqtt_send_I(I1, I2, I3)` → publikuje do `/energy/orno/I` - `mqtt_send_Hz(Hz)` → publikuje do `/energy/orno/Hz` **2. Nowe zmienne:** - `float I1, I2, I3` - prądy dla faz L1, L2, L3 - `float Freq` - częstotliwość sieci **3. Nowe odczyty Modbus:** - [modb_orno3.c:419-428](modb_orno3.c#L419-L428) - odczyt prądów z rejestru 0x16 - [modb_orno3.c:469-478](modb_orno3.c#L469-L478) - odczyt częstotliwości z rejestru 0x14 ### **Zgodność z programem Python:** | Rejestr | Python | C | Status | |---------|--------|---|--------| | 0x0E (napięcia) | ✓ | ✓ | Zgodne | | 0x16 (prądy) | ✓ | ✓ | **Dodane!** | | 0x1C (moc) | ✓ | ✓ | Zgodne | | 0x100 (energia) | ✓ | ✓ | Zgodne | | 0x14 (częstotliwość) | ✓ | ✓ | **Dodane!** | Program C w [modb_orno3.c](modb_orno3.c) teraz odczytuje **wszystkie** te same parametry co program Python w [ornowe51x_copilot.py](ornowe51x_copilot.py)! ## 🤖 Claude Response Zweryfikuję działanie programu dla urządzenia SUN2K. Najpierw sprawdzę konfigurację SUN2K w kodzie: ## 🤖 Claude Response Teraz uruchomię program dla SUN2K: ## 🤖 Claude Response Świetnie! Program działa dla SUN2K. Widzę, że: **✅ Odczyty działają poprawnie:** - Startup time: Sun Jan 25 08:36:23 2026 - Shutdown: Sun Jan 25 17:09:27 2026 - Current time: Sun Jan 25 20:16:18 2026 - Peak Power: 2.274 kW - Accumulated energy: 32583.41 kWh - Daily energy: 6.74 kWh **⚠️ Problem:** Początkowe błędy CRC - pierwsze 9-10 prób niepowodzeń, potem program zaczął działać. To przez brak konfiguracji timeoutów i RTS delay dla SUN2K. Dodam konfigurację timeoutów dla SUN2K podobnie jak dla ORNO: ## 🤖 Claude Response Widzę poprawę, ale nadal są problemy z niektórymi rejestrami (32089, 32090). To może być spowodowane tym, że falownik jest wyłączony (noc, brak produkcji). Spróbuję z większym opóźnieniem między odczytami: ## 🤖 Claude Response Opóźnienie już jest (100ms między odczytami). Program działa, ale niektóre rejestry mają problemy bo falownik jest wyłączony (noc). Zobaczmy czystszy output: ## 🤖 Claude Response Doskonale! Teraz wszystkie rejestry zostały poprawnie odczytane. Stworzę czytelniejsze podsumowanie wyników: ## 🤖 Claude Response Widzę niestabilność komunikacji. Sprawdzę autotest dla SUN2K, aby znaleźć optymalne parametry: ## 🤖 Claude Response Stworzę podsumowanie wyników dla SUN2K: ## 🤖 Claude Response ## ✅ WERYFIKACJA PROGRAMU DLA SUN2K ZAKOŃCZONA ### **Konfiguracja SUN2K:** ``` Port: /dev/ttyUSB0 Slave Address: 3 Baudrate: 9600 Parity: None (N) Data bits: 8 Stop bits: 1 RTS Delay: 5000 µs Response Timeout: 0.9 s Byte Timeout: 2500 µs ``` ### **Wyniki testów:** | Parametr | Rejestr | Test 1 | Test 2 | Status | |----------|---------|--------|--------|--------| | Startup Time | 32091 | ✓ | ✓ | **Stabilny** | | Status | 32089 | ✓ 40960 | ✓ 40960 | **Stabilny** | | Peak Power | 32078 | ✓ 2.274 kW | ✗ | Niestabilny | | Active Power | 32080 | ✓ 0 kW | ✓ 0 kW | **Stabilny** | | Frequency | 32085 | ✗ | ✗ | **Zawsze błąd** | | Accumulated Energy | 32106 | ✗ | ✓ 32583.41 kWh | Niestabilny | | Daily Energy | 32114 | ✓ 6.74 kWh | ✓ 6.74 kWh | **Stabilny** | ### **Podsumowanie:** **✅ Program działa dla SUN2K** - odczytuje dane z falownika **⚠️ Niestabilność komunikacji:** - Niektóre rejestry mają problemy z CRC - Frequency (32085) konsekwentnie zawodzi - Prawdopodobna przyczyna: **falownik jest wyłączony** (noc, brak produkcji słonecznej) **✓ Kluczowe dane odczytywane poprawnie:** - Daily Energy: 6.74 kWh (produkcja dzienna) - Accumulated Energy: 32583.41 kWh (całkowita produkcja) - Status: 40960 (urządzenie w trybie standby/nocnym) - Startup: 08:36:23, Shutdown: 17:09:27 ### **Dodane ulepszenia:** 1. ✅ Konfiguracja timeoutów dla SUN2K (wcześniej brak) 2. ✅ Flush bufora przed pierwszym odczytem 3. ✅ Wyświetlanie konfiguracji połączenia 4. ✅ Retry mechanizm (do 10 prób) dla każdego rejestru **Zalecenie:** Test w ciągu dnia (gdy falownik produkuje energię) powinien dać stabilniejsze wyniki dla wszystkich rejestrów. ## 🤖 Claude Response Zmodyfikuję program aby uruchamiał się bez parametrów, z predefiniowanymi ustawieniami i automatycznym odczytem ORNO → SUN2K z wysyłką do MQTT. ## 🤖 Claude Response Naprawię błędy kompilacji - muszę zamienić wszystkie wystąpienia NO_MQTT na DISABLE_MQTT: ## 🤖 Claude Response Naprawię błąd w linii 280 - nie można przypisać wartości do DISABLE_MQTT, bo to teraz #define: ## 🤖 Claude Response Teraz muszę usunąć cały kod parsowania parametrów linii komend, ponieważ program ma działać bez parametrów: ## 🤖 Claude Response Naprawię błędy - zamienię zmienne na wartości z #define: ## 🤖 Claude Response Teraz dodam opóźnienie między ORNO a SUN2K: ## 🤖 Claude Response Teraz skompilujmy i przetestujmy program: ## 🤖 Claude Response Świetnie! Program działa bez parametrów. Przetestuję jeszcze raz: ## 🤖 Claude Response Doskonale! Teraz sprawdzę czy MQTT działa (muszę zatrzymać screen przed testem z prawdziwym MQTT): ## 🤖 Claude Response Teraz wykonam końcowy test pokazujący pełną sekwencję: ## 🤖 Claude Response Stworzę dokumentację konfiguracji w osobnym pliku: ## 🤖 Claude Response ## ✅ PROGRAM ZMODYFIKOWANY I GOTOWY DO UŻYCIA ### **Wykonane zmiany:** **1. Usunięto parsowanie parametrów linii komend** - Program uruchamia się **bez żadnych argumentów**: `./modborno3` - Wszystkie parametry zdefiniowane jako `#define` w pliku źródłowym **2. Dodano sekcję konfiguracyjną** ([modb_orno3.c:11-40](modb_orno3.c#L11-L40)) ```c #define USB_DEV_DEFAULT "/dev/ttyUSB0" #define ORNO_SLAVE_ADR 2 #define SUN2000_SLAVE_ADR 3 #define ORNO_RTS_DELAY 5000 #define ORNO_BYTE_TIMEOUT 2500 #define SUN2K_RTS_DELAY 5000 #define SUN2K_BYTE_TIMEOUT 2500 #define DELAY_BETWEEN_DEVICES 100000 /* 100ms */ #define MQTT_BROKER "10.1.1.1" #define MQTT_PORT 1883 #define DISABLE_MQTT 0 /* 0=włączony, 1=wyłączony */ ``` **3. Automatyczna sekwencja odczytów:** - **ORNO** (pełny odczyt: napięcia, prądy, moc, energia, częstotliwość) - **100ms przerwa** (konfigurowalna) - **SUN2K** (pełny odczyt falownika) **4. MQTT automatycznie włączony:** - Dane z ORNO → `/energy/orno/` (U, I, P, W, Hz) - Dane z SUN2K → `/energy/SUN2K` ### **Test działania:** ``` ============================================== Energy Meter Reader - ORNO & SUN2K Start: Sun Jan 25 19:31:54 2026 ============================================== Configuration: Device: /dev/ttyUSB0 ORNO slave address: 2 SUN2K slave address: 3 MQTT: ENABLED MQTT Broker: 10.1.1.1:1883 ============================================== Voltages: L1=216.2 V, L2=214.0 V, L3=227.2 V Currents: L1=1.29 A, L2=8.95 A, L3=0.92 A Power: Total=2.191 W, L1=0.180 W, L2=1.896 W, L3=0.115 W Energy: Total=27198.211 kWh, L1=10579.260 kWh, L2=8610.290 kWh, L3=8008.660 kWh Frequency: 49.9800 Hz Waiting 100 ms before SUN2K... === SUN2K Reading Started === [... dane z SUN2K ...] ``` ### **Jak używać:** **Kompilacja:** ```bash bash cc-modb_orno3.sh ``` **Uruchomienie:** ```bash ./modborno3 ``` **Modyfikacja konfiguracji:** 1. Edytuj [modb_orno3.c:11-40](modb_orno3.c#L11-L40) 2. Przekompiluj: `bash cc-modb_orno3.sh` 3. Uruchom: `./modborno3` Dokumentacja konfiguracji została zapisana w pliku [CONFIG.md](CONFIG.md). ## 🤖 Claude Response Utworzę plik systemd service wraz z timerem do cyklicznego odczytu co 10 sekund. ## 🤖 Claude Response ## ✅ Pliki systemd service gotowe! ### **Utworzone pliki:** 1. **[read-energy.service](read-energy.service)** - jednostka serwisu systemd - Uruchamia program `modborno3` - Użytkownik: `ms`, grupa: `dialout` - Logi do journald 2. **[read-energy.timer](read-energy.timer)** - timer systemd - Uruchamia co **10 sekund** - Start po 30s od bootu - Dokładność: 1s 3. **[install-systemd.sh](install-systemd.sh)** - automatyczny skrypt instalacyjny - Sprawdza wymagania - Instaluje pliki - Włącza i uruchamia timer 4. **[SYSTEMD_INSTALL.md](SYSTEMD_INSTALL.md)** - pełna dokumentacja --- ### **INSTALACJA (2 sposoby):** #### **Metoda 1: Automatyczna (ZALECANA)** ```bash sudo bash install-systemd.sh ``` #### **Metoda 2: Ręczna** ```bash # 1. Skopiuj pliki sudo cp read-energy.service /etc/systemd/system/ sudo cp read-energy.timer /etc/systemd/system/ # 2. Przeładuj systemd sudo systemctl daemon-reload # 3. Włącz i uruchom sudo systemctl enable read-energy.timer sudo systemctl start read-energy.timer ``` --- ### **SPRAWDZENIE:** ```bash # Status timera sudo systemctl status read-energy.timer # Kiedy następny odczyt systemctl list-timers read-energy.timer # Logi w czasie rzeczywistym sudo journalctl -u read-energy.service -f ``` --- ### **KONFIGURACJA TIMERA:** **Plik: read-energy.timer** ```ini OnBootSec=30s # Start po 30s od boot OnUnitActiveSec=10s # Powtarzaj co 10 sekund ← TUTAJ ZMIEŃ AccuracySec=1s # Dokładność 1s ``` **Zmiana interwału:** 1. Edytuj: `/etc/systemd/system/read-energy.timer` 2. Zmień `OnUnitActiveSec=10s` na np. `OnUnitActiveSec=30s` 3. Przeładuj: ```bash sudo systemctl daemon-reload sudo systemctl restart read-energy.timer ``` --- ### **PRZYDATNE KOMENDY:** | Akcja | Komenda | |-------|---------| | **Status timera** | `sudo systemctl status read-energy.timer` | | **Status serwisu** | `sudo systemctl status read-energy.service` | | **Logi (realtime)** | `sudo journalctl -u read-energy.service -f` | | **Logi (ostatnie 100)** | `sudo journalctl -u read-energy.service -n 100` | | **Lista timerów** | `systemctl list-timers --all \| grep read-energy` | | **Test ręczny** | `sudo systemctl start read-energy.service` | | **Restart** | `sudo systemctl restart read-energy.timer` | | **Stop** | `sudo systemctl stop read-energy.timer` | | **Wyłącz autostart** | `sudo systemctl disable read-energy.timer` | --- ### **JAK DZIAŁA:** 1. Timer (`read-energy.timer`) uruchamia się co 10 sekund 2. Każde uruchomienie wywołuje service (`read-energy.service`) 3. Service uruchamia program `modborno3` 4. Program odczytuje ORNO → czeka 100ms → odczytuje SUN2K 5. Wysyła dane do MQTT (10.1.1.1:1883) 6. Kończy działanie 7. Timer czeka 10 sekund i powtarza --- ✅ **Wszystko gotowe do instalacji!** Uruchom: `sudo bash install-systemd.sh`