niedziela, 26 października 2014

OpenHab, arduino i mqtt binding


Jak już pisałem wcześniej komunikacja arduino z OpenHab za pomocą TCP nie sprawdziła się w praktyce. Za to z czystym sumieniem mogę stwierdzić że komunikacja za pomocą MQTT działa znakomicie.

Przy takim rozwiązaniu dochodzi jednak dodatkowa warstwa pośrednia - broker.
W uproszczeniu można powiedzieć że broker zajmuje się rozprowadzaniem komunikatów do zainteresowanych klientów.

Rozwiązanie to działa na zasadzie mechanizmu Publish - subscribe.
Odpowiednie urządzenia mogą publikować (Publish) komunikaty w danym temacie (TOPIC). Klienci podłączają się do brokera informując go że są zainteresowani (subscribe) komunikatami z danego tematu.

Przenosząc to na płaszczyznę automatyki domowej ja zastosowałem następującą architekturę:

Na Raspberry PI zainstalowałem broker MQTT. Najpopularniejszym brokerem obecnie jest chyba Mosquitto.

Aby zainstalować mosquitto należy wykonać następujące polecenie:

sudo apt-get install mosquitto mosquitto-clients

Po instalacji pojawi się katalog:

/etc/mosquitto

w którym znajduje się plik konfiguracyjny brokera

mosquitto.conf

Wystarczy bardzo prosta konfiguracja:

Jak widać z powodu bezpieczeństwa wyłączyłem anonimowy dostęp do brokera. W tym przypadku należy utworzyć plik

 /etc/mosquitto/password_file

,w którym zapiszemy login i hasło do brokera z którego  będą korzystać Arduino i OpenHab.
Plik powinien zawierać wpis w postaci:

login:hasło

Teraz należy zrestartować broker poleceniem:

/etc/init.d/mosquitto restart

Następnie można przetestować działanie brokera. Dostępne są dwa programy:

mosquitto_sub 

do obsługi subskrypcji oraz

mosquitto_pub 

do obsługi publikowania.

Na początku należy uruchomić polecenie:

mosquitto_sub -h localhost -u login -P hasło -t /house

co oznacza że utworzyliśmy klienta który podłączył się do brokera na serwerze localhost przy użyciu loginu "login" i hasła "hasło" (zdefiniowanych w pliku password_file). Klient subskrybował wszystkie wiadomości w temacie (TOPIC) /house.

Po wykonaniu polecenia klient oczekuje na komunikaty.

W drugiej konsoli należy uruchomić polecenie:

mosquitto_pub -h localhost -u login -P hasło -t /house -m test

Oznacza to że na brokerze pod adresem localhost opublikowaliśmy wiadomość o treści "test" w temacie /house

Jeśli wszystko wykonaliśmy poprawnie na konsoli na której uruchomiliśmy mosquitto_sub powinna pojawić się zawartość wiadomości, czyli "test"

Dla eksperymentu można uruchomić kilka klientów mosquitto_sub nasłuchujących dany "topic". Na wszystkich jednocześnie powinna pojawić się treść opublikowanego komunikatu


Mając działający broker można przystąpić do konfiguracji OpenHab.

W tym celu należy przekopiować plik jar o nazwie

org.openhab.bindings.mqtt-1.5.0.jar (numer wersji może być inny)

 do katalogu addons serwera openhab.
W pliku konfiguracyjnym

configuration/openhab_default.cfg

należy dopisać następujące linie:


Załóżmy że chcemy sterować halogenem. W tym przypadku plik

configurations/items/house.items

powinien wyglądać następująco:

Oznacza to że w naszej konfiguracji mamy jeden przełącznik odpowiadający za załączanie halogena.
Załączenie przełącznika OPUBLIKUJE wiadomość o treści "halogen#1" na brokerze mqtt w topic'u "/house". Wyłączenie przełącznika OPUBLIKUJE wiadomość o treści "halogen#0" na brokerze mqtt również w topic'u "/house"
Dodatkowo obsługa tego przełącznika SUBSKRYBUJE topic /houseIn na tym samym brokerze.
W pliku

transform/halogen.map 

powinno znaleźć się mapowanie treści otrzymanej wiadomości na stan przełącznika.
Plik powinien mieć następującą zawartość:

halogen#1=ON
halogen#0=OFF

Nasłuchiwanie służy do aktualizacji stanu przełącznika. Pamiętajmy że halogen można zapalić również zwykłym przełącznikiem na ścianie. Wówczas OpenHab powinien się o tym dowiedzieć aby wyświetlić odpowiedni stan przełącznika.

To cała konfiguracja po stronie OpenHab. Należy tylko zrestartować usługę.

Pozostaje jeszcze obsługa po stronie mikrokontrolera.
Bibliotek do obsługi mqtt na arduino jest kilka. Ja wykorzystałem bibliotekę PubSubClient którą znalazłem pod adresem:
http://knolleary.net/arduino-client-for-mqtt/

Poniżej przedstawiam fragmenty kodu które obrazują zasadę działania:
Nie jest to kompletny kod, ponieważ całość wraz z obsługą wszystkich przekaźników które mam obecnie jest zbyt duża żeby wklejać je na bloga. Większe fragmenty publikowane były już w poprzednich wpisach. Myślę że osoby obeznane z tematem bez problemu powinny poradzić sobie z wykorzystaniem podanych fragmentów. W przypadku pytań  piszcie w komentarzach.

Jedyny fragment który sprawiał problemy to okolice wiersza 45. Po  pewnym czasie od momentu restartu arduino przy wciskaniu przełączników sprzętowych przestawały dochodzić potwierdzenia do OpenHab. Okazało się że z jakichś nieokreślonych powodów było zrywane połączenie między Arduino a MQTT. Dodanie sprawdzania stanu i ponownego połączenia w przypadku gdy połączenie nie było aktywne rozwiązało problem.

Po tych zmianach cały układ działa bardzo stabilnie i myślę że można stwierdzić że można go z powodzeniem wykorzystywać w warunkach produkcyjnych



