Tutorial: Publikowanie komunikatu MQTT Discovery, który trafia do panelu energii

Spis treści
Urządzenie zgłaszające się przez MQTT robi to jednym komunikatem. Trafia on na temat, którego Home Assistant i tak nasłuchuje, niesie JSON i musi mieć flagę retained – inaczej istnieje tylko do najbliższego restartu jednej ze stron.
Utworzenie encji tą drogą to sprawa sześciu linii. Doprowadzenie do tego, by encja została przyjęta jako źródło energii, to sprawa trzech kolejnych – i właśnie tam leży cała praca: każde z tych trzech pól zostaje po cichu pominięte, gdy jest ustawione źle, a objaw zawsze wygląda tak samo, jak pusta lista wyboru.

Temat decyduje, gdzie pojawi się encja
Discovery działa przez wzorzec tematu, a nie przez wywołanie rejestrujące. Home Assistant subskrybuje prefiks, a wszystko opublikowane pod nim w odpowiedniej postaci staje się encją.
homeassistant/sensor/kellerzaehler/energie/config
│ │ │ │
prefiks komponent node_id object_id
Prefiks brzmi homeassistant, dopóki nie został zmieniony w integracji MQTT. Komponent określa typ encji i musi odpowiadać temu, co opisuje zawartość – sensor dla wartości pomiarowej, binary_sensor dla stanu tak-nie, switch dla czegoś przełączalnego.
Node ID i object ID to dowolny tekst służący wyłącznie zachowaniu niepowtarzalności tematu. Nie są identyfikatorem encji: ten powstaje później z nazwy, a temat zmieniony po fakcie tworzy drugą encję, zamiast zmienić nazwę pierwszej.
Najmniejsza zawartość, która naprawdę działa
Cztery klucze wystarczą, aby encja zaistniała. Nazwa, temat z napływającymi pomiarami, jednostka oraz identyfikator przetrwający restarty.
{
"name": "Licznik w piwnicy",
"state_topic": "dom/piwnica/licznik",
"unit_of_measurement": "kWh",
"unique_id": "kellerzaehler_energie"
}
Z tych czterech szczególnie opłaca się unique_id. Bez tego klucza encja wprawdzie się pojawia, lecz nie da się jej zmienić nazwy, przypisać do obszaru ani w ogóle wybrać w panelu energii. Identyfikator musi być niepowtarzalny w całej instalacji, dlatego części tematu dobrze się do tego nadają.
Blok device jest dobrowolny i zwraca się natychmiast: encje z tym samym identyfikatorem zostają zebrane w jedno urządzenie, a jedno urządzenie z ośmioma pomiarami żyje się znacznie wygodniej niż osiem luźnych encji.
"device": {
"identifiers": ["kellerzaehler"],
"name": "Licznik w piwnicy",
"manufacturer": "Eastron",
"model": "SDM630"
}
Trzy pola, które czyta panel energii
Encja z liczbą w środku to jeszcze nie źródło energii. Trzy pola muszą do siebie pasować, zanim pojawi się na liście wyboru, a każde z nich opisuje co innego.
| Pole | Wymagana wartość | Znaczenie |
|---|---|---|
| device_class | energy | Liczba jest ilością energii, nie mocą |
| unit_of_measurement | Wh, kWh, MJ lub GJ | Jednostka, w której liczona jest ta ilość |
| state_class | total_increasing | Wartość rośnie wyłącznie w górę |
Najczęściej nie pasują do siebie dwa pierwsze. Licznik podający waty jest czujnikiem mocy: device_class power, state_class measurement, jednostka W. Taki czujnik jest pożyteczny i poprawny, a mimo to nigdy nie pojawi się jako źródło energii, bo moc nie jest energią. Panel energii szuka stanu licznika, który się sumuje.
Trzecie pole rozstrzyga, jak potraktowane zostanie wyzerowanie licznika. Przy total_increasing nagle mniejsza wartość uchodzi za nowy cykl liczenia, a nie za ujemne zużycie, i statystyka biegnie dalej. Przy total ten sam skok wymaga znacznika czasu last_reset do interpretacji, a bez niego z danej godziny robi się wyskok. Dla fizycznego licznika, który idzie do przodu i czasem zaczyna od nowa, total_increasing jest wyborem uczciwym.
Publikacja ręczna
Nic z tego nie wymaga urządzenia. Jedno polecenie tworzy encję, a to samo polecenie z inną treścią ją aktualizuje.
mosquitto_pub -h 192.168.1.10 -u ha -P tajne -r \
-t "homeassistant/sensor/kellerzaehler/energie/config" \
-m '{
"name": "Licznik w piwnicy",
"state_topic": "dom/piwnica/licznik",
"unit_of_measurement": "kWh",
"device_class": "energy",
"state_class": "total_increasing",
"unique_id": "kellerzaehler_energie",
"device": { "identifiers": ["kellerzaehler"], "name": "Licznik w piwnicy" }
}'
mosquitto_pub -h 192.168.1.10 -u ha -P tajne -r \
-t "dom/piwnica/licznik" -m "18234.7"
Przełącznik -r bywa zapominany, a należy się obu komunikatom z dwóch różnych powodów. Na temacie konfiguracyjnym sprawia, że opis przetrwa restart Home Assistant – inaczej encja znika aż do przypadkowego ponownego zgłoszenia urządzenia. Na temacie stanu sprawia, że encja ma wartość zaraz po restarcie, zamiast stać jako niedostępna do czasu kolejnego pomiaru.
Uwaga co do rozmiaru zawartości: firmware mówiący językiem discovery wysyła zwykle skrócone klucze – stat_t, dev_cla, stat_cla, unit_of_meas, uniq_id, dev. Obie pisownie działają i wolno je nawet mieszać. Zawartość pisana ręcznie pozostaje czytelniejsza w postaci pełnej.
Gdy encja się pojawia i zostaje pusta
Encja, która istnieje i nic nie pokazuje, to niemal zawsze rozjazd tematów: state_topic w zawartości i temat, na którym publikowana jest wartość, różnią się o jeden znak. Subskrypcja z symbolem wieloznacznym pokazuje obie strony naraz.
mosquitto_sub -h 192.168.1.10 -u ha -P tajne -v -t "dom/#"
Jeżeli wartość dociera, ale tkwi w większym komunikacie JSON, wyciąga ją value_template – "value_template": "{{ value_json.total_kwh }}". Bez tego encja dostaje cały obiekt i zgłasza go jako nieznany.
Do tego ostrzeżenie przed polem, które wygląda pomocnie: expire_after ustawia encję jako niedostępną, gdy w podanej liczbie sekund nie nadejdzie żadna wartość. Przy przełączniku bywa to użyteczne. Przy liczniku energii rozrywa statystykę długoterminową, bo każda przerwa kończy cykl liczenia. Licznik meldujący się co piętnaście minut radzi sobie lepiej bez tego pola.
Przy ostatnim kroku pomaga cierpliwość. Statystyka długoterminowa powstaje w odcinkach pięciominutowych, a panel energii zbiera dane godzinami. Świeżo utworzony czujnik pozostaje więc pusty, dopóki nie minie pierwsza pełna godzina. To nie jest usterka, a ponowna publikacja zawartości niczego nie przyspiesza.
Usunięcie urządzenia bez pozostawiania widma
Skasowanie encji w interfejsie działa do najbliższego restartu – wtedy zachowany komunikat konfiguracyjny tworzy ją ponownie. Usunięcie musi nastąpić tam, gdzie nastąpiło utworzenie.
mosquitto_pub -h 192.168.1.10 -u ha -P tajne -r \
-t "homeassistant/sensor/kellerzaehler/energie/config" -m ""
Pusta zawartość z flagą retained na temacie konfiguracyjnym kasuje jednocześnie encję i zapamiętany komunikat. Temat stanu zachowuje własną wartość retained i najlepiej wyczyścić go tak samo – inaczej kolejne urządzenie na tym temacie odziedziczy pomiar należący do czegoś innego.