Jak zbudować własny inteligentny dom w jedno popołudnie?

PubNub Developer Relations - Feb 20 - - Dev Community

Internet rzeczy (IoT) znacznie się zmienił na przestrzeni lat, a inteligentne domy stają się coraz bardziej powszechne. Dzięki najnowszym osiągnięciom, właściciele domów mają teraz dostęp do różnych technologii inteligentnego domu, od zaawansowanych systemów bezpieczeństwa po inteligentnych asystentów domowych.

Pojawiły się nowe produkty i technologie, takie jak SmartThings i urządzenia kompatybilne z Apple HomeKit, a także inteligentne głośniki z obsługą Spotify, takie jak HomePod, oraz urządzenia zasilane przez Z-Wave i Zigbee. Nawet routery są teraz dostarczane z obsługą inteligentnego domu. Pomimo tych zmian, niniejszy artykuł nadal oferuje cenne informacje dla wszystkich zainteresowanych tworzeniem projektów inteligentnego domu.

Dowiedz się więcej o tym, jak PubNub wspiera tysiące klientów na całym świecie w naszych zasobach PubNub for Developers. Można tam również znaleźć kilka historii sukcesu klientów, które ilustrują skuteczność naszej oferty w świecie rzeczywistym. Jeśli masz jakiekolwiek sugestie lub pytania dotyczące treści tego artykułu, skontaktuj się z nami pod adresem devrel@pubnub.com.

W dzisiejszych czasach technologie IoT sprawiły, że inteligentne domy i automatyka domowa stały się bardziej powszechne. Właściciele domów korzystają obecnie z zaawansowanych produktów, takich jak pakiet urządzeń Ring do ochrony domu. Asortyment ten obejmuje czujniki ruchu, dzwonki wideo do drzwi, inteligentne zamki i najnowocześniejsze kamery bezpieczeństwa zintegrowane z inteligentnymi produktami domowymi obsługiwanymi przez SmartThings i Apple HomeKit.

Systemy inteligentnego domu mogą również pomagać właścicielom domów w ich codziennych czynnościach. Produkty takie jak Nest Thermostat mogą automatycznie regulować temperaturę, podczas gdy inteligentne wyświetlacze, takie jak Lenovo Smart Display, mogą wyświetlać spersonalizowane treści. Philips Hue umożliwia właścicielom domów sterowanie włącznikami światła za pomocą inteligentnych żarówek, podczas gdy Apple HomePod i produkty Bose z obsługą Spotify oferują funkcje inteligentnego głośnika. Zarządzanie sterowaniem głosowym jest również możliwe przy użyciu osobistych asystentów, takich jak Google Home, Amazon Alexa, Amazon Echo lub Siri, które ułatwiają sterowanie różnymi urządzeniami IoT wraz z ustawianiem timerów. Pomimo obszernej listy istniejących urządzeń inteligentnego domu, niniejszy samouczek poprowadzi Cię przez proces tworzenia własnego systemu inteligentnego domu przy użyciu PubNub.

W PubNub specjalizujemy się w przybliżaniu sfery IoT masom. Dzięki naszemu API danych w czasie rzeczywistym i platformie Virtual Spaces, możesz polegać na PubNub, aby zasilić swoje centrum inteligentnego domu. Sprawdźmy, jak stworzyć intuicyjny i wydajny system inteligentnego domu z trzema technologiami inteligentnego domu.

Stwórzmy system inteligentnego domu

Co odróżnia inteligentny dom od zwykłego? Dwa kluczowe czynniki: automatyzacja i centralność. Inteligentny dom automatyzuje podstawowe zadania i może przesyłać informacje w obie strony z centralnej lokalizacji, zazwyczaj aplikacji domowej. W tym samouczku użyjemy PubNub do wdrożenia tych dwóch filarów IoT i zbudujemy następujące technologie:

  • Smart Light - automatyzacja oświetlenia

  • Light Detector - centralizacja danych

  • Door Detector - centralizacja danych

Wymagania

Do stworzenia tych trzech technologii IoT, które tworzą system inteligentnego domu, potrzebujemy następujących materiałów i sprzętu:

Raspberry Pi

Aby zaprogramować nasze technologie IoT i umożliwić im komunikację między Tobą a Twoim domem, potrzebujesz mikrokontrolera. Jednym z najłatwiejszych w użyciu mikrokontrolerów jest najnowsza wersja Raspberry Pi, którą od stycznia 2022 roku jest Raspberry Pi 4. Jeśli nigdy wcześniej go nie konfigurowałeś, instrukcje można znaleźć na stronie internetowej produktu.

