Kontroluj swój klimat za pomocą tego samouczka dotyczącego termostatu Raspberry Pi

Opublikowany: 2022-03-11

W klimatyzacji w wielu domach brakuje nowoczesnych udogodnień, takich jak centralna automatyka, programowalne termostaty, wiele czujników lub sterowanie Wi-Fi. Ale starsza technologia klimatyzacji jest nadal niezawodna, więc w wielu przypadkach jest mało prawdopodobne, aby została wkrótce zmodernizowana.

Wymaga to jednak od użytkowników częstego przerywania pracy lub snu w celu włączenia lub wyłączenia klimatyzatora. Dotyczy to zwłaszcza domów o ciasnych układach, takich jak mój:

Rzut z klimatyzatorem u góry, na prawo od środka. Aby dotrzeć do większości pomieszczeń, w tym do sypialni w lewym dolnym rogu, jego wyjście musi zaokrąglać się w dwa rogi.
Mój niekonwencjonalny plan piętra sprawia, że ​​chłodzenie za pomocą jednego klimatyzatora podokiennego jest wyzwaniem. Nie ma bezpośredniej linii do zdalnego sterowania z sypialni i nie ma bezpośredniej ścieżki, przez którą chłodne powietrze dociera do wszystkich pomieszczeń.

Domy w USA mają zwykle centralną klimatyzację, ale na całym świecie tak nie jest. Brak centralnego klimatyzacji ogranicza możliwości automatyzacji, co utrudnia osiągnięcie tej samej temperatury w całym domu. W szczególności utrudnia to uniknięcie wahań temperatury, które mogą wymagać ręcznej interwencji.

Jako inżynier i entuzjasta Internetu Rzeczy (IoT) widziałem możliwość zrobienia kilku przydatnych rzeczy naraz:

  • Pomóż oszczędzać energię, poprawiając wydajność mojego samodzielnego klimatyzatora
  • Spraw, aby mój dom był bardziej komfortowy dzięki automatyzacji i integracji z Google Home
  • Dostosuj moje rozwiązanie dokładnie tak, jak chciałem, zamiast ograniczać się do dostępnych na rynku opcji
  • Odśwież niektóre z moich umiejętności zawodowych, używając wypróbowanego i przetestowanego sprzętu

Mój klimatyzator to podstawowe urządzenie z prostym pilotem na podczerwień. Znałem urządzenia umożliwiające współpracę klimatyzatorów z systemami inteligentnego domu, takie jak Sensibo czy Tado. Zamiast tego zastosowałem podejście „zrób to sam” i stworzyłem termostat Raspberry Pi, pozwalający na bardziej wyrafinowaną kontrolę w oparciu o dane wejściowe czujników z różnych pomieszczeń.

Sprzęt termostatu Raspberry Pi

Używałem już kilku Raspberry Pi Zero W w połączeniu z modułami czujników DHT22 do monitorowania temperatury i wilgotności w różnych pomieszczeniach. Ze względu na segmentowy plan piętra zainstalowałem czujniki, aby monitorować, jak ciepło było w różnych częściach mojego domu.

Mam również domowy system nadzoru (niewymagany w tym projekcie) na komputerze z systemem Windows 10 z WSL 2. Chciałem zintegrować odczyty czujników z wideo z monitoringu, jako nakładkę tekstową na wideo.

Okablowanie czujnika

Czujniki były proste do okablowania, miały tylko trzy połączenia:

Pierwsze połączenie to "VCC od czujnika do PIN1 - 3v3", drugie to "DANE z czujnika do PIN7 - GPIO4", a trzecie to "GND od czujnika do PIN9 - GND".
Schemat okablowania modułu DHT22, przedstawiający piny służące do podłączenia go do Raspberry Pi.

Użyłem Raspberry Pi OS Lite, instalując Python 3 z PiP i bibliotekę Adafruit_DHT dla Pythona do odczytu danych z czujnika. Jest technicznie przestarzały, ale prostszy w instalacji i obsłudze. Ponadto wymaga mniej zasobów w naszym przypadku użycia.

