HomeKit - mriksman/esp-idf-homekit GitHub Wiki
ESP-HomeKit
http-parser/http_parser.h
is the same one found in ESP8266 RTOS SDK components. In ESP-IDF, you need to instead include nghttp
. To use Espressif's http-parser
, you would need to modify the include
, so it's just easier to grab a copy of http-parser
and place it in components
When using esp_random()
, ESP8266 RTOS SDK will panic on first boot. Known issue. Restart, and you can begin pairing. However, pairing does not complete successfully. Swapping out this function with os_get_random()
solves this issue.
Need to increase Watchdog Timeout (Component config → Common ESP-related → Task Watchdog timeout period (seconds)
) to 26.2144s
.
Setting Minimize firmware size
reduces the firmware size by 70KB, but increases the pairing time from 20 seconds to 34 seconds. If you can spare the space, you should!
Had to add this to both CMakeLists
for wolfssl
_and _ esp-homekit
if(CONFIG_HOMEKIT_SMALL)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} \
-DCURVE25519_SMALL \
-DED25519_SMALL"
)
endif()
Getter, Setter, Callback
If you use .getter and/or .setter, it will override the usual internal method of getting and setting the characteristic value.
- Service is part of the accessory declaration;
HOMEKIT_SERVICE(LIGHTBULB, .primary=true, .characteristics=(homekit_characteristic_t*[]){
HOMEKIT_CHARACTERISTIC(NAME, "Sample LED"),
HOMEKIT_CHARACTERISTIC(
ON, false,
.getter=led_on_get,
.setter=led_on_set
),
You’ll need to save the internal state to global variable and retrieve from it;
homekit_value_t led_on_get() {
return HOMEKIT_BOOL(led_on);
}
void led_on_set(homekit_value_t value) {
led_on = value.bool_value;
led_write(led_on);
}
- The Service is declared with a variable;
HOMEKIT_SERVICE(LIGHTBULB, .primary=true, .characteristics=(homekit_characteristic_t*[]){
HOMEKIT_CHARACTERISTIC(NAME, "LED"),
&lightbulb_service,
NULL
}),
homekit_characteristic_t lightbulb_service = HOMEKIT_CHARACTERISTIC_(
ON, false,
.getter=led_on_get,
.setter=led_on_set
);
You can then store the value to lightbulb_service.value.bool_value
.
- Use
.callback
. You can read the internal state with_ch->value
, or directly fromlightbulb1_service.value.bool_value
which will update automatically (as you have not overridden with.getter
and.setter
)
homekit_characteristic_t lightbulb1_service = HOMEKIT_CHARACTERISTIC_(
ON, false, .callback=HOMEKIT_CHARACTERISTIC_CALLBACK(
lightbulb_callback, .context=&light1_gpio
)
);
void lightbulb_callback(homekit_characteristic_t *_ch, homekit_value_t value, void *context) {
int light_gpio = *((uint8_t*) context);
gpio_set_level(light_gpio, value.bool_value ? 0 : 1);
}
This makes it easier to use a single callback for multiple services of the same type (multiple lights). Each one can have a context set to the GPIO number of the light they control.
When a physical button press is detected, it can read directly from lightbulb1_service.value.bool_value
, toggle it, and notify the characteristic of the change.
lightbulb1_service.value.bool_value = !lightbulb1_service.value.bool_value;
homekit_characteristic_notify(&lightbulb1_service, lightbulb1_service.value);
I can’t see a reason why you wouldn’t use .callback
.
You can grab information from the characteristic variable;
homekit_characteristic_t *service_name = homekit_service_characteristic_by_type(
_ch->service, HOMEKIT_CHARACTERISTIC_NAME
);
ESP_LOGI(TAG, "Name: %s", service_name->value.string_value);