Yeelight Lampen über einen Eigenbau-Bewegungssensor mittels HomeKit steuern

Artikel vom 20.08.2019 um 19:31


Da ich schon länger nichts mehr gepostet habe, habe ich mir überlegt, mal eine andere Art von Artikel zu schreiben. Normalerweise berichte ich hauptsächlich von der Werkstatt – da ich momentan aber nicht sehr oft die Möglichkeit dazu habe, werde ich von meiner neuen Heimautomation berichten.

Eine kleine Einführung in mein „smartes“ Zuhause

Ich habe angefangen im Internet nach Wifi-Lampen zu suchen, damit ich meine Lichter von überall steuern und auch Stehlampen unkompliziert an- und ausschalten kann. Da ich öfter in China unterwegs bin, fiel die Wahl auf die günstigen Smart Lampen von Yeelight (Yeelight Color Blub V2). Diese sollten laut Fa. Yeelight seit ca. einem Jahr HomeKit zertifiziert werden. Da mir das Warten nun aber zu lästig wurde, habe ich mir eine Homebridge mit einem Raspberry Pi eingerichtet. Raspberry Pi ist eigentlich nur ein günstiger Linux-Rechner. Homebridge ist ein NodeJS Programm auf dem Linux-Rechner, mit dem man nicht unterstützte Geräte in das Apple HomeKit einbinden kann. Anleitungen zum Einrichten des Raspberry Pi und der Homebridge gibt es bereits zahlreiche im Internet. Mir hat folgender Artikel dabei eigentlich am Besten geholfen: https://smartapfel.de/homebridge/homebridge-installieren/ Wenn einmal der Raspi und die Homebridge eingerichtet sind, können über Homebridge-Plugins unterschiedliche Geräte HomeKit kompatibel gemacht werden. Für meine Yeelights verwende ich folgendes Plugin: https://www.npmjs.com/package/homebridge-yeelight-wifi Die Homebridge wird zum HomeKit mittels QR-Code hinzugefügt. Diese Bridge stellt dann die Verbindung zu den anderen Geräten her. Nun konnte ich bereits alle meine Yeelight Lampen mit meinem HomeKit steuern. Ich habe dann gleichzeitig allen Yeelight Lampen den Internetzugang gesperrt, da ich nun nicht mehr abhängig von den Mi-Servern (Mutterkonzern von Yeelight) bin. Dabei habe ich auch gemerkt, dass quasi im 30-Sekunden-Takt von den Yeelights eine Verbindung zu folgenden Domains aufgebaut werden sollte: de.ott.io.mi.com, de.ot.io.mi.com. Da diese aber nun keinen Internetzugriff mehr haben, laufen die Anfragen der Geräte ins Leere.

Meinen eigenen Bewegungsmelder herstellen

Nach der kleinen Einführung in mein Zuhause kommen wir nun zum eigentlichen Thema dieses Artikels. Ich wollte in meinen Flur einen Bewegungsmelder einbauen, der zum einen nachts das Licht über das HomeKit ein- und ausschaltet und zum anderen, wenn niemand zu Hause ist, meldet, wenn etwas durch den Flur läuft. Das einzige Problem: Ich habe keine Steckdose im Flur. Da ich leider online keinerlei Infos zu einem batteriebetriebenen Bewegungsmelder gefunden habe, habe ich mich Stück für Stück selbst auf die Lösung gebracht. Ich habe mehrere Versionen des Bewegungsmelders gefertigt. Werde aber nur von meiner vorläufig-finalen Version berichten und an einigen Punkten auf die entstandenen Schwierigkeiten hinweisen.

Stückliste