Chciałem również mieć rejestr wszystkich odczytów, więc użyłem serwera innej firmy, ThingSpeak, do hostowania moich danych i obsługiwania ich za pomocą wywołań API. Jest to stosunkowo proste, a ponieważ nie potrzebowałem odczytów w czasie rzeczywistym, zdecydowałem się wysyłać dane co pięć minut.

 import requests import time import random import Adafruit_DHT KEY = 'api key' def pushData(temp:float, hum:float): '''Takes temp and humidity and pushes to ThingsSpeak''' url = 'https://api.thingspeak.com/update' params = {'api_key': KEY, 'field5': temp, 'field6': hum} res = requests.get(url, params=params) def getData(sensor:int, pin:int): ''' Input DHT sensor type and RPi GPIO pin to collect a sample of data Parameters: sensor: Either 11 or 22, depending on sensor used (DHT11 or DHT22) pin: GPIO pin used (eg 4) ''' try: humidity, temperature = Adafruit_DHT.read_retry(sensor, pin) return humidity, temperature except: Exception("Error reading sensor data") return False if __name__ == "__main__": sensor = 22 # Change to 11 if using DHT11 pin = 4 # I used GPIO pin 4 while True: h, t = getData(sensor, pin) pushData(t, h) time.sleep(300)

Na moim dedykowanym komputerze do nadzoru z uruchomionym WSL 2 skonfigurowałem skrypt PHP, który pobiera dane z ThingSpeak, formatuje je i zapisuje w prostym pliku .txt . Ten plik .txt jest potrzebny mojemu oprogramowaniu do nadzoru do nałożenia go na strumień wideo.

Ponieważ miałem już w domu trochę automatyki, w tym inteligentne żarówki i kilka procedur w Google Home, wynikało z tego, że będę używał danych z czujnika jako inteligentnego termostatu w Google Home. Moim planem było stworzenie procedury Google Home, która automatycznie włącza lub wyłącza klimatyzację w oparciu o temperaturę w pomieszczeniu, bez konieczności wprowadzania danych przez użytkownika.

Zdjęcie urządzenia w kształcie czarnego krążka.
Inteligentny pilot zdalnego sterowania PNI SafeHome PT11IR Wi-Fi.

Droższe rozwiązania typu „wszystko w jednym”, takie jak te oferowane przez Sensibo i Tado, wymagają mniej konfiguracji technicznej, ale za ułamek kosztów PNI SafeHome PT11IR umożliwił mi użycie mojego telefonu do sterowania dowolną liczbą urządzeń na podczerwień w jego zasięgu. Aplikacja sterująca Tuya integruje się z Google Home.

Pokonywanie problemów z integracją Google Home

Mając dostępny inteligentny klimatyzator i dane z czujników, próbowałem rozpoznać Raspberry jako termostat w Google Home, ale bezskutecznie. Udało mi się wysłać dane z czujnika do Google IoT Cloud i jego usługi Pub/Sub, ale nie było możliwości wysłania ich do Google Home, aby utworzyć procedurę na podstawie tych danych.

Po kilku dniach zastanawiania się nad tym pomyślałem o nowym podejściu. A jeśli nie musiałem wysyłać danych do Google Home? A gdybym mógł sprawdzić dane lokalnie i wysłać polecenie do Google Home, aby włączyć lub wyłączyć klimatyzator? Z powodzeniem testowałem polecenia głosowe, więc takie podejście wydawało się obiecujące.

Szybkie wyszukiwanie uruchomiło Assistant Relay, system oparty na Node.js, który umożliwia użytkownikowi wysyłanie poleceń do Asystenta Google, umożliwiając użytkownikowi powiązanie czegokolwiek z Asystentem Google, o ile wie, co zrobić z otrzymanymi danymi wejściowymi.

Co więcej, dzięki Assistant Relay, mogłem zakończyć polecenia mojemu Asystentowi Google, po prostu wysyłając żądania POST do urządzenia z uruchomionym serwerem Node.js (w tym przypadku moim Raspberry Pi Zero W) z pewnymi wymaganymi parametrami. Otóż ​​to. Skrypt jest dobrze udokumentowany, więc nie będę tu wchodzić w szczegóły.

Ponieważ dane z czujników były już odczytywane na komputerze nadzoru, pomyślałem, że mogę zintegrować żądanie ze skryptem PHP, aby utrzymać wszystko w jednym miejscu.

Ponieważ prawdopodobnie nie masz wymagań dotyczących pliku .txt , możesz uprościć ten proces, bezpośrednio odczytując dane z czujnika i wydając polecenia w oparciu o te dane do usługi Google Assistant za pośrednictwem Assistant Relay. Wszystko to można wykonać z jednego urządzenia Raspberry Pi, bez konieczności stosowania dodatkowego sprzętu. Ponieważ jednak wykonałem już połowę pracy, sensowne było wykorzystanie tego, co miałem. Oba skrypty w tym artykule mogą być używane na jednym komputerze; ponadto, w razie potrzeby, skrypt PHP można przepisać w Pythonie.

Ustawienia warunków i działanie automatyczne

