HubScreen – nowe funkcje i optymalizacja działania

Wstęp

Z racji, że ekran z projektu HubScreen posiadał dużo potencjału, który marnował się niewykorzystany, postanowiłem znaleźć dodatkowe zastosowania. Zostały one przedstawione poniżej.

Uniwersalna bramka ZigBee

Żeby znaleźć jakieś nowe zastosowanie dla działającego przez 24h/dobę Raspberry postanowiłem zbudować sobie uniwersalną bramkę ZigBee w oparciu o układ CC2531 i oprogramowanie Zigbee2Mqtt.

Wszystko zaczęło się od potrzeby posiadania termometru na balkonie, ale jak wiemy mamy XXI wiek, więc to nie mógł być taki zwykły termometr 😉 W tym celu zakupiłem układ sniffera ZigBee CC2531 na Aliexpress za ok. 15 zł i czujnik Xiaomi Aqara WSDCGQ11LM za 67 zł.

Układ CC2531 normalnie jest wykorzystywany jako sniffer ZigBee (przetestowany na sterownikach wykorzystywanych w pracy 😉 ), ale po zmianie firmware według tej instrukcji staje się uniwersalną bramką ZigBee. Problemem podczas prób uruchomienia Zigbee2Mqtt był fakt, że usługa chciała wystartować dopiero po zainstalowaniu Node.js w wersji 11.15.0.

Do wymiany firmware chciałem wykorzystać płytkę Raspberry Pi 4B, ale niestety przy próbie odczytania wersji firmware z układu CC2531 otrzymywałem odpowiedź ID = 0000 lub ID = ffff. Niedawno czytałem, że podobno ma pomagać aktualizacja biblioteki wiringPi, ale w moim przypadku z problemem sobie poradziłem poprzez zmianę płytki na Raspberry Pi 3B (RPi 3B).

Ze względu na wcześniejsze pomiary obciążenia Raspberry Pi Zero (RPi Zero) postanowiłem wymienić je na wspomniane przed chwilą Raspberry Pi 3B, które dzięki zwiększonej wydajności miało poradzić sobie z obsługą projektu HubScreen i nowym zadaniem bycia bramką ZigBee. Na początku nie wyglądało, żeby miały występować jakieś problemy, ale po kilku dniach pracy okazało się, że nie jest tak kolorowo:

  • procesor RPi osiągał temperaturę minimum 60°C niezależnie od obciążenia (aż radiator zaczął spływać z procesora; próbowałem nawet obniżać częstotliwość, ale niczego to nie zmieniało),
  • pobór energii zwiększył się 10-krotnie w porównaniu do tego co było przy RPi Zero.

Problemy wynikały zapewne z moich studenckich czasów, gdzie RPi 3B nie miało zbyt łatwego życia. Dlatego musiałem wrócić do RPi Zero i opracować rozwiązanie dla zbyt małej mocy obliczeniowej – a o nim już poniżej.

Zdalny pulpit

Z racji uruchomienia w ostatnim czasie domowego serwera najlepszym sposobem zmniejszenia obciążenia byłoby przeniesienie zadań wymagających dużej mocy obliczeniowej na platformę bardziej do nich przystosowaną.

I taką „platformą” został domowy serwer z systemem Windows Server 2019. Różnicę w obciążeniu widać na poniższym zrzucie ekranu (trzeba pamiętać, że RPi Zero obsługuje teraz dodatkowe zadanie pod postacią bramki ZigBee).

Obciążenie Raspberry Pi Zero przy nowym podejściu

Do obsługi projektu utworzyłem nowego użytkownika, który podczas logowania otwiera przeglądarkę internetową ze stroną hostowaną na RPi Zero. Dzięki temu, gdy RPi ma awarię albo po prostu jest wyłączone, nie jest zużywany transfer danych potrzebny do ciągłego odświeżania informacji wyświetlanych na Ekranie.

