mongoose-os-apps / example-homekit

Demo application for HomeKit ADK
Apache License 2.0
7 stars 5 forks source link

How we can create an accessory dynamically #2

Closed jkano closed 4 years ago

jkano commented 4 years ago

Hi,

I'm creating an image of a ESP32 that talks to other devices using the serial port and asks for the device information (name, hw ver, fw ver, etc) and also it asks the device capabilities (e.g serial device is a Switch or Temperature sensor, etc) so depending on the device response the ESP32 has to create the correct HAPAccessory (setting the services and characteristics).

I'm checking that the accessory.services variable is a const so how we can add services dynamically to that variable if it is defined in HAP as a const?

rojer commented 4 years ago

the set of services is constant and cannot be changed without recreating the accessory. i think this looks like the use case for accessory proxy. i have not tried it myself though.

jkano commented 4 years ago

Thanks for the reply. What I'm looking for is:

In the example you have the accessory is created like this:

static HAPAccessory accessory = {
    .aid = 1,
    .category = kHAPAccessoryCategory_LightBulb,
    .name = CS_STRINGIFY_MACRO(HAP_PRODUCT_NAME),
    .manufacturer = CS_STRINGIFY_MACRO(HAP_PRODUCT_VENDOR),
    .model = CS_STRINGIFY_MACRO(HAP_PRODUCT_MODEL),
    .serialNumber = NULL,     // Set from config.
    .firmwareVersion = NULL,  // Set from build_id.
    .hardwareVersion = CS_STRINGIFY_MACRO(HAP_PRODUCT_HW_REV),
    .services =
        (const HAPService *const[]){&mgos_hap_accessory_information_service,
                                    &mgos_hap_protocol_information_service,
                                    &mgos_hap_pairing_service,
                                    &lightBulbService, NULL},
    .callbacks = {.identify = IdentifyAccessory}};

I would like to create a dynamic accessory, basically before creating this accessory variable, all the information of the device will be retrieved using serial port. Then, using all it's info, the .category, .name, .manufacturer, .model, etc, will be populated.

The only issue I'm seeing is the .services variable as it is a const. I would like to populate the .service variable depending on the device type. (e.g. If the device is a Switch, I will add a switchService, if the device is a lightBulb I will add the lightBulbService) also, the device maybe can have multiple services (e.g a Switch device that has 2 channels will have switchService1, switchService2) but I don't know how to do it as the .services variable is a const.

Is there a way to initialize this variable the way I'm looking to do?

rojer commented 4 years ago

oh, i see. yes, by all means - do whatever you need before creating the service, heap-allocate all the arrays and structures and only then create accessory. it's not going to be pretty but it's doable.

jkano commented 4 years ago

Thanks for the reply.

Yeah, that's what I'm trying to do but the accessory variable is declared as a global var on the App.c and other functions uses it (AppAccessoryServerStart and AppAccessoryGetInfo). So, once declared as a global var it can't be changed (the .services).

This is what I'm doing, in the AppInitialize I'm requesting all the device info and then I create a HAPAccessory local var with all the device info and the correct .services, but my question is how I can assign this local var info to the global variable or return this variable on the other functions (AppAccessoryServerStart and AppAccessoryGetInfo).

Thanks

rojer commented 4 years ago

you'll have to make it dynamically allocated and pass a pointer around where it's needed. it's basic C knowledge, really. sorry, i don't have time to teach it.

jkano commented 4 years ago

Yeah, sorry about that. I was not thinking clearly. Already did it, I created the accessory and allocated the memory for it. Then I pass the pointer to it on the other functions. Thanks for the sugestions.

rojer commented 4 years ago

ok, glad you managed it. it seems like a rare use case, i don't think i will be adding it to the code in the interest of clarity.

jkano commented 4 years ago

Yeah.. it's only that we want to have a single image for an esp32 that can convert our non-wifi devices into HomeKit compatible devices. But yeah, it's a rare case. Thanks for your help