niedziela, 29 czerwca 2014

OpenHab, arduino, inteligentny dom, sterowanie za pośrednictwem protokołu TCP

Jakiś czas temu obiecałem opisanie sterowania urządzeniami za pośrednictwem Arduino i OpenHab przy pomocy protokołu TCP.
Niestety nie jest to tak bezproblemowe jak mogłoby się wydawać, więc nie zdecydowałem się na wykorzystanie takiego rozwiązania w produkcyjnych warunkach, ale opiszę to co udało mi się ustalić. Być może komuś się przyda.

Zacznijmy zatem od początku.
W pierwszym kroku należy pobrać OpenHab RuntimeCore.
Znajdziemy je pod adresem http://www.openhab.org/downloads.html
Po rozpakowaniu archiwum zip, należy zajrzeć do katalogu configurations.
Konieczne będzie utworzenie tzw. sitemap'y. Jest to struktura głównego menu, w którym możemy grupować sobie urządzenia na przykład wg pomieszczeń w których się znajdują, czyli salon, łazienka, piętro itd. 
W moim przykładzie będę chciał sterować tylko jednym urządzeniem, załóżmy że będzie to taśma led w salonie.
Zatem moja sitemap'a będzie znajdowała się w pliku house.sitemap w podkatalogu sitemaps i będzie zawierała następujące wpisy:

sitemap Dom label="Menu główne"
{
Frame {
Group item=Salon label="Salon" icon="firstfloor"
}

}

Następnie musimy utworzyć plik house.items w podkatalogu items, gdzie określamy kontrolery naszych urządzeń. Dla naszego przypadku testowego będzie on wyglądał następująco:

Znalazł się w nim jeden element typu Switch, który może przyjmować wartości ON oraz OFF.
Następnie jest informacja iż obsługa przełącznika ma być realizowana za pośrednictwem protokołu TCP, oraz konfiguracja wyjściowa (elementy ze znakiem ">") i wejściowa (elementy ze znakiem "<").
Określone zostało również mapowanie komend które zostanie wykorzystane przy zmianie stanu przycisku. Mapowanie znajduje się w pliku salonled.map. Pliki mapowań umieszczamy w podkatalogu transform. Plik salonled.map w moim przypadku wygląda następująco:

ON=salonled#
OFF=salonled#

Oznacza to że zarówno przy komendzie "ON" (włączenie przełącznika), jak i przy komencie "OFF" (wyłączenie przełącznika) na adres 192.168.0.5:8888 (adres IP arduino) zostanie wysłany ciąg znaków "salonled#".

W ten sposób załatwione mamy sterowanie taśmą LED po stronie OpenHab. Co jednak w przypadku gdy stan oświetlenia zostanie zmieniony bez udziału OpenHab? Na przykład za pomocą przełącznika na ścianie? Konieczne jest aby informacja o zmianie stanu dotarła do OpenHab, aby mógł on wyświetlić użytkownikowi który może znajdować się daleko od domu aktualny stan oświetlenia.
Do tego wykorzystałem komunikację zwrotną, czyli OpenHab również będzie nasłuchiwał na wybranym porcie, a Arduino przy każdej zmianie stanu oświetlenia będzie wysyłało informację na podany numer IP.
W pliku house.items widać że mapowanie w konfiguracji wejściowej OpenHab zrobione jest za pośrednictwem JavaScriptu. Jest to spowodowane problemami na które w międzyczasie się natknąłem.
Założyłem że w przypadku załączenia oświetlenia Arduino wyśle komunikat salonled#1 a w przypadku wyłączenia salonled#0. Pomimo tego że obsłużyłem takie komendy w mapowaniu OpenHab konfiguracja nie działała poprawnie. Dopiero po analizie kodu źródłowego OpenHab'a i podłączeniu JavaScriptu który umożliwił wyświetlenie w log'u komunikatów które docierają do OpenHab okazało się że treść polecenia jest dużo dłuższa i uzupełniona pustymi znakami. Prawdopodobnie przesyłany był pełny bufor TCP - nie badałem tego tematu dokładniej.
Rozwiązaniem okazało się trim'owanie komunikatu i ręczne obsłużenie mapowania na odpowiedni stan przycisku. Udało się to osiągnąć następującym skryptem JS (OpenHab wspiera skrypty RHINO), który umieściłem w pliku salonled.js w podkatalogu transform:


Należy jeszcze włączyć obsługę TCP w OpenHab.
W tym celu należy pobrać dodatkowe plugin'y (OpenHab AddOns), a następnie plik org.openhab.binding.tcp-1.4.0.jar (lub inna wersja) skopiować do katalogu addons z serwera OpenHab.
W pliku configurations/openhab_default.cfg należy odkomentować linię

tcp:port=25001

Dzięki temu OpenHab będzie nasłuchiwał na porcie 25001
Teraz można uruchomić OpenHab skryptem startup.sh (lub startup.bat w przypadku Windows) upewniając się wcześniej że mamy zainstalowaną odpowiednią wersję javy.
Po chwili pod adresem;

http://localhost:8080/openhab.app?sitemap=house

dostępne powinno być menu główne naszej konfiguracji.

To już cała konfiguracja po stronie OpenHab. Pozostaje kod źródłowy po stronie Arduino.

Odsyłam tutaj do wpisu http://technika-laika.blogspot.com/2014/04/arduino-sterowanie-przekaznikiem-za.html gdzie jest pierwotna wersja kodu źródłowego, dokładniejszy opis i wyjaśnienie nazewnictwa plików.
Jedyne zmiany które się pojawiają to zmiany komunikacji zwrotnej w pliku network.ino:

oraz dodanie wysłania komunikatu zwrotnego w pliku salon_led.ino: Działanie całej kongfiguracji można zobaczyć na poniższym filmie:



 Generalnie zamierzony cel został osiągnięty, natomiast problemy na które się natknąłem, konieczność zrywania połączenia po obsłudze komunikatu, opóźnienia przy wznawianiu połączenia przez OpenHab powodują że nie polecam takiego rozwiązania w warunkach produkcyjnych. Być może ktoś z Was poradził sobie z tymi problemami. Jeśli tak, proszę o informację w komentarzach. Dużo ciekawiej zapowiada się komunikacja za pomocą mqtt którą postaram się zademonstrować w kolejnym wpisie.

Brak komentarzy:

Prześlij komentarz