Zdalny pulpit uruchamiam w systemie Linux dzięki aplikacji Remmina (dobrze mi się tego używało za czasów zabawy z Ubuntu). Skrypt uruchamiający aplikację jest uruchamiany automatycznie przy starcie RPi Zero. Dzięki temu z punktu widzenia użytkownika działanie jest dokładnie takie samo jak w przypadku wcześniejszego rozwiązania, ale za to widać znaczną różnicę w szybkości działania (chociażby po cyfrowym zegarze z sekundnikiem generowanym przez skrypt JavaScript).

Dodatkowo wykorzystałem Harmonogram zadań systemu Windows w celu wyłączania procesu przeglądarki w nocy i ponownego uruchamiania rano (kolejny sposób na oszczędność transferu).

Klasyczne problemy z Windowsem

Niestety wiele dni pracy Ekranu ze zdalnym pulpitem doprowadziło do obserwacji, że po kilku godzinach okno przeglądarki internetowej traci focus i nie mogę zmieniać kart przeglądarki za pomocą skrótu klawiaturowego Alt + Tab bez dodatkowego kliknięcia na któryś element strony internetowej. Czasami Remmina się po prostu wyłączała bez podania żadnego powodu.

Przyczyną było tracenie połączenia sesji RDP lub występowanie dużych opóźnień w połączeniu pomiędzy RPi Zero a serwerem. Problem postanowiłem rozwiązać na kilku płaszczyznach:

  • poprzez przywracanie focus’a przy logowaniu do konta użytkownika (np. gdy Remmina rozłączała się ze zdalnym pulpitem i przy ponownym łączeniu kolejny raz logowała do konta Windows’a):
Do przywrócenia focus’a wykorzystuję skrypt sendKeys, a jego uruchomienia dokonuję z wygodnego graficznego narzędzia Task Scheduler (Harmonogram zadań), które pozwala reagować na zdarzenie, którym jest zalogowanie do systemowego konta
  • poprzez automatyczne zabijanie i ponowne uruchamianie aplikacji Remmina w przypadku problemów z działaniem – w tym celu wykorzystałem program supervise (wchodzący w skład pakietu daemontools), który nadzoruje pracę uruchamianych przez niego procesów. Nie mogłem skorzystać z narzędzia systemctl w Debianie ze względu na uruchamianie zdalnego pulpitu w warstwie graficznej do której to narzędzie nie sięga.
  • poprzez usprawnienie domowej sieci komputerowej:

Ekran projektu HubScreen i router znajdują się w dwóch skrajnych miejscach mieszkania, a samo Raspberry ma antenę na płycie PCB, więc taki układ nie może sprawnie działać. W tym celu postanowiłem dokonać odpowiednich pomiarów, aby dowiedzieć się jaki ma to wpływ na opóźnienia oraz samą dostępność Raspberry w mojej sieci komputerowej. W tym celu pewnego sobotniego dnia postanowiłem zainstalować serwer Zabbix’a na moim Windows Serwerze (uroki posiadania komputera włączonego 24h/dobę oraz Docker’a, który pozwala na błyskawiczne uruchomienie dowolnego oprogramowania) i odpowiedniego agenta na RPi. Następnie przystąpiłem do pomiarów (a właściwie to Zabbix):

Opóźnienie (ping) pomiędzy serwerem a Ekranem
Dostępność Ekranu w sieci

Pomiary były dokonywane co 10 sekund, aby dało się także normalnie korzystać z domowej sieci.

Na powyższych wykresach dotyczących kilku dni pomiarów możemy odczytać następujące wartości:

  • Średnie opóźnienie (ping): 20,32 ms
  • Maksymalne opóźnienie (ping): 523,5 ms
  • Średnia dostępność Ekranu w sieci: 98,2 %

Trzeba było to w jakiś sposób usprawnić (szczególnie ten wykres dostępności). Pierwszy pomysł na jaki wpadłem to zastosowanie repeatera WiFi. Niestety klasyczny podłączany do zwykłego gniazdka w ścianie nie wchodził w grę ze względu na niekorzystne ułożenie gniazdek w mieszkaniu. Dlatego wpadłem na genialny pomysł: repeater pod sufitem jako LED’owa żarówka! W salonie akurat znajduje się kinket z idealnym widokiem na router znajdujący się na drugim końcu mieszkania. Niestety takie inteligentne żarówki wymagają zasilania 24h/dobę, więc musiałbym wymienić co najmniej dwie. I tutaj znalazłem idealny zestaw: żarówka z repeaterem WiFi i żarówka z głośnikiem bluetooth JBL’a. No idealny zestaw do mojego budowanego inteligentnego mieszkania. Na szczęście tuż przed kliknięciem przycisku „Kup” postanowiłem zasięgnąć rady ludzi z Reddita. Tam uświadomiono mnie o jeszcze jednej ważnej rzeczy: może zasięg WiFi się zwiększy, ale to wszystko kosztem opóźnień. Zasugerowano mi zbudowanie sobie sieci PLC (PowerLine Communication), która pozwala na komunikację poprzez przewody elektryczne. I to był strzał w dziesiątkę. Na Allegro za 255 zł udało mi się kupić zestaw do takiego zastosowania z routerem WiFi. Dzięki PLC opóźnienia w sieci z jednego końca mieszkania do drugiego są naprawdę minimalne, mogę sobie w końcu swobodnie korzystać z Internetu na balkonie i dodatkowo mogę grać w gry na telewizorze transmitując obraz z domowego komputera poprzez sieć (opóźnienia są naprawdę bardzo niskie).

Nowy układ sieci przedstawiłem poniżej:

A tutaj pomiary dla nowej konfiguracji:

Opóźnienie (ping) pomiędzy serwerem a Ekranem po dodaniu nowego Access Point’a
Dostępność Ekranu w sieci po dodaniu nowego Access Point’a

Na powyższych wykresach dotyczących kilku dni pomiarów po dodaniu nowego Access Point’a możemy odczytać następujące wartości:

  • Średnie opóźnienie (ping): 12,29 ms
  • Maksymalne opóźnienie (ping): 366,4 ms
  • Średnia dostępność Ekranu w sieci: 99,98 %

Teraz poziom dostępności jest na znacznie lepszym poziomie co można odczuć podczas codziennego korzystania z Ekranu 😉

Domoticz

Z racji, że w domu zaczęły pojawiać się pierwsze czujniki ZigBee to trzeba było gdzieś przechować generowane pomiary. I tak, kierując się poradami oraz doświadczeniami z pracy, poszedłem w kierunku systemu Domoticz.

Całkiem przyjemny system. Prosta konfiguracja. Szybkie działanie. Interfejs aplikacji w postaci strony WWW. Bez problemu udało się połączyć z Zigbee2MQTT. Na dodatek Domoticz posiada REST API, które pozwoliło mi na podłączenie czujnika DHT-11 czy czujnika ruchu odczytywanego przez RPi. Napisałem również aplikację, która na podstawie pingowania przez Bluetooth smartphone’ów decyduje czy w domu jest któryś z mieszkańców i modyfikuje zachowanie HubScreen’a, a historię statusów archiwizuje w bazie danych Domoticza. Dodatkowo udało się połączyć Domoticza z systemem Casambi (za pomocą autorskiej aplikacji Casambi2Domoticz napisanej w .NET Core) co pozwoliło na prezentację danych z czujnika powietrza Casambi.

Ale nie ma róży bez kolców. Jeśli chodzi o wady to Domoticz robi wrażenie przestarzałej aplikacji. Niedobór ciekawych pluginów, mało wodotrysków w interfejsie, brak prostej zmiany motywu itd. Potrzebowałem czegoś więcej.

Ostatnio ze względu na projekt prowadzony w pracy pojawiły się u mnie nowe doświadczenia z alternatywą dla Domoticza czyli Home Assistant’em, więc powoli przygotowuję się psychicznie na przeprowadzkę do nowego systemu „Inteligentnego mieszkania” 😉

Podsumowanie

Przedstawiona powyżej konfiguracja nie przetrwała próby czasu… Ale o tym w innym wpisie 😉 Najważniejsze, że to co wtedy się nauczyłem to moje 🙂

PLCino – opis projektu

Skąd pomysł na projekt?

