Wie Homekit Schalter Sketch zu Taster umschreiben?



  • Hey,
    ich würde ich gerne meinen Fernseher an und ausschalten können, ich habe an den ein/aus Taster Kabel angelötet. Wenn ich diese kurz zusammen halte, geht der Fernseher an, und wenn ich das nochmal mache, wieder aus. Ich würde gerne wenn möglich das ganze mit dem D1 mini und einem Relais machen machen, den HomeKit Schalter https://my.makesmart.net/topic/83/esp8266-d1-mini-relais-als-homekit-schalter-ohne-bridge-tutorial habe ich bereits getestet, aber dieser lässt dauerhaft Strom durch, nun meine Frage: ist es möglich den code für die HomeKit Relais ohne Bridge so umzuschreiben, so das das Relais für eine Sekunde geöffnet und dann wieder geschlossen wird, aber trotzdem in HomeKit an steht nach dem 1. betätigen, und aus nach dem 2.? ich hoffe ihr könnt mir helfen, Liebe Grüße



  • Hallo @JonasPies1912

    schick von deinem verwendeten Code doch mal den Abschnitt, in dem das Relais geschaltet wird bzw. den ganzen Sketch. So kann man dir wahrscheinlich besser helfen.



  • Der sketch besteht aus 3 teilen (mein_schalter & my_accessory.c & wifi_info.h) meiner Meinung ist nur der 1. und 2. für das schalten und anzeigen des status zuständig.

    1.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);
    }
    
    //==============================
    // 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.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.wifi_info.h:

    #ifndef WIFI_INFO_H_
    #define WIFI_INFO_H_
    
    #if defined(ESP8266)
    #include <ESP8266WiFi.h>
    #elif defined(ESP32)
    #include <WiFi.h>
    #endif
    
    const char *ssid = "Jonas FRITZ!Box";
    const char *password = "12345678901234";
    
    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
    

    Das sind 3 separate Tabs nach jedem : ein neuer Tab



  • Ja, da hast du recht. Für den Schalter ist im Endeffekt nur der erste Sketch zuständig.

    Und zwar die folgenden Zeilen:

    // 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);
    }
    

    Das kannst du ganz leicht bearbeiten, um dein Vorhaben umzusetzen.

    Das hier ist einfach gesagt ein verkürzes If-Statement:

    digitalWrite(PIN_SWITCH, on ? HIGH : LOW);
    

    ausgeschrieben würde es so aussehen:

      if(cha_switch_on.value.bool_value == on){
        digitalWrite(PIN_SWITCH, HIGH);
      }else{
        digitalWrite(PIN_SWITCH, LOW);   
      }
    

    Das kannst du dann also für deinen TV verwenden, indem du einfach den kompletten void cha_switch_on_setter() mit dem hier ersetzt:

    // 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);
    
      if(cha_switch_on.value.bool_value == on){
        digitalWrite(PIN_SWITCH, HIGH);
        delay(500); 
        digitalWrite(PIN_SWITCH, LOW);  
      }else{
        digitalWrite(PIN_SWITCH, HIGH);
        delay(500); 
        digitalWrite(PIN_SWITCH, LOW);   
      }
      
    }
    

    Das lässt dein Relais für 500ms Schalten und geht danach wieder aus. Der Schalter in HomeKit bleibt dennoch auf an. Beim Ausschalten das gleiche: Relais geht an für 500ms, danach wieder aus. Dann geht der Schalter in HomeKit auf aus.

    Wünsche dir viel Erfolg beim Umsetzen deines Smarten 📺 👍



  • vielen vielen Dank, funktioniert super