Navigation

    makesmart

    • Registrieren
    • Anmelden
    • Suche
    • Aktuell
    • Tags
    • Kategorien
    • Ungelesen
    • Beobachtet
    • Beliebt
    • Gespeichert

    ESP8266 D1 Mini Relais als HomeKit Schalter ohne Bridge - Tutorial

    Tipps, Tricks & Tutorials
    d1 mini esp8266 homekit iot schalter smarthome tutorial
    7
    25
    417
    Lade mehr Beiträge
    • Älteste zuerst
    • Neuste zuerst
    • Meiste Stimmen
    Antworten
    • In einem neuen Thema antworten
    Anmelden zum Antworten
    Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
    • cooper
      cooper zuletzt editiert von cooper

      Wenn es bisher darum ging den ESP8266 D1 Mini in HomeKit einzubinden, bin ich immer den Weg über meine Homebridge auf dem Raspberry Pi gegangen. In der letzten Zeit hat sich da sehr viel getan und mittlerweile gibt es nicht nur eine Lösung das ganze auch ohne Bridge zu erreichen. Wir werden heute einen D1 Mini ohne Bridge oder sonstiges Zubehör direkt und nativ in HomeKit einbinden. Es handelt sich dabei erstmal nur um einen einfachen Schalter der ein Relaismodul betätigt.


      HomeKit-ESP8266 - Arduino IDE Bibliothek hinzufügen

      Bevor wir damit beginnen unseren eigenen HomeKit-Schalter einzubinden, muss eine Bibliothek in der Arduino IDE installiert werden. Das geht über den Bibliotheksverwalter. Ihr erreicht ihn über das Menü der Arduino IDE. Die Bibliothek heißt HomeKit-ESP8266 und kann über die Suche des Bibliotheksverwalters gefunden werden.

      Arduino IDE
      └───Werkzeuge
          └───Bibliotheken verwalten...
      

      HomeKit-ESP8266 - Arduino IDE Bibliothek installieren


      HomeKit-ESP8266 - Der Code

      Um den ESP8266 in HomeKit einzubinden, ist mehr als nur eine Datei notwendig. Ihr könnt dem Tutorial weiter folgen und die Dateien selber anlegen, oder die fertigen Dateien herunterladen: makesmart-esp8266-homekit-relais.zip


      Öffnet die Arduino IDE und speichert das Projekt an einem beliebigen Ort. Nachdem das getan ist, müsst ihr zwei weitere Dateien anlegen. Das über die Tastenkombination Strg + Umschalt + N oder über den Klick auf den Pfeil in der rechten oberen Ecke.

      Arduino IDE neue Datei anlegen

      Nennt die erste Datei my_accessory.c und die zweite Datei wifi_info.h.


      Jetzt kommen wir zum eigentlichen Code. Den Code könnt ihr 1:1 für die jeweilige Datei kopieren, einfügen und speichern.

      1. Datei: mein_schalter.ino

      #include <Arduino.h>
      #include <arduino_homekit_server.h>
      #include "wifi_info.h"
      
      #define LOG_D(fmt, ...)   printf_P(PSTR(fmt "\n") , ##__VA_ARGS__);
      
      void setup() {
        Serial.begin(115200);
        wifi_connect();
        homekit_storage_reset();
        my_homekit_setup();
      }
      
      void loop() {
        my_homekit_loop();
        delay(10);
      }
      
      //==============================
      // HomeKit setup and loop
      //==============================
      
      // Zugriff auf die Definitionen des Accessories in my_accessory.c
      extern "C" homekit_server_config_t config;
      extern "C" homekit_characteristic_t cha_switch_on;
      
      static uint32_t next_heap_millis = 0;
      
      #define PIN_SWITCH 15
      
      // Diese Funktion wird aufgerufen, wenn der Schalter in HomeKit betätigt wird
      void cha_switch_on_setter(const homekit_value_t value) {
        bool on = value.bool_value;
        cha_switch_on.value.bool_value = on;
        LOG_D("Switch: %s", on ? "ON" : "OFF");
        digitalWrite(PIN_SWITCH, on ? HIGH : LOW);
      }
      
      void my_homekit_setup() {
      
        
        pinMode(PIN_SWITCH, OUTPUT);
        digitalWrite(PIN_SWITCH, HIGH);
        cha_switch_on.setter = cha_switch_on_setter;
        arduino_homekit_setup(&config);
      
      
      
        // Das hier kann verwendet werden, um den Status an HomeKit zurückzusenden,
        // falls ein zusätzlicher pysischer Button o.ä verwendet wird.
        
        // bool switch_is_on = true/false;
        // cha_switch_on.value.bool_value = switch_is_on;
        // homekit_characteristic_notify(&cha_switch_on, cha_switch_on.value);
      }
      
      
      
      void my_homekit_loop() {
        arduino_homekit_loop();
        const uint32_t t = millis();
        if (t > next_heap_millis) {
          // heap-Info alle 30 Sekunden im seriellen Monitor ausgeben
          next_heap_millis = t + 30 * 1000;
          LOG_D("Free heap: %d, HomeKit clients: %d",
              ESP.getFreeHeap(), arduino_homekit_connected_clients_count());
      
        }
      }
      
      

      2. Datei: my_accessory.c

      #include <homekit/homekit.h>
      #include <homekit/characteristics.h>
      
      void my_accessory_identify(homekit_value_t _value) {
        printf("accessory identify\n");
      }
      
      // Switch (HAP section 8.38)
      // required: ON
      // optional: NAME
      
      // format: bool; HAP section 9.70; write the .setter function to get the switch-event sent from iOS Home APP.
      homekit_characteristic_t cha_switch_on = HOMEKIT_CHARACTERISTIC_(ON, true);
      
      // max. Länge 64
      homekit_characteristic_t cha_name = HOMEKIT_CHARACTERISTIC_(NAME, "Schalter");
      
      homekit_accessory_t *accessories[] = {
          HOMEKIT_ACCESSORY(.id=1, .category=homekit_accessory_category_switch, .services=(homekit_service_t*[]) {
              HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]) {
                  HOMEKIT_CHARACTERISTIC(NAME, "Schalter"),
                  HOMEKIT_CHARACTERISTIC(MANUFACTURER, "makesmart Community"),
                  HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "1234567"),
                  HOMEKIT_CHARACTERISTIC(MODEL, "ESP8266 D1 Mini"),
                  HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "1.0"),
                  HOMEKIT_CHARACTERISTIC(IDENTIFY, my_accessory_identify),
                  NULL
              }),
          HOMEKIT_SERVICE(SWITCH, .primary=true, .characteristics=(homekit_characteristic_t*[]){
            &cha_switch_on,
            &cha_name,
            NULL
          }),
              NULL
          }),
          NULL
      };
      
      homekit_server_config_t config = {
          .accessories = accessories,
          .password = "123-45-678"
      };
      
      

      3. Datei: wifi_info.h

      Im folgenden Code müsst ihr eure WLAN-Zugangsdaten anpassen. Es sind die folgenden beiden Variablen:

      const char *ssid = "WIFI-SSID";
      const char *password = "WIFI-PASSWD";
      
      #ifndef WIFI_INFO_H_
      #define WIFI_INFO_H_
      
      #if defined(ESP8266)
      #include <ESP8266WiFi.h>
      #elif defined(ESP32)
      #include <WiFi.h>
      #endif
      
      const char *ssid = "WIFI-SSID";
      const char *password = "WIFI-PASSWD";
      
      void wifi_connect() {
        WiFi.persistent(false);
        WiFi.mode(WIFI_STA);
        WiFi.setAutoReconnect(true);
        WiFi.begin(ssid, password);
        Serial.println("WiFi connecting...");
        while (!WiFi.isConnected()) {
          delay(100);
          Serial.print(".");
        }
        Serial.print("\n");
        Serial.printf("WiFi connected, IP: %s\n", WiFi.localIP().toString().c_str());
      }
      
      #endif
      
      

      Nachdem alle drei Dateien gespeichert wurden, kann das Programm auf den ESP8266 D1 Mini geladen werden. Geht dazu wieder in den Reiter “mein_schalter” und ladet das Programm auf den ESP.


      HomeKit-ESP8266 - Die Einbindung in Homekit

      Die Einbindung des DIY ESP8266 Relais in HomeKit ist ziemlich einfach.Öffnet dazu die Home-App und fügt ein neues Gerät hinzu. Der Schalter sollte in den Geräten in der Nähe auftauchen. Per Tippen auf den Schalter kann dieser hinzugefügt werden. Zum Hinzufügen muss ein Code eingegeben werden, der Code zum Koppeln lautet 123-45-678.

      HomeKit neues Gerät hinzufügen


      HomeKit-ESP8266 - Die Verdrahtung

      Der ESP wurde erfolgreich in HomeKit eingebunden und kann von nun an für Automationen und Szenen verwendet werden. Aber eins fehlt noch: Das Relais. Das ist wohl das geringste Übel dieses Tutorials - hier der Schaltplan:

      ESP8266 D1 Mini Relaiy KY-019 Schaltplan

      KY-19 Relaismodul ESP8266 D1 Mini
      S D8
      + 5V
      - G

      Und fertig ist das HomeKit-Relais mit dem ESP8266 D1 Mini. Nativ. Ohne Bridge. Superschnell und super einfach. 🙂

      Erfolgreich getestet und im Einsatz hab ich es mit diesen Produkten vom makesmart.shop.


      Solltest du mit dem Programmieren / Debugging fertig sein, ist noch ein letzter Schritt nötig.

      homekit_storage_reset();
      

      Diese Zeile muss im setup() auskommentiert werden. Sonst muss der ESP8266 D1 Mini jedes mal aufs neue mit HomeKit gepaired werden. Wenn die Zeile auskommentiert oder entfernt ist, wird der D1 Mini auch nach dem Abstecken wieder als der gleiche Schalter erkannt und kann eingesetzt werden.


      Möchtest du mehr als ein Relais mit nur einem D1 Mini direkt via HomeKit steuern?
      Der User @Menuhin hat sich die Arbeit gemacht das Programm anzupassen, um mehr Relais damit steuern zu können. Den abgeänderten Sketch und eine Beschribung dazu findet ihr hier:

      Update von Menuhin für weitere Relais an einem D1 Mini

      Disclaimer: Ich bin gerade frisch über diese Libary gestoßen und sehe darin (für mich persönlich) sehr viel potenzial. Ich werde vermutlich noch weitere Tutorials über die Libary und das Thema allgemein veröffentlichen. Es soll nicht bei diesem einen Schalter bleiben. Thermostate, Sensoren und so weiter sind ebenfalls möglich.

      Denss 1 Antwort Letzte Antwort Antworten Zitieren 5
      • K
        Kennyvi7 zuletzt editiert von

        Hallo,habe dein Tutorial nachgebaut, funktioniert super.
        Auch ich möchte diese Libary für mich nutzen. Leider stecke ich noch in den Arduino Kinderschuhen…
        und ich schaffe es leider nicht einen zweiten ESP anzumelden. hat du da einen Tip für mich?

        1 Antwort Letzte Antwort Antworten Zitieren 0
        • H
          HomeKitDude zuletzt editiert von

          Hallo!
          Erstmal vielen Dank für diese einfache und leicht verständliche Anleitung.
          In einem aktuellen Projekt in meinem Partykeller soll der HomeKit-ESP einen Raspberry Pi ein- und asusschalten.
          Da der Raspi es allerdings nicht besonders mag hart ausgeschaltet zu werden müsste ich über einen GPIO-Shutdown den Raspi erst herunterfahren, bevor ich ihn vom Strom trennen kann.
          Damit kommen wir zu meiner Frage:
          Ist es möglich den Code um folgendes Szenario zu erweitern: Sobald in HomeKit AUS geschaltet wird, wird erst für kurze Zeit ein GPIO des ESP auf High gesetzt, um den GPIO-Shutdown am Raspi zu bewirken, dann wird für ein paar Sekunden gewartet und erst dann wird über das Relais ausgeschaltet.

          cooper 1 Antwort Letzte Antwort Antworten Zitieren 0
          • cooper
            cooper @HomeKitDude zuletzt editiert von cooper

            @HomeKitDude

            Du könntest folgendes Zeile anpassen um weitere Abläufe / Befehle hinzuzufügen.

            // Diese Funktion wird aufgerufen, wenn der Schalter in HomeKit betätigt wird
            void cha_switch_on_setter(const homekit_value_t value) {
              bool on = value.bool_value;h
              cha_switch_on.value.bool_value = on;
              LOG_D("Switch: %s", on ? "ON" : "OFF");
              digitalWrite(PIN_SWITCH, on ? HIGH : LOW);
            }
            

            befindet sich in der mein_schalter.ino.
            Hier könntest du deinen GPIO ansteuern und danach erst das Relais aus oder wie auch immer. 🙉

            1 Antwort Letzte Antwort Antworten Zitieren 1
            • Paxi08
              Paxi08 zuletzt editiert von

              Hallo,
              Danke für das Top Tutorial.
              Ich habe eine Frage bezüglich dem Wiederverbinden nach abschalten. Denn wenn ich aktuell den D1 vom Strom trenne und wieder anschließe dann muss ich ihn in der App wieder neu hinzufügen anstatt das er automatisch wiedergefunden wird.

              Gibt es eine Möglichkeit dies im Code zu ändern.

              Über deine Hilfe wäre ich sehr dankbar.

              cooper 1 Antwort Letzte Antwort Antworten Zitieren 0
              • cooper
                cooper @Paxi08 zuletzt editiert von

                @Paxi08 Danke 🙂

                Bringt das hier nichts?

                Solltest du mit dem Programmieren / Debugging fertig sein, ist noch ein letzter Schritt nötig.

                homekit_storage_reset();

                Diese Zeile muss im setup() auskommentiert werden. Sonst muss der ESP8266 D1 Mini jedes mal aufs neue mit HomeKit gepaired werden. Wenn die Zeile auskommentiert oder entfernt ist, wird der D1 Mini auch nach dem Abstecken wieder als der gleiche Schalter erkannt und kann eingesetzt werden.

                1 Antwort Letzte Antwort Antworten Zitieren 1
                • WupDich
                  WupDich zuletzt editiert von

                  Hey echt cooles Tutorial! Bin noch Anfänger mit Arduino und mache üblicherweise nur Copy und Paste. Würde gerne ein Projekt machen wo ich das gleiche mit 4 oder 5 Relais an einem ESP mache. Wie würde das gehen?
                  Vielen Dank schonmal. 🙂

                  cooper 1 Antwort Letzte Antwort Antworten Zitieren 0
                  • cooper
                    cooper @WupDich zuletzt editiert von

                    @WupDich Freut mich wenn es dir gefällt.

                    Wenn du mehr als nur ein Accessoire auf dem ESP betreiben möchtest, müsstest du den ESP als Bridge aka Gateway definieren - nicht als Accessoire.

                    Ich habe das selber noch nicht gemacht und komme wohl auch nicht dazu, das selbst zu probieren in nächster Zeit.

                    Wenn du ein eigenes Thema aufmachst findest du vielleicht jemanden, der dir Hilfestellung bietet. 🙂

                    Hier ist zumindest schon mal ein Beispiel mit mehreren Accessoires auf einem ESP.

                    https://github.com/Mixiaoxiao/Arduino-HomeKit-ESP8266/tree/master/examples/Example04_MultipleAccessories

                    1 Antwort Letzte Antwort Antworten Zitieren 0
                    • Denss
                      Denss @cooper zuletzt editiert von

                      @cooper Wie kann ich das jetzt für meine Türe verwenden? Ich habe es jetzt soweit hinbekommen das ich beim einschalten über HomeKit das Relais 2500ms an schalte und es sich danach wieder ausschaltet. Der Status in HomeKit stimmt dann aber nicht mehr. Gibt es dafür eine Lösung? Und kann man das auch als Schloß in HomeKit anzeigen lassen?

                      Vielen Dank im Voraus
                      Grüße
                      Denis

                      cooper 1 Antwort Letzte Antwort Antworten Zitieren 0
                      • cooper
                        cooper @Denss zuletzt editiert von cooper

                        @Denss Steht im Code auskommentiert

                        // Das hier kann verwendet werden, um den Status an HomeKit zurückzusenden,
                          // falls ein zusätzlicher pysischer Button o.ä verwendet wird.
                          
                          // bool switch_is_on = true/false;
                          // cha_switch_on.value.bool_value = switch_is_on;
                          // homekit_characteristic_notify(&cha_switch_on, cha_switch_on.value);
                        

                        Das mit dem Schloss weiß ich nicht, da müsste man sich mit der Libary beschäftigen. 🙂

                        Habe mein Schloss via Homebridge eingebunden. 👍

                        Denss 1 Antwort Letzte Antwort Antworten Zitieren 0
                        • Denss
                          Denss @cooper zuletzt editiert von

                          @cooper Das hatte ich schon mal eingefügt. Dann hat sich das Relais halt ständig an und aus geschalten. Welches Plugin hast du für die Homebridge verwendet?

                          cooper 1 Antwort Letzte Antwort Antworten Zitieren 0
                          • cooper
                            cooper @Denss zuletzt editiert von

                            @Denss Dann musst du es wahrscheinlich auscanclen.

                            Hier war letztens eine Frage dazu:
                            https://my.makesmart.net/topic/129/relais-beim-ersten-knopfdruck-high-beim-zweiten-knopfdruck-low-setzen/3

                            Als plugin verwende ich http-webhooks.

                            1 Antwort Letzte Antwort Antworten Zitieren 0
                            • M
                              Menuhin zuletzt editiert von

                              Hallo Cooper,

                              Ich versuche seit einigen Tagen das tolle Script umzuarbeiten für zwei oder mehrere Schalter.

                              Hier sind meine zwei Konfigurations-Dateien:

                              mein_schalter.ino

                              #include <Arduino.h>
                              #include <arduino_homekit_server.h>
                              #include "wifi_info.h"
                              
                              #define LOG_D(fmt, ...)   printf_P(PSTR(fmt "\n") , ##__VA_ARGS__);
                              
                              void setup() {
                                Serial.begin(115200);
                                wifi_connect();
                                homekit_storage_reset();
                                my_homekit_setup();
                              }
                              
                              void loop() {
                                my_homekit_loop();
                                delay(10);
                              }
                              
                              //==============================
                              // HomeKit setup and loop
                              //==============================
                              
                              // Zugriff auf die Definitionen des Accessories in my_accessory.c
                              extern "C" homekit_server_config_t config;
                              extern "C" homekit_characteristic_t cha_switch_on1;
                              extern "C" homekit_characteristic_t cha_switch_on2;
                              
                              static uint32_t next_heap_millis = 0;
                              
                              #define PIN_SWITCH1 D8
                              #define PIN_SWITCH2 D7
                              
                              // Diese Funktion wird aufgerufen, wenn der Schalter in HomeKit betätigt wird
                              void cha_switch_on1_setter(const homekit_value_t value) {
                                bool on = value.bool_value;
                                cha_switch_on1.value.bool_value = on;
                                LOG_D("Switch: %s", on ? "ON" : "OFF");
                                digitalWrite(PIN_SWITCH1, on ? HIGH : LOW);
                              }
                              
                              void cha_switch_on2_setter(const homekit_value_t value) {
                                bool on = value.bool_value;
                                cha_switch_on2.value.bool_value = on;
                                LOG_D("Switch: %s", on ? "ON" : "OFF");
                                digitalWrite(PIN_SWITCH2, on ? HIGH : LOW);
                              }
                              
                              void my_homekit_setup() {
                                pinMode(PIN_SWITCH1, OUTPUT);
                                digitalWrite(PIN_SWITCH1, HIGH);
                                cha_switch_on1.setter = cha_switch_on1_setter;
                                arduino_homekit_setup(&config);
                                pinMode(PIN_SWITCH2, OUTPUT);
                                digitalWrite(PIN_SWITCH2, HIGH);
                                cha_switch_on2.setter = cha_switch_on2_setter;
                                arduino_homekit_setup(&config);
                                 // Das hier kann verwendet werden, um den Status an HomeKit zurückzusenden,
                                // falls ein zusätzlicher pysischer Button o.ä verwendet wird.  
                                // bool switch_is_on = true/false;
                                // cha_switch_on.value.bool_value = switch_is_on;
                                // homekit_characteristic_notify(&cha_switch_on, cha_switch_on.value);
                              }
                              
                              void my_homekit_loop() {
                                arduino_homekit_loop();
                                const uint32_t t = millis();
                                if (t > next_heap_millis) {
                                  // heap-Info alle 30 Sekunden im seriellen Monitor ausgeben
                                  next_heap_millis = t + 30 * 1000;
                                  LOG_D("Free heap: %d, HomeKit clients: %d",
                                      ESP.getFreeHeap(), arduino_homekit_connected_clients_count());
                                }
                              }
                              

                              my_accessory.c

                              #include <homekit/homekit.h>
                              #include <homekit/characteristics.h>
                              
                              void my_accessory_identify1(homekit_value_t _value) {
                                printf("accessory identify\n");
                              }
                              
                              void my_accessory_identify2(homekit_value_t _value) {
                                printf("accessory identify\n");
                              }
                              
                              // Switch (HAP section 8.38)
                              // required: ON
                              // optional: NAME
                              
                              // format: bool; HAP section 9.70; write the .setter function to get the switch-event sent from iOS Home APP.
                              homekit_characteristic_t cha_switch_on1 = HOMEKIT_CHARACTERISTIC_(ON, true);
                              homekit_characteristic_t cha_switch_on2 = HOMEKIT_CHARACTERISTIC_(ON, true);
                              
                              // max. Länge 64
                              homekit_characteristic_t cha_name1 = HOMEKIT_CHARACTERISTIC_(NAME, "Schalter1");
                              homekit_characteristic_t cha_name2 = HOMEKIT_CHARACTERISTIC_(NAME, "Schalter2");
                              
                              homekit_accessory_t *accessories[] = {
                                  HOMEKIT_ACCESSORY(.id=1, .category=homekit_accessory_category_switch, .services=(homekit_service_t*[]) {
                                      HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]) {
                                          HOMEKIT_CHARACTERISTIC(MANUFACTURER, "makesmart Community"),
                                          HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "1234567"),
                                          HOMEKIT_CHARACTERISTIC(MODEL, "ESP8266 D1 Mini"),
                                          HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "1.0"),
                                          HOMEKIT_CHARACTERISTIC(IDENTIFY, my_accessory_identify1),
                                          NULL
                                      }),
                                  HOMEKIT_SERVICE(SWITCH, .primary=true, .characteristics=(homekit_characteristic_t*[]){
                                   HOMEKIT_CHARACTERISTIC(NAME, "Schalter1"),
                                   &cha_switch_on1,
                                    &cha_name1,
                                    NULL
                                  }),
                                      NULL
                                  }),
                                  
                                  HOMEKIT_ACCESSORY(.id=2, .category=homekit_accessory_category_switch, .services=(homekit_service_t*[]) {
                                      HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]) {
                                          HOMEKIT_CHARACTERISTIC(MANUFACTURER, "makesmart Community"),
                                          HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "1234567"),
                                          HOMEKIT_CHARACTERISTIC(MODEL, "ESP8266 D1 Mini"),
                                          HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "1.0"),
                                          HOMEKIT_CHARACTERISTIC(IDENTIFY, my_accessory_identify2),
                                          NULL
                                      }),
                                  HOMEKIT_SERVICE(SWITCH, .primary=true, .characteristics=(homekit_characteristic_t*[]){
                                           HOMEKIT_CHARACTERISTIC(NAME, "Schalter2"),
                                   &cha_switch_on2,
                                    &cha_name2,
                                    NULL
                                  }),
                                      NULL
                                  }),
                                  NULL
                              };
                              
                              homekit_server_config_t config = {
                                  .accessories = accessories,
                                  .password = "123-45-678"
                              };
                              

                              Leider bekomme ich beim Ausführen immer die Meldung:

                              HomeKit: Invalid accessory declaration: no Name characteristic in AccessoryInfo service
                              

                              Ich finde meinen Fehler nicht. Haben Sie eventuell einen Tipp für mich?

                              cooper 1 Antwort Letzte Antwort Antworten Zitieren 0
                              • cooper
                                cooper @Menuhin zuletzt editiert von

                                @Menuhin Leider habe ich es bisher zeitlich selber noch nicht geschafft, multiple Accessories zu testen.

                                Aber nachdem du schon weit gekommen bist im Sinne vom Code, dann hilft dir vielleicht ein Blick in das Beispiel mit den Multiple Accessories.

                                https://github.com/Mixiaoxiao/Arduino-HomeKit-ESP8266/tree/master/examples/Example04_MultipleAccessories

                                Der ESP muss bei mehr als einem Accessorie wohl als Bridge programmiert werden.

                                This example is a bridge (aka a gateway) which contains multiple accessories.

                                Würde mich freuen wenn du ein Update geben könntest, falls du was herausgefunden hast. 🙂 Bis ich mich da selber nochmal ransetzen kann, werden wohl noch ein paar Tage … vergehen.

                                Gruß

                                1 Antwort Letzte Antwort Antworten Zitieren 1
                                • M
                                  Menuhin zuletzt editiert von Menuhin

                                  Nach ein paar Versuchen bin ich jetzt fündig geworden bei all meinen Fehlern.
                                  Für alle, die auch gerne mehrere Schalter/Relais direkt über Homekit in der App und angeschlossen am ESP realisieren wollen, kommen hier die beiden angepassten Dateien für
                                  mein_schalter und my_accessory.c

                                  Bei mir laufen die beiden Relais an den Schnittstellen D7 und D8 meines D1-ESPs. Das müsste man ggf anpassen und natürlich ist es nach diesem Prinzip auch möglich, mehr als zwei Relais einzubinden:

                                  mein_schalter

                                  #include <Arduino.h>
                                  #include <arduino_homekit_server.h>
                                  #include "wifi_info.h"
                                  
                                  #define LOG_D(fmt, ...)   printf_P(PSTR(fmt "\n") , ##__VA_ARGS__);
                                  
                                  void setup() {
                                    Serial.begin(115200);
                                    wifi_connect();
                                    homekit_storage_reset();
                                    my_homekit_setup();
                                  }
                                  
                                  void loop() {
                                    my_homekit_loop();
                                    delay(10);
                                  }
                                  
                                  extern "C" homekit_server_config_t config;
                                  extern "C" homekit_characteristic_t cha_switch1_on;
                                  extern "C" homekit_characteristic_t cha_switch2_on;
                                  
                                  static uint32_t next_heap_millis = 0;
                                  
                                  #define PIN_SWITCH1 D8
                                  #define PIN_SWITCH2 D7
                                  
                                  void cha_switch1_on_setter(const homekit_value_t value) {
                                    bool on = value.bool_value;
                                    cha_switch1_on.value.bool_value = on;
                                    LOG_D("Switch: %s", on ? "ON" : "OFF");
                                    digitalWrite(PIN_SWITCH1, on ? HIGH : LOW);
                                  }
                                  
                                  void cha_switch2_on_setter(const homekit_value_t value) {
                                    bool on = value.bool_value;
                                    cha_switch2_on.value.bool_value = on;
                                    LOG_D("Switch: %s", on ? "ON" : "OFF");
                                    digitalWrite(PIN_SWITCH2, on ? HIGH : LOW);
                                  }
                                  
                                  void my_homekit_setup() {
                                    pinMode(PIN_SWITCH1, OUTPUT);
                                    digitalWrite(PIN_SWITCH1, HIGH);
                                    cha_switch1_on.setter = cha_switch1_on_setter;
                                    pinMode(PIN_SWITCH2, OUTPUT);
                                    digitalWrite(PIN_SWITCH2, HIGH);
                                    cha_switch2_on.setter = cha_switch2_on_setter;
                                    arduino_homekit_setup(&config);
                                  }
                                  
                                  void my_homekit_loop() {
                                    arduino_homekit_loop();
                                    const uint32_t t = millis();
                                    if (t > next_heap_millis) {
                                      next_heap_millis = t + 30 * 1000;
                                      LOG_D("Free heap: %d, HomeKit clients: %d",
                                          ESP.getFreeHeap(), arduino_homekit_connected_clients_count());
                                    }
                                  }
                                  

                                  my_accessory.c

                                  Die Datei my_accessory.c fungiert in der Tat als Bridge und wird problemlos mit mehreren Schaltern betrieben, die dann auch im Homekit variabel verschiedenen Zimmern zugeordnet werden können etc.
                                  Sie kann ebenfalls nach dem unten stehenden Prinzip .id=1, .id=2, .id=3 um weitere Schalter erweitert werden.
                                  Unter .id1 sind nur die grundsätzlichen Angaben für die Bridge definiert, die Schalter sind dann fortlaufend (bei mir ist Schalter1 dann .id=2 und Schalter2 ist .id=3)

                                  #include <homekit/homekit.h>
                                  #include <homekit/characteristics.h>
                                  
                                  void my_accessory_identify(homekit_value_t _value) {
                                    printf("accessory identify\n");
                                  }
                                  
                                  homekit_characteristic_t cha_switch1_on = HOMEKIT_CHARACTERISTIC_(ON, true);
                                  homekit_characteristic_t cha_switch2_on = HOMEKIT_CHARACTERISTIC_(ON, true);
                                  
                                  homekit_accessory_t *accessories[] = {
                                      HOMEKIT_ACCESSORY(.id=1, .category=homekit_accessory_category_bridge, .services=(homekit_service_t*[]) {
                                          HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]) {
                                              HOMEKIT_CHARACTERISTIC(NAME, "Multiple Switches"),
                                              HOMEKIT_CHARACTERISTIC(MANUFACTURER, "Homekit Switches"),
                                              HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "1234567"),
                                              HOMEKIT_CHARACTERISTIC(MODEL, "ESP8266 D1 Mini"),
                                              HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "1.0"),
                                              HOMEKIT_CHARACTERISTIC(IDENTIFY, my_accessory_identify),
                                              NULL
                                          }),
                                          NULL
                                      }),    
                                      HOMEKIT_ACCESSORY(.id=2, .category=homekit_accessory_category_switch, .services=(homekit_service_t*[]) {
                                      HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]) {
                                              HOMEKIT_CHARACTERISTIC(NAME, "Switch1"),
                                              HOMEKIT_CHARACTERISTIC(IDENTIFY, my_accessory_identify),
                                              NULL
                                          }),
                                      HOMEKIT_SERVICE(SWITCH, .primary=true, .characteristics=(homekit_characteristic_t*[]){
                                               HOMEKIT_CHARACTERISTIC(NAME, "Schalter1"),
                                       &cha_switch1_on,
                                        NULL
                                      }),
                                      NULL
                                  }),
                                      HOMEKIT_ACCESSORY(.id=3, .category=homekit_accessory_category_switch, .services=(homekit_service_t*[]) {
                                          HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]) {
                                              HOMEKIT_CHARACTERISTIC(NAME, "Switch2"),
                                              HOMEKIT_CHARACTERISTIC(IDENTIFY, my_accessory_identify),
                                              NULL
                                          }),
                                      HOMEKIT_SERVICE(SWITCH, .primary=true, .characteristics=(homekit_characteristic_t*[]){
                                               HOMEKIT_CHARACTERISTIC(NAME, "Schalter2"),
                                       &cha_switch2_on,
                                        NULL
                                      }),
                                      NULL
                                  }),
                                      NULL
                                  };
                                  
                                  homekit_server_config_t config = {
                                      .accessories = accessories,
                                      .password = "123-45-678"
                                  };
                                  

                                  wifi_info.h bleibt unverändert und muss nur bei den Werten für das eigene WLAN angepasst werden.

                                  Viel Spaß beim Ausprobieren!
                                  Danke nochmal an den @cooper!!!

                                  cooper H 2 Antworten Letzte Antwort Antworten Zitieren 2
                                  • cooper
                                    cooper @Menuhin zuletzt editiert von cooper

                                    @Menuhin Wow super danke für deine Mühe! 👏

                                    Ich werde das oben gleich mal mit einfügen und verlinken. Top!! 🙂

                                    Hier auch was für dich @WupDich

                                    1 Antwort Letzte Antwort Antworten Zitieren 0
                                    • H
                                      HomeKitDude @Menuhin zuletzt editiert von

                                      @menuhin
                                      Vielen Dank erstmal für deine Mühe!
                                      Einen Doppelschalter brauche ich demnächst auch, da werde ich dein Scrip hier direkt übernehmen 🙂

                                      Ich habe allerdings gerade ein anderes Problem.
                                      Ich würde gerne ein Relais betreiben und zehn Sekunden vor dem Ein- bzw. Ausschalten dieses Relais einen anderen GPIO kurz auf High setzen:

                                      #include <Arduino.h>
                                      #include <arduino_homekit_server.h>
                                      #include "wifi_info.h"
                                      
                                      #define LOG_D(fmt, ...)   printf_P(PSTR(fmt "\n") , ##__VA_ARGS__);
                                      const int buttonPin = 13;
                                      
                                      void setup() {
                                        Serial.begin(115200);
                                        wifi_connect();
                                        pinMode(buttonPin, OUTPUT);
                                        my_homekit_setup();
                                      }
                                      
                                      void loop() {
                                        my_homekit_loop();
                                        delay(10);
                                      }
                                      
                                      //==============================
                                      // HomeKit setup and loop
                                      //==============================
                                      
                                      // Zugriff auf die Definitionen des Accessories in my_accessory.c
                                      extern "C" homekit_server_config_t config;
                                      extern "C" homekit_characteristic_t cha_switch_on;
                                      
                                      static uint32_t next_heap_millis = 0;
                                      
                                      #define PIN_SWITCH 15
                                      
                                      // Diese Funktion wird aufgerufen, wenn der Schalter in HomeKit betätigt wird
                                      void cha_switch_on_setter(const homekit_value_t value) {
                                        bool on = value.bool_value;
                                        cha_switch_on.value.bool_value = on;
                                        LOG_D("Switch: %s", on ? "ON" : "OFF");
                                        digitalWrite(buttonPin, HIGH);
                                        delay(500);
                                        digitalWrite(buttonPin, LOW);
                                        delay(10000);
                                        digitalWrite(PIN_SWITCH, on ? HIGH : LOW);
                                      }
                                      
                                      void my_homekit_setup() {
                                      
                                        
                                        pinMode(PIN_SWITCH, OUTPUT);
                                        digitalWrite(PIN_SWITCH, HIGH);
                                        cha_switch_on.setter = cha_switch_on_setter;
                                        arduino_homekit_setup(&config);
                                      
                                      
                                      
                                        // Das hier kann verwendet werden, um den Status an HomeKit zurückzusenden,
                                        // falls ein zusätzlicher pysischer Button o.ä verwendet wird.
                                        
                                        // bool switch_is_on = true/false;
                                        // cha_switch_on.value.bool_value = switch_is_on;
                                        // homekit_characteristic_notify(&cha_switch_on, cha_switch_on.value);
                                      }
                                      
                                      
                                      
                                      void my_homekit_loop() {
                                        arduino_homekit_loop();
                                        const uint32_t t = millis();
                                        if (t > next_heap_millis) {
                                          // heap-Info alle 30 Sekunden im seriellen Monitor ausgeben
                                          next_heap_millis = t + 30 * 1000;
                                          LOG_D("Free heap: %d, HomeKit clients: %d",
                                              ESP.getFreeHeap(), arduino_homekit_connected_clients_count());
                                      
                                        }
                                      }
                                      

                                      Das Funktioniert auch soweit theoretisch, allerdings geht das Ganze in HomeKit nicht. Aufgrund der zehnsekündigen Verzögerung wird mir direkt in der Apple Home App angezeigt, dass das Gerät nicht erreichbar ist. Nach mehreren Minuten (z.T. dauert es auch Stunden) wird dann der aktuelle Status wieder angezeigt.

                                      Hast du eine Idee, wie ich dieses zehnsekündige Delay implementieren kann, ohne dass es diese “Gerät antwortet nicht” Fehlermeldung in Apple Home gibt?
                                      Gibt es irgendwo einen Parameter, wo man einstellen kann, ab welchem Intervall das Gerät als nicht erreichbar deklariert wird?

                                      Vielen Dank im Voraus!

                                      cooper 1 Antwort Letzte Antwort Antworten Zitieren 0
                                      • cooper
                                        cooper @HomeKitDude zuletzt editiert von

                                        @homekitdude sagte in ESP8266 D1 Mini Relais als HomeKit Schalter ohne Bridge - Tutorial:

                                        Ich habe allerdings gerade ein anderes Problem.
                                        Ich würde gerne ein Relais betreiben und zehn Sekunden vor dem Ein- bzw. Ausschalten dieses Relais einen anderen GPIO kurz auf High setzen:

                                        Das ist kein Problem der Library. Das gehört eher allgemein zu ESP und Single Core. 😛

                                        // Diese Funktion wird aufgerufen, wenn der Schalter in HomeKit betätigt wird
                                        void cha_switch_on_setter(const homekit_value_t value) {
                                          bool on = value.bool_value;
                                          cha_switch_on.value.bool_value = on;
                                          LOG_D("Switch: %s", on ? "ON" : "OFF");
                                          digitalWrite(buttonPin, HIGH);
                                          delay(500);
                                          digitalWrite(buttonPin, LOW);
                                          delay(10000);
                                          digitalWrite(PIN_SWITCH, on ? HIGH : LOW);
                                        }
                                        
                                         delay(10000);
                                        

                                        ist blocking. Das heißt dein gesamtes Programm pausiert und ist somit in diesem Zeitraum für HomeKit einfach nicht erreichbar, weil sich der ESP dumm stellt und auf gar nichts und niemanden reagiert, solange dieser delay() nicht abgelaufen ist.

                                        Du solltest hier eher mit millis() arbeiten.

                                        https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay

                                        H 1 Antwort Letzte Antwort Antworten Zitieren 0
                                        • H
                                          HomeKitDude @cooper zuletzt editiert von

                                          @cooper
                                          Danke für die schnelle Antwort und den passenden Link.
                                          Bin heute irgendwie nicht in der Lage mich zu konzentrieren, daher werd ich mich da morgen mal dran setzen und versuchen das zu implementieren 🙂
                                          Ich werde anschließend berichten, ob es geklappt hat 🙂

                                          cooper 1 Antwort Letzte Antwort Antworten Zitieren 1
                                          • cooper
                                            cooper @HomeKitDude zuletzt editiert von

                                            @homekitdude Würde mich freuen.
                                            Vielleicht wäre es dann nicht schlecht, die ganzen Modifikationen oben aufzulisten wenn es noch mehr werden. 😄

                                            Dann ist für jeden vielleicht nochmal gleich was passendes dabei. 👍🏻 Bzw. eher so als kleine Sammlung 🙂

                                            H 1 Antwort Letzte Antwort Antworten Zitieren 0
                                            • H
                                              HomeKitDude @cooper zuletzt editiert von HomeKitDude

                                              @cooper
                                              Versuche mich da gerade einzuarbeiten. Leider hab ich aktuell keinen zugriff auf den ESP, daher muss ich die Lösung erstmal ohne Try’n’Error finden.
                                              Wenn es bei der Lösung nur darum geht die delay() Funktion zu meiden und durch eine Funktion mit millis() zu ersetzen, dann könnte doch die folgende Funktion schon die Lösung sein (interval = 10000):

                                              void waitTenSec(){
                                                unsigned long currentMillis = millis();
                                                unsigned long goal = millis() + interval;
                                                while(currentMillis < goal) {
                                                  currentMillis = millis();
                                                }
                                              }
                                              

                                              Wenn ich das dann folgendermaßen in den Code einsetze, dann sollte es doch funktionieren

                                              #include <Arduino.h>
                                              #include <arduino_homekit_server.h>
                                              #include "wifi_info.h"
                                               
                                              #define LOG_D(fmt, ...)   printf_P(PSTR(fmt "\n") , ##__VA_ARGS__);
                                              const int buttonPin = 13;
                                              const long interval = 10000;
                                               
                                              void setup() {
                                                Serial.begin(115200);
                                                wifi_connect();
                                                pinMode(buttonPin, OUTPUT);
                                                my_homekit_setup();
                                              }
                                               
                                              void loop() {
                                                my_homekit_loop();
                                                delay(10);
                                              }
                                               
                                              //==============================
                                              // HomeKit setup and loop
                                              //==============================
                                               
                                              // Zugriff auf die Definitionen des Accessories in my_accessory.c
                                              extern "C" homekit_server_config_t config;
                                              extern "C" homekit_characteristic_t cha_switch_on;
                                               
                                              static uint32_t next_heap_millis = 0;
                                               
                                              #define PIN_SWITCH 15
                                               
                                              // Diese Funktion wird aufgerufen, wenn der Schalter in HomeKit betätigt wird
                                              void cha_switch_on_setter(const homekit_value_t value) {
                                                bool on = value.bool_value;
                                                cha_switch_on.value.bool_value = on;
                                                LOG_D("Switch: %s", on ? "ON" : "OFF");
                                                digitalWrite(buttonPin, HIGH);
                                                delay(1000);
                                                digitalWrite(buttonPin, LOW);
                                                waitTenSec();
                                                digitalWrite(PIN_SWITCH, on ? HIGH : LOW);
                                              }
                                               
                                              void waitTenSec(){
                                                unsigned long currentMillis = millis();
                                                unsigned long goal = millis() + interval;
                                                while(currentMillis < goal) {
                                                  currentMillis = millis();
                                                }
                                              }
                                              
                                              void my_homekit_setup() {
                                                pinMode(PIN_SWITCH, OUTPUT);
                                                digitalWrite(PIN_SWITCH, HIGH);
                                                cha_switch_on.setter = cha_switch_on_setter;
                                                arduino_homekit_setup(&config);
                                               
                                                // Das hier kann verwendet werden, um den Status an HomeKit zurückzusenden,
                                                // falls ein zusätzlicher pysischer Button o.ä verwendet wird.
                                                
                                                // bool switch_is_on = true/false;
                                                // cha_switch_on.value.bool_value = switch_is_on;
                                                // homekit_characteristic_notify(&cha_switch_on, cha_switch_on.value);
                                              }
                                               
                                               
                                               
                                              void my_homekit_loop() {
                                                arduino_homekit_loop();
                                                const uint32_t t = millis();
                                                if (t > next_heap_millis) {
                                                  // heap-Info alle 30 Sekunden im seriellen Monitor ausgeben
                                                  next_heap_millis = t + 30 * 1000;
                                                  LOG_D("Free heap: %d, HomeKit clients: %d",
                                                      ESP.getFreeHeap(), arduino_homekit_connected_clients_count());
                                               
                                                }
                                              }
                                              

                                              Oder hab ich einen Denkfehler? So einfach kann es doch eigentlich gar nicht sein 😄

                                              cooper 1 Antwort Letzte Antwort Antworten Zitieren 0
                                              • cooper
                                                cooper @HomeKitDude zuletzt editiert von

                                                @homekitdude sagte in ESP8266 D1 Mini Relais als HomeKit Schalter ohne Bridge - Tutorial:

                                                while(currentMillis < goal) { currentMillis = millis(); }

                                                while(currentMillis < goal) {
                                                    currentMillis = millis();
                                                  }
                                                

                                                While ist wieder blocking… :heh:

                                                Eigentlich kannst du das Beispiel was ich geschickt habe 1:1 verwenden.
                                                Die Abfrage ob millis > goal ist muss einfach mit oh den loop() dann wird es ja auch laufend geprüft.

                                                H 1 Antwort Letzte Antwort Antworten Zitieren 0
                                                • H
                                                  HomeKitDude @cooper zuletzt editiert von HomeKitDude

                                                  @cooper
                                                  Soweit ich das sehe komme ich doch für mein Problem in keinem Fall an einem delay() oder der while-Schleife vorbei.

                                                  // Diese Funktion wird aufgerufen, wenn der Schalter in HomeKit betätigt wird
                                                  void cha_switch_on_setter(const homekit_value_t value) {
                                                    bool on = value.bool_value;
                                                    cha_switch_on.value.bool_value = on;
                                                    LOG_D("Switch: %s", on ? "ON" : "OFF");
                                                    //hier wird der kurze Impuls für den buttonPin ausgegeben (die Sekunde delay() ist unkritisch)
                                                    digitalWrite(buttonPin, HIGH);
                                                    delay(1000);
                                                    digitalWrite(buttonPin, LOW);
                                                    //hier muss das digitalWrite(...) für zehn Sekunden verzögert werden
                                                    digitalWrite(PIN_SWITCH, on ? HIGH : LOW);
                                                  }
                                                  

                                                  Nachdem der Impuls über den buttonPin abgegeben wurde müsste die Funktion doch weiter durchlaufen bzw. zu ende laufen müssen, um den ESP für HomeKit ansprechbar zu halten.
                                                  Das aber wiederum führt dazu, dass

                                                  digitalWrite(PIN_SWITCH, on ? HIGH : LOW);
                                                  

                                                  ausgeführt wird und das Relais schaltet. Und zwar ohne die zehn Sekunden wartezeit, die der buttonPin benötigt und sein Script auszuführen.
                                                  Ich bekomm es grade nicht auf die Kette, wie ich da die millis()-Funktion implementieren kann, damit das läuft. Entweder ich bin zu eingerostet oder ich denke zu kompliziert…

                                                  cooper 1 Antwort Letzte Antwort Antworten Zitieren 0
                                                  • cooper
                                                    cooper @HomeKitDude zuletzt editiert von cooper

                                                    @homekitdude sagte in ESP8266 D1 Mini Relais als HomeKit Schalter ohne Bridge - Tutorial:

                                                    Soweit ich das sehe komme ich doch für mein Problem in keinem Fall an einem delay() oder der while-Schleife vorbei.

                                                    Nein es geht auch ohne. :heh: Hab mich jetzt kurz an den PC gesetzt und den Sketch mal dementsprechend umgeschrieben. :programmingparrot:

                                                    Zuerst habe ich ein paar Variablen erstellt - orientier dich dabei bitte an dem Blink without delay()-Beispiel. Das sollte dir bekannt vorkommen.

                                                    const long switchDelay = 10000;
                                                    unsigned long changedAt = 0;
                                                    bool checkForUpdate;
                                                    

                                                    Die Variable checkForUpdate ist da, um die Funktion des Prüfens später auszucanclen, sonst würde sie in Dauerschleife laufen.

                                                    Zusätzlich dazu, habe ich die Variable on für den Status global gesetzt, sodass ich auch außerhalb der Funktion cha_switch_on_setter() darauf zugreifen kann.

                                                    bool on;
                                                    
                                                    // Diese Funktion wird aufgerufen, wenn der Schalter in HomeKit betätigt wird
                                                    void cha_switch_on_setter(const homekit_value_t value) {
                                                      on = value.bool_value;
                                                      // hier der ganze Rest der Funktion
                                                    
                                                      checkForUpdate = true;
                                                    }
                                                    

                                                    ^ innerhalb dieser Funktion wird auch dein buttonPin auf HIGH bzw. LOW gesetzt.

                                                    Nach Ablauf der 10 Sekunden, wird der Status und der Zustand des Relais geädert:

                                                    if (millis() - changedAt >= switchDelay && checkForUpdate == true) {
                                                        checkForUpdate = false;
                                                        changedAt = millis();
                                                    
                                                        cha_switch_on.value.bool_value = on;
                                                        homekit_characteristic_notify(&cha_switch_on, cha_switch_on.value);
                                                        LOG_D("Switch: %s", on ? "ON" : "OFF");
                                                    
                                                    }
                                                    

                                                    Sobald checkForUpdate = false gesetzt wird, wird diese Abfrage übersprungen - sonst würde sich dein Relais wieder selbst aus- und wieder anschalten. Die Prüfung läuft sonst einfach durchgehend im Loop.

                                                    PS: Es könnte sein, dass du den switchDelay = 10000 etwas reduzieren musst, da du ja bereits ein delay(1000) drinnen hast und auch nach jedem loop() nochmal ein delay(10) drinnen ist.

                                                    void loop() {
                                                      my_homekit_loop();
                                                      delay(10);
                                                    }
                                                    

                                                    Hier siehst du nochmal die Ausschaltverzögerun und das Triggern des zusätzlichen GPIOs:


                                                    Das hier sind btw die beiden wichtigen Zeilen zum Schalten des Schalters in HomeKit.

                                                     
                                                    cha_switch_on.value.bool_value = true;
                                                    homekit_characteristic_notify(&cha_switch_on, cha_switch_on.value);
                                                    
                                                    //bzw.
                                                    
                                                    cha_switch_on.value.bool_value = false;
                                                    homekit_characteristic_notify(&cha_switch_on, cha_switch_on.value);
                                                    

                                                    Code für Aus- und Einschaltverzögerung

                                                    #include <Arduino.h>
                                                    #include <arduino_homekit_server.h>
                                                    #include "wifi_info.h"
                                                     
                                                    #define LOG_D(fmt, ...)   printf_P(PSTR(fmt "\n") , ##__VA_ARGS__);
                                                    const int buttonPin = 13;
                                                     
                                                    void setup() {
                                                      Serial.begin(115200);
                                                      wifi_connect();
                                                      pinMode(buttonPin, OUTPUT);
                                                      my_homekit_setup();
                                                    }
                                                     
                                                    void loop() {
                                                      my_homekit_loop();
                                                      delay(10);
                                                    }
                                                     
                                                    //==============================
                                                    // HomeKit setup and loop
                                                    //==============================
                                                     
                                                    // Zugriff auf die Definitionen des Accessories in my_accessory.c
                                                    extern "C" homekit_server_config_t config;
                                                    extern "C" homekit_characteristic_t cha_switch_on;
                                                     
                                                    static uint32_t next_heap_millis = 0;
                                                     
                                                    #define PIN_SWITCH 15
                                                     
                                                    
                                                    const long switchDelay = 10000;
                                                    unsigned long changedAt = 0;
                                                    bool checkForUpdate;
                                                    
                                                    bool on;
                                                    
                                                    // Diese Funktion wird aufgerufen, wenn der Schalter in HomeKit betätigt wird
                                                    void cha_switch_on_setter(const homekit_value_t value) {
                                                      on = value.bool_value;
                                                      
                                                      digitalWrite(buttonPin, HIGH);
                                                      LOG_D("buttonPin HIGH");
                                                    
                                                      delay(1000);
                                                      
                                                      digitalWrite(buttonPin, LOW);
                                                      LOG_D("buttonPin LOW");
                                                      changedAt = millis();
                                                    
                                                      checkForUpdate = true;
                                                    
                                                      /*
                                                       * Wait 10 Seconds
                                                       * wird in my_homekit_loop() aufgerufen.
                                                      */
                                                    }
                                                    
                                                     
                                                    void my_homekit_setup() {
                                                      pinMode(PIN_SWITCH, OUTPUT);
                                                      digitalWrite(PIN_SWITCH, HIGH);
                                                      cha_switch_on.setter = cha_switch_on_setter;
                                                      arduino_homekit_setup(&config);
                                                     
                                                      // Das hier kann verwendet werden, um den Status an HomeKit zurückzusenden,
                                                      // falls ein zusätzlicher pysischer Button o.ä verwendet wird.
                                                      
                                                      // bool switch_is_on = true/false;
                                                      // cha_switch_on.value.bool_value = switch_is_on;
                                                      // homekit_characteristic_notify(&cha_switch_on, cha_switch_on.value);
                                                    }
                                                     
                                                    void my_homekit_loop() {
                                                    
                                                      arduino_homekit_loop();
                                                      const uint32_t t = millis();
                                                      if (t > next_heap_millis) {
                                                        // heap-Info alle 30 Sekunden im seriellen Monitor ausgeben
                                                        next_heap_millis = t + 30 * 1000;
                                                        LOG_D("Free heap: %d, HomeKit clients: %d",
                                                            ESP.getFreeHeap(), arduino_homekit_connected_clients_count());
                                                     
                                                      }
                                                    
                                                    
                                                      if (millis() - changedAt >= switchDelay && checkForUpdate == true) {
                                                        checkForUpdate = false;
                                                        changedAt = millis();
                                                    
                                                        cha_switch_on.value.bool_value = on;
                                                        homekit_characteristic_notify(&cha_switch_on, cha_switch_on.value);
                                                        LOG_D("Switch: %s", on ? "ON" : "OFF");
                                                    
                                                      }
                                                    
                                                    }
                                                    

                                                    Es geht also doch ohne delay() und while :schmartie:

                                                    H 1 Antwort Letzte Antwort Antworten Zitieren 0
                                                    • H
                                                      HomeKitDude @cooper zuletzt editiert von HomeKitDude

                                                      @cooper
                                                      Chapeau 😳
                                                      Das hätte ich mit meinen rudimentären Java/Python/Arduino Kenntnissen aus dem Stand nicht hinbekommen.
                                                      Sehe da auch kaum Parallelen auf den ersten Blick zum Blink without delay() Beispiel. Aber im großen und ganzen hast du recht, dass das grundsätzlich sehr ähnlich ist. Nur nicht für einen Laien wie mich 😅
                                                      Vielen Dank auf jeden Fall schon mal! ☺️

                                                      1 Antwort Letzte Antwort Antworten Zitieren 0
                                                      • 1 / 1
                                                      • First post
                                                        Last post