esp-homekit-demo icon indicating copy to clipboard operation
esp-homekit-demo copied to clipboard

HomeKit Devices shows No Response

Open AR-Tawil opened this issue 4 years ago • 4 comments

Hi, I'm really puzzled about the non responsive state of my devices. I noticed that my accessories becomes unresponsive immediately once my Home App is running in the background. It take around 30 seconds for the accessories to become available when I return to the home App and some even takes longer.

I'm using an ipad as my home hub for automation and for sharing resources. I can keep accessories responsive if I leave the home app opened on my iPad and on active state running in the foreground?!!! Also, I sometimes get a DHCP is not healthy network alerts but not sure why this happens?

Can you please advise if you have encountered similar issue and how you managed to overcome it.

Thank you for your excellent work and appreciate your support.

AR Tawil

IMG_8634

AR-Tawil avatar Aug 12 '20 17:08 AR-Tawil

This is the code I'm using:

#include <stdio.h>
#include <espressif/esp_wifi.h>
#include <espressif/esp_sta.h>
#include <esp/uart.h>
#include <esp8266.h>
#include <FreeRTOS.h>
#include <task.h>

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

#include "mqtt_client.c"

#include <lwip/err.h>
#include <lwip/sockets.h>
#include <lwip/sys.h>
#include <lwip/netdb.h>
#include <lwip/dns.h>

/* Add extras/sntp component to makefile for this include to work */
#include <sntp.h>
#include <time.h>
#include <string.h>
#include <ota-api.h>

#define SNTP_SERVERS 	"0.pool.ntp.org", "1.pool.ntp.org", \
						"2.pool.ntp.org", "3.pool.ntp.org"

#define vTaskDelayMs(ms)	vTaskDelay((ms)/portTICK_PERIOD_MS)
#define UNUSED_ARG(x)	(void)x

time_t ts; 

int c_hash_previous = 0;

homekit_characteristic_t ota_trigger  = API_OTA_TRIGGER;
homekit_characteristic_t manufacturer = HOMEKIT_CHARACTERISTIC_(MANUFACTURER,  "IoT Smart Solutions");
homekit_characteristic_t serial       = HOMEKIT_CHARACTERISTIC_(SERIAL_NUMBER, "48:3F:DA:54:F6:1F");
homekit_characteristic_t model        = HOMEKIT_CHARACTERISTIC_(MODEL,         "KitcheHubLight");
homekit_characteristic_t revision     = HOMEKIT_CHARACTERISTIC_(FIRMWARE_REVISION,  "0.0.1");

char* concat(const char *s1, const char *s2, const char *s3)
{
    char *result = malloc(strlen(s1) + strlen(s2) + strlen(s3) + 1); // +1 for the null-terminator
    // in real code you would check for errors in malloc here
    strcpy(result, s1);
    strcat(result, s2);
    strcat(result, s3);
    return result;
}

void removeStringTrailingNewline(char *str) {
  if (str == NULL)
    return;
  int length = strlen(str);
  if (str[length-1] == '\n')
    str[length-1]  = '\0';
}

static void wifi_init() {
    struct sdk_station_config wifi_config = {
        .ssid = WIFI_SSID,
        .password = WIFI_PASSWORD,
    };

    sdk_wifi_set_opmode(STATION_MODE);
    sdk_wifi_station_set_config(&wifi_config);
    sdk_wifi_station_connect();
}

void sntp_tsk(void *pvParameters)
{
	const char *servers[] = {SNTP_SERVERS};
	UNUSED_ARG(pvParameters);

	/* Wait until we have joined AP and are assigned an IP */
	while (sdk_wifi_station_get_connect_status() != STATION_GOT_IP) {
		vTaskDelayMs(100);
	}

	/* Start SNTP */
	printf("Starting SNTP... ");
	/* SNTP will request an update each 60 minutes */
	sntp_set_update_delay(60*60000);
	/* Set GMT+1 zone, daylight savings off */
	const struct timezone tz = {1*60, 0};
	/* SNTP initialization */
	sntp_initialize(&tz);
	/* Servers must be configured right after initialization */
	sntp_set_servers(servers, sizeof(servers) / sizeof(char*));
	printf("DONE!\n");

	/* Print date and time each 5 seconds */
	while(1) {
		vTaskDelayMs(60000);
		ts = time(NULL);
		printf("TIME: %s", ctime(&ts));
	}
}

const int led_gpio = 16;
bool led_on = false;


void led_write(bool on) {
    gpio_write(led_gpio, on ? 0 : 1);

}

void led_init() {
    gpio_enable(led_gpio, GPIO_OUTPUT);
    led_write(led_on);
}

void led_identify_task(void *_args) {
    for (int i=0; i<3; i++) {
        for (int j=0; j<2; j++) {
            led_write(true);
            vTaskDelay(100 / portTICK_PERIOD_MS);
            led_write(false);
            vTaskDelay(100 / portTICK_PERIOD_MS);
        }

        vTaskDelay(250 / portTICK_PERIOD_MS);
    }

    led_write(led_on);
    vTaskDelete(NULL);
}

void led_identify(homekit_value_t _value) {
    printf("LED identify\n");
    xTaskCreate(led_identify_task, "LED identify", 128, NULL, 2, NULL);
}

homekit_value_t led_on_get() {
    return HOMEKIT_BOOL(led_on);
}

void led_on_set(homekit_value_t value) {
    if (value.format != homekit_format_bool) {
        printf("Invalid value format: %d\n", value.format);
        return;
    }

    char*  action_time = ctime(&ts);
   removeStringTrailingNewline (action_time);
    led_on = value.bool_value;
    printf("led Valueeee = %d\n", led_on); 
    char* time_on = concat("{ \"device type\": \"light\", \"serial number\": \"48:3F:DA:54:F6:1F\", \"status\": \"ON\", \"time\":\" " , action_time, "\" }");
    char* time_off = concat("{ \"device type\": \"light\", \"serial number\": \"48:3F:DA:54:F6:1F\", \"status\": \"OFF\", \"time\":\" " , action_time, "\" }");

    sendMqttMessage(led_on ? time_on : time_off);
    //sendMqttMessage(led_on ? "{ \"status\": \"ON\", \"time\" : " + " \" "  + ctime(&ts) + " \" }"   : "OFF");

    led_write(led_on);
}


homekit_accessory_t *accessories[] = {
    HOMEKIT_ACCESSORY(.id=1, .category=homekit_accessory_category_lightbulb, .services=(homekit_service_t*[]){
        HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]){
            HOMEKIT_CHARACTERISTIC(NAME, "Kitchen Hub Light"),
            &manufacturer,
            &serial,
            &model,
            &revision,
            HOMEKIT_CHARACTERISTIC(IDENTIFY, led_identify),
            NULL
                }),
        HOMEKIT_SERVICE(LIGHTBULB, .primary=true, .characteristics=(homekit_characteristic_t*[]){
            HOMEKIT_CHARACTERISTIC(NAME, "Kitchen Hub Light"),
            HOMEKIT_CHARACTERISTIC(
                ON, false,
                .getter=led_on_get,
                .setter=led_on_set
            ),
             &ota_trigger,
            NULL
        }),
        NULL
    }),
    NULL
};

homekit_server_config_t config = {
    .accessories = accessories,
    .password = "111-11-009"
};

void user_init(void) {
    uart_set_baud(0, 115200);
    wifi_init();
   /*  int c_hash=ota_read_sysparam(&manufacturer.value.string_value,&serial.value.string_value,
                                      &model.value.string_value,&revision.value.string_value);
	printf("c_hash = %d\n", c_hash);
    //c_hash=1; revision.value.string_value="0.0.1"; //cheat line
    config.accessories[0]->config_number=c_hash; 
	//printf("config.accessories[000000000000000000] = %d\n", config.accessories[0]->config_number);  */
    led_init();
    homekit_server_init(&config);
    xTaskCreate(sntp_tsk, "SNTP", 1024, NULL, 1, NULL);
}

Folder Structure:

folder_structure

AR-Tawil avatar Aug 12 '20 17:08 AR-Tawil

Not sure why you get "DHCP is unhealthy" messages, this might be related to your network router configuration, but that might cause issues with HomeKit. It takes some time for iOS to query accessory state after going out of sleep, so it is expected. However, accessories should not show up as "No Response", there should be a "Updating" status. Can you send debug logs from a device when it experiences a problem.

maximkulkin avatar Aug 12 '20 17:08 maximkulkin

Thank you for your reply Maxim.

Please see below my network details and let me know if you can spot something wrong. I'm not sure why Brand and Model, Bonjour and DHCP are not showing any details. Also I noticed that my router is not able to recognise the names for my devices?!!

Fing router

AR-Tawil avatar Aug 13 '20 17:08 AR-Tawil

It says that you do not have DHCP active. That won't work. You need DHCP running.

maximkulkin avatar Aug 13 '20 18:08 maximkulkin