maximkulkin / esp-homekit

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

Differentiate same HOMEKIT_SERVICE #73

Closed GermanSheepDog closed 5 years ago

GermanSheepDog commented 5 years ago

Hello,

I like to control some LED or some other actors of same service-type. For example I used the HOMEKIT_SERVICE_LIGHTBULB:

HOMEKIT_SERVICE(LIGHTBULB, .primary=true, .characteristics=(homekit_characteristic_t*[]){
            HOMEKIT_CHARACTERISTIC(NAME, "Sample LED"),
            HOMEKIT_CHARACTERISTIC(
                ON, false,
                .getter=led_on_get1,
                .setter=led_on_set1
            ),
            NULL
        }),
        NULL

For the second bulb, I use led_on_get2 and led_on_set2 and so on. It would be a great deal, if I can give with a parameter called 'getter_arg':

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,
                .getter_arg=<my_arg>
            ),
            NULL
        }),
        NULL

I think that was the need to expand "types.h":

    //homekit_value_t (*getter)(); <- old
    homekit_value_t (*getter)(unsigned int getter_arg);
    uint8_t getter_arg;
    //void (*setter)(const homekit_value_t); <- old
    void (*setter)(unsigned int getter_arg, const homekit_value_t);

The new 'getter_arg' will be used for getter and setter call! So I can use the same functions for many bulbs or other actors.

With some more stuff you can implement such functions in app_main:

  ret = homekit_register (HOMEKIT_SERVICE_LIGHTBULB, "LED1", &handle_homekit_LED, (void*) 1);
  ret = homekit_register (HOMEKIT_SERVICE_LIGHTBULB, "LED2", &handle_homekit_LED, (void*) 2);
  ret = homekit_register (HOMEKIT_SERVICE_LIGHTBULB, "LED3", &handle_homekit_LED, (void*) 3);
RavenSystem commented 5 years ago

This improvement will be welcome for me.

maximkulkin commented 5 years ago

Ok, I have implemented a new getter/setter API. Characteristics now have three new fields:

getter_ex/setter_ex are function pointers that take characteristic pointer as first argument. You can use characteristic to distinguish between characteristics.

Alternatively, you can use context field (void*) to store pointer to any other data and you can use that data inside getter_ex/setter_ex callbacks.