Virtuino IoT może pracować z dwoma protokołami komunikacji - Websockets i MQTT. Ja wybrałem Websockets gdyż zdecydowana większość komunikacji mojej automatyki zamyka się w obrębie lokalnej sieci WiFi.
Protokół ten to mocno zmodyfikowany i uproszczony HTTP nie wymagający potwierdzeń w przesyłaniu informacji co znacznie zmniejsza ruch sieciowy. Ale wymaga wcześniejszego zestawienia i utrzymania połączenia pomiędzy klientem a serwerem. Połączenie nawiązuje klient co skutkuje ustawieniem "sztywnego" łącza między aplikacją a modułem. Od tego momentu zarówno klient jak i serwer mogą wysyłać nawzajem informacje wiedząc, że po drugiej stronie jest gotowy do ich odbioru obiekt. Sztywne łącze może być zlikwidowane przez każdą ze stron specjalną komendą lub znika gdy któraś ze stron przestanie odpowiadać na przesyłane ramki kontrolne wewnętrznym mechanizmem Websockets zwanym ping-pong.
Każda ze stron może wysłać ramkę ping oczekując w określonym czasie odpowiedzi ramką pong. Po zadanej ilości nieodebranych ramek nadawca ping ustawia status odbiorcy jako rozłączony. Mechanizm ten na pewno działa od aplikacji do modułu co widać po kolorze kropek u góry okna Virtuino.
Jak jest w serwerze? nie udał się mi ustalić choć kod mechanizmu ping-pong jest obecny w bibliotece Websockets. Efekt jest taki, iż utrata łączności pomiędzy klientem a serwerem z powodu np. zaniku sieci WiFi nie skutkuje w serwerze ustawieniem statusu klienta jako rozłączony. Po wznowieniu dostępu do sieci obu urządzeń często zdarza się, że nie następuje ponowne zestawienie sztywnego łącza pomiędzy modułem a aplikacją. Przywrócenie komunikacji następuje albo po restarcie aplikacji albo modułu.
Dużo łatwiej jest zmusić moduł ESP do restartu po stwierdzeniu braku komunikacji z aplikacją Virtuino. W tym celu zaimplementowałem własny mechanizm ping-pong od strony serwera.
Serwer co kilka sekund wysyła zmianę stanu wybranego pinu do Virtuino a w odpowiedzi aplikacja wysyła zmianę stanu innego pinu do modułu. Brak kilku ramek pong od aplikacji jest sygnałem do restartu modułu. W praktyce okazało się, że zamiast restartu całego modułu wystarczy restart samego protokołu Websocket.
Poniżej kod wysyłający cyklicznie zmiany stanu pinu V0 do aplikacji, sprawdzający stan licznika nieodebranych ramek pong i restartujący protokół Websocket.
int wsk_led = 0;
int pongcounter = 10;
void led_app_timer() // esp -----> app every 3000 ms
{
wsk_led = !wsk_led;
sendValue(pin0, String(wsk_led)); //esp ----> app
pongcounter = pongcounter - 1;
Serial.print("pongcounter ");
Serial.println(pongcounter);
if (pongcounter < 1) {
webSocket.close();
webSocket.begin();
Serial.println("webSocet restart");
pongcounter = 10;
}
}
W aplikacji ustawiłem skrypty zamieniające zmiany stanu na pinie V0 na zmiany stanu pinu V6 wysyłanego do modułu ESP.
I ostatni element układanki ping-pong - procedura odbioru ramki pong z aplikacji i ustawianie na max licznika nieodebranych potwierdzeń gdy ramka pong zostanie odebrana. I przy okazji zmieniam stan wewnętrznego LED układu ESP8266 dla szybkiej kontroli poprawności komunikacji od strony serwera.
void pin6_rec(String value)
{
int v = value.toInt();
if (v == 1) digitalWrite(led_wew, HIGH); else digitalWrite(led_wew, LOW);
pongcounter = 10;
}
Problem, który opisałem, ujawnił się z momentem postawienia na stałe aplikacji Virtuino jako domowego centrum zarządzania automatyką. Wcześniej, gdy aplikację uruchamiałem sporadycznie problem nie nie mógł być zauważony gdyż aplikacja wznawia sztywne połączenie z serwerem (z serwerami) zaraz po uruchomieniu.
Jak na razie wszystko działa Ok z czego mniej się cieszy nasz ulubiony ciąg dalszy
Brak komentarzy:
Prześlij komentarz