mirror of
https://github.com/espressif/esp-matter.git
synced 2026-04-27 19:13:13 +00:00
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:
@@ -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 :
|
||||
- 
|
||||
|
||||
### 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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user