Skip to content

ESP-Rainmaker mobile app and Matter endpoints issue #375

Description

@KalashQK

Answers checklist.

  • I have read the Rainmaker documentation and the issue is not addressed there.
  • I have updated my IDF branch (release/vX.Y) to the latest version and checked that the issue is present there. This is not applicable if you are using Rainmaker with Arduino.
  • I have searched the Rainmaker forum and issue tracker for a similar issue and not found a similar issue.

IDF / ESP32-Arduino version.

ESP-IDF v5.5.4

Operating System used.

Linux

How did you build your project?

Command line with idf.py

Development Kit.

Custom board ESP32-Wroom-32

What is the expected behavior?

My node consists of several separate devices (a switch, addressable LEDs, and a few sensors). Everything operates correctly when controlled via the ESP-RainMaker cloud, and it should work just as well with local control via Matter. When I toggle the standalone switch, only that switch should activate, without affecting the lighting. Conversely, when I toggle the lighting switch, only the lighting should turn on, without affecting the standalone switch. In other words, commands from the ESP-RainMaker app need to be routed to distinct endpoints for the different devices.

What is the actual behavior?

Currently, cloud-based control via ESP-RainMaker works correctly; however, with local control via Matter, all commands from the ESP-RainMaker app are sent only to Endpoint 1. Endpoint 1 is currently configured for the addressable LEDs. When I turn on the LEDs, only the LEDs (Endpoint 1) activate. When I turn on the separate switch (Endpoint 2), the LEDs (Endpoint 1) activate instead. The same behavior occurs when turning them off. When I open the sensor readings page in the ESP-RainMaker app, the reading clusters for the endpoint are unrecognized. All devices are displayed using the name of Endpoint 1 (the LEDs).

Steps to reproduce.

  1. In app_main:
    light_handle = app_driver_light_init();
    app_driver_handle_t button_handle = app_driver_button_init(light_handle);

    switch_handle = app_driver_button_init(switch_handle);
    app_driver_switch_set_power(switch_handle, DEFAULT_SWITCH_POWER);
    button_driver_handle_t sbutton_handle = app_driver_button_init(switch_handle);
    //app_reset_button_register((button_handle_t)switch_handle, WIFI_RESET_BUTTON_TIMEOUT, FACTORY_RESET_BUTTON_TIMEOUT);

    temperature_sensor_handle = app_sensor_init();

  2. In app_driver:

app_driver_handle_t app_driver_light_init()
{
/* Initialize led */
led_driver_config_t config = led_driver_get_config();
led_driver_handle_t handle = led_driver_init(&config);
return (app_driver_handle_t)handle;
}

app_driver_handle_t app_driver_button_init(void *user_data)
{

button_handle_t shandle = NULL;

const button_config_t btn_cfg = {0};
const button_gpio_config_t btn_gpio_cfg = {
.gpio_num = OUTPUT_GPIO2,
.active_level = 0,
};

if (iot_button_new_gpio_device(&btn_cfg, &btn_gpio_cfg, &shandle) != ESP_OK) {
ESP_LOGE(TAG, "Failed to create button device");
return NULL;
}

button_gpio_config_t gpio_cfg = {
    .gpio_num = OUTPUT_GPIO2,
    .active_level = 0,
    .enable_power_save = false,
};


/* Configure power */
gpio_config_t io_conf = {
    .mode = GPIO_MODE_OUTPUT,
    .pull_up_en = GPIO_PULLUP_ENABLE,
};
io_conf.pin_bit_mask = ((uint64_t)1 << OUTPUT_GPIO);
/* Configure the GPIO */
gpio_config(&io_conf);




iot_button_register_cb(shandle, BUTTON_SINGLE_CLICK, NULL, app_driver_button_toggle_cb, user_data);
return (button_driver_handle_t)shandle;

}

  1. In app_matter_light
    esp_err_t app_attribute_update_cb(attribute::callback_type_t type, uint16_t endpoint_id, uint32_t cluster_id,
    uint32_t attribute_id, esp_matter_attr_val_t *val, void priv_data)
    {
    esp_err_t err = ESP_OK;
    printf("AttrCB Endpoint ID: %d", endpoint_id);
    //printf("AttrUpdate CB Light Endpoint ID: %d", light_endpoint_id);
    if (type == PRE_UPDATE) {
    /
    Driver update */
    if (endpoint_id == 1) {
    led_driver_handle_t handle = (led_driver_handle_t)priv_data;
    printf("AttrUpdate CB Light Endpoint ID: %d", light_endpoint_id);
    if (cluster_id == OnOff::Id) {
    if (attribute_id == OnOff::Attributes::OnOff::Id) {
    err = app_driver_light_set_power(handle, val->val.b);
    }
    } else if (cluster_id == LevelControl::Id) {
    if (attribute_id == LevelControl::Attributes::CurrentLevel::Id) {
    err = app_driver_light_set_brightness(handle, REMAP_TO_RANGE(val->val.u8, MATTER_BRIGHTNESS, STANDARD_BRIGHTNESS));
    }
    } else if (cluster_id == ColorControl::Id) {
    if (attribute_id == ColorControl::Attributes::CurrentHue::Id) {
    err = app_driver_light_set_hue(handle, REMAP_TO_RANGE(val->val.u8, MATTER_HUE, STANDARD_HUE));
    } else if (attribute_id == ColorControl::Attributes::CurrentSaturation::Id) {
    int value=val->val.u8;
    if(value>255) value=255;
    if(value==0) value=255;
    err = app_driver_light_set_saturation(handle, REMAP_TO_RANGE(value, MATTER_SATURATION, STANDARD_SATURATION));
    printf("app_attribute_update_cb: %.2d", value);
    } else if (attribute_id == ColorControl::Attributes::ColorTemperatureMireds::Id) {
    //err = led_driver_set_temperature(handle, REMAP_TO_RANGE_INVERSE(val->val.u16, STANDARD_TEMPERATURE_FACTOR));
    }
    }
    }

     if (endpoint_id == 2) {
     	led_driver_handle_t handle = (led_driver_handle_t)priv_data;
     	if (cluster_id == OnOff::Id) {
     		printf("AttrCB Endpoint ID: %d", endpoint_id);
             if (attribute_id == OnOff::Attributes::OnOff::Id) {
                 err = app_driver_switch_set_power(handle, val->val.b);
             }
         }
     }
    

    } else if (type == POST_UPDATE) {
    if (!rmaker_init_done) {
    ESP_LOGI(TAG, "RainMaker init not done. Not processing attribute update");
    return ESP_OK;
    }
    if (endpoint_id == light_endpoint_id) {
    /* RainMaker update */
    const char *device_name = LIGHT_DEVICE_NAME;
    const char *param_name = app_matter_get_rmaker_param_name_from_id(cluster_id, attribute_id);
    if (!param_name) {
    ESP_LOGD(TAG, "param name not handled");
    return ESP_FAIL;
    }

     const esp_rmaker_node_t *node = esp_rmaker_get_node();
     esp_rmaker_device_t *device = esp_rmaker_node_get_device_by_name(node, device_name);
     esp_rmaker_param_t *param = esp_rmaker_device_get_param_by_name(device, param_name);
     if (!param) {
         ESP_LOGE(TAG, "Param %s not found", param_name);
         return ESP_FAIL;
     }
    
     esp_rmaker_param_val_t rmaker_val = app_matter_get_rmaker_val(val, cluster_id, attribute_id);
     return esp_rmaker_param_update_and_report(param, rmaker_val);
    

    }
    if (endpoint_id == switch_endpoint_id) {
    /* RainMaker update */
    const char *device_name = SWITCH_DEVICE_NAME;
    const char *param_name = app_matter_get_rmaker_param_name_from_id(cluster_id, attribute_id);
    if (!param_name) {
    ESP_LOGD(TAG, "param name not handled");
    return ESP_FAIL;
    }
    printf("AttrCB Switch Endpoint ID: %d", endpoint_id);
    const esp_rmaker_node_t *node = esp_rmaker_get_node();
    esp_rmaker_device_t *device = esp_rmaker_node_get_device_by_name(node, device_name);
    esp_rmaker_param_t *param = esp_rmaker_device_get_param_by_name(device, param_name);
    if (!param) {
    ESP_LOGE(TAG, "Param %s not found", param_name);
    return ESP_FAIL;
    }

     esp_rmaker_param_val_t rmaker_val = app_matter_get_rmaker_val(val, cluster_id, attribute_id);
     return esp_rmaker_param_update_and_report(param, rmaker_val);
    

    }

}
return err;

}

esp_err_t app_matter_switch_create(button_driver_handle_t driver_handle)
{
node_t *node = node::get();
if (!node) {
ESP_LOGE(TAG, "Matter node not found");
return ESP_FAIL;
}

on_off_light_switch::config_t switch_config;
endpoint_t *endpoint = on_off_light_switch::create(node, &switch_config, ENDPOINT_FLAG_NONE, driver_handle);
printf("Switch Endpoint ID: %d", switch_endpoint_id);
if (!endpoint) {
    ESP_LOGE(TAG, "Matter endpoint creation failed");
    return ESP_FAIL;
}
cluster::groups::config_t groups_config;
cluster::groups::create(endpoint, &groups_config, CLUSTER_FLAG_SERVER | CLUSTER_FLAG_CLIENT);

//switch_endpoint_id = endpoint::get_id(endpoint);
switch_endpoint_id = 2;
endpoint::enable(endpoint);
printf("Switch Endpoint ID: %d", switch_endpoint_id);
ESP_LOGI(TAG, "Switch created with endpoint_id %d", switch_endpoint_id);
return ESP_OK;

}

esp_err_t app_matter_sensor_create(app_driver_handle_t driver_handle)
{
node_t *node = node::get();
if (!node) {
ESP_LOGE(TAG, "Matter node not found");
return ESP_FAIL;
}

temperature_sensor::config_t temp_sensor_config;

endpoint_t *temp_sensor_ep = temperature_sensor::create(node, &temp_sensor_config, ENDPOINT_FLAG_NONE, driver_handle);
temp_endpoint_id = endpoint::get_id(temp_sensor_ep);
//cluster_t *temp_cluster = cluster::get(temp_sensor_ep, TemperatureMeasurement::Id);

endpoint::enable(temp_sensor_ep);

temperature_measurement::config_t temperature_measurement_config;
temp_sensor_config.temperature_measurement.measured_value = 2500; // 25.00 °C по умолчанию
cluster_t *cluster = temperature_measurement::create(temp_sensor_ep, &temperature_measurement_config, CLUSTER_FLAG_SERVER);

ABORT_APP_ON_FAILURE(temp_sensor_ep != nullptr, ESP_LOGE(TAG, "Failed to create temperature_sensor endpoint"));
printf("Sensor Endpoint ID: %d", temp_endpoint_id);
//{
//	esp_matter_attr_val_t temp_val;
//}
// add the humidity sensor device
humidity_sensor::config_t humidity_sensor_config;
endpoint_t * humidity_sensor_ep = humidity_sensor::create(node, &humidity_sensor_config, ENDPOINT_FLAG_NONE, driver_handle);
ABORT_APP_ON_FAILURE(humidity_sensor_ep != nullptr, ESP_LOGE(TAG, "Failed to create humidity_sensor endpoint"));

endpoint::enable(humidity_sensor_ep);
// initialize temperature and humidity sensor driver (shtc3)

    static bme_sensor_config_t bme_config = {
    .temperature = {
        .cb = temp_sensor_notification,
        .endpoint_id = endpoint::get_id(temp_sensor_ep),
    },
    .humidity = {
        .cb = humidity_sensor_notification,
        .endpoint_id = endpoint::get_id(humidity_sensor_ep),
    },
};
//esp_rmaker_param_val_t rmaker_val = app_matter_get_rmaker_val(val, cluster_id, attribute_id);
 //   return esp_rmaker_param_update_and_report(param, rmaker_val);
//err = bme_sensor_init(&bme_config);

return ESP_OK;
}

Debug Logs.

Endpoints created
I (994) app_matter: Light created with endpoint_id 1
Light Endpoint ID: 1 Switch Endpoint ID: 0 Switch Endpoint ID: 2I (1004) app_matter: Switch created with endpoint_id 2
Sensor Endpoint ID: 3

Consoles log when open sensors page in mobile app:
E (23164) chip[DMG]: Read request on unknown cluster - no data version available
E (23164) chip[DMG]: Fail to retrieve data, roll back and encode status on clusterId: 0x0000_0402, attributeId: 0x0000_0000err = 5c3

More Information.

Image

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions