espressif / esp-matter

Espressif's SDK for Matter
Apache License 2.0
610 stars 146 forks source link

Custom bridge endpoints, round 2 (CON-782) #647

Closed jonsmirl closed 1 month ago

jonsmirl commented 9 months ago

My first idea on how to do this was to use the standard bridge endpoints and then modify the endpoint after it was constructed. That's what this PR does: https://github.com/espressif/esp-matter/pull/640

Having worked on this for a couple of days I believe a better approach would be to eliminate esp_matter_bridge:: set_device_type() https://github.com/espressif/esp-matter/blob/main/components/esp_matter_bridge/esp_matter_bridge.cpp#L179 And then handle the creating of endpoints in user code via a callback. Doing it that way lets me add new device types without having to modify esp_matter. This wouldn't be for just custom devices types, all device types the bridge supports would work this way. The bridge will still store the device type in NVS and use the callback when the bridge is restored.

I'll code this up and submit a new PR.

jonsmirl commented 9 months ago

I created a PR for the needed hook. https://github.com/espressif/esp-matter/pull/710

jonsmirl commented 9 months ago

This change would be better if app_bridged_device_address_t were moved into esp-matter. https://github.com/espressif/esp-matter/blob/main/examples/common/app_bridge/app_bridged_device.h#L22

Then rework them like this...

Move the message type to the first field, and then allow for some custom message types to the update function. That would let me split my updates off from the bridge updates more easily.

Once app_bridged_device_address_t is in esp-matter the void pointer on create and resume can be changed to app_bridged_device_address_t*.

/** Bridged Device Type */
typedef enum {
    /** ZigBee */
    ESP_MATTER_BRIDGED_DEVICE_TYPE_ZIGBEE = 0,
    /** BLE Mesh */
    ESP_MATTER_BRIDGED_DEVICE_TYPE_BLEMESH,
    /** ESP-NOW */
    ESP_MATTER_BRIDGED_DEVICE_TYPE_ESPNOW,
    /** CUSTOM 1 */
    ESP_MATTER_BRIDGED_DEVICE_TYPE_CUSTOM1,
    /** CUSTOM 2 */
    ESP_MATTER_BRIDGED_DEVICE_TYPE_CUSTOM2,
    /** CUSTOM 3 */
    ESP_MATTER_BRIDGED_DEVICE_TYPE_CUSTOM3,
} app_bridged_device_type_t;

/* Bridged Device Address */
typedef union {
    /** ZigBee */
    struct {
        uint8_t zigbee_endpointid;
        uint16_t zigbee_shortaddr;
    };
    /** BLE Mesh */
    struct {
        uint16_t blemesh_addr;
    };
    /** ESP-NOW */
    struct {
        uint8_t espnow_macaddr[6];
    };
} app_bridged_device_address_t;

/* Bridged Device */
typedef struct app_bridged_device {
    /** Type of Bridged Device */
    app_bridged_device_type_t dev_type;
    /** Bridged Device */
    esp_matter_bridge::device_t *dev;
    /** Address of Bridged Device */
    app_bridged_device_address_t dev_addr;
    /** Pointer of Next Bridged Device */
    struct app_bridged_device *next;
    /* User initialization data */
    void *priv_data;
} app_bridged_device_t;
jonsmirl commented 1 month ago

The best way to solve this is to copy the bridge support code from the examples/common directory into your own app and start modifying it. That is what I did.