Tym razem chciałem pokazać jak można w praktyczny sposób użyć biblioteki, którą opisałem w poprzednim poście.
Klient w konsoli
Zastanawiałem się jaka forma klienta byłaby najlepsza. Napisałem więc prostego klienta konsolowego w Javie. Jar odpalany z konsoli ma tą jedną podstawową zaletę, że można go łatwo łączyć z innymi komendami i narzędziami. W ten prosty sposób otrzymałem bardzo uniwersalne API. Nie trzeba zmieniać klienta, żeby go zintegrować z niemal wszystkim. Wydaje mi się, że takie podejście załatwi 80% przypadków. Pozostałe 20% prawdopodobnie będzie potrzebowało dedykowanego rozwiązania dlatego kod został udostępniony na Githubie i każdy kto ma trochę wolnego czasu może wysłać pull request lub zgłosić błąd. Będę się starał rozwijać klienta w miarę wolnego czasu i możliwości. Będę się starał nie łamać kompatybilności wstecznej z istniejącym rozwiązaniem, oraz liczę że Grenton również nie zmieni API.
Kod klienta i biblioteki szyfrującej jest dostępny pod adresem: https://github.com/Domktorymysli/grenton-simple-client.
Komunikacja
Komunikacja Grentona z telefonem wygląda jak bardzo proste RPC, oparte na typach prostych (string, int, boolean). Telefon, w większości przypadków, inicjalizuje połączenie i odpytuje CLU o metody. Jako wynik “procedury” zwracają string. Wygląda na proste rozwiązanie, ale zważywszy na to, że komunikaty muszą być wysyłane i odbierane bardzo szybko, wygląda że się sprawdza. GUI ma zaszyte w swojej konfiguracji nazwy funkcji, które może wywoływać na CLU. Jeszcze nie znalazłem metody na CLU, która by pozwoliła wysłać wiadomość do klienta (telefonu). Bez tego komunikacja może być tylko wywoływana z zewnątrz. Myślę, że znajdę mechanizm, który pozwoli wysyłać powiadomienie do telefony, gdy nastąpi jakieś zdarzenie na CLU.
Bezpieczeństwo
Dla wszystkich, którzy uważają, że Grenton nie jest bezpieczny, bo udało się napisać tego typu narzędzie, chciałem przekazać, że to nie tak. Mam u siebie na biurku CLU, moduły, OMa, sniffer ruchu, mam swobodny dostęp do wszystkich plików konfiguracyjnych oraz kluczy. Pamiętaj, że Twój “inteligenty dom” jest bezpieczny ponieważ to Ty wiesz jakie Twój system ma mocne i słabe strony. Najbezpieczniejszy system będzie bezradny, gdy zostawisz otwarte WiFi lub podłączysz kamery, domofon na zewnątrz domu do tej samej sieci co system automatyki domowej. Proszę jedynie o nie wyciąganie pochopnych wniosków. Świadomość użytkowników, to jeden z celi tego bloga.
Pliki do pobrania
W ramach postu http://domktorymysli.pl/2017/12/grenton-komunikacja-2/ napisałem bibliotekę, która pozwala na komunikację z CLU. Przez ostatni tydzień ją trochę poprawiłem. A teraz chciałem pokazać, co można zrobić używając tego narzędzia.
Narzędzie jest dostępne pod adresem: https://github.com/Domktorymysli/grenton-simple-client.
Aby zbudować klienta, należy ściągnąć stabilne wydanie https://github.com/Domktorymysli/grenton-simple-client/releases, zainstalować Java 1.8 oraz Mavena 3. Oraz wywołać dwie komendy.
mvn clean
mvn install
Po tych zabiegach w katalogu target powinny znajdować się dwa jary. Ciebie interesuje ten: simple-client-1.0-shaded.jar powinien zajmować coś ok 2 MB.
Lub jak Ci się nie chce, gotowy jar do pobrania znajduje się tutaj: http://domktorymysli.pl/files/simple-client-1.0.jar
Pierwszy “projekt”
Na pierwszy projekt przygotowałem proste pobieranie temperatury z CLU. Na prośbę @andre z forum http://forum.lic.pl/grenton/grenton-szczegoly-techniczne/. Jak Ty masz jakiś pomysł na projekt, daj znać na forum, postaram się pomóc.
Znajdź i przygotuj klucze
Otwórz OM wczytaj projekt. W tej chwili OM stworzył tymczasowy plik w którym zapisane są klucze w zdekodowanej formie. Np. u mnie te pliki można znaleźć w:
D:\Grenton\workspace\Test2>dir
Volume in drive D is Nowy
Volume Serial Number is 242C-0526Directory of D:\Grenton\workspace\Test2
04.12.2017 22:03 <DIR> .
04.12.2017 22:03 <DIR> ..
04.12.2017 22:03 209 .project
04.12.2017 22:03 <DIR> interfaces
08.12.2017 00:46 679 properties.xml
04.12.2017 22:03 <DIR> scripts
08.12.2017 00:46 285 724 system.xml
Interesuje nas plik properties.xml oraz jego zawartość. W moim przypadku wygląda on następująco:
<object-stream>
<ProjectProperties id=”1″>
<ipRangeStart>192.168.1.2</ipRangeStart>
<ipRangeEnd>192.168.1.255</ipRangeEnd>
<validateRangeIp>false</validateRangeIp>
<version>6</version>
<projectCipherKey id=”2″>
<keyBytes id=”3″>KY1Ajg+pDBQcP2cHnIFNRQ==</keyBytes>
<ivBytes id=”4″>/gV+nXMOUlBbuc3uhkk/eA==</ivBytes>
</projectCipherKey>
<autoUpdateInterfacesBase>false</autoUpdateInterfacesBase>
<encryptedCLU class=”tree-map” id=”5″>
<entry>
<string>192.168.2.200</string>
<boolean>true</boolean>
</entry>
</encryptedCLU>
<readyToUpdate>false</readyToUpdate>
</ProjectProperties>
</object-stream>
Utwórz folder na testy. W moim przypadku d:\testy i skopiuj tam plik jar ściągnięty z http://domktorymysli.pl/files/simple-client-1.0.jar. Wejdź do konsoli i uruchom narzędzie w ten sposób:
java -jar simple-client-1.0.jar
Powinieneś otrzymać komunikat:
D:\testy>java -jar simple-client-1.0.jar
usage: grentonCli
-c,–config <arg> plik konfiguracyjny. Zobacz przykladowy plik
properties-dist.xml
-f,–function <arg> nazwa funkcji na CLU
-ip,–ip <arg> ip zwrotne
-p,–parameters <arg> parametry funkcji, oddzielone przecinkamiParse error: Missing required options: c, f, ip
To znaczy, że jest ok.
Stwórz plik properties-dist.xml na podstawie tego pliku: https://github.com/Domktorymysli/grenton-simple-client/blob/master/properties-dist.xml oraz pliku z OMa.
Ma on wyglądać tak:
<properties>
<cluKey>KY1Ajg+pDBQcP2cHnIFNRQ==</cluKey>
<cluIv>/gV+nXMOUlBbuc3uhkk/eA==</cluIv>
<cluIp>192.168.2.200</cluIp>
<cluPort>1234</cluPort>
</properties>
Ale w miejscu cluKey, CluIv oraz cluIp mają być Twoje wartości.
Pierwszy test:
Wygląda, że wszystko gotowe aby sprawdzić czy wszystko działa musisz stworzyć nową funkcję w OM.
W ciele tej funkcji napisz:
return “Hello world”
Wyślij skrypt na CLU. Teraz wywołamy tę funkcję. Przejdź do konsoli i wpisz wywołanie:
java -jar simple-client-1.0.jar -c properties-dist.xml -f hello_world -ip 192.168.2.100 -p nil
gdzie parametry:
-c properties-dist.xml to plik z konfiguracją
-f hello_world to nazwa naszej funkcji, która wywołujemy
-ip 192.168.2.100 to IP na które ma wrócić wiadomość – nie wiem czemu Grenton to wysyła w każdym razie jak wpiszesz to cokolwiek to i tak działa (o ile to poprawny adres ip
– p parametry oddzielone od siebie przecinkami. W tym przypadku nil oznacza brak parametrów.
Po uruchomieniu otrzymamy wynik:
D:\testy>java -jar simple-client-1.0.jar -c properties-dist.xml -f hello_world -ip 192.168.2.100 -p nil
Hello world
🙂
Pobieranie temperatury:
To tylko prosty przykład, ale możliwości są nieograniczone. Można pobierać status wyjść, wejść itp. Masa zabawy:
Napisałem taki skrypt (nazwa test):
temperatureSensorOne = DOM->x113247182_ONEW_SENSOR1->Value
temperatureSensorTwo = DOM->x154160907_ONEW_SENSOR1->Valuereturn “{\”t1\”:” .. temperatureSensorOne .. “,\”t2\”:” .. temperatureSensorTwo .. “}”
Gdzie wynik to JSON, tyle że wpisany ręcznie. temperatureSensorOne i temperatureSensorTwo to zmienne do których przypisałem wartości z termometrów.
Wywołanie i wynik:
D:\testy>java -jar simple-client-1.0.jar -c properties-dist.xml -f test -ip 192.168.2.100 -p nil
{“t1″:20.200001,”t2”:20.100000}
Proszę bardzo. Aktualna temperatura dla dwóch termometrów Dallas wpiętych w analog in wynosi 20 stopni w tej chwili. Teraz możesz te dane wrzucić do bazy danych, pliku wysłać gdzieś przez http.
W przypadku błędów:
O dziwo w tym wypadku można sprawdzić co się stało. Np. wywołanie nieistniejącego skryptu zwróci błąd:
D:\testy>java -jar simple-client-1.0.jar -c properties-dist.xml -f hello_world_2 -ip 192.168.2.100 -p nil
LUA ERROR: [string “_fresult = hello_world(nil)”]:1.000000: attempt to call global ‘hello_world_2’ (a nil value)
W końcu coś widać!
Więcej informacji można znaleźć w pliku logów (grenton_cli.log), który klient utworzył w katalogu w którym znajduje się Jar. Zapisywane są tam wszystkie wywołania i czas odpowiedzi z CLU:
Mój plik z logami wygląda tak:
2017-12-09 15:18:46 INFO GrentonCli:47 – Sending command: req:192.168.2.100:00f3aa:hello_world(nil) to 192.168.2.200
2017-12-09 15:18:46 INFO GrentonCli:59 – Clu response: resp:192.168.2.200:0000f3aa:LUA ERROR: [string “_fresult = hello_world(nil)”]:1.000000: attempt to call global ‘hello_world’ (a nil value), in 104ms
2017-12-09 15:19:58 INFO GrentonCli:47 – Sending command: req:192.168.2.100:00562a:hello_world(nil) to 192.168.2.200
2017-12-09 15:19:58 INFO GrentonCli:59 – Clu response: resp:192.168.2.200:0000562a:Hello world, in 87ms
2017-12-09 15:25:23 INFO GrentonCli:47 – Sending command: req:192.168.2.100:004179:test(nil) to 192.168.2.200
2017-12-09 15:25:23 INFO GrentonCli:59 – Clu response: resp:192.168.2.200:00004179:{“t1″:20.200001,”t2”:20.100000}, in 95ms
Gdy wystąpią jakieś większe błędy wrzuć na forum ten plik to będę w stanie pomóc.
Co dalej?
To już zależy od Ciebie. Obejrzyj pliki, które generuje gui. Można tam znaleźć trochę przykładowych komend.