30 komentarzy:

  1. Mam pytanie - jestem na etapie projektowania instalacji u siebie w domu.
    Jak uważasz czy model który jest umieszczony tutaj:
    https://electronichamsters.files.wordpress.com/2014/06/diagrams1.png

    czyli wszystkie sensory łacza sie po wifi do gateway sie sprawdzaja?
    Zastanawiam sie czy ciagnąc kable do kazdego sensora czy oprzec to na wifi?

    Czy mógłbyś mi doradzić na co zwrocic uwage podczas projektowania instalacji tak żeby później nie żałować że coś pominałem?

    z góry dziekuje!

    OdpowiedzUsuń
  2. Trudno mi powiedzieć czy połączenie po wi-fi się sprawdzi. nie korzystałem z takiego rozwiązania.

    Jeśli miałbym cokolwiek doradzać - Zastanów się bardzo dobrze już na etapie projektu czym w przyszłości będziesz chciał sterować, lub jakie czujniki będziesz chciał montować.
    Jeśli masz możliwość połóż nawet więcej przewodów niż będziesz potrzebował. Ja już teraz zauważam że kilku mi brakuje. Połóż dobrej jakości przewody. Nie ma nic bardziej irytującego jak łamiące się końcówki przewodów przy ich podłączaniu. Jeśli będziesz robił instalację na tej zasadzie co ja, czyli zwykła instalacja + skrętka do puszki - wykorzystaj jak największe (najgłębsze, lub nawet podwójne puszki, których część będzie zatynkowana. W zwykłej małej puszce ciężko jest sensownie upchnąć przekaźnik tak żeby nie bać się że zrobi się jakieś zwarcie, lub połamią się styki

    OdpowiedzUsuń
  3. A powiedz czy lepiej zaprojektować jeden punkt zbiorczy wszystkich kabli czy podzielic dom na strefy?
    Tak że np. wszystkie kable, czujniki itd z salonu zejda sie w jakiejs skrzynce w okolicach salonu - tam bedzie podpiety sterownik arduino i on dopiero podzie skrętka do serwerowni do RPI badz serwera.

    Jak wyszlo to u Ciebie?

    OdpowiedzUsuń
  4. ja zrobiłem jeden punkt zbiorczy, ale jest tych kabli dużo i czasami ciężko w nich cokolwiek zrobić. Ja zrobiłem szafę typu rack w garażu. Tam mam wszystko. Kable do sterowników, ale też kable do oświetlenia schodów, do instalacji ethernet. Jak się tak głębiej zastanowić, można by zrobić kilka stref, ale wtedy będziesz musiał chyba na każdą strefę zrobić osobne arduino. Ma to swoje wady, ale też zalety. Na takie pytanie musisz sobie sam odpowiedzieć. Wszystko zależy od indywidualnych potrzeb.

    OdpowiedzUsuń
  5. A myslales moze o jakims switchu ktory przelaczalby instalacje miedzy standardowa a inteligenta?
    Zeby w razie awari arduino przepiac sie na zwykla instalacje

    OdpowiedzUsuń
  6. I jakie srodki ostroznosci zastosowales podczas pracy z ethernet shieldem?:)
    W moim juz prawie wszystkie piny chyba sie spalily bo pokazuja tylko stan HIGH i nie da sie go zmienic na LOW

    OdpowiedzUsuń
  7. Jeśli chodzi o switch, to nie mam pomysłu jak można w prosty sposób przełączyć się pomiędzy instalacją. Mam przełączniki dzwonkowe, więc w grę wchodzi chyba tylko wymiana przełączników na zwykłe.

    Jeśli chodzi o środki ostrożności, to nie zdarzyło mi się żeby jakikolwiek pin się przepalił, więc tak na prawdę nie mam żadnych specjalnych

    OdpowiedzUsuń
  8. Kurcze nie wiem czemu ale u mnie sie mqtt nie sprawdza - caly czas traci polaczenie i raz nawiaze szybko, raz dlugo raz wcale - nie bardzo wiem w czym jest problem :/

    Apropo szybkiego przelaczania - w przypadku gniazdek sciennych ciezko chyba ale w przypadku kontaktów mysle ze mozna zrobic swicz ktory bedzie przelaczal na standardowa instalacje

    OdpowiedzUsuń
  9. kiedy mqtt wysyla z openhab wiadomosc - arduino dobrze dziala - gorzej jezeli w momencie nacisniecia przycisku - mqtt traci polaczenie i roznie potem bywa

    OdpowiedzUsuń
  10. problem podobny do tego goscia - tak jakby digital read wieszal ardiuno - bo nawet ping wtedy nie odpowiada i musze restartowac sterownik
    https://github.com/knolleary/pubsubclient/issues/18

    OdpowiedzUsuń
  11. a masz weryfikację czy jest połączenie? 48-ma linia na listingu. u mnie takie były objawy bez tego sprawdzania. Po dodaniu tego problem zniknął.

    OdpowiedzUsuń
  12. Tak sprawdzam to - w logach widze:
    Client arduinoClient already connected, closing old connection.
    New client connected from 192.168.1.116 as arduinoClient.
    New connection from 192.168.1.116.

    nie rozumiem dlaczego arduino mysli ze polaczenie jest rozlaczone a logi pokazuja co innego

    OdpowiedzUsuń
    Odpowiedzi
    1. do tego widze bledy typu Socket read error on client arduinoClient, disconnecting.

      Usuń
  13. mniej wiecej tak wyglada moj log z arduino:
    Initialize Ethernet...
    Initialize MQTT connection... OK
    Setting halogen state to OFF...
    Mqtt callback: halogen#0
    Changing state to ON
    MQTT has been lost - reconnecting... OK
    Mqtt callback: halogen#0
    Changing state to OFF
    MQTT has been lost - reconnecting... OK
    Mqtt callback: halogen#0
    Changing state to ON
    MQTT has been lost - reconnecting...

    - i tak caly czas - gdzie bardzo czesto sie nie polaczy spowrotem i albo dostane failed albo musze restartowac sterownik

    OdpowiedzUsuń
    Odpowiedzi
    1. mowa o sterowaniu przyciskiem - z openhaba to dziala w miare dobrze

      Usuń
  14. Po ciezkich bojach doszedlem co to bylo :) Pomylilem piny INPUT z OUTPUTEM przez co plytka wariowała i sie wieszala :) - info dla potomnych :)

    PS. dzieki za bardzo uzytecznego bloga - postaram sie tez dzielic tutaj informacjami i pomyslami :)
    pozdro

    OdpowiedzUsuń
  15. Powiedz czy implementowales jakies sciemniacze swiatla
    ?

    OdpowiedzUsuń
  16. nie, nie robiłem niczego takiego

    OdpowiedzUsuń
  17. Zastanawia mnie czy nie prościej podłączyć arduino przez USB lub rs232
    Wydaje mi się że skoro coś ma być bezawaryjne należy raczej skorzystać z pewnych metod komunikacji niż komunikować połaczeniami.
    Proszę zwrócić uwagę że komunikacja mqtt działa w warstwie 7 OSI, natomiast połączenie USB lub co lepsze RS232 jest w warstwie sprzętowej. To takie moje spostrzeżenie..

    OdpowiedzUsuń
  18. Jestem totalnie zielony w arduino, jak dodać obsługę większej liczby urządzeń?

    OdpowiedzUsuń
  19. Witam. Jestem na etapie fundamentów w moim nowym domu i bardzo mi się podoba pomysł wykorzystania arduino do sterowania oświetleniem i nawadnianiem (w moim przypadku). Pytanie moje brzmi: co powinienem dokładnie kupić by sterować 9 przekaźnikami? Na pewno arduino mega z ethernet shieldem, 9 pojedynczych przekaźników do puszek z przełącznikami dzwonkowymi. Nie znam się kompletnie na rapspberry pi a widzę że jest także potrzebne dla sprawnego kpmunikowania sie arduino z open hubem. Prosiłbym o podpowiedź jakie arduino mega i rapsberry pi kupić aby wszystko zadziałało jak należy. Czy do rapsberry potrzebne są dodatkowe shieldy czy też wystarczy sama płytka? Będę wdzięczny za każdą podpowiedź.

    OdpowiedzUsuń
    Odpowiedzi
    1. Ja mam chińską podróbkę Arduino mega z chińskim ethernet shieldem i działa dobrze. Jeśli chodzi o raspberry to praktycznie każde z portem ethernet będzie dobre, ale oczywiście polecam wersję 2'gą ponieważ jest najszybsza.
      Żadnych shieldów do Raspberry nie mam.

      Obecnie planuję pozbyć się zupełnie arduino i zrobić wszystko na raspberry - znalazłem jakąś płytkę rozszerzającą GPIO, ale to mam na razie w planach, jeszcze nie testowałem rozwiązania więc nic więcej nie mogę na razie napisać

      Usuń
    2. Tak więc wstrzymam się z zakupami. Jaki jest powód takowej modyfikacji? Nie jestem obeznany w programowaniu. Chciałem raczej skorzystać z informacji znalezionych w sieci dlatego ten blog jest dla mnie czymś czego szukałem. Mam nadzieję, że do czasu zakończenia mojej budowy doczekam się kolejnych ulepszonych propozycji inteligentnego domu. Czekam na wpisy.

      Usuń
    3. Powodem modyfikacji jest chęć uproszczenia architektury.
      Obecna działa całkiem sprawnie, ale z arduino czasami są problemy po zanikach energii. Ethernet shield czasami ma problemy z uruchomieniem i trzeba ręcznie zresetować arduino. Na szczęście zdarza się to bardzo rzadko. Jak tylko uda mi się coś wymyślić z samym raspberry na pewno stworzę jakiś wpis na blogu

      Usuń
    4. Polecam poczytać o bibliotece leOS 2 do arduino.
      Pozdrawiam

      Usuń
  20. Chciałbym tylko zwrócić uwagę że MQTT na Arduino nie jest praktycznie zabezpieczone przed włamaniem w żaden sposób (oprócz fizycznego zab.).
    A co jeśli przez WIFI będziesz chciał czym sterować
    Moim zdaniem MQTT jest sens stosować tylko w połączeniu z SSL, a tego atmega nie zrobi.

    Pozdrawiam
    Tomasz

    OdpowiedzUsuń
  21. wyskakuje mi taki błąd:
    arduino_mmqt:38: error: 'client' was not declared in this scope

    exit status 1
    'client' was not declared in this scope
    już kończą mi się pomysły

    OdpowiedzUsuń
  22. Witam ja kobinuje z domoticz (json) udalo mi sie cos zmotowac z gotwych szkicow i moge zapalac swiatlo z domoticz ale juz nic nie moge znalesc do wyslania infotmacji o zwarciu do masy wlacznikem chwilowym ktos pomoze ? pozdrawiam

    OdpowiedzUsuń