Domoticz #2 – konfiguracja Xiaomi Mijia Bluetooth Hygrothermograph
Mamy już zainstalowanego domoticza, to teraz czas na skonfigurowanie w nim czujników i urządzeń wykonawczych. Na pierwszy ogień pójdą popularne termometry Xiaomi Mija z bluetooth, wyświetlaczem LCD i funkcją pomiaru wilgotności.
Obecna wersja Domoticza (4.11478) nie posiada wbudowanej obsługi termometrów / higrometrów Xiaomi Mijia (kod produktu LYWSDCGQ), ale wystarczy prosty skrypt, chwila konfiguracji i już działa. Mój Domoticz stoi na Raspberry 3 z wbudowanym Bluetooth, także nie muszę nawet wpinać dodatkowego modułu do portu USB.
Dodajemy czujniki Xiaomi do Domoticza
W Domoticzu przechodzimy do Konfiguracja (Config), dalej Sprzęt (Hardware). Wpisujemy dowolną nazwę (u mnie Mi sensor Temp & Hum disp) a jako Typ wybieramy Dummy (Does nothing, use for virtual switches only), dokładnie wygląda to tak:
Wciskamy Dodaj (Add). Sprzęt pojawi się na górze z przyciskiem Utwórz wirtualne czujniki. Wciskamy go i w nowym okienku w polu Nazwa podajemy nazwę czujnika, oraz jego Typ: Temp+Wilg:
Operację powtarzamy tyle razy ile mamy czujników i spisujemy sobie ich indeksy – kolumna IDX na początku tabeli. Aha, czujniki znajdziesz w Konfiguracja -> Sprzęt oraz w głównej zakładce Temperatura. Teraz czas na resztę konfiguracji.
Instalacja i konfiguracja skryptu mijia-sensor-domoticz
Skrypt do domoticza znajduje się na githubie. A dokładniej tu: https://github.com/pFenners/mijia-sensor-domoticz. Instalacja to poprostu sklonowanie repozytorium. Najlepiej (dla porządku), zrobić to w folderze /domoticz/scripts/python za pomocą polecenia:
git clone https://github.com/pFenners/mijia-sensor-domoticz
W folderze głównym domoticza, dalej scripts/python/ pojawił się nowy katalog mijia_sensor_domoticz:
Teraz fajny bajer – zeskanujemy sobie otoczenie w poszukiwaniu urządzeń bluetooth:
sudo hcitool lescan
Prócz telewizorów sąsiadów, powinniśmy znaleźć nasze termometry Xiaomi Mijia, ich mac adres zaczyna się od 4C:65 i nazwa MJ_HT_V1:
Jak widać wyżej, moje 2 termometry Xiaomi zostały odnalezione. Niektóre urządzenia zostały wykryte dwukrotnie. To co nas interesuje to adresy mac, które zaraz wpiszemy do skryptu, warto więc je zanotować.
Będąc nadal w katalogu /domoticz/scripts/python, wpisujemy:
nano mijia-sensor-domoticz/domoticz_mijia.py
Otworzy to nam skrypt z możliwością edycji:
Przechodzimy na koniec pliku i w miejsce 3 przykładowych adresów mac wpisujemy nasze, dalej wpisujemy numer indeksu (IDX) identyczny z wirtualnymi sensorami z zakładki Konfiguracja -> Urządzenia. W moim przypadku są to kolejno 1 i 2:
Po zapisaniu możemy sprawdzić czy wszystko działa., uruchamiając skrypt:
/usr/bin/python3 mijia-sensor-domoticz/domoticz_mijia.py
U mnie wszystko zadziałało zgodnie z oczekiwaniami, czyli czujniki zostały odpytane, a domoticz zasilony danymi:
Sprawdźmy jak wygląda zakładka Konfiguracja -> Urządzenia:
Jak widać, prócz temperatury i wilgotności mamy też stan baterii czujnika. To teraz zautomatyzujmy całość.
Automatyczne odpytywanie czujników Xiaomi w Domoticz
Najprostszą metodą automatycznego odczytywania danych z termometrów Xiaomi Mijia będzie użycie cron’a. który co jakiś, zdefiniowany czas będzie uruchamiał skrypt domoticz_mijia.py. W tym celu wpisujemy:
crontab -e
i dopisujemy czas co jaki ma się uruchamiać skrypt, oraz ścieżkę do niego. Ja wybrałem odpytywanie co 20 minut:
W zakładce Temperatura możemy zobaczyć nasze czujniki i ich statusy:
Po wciśnięciu Logi zobaczymy wykresy – dobowy, miesięczny i roczny:
Podsumowanie
Co nam daje pomiar temperatury? Po pierwsze możemy zoptymalizować ogrzewanie w mieszkaniu. Stosując urządzenia wykonawcze, np. głowice termostatyczne w grzejnikach, możemy utrzymywać stabilną temperaturę, bez niedogrzania i przegrzewania mieszkania. W bardziej rozbudowanych systemach można sterować kotłem, pompą ciepła czy wentylacją.
W kolejnej części opiszę jak podpiąć czujniki fizycznie do Raspberry i odczytywać ich wskazania przez Domoticz.
Przypominam też o pierwszym wpisie dotyczącym inteligentnego domu: Domoticz#1 – Instalacja na RPi.
Rozumiem, iż co 20 min pobierasz paczkę danych z 20 minut? Czy co 20 min jest dokonywany jeden pomiar?
Co 20 minut dokonywany jest jeden pomiar.
Witam, mam problem. niestety u mnie nie wszystko poszło dobrze. Mianowicie dane odczytuje prawidłowo, ale jest błąd i nie widzę nic w domoticzu. Poniżej wklejam jak to u mnie wygląda:
pi@raspberrypi:~/domoticz/scripts/python $ /usr/bin/python3 mijia-sensor-domoticz/domoticz_mijia.py
mijia-sensor-domoticz/domoticz_mijia.py:23: DeprecationWarning: encodestring() is a deprecated alias since 3.1, use encodebytes()
base64string = base64.encodestring((‘%s:%s’ % (domoticzusername, domoticzpassword)).encode()).decode().replace(‘\n’, ”)
1: updating
Mi Sensor: 58:2D:34:31:09:8B
Firmware: 00.00.66
Name: MJ_HT_V1
Temperature: 22.0°C
Humidity: 49.6%
Battery: 37%
http://127.0.0.1:8000/json.htm?type=command¶m=udevice&idx=12&nvalue=0&svalue=22.0;49.6;1&battery=37
Traceback (most recent call last):
File “/usr/lib/python3.7/urllib/request.py”, line 1317, in do_open
encode_chunked=req.has_header(‘Transfer-encoding’))
File “/usr/lib/python3.7/http/client.py”, line 1244, in request
self._send_request(method, url, body, headers, encode_chunked)
File “/usr/lib/python3.7/http/client.py”, line 1290, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File “/usr/lib/python3.7/http/client.py”, line 1239, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File “/usr/lib/python3.7/http/client.py”, line 1026, in _send_output
self.send(msg)
File “/usr/lib/python3.7/http/client.py”, line 966, in send
self.connect()
File “/usr/lib/python3.7/http/client.py”, line 938, in connect
(self.host,self.port), self.timeout, self.source_address)
File “/usr/lib/python3.7/socket.py”, line 727, in create_connection
raise err
File “/usr/lib/python3.7/socket.py”, line 716, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refused
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File “mijia-sensor-domoticz/domoticz_mijia.py”, line 92, in
update(“58:2D:34:31:09:8B”,”12″)
File “mijia-sensor-domoticz/domoticz_mijia.py”, line 88, in update
domoticzrequest(“http://” + domoticzserver + “/json.htm?type=command¶m=udevice&idx=” + idx_temp + “&nvalue=0&svalue=” + val_temp + “;” + val_hum + “;”+ val_comfort + “&battery=” + val_bat)
File “mijia-sensor-domoticz/domoticz_mijia.py”, line 29, in domoticzrequest
response = urllib.request.urlopen(request)
File “/usr/lib/python3.7/urllib/request.py”, line 222, in urlopen
return opener.open(url, data, timeout)
File “/usr/lib/python3.7/urllib/request.py”, line 525, in open
response = self._open(req, data)
File “/usr/lib/python3.7/urllib/request.py”, line 543, in _open
‘_open’, req)
File “/usr/lib/python3.7/urllib/request.py”, line 503, in _call_chain
result = func(*args)
File “/usr/lib/python3.7/urllib/request.py”, line 1345, in http_open
return self.do_open(http.client.HTTPConnection, req)
File “/usr/lib/python3.7/urllib/request.py”, line 1319, in do_open
raise URLError(err)
urllib.error.URLError:
Sprawdź czy w pliku domoticz_mijia.py wskazujesz właściwy adres:port domoticza w zmiennej domoticzserver
Dziękuję za pomoc. Nie wiem jak ja to zrobiłem, ale chyba ze 10 razy sprawdzałem czy wszystko jest ok i nie zauważyłem że port zły wpisałem. Jeszcze raz bardzo dziękuję wszystko teraz śmiga.
Witam,
Postąpiłem zgodnie z Pana tutorialem, ale po uruchomieniu skryptu otrzymuje komunikat
pi@raspberrypi:~/domoticz/scripts/python $ /usr/bin/python3 mijia-sensor-domoticz/domoticz_mijia.py
mijia-sensor-domoticz/domoticz_mijia.py:23: DeprecationWarning: encodestring() is a deprecated alias since 3.1, use encodebytes()
base64string = base64.encodestring((‘%s:%s’ % (domoticzusername, domoticzpassword)).encode()).decode().replace(‘\n’, ”)
1: updating
Characteristic Write Request failed: Attribute can’t be written
Error reading value retry after 5 seconds…
Czujniki wykryte poprzez sudo hcitool lescan.
z góry dziękuję za pomoc
Posiadam czujnik LYWSD03MMC i widzę że ten skrypt z tym nie działa.
Właśnie miałem pytać, czy masz czujniki okrągłe, czy kwadratowe. Obsługę kwadratowych opiszę za jakiś czas. Na dniach pojawi się opis bramki DIY ZigBee do domoticza, dzięki której będzie można obsługiwać dziesiątki czujników.
Cześć, dzięki wielkie za ten poradnik. Szukałem tego od jakiegoś czasu 🙂 Mam taki kłopot, RPi nie robi update automatycznie. Przy próbie wywołania skryptu ręcznie zamiast z crona dostaję
connect error: Device or resource busy (16)
connect error: Device or resource busy (16)
connect error: Device or resource busy (16)
connect error: Device or resource busy (16)
Error reading value retry after 5 seconds…
Nie wiem o co chodzi bo to wygląda jakby BT był cały czas zajęty? Będę wdzięczny za pomoc.
Małe uzupełnienie do mojego komentarza. Przy ręcznym uruchomieniu dostaję “DeprecationWarning: decodestring() is a deprecated alias since 3.1, use decodebytes()base64string = base64.encodestring((‘%s:%s’ % (domoticzusername, domoticzpassword)).encode()).decode().replace(‘\n’, ”)”
To jest ostrzeżenie dotyczące zmian w instrukcjach Pythona i na tą chwilę nie ma znaczenia. Używasz jeszcze do czegoś Bluetootha? Informacja “connect error: Device or resource busy (16)” nie pochodzi ze skryptu, jest generowana przez Raspbiana. Może masz uruchomione w innym procesie skanowanie urządzeń blutetooh? Po restarcie też to dostajesz?
@Wojtek,
Dzięki za odpowiedź. Robiłem wczoraj wieczorem kilka prób na tym skrypcie i finalnie wróciłem do wersji podstawowej.
Nie używam BT do niczego innego. Po restarcie RPi to również występowało. Spróbowałem zrobić update firmware czujników (3 szt.). Dziwne jest to że po update firmware i ponownym sprawdzeniu czy są dostępne nowe wersje w aplikacji Xiaomi Home i cały czas otrzymuję że jest dostępna nowa (ta sama!!!) aktualizacja.
Po tym jak zrestartowałem czujniki, RPi, i Domoticza oraz update firmware na 3 czujnikach po kolejno, udaje się pobierać cyklicznie dane z czujników.
Aby pozbyć się ostrzeżenia:
mijia-sensor-domoticz/domoticz_mijia.py:23: DeprecationWarning: encodestring() is a deprecated alias since 3.1, use encodebytes()
Zmieńcie w skrypcie linie zawierającą:
base64string = base64.encodestring
na
base64string = base64.encodebytes
Dokładnie, dzięki za opis.
Super sprawa z odczytem tych czujników bezpośrednio z maliny, wszystko jest ok ale zasięg BLE u mnie pozostawia wiele do życzenia – u mnie mniej niż 8 m przez jedną ścianę z cegły, z sąsiedniego pokoju już nie odbiera, czy to jest normalne ? Testuję na Rpi Zero W,
@Slawomir Nowak U mnie podobnie. Temperaturę mogę łapać tylko z sensorów które sa w domu. Po wystawieniu czujnika za okno nie ma szans na jego wykrycie. Zasięg jest niewielki. Używam rpi 3b+. Liczę na to że urządzenia komunikujące się po ZigBee będą miały lepszy zasięg.
Mam to rozwiązanie od pewnego czasu testowałem oprócz tego RPIeasy niestety malina potrafi nie wiadomo dlaczego raz na 24 godziny albo raz na 48 godzin zablokować bluetooth czasami jest to 3 w nocy czasami 4 nie ma reguły przeniosłem ten skrypt na maszynę z ubuntu i działa doskonale pomiar robię co 5 minut myślę że jest to w miarę rozsądnie
W moim przypadku też wyskakiwał mi błąd Errno111 po odpaleniu skryptu, problem był niewłaściwy port. U mnie po świeżej instalacji poprawny port to 8080.
domoticzserver = “127.0.0.1:8080”
Zrobiłem wszystko zgodnie z instrukcją adres serwera 127.0.0.1:80, przy odczycie otrzymuje komunikat: connect: Connection refused (111)
Adres mac czujnika temp. widoczny i dodany. Ma może ktoś pomysł co może być nie tak?
Spróbuj portu 8080 zamiast 80.
A mi nie działa crontab do automatyzacji…
*/5 * * * * /usr/bin/python3 home/pi/domoticz/scripts/python/mijia-sensor-domoticz/domoticz_mijia.py >/dev/null 2>&1
Zobacz w logach crona dlaczego.
Może dlatego że robiłem crona na telefonie w kliencie ssh. Jak zrobiłem na PC w putty to ruszyło bez problemu
W terminalu temperatura się wyświetla. Kafelek z temp.i wilgotnością w Dummy zrobiony. Calyczas pokazuje 0 stopni i 50% wilgotności. Mecze już kilka miesięcy, cały czas to samo. Domoticz nie pobiera danych. Pomocy.
Przestało działać, wyświetla takie oto komunikaty:
pi@domoticz:~/domoticz/scripts/python $ sudo /usr/bin/python3 mijia-sensor-domoticz/domoticz_mijia.py
1: updating
Mi Sensor: 4C:65:A8:D9:A3:F0
Firmware: 00.00.68
Name: MJ_HT_V1
Temperature: 24.4°C
Humidity: 49.9%
Battery: 80%
http://127.0.0.1:8080/json.htm?type=command¶m=udevice&idx=1&nvalue=0&svalue=24.4;49.9;1&battery=80
Traceback (most recent call last):
File “/home/pi/domoticz/scripts/python/mijia-sensor-domoticz/domoticz_mijia.py”, line 92, in
update(“4C:65:A8:D9:A3:F0″,”1”)
File “/home/pi/domoticz/scripts/python/mijia-sensor-domoticz/domoticz_mijia.py”, line 88, in update
domoticzrequest(“http://” + domoticzserver + “/json.htm?type=command¶m=udevice&idx=” + idx_temp + “&nvalue=0&svalue=” + val_temp + “;” + val_hum + “;”+ val_comfort + “&battery=” + val_bat)
File “/home/pi/domoticz/scripts/python/mijia-sensor-domoticz/domoticz_mijia.py”, line 29, in domoticzrequest
response = urllib.request.urlopen(request)
File “/usr/lib/python3.9/urllib/request.py”, line 214, in urlopen
return opener.open(url, data, timeout)
File “/usr/lib/python3.9/urllib/request.py”, line 523, in open
response = meth(req, response)
File “/usr/lib/python3.9/urllib/request.py”, line 632, in http_response
response = self.parent.error(
File “/usr/lib/python3.9/urllib/request.py”, line 561, in error
return self._call_chain(*args)
File “/usr/lib/python3.9/urllib/request.py”, line 494, in _call_chain
result = func(*args)
File “/usr/lib/python3.9/urllib/request.py”, line 641, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 401: Unauthorized
Pomoże ktoś to naprawić…?
Trzeba włączyć w Domoticz “API Protection”