Przekaźnik

Aby chronić nasze Raspberry Pi przed wysokimi napięciami, które mogłyby je uszkodzić, będziemy potrzebować przekaźnika. Przekaźnik jest zasadniczo przełącznikiem, który może obsługiwać wysokie prądy i napięcia, dzięki czemu RPi nie musi tego robić.

Lampa

Aby stworzyć inteligentną lampę, będziemy potrzebować prostej, niedrogiej lampy.

Fototranzystor

Do zbudowania inteligentnego czujnika światła potrzebny będzie fototranzystor. Element ten działa jak przełącznik, umożliwiając przepływ prądu tylko w obecności światła, co czyni go idealnym czujnikiem do określania, czy światła w domu są włączone.

Folia aluminiowa i drut

Aby stworzyć czujnik drzwiowy, należy użyć podkładek kontaktowych z folii cynowej, które umożliwiają przepływ prądu w przypadku zetknięcia się podkładek. W ten sposób można przymocować podkładkę do drzwi i ich ramy, tak aby za każdym razem, gdy drzwi są zamknięte, podkładki stykały się i informowały Raspberry Pi, że nasze drzwi są zamknięte. Będziesz musiał stworzyć dwie podkładki z folii cynowej, z przewodami podłączonymi do każdej z nich. Przymocuj jedną podkładkę do drzwi, a drugą do ramy za pomocą taśmy malarskiej.

Przejdźmy teraz do konfiguracji sprzętu.

Konfiguracja sprzętu

Inteligentna lampa

Aby stworzyć inteligentną lampę z dowolnej zwykłej lampy, należy rozdzielić kabel zasilający na dwie części (oczywiście po odłączeniu) i zdjąć część obudowy, aby odsłonić przewody. Każda lampa ma kabel zasilający (zazwyczaj czerwony) i kabel uziemiający (zazwyczaj czarny).

Teraz chwyć przekaźnik i podłącz przewody uziemienia z powrotem razem, podłącz jeden koniec przewodu zasilającego do portu NO (normalnie otwartego) przekaźnika, a drugi koniec do portu NC (normalnie zamkniętego) przekaźnika.

Teraz, aby podłączyć moduł lampy-przekaźnika do RPi, podłącz je do pinów GPIO RPi.

Czujniki światła

Obwód czujnika światła jest znacznie prostszy w implementacji. Podłącz fototranzystor do jednego z pinów GPIO RPI.

Czujnik drzwi

W przypadku czujnika drzwi, podłącz jeden pad do pinu GPIO na RPi, a drugi pad do masy (dla celów diagramu pady są reprezentowane jako diody LED).

Projektowanie systemu

Przed rozpoczęciem implementacji kodu upewnij się, że założyłeś darmowe konto PubNub, ponieważ będziesz potrzebował kluczy publikowania/subskrybowania do wysyłania informacji przez sieć PubNub.

Włącz SSH

Protokół Secure Shell (SSH) umożliwia użytkownikom zdalny dostęp do terminali RPi z komputerów przez WiFi. W połączeniu z GitHub użytkownicy mogą przesyłać kod ze swoich komputerów do zdalnego repozytorium, SSH do terminala Pi i pobierać kod bezprzewodowo. Pozwala to na szybszy i płynniejszy proces rozwoju.

Aby włączyć SSH na swoim RPi, postępuj zgodnie z prostymi i szybkimi instrukcjami.

Pobieranie bibliotek urządzeń i zależności

W przypadku naszych urządzeń, aby je włączyć, konieczne jest podanie napięcia wyjściowego 1 lub 0 z RPI. I odwrotnie, czujniki dają RPi napięcie wejściowe 1 lub 0, w zależności od tego, czy są mokre czy suche. Obie te funkcje wymagają użycia pinów GPIO RPi.

Ponieważ będziesz kodować w Pythonie, przydatne będzie zainstalowanie biblioteki GPIO Zero, która pozwoli ci wykonywać proste wywołania funkcji w celu aktywacji lub odczytu pinów.

UWAGA: Należy pamiętać, że biblioteki te muszą być zainstalowane na RPi poprzez SSH-ing do urządzenia i uruchomienie poniższych poleceń.

sudo apt install python-gpiozero
Enter fullscreen mode Exit fullscreen mode