Od czasów szkoły średniej uwielbiałem programować sterowniki PLC. Powodem takiego stanu rzeczy był fakt, że chodziłem do technikum mechatronicznego i intensywnie pracowaliśmy na sterownikach PLC ze względu na nadchodzący egzamin zawodowy. Również kadra nauczycielska, która posiadała wykształcenie elektryczne, potrafiła posługiwać się głównie tylko graficznymi językami programowania, czyli np. językiem drabinkowym.

Na moich studiach dodatkowo wkręciłem się w „konwencjonalne” programowanie, czyli języki C/C++. Dlatego, gdy przyszedł czas wyboru tematu pracy inżynierskiej, po wcześniejszym pobieżnym research’u w wyniki którego nie znalazłem podobnego rozwiązania, postanowiłem opracować aplikację dla układów Arduino pozwalającą na programowanie w języku drabinkowym.

O aplikacji

Zadaniem aplikacji jest umożliwienie programowania układów Arduino (Leonardo, Nano, Mega) w języku drabinkowym, który stosowany jest głównie przy programowaniu sterowników PLC. PLCino do działania wymaga uprawnień administratora, ponieważ umożliwia kompilowanie kodu i programowanie układów Arduino z poziomu edytora.

Zaimplementowane elementy języka drabinkowego to:

  • styki,
  • cewki,
  • liczniki,
  • timery,
  • operatory porównania.

Aplikacja została opracowana z wykorzystaniem bibliotek Qt w wersji 5.9.1. Przy próbach kompilacji za pomocą nowszych wersji występowały wyjątki przy korzystaniu z funkcji dostarczanych przez biblioteki.

Wadą aplikacji było opracowywanie jej w czasach, gdy prowadzący nie widzieli problemów z nazewnictwem zmiennych czy funkcji w języku polskim (do dzisiaj te długie nazwy kłują mnie po oczach).

Innym problemem była biblioteka Qt. Wtedy wydawało mi się, że jest to coś idealnego dla języka C++, ponieważ pozwalała wykorzystać wspomniany język w operacjach niskopoziomowych jak i wysokopoziomowych (czyli w tym przypadku dobrze wyglądającym GUI – nie to co Windows Forms). Wartością dodaną miała być wieloplatformowość pozwalająca na proste przeniesienie aplikacji PLCino na systemy linux. Niestety ze względu na wykorzystanie aplikacji avrdude nie było to możliwe – gdy chciałem rozbudowywać mój projekt okazało się, że Qt staje się coraz mniej open source i przez to nieznana była przyszłość tych bibliotek, więc postanowiłem wstrzymać się z dalszymi pracami i poczekać, aż sytuacja się wyjaśni.

Aplikacja w obecnej postaci pozwala na programowanie układów Arduino (bezpośrednio z poziomu edytora):

  • Leonardo,
  • Nano,
  • Mega.

TODO

  • Dodanie obsługi kolejnych układów Arduino
  • Dodanie obsługi kolejnych elementów języka drabinkowego
  • Oczyszczenie aplikacji avrdude ze zbędnych bibliotek i kodów źródłowych

Jak używać aplikacji?

Na moim GitHub’ie można znaleźć instalator aplikacji, który jak zawsze został opracowany za pomocą kreatora Inno Setup. Instaluje w systemie operacyjnym aplikację PLCino wraz z niezbędnymi bibliotekami. W przypadku problemów z działaniem należy uruchomić aplikację z uprawnieniami administracyjnymi.

W katalogu „przyklady” (znajdującym się w tym samym katalogu co plik wykonywalny PLCino.exe) można znaleźć przykładowe programy, które prezentują funkcjonalność aplikacji.

Do obwodów tworzonych w aplikacji elementy drabinki dodaje się poprzez wykorzystanie techniki przeciągnij&upuść (drag&drop). Edycji właściwości elementu można dokonać poprzez dwukrotne kliknięcie LPM (lewym przyciskiem myszy) na elemencie w wybranym obwodzie.

Zrzuty ekranu

Kody źródłowe

Kody źródłowe

Aplikacja

Aplikacja