Każda zmiana stanu w Home Assistancie trafia do bazy danych. Włączenie światła, odczyt temperatury, spadek baterii telefonu o jeden procent, płytka ESP, która co kilka sekund melduje siłę sygnału Wi-Fi. Wszystko to zapisuje integracja Recorder i przy niewielkiej instalacji domyślne ustawienia są w porządku. Gdy jednak dojdzie kilka liczników energii, kilkanaście urządzeń z ESPHome i parę gadatliwych integracji chmurowych, plik rośnie do kilku gigabajtów, kopie zapasowe robią się wolne, a Raspberry Pi z kartą SD zapisuje na nią znacznie więcej, niż powinno.
Rzadko pomaga przejście na MariaDB. W większości domów za większość wierszy odpowiada kilka encji. Wystarczy je znaleźć, przestać zapisywać to, czego nikt nie ogląda, a resztę ustawień zostawić w spokoju. Poniżej opisuję, jak to zrobić i nie stracić historii, na której ci zależy.
Co zapisuje Recorder i jak długo to trzyma
Recorder działa od razu po instalacji. Korzysta z niego historia, więc nie dodajesz go ręcznie. Jeśli niczego nie zmienisz, dane trafiają do pliku SQLite /config/home-assistant_v2.db.
W tym pliku są dwa rodzaje danych i każdy znika z bazy po innym czasie:
- Stany i zdarzenia. Każda aktualizacja stanu to osobny wiersz, także wtedy, gdy zmienił się tylko atrybut, na przykład utwór w odtwarzaczu albo kolor światła. Te wiersze są usuwane po liczbie dni ustawionej w
purge_keep_days, domyślnie po 10. - Statystyki. Dla czujników z klasą stanu (
measurement,total,total_increasing) Home Assistant co 5 minut liczy statystyki krótkoterminowe, a co godzinę długoterminowe. Krótkoterminowe znikają razem ze stanami. Godzinowych Home Assistant nigdy nie usuwa. Z nich korzysta panel energii i karta wykresu statystyk, i dlatego zeszłoroczny przebieg temperatury nadal jest widoczny, chociaż surowe stany z 10 dni dawno zniknęły.
Jeśli więc potrzebujesz roku historii temperatury albo zużycia energii, nie musisz ustawiać purge_keep_days: 365. Statystyki godzinowe już ją przechowują, po 24 wiersze na czujnik dziennie. Dłuższy okres przechowywania oznacza głównie miliony surowych wierszy, których i tak nikt nie przegląda.
Sprzątanie, które dzieje się samo
Domyślna konfiguracja ma dwa zaplanowane zadania:
auto_purge: truecodziennie o 04:12 czasu lokalnego usuwa stany i zdarzenia starsze niżpurge_keep_days.auto_repack: truew drugą niedzielę każdego miesiąca, po czyszczeniu, przepisuje całą bazę od nowa.
To różnica, o której warto pamiętać. Czyszczenie usuwa wiersze, ale plik od razu się nie zmniejsza, tylko wolniej rośnie. Miejsce na dysku odzyskasz dopiero po przepakowaniu. Jeśli usunąłeś dużo danych i potrzebujesz miejsca od razu, zajrzyj do sekcji o akcjach ręcznych.
Sprawdź, ile zajmuje baza
Wejdź w Settings > System > Repairs, otwórz menu pod trzema kropkami, wybierz System information i w sekcji Recorder znajdź pozycję Estimated Database Size (MiB). Zanotuj tę liczbę, żeby później mieć porównanie.
Potem sprawdź wolne miejsce na dysku. Dokumentacja Recordera stawia sprawę jasno: wolnego miejsca zawsze musi być co najmniej tyle, ile zajmuje baza. Przy bazie 1,5 GiB potrzebujesz kolejnych 1,5 GiB wolnego miejsca, bo przebudowa i przepakowanie kopiują dane, zwłaszcza przy aktualizacjach Home Assistanta zmieniających strukturę bazy. Jeśli plik SQLite się uszkodzi, Home Assistant odkłada go na bok i zakłada nową bazę, a do tego według dokumentacji wolne miejsce równe 2,5-krotności rozmiaru bazy jest niezbędne. Pełny dysk w trakcie aktualizacji to jeden ze sposobów na utratę całej historii.
Znajdź encje, które zapisują najwięcej
Zgadywanie to kiepski sposób na wybór wykluczeń. Lepiej spojrzeć w dane. Aplikacja SQLite Web z repozytorium Home Assistant Community Apps otwiera domyślną bazę w przeglądarce. Zainstaluj ją w menu Ustawienia > Aplikacje (Settings > Apps), uruchom i otwórz jej interfejs.
Tabela states nie przechowuje identyfikatorów encji bezpośrednio, są w tabeli states_meta, więc potrzebne jest złączenie. To zapytanie liczy wiersze dla każdej encji:
SELECT states_meta.entity_id, COUNT(*) AS row_count
FROM states
JOIN states_meta ON states.metadata_id = states_meta.metadata_id
GROUP BY states_meta.entity_id
ORDER BY row_count DESC
LIMIT 25;
Bazy nie modyfikuj. Dokumentacja danych Home Assistanta ostrzega, że zapis do niej w trakcie działania Home Assistanta może uszkodzić historię. Uruchamiaj tylko zapytania SELECT.
Na górze listy często lądują:
- czujniki mocy i prądu z inteligentnych gniazdek albo mierników energii, które raportują co kilka sekund;
- czujniki siły sygnału Wi-Fi, czasu pracy i adresu IP, dodawane przez ESPHome albo inne oprogramowanie do każdego urządzenia;
- czujniki telefonu z aplikacji mobilnej (bateria, kroki, rodzaj połączenia);
- encje pogody i słońca z wieloma często zmieniającymi się atrybutami.
Jeśli jedna encja ma dziesięć razy więcej wierszy niż następna, od niej zacznij.
Przestań zapisywać to, czego nie oglądasz
Wykluczenia wpisuje się w pliku configuration.yaml. Nie da się ich ustawić w interfejsie, więc po edycji pliku uruchom Home Assistanta ponownie. Na początek może to wyglądać tak:
recorder:
commit_interval: 30
exclude:
domains:
- update
entity_globs:
- sensor.*_wifi_signal
- sensor.*_uptime
entities:
- sensor.last_boot
Co robi każda część:
domainspomija całą domenę, tutaj encjeupdate, których historii rzadko się potrzebuje.entity_globsdopasowuje wzorce:*oznacza dowolny ciąg znaków, a?jeden znak. Jeśli urządzenia z ESPHome mają spójne nazwy, jedna linia obejmie je wszystkie.entitiesto lista konkretnych identyfikatorów encji.sensor.last_bootpodaje sama dokumentacja Recordera jako przykład encji zapisywanej bardzo często.event_types, którego tu nie używam, pomija zdarzenia określonego typu, na przykład własne zdarzenie, które jakaś automatyzacja wysyła bez przerwy. Na historię stanów nie wpływa.
Nazwy dopasuj do swojej instalacji. Powyższe wzorce zadziałają tylko wtedy, gdy encje rzeczywiście tak się nazywają.
Jest też include, ale z nim trzeba uważać. Gdy ustawisz jakikolwiek filtr include, wszystko spoza listy przestaje być zapisywane. Przy celowo minimalnej konfiguracji to się sprawdza, ale łatwo zapomnieć o nowym urządzeniu i potem się zastanawiać, czemu nie ma historii. W większości domów bezpieczniej zostać przy samym exclude.
Dwie rzeczy, które łatwo pomylić:
- Ukrycie encji nie wyłącza jej zapisu. Ukryte encje nadal trafiają do bazy.
- Filtr integracji Activity to coś innego. Ukrywa wpisy tylko w panelu aktywności. Wykluczenia w Recorderze w ogóle nie wpuszczają danych do bazy.
Nie wykluczaj tego, czego potrzebuje panel energii
Statystyki długoterminowe powstają z zapisanych stanów. Jeśli wykluczysz czujnik mocy albo energii, nie dostanie nowych statystyk i zniknie z panelu energii oraz z wykresów statystyk. Przy hałaśliwym czujniku energii lepiej więc ograniczyć częstotliwość raportów niż go wykluczać.
W ESPHome zrobisz to w samym urządzeniu:
sensor:
- platform: hlw8012
# piny i pozostałe opcje dla konkretnego urządzenia
power:
name: "Power"
filters:
- throttle_average: 60s
throttle_average: 60s wysyła jedną uśrednioną wartość na minutę zamiast każdego odczytu, o ile w tej minucie przyszedł choć jeden. Wykres nadal ma sens, a do bazy trafia dużo mniej wierszy.
Sprawdź też opcję force_update w czujnikach ESPHome. Przy wartości true Home Assistant tworzy zmianę stanu przy każdej aktualizacji, nawet gdy wartość się nie zmieniła. Dokumentacja ESPHome ostrzega, że może to znacznie powiększyć bazę. Zostaw false, chyba że takie narzędzie jak Grafana naprawdę tego wymaga.
Rzadszy zapis na karcie SD
commit_interval określa, co ile sekund Recorder zapisuje zebrane zmiany na dysk. Domyślnie co 5 sekund. Wyższa wartość to mniej operacji zapisu i dokumentacja Recordera zaleca ją wprost przy Raspberry Pi z kartą SD, podając jako przykład 30 sekund. Baza będzie trochę opóźniona, ale historia i panel aktywności nadal pokażą bieżące dane. Wartość 0 ustaw tylko wtedy, gdy każda zmiana musi trafić do bazy od razu.
Jeśli Home Assistant od dawna działa na Raspberry Pi z kartą SD, to jedyne ustawienie, które warto zmienić nawet przy rozsądnym rozmiarze bazy.
Posprzątaj to, co już jest w bazie
Wykluczenia działają dopiero od ponownego uruchomienia. Wiersze, które już są w bazie, zostają tam, dopóki nie usunie ich nocne czyszczenie. Żeby usunąć je wcześniej, użyj akcji Recordera w narzędziach deweloperskich (Developer tools > Actions).
Usunięcie danych konkretnych, hałaśliwych encji:
action: recorder.purge_entities
data:
keep_days: 0
entity_globs:
- sensor.*_wifi_signal
- sensor.*_uptime
Domyślnie keep_days wynosi 0, czyli usuwa wszystkie pasujące dane. Wyższa wartość zachowa najnowszą historię. Wzorce w entity_globs wpisz jako listę YAML. Znany jest błąd, w którym kilka wzorców wpisanych w edytorze wizualnym zapisuje się jako jeden ciąg oddzielony spacjami: akcja nie zgłasza żadnego błędu, ale niczego nie usuwa.
Żeby zastosować nowe wykluczenia do starych danych i od razu zmniejszyć plik:
action: recorder.purge
data:
apply_filter: true
repack: true
Przy SQLite i PostgreSQL repack przepisuje całą bazę od nowa. To ciężka operacja: Home Assistant może w tym czasie zwolnić, a zajęte miejsce na dysku chwilowo rośnie. Uruchamiaj ją, gdy wolnego miejsca jest co najmniej tyle, ile zajmuje baza, i nie tuż przed chwilą, w której Home Assistant musi szybko reagować.
Jeśli jedna encja ciągle sprawia kłopot, możesz zaplanować recorder.purge_entities w automatyzacji, na przykład co noc z keep_days: 5. Dokumentacja Home Assistanta pokazuje dokładnie taki przykład dla hałaśliwego czujnika mocy.
Czy potrzebujesz MariaDB albo PostgreSQL?
Zwykle nie. Według dokumentacji Recordera SQLite to opcja domyślna, zalecana i najlepiej przetestowana. Obsługiwane są też MariaDB (od wersji 10.3), MySQL (od 8.0) i PostgreSQL (od 12), ale zmiana bazy może oznaczać utratę historii, a przenoszenie danych między silnikami nie jest obsługiwane. W przypadku MariaDB dokumentacja wspomina też o spadku wydajności w wersjach starszych niż 10.5.17, 10.6.9, 10.7.5 i 10.8.4.
Osobny serwer bazy danych ma sens, gdy już taki masz i wiesz, jak robić jego kopie, albo gdy dane mają być dostępne dla innych narzędzi. Nie pomoże jednak bazie, która urosła, bo kilka czujników zapisuje za dużo. Na to są wykluczenia i filtry.
Typowe błędy
- Wydłużenie
purge_keep_days, żeby mieć wykresy z całego roku. Statystyki długoterminowe robią to dużo taniej. - Wykluczenie czujnika energii, który potem znika z panelu energii. Lepiej ograniczyć częstotliwość raportów w urządzeniu.
- Dodanie jednego wpisu
includei utrata historii wszystkiego innego. - Oczekiwanie mniejszego pliku zaraz po czyszczeniu. Miejsce odzyskasz dopiero po przepakowaniu.
- Brak miejsca na dysku w trakcie aktualizacji. Trzymaj zawsze co najmniej tyle wolnego miejsca, ile zajmuje baza.
- Ręczne zmiany w bazie, gdy Home Assistant działa. Tylko odczyt albo akcje Recordera.
- Przekonanie, że ukrycie encji wyłącza jej zapis. Nie wyłącza, do tego służy
exclude.