• Ein ESP32 Development Board (der Wifi-Mircocontroller) • HC-SR501 (PIR - Bewegungssensor) • LiPo Akku 1000-2000mAh • Ladegerät für den LiPo Akku • Kunststoff-Gehäuse bzw. Abzweigdose Da ich viel rumprobiert habe und einige Versionen teste musste (über mehrere Wochen), habe ich eine relativ große Universalbox und ein Breadboard inkl. Jumper-Kabel gekauft. Diese Komponenten sind aber nicht notwendig. Ich hatte zuerst nach günstigen, WLAN-fähigen Microcontrollern im Internet gesucht. Dort habe den ESP32 gefunden und mich dann letztendlich auch für diesen entschieden. Die anfänglich vermuteten Vorteile waren für mich der Preis des ESP32 DevKits, eine geringe Betriebsspannung von 3,3V und den unschlagbar geringen Stomverbrauch im deep sleep modus (hat sich später aber anders herausgestellt). Beim Bewegungssensor habe ich den HC-SR501 verwendet. Hier steht zwar online, dass er mit einer Betriebsspannung von mindestens 5 Volt betrieben werden soll, er läuft bei mir aber auch mit 3 Volt. Es gibt auch noch eine kleinere Variante, bei dieser kann dann aber nicht die Empfindlichkeit und die Haltedauer eingestellt werden. Da ich nun dachte, dass ich eine Spannung von 3,3 Volt für den ESP32 benötige, habe ich zusätzlich noch einen DC–DC–Spannungswandler bestellt. Dieser kann Eingangsspannungen von 3 V bis 40 V in einstellbare Ausgangsspannung umwandeln. Ich habe mich dann für 4x AA Batterien (maximal 6V) als Stromversorgung entschieden. Diese werden mit einem Batteriehalter in meiner Anschlussdose befestigt. Leider habe ich im Verlauf meiner Tests gemerkt, dass die Spannungsversorgung mittels 4xAA-Batterie nicht zufriedenstellend ist. Des ESP-Chip benötigt beim Verbinden mit dem W-Lan ca. 150mA. Wenn diese von der Batterie nicht zur Verfügung gestellt werden können, startet der ESP32 neu. Daher kam ich dann gegen Ende zu der Lösung LiPo-Akkus zu verwenden. Diese haben lange hohe Spannungen und können die notwendigen Stöme für den ESP32 zur Verfügung stellen.

Grundüberlegung Kommunikation zwischen der Homebridge und dem Bewegungsmelder

Das ganze Projekt steht und fällt mit der Verbindung zwischen dem HomeKit und dem Bewegungsmelder. Zuerst wollte ich mittels TCP-Socket eine Verbindung zum Raspberry Pi herstellen, sobald eine Bewegung erkannt wird. (Dies ist technisch auch sehr einfach möglich. Das ESP32 Programm dazu kann ich gerne zur Verfügung stellen.) Ich wollte aber unbedingt eine Homekit-Implementierung haben. Daher habe ich zufällig ein Homebridge-Plugin namens „homebridge-http-webhooks“ gefunden. Dieses Plugin ermöglicht das Aufrufen einer URL um den Status von verschiedenen HomeKit-Elementen zu verändern (vielen Dank in dem Zug an den Ersteller des Plugins). In meinem Fall rufe ich eine Webseite auf, wenn die Bewegung erkannt wird:
http://ipdesraspberrypi:51828/?accessoryId=motion_sensor&state=true&batteryLevel=95
Dieses Plugin habe ich genommen und so weit abgespeckt, dass nur noch Bewegungsmelder unterstützt werden und die Batterieladung meines Sensors im HomeKit mit angezeigt wird. Es kann aber natürlich auch das Standard-Plugin „homebridge-http-webhooks“ unverändert verwendet werden (ich habe es nur verändert, da ich die Batterieladung sehen wollte). Um das Plugin selbst zu verändern:
mkdir ~/homebridge-gitRepo/
cd ~/homebridge-gitRepo/
git clone homebridge-http-webhooks
cd homebridge-http-webhooks
nano index.js
Nun sollte in einem Editor die originale index.js – Datei des Plugins angezeigt werden. Diese kann nach eigenen Bedürfnissen angepasst werden. Ich habe bei mir lediglich die Timeout-Zeit auf 120 Sekunden geändert und dann installiert. Zum Installieren des veränderten Plugins:
cd ~/homebridge-gitRepo/homebridge-http-webhooks
sudo npm install –g .
Achtung! Der Punkt ist hier gewollt und sollte so auch eingegeben werden. Das veränderte Plugin ist nun in der Homebridge installiert. Um die Änderungen zu laden, muss die Homebridge neu gestartet werden. Da meine als Service läuft starte ich die Homebridge wie folgt neu:
sudo systemctl restart homebridge

Schaltplan des Bewegungssensors

Nun komme ich zu meinen verschiedenen (Fehl-)Versuchen... Zuerst habe ich den ESP32 und den PIR-Sensor mit dem DC-DC-Wandler und 3,3V Betrieben. Der ESP32 war so lange im deep sleep Modus, bis der PIR-Sensor eine Bewegung erkannt hat. Falls ein Signal von PIR Sensor über (OUT) an den ESP32 gekommen ist, hat der PIR Sensor die Bewegung an den RaspberryPi weiter gegeben. Es hat alles auch relativ stabil funktioniert, jedoch waren die Batterien innerhalb von ca. 2-3 Tagen leer. Nun dachte ich, dass der PIR Sensor zu viel Strom verbraucht. Also habe ich versucht diesen tagsüber auszuschalten. Ich habe in meine Schaltung also ein FlipFlop-Glied mit eingebaut, welches den PIR Sensor nur nachts über einen Transitor bestromt. Der ESP32 war dann tagsüber bis zum Sonnenuntergang im deep sleep modus (großer Aufwand). Da ich mir dabei relativ sicher war, habe ich mir auch eine Leiterplatte (PCB-Board) selbst erstellt. Alles hat auch wieder funktioniert - jedoch war die Batterie dann wieder innerhalb ein paar Tage leer. Ich habe dann also nochmal alles vermessen und dabei festgestellt, das mein ESP32 Development Board im deep sleep modus deutlich zu viel Energie verbraucht. Dies kann auch in diversen Foren nachgelesen werden - mein ESP32 "frisst" ca. 10mA im deep sleep (1000 - mal mehr als der ESP32 im Datenblatt angegeben ist). Nach Recheren habe ich herausgefunden, dass der AMS-Chip und der USB-To-UART chip daran Schuld haben und diese die ganze Zeit mit Strom versogt werden. Nach einer weiteren Runde grübeln kam ich dann letztendlich auf eine akzeptable Lösung für mein Problem: (Beim Schaltplan ist auf die richtige Pin-Belegung des DevKits zu achten und welcher Pin in dem Micro-Controller-Programm abgefragt wird) Mein PIR-Sensor, der HC-SR501, verbraucht im Idle ca. 10 uA Strom. Wenn dieser eine Bewegung erkennt ca. 30uA. Deshalb habe ich mich dazu entschlossen, dass der PIR-Sensor den ESP32 über einen Transitor Strom gibt, sobald dieser eine Bewegung meldet. Damit "frisst" das ESP32 DevKit keinen Strom mehr, wenn keine Bewegung erkannt wird. Die Trigger-Zeit (Zeit, wie lange der PIR-Sensor ein positives OUT-Signal Liefert) muss nun realtiv hoch gewählt werden - mein PIR-Sensor bleibt für ca. 80 Sekunden "HIGH". Das heißt der ESP32 muss innerhalb der 80 Sekunden sein gesamtes Programm abgeschlossen haben. Ich habe mir dann für diese einfache Verkabelung eine Leiterplatte gebaut. Das PCB-Layout sah wie folgt aus: Ich musste nun lediglich noch die Komponenten auf das Board drauf löten. Ich habe einen 100kOhm und einen 68kOhm Widerstand eingesetzt, um die Batteriespannung von 7,4V auf 3V zu teilen, damit der ESP32 diese Spannung auslesen und an das HomeKit weitergeben kann. Zum Schalten des Development Boards habe ich einen MOSFET-Transistor verbaut. Die Stromversorgung des ESP32 und des PIR-Sensors wird nun direkt über die 7,4V-Spannung des LiPo Akkus gewährleistet, da der DC-DC-Wandler auch kontinuierlich ca. 10mA Strom verbraucht. Mit diesen neuen Komponenten habe ich nun eine errechnete Laufzeit des Bewegungsmelders eine Laufzeit von 200 Tagen (bei 150 Aktivierungen pro Tag). Die fertig geätzte Leiterplatte sah dann wie folgt aus (hier auf dem Bild rechts ist auch eine zweite Leiterplatte zu sehen, welche ich für einen ESP32 Cam-Modul erstellt habe):

ESP32 programmieren

Der ESP32 Microcontroller muss noch gelernt bekommen, was er zu tun hat. Wir wollen nun, dass der ESP32 sofort nach dem Einschalten eine Bewegung an den RaspberryPi meldet. Des Weiteren will ich wissen, wie die Eingangsspannung vom ESP32 Board und des PIR-Sensors sind. Außerdem habe ich nachträglich noch eine Routine eingebracht, die auf Firmwareupdates des ESP32 bei meinem RaspberryPi prüft (FOTA - Firmware Over The Air update). Damit kann ich eine neues Firmware-Version auf meinen RaspberryPi laden und diese wird beim der nächsten Bewegungsmeldung heruntergeladen und installiert (geflasht). Die Infos soll der Microcontroller im Fall eines Erkennens einer Bewegung an den RaspberryPi mittels Wifi weiter geben. Der Pin G15 misst bei mir die Eingangsspannung mit Hilfe des 100k/68k Ohm Spannungsteilers.
!
Ich habe gemerkt, dass bei manchen Boards der GND Anschluss direkt neben dem 5V Anschluss nicht funktioniert. Dies ist anscheinend ein Druckfehler und sollte CMD heißen. Außerdem kann jedes Dev-Board unterschiedliche Pinbelegungen haben. Hier ist vor der Schaltungserstellung darauf zu achten und dies zu überprüfen.
Dabei kam nun folgender Source Code raus, welcher mittels des Programms „arduino ide“ auf den ESP32 gespielt werden kann.
#include <WiFi.h>
#include <HTTPClient.h>
#include <Arduino.h> 

#define BAUD_RATE 115200

const char * ssid = "FRITZ!Box";
const char * password = "wlan-passwort";
const char * server = "IP_VOM_RASPI:51828";
int BatteryLevel;

void setup() {

  Serial.begin(BAUD_RATE);
  Serial.println("Reading the current Voltage: ");

  float VBattery = 168.0f/68.0f * 3.3f * float(measureADC(15)) / 4096.0f;
  BatteryLevel = (int)( ((VBattery-5.9f) / 1.5f)*100 );
  
  Serial.print("Battery Voltage = "); Serial.print(VBattery, 2); Serial.println(" V = " + String(BatteryLevel) + "%"); 
  
  Serial.println("Motion detected");

  // Starting the WiFi client 
  WiFiClient client;
  
  // Connecting to WiFi 
  Serial.print("Wifi tries to connect.");
  WiFi.begin(ssid, password);

  int n = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(20);
    Serial.print(".");
    n = n + 1;
    if ( n > 200 ) {
      gotoSleep();
    }
  }
  Serial.println(".");
  Serial.println("Wifi sucessfully connected!");
  
  Serial.println("Trying to set the HomeKit motion");

  // Setting up the HTTP request
  HTTPClient http;
  http.begin("http://" + String(server) + "/?accessoryId=motion_sensor&state=true&batteryLevel=" + String(BatteryLevel));
  int httpCode = http.GET();

  if (httpCode > 0) {
    String payload = http.getString();

    // HTTP request succeeded
    Serial.println("Connected to server");
    Serial.println("The following string was returned from server: " + payload);

  } else {
    Serial.println("Error on HTTP request..");
  }
  http.end();

  // checkForUpdates();
  // Eine Funktion fürs Installieren von Firmware Over-The-Air über meinen eigenen Server
  
  gotoSleep();
}

int measureADC(int PIN) {
  // Measure the batteryVoltage 5 times with 100ms delay to verify the result
  int j = 0;
  int measure = 0;
  
  while(j < 5) {
    delay(100);
    j = j+1;
    measure = measure + analogRead(PIN);
  }

  measure = measure/5;
  return measure;
}

void loop() {
  // The program should never reach this loop
}

void gotoSleep() {
  Serial.println("Deep sleep mode enabled");
  esp_deep_sleep_start();
}

void sleepFor(int secounds) {
  Serial.println("Sleeping for " + String(secounds) + " secounds");
  uint64_t sleeptime = UINT64_C(secounds * 1000000);
  esp_sleep_enable_timer_wakeup(sleeptime);
  esp_deep_sleep_start();
}
Der ESP32 wird einfach mittels Micro-USB Kabel an den Computer angeschlossen und geflasht. Eine gute Beschreibung, wie man den ESP32 flashen kann, ist hier zu finden: https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-mac-and-linux-instructions/ Ist das Gerät mit der Homebridge gekoppelt und der Bewegungssensor eingerichtet kann alles in der Home-App getestet werden (der Bewegungssensor sollte bereits nach dem Einrichten der Homebridge und dem Installieren der Plugins in der Home-App auftauchen). Der batteriebetriebene Bewegungsmelder kann überall dort verwendet werden, wo eben kein Strom zur Verfügung ist und man auch kein Strom verlegen will. Ich könnte mir vorstellen, dass der Sensor (so lange er Verbindung zum Wifi bekommen kann) auch draußen als Bewegungsmelder Verwendung finden kann (zum Beispiel Kellertreppe hinter dem Haus, Gartenhütte, etc..). Die Zeit zwischen der tatsächlichen Bewegung (PIR Sensor löst Bewegungmeldung aus) und bis ich eine Benachrichtigung auf dem Handy erhalten bzw. bis das Licht an geht dauert bei mir ca. 1,8 - 2,5 Sekunden. Ich habe den Bewegungsmelder so im HomeKit eingestellt, dass er alle Handys bei Bewegung benachrichtigt, falls niemand zu Hause ist. Wenn nachts (Sonnenunter- bis Sonnenaufgang) Bewegung erkannt wird, geht das Flurlicht für zwei Minuten an, danach wieder für zwei Minuten aus. Ich habe bereits zwei weitere Sensoren hergestellt. Einer ist zusätzlich mit einer Kamera ausgestattet (ESP32 Cam), welcher bei einer Bewegung mittels HTTPS-Post ein Bild auf meinen Server lädt, und ein anderer, der die Yeelights mittels TCP-Paket (ohne Homekit) aktiviert. Falls Interesse besteht, kann ich dazu und von dem OTA-Update den Quellcode gerne teilen. Ich hoffe der etwas ungewöhnliche Artikel hat euch trotzdem gefallen und wünsche natürlich viel Spaß beim Nachbauen. Ich werde berichten, falls ich genau weiß, wie lange die Batterie des Bewegungsmelders hält und wenn ich weitere Versionen fertig habe.
!
Ich übernehme keine Garantie für Richtigkeit oder Funktion der Verkabelung und Programme. Die Benutzung erfolgt auf eigene Verantwortung!


Verfassen Sie einen Kommentar zu diesem Artikel:


Um einen Kommentar verfassen zu können, müssen sie der Speicherung von Cookies zustimmen.
Ich stimme zu, dass Cookies gespeichert werden.