Skip to content

Commit ee0fb90

Browse files
Add example with two endpoints (#5)
* Add example with two endpoints * Fix folder structure
1 parent f8e947b commit ee0fb90

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
#include "Matter.h"
2+
#include <app/server/OnboardingCodesUtil.h>
3+
using namespace chip;
4+
using namespace chip::app::Clusters;
5+
using namespace esp_matter;
6+
using namespace esp_matter::endpoint;
7+
8+
/**
9+
* This program presents example Matter plugin unit (switch) device with two endpoints
10+
* with OnOff clusters by controlling LEDs with Matter and toggle buttons.
11+
*
12+
* You can toggle plugin unit by both:
13+
* - Matter (via CHIPTool or other Matter controller)
14+
* - toggle button (with debouncing)
15+
*/
16+
17+
// Please configure your PINs
18+
const int LED_PIN_1 = 2;
19+
const int LED_PIN_2 = 17;
20+
const int TOGGLE_BUTTON_PIN_1 = 0;
21+
const int TOGGLE_BUTTON_PIN_2 = 21;
22+
23+
// Debounce for toggle button
24+
const int DEBOUNCE_DELAY = 500;
25+
int last_toggle;
26+
27+
// Cluster and attribute ID used by Matter plugin unit device
28+
const uint32_t CLUSTER_ID = OnOff::Id;
29+
const uint32_t ATTRIBUTE_ID = OnOff::Attributes::OnOff::Id;
30+
31+
// Endpoint and attribute ref that will be assigned to Matter device
32+
uint16_t plugin_unit_endpoint_id_1 = 0;
33+
uint16_t plugin_unit_endpoint_id_2 = 0;
34+
attribute_t *attribute_ref_1;
35+
attribute_t *attribute_ref_2;
36+
37+
// There is possibility to listen for various device events, related for example
38+
// to setup process Leaved as empty for simplicity
39+
static void on_device_event(const ChipDeviceEvent *event, intptr_t arg) {}
40+
static esp_err_t on_identification(identification::callback_type_t type,
41+
uint16_t endpoint_id, uint8_t effect_id,
42+
void *priv_data) {
43+
return ESP_OK;
44+
}
45+
46+
// Listener on attribute update requests.
47+
// In this example, when update is requested, path (endpoint, cluster and
48+
// attribute) is checked if it matches plugin unit attribute. If yes, LED changes
49+
// state to new one.
50+
static esp_err_t on_attribute_update(attribute::callback_type_t type,
51+
uint16_t endpoint_id, uint32_t cluster_id,
52+
uint32_t attribute_id,
53+
esp_matter_attr_val_t *val,
54+
void *priv_data) {
55+
if (type == attribute::PRE_UPDATE && cluster_id == CLUSTER_ID && attribute_id == ATTRIBUTE_ID) {
56+
// We got an plugin unit on/off attribute update!
57+
boolean new_state = val->val.b;
58+
if (endpoint_id == plugin_unit_endpoint_id_1) {
59+
digitalWrite(LED_PIN_1, new_state);
60+
} else if (endpoint_id == plugin_unit_endpoint_id_2) {
61+
digitalWrite(LED_PIN_2, new_state);
62+
}
63+
}
64+
return ESP_OK;
65+
}
66+
67+
void setup() {
68+
Serial.begin(115200);
69+
pinMode(LED_PIN_1, OUTPUT);
70+
pinMode(LED_PIN_2, OUTPUT);
71+
pinMode(TOGGLE_BUTTON_PIN_1, INPUT);
72+
pinMode(TOGGLE_BUTTON_PIN_2, INPUT);
73+
74+
// Enable debug logging
75+
esp_log_level_set("*", ESP_LOG_DEBUG);
76+
77+
// Setup Matter node
78+
node::config_t node_config;
79+
node_t *node =
80+
node::create(&node_config, on_attribute_update, on_identification);
81+
82+
// Setup Plugin unit endpoint / cluster / attributes with default values
83+
on_off_plugin_unit::config_t plugin_unit_config;
84+
plugin_unit_config.on_off.on_off = false;
85+
plugin_unit_config.on_off.lighting.start_up_on_off = false;
86+
endpoint_t *endpoint_1 = on_off_plugin_unit::create(node, &plugin_unit_config,
87+
ENDPOINT_FLAG_NONE, NULL);
88+
endpoint_t *endpoint_2 = on_off_plugin_unit::create(node, &plugin_unit_config,
89+
ENDPOINT_FLAG_NONE, NULL);
90+
91+
// Save on/off attribute reference. It will be used to read attribute value
92+
// later.
93+
attribute_ref_1 =
94+
attribute::get(cluster::get(endpoint_1, CLUSTER_ID), ATTRIBUTE_ID);
95+
attribute_ref_2 =
96+
attribute::get(cluster::get(endpoint_2, CLUSTER_ID), ATTRIBUTE_ID);
97+
98+
// Save generated endpoint id
99+
plugin_unit_endpoint_id_1 = endpoint::get_id(endpoint_1);
100+
plugin_unit_endpoint_id_2 = endpoint::get_id(endpoint_2);
101+
102+
// Start Matter device
103+
esp_matter::start(on_device_event);
104+
105+
// Print codes needed to setup Matter device
106+
PrintOnboardingCodes(
107+
chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE));
108+
}
109+
110+
// Reads plugin unit on/off attribute value
111+
esp_matter_attr_val_t get_onoff_attribute_value(esp_matter::attribute_t *attribute_ref) {
112+
esp_matter_attr_val_t onoff_value = esp_matter_invalid(NULL);
113+
attribute::get_val(attribute_ref, &onoff_value);
114+
return onoff_value;
115+
}
116+
117+
// Sets plugin unit on/off attribute value
118+
void set_onoff_attribute_value(esp_matter_attr_val_t *onoff_value, uint16_t plugin_unit_endpoint_id) {
119+
attribute::update(plugin_unit_endpoint_id, CLUSTER_ID, ATTRIBUTE_ID, onoff_value);
120+
}
121+
122+
// When toggle plugin unit button is pressed (with debouncing),
123+
// plugin unit attribute value is changed
124+
void loop() {
125+
if ((millis() - last_toggle) > DEBOUNCE_DELAY) {
126+
if (!digitalRead(TOGGLE_BUTTON_PIN_1)) {
127+
last_toggle = millis();
128+
// Read actual on/off value, invert it and set
129+
esp_matter_attr_val_t onoff_value = get_onoff_attribute_value(attribute_ref_1);
130+
onoff_value.val.b = !onoff_value.val.b;
131+
set_onoff_attribute_value(&onoff_value, plugin_unit_endpoint_id_1);
132+
}
133+
134+
if (!digitalRead(TOGGLE_BUTTON_PIN_2)) {
135+
last_toggle = millis();
136+
// Read actual on/off value, invert it and set
137+
esp_matter_attr_val_t onoff_value = get_onoff_attribute_value(attribute_ref_2);
138+
onoff_value.val.b = !onoff_value.val.b;
139+
set_onoff_attribute_value(&onoff_value, plugin_unit_endpoint_id_2);
140+
}
141+
}
142+
}

0 commit comments

Comments
 (0)