5.7 KiB
- Timer powrotu do automatyzacji
Backend już przechowywał local_thermostat_resume_at, ale przy takim scenariuszu:
lokalny OFF → licznik 15 min → pilot/direct ON → pilot/direct OFF
stary deadline nadal istniał. Sterowanie pilotem miało wyższy priorytet, ale timer lokalnego OFF nadal „leciał pod spodem”.
Poprawiłem to tak:
dodałem centralną metodę set_local_thermostat_power(...), każde nowe OFF ustawia świeże now + 15 min, ON kasuje deadline, podczas device_manual_override timer lokalnego OFF nie może wygasnąć, gdy użytkownik po pilocie/direct wróci do wcześniejszego stanu OFF, backend ustawia nowe pełne 15 minut, HA bierze dokładny local_thermostat_resume_at zwrócony przez backend, więc stary odczyt nie powinien chwilowo przywracać poprzedniego timera.
Frontend nadal może odświeżać MM:SS co sekundę lokalnie — to jest właściwe. Frontend tylko wyświetla czas, backend decyduje kiedy przejąć sterowanie. Jeśli chcesz całkowicie uniezależnić wyświetlanie od zegara przeglądarki, później można dodać server_time albo remaining_seconds.
- Pilot + Home Assistant + Web — jak powinno to działać
Tutaj obecna architektura jest już częściowo dobra. Masz dwa różne rodzaje poleceń:
bezpośrednie urządzenie — pilot, Web „Devices”, fizyczny climate w HA, termostat strefy — Quick Thermostat w Web i climate._thermostat w HA.
Logicznie ustawiłbym następujące zasady:
Pilot/direct przejmuje urządzenie. Powstaje device_manual_override. Harmonogram, grupa i automatyka nie walczą wtedy z człowiekiem. Kolejna komenda direct z HA/Web zmienia tę samą ręczną sesję i nadal nie uruchamia automatyki. Komenda do termostatu strefy oznacza świadome: „teraz znowu steruje regulator”. Wtedy device_manual_override jest kasowany i zaczyna obowiązywać termostat. Grupy, harmonogram i automatyzacje nie powinny po cichu odbierać sterowania pilotowi. Globalne OFF powinno pozostać nadrzędne — i obecny kod właśnie tak działa.
To jest bardzo sensowna polityka.
W panelu dodałbym jednak jawny status jednego właściciela:
Automatyka / Termostat lokalny / Pilot / HA — sterowanie bezpośrednie / Web — sterowanie bezpośrednie / Globalnie wyłączone
oraz:
od kiedy, do kiedy, dlaczego, przycisk Przejmij sterowanie termostatem.
API też powinno to wystawiać, np. logicznie jako:
control_owner control_source control_since resume_at
Obecnie device_manual_override jest zapisany, ale dokładne źródło przejęcia jest głównie w logach. Przy dalszym rozwoju warto zrobić z tego normalny stan.
Szczególnie w HA rozważyłbym, żeby fizyczny climate urządzenia był oznaczony jako „sterowanie bezpośrednie / zaawansowane”, a głównym encją użytkową był termostat strefy. Teraz użytkownik może mieć dwa climate dla jednego klimatyzatora, które celowo mają inne znaczenie — łatwo się pomylić.
- Co jeszcze brakuje przed używaniem tego jako głównego ogrzewania/chłodzenia
Najważniejsze rzeczy, w tej kolejności:
Blokada współbieżnych zmian strefy. To jest realny problem w obecnym kodzie. HA i Web mogą prawie równocześnie pobrać ten sam Zone, zmienić różne pola i zapisać cały JSON. Ostatni zapis może nadpisać poprzednią zmianę. Dałbym per-zone mutex oraz docelowo revision/optimistic locking. To jest dla mnie najwyższy następny priorytet. Formalny model własności sterowania. Zamiast sprawdzania w wielu miejscach device_manual_override, local_thermostat_power, group gate itd., jedna metoda typu resolve_control_owner() powinna określać kto aktualnie może wysyłać komendy. Panel, HA i engine korzystałyby z tej samej odpowiedzi. Ochrona przed szybkim przełączaniem Heat ↔ Cool / OFF ↔ ON. W modelu masz min_on_seconds i min_off_seconds, ale obecnie praktycznie nie są wykorzystywane przez regulator. Zmiana trybu jest wręcz traktowana jako pilna. Dla głównego źródła ogrzewania dodałbym minimum 3–5 minut blokady po wyłączeniu oraz przy zmianie Heat/Cool. Kontrola świeżości czujnika HA. read_temperature() sprawdza, czy wartość jest liczbą, ale nie sprawdza wieku last_updated. Sensor może wisieć z poprawną wartością przez wiele godzin. Potrzebny jest np. sensor_stale_after=5 min, fallback na GREE i informacja/alarm. Tryby ręcznego „hold”. Zamiast jednej zasady warto mieć: 15 min, 30 min, 1 h, do kolejnego harmonogramu, do godziny..., bezterminowo. Ten sam mechanizm można potem wykorzystać dla temperatury, profilu, pilota i lokalnego OFF. Zmiana harmonogramu podczas ręcznego przejęcia. Kod aktualizuje granicę manual_override_until dla ręcznego profilu/setpointu po edycji harmonogramu, ale nie widzę analogicznego przeliczania device_manual_override_until. To może pozostawić nieaktualny termin przejęcia po zmianie grafiku. Desired state vs actual state. Warto w API jasno publikować „czego chce regulator” i „co faktycznie ma klimatyzator”, plus powód rozbieżności: pilot, offline, timer, group OFF, lockout. Część tego już masz w control-plan, więc to jest naturalne rozszerzenie. Ochrona temperaturowa. Dla głównego ogrzewania przyda się opcjonalny „frost protection”, np. alarm lub awaryjne grzanie poniżej określonej temperatury. Powinno być osobno konfigurowalne, żeby świadome globalne OFF nie zostało niespodziewanie złamane. Dopiero później rozważałbym automatyczne Heat/Cool na podstawie temperatury z dużą martwą strefą i minimalnym czasem pozostawania w jednym trybie.
Najbliższa zmiana architektoniczna, którą zrobiłbym teraz, to więc ControlOwnership + per-zone locking/revision. To rozwiąże większość przyszłych konfliktów HA ↔ Web ↔ pilot w jednym miejscu, zamiast dodawać kolejne wyjątki.