Komunikacja kiosk ↔ sprzęt: z bezpośredniej (Modbus) na API agenta SmartConf¶
TL;DR
Kiosk nie rozmawia już bezpośrednio ze sterownikiem zamków (Modbus TCP). Całe sterowanie sprzętem idzie teraz przez lokalnego agenta SmartConf po HTTP na 127.0.0.1:8800 (/v1/...). Modbus pozostał w kodzie jako sterownik dev/awaryjny, ale w produkcji jest martwy (etap-20 usunął nawet adres Modbus skrytek). To kluczowa zmiana architektury z etapów 8–9, dokończona w 16–20.
Dlaczego zmiana¶
Bezpośredni Modbus z kiosku miał wady: - Współbieżność i sekwencje DynaBoxa (obrót bębna, re-rygiel, prezentacja kolumny) wymagały złożonej logiki w kiosku, podatnej na wyścigi. - Brak jednego miejsca na telemetrię, discovery, diagnostykę i wersję firmware sterownika. - Trudny serwis zdalny i podgląd, co maszyna faktycznie robi z zamkami.
Agent SmartConf (osobny proces na maszynie, C#) bierze to na siebie: zna sprzęt (LockerBox/DynaBox), zarządza cyklem otwarcia, kolejką, timeoutami i re-ryglem, a kioskowi wystawia proste, idempotentne API HTTP.
Przed → po¶
flowchart LR
subgraph PRZED["PRZED — bezpośrednio"]
K1[Kiosk Flutter] -- Modbus TCP :502 --> C1[Sterownik zamków]
end
subgraph PO["PO — przez agenta"]
K2[Kiosk Flutter] -- HTTP /v1 127.0.0.1:8800 --> A[Agent SmartConf]
A -- sterowanie sprzętem --> C2[Sterownik zamków]
A -- telemetria/zgłoszenia --> Cloud[(Backend SmartBox)]
end
Powierzchnia API agenta (/v1, na 127.0.0.1:8800)¶
Nagłówki: X-Api-Key (klucz agenta), X-Client-Name / X-Client-Version (tożsamość kiosku).
| Wywołanie | Po co |
|---|---|
GET /v1/machine |
typ maszyny (DynaBox / LockerBox) |
GET /v1/compartments |
geometria bębna + rozmiary komórek (DynaBox) |
GET /v1/status |
ostatni znany stan drzwi (cache) |
GET /v1/events?after=<seq> |
strumień zdarzeń sprzętu (sekwencyjny) |
POST /v1/doors/{N}/open |
pojedyncze otwarcie wirtualnej skrytki N (wydawanie/odbiór) |
POST /v1/jobs/open {doors[]} |
masowe otwarcie (uzupełnianie/inwentaryzacja) — etap-16 |
GET /v1/jobs[/{id}] |
poll stanu joba (queued→opening→unlocked→open→done/failed/timeout) |
POST /v1/jobs/{id}/cancel |
anulowanie kolejki (queued → skipped) |
POST /v1/master/clear |
kasowanie alarmów mastera |
Dwie ścieżki otwierania¶
- Pojedyncza skrytka (
locker_open_screen/JobOpenScreen, etap-17) — wydawanie i odbiór, zawsze 1 naraz; DynaBox po otwarciu re-rygluje (close(N)). - Masowa (Job API, etap-16) — uzupełnianie + inwentaryzacja; agent zarządza współbieżnością (≤3 dla LockerBox, 1 dla DynaBox), kolejką, cyklem i timeoutami; kiosk tylko pollu je i renderuje stan per skrytka.
Pre-check przed otwarciem (lockerOpenPreCheck)¶
NIE czytaj drzwi jako bramki przed otwarciem na SmartConf (DynaBox)
Na DynaBoxie wirtualna komórka z niezaprezentowanej kolumny czyta złe drzwi fizyczne → fałszywe „skrytka otwarta", blokujące nadanie i odbiór. Dlatego wspólny lockerOpenPreCheck(hardware, N):
- SmartConf (DynaBox + LockerBox) = NO-OP — pre-flight agenta wewnątrz
POST /v1/jobs/openjest świadomy zaprezentowanej kolumny i sam bramkuje gotowość. - mock / dev / Modbus — zachowują bramkę
isClosed(N).
Każda przyszła operacja otwierająca skrytkę MUSI korzystać z tej wspólnej metody (flutter-machine-ui/lib/hardware/locker_open_precheck.dart). Audyt 5 operacji (nadanie/odbiór/wydanie/uzupełnienie/inwentaryzacja) = czysty.
Tryb serwisowy i discovery¶
- Maszyna po rejestracji startuje w
maintenanceMode=true→ kiosk pokazuje Service Mode, póki admin nie połączy SmartConf. - Discovery: kiosk skanuje
localhost+ podsieci /24 swoich kart sieciowych (zadanieDISCOVER_SMARTCONF); kandydaci lądują w panelu. - Połączenie: admin ustawia URL agenta + opcjonalny klucz (
PATCH /machines/:id/smartconf); kiosk czyta to z/machines/mei rekonfiguruje sterownik na żywo (SmartConfHardware.applyConfig) — bez restartu. - Auto-maintenance: gdy agent staje się nieosiągalny, backend (worker) parkuje maszynę w trybie serwisowym (
maintenanceAuto=true) i zdejmuje po odzyskaniu — ale tylko jeśli park był automatyczny.
Audyt /v1 (etap-14)¶
Każde wywołanie /v1 jest logowane w kiosku (ring-buffer) i relayowane do backendu → panel maszyny → „Log API /v1" (mutacje zawsze, idle-polle próbkowane, w oknie capture wszystko). Retencja 7 dni (MachineApiLog). Bezcenne przy diagnostyce „co maszyna zrobiła z zamkami".
Status drogi Modbus¶
| Modbus (bezpośrednio) | SmartConf (agent) | |
|---|---|---|
| LockerBox | sterownik w repo (modbus_locker_hardware.dart), nieaktywny |
aktywny |
| DynaBox | nigdy nie był drogą produkcyjną | aktywny |
| Adres Modbus skrytki | usunięty z DB/schema (etap-20) | — |
| Kiedy używany | tylko mock/dev/ewentualny fallback | produkcja |
Plik abstrakcji: flutter-machine-ui/lib/hardware/locker_hardware.dart (interfejs open/openMany/events/isClosed), implementacje: modbus_locker_hardware.dart (martwy) i smartconf_hardware.dart (aktywny).
Powiązane¶
- Roadmapa etapów — etapy 8, 9, 14, 16, 17, 19, 20
- Kiosk Helper — Helper nie zarządza zamkami (to robi SmartConf); nadzoruje proces kiosku, RFID i OTA