Merge branch 'fix/generic_switch' into 'main'

examples/generic_switch: Update generic switch wrt spec changes.

See merge request app-frameworks/esp-matter!893
This commit is contained in:
Shu Chen
2024-12-17 17:48:46 +08:00
8 changed files with 129 additions and 146 deletions
+6 -50
View File
@@ -3,16 +3,10 @@
This example creates a Generic Switch device using the ESP
Matter data model.
This example demonstrates the use of few optional data model elements like :
- Fixed Label Cluster : provides a feature for the device to tag an endpoint with zero or more read only labels (demonstrated through nvs).
- User Label Cluster : This cluster provides a feature to tag an endpoint with zero or more labels.
- Taglist Feature of Descriptor Cluster : used to disambiguate sibling endpoints where two or more sibling
endpoints have an overlap in the supported device types with each such endpoint having a unique TagList.
Note:
In order to retrieve the label-list from the fixed-label cluster the two options:
``CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER`` and ``CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER`` have been set through sdkconfig.defaults.
See the [docs](https://docs.espressif.com/projects/esp-matter/en/latest/esp32/developing.html) for more information about building and flashing the firmware.
## 1. Additional Environment Setup
@@ -31,51 +25,13 @@ through menuconfig:
Follow the steps mentioned [here](https://docs.espressif.com/projects/esp-matter/en/latest/esp32/insights.html)
### 1.3 Flash the factory partition
The steps below should be followed in order to access the fixed-labels.
- If monitoring the device using ``idf.py monitor``,press `` Ctrl + ]`` to stop the process.
- The following command must be executed to flash the mfg partition:
```
esptool.py -p [port-name] write_flash 0x10000 mfg_binaries/20202020_3841.bin
```
- Execute the command ``idf.py monitor``
## 2.Commissioning and Control
- Commission the device with ``discriminator: 3841``and `` passcode: 20202020``
- Commission the device with ``discriminator: 3840``and `` passcode: 20202021``
```
chip-tool pairing ble-wifi 0x7283 [ssid] [password] 20202020 3841
chip-tool pairing ble-wifi 0x7283 [ssid] [password] 20202021 3840
```
- Alternatively, below QR Code or Manual pairing code can be used for commissioning
- Manualcode : 34970012334
- QRCode :
- ![QRCode](mfg_binaries/matter_qrcode_20202020_3841.png)
### 2.1 Fixed-Labels
- To read the fixed-labels, use chip-tool.
```
chip-tool fixedlabel read label-list 0x7283 1
```
### 2.2 User-Labels
- The example command given below should be executed to write to the label-list of User Label Cluster.
```
chip-tool userlabel write label-list '[{"label":"room", "value":"bedroom 1"}, {"label":"orientation", "value":"east"}]' 0x7283 1
```
- To read label-list of User Label Cluster execute the command given below.
```
chip-tool userlabel read label-list 0x7283 1
```
### 2.3 Using the TagList Feature
### 2.1 Using the TagList Feature
To read the taglist of the Descriptor cluster execute the command given below.
@@ -83,7 +39,7 @@ To read the taglist of the Descriptor cluster execute the command given below.
chip-tool descriptor read tag-list 0x7283 1
```
## 2. Post Commissioning Setup
## 3. Post Commissioning Setup
This should be followed by: Commission the generic switch device
- Turn on chip-tool interactive mode. ``./chip-tool interactive start``
@@ -91,13 +47,13 @@ This should be followed by: Commission the generic switch device
``switch subscribe-event long-press <min-interval> <max-interval> <destination-id> <endpoint-id>``
- `Double press the boot button` on device so that client will receive event after max-interval.
### 2.1 Latching switch
### 3.1 Latching switch
Following are latching switch events mapped with boot button on device.
- `Double Press` -----------> `switch-latched`
### 2.2 Momentary switch
### 3.2 Momentary switch
Following are momentary switch events mapped with boot button on device.
+57 -47
View File
@@ -36,13 +36,15 @@ esp_err_t app_driver_attribute_update(app_driver_handle_t driver_handle, uint16_
}
#if CONFIG_GENERIC_SWITCH_TYPE_LATCHING
static uint8_t latching_switch_previous_position = 0;
static void app_driver_button_switch_latched(void *arg, void *data)
{
ESP_LOGI(TAG, "Switch lached pressed");
gpio_button * button = (gpio_button*)data;
int switch_endpoint_id = (button != NULL) ? get_endpoint(button) : 1;
// Press moves Position from 0 (idle) to 1 (press)
uint8_t newPosition = 1;
// Press moves Position from 0 (idle) to 1 (press) and vice versa
uint8_t newPosition = (latching_switch_previous_position == 1) ? 0 : 1;
latching_switch_previous_position = newPosition;
chip::DeviceLayer::SystemLayer().ScheduleLambda([switch_endpoint_id, newPosition]() {
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(switch_endpoint_id, newPosition);
// SwitchLatched event takes newPosition as event data
@@ -51,18 +53,25 @@ static void app_driver_button_switch_latched(void *arg, void *data)
}
#endif
#if CONFIG_GENERIC_SWITCH_TYPE_MOMENTARY
static int current_number_of_presses_counted = 1;
static bool is_multipress = 0;
static uint8_t idlePosition = 0;
static void app_driver_button_initial_pressed(void *arg, void *data)
{
ESP_LOGI(TAG, "Initial button pressed");
gpio_button * button = (gpio_button*)data;
int switch_endpoint_id = (button != NULL) ? get_endpoint(button) : 1;
// Press moves Position from 0 (idle) to 1 (press)
uint8_t newPosition = 1;
chip::DeviceLayer::SystemLayer().ScheduleLambda([switch_endpoint_id, newPosition]() {
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(switch_endpoint_id, newPosition);
// InitialPress event takes newPosition as event data
switch_cluster::event::send_initial_press(switch_endpoint_id, newPosition);
});
if(!is_multipress) {
ESP_LOGI(TAG, "Initial button pressed");
gpio_button * button = (gpio_button*)data;
int switch_endpoint_id = (button != NULL) ? get_endpoint(button) : 1;
// Press moves Position from 0 (idle) to 1 (press)
uint8_t newPosition = 1;
chip::DeviceLayer::SystemLayer().ScheduleLambda([switch_endpoint_id, newPosition]() {
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(switch_endpoint_id, newPosition);
// InitialPress event takes newPosition as event data
switch_cluster::event::send_initial_press(switch_endpoint_id, newPosition);
});
is_multipress = 1;
}
}
static void app_driver_button_release(void *arg, void *data)
@@ -70,28 +79,9 @@ static void app_driver_button_release(void *arg, void *data)
gpio_button *button = (gpio_button *)data;
int switch_endpoint_id = (button != NULL) ? get_endpoint(button) : 1;
if (iot_button_get_ticks_time((button_handle_t)arg) < 5000) {
ESP_LOGI(TAG, "Short button release");
// Release moves Position from 1 (press) to 0 (idle)
uint8_t previousPosition = 1;
uint8_t newPosition = 0;
chip::DeviceLayer::SystemLayer().ScheduleLambda([switch_endpoint_id, previousPosition, newPosition]() {
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(switch_endpoint_id, newPosition);
// ShortRelease event takes previousPosition as event data
switch_cluster::event::send_short_release(switch_endpoint_id, previousPosition);
});
} else {
ESP_LOGI(TAG, "Long button release");
// Release moves Position from 1 (press) to 0 (idle)
uint8_t previousPosition = 1;
uint8_t newPosition = 0;
chip::DeviceLayer::SystemLayer().ScheduleLambda([switch_endpoint_id, previousPosition, newPosition]() {
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(switch_endpoint_id, newPosition);
// LongRelease event takes previousPositionPosition as event data
switch_cluster::event::send_long_release(switch_endpoint_id, previousPosition);
});
}
chip::DeviceLayer::SystemLayer().ScheduleLambda([switch_endpoint_id]() {
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(switch_endpoint_id, idlePosition);
});
}
static void app_driver_button_long_pressed(void *arg, void *data)
@@ -108,8 +98,6 @@ static void app_driver_button_long_pressed(void *arg, void *data)
});
}
static int current_number_of_presses_counted = 1;
static void app_driver_button_multipress_ongoing(void *arg, void *data)
{
ESP_LOGI(TAG, "Multipress Ongoing");
@@ -118,11 +106,25 @@ static void app_driver_button_multipress_ongoing(void *arg, void *data)
// Press moves Position from 0 (idle) to 1 (press)
uint8_t newPosition = 1;
current_number_of_presses_counted++;
chip::DeviceLayer::SystemLayer().ScheduleLambda([switch_endpoint_id, newPosition]() {
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(switch_endpoint_id, newPosition);
// MultiPress Ongoing event takes newPosition and current_number_of_presses_counted as event data
switch_cluster::event::send_multi_press_ongoing(switch_endpoint_id, newPosition, current_number_of_presses_counted);
});
uint16_t endpoint_id = switch_endpoint_id;
uint32_t cluster_id = Switch::Id;
uint32_t attribute_id = Switch::Attributes::FeatureMap::Id;
attribute_t *attribute = attribute::get(endpoint_id, cluster_id, attribute_id);
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
attribute::get_val(attribute, &val);
uint32_t feature_map = val.val.u32;
uint32_t msm_feature_map = switch_cluster::feature::momentary_switch_multi_press::get_id();
uint32_t as_feature_map = switch_cluster::feature::action_switch::get_id();
if(((feature_map & msm_feature_map) == msm_feature_map) && ((feature_map & as_feature_map) != as_feature_map)) {
chip::DeviceLayer::SystemLayer().ScheduleLambda([switch_endpoint_id, newPosition]() {
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(switch_endpoint_id, newPosition);
// MultiPress Ongoing event takes newPosition and current_number_of_presses_counted as event data
switch_cluster::event::send_multi_press_ongoing(switch_endpoint_id, newPosition, current_number_of_presses_counted);
});
}
}
static void app_driver_button_multipress_complete(void *arg, void *data)
@@ -132,15 +134,24 @@ static void app_driver_button_multipress_complete(void *arg, void *data)
int switch_endpoint_id = (button != NULL) ? get_endpoint(button) : 1;
// Press moves Position from 0 (idle) to 1 (press)
uint8_t previousPosition = 1;
uint8_t newPosition = 0;
static int total_number_of_presses_counted = current_number_of_presses_counted;
chip::DeviceLayer::SystemLayer().ScheduleLambda([switch_endpoint_id, previousPosition, newPosition]() {
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(switch_endpoint_id, newPosition);
uint16_t endpoint_id = switch_endpoint_id;
uint32_t cluster_id = Switch::Id;
uint32_t attribute_id = Switch::Attributes::MultiPressMax::Id;
attribute_t *attribute = attribute::get(endpoint_id, cluster_id, attribute_id);
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
attribute::get_val(attribute, &val);
uint8_t multipress_max = val.val.u8;
int total_number_of_presses_counted = (current_number_of_presses_counted > multipress_max)? 0:current_number_of_presses_counted;
chip::DeviceLayer::SystemLayer().ScheduleLambda([switch_endpoint_id, previousPosition, total_number_of_presses_counted]() {
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(switch_endpoint_id, idlePosition);
// MultiPress Complete event takes previousPosition and total_number_of_presses_counted as event data
switch_cluster::event::send_multi_press_complete(switch_endpoint_id, previousPosition, total_number_of_presses_counted);
// Reset current_number_of_presses_counted to initial value
current_number_of_presses_counted = 1;
});
is_multipress = 0;
}
#endif
@@ -162,13 +173,12 @@ app_driver_handle_t app_driver_button_init(gpio_button * button)
#if CONFIG_GENERIC_SWITCH_TYPE_LATCHING
iot_button_register_cb(handle, BUTTON_DOUBLE_CLICK, app_driver_button_switch_latched, button);
iot_button_register_cb(handle, BUTTON_PRESS_DOWN, app_driver_button_switch_latched, button);
#endif
#if CONFIG_GENERIC_SWITCH_TYPE_MOMENTARY
iot_button_register_cb(handle, BUTTON_PRESS_DOWN, app_driver_button_initial_pressed, button);
iot_button_register_cb(handle, BUTTON_PRESS_UP, app_driver_button_release, button);
iot_button_register_cb(handle, BUTTON_LONG_PRESS_START, app_driver_button_long_pressed, button);
iot_button_register_cb(handle, BUTTON_PRESS_REPEAT, app_driver_button_multipress_ongoing, button);
iot_button_register_cb(handle, BUTTON_PRESS_REPEAT_DONE, app_driver_button_multipress_complete, button);
#endif
+4 -24
View File
@@ -170,12 +170,6 @@ static esp_err_t create_button(struct gpio_button* button, node_t* node)
generic_switch_endpoint_id = endpoint::get_id(endpoint);
ESP_LOGI(TAG, "Generic Switch created with endpoint_id %d", generic_switch_endpoint_id);
cluster::fixed_label::config_t fl_config;
cluster_t *fl_cluster = cluster::fixed_label::create(endpoint, &fl_config, CLUSTER_FLAG_SERVER);
cluster::user_label::config_t ul_config;
cluster_t *ul_cluster = cluster::user_label::create(endpoint, &ul_config, CLUSTER_FLAG_SERVER);
/* Add additional features to the node */
cluster_t *cluster = cluster::get(endpoint, Switch::Id);
@@ -185,6 +179,10 @@ static esp_err_t create_button(struct gpio_button* button, node_t* node)
#if CONFIG_GENERIC_SWITCH_TYPE_MOMENTARY
cluster::switch_cluster::feature::momentary_switch::add(cluster);
cluster::switch_cluster::feature::action_switch::add(cluster);
cluster::switch_cluster::feature::momentary_switch_multi_press::config_t msm;
msm.multi_press_max = 5;
cluster::switch_cluster::feature::momentary_switch_multi_press::add(cluster, &msm);
#endif
return err;
@@ -244,24 +242,6 @@ extern "C" void app_main()
SetTagList(1, chip::Span<const Descriptor::Structs::SemanticTagStruct::Type>(gEp1TagList));
SetTagList(2, chip::Span<const Descriptor::Structs::SemanticTagStruct::Type>(gEp2TagList));
nvs_handle_t handle;
nvs_open_from_partition(CONFIG_CHIP_FACTORY_NAMESPACE_PARTITION_LABEL, "chip-factory", NVS_READWRITE, &handle);
ABORT_APP_ON_FAILURE(err == ESP_OK, ESP_LOGE(TAG, "Failed to open namespace:chip-factory from partition:"
CONFIG_CHIP_FACTORY_NAMESPACE_PARTITION_LABEL ", err:%d", err));
int32_t out_value = 0;
if (nvs_get_i32(handle, "fl-sz/1", &out_value) == ESP_ERR_NVS_NOT_FOUND)
{
nvs_set_i32(handle, "fl-sz/1", 2);
nvs_set_str(handle, "fl-k/1/0", "myEP1LBL1");
nvs_set_str(handle, "fl-v/1/0", "valEP1LBL1");
nvs_set_str(handle, "fl-k/1/1", "myEP1LBL2");
nvs_set_str(handle, "fl-v/1/1", "valEP1LBL2");
}
nvs_commit(handle);
nvs_close(handle);
#if CONFIG_ENABLE_CHIP_SHELL
esp_matter::console::diagnostics_register_commands();
esp_matter::console::wifi_register_commands();
Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

@@ -37,15 +37,6 @@ CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n
# Disable DS Peripheral
CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n
# Enable for fixed-label
CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER=y
CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER=y
CONFIG_ENABLE_ESP32_DEVICE_INSTANCE_INFO_PROVIDER=y
CONFIG_FACTORY_PARTITION_DAC_PROVIDER=y
CONFIG_FACTORY_DEVICE_INFO_PROVIDER=y
CONFIG_FACTORY_DEVICE_INSTANCE_INFO_PROVIDER=y
CONFIG_FACTORY_COMMISSIONABLE_DATA_PROVIDER=y
# Enable HKDF in mbedtls
CONFIG_MBEDTLS_HKDF_C=y