maximkulkin / esp-homekit

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

QUESTION : Dynamic "name" after init_accessory - without esp restart #198

Closed kiralikbeyin closed 2 years ago

kiralikbeyin commented 2 years ago

I am trying to change accessory name of a switch and also tried to change Tv -> _input_source1name

Is it possbile to change strings like int of accessory values..?

homekit_characteristic_t input_source1_name = HOMEKIT_CHARACTERISTIC_( CONFIGURED_NAME, "HDMI 1", .callback=HOMEKIT_CHARACTERISTIC_CALLBACK(on_input_configured_name) );

for example change HDMI 1 to Cinema after homekit accessory init (without esp restart)

maximkulkin commented 2 years ago

So, normally names of accessories are not expected to change. Those characteristic permissions do not even include write and notification permissions. Updating those values is not recommended. For TVs Apple used a separate type of characteristic - CONFIGURED_NAME (as opposed to normal NAME characteristic everywhere else) which permissions do include reading, writing and notifications. You can attach custom getters/setters for those characteristics that will get/put data from a persisted storage (e.g. sysparams):

sysparam_set_string("input1_name", value.string_value);

or

if (sysparam_get_string("input1_name", &s) == SYSPARAM_OK) {
    homekit_value_destruct(&input_source1_name.value);
    input_source1_name.value = HOMEKIT_STRING(s);
}
kiralikbeyin commented 2 years ago
...
homekit_characteristic_t input_source1_name = HOMEKIT_CHARACTERISTIC_(
    CONFIGURED_NAME, "HDMI 1",
    //.callback=HOMEKIT_CHARACTERISTIC_CALLBACK(on_input_configured_name),
    .getter = get_input_one,
    .setter = set_input_one
);

homekit_service_t input_source1 =
    HOMEKIT_SERVICE_(INPUT_SOURCE, .characteristics=(homekit_characteristic_t*[]){
        HOMEKIT_CHARACTERISTIC(NAME, "hdmi1"),
        HOMEKIT_CHARACTERISTIC(IDENTIFIER, 1),
        &input_source1_name,
        HOMEKIT_CHARACTERISTIC(INPUT_SOURCE_TYPE, HOMEKIT_INPUT_SOURCE_TYPE_HDMI),
        HOMEKIT_CHARACTERISTIC(IS_CONFIGURED, true),
        HOMEKIT_CHARACTERISTIC(CURRENT_VISIBILITY_STATE, HOMEKIT_CURRENT_VISIBILITY_STATE_SHOWN),
        NULL
    });

...
homekit_value_t get_input_one()
{
        sprintf(my_string,"%d", my_number);
        printf("get_input_one %s\n", my_string);

        taskYIELD();
        //homekit_value_destruct(&input_source1_name.value);
        input_source1_name.value = HOMEKIT_STRING(my_string);
        taskYIELD();

        //return HOMEKIT_STRING(my_string);
        return (input_source1_name.value);
}

void set_input_one()
{
        sprintf(my_string,"%d", my_number);
        printf("set_input_one %s\n", my_string);

        input_source1_name.value = HOMEKIT_STRING(my_string);
        printf("set_input_one input_source1_name %s\n", input_source1_name.value.string_value);

        //homekit_characteristic_notify(&input_source1_name, input_source1_name.value);
        homekit_characteristic_notify(&input_source1, input_source1_name.value);

}

if i remove free(value->string_value); input name changes only once,

void homekit_value_destruct(homekit_value_t *value) {
    if (!value->is_null) {
        switch (value->format) {
            case homekit_format_string:
                if (!value->is_static && value->string_value)
                    {
                      free(value->string_value);
                      ??
                    }
                break;
            case homekit_format_tlv:
                if (!value->is_static && value->tlv_values)
                    tlv_free(value->tlv_values);
                break;
            case homekit_format_data:
                if (!value->is_static && value->data_value)
                    free(value->data_value);
                break;
            default:
                // unknown format
                break;
        }
    }
}

if free(value->string_value); stays;

get_input_one 88
assertion "heap != NULL && "free() target pointer is outside heap areas"" failed: file "/Users/my/esp/esp-idf/components/heap/heap_caps.c", line 304, function: heap_caps_free

abort() was called at PC 0x400dc2bf on core 0
0x400dc2bf: __assert_func at /builds/idf/crosstool-NG/.build/HOST-x86_64-apple-darwin12/xtensa-esp32-elf/src/newlib/newlib/libc/stdlib/assert.c:62 (discriminator 8)

Backtrace:0x40088063:0x3ffd4d50 0x40088861:0x3ffd4d70 0x4008f63e:0x3ffd4d90 0x400dc2bf:0x3ffd4e00 0x400820c7:0x3ffd4e30 0x4008f669:0x3ffd4e50 0x4012f0a2:0x3ffd4e70 0x40130649:0x3ffd4e90 0x40131659:0x3ffd4ed0 0x40132de6:0x3ffd4ef0 0x400efdb9:0x3ffd4f10 0x40130926:0x3ffd4f70 0x40131e83:0x3ffd4fa0 0x40132f4c:0x3ffd4fe0 0x4008bf29:0x3ffd50a0
0x40088063: panic_abort at /Users/my/esp/esp-idf/components/esp_system/panic.c:368

0x40088861: esp_system_abort at /Users/my/esp/esp-idf/components/esp_system/system_api.c:112

0x4008f63e: abort at /Users/my/esp/esp-idf/components/newlib/abort.c:46

0x400dc2bf: __assert_func at /builds/idf/crosstool-NG/.build/HOST-x86_64-apple-darwin12/xtensa-esp32-elf/src/newlib/newlib/libc/stdlib/assert.c:62 (discriminator 8)

0x400820c7: heap_caps_free at /Users/my/esp/esp-idf/components/heap/heap_caps.c:304 (discriminator 1)

0x4008f669: free at /Users/my/esp/esp-idf/components/newlib/heap.c:46

0x4012f0a2: homekit_value_destruct at /Users/my/Documents/esp32-yeni/components/common/homekit/src/accessories.c:130

0x40130649: write_characteristic_json at /Users/my/Documents/esp32-yeni/components/common/homekit/src/server.c:594

0x40131659: homekit_server_on_get_accessories at /Users/my/Documents/esp32-yeni/components/common/homekit/src/server.c:2002 (discriminator 3)

0x40132de6: homekit_server_on_message_complete at /Users/my/Documents/esp32-yeni/components/common/homekit/src/server.c:2959

0x400efdb9: http_parser_execute at /Users/my/esp/esp-idf/components/nghttp/port/http_parser.c:1895 (discriminator 3)

0x40130926: homekit_client_process at /Users/my/Documents/esp32-yeni/components/common/homekit/src/server.c:3062

0x40131e83: homekit_run_server at /Users/my/Documents/esp32-yeni/components/common/homekit/src/server.c:3286

0x40132f4c: homekit_server_task at /Users/my/Documents/esp32-yeni/components/common/homekit/src/server.c:3450 (discriminator 3)

0x4008bf29: vPortTaskWrapper at /Users/my/esp/esp-idf/components/freertos/port/xtensa/port.c:168

@maximkulkin

i tried as you suggested but i'm stuck here..

kiralikbeyin commented 2 years ago

Ok i changed "my_string" char array variable to char pointer so it can be "free"