Chciałem, aby automatyczne przełączanie zasilania odbywało się tylko w nocy, więc określiłem godziny, w których chcę zautomatyzować działanie — od 22 do 7 rano — i ustawić preferowaną temperaturę. Identyfikacja prawidłowych przedziałów temperatur — aby osiągnąć komfortowy zakres bez skracania żywotności jednostki klimatyzacyjnej poprzez zbyt częste włączanie i wyłączanie jej zasilania — wymagała kilku prób, aby to zrobić dobrze.

Skrypt PHP, który utworzył nakładkę danych z czujnika, był uruchamiany co pięć minut za pomocą zadania cron, więc jedyne, co do niego dodałem, to warunki i żądanie POST.

Stworzyło to jednak problem. Gdyby warunki były spełnione, skrypt co pięć minut wysyłałby polecenie „włącz”, nawet jeśli klimatyzacja była już włączona. To spowodowało, że urządzenie wydało irytujące dźwięki, nawet po poleceniu „wyłącz”. Aby to naprawić, potrzebowałem sposobu na odczytanie aktualnego stanu urządzenia.

Elegancja nie była priorytetem, więc stworzyłem plik JSON zawierający tablicę. Za każdym razem, gdy polecenie „włącz” lub „wyłącz” zakończy się pomyślnie, skrypt doda ostatni status do tej tablicy. To rozwiązało redundancję; jednak szczególnie upalne dni lub nadmierne ogrzewanie w okresie zimowym może spowodować ponowne spełnienie warunków. Zdecydowałem, że w takich sytuacjach wystarczy ręczne przesterowanie. Jako ćwiczenie dla czytelnika zostawię w tym celu dodanie zwrotu przed snippetem switch:

 <?php switch(true) { case $temperature > 27: turnAc('on'); break; case $temperature < 24: turnAc('off'); break; } function turnAc($status) { $command = 'turn on hallway ac'; // hallway ac is the Google Home device name for my AC if ($status == 'off') { $command = 'turn off hallway ac'; } if ($status == 'on' && checkAc() == 'on') { return; } if ($status == 'off' && checkAc() == 'off') { return; } $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => 'local assistant server ip', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS =>'{ "command": '.$command.', "converse": false, "user": "designated user" }', CURLOPT_HTTPHEADER => array( 'Content-Type: application/json' ), )); $response = curl_exec($curl); curl_close($curl); $obj = null; try { $obj = json_decode($response); } catch (Exception $e) { } if (!$obj || $obj->success != true) { markAc($status == 'on' ? 'off' : 'on'); // if error, mark it as opposite status return; } markAc($status); } function markAc($status) { $file = __DIR__ . "/markAc.json"; $json = json_decode(file_get_contents($file), true); $json[] = array(date('F j, YH:i:s'), $status); $handler = fopen($file, "w") or die("Unable to open file!"); $txt = json_encode($json); fwrite($handler, $txt); fclose($handler); } function checkAc() { $file = __DIR__ . "/markAc.json"; $json = json_decode(file_get_contents($file), true); $end = array_pop($json); return $end[1]; }

To zadziałało, ale nie przy pierwszej próbie. Po drodze musiałem wymyślić różne rzeczy i dostosować je w razie potrzeby. Mam nadzieję, że korzystając z mojego doświadczenia, nie będziesz musiał robić tak wiele, aby zrobić to dobrze za pierwszym razem.

Wartość kontrolera termostatu Raspberry Pi

Byłem zmotywowany do zautomatyzowania klimatyzacji, ponieważ niekonwencjonalny układ mojego domu czasami powodował bardzo różne temperatury w różnych pomieszczeniach. Ale automatyzacja ogrzewania i chłodzenia przynosi korzyści nawet tym, którzy nie borykają się z tym konkretnym problemem.

Ludzie na całym świecie żyją w różnych klimatach i płacą różne ceny za energię (i różne stawki o różnych porach dnia), więc nawet niewielka poprawa efektywności energetycznej może sprawić, że automatyzacja będzie opłacalna w niektórych regionach.

Co więcej, ponieważ coraz więcej domów staje się zautomatyzowanych, istnieje powód, aby zbadać potencjał automatyzacji starszych energochłonnych urządzeń i urządzeń, takich jak klimatyzatory, grzejniki elektryczne i podgrzewacze wody. Ponieważ urządzenia te są zwykle nieporęczne, trudne do zainstalowania i drogie w modernizacji, wiele osób utknie z nimi na wiele lat. Uczynienie tych „głupich” urządzeń nieco inteligentniejszymi może nie tylko poprawić komfort i efektywność energetyczną, ale także wydłużyć ich żywotność.


Dalsza lektura na blogu Toptal Engineering:

  • Jak zbudować serwer Raspberry Pi do rozwoju?
  • Jak zmienić przeznaczenie starego smartfona na pilota?