Napisz do mnie

Wyślij prywatną wiadomość

MQTT - STRUKTURA TEMATÓW WIADOMOŚCI

opublikowano: 10 lut 2019 wyświetleń: 287 komentarzy: 0

#dariahomesystem #IoT #home automation #automatyka domowa #MQTT #Node-RED #JSON

Jak ugryźć temat... tematów wiadomości w MQTT?

W jednym z wcześniejszych wpisów dotyczącym połączenia Hapcana z Node-REDem wspomniałem o problemie z utrzymaniem porządku i czytelności przepływów. Poniższy rysunek poglądowy dla przypomnienia:

Skomplikowane połączenia w Node-RED

Wszystko jest tutaj ładnie pomieszane i będzie to bardzo trudne w utrzymaniu. Dlatego też, postanowiłem, po pierwsze podzielić cały system oparty o Node-RED na osobne przepływy, spełniające określone zadania. Sprawa prosta i oczywista. Node-RED umożliwia tworzenie połączeń pomiędzy przepływami i tak można z jednej karty wywołać funkcje znajdujące się na innej karcie. Ma to jednak jeden minus — wszystkim zajmuje się Node-RED.

Postanowiłem zatem uniezależnić się od jednego tylko procesu i całą komunikację pomiędzy urządzenia, serwisami, usługami przepuszczam przez zewnętrzny proces serwera MQTT.

STRUKTURA TEMATÓW MQTT

Protokół nie wymusza żadnej konkretnej struktury, zatem mamy pełną dowolność. Niestety szybko okazuje się, że zaczniemy wyszukiwać w internetach fraz: jaka struktura mqtt. Każdy ma swoją wersję, swój pomysł. Czy w temacie umieszczać informację, który parametr w systemie się zmienia? Czy może nazwę albo adres urządzenia? A może jego typ… albo położenie w domu, a co jeśli usługa nie ma położenia, bo jest tylko usługą :).

Głowiłem się na tym tematem dosyć długo. Od wyboru sposobu tworzenia tematów zależy też, czy będziesz mógł skorzystać np. z aplikacji na Androida, w którym mógłbyś oglądać i sterować swoim systemem. Ich możliwości są nieco ograniczone i wymuszają one poniekąd pewne informacje zawarte w temacie.

Po wielu próbach opracowałem, nie powiem, że do końca oraz, że jest to jedyny, najlepszy i w ogóle… sposób zapisu tematów.

ŹRÓDŁO / DOMENA / LOKALIZACJA-USŁUGA / NAZWA / TYP / RODZAJ

Wygląda groźnie, w praktyce mi jest łatwiej zapamiętać takie tematy i pisać je z głowy. Kilka założeń odnośnie tematów i wiadomości:

  • wszystkie tematy mają tę samą strukturę — co za tym idzie, głębokość
  • wiadomości w formacie JSON
  • tematy nie przekazują informacji o statusie ani instrukcji sterujących

Dlaczego JSON? Bo można go w dowolnej chwili rozszerzyć o dodatkowe dane i nie posypie się cały istniejący już kod. Z podobnego względu tematy nie zawierają informacji nt. statusu ani instrukcji sterujących. Niektóre statusy czy instrukcje mają więcej niż 1 parametr. W temacie trzeba by to realizować poprzez jego zmienną długość lub wysyłać kilka osobnych instrukcji sterujących — a niestety niektóre urządzenia potrzebują kompletu instrukcji aby zachowywały się poprawnie.

W tabeli poniżej podam kilka przykładów słów kluczowych, używanych przeze mnie w temacie.

ŹRÓDŁO DOMENA LOKALIZACJA-USŁUGA NAZWA TYP RODZAJ
home env room1 walllight light status
car   interior ceiling switch control
rod   kitchen door blind health
mobile1 sys generator evening scene  
mobile2     night event  
           

PRZYKŁADOWE TEMATY

  • home/env/room1/walllight/light/status
  • home/env/room1/walllight/light/control
  • home/env/kitchen/leftwindow/switch/status
  • home/env/room2/window2/blind/control
  • home/sys/generator/sun/event/status
  • home/sys/room1/night/scene/control
  • car/env/interior/front/temperature/status

DOKŁADNIEJSZY OPIS

Źródło wskazuje na fragment systemu, który bezpośrednio jest związany z wiadomością. Wszystko co jest generowane w domu i jest z nim związane ma tutaj wartość home. Inne wartości wskazują na zewnętrzne jednostki organizacyjne, jakimi np jest samochód, działka (ROD) czy smartfon.

Domena ma obecnie dwie wartości i pozwala sprecyzować o jaki świat chodzi :)

  • env — environment, czyli podsystem związany z fizycznymi urządzeniami, jak światła, rolety, czujniki
  • sys  — system, czyli podsystem związany z wszelkimi wirtualnymi usługami, serwisami, wiadomości systemowe

Lokalizacja/usługa przybliża z czym mamy do czynienia. W przypadku domeny env są to zazwyczaj nazwy pomieszczeń, czyli room1, room2, kitchen, wc, bathroom, hall, interior. W przypadku domeny systemowej np. generator, ale też room1, room2 itp. — co oznacza, że usługa działa w obrębie konkretnego pomieszczenia.

Nazwa to sprawa oczywista, coś co pozwala mi zidentyfikować czy chodzi o lampę na suficie czy na ścianie, usługę taką czy inną.

Typ dotyczyć może fizycznego typu urządzenia: light, switch, temp, blind, lub też usługi: scene, event. Pozwala np. grupować wszystkie informacje o światłach pochodzące z mieszkania i zasubskrybować je pod jednym tematem.

Rodzaj określa przeznaczenie wiadomości:

  • status — oznacza, że wiadomość zawiera informacje o statusie urządzenia bądź usługi
  • control — oznacza wiadomość sterującą danym urządzeniem lub usługą

Trzymając się takiego podziału wiem czego konkretnie dotyczy wiadomość, czy jest to urządzenie czy usługa, gdzie się ono znajduje, czy jest to wiadomość sterująca czy status.

Sytuacje dyskusyjne

Kwestia organizacji niektórych tematów nie jest taka oczywista, trzeba po prostu popatrzyć, jak będzie dla nas wygodniej. Przykładowo informacja o zajściu słońca. Jest ona generowana przez fragment kodu w Node-RED, który pozwala emitować wszelkie zdarzenia związane ze słońcem, sunrise, sunset, night (wschód, zachód, noc) itp.

Temat mógłby zatem wyglądać tak:

  • home/sys/suneventsgenerator/sunset/event/status

Zawiera on informację o tym, że jest to jakieś zdarzenie systemowe, że wygenerowała ją usługa suneventsgenerator. Można zasubksrybować się pod ten konkretny temat i wykonać jakąś operację po zachodzie słońca — np. włączyć światła na zewnątrz. Ale teraz, żeby je o świcie wyłączyć należałoby zasubskrybować się do analogicznego zdarzenia na wschód słońca:

  • home/sys/suneventsgenerator/sunrise/event/status

Inne rozwiązanie, to nasłuchiwanie wszystkich tematów związanych z generatorem słonecznym, czyli :

  • home/sys/suneventsgenerator/+/event/status

Wtedy trzeba jednak po odebraniu powiadomienia sprawdzić jaki jest 4 człon tematu, aby wiedzieć jakie to zdarzenie nastąpiło. W tym jak i w powyższych rozwiązaniach sam temat mówi nam już w zasadzie wszystko co chcemy wiedzieć, wiadomość sama w sobie jest zbędna.

Ja póki co zainwestowałem w jeszcze inny sposób, czyli zamiast generatora słonecznego (suneventsgenerator) mam usługę generator. Generator może być oparty o różne aspekty, słońce, czas, być może kalendarz imienin. Tematy generowane u mnie wyglądają zatem tak:

  • home/sys/generator/sun/event/status
  • home/sys/generator/time/event/status

W samym temacie nie mam jasnej informacji co się stało — tę informację niesie treść wiadomości. Wiem tylko, że nastąpiło jakieś zdarzenie związane ze słońcem lub z czasem. A sama wiadomość, to zgodnie z założeniami JSON:

{
  "event": "sunset"
}

To oczywiście pociąga za sobą konieczność przetwarzania wiadomości aby sprawdzić jakie to zdarzenie przyszło i tym zajmuje się klocek w Node-RED.

 

KOMUNIKACJA I ABSTRAKCJA

Przy nieco większych systemach problematyczne staje się pamiętanie jaki adres Hapcan ma dane urządzenie, jakie instrukcje trzeba do niego wysłać oraz jak odczytać z niego dane. Dlatego też wszelkie urządzenia Hapcan, oraz inne typu Philips Hue, mam zmapowane na odpowiednie tematy MQTT i tylko przez MQTT mogę się z nimi komunikować. Oczywiście jest to założenie, bo w praktyce nie ma tutaj żadnych ograniczeń.

W Node-RED mam osobne karty (przepływy), na których wszystkie urządzenia generują odpowiednie tematy rodzaju status, oraz odpowiednio zaadresowane tematy control pozwalają sterować urządzeniami. W tym momencie wiedza o tym, że światło w kuchni to jest moduł Hapcan nr (4,2), przekaźnik 5 przestaje być istotna przy programowaniu systemu. Jest ona zapisana tylko w jednym miejscu gdzie następuje mapowanie Hapcan-MQTT.

Jeśli zatem pragnę sterować światłem na suficie w kuchni to tworzę z głowy odpowiedni temat:

  • home/env/kitchen/ceiling/light/control

i mam pewność, że dotrze to do odpowiedniego przekaźnika w Hapcanie. Takie podejście ma dużo więcej zalet. W przypadku awarii, lub zmiany w infrastrukturze Hapcana i np. podłączeniu zamiast przekaźnika żarówki Philips Hue (zigbee) nie muszę modyfikować całego istniejącego już kodu. Wystarczy zmienić tylko mapowanie.

Cała kontrola nad urządzeniami przechodzi zatem zawsze przez jeden punkt. Daje to możliwość wpływu na wiadomości sterujące niezależnie od tego, kto je wysłał. Przykładowo w godzinach wieczornych światła są delikatnie ściemniane i niezależnie od tego czy będą włączone pilotem, przyciskiem, głosem czy poprzez czujnik ruchu, każde z tych poleceń przejdzie przez kawałek kodu, który zmieni bądź też doda parametr brightness odpowiadający za jasność świecenia danej lampy.

Również w sytuacji gdy chcemy jakiś element systemu odłączyć, wiadomo że wystarczy przerwać jedną nitkę w mapowaniu a nie przeszukiwać cały system w poszukiwaniu użycia bloczka sterującego odpowiednim przekaźnikiem.

O tym jednak, w następnej części.


CZYTAJ DALEJ POZOSTAŁE CZĘŚCI TEGO ARTYKUŁU


ZOBACZ RÓWNIEŻ POLECANE WPISY


Comments (0)


Allowed tags: <b><i><br>


PODOBAŁO SIĘ?

PODOBAŁO SIĘ?


0 like voting
is closed
thanks
for your vote

PODZIEL SIĘ

PODZIEL SIĘ