maximkulkin / esp-homekit

Apple HomeKit accessory server library for ESP-OPEN-RTOS
MIT License
1.1k stars 168 forks source link

How can I update to the current status of a lock in HomeKit ? #183

Open Denss02 opened 3 years ago

Denss02 commented 3 years ago

Hello, I would like to switch the electric strike of my front door. My current code works but do not show the right state and shows up as switch. The relay turns on for 2500ms and after that off but the state is now on/unlocked while the door is off/locked again. But I want to see it as door lock in HomeKit (what works) with the right state (what doesn't work). Here is my try with the door lock shown up in HomeKit (it does not show the right state):

#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();
  my_homekit_setup();
  //homekit_storage_reset();
}

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

//==============================
// HomeKit setup and loop
//==============================

extern "C" homekit_server_config_t config;
extern "C" homekit_characteristic_t lockTar;

static uint32_t next_heap_millis = 0;

#define PIN_SWITCH 15

void lockTar_setter(const homekit_value_t value) {
  bool on = value.bool_value;
  lockTar.value.bool_value = 0;
  LOG_D("Switch: %s", on ? "ON" : "OFF");
  //digitalWrite(PIN_SWITCH, on ? HIGH : LOW);

   if(lockTar.value.bool_value == 0){
     digitalWrite(PIN_SWITCH, HIGH);
     delay(2500); 
     digitalWrite(PIN_SWITCH, LOW);  
   } 
   else{
     digitalWrite(PIN_SWITCH, HIGH);
     delay(2500); 
     digitalWrite(PIN_SWITCH, LOW);  
   }
}

void my_homekit_setup() {

  pinMode(PIN_SWITCH, OUTPUT);
  digitalWrite(PIN_SWITCH, LOW);
  lockTar.setter = lockTar_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());

  }
}

Accessory:

#include <homekit/homekit.h>
#include <homekit/characteristics.h>

bool armed = false;
bool door_closed = false;

void my_accessory_identify(homekit_value_t _value) {
  printf("accessory identify\n");
}

void update_state();

void on_update(homekit_characteristic_t *ch, homekit_value_t value, void *context) {
    update_state();
}

homekit_characteristic_t lockCur = HOMEKIT_CHARACTERISTIC_(LOCK_CURRENT_STATE, 0);
homekit_characteristic_t lockTar = HOMEKIT_CHARACTERISTIC_(LOCK_TARGET_STATE, 0,.callback=HOMEKIT_CHARACTERISTIC_CALLBACK(on_update));

homekit_characteristic_t cha_name = HOMEKIT_CHARACTERISTIC_(NAME, "Haustür");

void update_state() {

  uint8_t newstate = lockTar.value.int_value;

  if (newstate == 1) {
    if (door_closed){
      armed = true;
      //printf("Locked!\n");
      lockCur.value = lockTar.value;
      homekit_characteristic_notify(&lockCur, lockCur.value);
    } else {
      homekit_characteristic_notify(&lockCur, HOMEKIT_UINT8(2));
    }
  }
  if (newstate == 0) {
    armed = false;
    //printf("Unlocked!\n");
    lockCur.value = lockTar.value;
    homekit_characteristic_notify(&lockCur, lockCur.value);
  }
}

homekit_accessory_t *accessories[] = {
    HOMEKIT_ACCESSORY(.id=1, .category=homekit_accessory_category_door_lock, .services=(homekit_service_t*[]) {
        HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]) {
            HOMEKIT_CHARACTERISTIC(NAME, "Haustür"),
            HOMEKIT_CHARACTERISTIC(MANUFACTURER, "Denis"),
            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(
                LOCK_MECHANISM,
                .primary=true,
                .characteristics=(homekit_characteristic_t*[]) {
                    &lockCur,
                    &lockTar,
                    &cha_name,
                    NULL
    }),
        NULL
    }),
    NULL
};

homekit_server_config_t config = {
    .accessories = accessories,
    .password = "123-45-678"
};

I hope anyone can help.

Kind regards Denis

maximkulkin commented 3 years ago

This example should show up as a lock.

Denss02 commented 3 years ago

@maximkulkin Yes. My Problem is with the example that i can't find all of the libraries. Also I'm not so familiar with the HomeKit library. I only need the right status of the relay. Also I have the problem that the ESP show no response after ~ 2 days.