Skip to content

Commit

Permalink
Merge branch 'fix/generic_switch' into 'main'
Browse files Browse the repository at this point in the history
examples/generic_switch: Update generic switch wrt spec changes.

See merge request app-frameworks/esp-matter!893
  • Loading branch information
chshu committed Dec 17, 2024
2 parents 53da97b + 447e0b1 commit 2e0eaf6
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 146 deletions.
69 changes: 54 additions & 15 deletions components/esp_matter/esp_matter_feature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2761,16 +2761,15 @@ namespace latching_switch {

uint32_t get_id()
{
// The SwitchFeature enum class is not added in the upstream code.
// Return the code according to the SPEC
return (uint32_t)0x01;
return (uint32_t)Switch::Feature::kLatchingSwitch;
}

esp_err_t add(cluster_t *cluster)
{
VerifyOrReturnError((get_feature_map_value(cluster) & feature::momentary_switch::get_id()) != feature::momentary_switch::get_id(), ESP_ERR_NOT_SUPPORTED, ESP_LOGE(TAG, "Latching switch is not supported because momentary switch is present"));
update_feature_map(cluster, get_id());

event::create_switch_latched(cluster);
return ESP_OK;
}

Expand All @@ -2780,16 +2779,15 @@ namespace momentary_switch {

uint32_t get_id()
{
// The SwitchFeature enum class is not added in the upstream code.
// Return the code according to the SPEC
return (uint32_t)0x02;
return (uint32_t)Switch::Feature::kMomentarySwitch;
}

esp_err_t add(cluster_t *cluster)
{
VerifyOrReturnError((get_feature_map_value(cluster) & feature::latching_switch::get_id()) != feature::latching_switch::get_id(), ESP_ERR_NOT_SUPPORTED, ESP_LOGE(TAG, "Momentary switch is not supported because latching switch is present"));
update_feature_map(cluster, get_id());

event::create_initial_press(cluster);
return ESP_OK;
}

Expand All @@ -2799,16 +2797,19 @@ namespace momentary_switch_release {

uint32_t get_id()
{
// The SwitchFeature enum class is not added in the upstream code.
// Return the code according to the SPEC
return (uint32_t)0x04;
return (uint32_t)Switch::Feature::kMomentarySwitchRelease;
}

esp_err_t add(cluster_t *cluster)
{
VerifyOrReturnError((get_feature_map_value(cluster) & feature::momentary_switch::get_id()) == feature::momentary_switch::get_id(), ESP_ERR_NOT_SUPPORTED, ESP_LOGE(TAG, "Momentary switch release is not supported because momentary is absent"));
uint32_t as_feature_map = feature::action_switch::get_id();
uint32_t ms_feature_map = feature::momentary_switch::get_id();
uint32_t feature_map = get_feature_map_value(cluster);
VerifyOrReturnError(((feature_map & ms_feature_map) != ms_feature_map) || ((feature_map & as_feature_map) == as_feature_map), ESP_ERR_NOT_SUPPORTED, ESP_LOGE(TAG, "Momentary switch release is not supported."));
update_feature_map(cluster, get_id());

event::create_short_release(cluster);
return ESP_OK;
}

Expand All @@ -2818,17 +2819,23 @@ namespace momentary_switch_long_press {

uint32_t get_id()
{
// The SwitchFeature enum class is not added in the upstream code.
// Return the code according to the SPEC
return (uint32_t)0x08;
return (uint32_t)Switch::Feature::kMomentarySwitchLongPress;
}

esp_err_t add(cluster_t *cluster)
{
uint32_t momentary_and_momentart_switch_release_feature_map = feature::momentary_switch::get_id() | feature::momentary_switch_release::get_id();
VerifyOrReturnError((get_feature_map_value(cluster) & momentary_and_momentart_switch_release_feature_map) == momentary_and_momentart_switch_release_feature_map, ESP_ERR_NOT_SUPPORTED, ESP_LOGE(TAG, "Momentary switch long press is not supported because momentary switch and/or momentary switch release is absent"));
uint32_t msr_feature_map = feature::momentary_switch_release::get_id();
uint32_t as_feature_map = feature::action_switch::get_id();
uint32_t ms_feature_map = feature::momentary_switch::get_id();
uint32_t feature_map = get_feature_map_value(cluster);
VerifyOrReturnError((feature_map & ms_feature_map) != ms_feature_map, ESP_ERR_NOT_SUPPORTED, ESP_LOGE(TAG, "Momentary switch long press is not supported."));
VerifyOrReturnError(((feature_map & msr_feature_map) != msr_feature_map) && ((feature_map & as_feature_map) != as_feature_map), ESP_ERR_NOT_SUPPORTED, ESP_LOGE(TAG, "Momentary switch long press is not supported."));
update_feature_map(cluster, get_id());

event::create_long_press(cluster);
event::create_long_release(cluster);
return ESP_OK;
}

Expand All @@ -2838,23 +2845,55 @@ namespace momentary_switch_multi_press {

uint32_t get_id()
{
// The SwitchFeature enum class is not added in the upstream code.
// Return the code according to the SPEC
return (uint32_t)0x10;
return (uint32_t)Switch::Feature::kMomentarySwitchMultiPress;
}

esp_err_t add(cluster_t *cluster, config_t *config)
{
uint32_t momentary_and_momentart_switch_release_feature_map = feature::momentary_switch::get_id() | feature::momentary_switch_release::get_id();
VerifyOrReturnError((get_feature_map_value(cluster) & momentary_and_momentart_switch_release_feature_map) == momentary_and_momentart_switch_release_feature_map, ESP_ERR_NOT_SUPPORTED, ESP_LOGE(TAG, "Momentary switch multi press is not supported because momentary switch and/or momentary switch releaseis absent"));
uint32_t as_feature_map = feature::action_switch::get_id();
VerifyOrReturnError((get_feature_map_value(cluster) & as_feature_map) != as_feature_map, ESP_ERR_NOT_SUPPORTED, ESP_LOGE(TAG, "Momentary switch multi press is not supported because action switch is absent"));
uint32_t ms_feature_map = feature::momentary_switch::get_id();
uint32_t msr_feature_map = feature::momentary_switch_release::get_id();
uint32_t ms_and_msr = ms_feature_map | msr_feature_map;
if ((get_feature_map_value(cluster) & as_feature_map) != as_feature_map) {
if ((get_feature_map_value(cluster) & ms_and_msr) != ms_and_msr) {
ESP_LOGE(TAG, "Momentary switch multi press is not supported.");
return ESP_ERR_NOT_SUPPORTED;
}
event::create_multi_press_ongoing(cluster);
}
update_feature_map(cluster, get_id());

attribute::create_multi_press_max(cluster, config->multi_press_max);

event::create_multi_press_complete(cluster);
return ESP_OK;
}

} /* momentary_switch_multi_press */

namespace action_switch {

uint32_t get_id()
{
return (uint32_t)Switch::Feature::kActionSwitch;
}

esp_err_t add(cluster_t *cluster)
{
if ((get_feature_map_value(cluster) & feature::momentary_switch::get_id()) != feature::momentary_switch::get_id()) {
ESP_LOGE(TAG, "Momentary switch is present");
return ESP_ERR_NOT_SUPPORTED;
}
update_feature_map(cluster, get_id());

return ESP_OK;
}

} /* action_switch */

} /* feature */
} /* switch_cluster */

Expand Down
9 changes: 8 additions & 1 deletion components/esp_matter/esp_matter_feature.h
Original file line number Diff line number Diff line change
Expand Up @@ -1536,7 +1536,14 @@ typedef struct config {
uint32_t get_id();
esp_err_t add(cluster_t *cluster, config_t *config);

} /* momentary_switch_multi_pressy */
} /* momentary_switch_multi_press */

namespace action_switch {

uint32_t get_id();
esp_err_t add(cluster_t *cluster);

} /* action_switch */
} /* feature */
} /* switch_cluster */

Expand Down
56 changes: 6 additions & 50 deletions examples/generic_switch/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -31,73 +25,35 @@ 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
```
- 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 pairing ble-wifi 0x7283 [ssid] [password] 20202021 3840
```
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.
```
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``
- By default momentary switch is enabled so subscribe to long-press event via chip-tool.
``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.
Expand Down
Loading

0 comments on commit 2e0eaf6

Please sign in to comment.