Merge branch 'group-binding' into 'main'

Example: Add group binding for the light-switch app

See merge request app-frameworks/esp-matter!188
This commit is contained in:
Shu Chen
2022-09-27 10:21:00 +08:00
6 changed files with 236 additions and 54 deletions
+50 -2
View File
@@ -39,14 +39,41 @@ Update the switch's binding attribute to add the entry of remote device
binding write binding '[{"fabricIndex": 1, "node":20836, "endpoint":1, "cluster":6}]' 0x7283 0x1
```
### 2.2 Device console
### 2.2 Bind a group to switch
Using the chip-tool, commission 3 (or more) devices, 1 switch and 2 (or more) lights.
If you are having trouble, try commissioning them one at a time (by powering off the other device) as
the default discriminator and passcode are same for both of them.
Then use the below commands to add the devices to the group and bind the group to the switch.
For the commands below:
- Node Id of switch used during commissioning is 0x7283 (29315 in decimal)
- Node Id of light1 used during commissioning is 0x5164 (20836 in decimal)
- Node Id of light2 used during commissioning is 0x5163 (20835 in decimal)
- Group Id for the devices is 257 which is assigned by chip-tool when using the testing-group command
- Binding cluster is currently present on endpoint 1 on the switch
Send the testing-group command to the switch and lights.
This command will write the acl attributes of the nodes and add the endpoint 1 of the nodes to the group 257.
```
tests TestGroupDemoConfig --nodeId 29315
tests TestGroupDemoConfig --nodeId 20836
tests TestGroupDemoConfig --nodeId 20835
```
Update the switch's binding attribute to add the entry of group in the binding table:
```
binding write binding '[{"fabricIndex": 1, "group": 257}]' 0x7283 0x1
```
### 2.3 Device console
Switch specific console commands:
- Send command to all the bound devices on the specified cluster:
(The IDs are in hex):
```
matter esp bound invoke <endpoint_id> <cluster_id> <command_id>
matter esp bound invoke <local_endpoint_id> <cluster_id> <command_id>
```
- Example: Off:
@@ -64,6 +91,27 @@ Switch specific console commands:
matter esp bound invoke 0x1 0x6 0x2
```
- Send command to all the bound groups on the specified cluster:
(The IDs are in hex):
```
matter esp bound invoke-group <local_endpoint_id> <cluster_id> <command_id>
```
- Example: Off:
```
matter esp bound invoke-group 0x1 0x6 0x0
```
- Example: On:
```
matter esp bound invoke-group 0x1 0x6 0x1
```
- Example: Toggle:
```
matter esp bound invoke-group 0x1 0x6 0x2
```
## 3. Device Performance
### 3.1 Memory usage
+50 -31
View File
@@ -27,25 +27,34 @@ using namespace esp_matter::cluster;
static const char *TAG = "app_driver";
extern uint16_t switch_endpoint_id;
static uint32_t g_cluster_id = kInvalidClusterId;
static uint32_t g_command_id = kInvalidCommandId;
static esp_err_t app_driver_bound_console_handler(int argc, char **argv)
{
if (argc == 1 && strncmp(argv[0], "help", sizeof("help")) == 0) {
printf("Bound commands:\n"
"\thelp: Print help\n"
"\tinvoke: <endpoint_id> <cluster_id> <command_id>. "
"Example: matter esp bound invoke 0x0001 0x0006 0x0002.\n");
"\tinvoke: <local_endpoint_id> <cluster_id> <command_id>. "
"Example: matter esp bound invoke 0x0001 0x0006 0x0002.\n"
"\tinvoke-group: <local_endpoint_id> <cluster_id> <command_id>. "
"Example: matter esp bound invoke-group 0x0001 0x0006 0x0002.\n");
} else if (argc == 4 && strncmp(argv[0], "invoke", sizeof("invoke")) == 0) {
uint16_t endpoint_id = strtol((const char *)&argv[1][2], NULL, 16);
uint32_t cluster_id = strtol((const char *)&argv[2][2], NULL, 16);
uint32_t command_id = strtol((const char *)&argv[3][2], NULL, 16);
client::command_handle_t cmd_handle;
uint16_t local_endpoint_id = strtol((const char *)&argv[1][2], NULL, 16);
cmd_handle.cluster_id = strtol((const char *)&argv[2][2], NULL, 16);
cmd_handle.command_id = strtol((const char *)&argv[3][2], NULL, 16);
cmd_handle.is_group = false;
g_cluster_id = cluster_id;
g_command_id = command_id;
client::cluster_update(endpoint_id, cluster_id);
} else {
client::cluster_update(local_endpoint_id, &cmd_handle);
} else if (argc == 4 && strncmp(argv[0], "invoke-group", sizeof("invoke-group")) == 0) {
client::command_handle_t cmd_handle;
uint16_t local_endpoint_id = strtol((const char *)&argv[1][2], NULL, 16);
cmd_handle.cluster_id = strtol((const char *)&argv[2][2], NULL, 16);
cmd_handle.command_id = strtol((const char *)&argv[3][2], NULL, 16);
cmd_handle.is_group = true;
client::cluster_update(local_endpoint_id, &cmd_handle);
}
else {
ESP_LOGE(TAG, "Incorrect arguments. Check help for more details.");
return ESP_ERR_INVALID_ARG;
}
@@ -60,15 +69,14 @@ static esp_err_t app_driver_client_console_handler(int argc, char **argv)
"\tinvoke: <fabric_index> <remote_node_id> <remote_endpoint_id> <cluster_id> <command_id>. "
"Example: matter esp client invoke 0x0001 0xBC5C01 0x0001 0x0006 0x0002.\n");
} else if (argc == 6 && strncmp(argv[0], "invoke", sizeof("invoke")) == 0) {
client::command_handle_t cmd_handle;
uint8_t fabric_index = strtol((const char *)&argv[1][2], NULL, 16);
uint64_t node_id = strtol((const char *)&argv[2][2], NULL, 16);
uint16_t remote_endpoint_id = strtol((const char *)&argv[3][2], NULL, 16);
uint32_t cluster_id = strtol((const char *)&argv[4][2], NULL, 16);
uint32_t command_id = strtol((const char *)&argv[5][2], NULL, 16);
cmd_handle.endpoint_id = strtol((const char *)&argv[3][2], NULL, 16);
cmd_handle.cluster_id = strtol((const char *)&argv[4][2], NULL, 16);
cmd_handle.command_id = strtol((const char *)&argv[5][2], NULL, 16);
g_cluster_id = cluster_id;
g_command_id = command_id;
client::connect(fabric_index, node_id, remote_endpoint_id);
client::connect(fabric_index, node_id, &cmd_handle);
} else {
ESP_LOGE(TAG, "Incorrect arguments. Check help for more details.");
return ESP_ERR_INVALID_ARG;
@@ -100,32 +108,43 @@ static void app_driver_register_commands()
}
void app_driver_client_command_callback(client::peer_device_t *peer_device, uint16_t remote_endpoint_id,
void *priv_data)
client::command_handle_t *cmd_handle, void *priv_data)
{
/** TODO: Find a better way to get the cluster_id and command_id.
Once done, move the console commands to esp_matter_client. */
if (g_cluster_id == OnOff::Id) {
if (g_command_id == OnOff::Commands::Off::Id) {
if (cmd_handle->cluster_id == OnOff::Id) {
if (cmd_handle->command_id == OnOff::Commands::Off::Id) {
on_off::command::send_off(peer_device, remote_endpoint_id);
} else if (g_command_id == OnOff::Commands::On::Id) {
} else if (cmd_handle->command_id == OnOff::Commands::On::Id) {
on_off::command::send_on(peer_device, remote_endpoint_id);
} else if (g_command_id == OnOff::Commands::Toggle::Id) {
} else if (cmd_handle->command_id == OnOff::Commands::Toggle::Id) {
on_off::command::send_toggle(peer_device, remote_endpoint_id);
}
}
}
void app_driver_client_group_command_callback(uint8_t fabric_index, uint16_t group_id,
client::command_handle_t *cmd_handle, void *priv_data)
{
if (cmd_handle->cluster_id == OnOff::Id) {
if (cmd_handle->command_id == OnOff::Commands::Off::Id) {
on_off::command::group_send_off(fabric_index, group_id);
} else if (cmd_handle->command_id == OnOff::Commands::On::Id) {
on_off::command::group_send_on(fabric_index, group_id);
} else if (cmd_handle->command_id == OnOff::Commands::Toggle::Id) {
on_off::command::group_send_toggle(fabric_index, group_id);
}
}
}
static void app_driver_button_toggle_cb(void *arg)
{
ESP_LOGI(TAG, "Toggle button pressed");
uint16_t endpoint_id = switch_endpoint_id;
uint32_t cluster_id = OnOff::Id;
uint32_t command_id = OnOff::Commands::Toggle::Id;
client::command_handle_t cmd_handle;
cmd_handle.cluster_id = OnOff::Id;
cmd_handle.command_id = OnOff::Commands::Toggle::Id;
cmd_handle.is_group = false;
g_cluster_id = cluster_id;
g_command_id = command_id;
lock::chip_stack_lock(portMAX_DELAY);
client::cluster_update(endpoint_id, cluster_id);
client::cluster_update(switch_endpoint_id, &cmd_handle);
lock::chip_stack_unlock();
}
@@ -145,7 +164,7 @@ app_driver_handle_t app_driver_switch_init()
/* Other initializations */
app_driver_register_commands();
client::set_command_callback(app_driver_client_command_callback, NULL);
client::set_command_callback(app_driver_client_command_callback, app_driver_client_group_command_callback, NULL);
return (app_driver_handle_t)handle;
}
+4
View File
@@ -104,6 +104,10 @@ extern "C" void app_main()
ESP_LOGE(TAG, "Matter node creation failed");
}
/* Add group cluster to the switch endpoint */
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);
ESP_LOGI(TAG, "Switch created with endpoint_id %d", switch_endpoint_id);