Odczyt temperatur z systemu Bero przez API

Zainstalowałem ostatnio w domu system sterowania ogrzewaniem Bero. Opisując go, obiecałem, że przedstawię integrację z innymi systemami, w tym z moim systemem automatyki domowej. Jednym z elementów mojego inteligentnego domu jest zbieranie informacji o temperaturach. Rejestruję je w wielu miejscach, o czym kilkukrotnie pisałem, ostatnio przy okazji opisu termometru z wifi. Bero, z racji swojego przeznaczenia, także bada temperatury i wilgotność. Ponieważ w zestawie są bezprzewodowe czujniki, które łatwo zainstalować gdziekolwiek, więc przydadzą mi się informacje przez nie zbierane.

Czujnik BT1 Bero

Zajmiemy się więc dzisiaj odczytami informacji przez API systemu Bero. Miejscem, które obsługuje zapytania jest centralka sterująca ogrzewaniem. Nie ma więc potrzeby wykonywania połączeń na zewnątrz, wystarczą odwołania przez protokół http w sieci lokalnej. Przy okazji przetestujemy działanie głowic i utrzymywanie zadanej temperatury przez system Bero.

Potrzebne dane

Na początek należy się zastanowić, co będziemy chcieli odczytać. Zgodnie z architekturą systemu Bero, obiektem nadrzędnym dla czujników i głowic jest pokój – to do niego przypisane są głowice i czujnik temperatury i wilgotności. Z poziomu pokoju możemy odczytać m.in. temperaturę zadaną i ona będzie nas interesować. Ponieważ w pokoju mam czujnik temperatury i wilgotności, to jego odczyty będą mnie najbardziej interesować i to właśnie je chcę włączyć do moich obecnych danych i wykresów. Poza czujnikiem, w pokoju jest też głowica termostatyczna, wyposażona w termometr. Możliwe jest także zbadanie, w jakim stopniu urządzenie jest otwarte – im bardziej otwarta głowica, tym więcej wody przepuszcza i tym bardziej grzeje grzejnik.

Będziemy musieli więc pobrać kilka rejestrów z centralki, bo w nich znajdują się wszelkie informacje wysłane przez urządzenia bezprzewodowe, wraz z czasem ostatniej komunikacji. Oczywiste jest, że dla oszczędności baterii, komunikacja nie jest nieprzerwana, ale następuje cyklicznie. Należy wziąć pod uwagę tę specyfikę i przygotować się na to, że dane nie będą zawsze w pełni aktualne. Oczywiście nie przeszkadza to w gromadzeniu danych niezależnie od cykli komunikacji bezprzewodowej. Nie wnikając na tym etapie w działanie API, przyjmijmy, że będziemy potrzebować wartości rejestrów:
temp dla pokoju (wartość zadana temperatury)
temp dla czujnika (aktualna temperatura)
rh dla czujnika (aktualna wilgotność)
vtemp dla głowicy (aktualna temperatura)
vpos dla głowicy (aktualna pozycja)
vpos_min i vpos_range (dla określenia w jakim przedzialne porusza się trzpień głowicy)

Komunikacja z centralką ogrzewania przez API

Logowanie do centralki możliwe jest przez protokół http. Wykorzystywana jest autoryzacja typu Basic. Oznacza to, że gdy łączymy się przez przeglądarkę, pojawia się okienko z miejscem do wpisania nazwy użytkownika i hasła. Analogicznie wygląda komunikacja z API, także trzeba się zautoryzować metodą Basic. Użytkowników jest trzech standardowych – root, admin i user, a różnią się poziomem praw dostępu. Do odczytu danych wystarczy user.

Skąd wziąć dane do logowania? Na budowie centralki znajduje się informacja, że standardowymi danymi do logowania są root, root i są one aktualne po zresetowaniu ustawień centralki. Jednak przy parowaniu z kontem w serwisie myBero.com, hasła są zmieniane na losowe, ze względów bezpieczeństwa (można przywrócić domyślne trzymając przycisk resetowania przez 5 sekund). Na szczęście możemy je odzyskać (przydałaby się jeszcze możliwość zmiany). Są one dostępne po zalogowaniu w serwisie myBero, w zakładce Ustawienia. Dane są podane w formie zakodowanej przez base64, ze znakami specjalnymi zakodowanymi dodatkowo jak w adresach URL. Żeby więc otrzymać login i hasło, należy skopiować podany ciąg znaków i np. przepuścić go najpierw przez funkcję php urldecode, a potem przez base64_decode (lub skorzystać choćby z jakiegoś serwisu dekodującego). Nazwa użytkownika i hasło będą rozdzielone dwukropkiem.