Tworzenie aplikacji za pomocą PubNub

Pełny kod tego projektu znajduje się w tym repozytorium. Utwórz skrypt Pythona, aby połączyć nasze czujniki z Internetem. Otwórz nowy dokument w swoim ulubionym edytorze tekstu i zaimportuj biblioteki i inne zależności, aby umożliwić urządzeniom komunikację w sieci PubNub.

#---------------Library Setup----------------#
import pubnub
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub
from pubnub.callbacks import SubscribeCallback
from pubnub.enums import PNOperationType, PNStatusCategory

from gpiozero import Button, LED
from time import sleep

#--------------------------------------------#




#----------------PubNub Setup----------------#
pnconfig = PNConfiguration()
pnconfig.subscribe_key = "YOUR SUBSCRIBE KEY"
pnconfig.publish_key = "YOUR PUBLISH KEY"
pnconfig.ssl = False
pubnub = PubNub(pnconfig)
#--------------------------------------------#
Enter fullscreen mode Exit fullscreen mode

Musisz powiedzieć Raspberry Pi, które urządzenia są podłączone do którego z jego pinów:

#------------Sensor Declarations-------------#
#lamp is connected to GPIO4 as an LED
lamp = LED(4)

#door sensor is connected to GPIO3 as a Button
door_sensor = Button(3)
#light sensor is connected to GPIO14 as a Button
light = Button(14)
#--------------------------------------------#
Enter fullscreen mode Exit fullscreen mode

UWAGA: Lampa jest zadeklarowana jako dioda LED, ponieważ chcesz nią sterować tak, jakby była zwykłą diodą LED. Czujniki są inicjowane jako przyciski, ponieważ wysyłają stały aktywny sygnał w taki sam sposób, jak przycisk po przytrzymaniu lub naciśnięciu. Na tym polega magia biblioteki GPIO Zero, ponieważ interfejs z czujnikami i urządzeniami nie wymaga wysiłku.

Należy również utworzyć zmienną licznika, aby wiedzieć, ile razy nasze drzwi zostały otwarte:

#door counter
doorCount = 0
Enter fullscreen mode Exit fullscreen mode

Aby nasza lampa IoT mogła wchodzić w interakcje z klientem, musimy wykorzystać dwukierunkową funkcję pub/sub PubNub. Wymaga to dodania listenera do zarządzania przychodzącymi wiadomościami i skonfigurowania subskrypcji do nasłuchiwania na określonym kanale.

class MySubscribeCallback(SubscribeCallback):
    def status(self, pubnub, status):
        # The status object returned is always related to subscribe but could contain information about subscribe, heartbeat, or errors
        # use the operationType to switch on different options
        if status.operation == PNOperationType.PNSubscribeOperation or status.operation == PNOperationType.PNUnsubscribeOperation:
            if status.category == PNStatusCategory.PNConnectedCategory:
                # This is expected for a subscribe, this signifies no error or issue exists
            elif status.category == PNStatusCategory.PNReconnectedCategory:
                # This usually occurs if subscribe temporarily fails but reconnects. This indicates there was a temporary error but it has already been resolved
            elif status.category == PNStatusCategory.PNDisconnectedCategory:
                # This is the expected category for an unsubscribe. This means there was no error in unsubscribing from everything
            elif status.category == PNStatusCategory.PNUnexpectedDisconnectCategory:
                # This is usually an issue with the internet connection, this is an error, handle appropriately. A retry will be initiated automatically.
            elif status.category == PNStatusCategory.PNAccessDeniedCategory:
                # This indicates that PAM does not permit this client to subscribe to this channel and channel group configuration. This constitutes a specific error
            else:
                # This is usually an issue with the internet connection, this is an error, handle appropriately. A retry will be initiated automatically.
        elif status.operation == PNOperationType.PNSubscribeOperation:
            # Heartbeat operations can indeed encounter errors, so it is essential to verify if there's an error first. For more detailed information on how to configure heartbeat notifications through the status PNObjectEventListener callback, please refer to [PNConfiguration heartbeat config](https://www.pubnub.com/docs/sdks/javascript/api-reference/pn-configuration)
            if status.is_error():
                # There was an error with the heartbeat operation, handle here
            else:
                # Heartbeat operation was successful
        else:
            # Encountered unknown status type
Enter fullscreen mode Exit fullscreen mode

