[PYTHON] Cospas stärkste IoT-Haushaltsgeräte! Betreiben Sie TPLink-Produkte von Raspberry Pi

Was ist TPLink?

Ein Hersteller von Netzwerkgeräten in Shenzhen, China, dessen Hauptgeschäft Router sind. In den letzten Jahren haben wir uns auf IoT-Haushaltsgeräte wie intelligente Glühbirnen und intelligente Stecker konzentriert und aufgrund der guten Kostenleistung eine einzigartige Position bei Amazon aufgebaut.

plug.jpg [Smart Plug HS105](https://www.amazon.co.jp/Alexa%E8%AA%8D%E5%AE%9A%E5%8F%96%E5%BE%97%E8%A3%BD % E5% 93% 81% E3% 80% 91-% E7% 9B% B4% E5% B7% AE% E3% 81% 97% E3% 82% B3% E3% 83% B3% E3% 82% BB% E3% 83% B3% E3% 83% 88-Google% E3% 83% 9B% E3% 83% BC% E3% 83% A0% E5% AF% BE% E5% BF% 9C-% E9% 9F% B3 % E5% A3% B0% E3% 82% B3% E3% 83% B3% E3% 83% 88% E3% 83% AD% E3% 83% BC% E3% 83% AB-HS105 / dp / B078HSBNMT? Ref_ = ast_sto_dp)

bulb.jpg [Intelligente Glühbirne KL110](https://www.amazon.co.jp/%E3%80%90Amazon-Alexa%E8%AA%8D%E5%AE%9A-%E3%80%91TP-Link-KL110] -Google / dp / B07GC4JR83? Ref_ = ast_sto_dp & th = 1)

Diesmal mit der API, ・ EIN / AUS-Betrieb des Geräts ・ Erfassung von Informationen wie EIN-AUS und Helligkeit von Glühbirnen Ich habe versucht, es in Python und Node.js auszuführen

Da das oben Genannte viele der Anwendungen abdecken kann, die als IoT-Haushaltsgeräte betrachtet werden können. ** Das Ergebnis des Gefühls der Möglichkeit der Anwendung **!

Dinge notwendig

** ・ PC ** ** ・ Himbeer Pi ** ** ・ TPLink Smart Plug oder Glühbirne ** Diesmal habe ich die folgenden 3 Produkte ausprobiert HS105: Smart Plug KL110: Weiße Glühbirne KL130: Farbbirne

① Bestätigung der Datenerfassung

Testen Sie zunächst auf dem Terminal, ob Daten von TPLink abgerufen werden können.

Überprüfen Sie die IP

Installieren Sie tplink-smarthome-api (Referenz)

sudo npm install -g tplink-smarthome-api

Rufen Sie mit dem folgenden Befehl eine Liste der verbundenen TPLink-Geräte ab

tplink-smarthome-api search
HS105(JP) plug IOT.SMARTPLUGSWITCH 192.168.0.101 9999 B0BE76 ‥ Smart Plug
KL110(JP) bulb IOT.SMARTBULB 192.168.0.102 9999 98DAC4 ‥ Weiße Glühbirne
KL130(JP) bulb IOT.SMARTBULB 192.168.0.103 9999 0C8063 ‥ Farbglühbirne

Sie können sehen, dass alle drei Geräte erkannt wurden

Bestätigung der Erfassung von Gerätebetriebsinformationen

Sie können Geräteeinstellungen und OnOff mit dem folgenden Befehl abrufen

tplink-smarthome-api getSysInfo [IP-Adresse des Geräts]:9999

** ・ Beispiel für KL130 (Farbbirne) **

  :
  ctrl_protocols: { name: 'Linkie', version: '1.0' },
↓ Hier sind die Geräteeinstellungen
  light_state: {
    on_off: 1,
    mode: 'normal',
    hue: 0,
    saturation: 0,
    color_temp: 2700,
    brightness: 100
  },
↑ Dies ist die Geräteeinstellung
  is_dimmable: 1,
  is_color: 1,
  :

on_off: 0 bedeutet Ausschalten, 1 bedeutet Einschalten Farbton: Farbe? (0 im Weißmodus) color_temp: Farbtemperatur (0, wenn nicht im Weißmodus) Helligkeit: Helligkeit (in%) Scheint zu sein

** ・ Beispiel für KL110 (weiße Glühbirne) **

  :
  ctrl_protocols: { name: 'Linkie', version: '1.0' },
↓ Hier sind die Geräteeinstellungen
  light_state: {
    on_off: 1,
    mode: 'normal',
    hue: 0,
    saturation: 0,
    color_temp: 2700,
    brightness: 100
  },
↑ Dies ist die Geräteeinstellung
  is_dimmable: 1,
  is_color: 0,
  :

on_off: 0 bedeutet Ausschalten, 1 bedeutet Einschalten Farbton: Farbton (0 im Weißmodus) Sättigung: Sättigung color_temp: Farbtemperatur (0, wenn nicht im Weißmodus) Helligkeit: Helligkeit (in%) Es scheint, dass. Es ist fast das gleiche wie KL130, aber es ist keine Farbe, also scheint es is_color: 0 zu sein.

** ・ Beispiel für KL105 (Smart Plug) **

  alias: '',
↓ Hier sind die Geräteeinstellungen
  relay_state: 1,
  on_time: 288,
  active_mode: 'none',
  feature: 'TIM',
  updating: 0,
  icon_hash: '',
  rssi: -52,
  led_off: 0,
  longitude_i: 1356352,
  latitude_i: 348422,
↑ Dies ist die Geräteeinstellung
  hwId: '047D‥',

relay_state: 0 bedeutet Ausschalten, 1 bedeutet Einschalten on_time: Kontinuierliche Einschaltzeit rssi: WiFi-Signalstärke Es scheint, dass. Der Logitude und der Breitengrad werden ebenfalls angezeigt, aber das Rätsel vertieft sich, wenn es 5 km vom tatsächlichen Standort entfernt ist.

Oben können Sie mit dem Befehl bestätigen, dass Sie die gewünschten Informationen erhalten können! In den folgenden Kapiteln wird beschrieben, wie Sie das Programm (Node.js & Python) abrufen und bedienen.

② Status mit Node.js abrufen

** * Wenn Sie Node.js nicht erklären müssen, weil Sie Python verwenden, überspringen Sie dieses Kapitel und gehen Sie zu ③ **

Informationen zu Node.js finden Sie unter hier

Übergeben Sie den Pfad an npm (für Fenster)

Unter Windows wird der Pfad nicht an das globale Installationsziel von npm übergeben, und das Modul kann nicht mit Node.js geladen werden. Übergeben Sie ihn daher bitte anhand der folgenden Informationen https://qiita.com/shiftsphere/items/5610f692899796b03f99

Übergeben Sie den Pfad an npm (für Raspberry Pi)

Verwenden Sie den folgenden Befehl, um herauszufinden, wo das npm-Modul global installiert werden kann. (Aus irgendeinem Grund scheint es sich von dem Ordner zu unterscheiden, den der Befehl "npm bin -g" in Windows gefunden hat.)

npm ls -g 

Bearbeiten Sie .profile mit dem folgenden Befehl.

nano /home/[Nutzername]/.profile

Fügen Sie die folgende Zeile am Ende von .profile hinzu und starten Sie den Computer neu

export NODE_PATH=[Der oben untersuchte Weg]/node_modules

Wenn der durch den folgenden Befehl angegebene Pfad angezeigt wird, ist er erfolgreich.

printenv NODE_PATH

Erstellen eines node.js-Skripts

Erstellen Sie das folgende Skript

tplink_test.js


const { Client } = require('tplink-smarthome-api');
const client = new Client();
client.getDevice({ host: '192.168.0.102' }).then(device => {
  device.getSysInfo().then(console.log);
});

Wenn Sie das Skript mit dem folgenden Befehl ausführen, können Sie verschiedene Informationen auf dieselbe Weise wie mit ① abrufen.

node tplink_test.js

③ Status mit Python abrufen

Das Anmelden bei Node.js hat aufgrund mangelnder JavaScript-Kenntnisse nicht funktioniert Ich habe meine Gedanken wiedererlangt und ein Skript erstellt, um mit Python zu arbeiten und mich zu protokollieren.

Python hatte Probleme, weil ich kein so höfliches Dokument wie Node.js finden konnte, aber hier und hier Ich habe den Code entschlüsselt (tplink-lb130-api / blob / master / lb130.py) und das Skript erstellt.

Erstellen einer TPLink-Operationsklasse

Oben Ich habe die folgenden 4 Klassen unter Bezugnahme auf den Code erstellt. ** TPLink_Common (): Klasse allgemeiner Funktionen für Stecker und Glühbirnen ** ** TPLink_Plug (): Nur-Plug-Funktionsklasse ** (erbt TPLink_Common ()) ** TPLink_Bulb (): Nur Glühbirnen-Funktionsklasse ** (erbt TPLink_Common ()) ** GetTPLinkData (): Eine Klasse zum Abrufen von Daten mit der obigen Klasse **

tplink.py


import socket
from struct import pack
import json

#TPLink-Datenerfassungsklasse
class GetTPLinkData():
    #Methode zum Abrufen von Plug-Daten
    def get_plug_data(self, ip):
        #Erstellen einer Klasse für den Plug-Betrieb
        plg = TPLink_Plug(ip)
        #Daten abrufen und in Dikt konvertieren
        rjson = plg.info()
        rdict = json.loads(rjson)
        return rdict

    #Methode zur Erfassung von Glühbirnen-Daten
    def get_bulb_data(self, ip):
        #Erstellen einer Klasse zum Betreiben einer Glühbirne
        blb = TPLink_Bulb(ip)
        #Daten abrufen und in Dikt konvertieren
        rjson = blb.info()
        rdict = json.loads(rjson)
        return rdict

#TPLink Glühbirne & Stecker gemeinsame Klasse
class TPLink_Common():
    def __init__(self, ip, port=9999):
        """Default constructor
        """
        self.__ip = ip
        self.__port = port
    
    def info(self):
        cmd = '{"system":{"get_sysinfo":{}}}'
        receive = self.send_command(cmd)
        return receive
    
    def send_command(self, cmd, timeout=10):
        try:
            sock_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock_tcp.settimeout(timeout)
            sock_tcp.connect((self.__ip, self.__port))
            sock_tcp.settimeout(None)
            sock_tcp.send(self.encrypt(cmd))
            data = sock_tcp.recv(2048)
            sock_tcp.close()

            decrypted = self.decrypt(data[4:])
            print("Sent:     ", cmd)
            print("Received: ", decrypted)
            return decrypted

        except socket.error:
            quit("Could not connect to host " + self.__ip + ":" + str(self.__port))
            return None

    def encrypt(self, string):
        key = 171
        result = pack('>I', len(string))
        for i in string:
            a = key ^ ord(i)
            key = a
            result += bytes([a])
        return result

    def decrypt(self, string):
        key = 171
        result = ""
        for i in string:
            a = key ^ i
            key = i
            result += chr(a)
        return result

#TPLink-Stecker-Betriebsklasse
class TPLink_Plug(TPLink_Common):
    def on(self):
        cmd = '{"system":{"set_relay_state":{"state":1}}}'
        receive = self.send_command(cmd)

    def off(self):
        cmd = '{"system":{"set_relay_state":{"state":0}}}'
        receive = self.send_command(cmd)

    def ledon(self):
        cmd = '{"system":{"set_led_off":{"off":0}}}'
        receive = self.send_command(cmd)

    def ledoff(self):
        cmd = '{"system":{"set_led_off":{"off":1}}}'
        receive = self.send_command(cmd)
    
    def set_countdown_on(self, delay):
        cmd = '{"count_down":{"add_rule":{"enable":1,"delay":' + str(delay) +',"act":1,"name":"turn on"}}}'
        receive = self.send_command(cmd)

    def set_countdown_off(self, delay):
        cmd = '{"count_down":{"add_rule":{"enable":1,"delay":' + str(delay) +',"act":0,"name":"turn off"}}}'
        receive = self.send_command(cmd)
    
    def delete_countdown_table(self):
        cmd = '{"count_down":{"delete_all_rules":null}}'
        receive = self.send_command(cmd)

    def energy(self):
        cmd = '{"emeter":{"get_realtime":{}}}'
        receive = self.send_command(cmd)
        return receive

#Betriebsklasse der TPLink-Glühbirne
class TPLink_Bulb(TPLink_Common):
    def on(self):
        cmd = '{"smartlife.iot.smartbulb.lightingservice":{"transition_light_state":{"on_off":1}}}'
        receive = self.send_command(cmd)

    def off(self):
        cmd = '{"smartlife.iot.smartbulb.lightingservice":{"transition_light_state":{"on_off":0}}}'
        receive = self.send_command(cmd)

    def transition_light_state(self, hue: int = None, saturation: int = None, brightness: int = None,
                               color_temp: int = None, on_off: bool = None, transition_period: int = None,
                               mode: str = None, ignore_default: bool = None):
        # copy all given argument name-value pairs as a dict
        d = {k: v for k, v in locals().items() if k is not 'self' and v is not None}
        r = {
            'smartlife.iot.smartbulb.lightingservice': {
                'transition_light_state': d
            }
        }
        cmd = json.dumps(r)
        receive = self.send_command(cmd)
        print(receive)

    def brightness(self, brightness):
        self.transition_light_state(brightness=brightness)

    def purple(self, brightness = None, transition_period = None):
        self.transition_light_state(hue=277, saturation=86, color_temp=0, brightness=brightness, transition_period=transition_period)

    def blue(self, brightness = None, transition_period = None):
        self.transition_light_state(hue=240, saturation=100, color_temp=0, brightness=brightness, transition_period=transition_period)

    def cyan(self, brightness = None, transition_period = None):
        self.transition_light_state(hue=180, saturation=100, color_temp=0, brightness=brightness, transition_period=transition_period)

    def green(self, brightness = None, transition_period = None):
        self.transition_light_state(hue=120, saturation=100, color_temp=0, brightness=brightness, transition_period=transition_period)
    
    def yellow(self, brightness = None, transition_period = None):
        self.transition_light_state(hue=60, saturation=100, color_temp=0, brightness=brightness, transition_period=transition_period)

    def orange(self, brightness = None, transition_period = None):
        self.transition_light_state(hue=39, saturation=100, color_temp=0, brightness=brightness, transition_period=transition_period)
    
    def red(self, brightness = None, transition_period = None):
        self.transition_light_state(hue=0, saturation=100, color_temp=0, brightness=brightness, transition_period=transition_period)
    
    def lamp_color(self, brightness = None):
        self.transition_light_state(color_temp=2700, brightness=brightness)

Ausführen der TPLink-Operationsklasse

Die obige Klasse kann wie folgt für Python-Code ausgeführt werden

** ・ Wenn Sie die Glühbirne einschalten möchten **

TPLink_Bulb(IP-Adresse der Glühbirne).on()

** ・ Wenn Sie den Stecker ausschalten möchten **

TPLink_Plug(IP-Adresse des Steckers).off()

** ・ Wenn Sie den Stecker nach 10 Sekunden einschalten möchten **

TPLink_Plug(IP-Adresse des Steckers).set_countdown_on(10)

** ・ Wenn Sie die Helligkeit der Glühbirne auf 10% erhöhen möchten **

TPLink_Bulb(IP-Adresse der Glühbirne).brightness(10)

** ・ Wenn Sie die Glühbirne rot machen möchten (nur Farbglühbirne) **

TPLink_Bulb(IP-Adresse der Glühbirne).red()

** ・ Informationen wie Ein- und Ausschalten der Glühbirne abrufen **

info = GetTPLinkData().get_plug_data(IP-Adresse des Steckers)

④ Erstellung eines Python-Skripts für die Protokollierung

Mit der letzten Methode im vorherigen Kapitel habe ich ein Skript erstellt, das Informationen zu Glühbirnen und Steckern protokolliert. Die Struktur des Skripts lautet [hier](https://qiita.com/c60evaporator/items/283d0569eba58830f86e#%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%B9%E3%82 Dies entspricht% AF% E3% 83% AA% E3% 83% 97% E3% 83% 88% E4% BD% 9C% E6% 88% 90). Bitte lesen Sie den Link.

Einstellungsdatei

[Hier](https://qiita.com/c60evaporator/items/283d0569eba58830f86e#%E8%A8%AD%E5%AE%9A%E3%83%95%E3%82%A1%E3%82%A4%E3 Wie beim Artikel% 83% AB) haben wir die folgenden zwei Arten von Einstellungsdateien zur einfacheren Verwaltung erstellt. -DeviceList.csv: Beschreiben Sie die erforderlichen Informationen für jeden Sensor

DeviceList.csv
ApplianceName,ApplianceType,IP,Retry
TPLink_KL130_ColorBulb_1,TPLink_ColorBulb,192.168.0.103,2
TPLink_KL110_WhiteBulb_1,TPLink_WhiteBulb,192.168.0.102,2
TPLink_HS105_Plug_1,TPLink_Plug,192.168.0.101,2

Die Bedeutung der Spalten ist wie folgt ApplianceName: Verwalten Sie Gerätenamen und identifizieren Sie mehrere Geräte desselben Typs ApplianceType: Gerätetyp. TPLink_ColorBulb: Farbbirne (KL130 usw.) TPLink_WhiteBulb: Weiße Glühbirne (KL110 usw.) TPLink_Plug: Smart Plug (HS105 usw.) IP: IP-Adresse des Geräts Wiederholen: Maximale Anzahl von Neuausführungen Details (Anzahl der erneuten Ausführungen, wenn die Erfassung fehlschlägt, Details [hier](https://qiita.com/c60evaporator/items/283d0569eba58830f86e#%E4%B8%8D%E5%85%B7%E5] % 90% 881peripheral% E3% 81% AE% E5% 88% 9D% E6% 9C% 9F% E5% 8C% 96% E6% 99% 82% E3% 81% AB% E3% 82% A8% E3% 83 % A9% E3% 83% BC% E3% 81% 8C% E5% 87% BA% E3% 82% 8B))

-Config.ini: Geben Sie das CSV- und Protokollausgabeverzeichnis an

config.ini [Path] CSVOutput = /share/Data/Appliance LogOutput = /share/Log/Appliance Wenn beide in einem von samba erstellten freigegebenen Ordner ausgegeben werden, ist es bequem, von außerhalb des Raspberry Pi darauf zuzugreifen.

Aktuelles Skript

appliance_data_logger.py


from tplink import GetTPLinkData
import logging
from datetime import datetime, timedelta
import os
import csv
import configparser
import pandas as pd

#Globale Variablen
global masterdate

######TPLink-Datenerfassung######
def getdata_tplink(appliance):
    #Maximale Zufriedenheit, wenn kein Datenwert verfügbar ist.Wiederholen Wiederholen Sie den Scan
    for i in range(appliance.Retry):
        try:
            #Beim Einstecken
            if appliance.ApplianceType == 'TPLink_Plug':
                applianceValue = GetTPLinkData().get_plug_data(appliance.IP)
            #Wenn es eine Glühbirne ist
            elif appliance.ApplianceType == 'TPLink_ColorBulb' or appliance.ApplianceType == 'TPLink_WhiteBulb':
                applianceValue = GetTPLinkData().get_bulb_data(appliance.IP)
            else:
                applianceValue = None
        #Protokollausgabe, wenn ein Fehler auftritt
        except:
            logging.warning(f'retry to get data [loop{str(i)}, date{str(masterdate)}, appliance{appliance.ApplianceName}]')
            applianceValue = None
            continue
        else:
            break
    
    #Wenn der Wert erhalten werden kann, speichern Sie die POST-Daten in dict
    if applianceValue is not None:
        #Beim Einstecken
        if appliance.ApplianceType == 'TPLink_Plug':
            data = {        
                'ApplianceName': appliance.ApplianceName,        
                'Date_Master': str(masterdate),
                'Date': str(datetime.today()),
                'IsOn': str(applianceValue['system']['get_sysinfo']['relay_state']),
                'OnTime': str(applianceValue['system']['get_sysinfo']['on_time'])
            }
        #Wenn es eine Glühbirne ist
        else:
            data = {        
                'ApplianceName': appliance.ApplianceName,        
                'Date_Master': str(masterdate),
                'Date': str(datetime.today()),
                'IsOn': str(applianceValue['system']['get_sysinfo']['light_state']['on_off']),
                'Color': str(applianceValue['system']['get_sysinfo']['light_state']['hue']),
                'ColorTemp': str(applianceValue['system']['get_sysinfo']['light_state']['color_temp']),
                'Brightness': str(applianceValue['system']['get_sysinfo']['light_state']['brightness'])
            }
        return data
        
    #Wenn es nicht erhalten werden konnte, protokollieren Sie die Ausgabe
    else:
        logging.error(f'cannot get data [loop{str(appliance.Retry)}, date{str(masterdate)}, appliance{appliance.ApplianceName}]')
        return None

######CSV-Ausgabe von Daten######
def output_csv(data, csvpath):
    appliancename = data['ApplianceName']
    monthstr = masterdate.strftime('%Y%m')
    #Name des Ausgabeordnerordners
    outdir = f'{csvpath}/{appliancename}/{masterdate.year}'
    #Wenn der Ausgabezielordner nicht vorhanden ist, erstellen Sie einen neuen
    os.makedirs(outdir, exist_ok=True)
    #Pfad der Ausgabedatei
    outpath = f'{outdir}/{appliancename}_{monthstr}.csv'
    
    #Erstellen Sie eine neue Ausgabedatei, wenn diese nicht vorhanden ist
    if not os.path.exists(outpath):        
        with open(outpath, 'w', newline="") as f:
            writer = csv.DictWriter(f, data.keys())
            writer.writeheader()
            writer.writerow(data)
    #Fügen Sie eine Zeile hinzu, wenn die Ausgabedatei vorhanden ist
    else:
        with open(outpath, 'a', newline="") as f:
            writer = csv.DictWriter(f, data.keys())
            writer.writerow(data)

######Maine######
if __name__ == '__main__':    
    #Startzeit bekommen
    startdate = datetime.today()
    #Runden Sie die Startzeit in Minuten ab
    masterdate = startdate.replace(second=0, microsecond=0)   
    if startdate.second >= 30:
        masterdate += timedelta(minutes=1)

    #Konfigurationsdatei und Geräteliste lesen
    cfg = configparser.ConfigParser()
    cfg.read('./config.ini', encoding='utf-8')
    df_appliancelist = pd.read_csv('./ApplianceList.csv')
    #Gesamtzahl der Sensoren und erfolgreiche Datenerfassung
    appliance_num = len(df_appliancelist)
    success_num = 0

    #Protokollinitialisierung
    logname = f"/appliancelog_{str(masterdate.strftime('%y%m%d'))}.log"
    logging.basicConfig(filename=cfg['Path']['LogOutput'] + logname, level=logging.INFO)

    #Diktat für das Speichern aller erfassten Daten
    all_values_dict = None

    ######Datenerfassung für jedes Gerät######
    for appliance in df_appliancelist.itertuples():
        #Stellen Sie sicher, dass der Appliance-Typ TPLinke ist
        if appliance.ApplianceType in ['TPLink_Plug','TPLink_ColorBulb','TPLink_WhiteBulb']:
            data = getdata_tplink(appliance)
        #Andere als die oben genannten
        else:
            data = None        

        #Wenn Daten vorhanden sind, fügen Sie sie zu Dict hinzu, um alle Daten zu speichern und CSV auszugeben
        if data is not None:
            #all_values_Erstellen Sie ein neues Wörterbuch, wenn dict Keine ist
            if all_values_dict is None:
                all_values_dict = {data['ApplianceName']: data}
            #all_values_Zum vorhandenen Wörterbuch hinzufügen, wenn dict nicht None ist
            else:
                all_values_dict[data['ApplianceName']] = data

            #CSV-Ausgabe
            output_csv(data, cfg['Path']['CSVOutput'])
            #Erfolgszahl plus
            success_num+=1

    #Protokollausgabe des Verarbeitungsende
    logging.info(f'[masterdate{str(masterdate)} startdate{str(startdate)} enddate{str(datetime.today())} success{str(success_num)}/{str(appliance_num)}]')

Wenn Sie die oben genannten Schritte ausführen, werden die erfassten Daten in CSV mit dem Gerätenamen sowie dem Namen von Datum und Uhrzeit in dem in der Einstellungsdatei "CSVOutput" angegebenen Ordner ausgegeben. tplinkcsv.png

Damit ist die Informationserfassung abgeschlossen.

abschließend

Es läuft 24 Stunden am Tag auf RaspberrypPi und Python hat mehr Freiheit als IFTTT, sodass Sie verschiedene Ideen verkörpern können. ・ Kombiniert mit einem menschlichen Sensor, um beim Betreten einer Person Strom einzuschalten ・ Schalten Sie das Licht aus, wenn 30 Minuten oder länger keine Personen anwesend sind ・ Schaltet die Helligkeit der Glühbirne je nach Person automatisch um Und so weiter.

Ich habe einige Dinge, die ich machen möchte, also werde ich wieder darüber schreiben, wenn die Produktion abgeschlossen ist.

Recommended Posts

Cospas stärkste IoT-Haushaltsgeräte! Betreiben Sie TPLink-Produkte von Raspberry Pi
So bedienen Sie IOT-Haushaltsgeräte von Siri aus einfach durch API-Hacking
Senden Sie Daten von Raspberry Pi mit AWS IOT
Lassen Sie uns mit VPN (WireGuard) von außerhalb Ihres Hauses auf Ihren Home Rasp Pie zugreifen.
Verbinden Sie SORACOM mit Haushaltsgeräten und LINE Bot [Python / Flask / Raspberry Pi]
Ausgabe von Raspberry Pi an Line