Jakiś czas temu zacząłem bawić się ze Smart Home. W dalszym ciągu nie jest to jakaś bardzo wyrafinowana automatyka domowa, raczej monitorowanie plus parę akcji ułatwiających życie. Do tego zabawka w stylu udawanego wschodu słońca w celu łagodniejszego wstawania.
Termometry zewnętrzne
Przez długi czas zastanawiałem się nad termometrem zewnętrznym, bo do tej pory informacje o temperaturze zewnętrznej czerpałem z serwisów pogodowych, konkretnie z OpenWeather oraz Airly (razem z jakością powietrza). Różnice między tymi źródłami były dość widoczne, a do tego jeszcze różnica między tymi serwisami a tym, co widziałem na termometrze, trochę mnie irytowała. Przykładowo w tej chwili to jest prawie 2 stopnie...
Już jakiś czas temu nabyłem dongla SDR, ale ponieważ czujka zewnętrzna, którą miałem, nie była rozpoznawana przez rtl_433 - temat chwilowo zaparkowałem. To "chwilowo" trwało kilka miesięcy.
Ostatecznie zebrałem się w sobie i połączyłem czujkę (termometr z Lidla, marka Auriol, symbol HG2132TX) z OpenHab przez rtl_433 i MQTT.
Po pierwsze samo rtl_433 dobrze rozkodowało transmisję, więc dane wejściowe były, należało je tylko zinterpretować. Kilka modeli Auriol było obsługiwanych przez rtl_433, więc pewne wskazówki miałem, na przykład tutaj: auriol_ahfl.c. Co prawda moja czujka nie mierzy wilgotności, ale najbardziej istotną informacją było (de)kodowanie temperatury. A absolutnie kluczowy był ten fragment:
temp_raw = (int16_t)(((b[1] & 0x0f) << 12) | (b[2] << 4)); // uses sign extend
temp_c = (temp_raw >> 4) * 0.1f;
Postanowiłem rozkodowywać przychodzącą informację już w OpenHab skryptem w Jython, ale prototyp tego skryptu napisałem po prostu w Pythonie. Problematyczne są wartości ujemne, właściwy znak jest osiągany przez bit shifty, które są w pierwszej linii. Oczywiście nie można tego wprost przetłumaczyć na Pythona, ale pomocne było ctypes. Sprawdziłem, wszystko działało pięknie, podpiąłem pod OpenHab, a rano...
Rano pojawiły się temperatury typu 400 stopni. Oczywiście w rzeczywistości temperatura była ujemna, wiec coś najwyraźniej nie działało w moim skrypcie. Co bardziej irytujące wszystko prawidłowo się (de)kodowało w Pythonie, ale już w Jythonie nie. Nie pozostało mi więc nic innego jak użyć dirty hack i przy pomocy struct.pack i struct.unpack osiągnąć zamierzony efekt. Po prostu pakuję coś jako unsigned a rozpakowuję jako signed - działa.
Od tego czasu dorobiłem się kolejnego czujnika opisanego jako "(...) SONDA ZEWNĘTRZNA DO STACJI JVD RB657 RB658 (...)". Ten akurat rozpoznał się sam, bez problemu. W efekcie w tej chwili mam dwie czujki pogodowe w dwóch różnych miejscach, a ich wskazania wyglądają w tej chwili wyglądają tak:
- OpenWeather: 3.9
- Airly: 2.6
- Sensor #1: 5.1
- Sensor #2: 3.8
Sensor #1 pokazuje wyższą temperaturę, bo jest umieszczony w zacisznym miejscu zaraz przy budynku. Sensor #2 umieszczony jest w ogródku, więc pokazuje temperaturę powietrza, bez dodatkowego "ogrzewania". Przy tych zakresach temperatur Sensor #2 i OpenWeather pokazują bardzo zbliżone temperatury. Co ciekawe w chwili, gdy robi się mróz i temperatura spada poniżej 0, Sensor #2 zbliża się swymi wskazaniami do Airly.