W powyższym wywołaniu zwrotnym obecność obsługuje przychodzące dane obecności, podczas gdy wiadomość obsługuje polecenia lampy. Włączamy lampę, jeśli klient wyśle wiadomość "ON". I odwrotnie, jeśli wiadomość brzmi "OFF", wyłączamy lampę.

def presence(self, pubnub, presence):
    pass  # handle incoming presence data

def message(self, pubnub, message):
    #message handler for Lamp commands
    #Turn the lamp on if client receives the message ON
    if message.message == 'ON':
        lamp.on()
        #let your subscriber client know that the lamp has been turned on
        pubnub.publish().channel('ch1').message("lamp has been turned on").sync()
        sleep(3)
    #Turn the lamp on if client receives the message OFF
    elif message.message == 'OFF':
        lamp.off()
        #let your subscriber client know that the lamp has been turned off
        pubnub.publish().channel('ch1').message("lamp has been turned off").sync()
Enter fullscreen mode Exit fullscreen mode

Następnie upewniamy się, że nasz program dodaje funkcję MySubscribeCallback() i subskrybuje wybrany kanał, w tym przypadku "ch1".

pubnub.add_listener(MySubscribeCallback())
#make sure to subscribe to the channel of your choice. In this case, we chose to create a channel called ch1 to publish to
pubnub.subscribe().channels('ch1').execute()
Enter fullscreen mode Exit fullscreen mode

Zwróć uwagę na obsługę zdarzeń wiadomości. Za każdym razem, gdy program otrzymuje wiadomość od klienta aplikacji, analizuje ją za pomocą message.message. Następnie należy utworzyć programy obsługi zdarzeń za pomocą instrukcji if, aby włączyć lub wyłączyć lampę za pomocą polecenia GPIO . on ( ) lub .off().

Na koniec należy pamiętać, że gdy wiadomość jest publikowana z powrotem do klienta, użytkownik jest informowany, że jego żądanie zostało pomyślnie wykonane. W tym przypadku informujesz klienta, czy lampa jest włączona, czy wyłączona.

Ta sekcja jest opcjonalna (ponieważ nie jest używana w tym programie), ale można utworzyć wywołanie zwrotne wydawcy w celu wykonania funkcji za każdym razem, gdy wiadomość jest publikowana.

def publish_callback(result, status):
    pass
    # Handle PNPublishResult and PNStatus
Enter fullscreen mode Exit fullscreen mode

Ostatni segment programu będzie stale sprawdzał wejścia czujników, aby sprawdzić, czy czujniki coś wykrywają. Główna pętla while, będąca swego rodzaju "routerem", wielokrotnie sprawdza wejścia: while True:\. W ramach tej głównej pętli while można skonstruować pętle podrzędne, aby sondować czujniki. Ponieważ czujniki zostały zainicjalizowane jako przyciski z biblioteki GPIO Zero, wymagana jest funkcja .is\_held\.

Nawet jeśli nie używamy przycisku, czujniki działają tak, jakby były przyciskami, ponieważ symulują ten sam "sygnał przytrzymania przycisku", gdy są aktywne (tj. wykrywają coś). Istnieje kilka fragmentów kodu, które sondują czujnik drzwi i światła, sprawdzając ich stan. Jeśli czujnik jest aktywny, wiadomość jest publikowana z powrotem do klienta, informując go, czy czujnik jest włączony, czy wyłączony. Podobne zasady można zastosować do innych produktów inteligentnego domu, takich jak SmartThings, urządzenia Apple HomeKit, a nawet HomePod, znacznie rozszerzając możliwości inteligentnego domu.

Przesyłanie kodu

Aby przesłać kod do Raspberry Pi, zawsze zatwierdzaj kod w repozytorium, a następnie przeciągnij go do Raspberry Pi. Otwórz terminal, wprowadź katalog roboczy i zatwierdź kod w chmurze za pomocą tych poleceń.

git add .
git commit -m "updates"
git push
Enter fullscreen mode Exit fullscreen mode

SSH do Raspberry Pi i przejdź do odpowiedniego katalogu.

ssh pi@<YOUR IP ADDRESS>
cd <your directory>
Enter fullscreen mode Exit fullscreen mode

Następnie pobierz kod z chmury i uruchom go. Być może podczas oczekiwania poświęcisz trochę czasu na posłuchanie ulubionej playlisty Spotify lub ustawienie timerów dla swoich zadań. Wielozadaniowość to jedna z zalet połączonego świata!

git pull
python <Your program>.py
Enter fullscreen mode Exit fullscreen mode

Tworzenie klienta za pomocą PubNub

Następnie musimy zbudować skrypt klienta, który umożliwi korzystanie z telefonu komórkowego lub komputera do wysyłania i odbierania danych do i z naszych czujników. Wymaga to utworzenia pliku HTML, który używa przycisków do publikowania poleceń do Raspberry Pi i pól tekstowych do pobierania danych z Raspberry Pi. Można to osiągnąć za pomocą prostego skryptu HTML i dodania kilku przycisków, znaczników ID i PubNub JavaScript SDK. System ten jest wystarczająco elastyczny, aby zintegrować się z różnymi protokołami, w tym Z-Wave i ZigBee, otwierając dodatkowe obszary rozwoju.

<!DOCTYPE html>
<html>
  <body>
    <button type="button" onclick="publish('ON')">Lamp ON</button>
    <button type="button" onclick="publish('OFF')">Lamp OFF</button>
    <p id="lights">Lights are on?</p>
    <script src="https://cdn.pubnub.com/sdk/javascript/pubnub.4.20.2.js"></script>
    <script>
    var pubnub = new PubNub({
      publishKey : 'pub-c-2d8f55f6-daa7-467b-923b-6a1e6570c9fc',
      subscribeKey : 'sub-c-1575c412-2116-11e8-a7d0-2e884fd949d2',
      });
      function publish(a){
        var publishConfig = 
        {
          channel : "ch1",   //Your publishing channel name
          message : a
        };
        pubnub.publish(publishConfig, function(status, response){
          console.log(status, response);
        });
      }
Enter fullscreen mode Exit fullscreen mode

Na koniec należy nasłuchiwać kanału, na którym Raspberry Pi publikuje dane z czujnika światła. Możemy utworzyć instancję słuchacza za pomocą następującego bloku kodu:

    pubnub.addListener({
            message: function(m) {
                // handle message
                var channelName = m.channel; // The channel for which the message belongs
                var channelGroup = m.subscription; // The channel group or wildcard subscription match (if exists)
                var pubTT = m.timetoken; // Publish timetoken
                var msg = m.message; // The Payload
                var publisher = m.publisher; //The Publisher
                document.getElementById("lights").innerHTML = msg;
                console.log(msg);
            },
            presence: function(p) {
                // handle presence
                var action = p.action; // Can be join, leave, state-change or timeout
                var channelName = p.channel; // The channel for which the message belongs
                var occupancy = p.occupancy; // No. of users connected with the channel
                var state = p.state; // User State
                var channelGroup = p.subscription; //  The channel group or wildcard subscription match (if exists)
                var publishTime = p.timestamp; // Publish timetoken
                var timetoken = p.timetoken;  // Current timetoken
                var uuid = p.uuid; // UUIDs of users who are connected with the channel
            },
            status: function(s) {
                var affectedChannelGroups = s.affectedChannelGroups;
                var affectedChannels = s.affectedChannels;
                var category = s.category;
                var operation = s.operation;
            }
        });
        pubnub.subscribe({
            channels: ['ch2'],

        });
    </script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Zwróć uwagę, że zasubskrybowałeś ch2. Wynika to z faktu, że chcesz mieć dedykowany kanał dla danych z czujnika światła, aby nie musieć odróżniać danych od innych czujników. Jeśli zapomniałeś opublikować dedykowany kanał w procesie aplikacji, upewnij się, że wróciłeś i zrobiłeś to.

Po zapisaniu skryptu otwórz plik w przeglądarce internetowej i powinieneś otrzymać coś takiego:

Ukończyłeś implementację trzech prostych inteligentnych urządzeń domowych na Raspberry Pi! Przetestuj swój kod, łącząc się przez ssh z Raspberry Pi, aby uruchomić kod Pythona, a następnie wejść w interakcję z programem klienckim. Powinieneś być w stanie kontrolować swoją inteligentną lampę za pomocą dwóch przycisków, a także zobaczyć monity tekstowe, jeśli drzwi są otwarte lub światła są włączone. Udało ci się stworzyć inteligentny system domowy wykorzystujący podłączone urządzenia komunikujące się z PubNub.

Jeśli chcesz dowiedzieć się więcej o tym, jak zasilać aplikacje IoT i systemy inteligentnego domu, zapoznaj się z naszymi zasobami IoT.

W razie jakichkolwiek pytań lub wątpliwości prosimy o kontakt pod adresem devrel@pubnub.com.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .