HomeKit bekommt einen WLAN Binärsensor

HomeKit bekommt einen WLAN Binärsensor, den müssen wir uns aber leider selber basteln!

HomeKit bekommt einen WLAN Binärsensor
HomeKit bekommt einen WLAN Binärsensor

Ich benötige diesen Binärsensor für eine Integration meiner ABUS Terxon Alarmanlage an HomeKit. Dazu benutze ich folgende Dinge:

D1 mini verkabeln

Damit wir zwei Zustände übertragen können (“Aktiv/Inaktiv” und “Alarm ausgelöst”) benötigen wir zwei Taster-Anschlüsse am D1 mini. Diese habe ich an D1 und D2 verbunden. Das Bild unten zeigt das Beispielschema für einen Taster:

Homebridge Konfigurieren

Damit wir die Informationen des D1 mini in HomeKit sehen können, müssen wir einen Homebridge Server installieren. Hier gibt es ein Beispiel dafür auf einer Synology NAS. Es gibt aber auch andere Möglichkeiten, zum Beispiel auf einem Raspberry Pi.

Hier gib es ein Beispiel wie das Plugin in Homebridge installiert und konfiguriert wird.

In Homebridge benutzen wir das Plugin “homebridge-http-webhooks” und richten dort in den Einstellungen ein “Security” Gerät ein. Als “id” benutze ich in meinem Beispiel “alarmanlage”. Der “Name” ist frei wählbar und wird dann in HomeKit so angezeigt.

D1 mini programmieren

Hier erfahrt ihr wie ihr den D1 mini programmieren könnt.

Ich habe einen Sketch geschrieben der die zwei Binärsensoren an D1 und D2 ausliest und in ein “Security” Gerät von HomeKit konvertiert. Der D1 mini liest also D1 und D2 aus und sendet dann einen HTTP Request and Homebridge.

Hier gibt es den Sketch bei Github in einer aktuellen Version.

Alles was in dem Bereich EINSTELLUNGEN steht muss von euch konfiguriert werden.

(Letzte Aktualisierung des Scripts am 10.06.2021)

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>


// ########### EINSTELLUNGEN #################
// WLAN Einstellungen
const char* ssid = "SSID";
const char* password = "PASSWORT";

// Hombebridge Webhooks Einstellungen
String hbip = "192.168.178.51";
String hbport = "51828";
String hbid = "alarmanlage";

//Messintervall in Sekunden
int wait = 5;
// ###########################################


// Pin D1
int pinAlarmanlageStatus = D1;

// Pin D2
int pinAlarmanlageAusgeloest = D2;

// Alarmanlagen Status
String securitystatecurrent = "3"; // Default: Disarm
String securitystatetarget = "3"; // Default: Disarm

// Error Handling
String wlanstatus = "";
bool wlanerror = false;
String securitystatus = "";
bool securityerror = false;
String httprequeststatus = "";
bool httprequesterror = false;

// Webserver
WiFiServer server(80);

// Sender
WiFiClient client;
HTTPClient sender;


void connectWifi() {
  
  WiFi.persistent(false);   // daten nicht in Flash speichern
  WiFi.mode(WIFI_STA);

  WiFi.begin(ssid, password);

  // Verbindungsversuch max 5 Sekunden
  for (int x = 0; x < 10; x++) {
    delay(500);
  }

  // Prüfe Verbindung
  if (WiFi.status() != WL_CONNECTED)
  {
    // no connection
    wlanstatus = "Nicht Verbunden";
    wlanerror = true;
  }
  else
  {
    // connected
    wlanstatus = "Verbunden";
    wlanerror = false;
  }

}


void checkState(){

  //Hier wird der Wert an die Smarthome-Umgebung übertragen

  if (digitalRead(pinAlarmanlageStatus) == LOW)
    {
      // Open - Aus - Disarmed
      securitystatetarget = "3";
    }
  else
    {
       // Closed - An - Away
       securitystatetarget = "1";
    }

  if (digitalRead(pinAlarmanlageAusgeloest) == LOW)
    {
       // Open - Normal
    }
  else
    {
       // Closed - Ausgeloest - Triggered
       securitystatetarget = "4";
    }

  // Wenn Alarm ausgelöst
  if (securitystatetarget == "4")
    {
      // Send Current
      sendRequest("http://" + hbip + ":" + hbport + "/?accessoryId=" + hbid + "&currentstate=" + securitystatetarget);
    }
  else
    {
      // Send Target
      sendRequest("http://" + hbip + ":" + hbport + "/?accessoryId=" + hbid + "&targetstate=" + securitystatetarget);

      delay(1000);
      securitystatecurrent = securitystatetarget;
      
      // Send Current
      sendRequest("http://" + hbip + ":" + hbport + "/?accessoryId=" + hbid + "&currentstate=" + securitystatecurrent);
    }

  securitystatus = "Erfolgreich";

}

void sendRequest(String url) {

    if (sender.begin(client, url)){

    // HTTP-Code der Response speichern
    int httpCode = sender.GET();
   

    if (httpCode > 0) {
      
      // Anfrage wurde gesendet und Server hat geantwortet
      // Info: Der HTTP-Code für 'OK' ist 200
      if (httpCode == HTTP_CODE_OK) {

        // Hier wurden die Daten vom Server empfangen

        // String vom Webseiteninhalt speichern
        String payload = sender.getString();

        httprequeststatus = "Erfolgreich";  
        httprequesterror = false;
      }
      
    }else{
      // Falls HTTP-Error
      httprequeststatus = "HTTP-Error: ", sender.errorToString(httpCode).c_str();
      httprequesterror = true;
    }

    // Wenn alles abgeschlossen ist, wird die Verbindung wieder beendet
    sender.end();
    
  }else {
    httprequeststatus = "HTTP-Verbindung konnte nicht hergestellt werden!";
    httprequesterror = true;
  }
  
}



void setup() {

  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
  
  // Pin
  pinMode(pinAlarmanlageStatus, INPUT);
  pinMode(pinAlarmanlageAusgeloest, INPUT);
  
  // Connect to WiFi network
  if (WiFi.status() != WL_CONNECTED) connectWifi();

  // Start the server
  server.begin();

  // Set wait to sec
  wait = wait * 1000;
}

void loop() {

  // Error Handling LED
  if (wlanerror == false & securityerror == false & httprequesterror == false)
  {
    // Alles ok
    digitalWrite(LED_BUILTIN, LOW);   // turn the LED on
    delay(200);                       // wait 
    digitalWrite(LED_BUILTIN, HIGH);    // turn the LED off
  }
  else if (wlanerror == true)
  {
    // Doppelblinken bei WLAN Problem
    digitalWrite(LED_BUILTIN, LOW);   // turn the LED on
    delay(200);                       // wait 
    digitalWrite(LED_BUILTIN, HIGH);    // turn the LED off
    delay(100);                       // wait 
    digitalWrite(LED_BUILTIN, LOW);   // turn the LED on
    delay(200);                       // wait 
    digitalWrite(LED_BUILTIN, HIGH);    // turn the LED off
  }
  else if (httprequesterror == true)
  {
    // Dreifachblinken bei HttpRequest Problem
    digitalWrite(LED_BUILTIN, LOW);   // turn the LED on
    delay(200);                       // wait 
    digitalWrite(LED_BUILTIN, HIGH);    // turn the LED off
    delay(100);                       // wait 
    digitalWrite(LED_BUILTIN, LOW);   // turn the LED on
    delay(200);                       // wait 
    digitalWrite(LED_BUILTIN, HIGH);    // turn the LED off
    delay(100);                       // wait 
    digitalWrite(LED_BUILTIN, LOW);   // turn the LED on
    delay(200);                       // wait 
    digitalWrite(LED_BUILTIN, HIGH);    // turn the LED off
  }
  else
  {
    // Kein Blinken bei allen anderen Problemen
  }

  // Check WiFi network
  if (WiFi.status() != WL_CONNECTED)
  {
    // no connection
    wlanstatus = "Nicht Verbunden";
    wlanerror = true;
    connectWifi();
  }
  else
  {
    // connected
    wlanstatus = "Verbunden";
    wlanerror = false;
  }

  // Check Pin state and send request
  checkState();

  // Web UI
  WiFiClient client = server.available();
  if (client) {

    boolean blank_line = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
 
        if (c == '\n' && blank_line) {

          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");
          client.println();

          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          client.println("<head><meta http-equiv=refresh content=15></head><body bgcolor=white>");

          client.println("<h1>Status Alarmanlage</h1><h3>Hardware: Wemos D1 Mini</h3>");
          
          client.println("<div style=\"width:150px;background:#b3d9ff;padding:10px;float: left;clear: both;text-align: right;\"><b>STATUS LED</b></div>");
          client.println("<div style=\"width:600px;background:#f2f2f2;padding:10px;float: left;\">");
          client.println("- 1-fach Blinken &rArr; Alles ok<br>");
          client.println("- 2-fach Blinken &rArr; WLAN-Verbindungsproblem<br>");
          client.println("- 3-fach Blinken &rArr; HttpRequest Problem<br>");
          client.println("- Kein Blinken &rArr; Sonstiges Problem<br>");
          client.println("</div>");
          
          client.println("<br>");

          client.println("<div style=\"width:150px;background:#b3d9ff;padding:10px;float: left;clear: both;text-align: right;\"><b>WLAN</b></div>");
          client.println("<div style=\"width:600px;background:#f2f2f2;padding:10px;float: left;\">");
          client.println("Status &rArr; " + wlanstatus + "<br>");
          client.println("</br>");
          client.println("SSID &rArr; " + String(ssid) + "<br>");
          client.println("</div>");
          
          client.println("<br>");

          client.println("<div style=\"width:150px;background:#b3d9ff;padding:10px;float: left;clear: both;text-align: right;\"><b>INPUT</b></div>");
          client.println("<div style=\"width:600px;background:#f2f2f2;padding:10px;float: left;\">");
          client.println("Status &rArr; " + securitystatus + "<br>");
          client.println("</br>");
          client.println("Messintervall &rArr; " + String(wait / 1000) + " sec<br>");
          client.println("Alarmanlage Status (D1) &rArr; ");
          if (digitalRead(pinAlarmanlageStatus) == LOW)
            {
              client.println("Open"); 
            }
          else
            {
              client.println("Closed"); 
            }
          client.println("</br>");
          
          client.println("Alarmanlage Ausgeloest (D2) &rArr; "); 
          if (digitalRead(pinAlarmanlageAusgeloest) == LOW)
            {
              client.println("Open"); 
            }
          else
            {
              client.println("Closed"); 
            }
          client.println("</br>");
          client.println("Alarmanlage Status &rArr; " + securitystatecurrent + " (Stay=0 / Away=1 / Night=2 / Disarmed=3 / Triggered=4)<br>");  
          client.println("</div>");
          
          client.println("</br>");

          client.println("<div style=\"width:150px;background:#b3d9ff;padding:10px;float: left;clear: both;text-align: right;\"><b>OUTPUT</b></div>");
          client.println("<div style=\"width:600px;background:#f2f2f2;padding:10px;float: left;\">");
          client.println("Status &rArr; " + httprequeststatus + "<br>");
          client.println("</br>");
          client.println("Request Webhooks &rArr; http://" + hbip + ":" + hbport + "/?accessoryId=" + hbid + "&amp;targetstate=" + securitystatetarget + "<br>");
          client.println("Request Webhooks &rArr; http://" + hbip + ":" + hbport + "/?accessoryId=" + hbid + "&amp;currentstate=" + securitystatecurrent + "<br>"); 
          client.println("</div>");

          client.println("<div style=\"width:550px;padding:10px;float: left;clear: both;\">Sketch: Von Jan mit Liebe gemacht</div>");

          client.println("</body></html>"); 
          break;
        }
        if (c == '\n') {

          blank_line = true;
        }
        else if (c != '\r') {

          blank_line = false;
        }
      }
    } 

    delay(1);
    client.stop();

  }
  
  delay(wait);
}

D1 mini Webseite

Sobald ihr den Sketch auf den D1 mini gespielt habt, könnt ihr mit dessen IP-Adresse eine Webseite aufrufen die euch ein paar Informationen über den Status des D1 mini gibt.

In Hombridge sieht man nun auch das neue “Security” Gerät und kann die Statusveränderung erkennen sobald D1 und/oder D2 am D1 mini geschlossen wird.

Teile diesen Beitrag:

Das könnte dich auch interessieren …