Znając dane autoryzacyjne, możemy wywoływać funkcje API, choćby z pomocą przeglądarki. Pierwszy test można zrobić sprawdzając wersję oprogramowania centralki Bero, wpisując adres:

http://adres_ip_centralki/getregister.cgi?device_soft_version

W odpowiedzi dostaniemy dokument XML z iformacją o wersji:

<cmd status="ok">
<device id="0">
<reg vid="0" tid="device_soft_version" v="1.0.19.32"/>
</device>
</cmd>

Istotne jest, że w elemencie reg, z atrybutem tid odpowiadającym nazwie rejestru, o który pytamy, jest podany numer wersji jako wartość atrybutu v. Warto też zwrócić uwagę, na atrybut vid (wirtualny identyfikator obiektu), który w tym wypadku jest 0, bo taki jest zawsze identyfikator centralki. W zapytaniu moglibyśmy jawnie podać, że chodzi nam o rejestr urządzenia nr 0:

http://adres_ip_centralki/getregister.cgi?0@device_soft_version

Wynik zapytania będzie taki sam. Jakie są identyfikatory naszych urządzeń? Centralka, to jak już wiemy 0. Czujniki numerowane są od 1, a głowice od 21. Pierwszy pokój ma zaś numer 100. Nie wchodząc na razie w odnajdowanie powiązań, ponieważ interesuje nas pierwszy pokój (100), pierwszy czujnik (1) i pierwsza dodana głowica (21), przyjmiemy, że o takie vid będziemy pytać. Upewnimy się sprawdzając nazwę przypisaną do pokoju, przechowywaną w rejestrze name:

http://adres_ip_centralki/getregister.cgi?100@name
<cmd status="ok">
<device id="0">
<reg vid="100" tid="name" v="sypialnia"/>
</device>
</cmd>

Wszystko się zgadza. Zobaczmy jeszcze jak odczytać dwa rejestry jednocześnie – nazwę i temperaturę zadaną dla pomieszczenia.

http://adres_ip_centralki/getregister.cgi?100@name&100@temp
<cmd status="ok">
<device id="0">
<reg vid="100" tid="name" v="sypialnia"/>
<reg vid="100" tid="temp" v="18.50" min="0.00" max="0.00"/>
</device>
</cmd>

Możemy więc zapytać o wszystkie potrzebne dane za jednym razem:

http://adres_ip_centralki/getregister.cgi?1@temp&1@rh&21@vtemp&21@vpos_min&21@vpos_range&21@vpos&100@temp

W odpowiedzi przychodzi komplet danych:

<cmd status="ok">
<device id="0">
<reg vid="1" tid="temp" v="19.32" min="0.00" max="0.00"/>
<reg vid="1" tid="rh" v="50.73" min="0.00" max="0.00"/>
<reg vid="21" tid="vtemp" v="18.40" min="0.00" max="0.00"/>
<reg vid="21" tid="vpos_min" v="10" min="0" max="80"/>
<reg vid="21" tid="vpos_range" v="40" min="2" max="100"/>
<reg vid="21" tid="vpos" v="0" min="0" max="0"/>
<reg vid="100" tid="temp" v="18.50" min="0.00" max="0.00"/>
</device>
</cmd>

Gromadzenie danych

Do przechowywania danych z czujników bardzo dobrym narzędziem jest baza RRD (round robin database). Charakteryzuje się cyklicznym nadpisywaniem starszych danych, według zdefiniowanych okresów, łatwym wyliczaniem wartości średnich oraz prostymi metodami generowania wykresów prezentujących zebrane dane. Wykorzystamy więc projekt RRDtool do przechowywania temperatur i ich prezentacji.

W pierwszym kroku należy przygotować plik, w którym będą przechowywane dane:

rrdtool create bero-test.rrd -s 60 DS:temp:GAUGE:180:U:U DS:gtemp:GAUGE:180:U:U DS:utemp:GAUGE:180:U:U DS:rh:GAUGE:180:U:U DS:pozycja:GAUGE:180:U:U RRA:AVERAGE:0.5:4:44640

Polecenie tworzy plik bero-test.rrd, w którym krok wynosi 60s (przewidywana częstotliwość dostarczania danych). Definiujemy 5 źródeł danych (DS) typu gauge (miernik) – temp (temperatura z czujnika BT1), gtemp (temperatura głowicy), utemp (temperatura zadana), rh (wilgotność z czujnika BT1), pozycja (otwarcie głowicy w %). Dla każdego ze źródeł danych określamy heartbeat na poziomie 180 sekund (po tym czasie braku informacji stan licznika ustawiany jest na nieustalony) oraz pomijamy definiowanie minimalnej i maksymalnej wartości (to tylko szybki test). Dla tych mierników utworzone zostanie archiwum (RRA), uznając, że współczynnik danych nieznanych do znanych może wynosić 0,5 (nie wchodząc w szczegóły), na jeden punkt archiwum będzie przypadać średnia z 4 pomiarów (4 minut), a gromadzić chcemy cyklicznie 44640 punktów w trzymać będziemy dane z 4 miesięcy (44640 punktów). W jednym pliku może być wiele archiwów, gromadzących dane z różnych okresów z różną dokładnością. Nam natomiast wystarczą te średnie z 4 minut. Być może nawet moglibyśmy nie uśredniać danych, ale to standardowe parametry, z którymi zbieram pomiary, dlatego takie się pojawiły.

Aktualizację danych plików wykonuje się poleceniem rrdtool update, a jako parametry podaje się nazwę pliku i wartości rozdzielone dwukropkiem – timestamp i kolejne liczniki.

Przygotujemy skrypt php, który wywoływany co minutę (np. z crona) będzie zbierał dane z Bero i dopisywał dane do bazy RRD. Do łączenia się przez http wykorzystamy bibliotekę cURL.

$ip="192.168.33.100";
$user="user";
$userpass="HasloDoCentralki";
$sciezkaRRD="/tmp/bero-test.rrd";

// funkcja pobierająca dane rejestrów
function getregister( $reg )
{
 global $ip, $user, $userpass;

 $curl = curl_init();
 curl_setopt_array($curl, array(
 CURLOPT_RETURNTRANSFER => 1,
 CURLOPT_URL => 'http://'.$ip.'/getregister.cgi?'.$reg,
 CURLOPT_USERAGENT => '',
 CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
 CURLOPT_USERPWD => $user.":".$userpass
 ));
 $xml = curl_exec($curl);
 curl_close($curl);
 return($xml);
}

//zapytanie o potrzebne rejestry
$gxml=getregister("1@temp&1@rh&21@vtemp&21@vpos_min&21@vpos_range&21@vpos&100@temp");

//parsowanie wyniku XML
$xml=new SimpleXMLElement($gxml);

//przypisywanie danych do zmiennych
$temp=$xml->device->reg[0]['v'];
$rh=$xml->device->reg[1]['v'];
$gtemp=$xml->device->reg[2]['v'];
$ptemp=$xml->device->reg[6]['v'];
$vpos=$xml->device->reg[5]['v'];
$vposmin=$xml->device->reg[3]['v'];
$vposrange=$xml->device->reg[4]['v'];

// obliczamy otwarcie głowicy w procentach
if( $vpos>0 )
{
 $vpos=$vpos*100/($vposrange+$vposmin);
}

//dopisywanie danych do pliku RRD
echo exec('/usr/bin/rrdtool update '.$sciezkaRRD.' '.time().":$temp:$gtemp:$ptemp:$rh:$vpos");

Program nie wymaga chyba zbytnio komentarza. Cztery pierwsze linijki określają konfigurację i dane autentykacyjne. Należy pamiętać, że wywołanie getregister odnosi się do konkretnych numerów urządzeń i pokoju. Dla innych pokoi będzie trzeba je zmienić.

Interpretacja danych

Skoro dane mamy zebrane, to można przejść do ich analizy. Przygotujmy skrypt rysujący wykresy.

#!/bin/bash

BERO1=/tmp/bero-test.rrd
NOW=`date -u +%s`
PNG=/tmp/png

rrdtool graph $PNG/temperatury.png -a PNG -n TITLE:12 -t 'Test Bero - temperatura' \
-A -r -W 'Pomiary w różnych puntkach' -w 600 -h 250 --vertical-label 'Stopnie Celsjusza' --end now -s end-24h --slope-mode \
DEF:t=$BERO1:temp:AVERAGE LINE1:t#00bf00:Temperatura_czujnika \
'GPRINT:t:LAST:%2.1lfC' \
DEF:k=$BERO1:gtemp:AVERAGE LINE1:k#bf0000:Temperatura_głowicy \
'GPRINT:k:LAST:%2.1lfC' \
DEF:y=$BERO1:utemp:AVERAGE LINE1:y#999999:Temperatura_zadana \
'GPRINT:y:LAST:%2.1lfC' ;

rrdtool graph $PNG/glowice.png --lazy -a PNG -n TITLE:12 -t 'Test Bero - otwarcie głowicy' \
-A -r -W 'Pomieszczenia' -w 600 -h 250 --vertical-label 'pozycja %' --end now -s end-24h --slope-mode \
DEF:t=$BERO1:pozycja:AVERAGE LINE1:t#bfbf00:Sypialnia \
'GPRINT:t:LAST:%2.1lf';

rrdtool graph $PNG/wilgotnosc.png --lazy -a PNG -n TITLE:12 -t 'Test Bero - wilgotność' \
-A -r -W 'Pomieszczenia' -w 600 -h 250 --vertical-label 'wilgotność %' --end now -s end-24h --slope-mode \
DEF:t1=$TEST:rh:AVERAGE LINE1:t1#006600:Sypialnia_DHT22 \
'GPRINT:t1:LAST:%2.1lf' \
DEF:t=$BERO1:rh:AVERAGE LINE1:t#bfbf00:Sypialnia \
'GPRINT:t:LAST:%2.1lf';

Wynikiem działania skryptu są 3 wykresy. Skupmy się na razie na pierwszych dwóch. Pierwszy prezentuje temperatury – czujnika, głowicy i zadaną. Drugi informacje o procencie otwarcia głowicy. Najciekawsza jest analiza obu wykresów razem:

Bero - analiza temperatur

Bero - analiza pozycji głowicy

Wyraźnie widać silne otwarcie głowicy (żółty wykres) i grzanie gdy temperatura zadana (szara linia) rośnie z 19.8 stopnia Celsjusza do 20.4. Najlepiej pracę głowicy widać od godziny 10 do 16. Wtedy dla utrzymania właściwej temperatury, jest ona lekko otwierana i przymykana (pewnie mogłaby jeszcze lżej, ale to zawsze kompromis przyjęty w algorytmie). Jednocześnie widać na wykresie z czujnika temperatury na głowicy, jak złym miejscem jest pomiar przy grzejniku. Przy okazji – na wykresie pozycji głowicy są dwa drobne błędy. Nie mierzy ona oczywiście wilgotności.

Warto by jeszcze sprawdzić na ile temperatura czujnika BT1 pokrywa się z faktyczną temperaturą w pokoju. W tym celu dołączyłem do wykresu odczyty z czujnika temperatury i wilgotności opisywanego ostatnio. Sam czujnik znajdował się w innym miejscu (nieco bliżej drzwi – przez część czasu otwartych, ale także daleko od okna). Wyniki są zgodne z oczekiwaniami:

Bero - test utrzymania temperatury

Analogicznie można porównać informację o wilgotności, zbieraną przez oba czujniki (z innego okresu):

Bero - analiza wilgotności

Wskazania są bliskie, natomiast w przypadku mojego AM2301 są bardziej zmienne. Może to wynikać z faktu, że wymiana powietrza wewnątrz BT1 jest mniejsza, ze względu na małe otwory na obudowie (chociaż leży też w miejscu o mniejszym ruchu powietrza – dalej od drzwi). Natomiast widać, że i wartości są zbliżone i trendy zachowane (gdy rośnie lub maleje to na obu).

Podsumowanie

Poza testem API udało się też przyjrzeć pracy systemu i zweryfikować pomiary z innym czujnikiem. Obserwacje są zgodne z oczekiwaniami. Być może nie jest to najlepszy okres do testów, bo idzie wiosna i zapotrzebowanie na ciepło nie jest takie duże, jak w mrozy, ale jednocześnie woda w grzejnikach jest też chłodniejsza, bo tym steruje „pogodówka”. Sam grzejnik jest natomiast przewymiarowany, porównując go do innych pokoi, ale m.in. właśnie dlatego system zarządzania ogrzewaniem jest cenny. Pomieszczenie usytuowane jest od północy, więc wpływ słońca nie jest duży. Można natomiast zaobserwować napływ cieplejszego powietrza z innych pomieszczeń po szerszym otwarciu drzwi koło godziny 16. Może różnica nie była duża, natomiast na tyle znacząca, żeby zawór przy grzejniku zamknął się na jakiś czas. Pewnie w innym przypadku by się tylko nieco przymknął, jednak tutaj cały czas oscylowaliśmy w okolicach minimalnego otwarcia (20% według danych kalibracji odczytanych z API – vpos_min).

Jeżeli chodzi o API, to jest ono proste w użyciu i działa sprawnie. Co prawda ja osobiście preferuję wyniki w postaci JSON, bo można ich wprost użyć np. w NodeJS, ale parsowanie XML też nie jest problemem. W następnej części pewnie pokażę jakąś nieco bardziej złożoną integrację, np. z centralą alarmową Satel. Chyba, że pojawi się inny pomysł.

Ten wpis został opublikowany w kategorii Inteligentny Dom i oznaczony tagami , , , , , , . Dodaj zakładkę do bezpośredniego odnośnika.

6 odpowiedzi na Odczyt temperatur z systemu Bero przez API

  1. SpeX pisze:

    Uuuu, z tego co widzę, to ustawiłeś sobie cieplej między 6-8, a miałeś cieplej pomiędzy 8-10 :/

    • techniczny pisze:

      Heh, tak działa fizyka. Przy bezwładności domu, żeby go nagrzać i wychłodzić potrzeba trochę czasu, szczególnie przy naszych konstrukcjach. Gdyby bezwładność była mniejsza, to także oszczędności z dobrego sterowania byłyby większe.

      Natomiast w tym wypadku nie jest to zupełnie problem. Mimo, że temperatura jeszcze nie wzrosła, to przy pełnym otwarciu zaworu i ciepłych grzejnikach, odczucie ciepła jest bardzo dobre. Kaloryfer nie tylko ogrzewa powietrze, ale także wypromieniowuje ciepło i w ten sposób ogrzewa nas bezpośrednio.

      Swoją drogą dlatego ważne jest, żeby grzejniki nie działały w trybie włącz/wyłącz, tylko regulowały stopień otwarcia w możliwie małym stopniu. Przynajmniej w czasie, gdy w pomieszczeniu są ludzie.

      • SpeX pisze:

        Właśnie mi chodzi o fakt, iż system nie ma parametru „bezwładność”, żeby wiedział iż musi zacząć grzać wcześniej, by osiągnąć oczekiwany poziom o oczekiwanej porze.

        • techniczny pisze:

          Ależ ma. Jeżeli chcesz koniecznie mieć nagrzane o tej danej porze, to ustawiasz wcześniej grzanie, tak to działa we wszystkich systemach. Tylko, jak pisałem, w tym wypadku nagrzewanie wcześniej nie jest efektem wskazanym. Tu właśnie zależy na tym, żeby grzejniki były ciepłe gdy się wstaje, a nie, żeby nagrzać do tego czasu… Pół stopnia temperatury powietrza daje mniej niż ciepłe grzejniki.

  2. ptarac pisze:

    Używam systemu Bero z piecem Defro i sterownikiem Smart II. Jestem z niego bardo zadowolony. Oprócz niego mam system automatyki domowej zestawiony pod sterownikiem Vera EDGE UI6, gdzie mam m.in. zintegrowany alarm. Czy istnieje możliwość pokazania jak zintegrować ww. centralkę z systemem Bero?
    Pozdrawiam,

    • techniczny pisze:

      Niestety nie znam sterownika Vera, ale wygląda na to, że ma jakieś API. Jeżeli tak, to integracja jest możliwa. Natomiast nie bardzo mogę w niej pomóc.

Skomentuj ptarac Anuluj pisanie odpowiedzi

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *