Skip to content

Commit 5a2094a

Browse files
committed
feat(matter): Adds Matter Events callback plus example
1 parent 422e526 commit 5a2094a

File tree

4 files changed

+398
-13
lines changed

4 files changed

+398
-13
lines changed
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
// Copyright 2025 Espressif Systems (Shanghai) PTE LTD
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// Matter Manager
16+
#include <Matter.h>
17+
#include <WiFi.h>
18+
19+
// WiFi is manually set and started
20+
const char *ssid = "your-ssid"; // Change this to your WiFi SSID
21+
const char *password = "your-password"; // Change this to your WiFi password
22+
23+
// List of Matter Endpoints for this Node
24+
// On/Off Light Endpoint
25+
MatterOnOffLight OnOffLight;
26+
27+
// This function is called when a Matter event occurs
28+
void onMatterEvent(ArduinoMatter::matterEvent_t eventType, const chip::DeviceLayer::ChipDeviceEvent *eventInfo) {
29+
// Print the event type to Serial
30+
Serial.print("===> Got a Matter Event: ");
31+
switch (eventType) {
32+
case ArduinoMatter::MATTER_WIFI_CONNECTIVITY_CHANGE:
33+
Serial.println("WiFi Connectivity Change");
34+
break;
35+
case ArduinoMatter::MATTER_THREAD_CONNECTIVITY_CHANGE:
36+
Serial.println("Thread Connectivity Change");
37+
break;
38+
case ArduinoMatter::MATTER_INTERNET_CONNECTIVITY_CHANGE: {
39+
bool newIPAddress = false;
40+
Serial.print("Internet Connectivity Change :: ");
41+
if (eventInfo->InternetConnectivityChange.IPv4 != chip::DeviceLayer::ConnectivityChange::kConnectivity_NoChange) {
42+
Serial.print("IPv4 Connectivity: ");
43+
switch (eventInfo->InternetConnectivityChange.IPv4) {
44+
case chip::DeviceLayer::ConnectivityChange::kConnectivity_Established: {
45+
newIPAddress = true;
46+
break;
47+
}
48+
case chip::DeviceLayer::ConnectivityChange::kConnectivity_Lost:
49+
Serial.println("Lost");
50+
break;
51+
default:
52+
Serial.println("Unknown");
53+
break;
54+
}
55+
}
56+
if (eventInfo->InternetConnectivityChange.IPv6 != chip::DeviceLayer::ConnectivityChange::kConnectivity_NoChange) {
57+
Serial.print("IPv6 Connectivity: ");
58+
switch (eventInfo->InternetConnectivityChange.IPv6) {
59+
case chip::DeviceLayer::ConnectivityChange::kConnectivity_Established: {
60+
newIPAddress = true;
61+
break;
62+
}
63+
case chip::DeviceLayer::ConnectivityChange::kConnectivity_Lost:
64+
Serial.println("Lost");
65+
break;
66+
default:
67+
Serial.println("Unknown");
68+
break;
69+
}
70+
}
71+
// Print the IP address if it was established
72+
if (newIPAddress) {
73+
Serial.print("Established - IP Address: ");
74+
char ipAddressStr[chip::Transport::PeerAddress::kMaxToStringSize];
75+
eventInfo->InternetConnectivityChange.ipAddress.ToString(ipAddressStr);
76+
Serial.println(ipAddressStr);
77+
}
78+
break;
79+
}
80+
case ArduinoMatter::MATTER_SERVICE_CONNECTIVITY_CHANGE:
81+
Serial.println("Service Connectivity Change");
82+
break;
83+
case ArduinoMatter::MATTER_SERVICE_PROVISIONING_CHANGE:
84+
Serial.println("Service Provisioning Change");
85+
break;
86+
case ArduinoMatter::MATTER_TIME_SYNC_CHANGE:
87+
Serial.println("Time Sync Change");
88+
break;
89+
case ArduinoMatter::MATTER_CHIPOBLE_CONNECTION_ESTABLISHED:
90+
Serial.println("CHIPoBLE Connection Established");
91+
break;
92+
case ArduinoMatter::MATTER_CHIPOBLE_CONNECTION_CLOSED:
93+
Serial.println("CHIPoBLE Connection Closed");
94+
break;
95+
case ArduinoMatter::MATTER_CLOSE_ALL_BLE_CONNECTIONS:
96+
Serial.println("Close All BLE Connections");
97+
break;
98+
case ArduinoMatter::MATTER_WIFI_DEVICE_AVAILABLE:
99+
Serial.println("WiFi Device Available");
100+
break;
101+
case ArduinoMatter::MATTER_OPERATIONAL_NETWORK_STARTED:
102+
Serial.println("Operational Network Started");
103+
break;
104+
case ArduinoMatter::MATTER_THREAD_STATE_CHANGE:
105+
Serial.println("Thread State Change");
106+
break;
107+
case ArduinoMatter::MATTER_THREAD_INTERFACE_STATE_CHANGE:
108+
Serial.println("Thread Interface State Change");
109+
break;
110+
case ArduinoMatter::MATTER_CHIPOBLE_ADVERTISING_CHANGE:
111+
Serial.println("CHIPoBLE Advertising Change");
112+
break;
113+
case ArduinoMatter::MATTER_INTERFACE_IP_ADDRESS_CHANGED:
114+
switch (eventInfo->InterfaceIpAddressChanged.Type) {
115+
case chip::DeviceLayer::InterfaceIpChangeType::kIpV4_Assigned:
116+
Serial.println("IPv4 Address Assigned");
117+
break;
118+
case chip::DeviceLayer::InterfaceIpChangeType::kIpV4_Lost:
119+
Serial.println("IPv4 Address Lost");
120+
break;
121+
case chip::DeviceLayer::InterfaceIpChangeType::kIpV6_Assigned:
122+
Serial.println("IPv6 Address Assigned");
123+
break;
124+
case chip::DeviceLayer::InterfaceIpChangeType::kIpV6_Lost:
125+
Serial.println("IPv6 Address Lost");
126+
break;
127+
}
128+
break;
129+
case ArduinoMatter::MATTER_COMMISSIONING_COMPLETE:
130+
Serial.println("Commissioning Complete");
131+
break;
132+
case ArduinoMatter::MATTER_FAIL_SAFE_TIMER_EXPIRED:
133+
Serial.println("Fail Safe Timer Expired");
134+
break;
135+
case ArduinoMatter::MATTER_OPERATIONAL_NETWORK_ENABLED:
136+
Serial.println("Operational Network Enabled");
137+
break;
138+
case ArduinoMatter::MATTER_DNSSD_INITIALIZED:
139+
Serial.println("DNS-SD Initialized");
140+
break;
141+
case ArduinoMatter::MATTER_DNSSD_RESTART_NEEDED:
142+
Serial.println("DNS-SD Restart Needed");
143+
break;
144+
case ArduinoMatter::MATTER_BINDINGS_CHANGED_VIA_CLUSTER:
145+
Serial.println("Bindings Changed Via Cluster");
146+
break;
147+
case ArduinoMatter::MATTER_OTA_STATE_CHANGED:
148+
Serial.println("OTA State Changed");
149+
break;
150+
case ArduinoMatter::MATTER_SERVER_READY:
151+
Serial.println("Server Ready");
152+
break;
153+
case ArduinoMatter::MATTER_BLE_DEINITIALIZED:
154+
Serial.println("BLE Deinitialized");
155+
break;
156+
case ArduinoMatter::MATTER_COMMISSIONING_SESSION_STARTED:
157+
Serial.println("Commissioning Session Started");
158+
break;
159+
case ArduinoMatter::MATTER_COMMISSIONING_SESSION_STOPPED:
160+
Serial.println("Commissioning Session Stopped");
161+
break;
162+
case ArduinoMatter::MATTER_COMMISSIONING_WINDOW_OPEN:
163+
Serial.println("Commissioning Window Opened");
164+
break;
165+
case ArduinoMatter::MATTER_COMMISSIONING_WINDOW_CLOSED:
166+
Serial.println("Commissioning Window Closed");
167+
break;
168+
case ArduinoMatter::MATTER_FABRIC_WILL_BE_REMOVED:
169+
Serial.println("Fabric Will Be Removed");
170+
break;
171+
case ArduinoMatter::MATTER_FABRIC_REMOVED:
172+
Serial.println("Fabric Removed");
173+
break;
174+
case ArduinoMatter::MATTER_FABRIC_COMMITTED:
175+
Serial.println("Fabric Committed");
176+
break;
177+
case ArduinoMatter::MATTER_FABRIC_UPDATED:
178+
Serial.println("Fabric Updated");
179+
break;
180+
case ArduinoMatter::MATTER_ESP32_SPECIFIC_EVENT:
181+
Serial.println("Sending ESP32 Platform Specific Events");
182+
break;
183+
case ArduinoMatter::MATTER_ESP32_PUBLIC_SPECIFIC_EVENT:
184+
Serial.println("Next Event Has Populated EventInfo");
185+
break;
186+
default:
187+
// If the event type is not recognized, print "Unknown" and the event ID
188+
Serial.println("Unknown, EventID = 0x" + String(eventType, HEX));
189+
break;
190+
}
191+
}
192+
193+
void setup() {
194+
Serial.begin(115200);
195+
while (!Serial) {
196+
delay(10); // Wait for Serial to initialize
197+
}
198+
199+
// We start by connecting to a WiFi network
200+
Serial.print("Connecting to ");
201+
Serial.println(ssid);
202+
// Manually connect to WiFi
203+
WiFi.enableIPv6(true); // Enable IPv6 if needed
204+
WiFi.begin(ssid, password);
205+
// Wait for connection
206+
while (WiFi.status() != WL_CONNECTED) {
207+
delay(500);
208+
Serial.print(".");
209+
}
210+
Serial.println("\r\nWiFi connected");
211+
Serial.println("IP address: ");
212+
Serial.println(WiFi.localIP());
213+
delay(500);
214+
215+
// Initialize at least one Matter EndPoint
216+
OnOffLight.begin();
217+
218+
// Set the Matter Event Callback
219+
Matter.onEvent(onMatterEvent);
220+
// Matter beginning - Last step, after all EndPoints are initialized
221+
Matter.begin();
222+
Serial.println("Starting Matter Commission Test...");
223+
224+
}
225+
226+
void loop() {
227+
// Check Matter Commissioning state
228+
if (!Matter.isDeviceCommissioned()) {
229+
Serial.println("");
230+
Serial.println("Matter Node is not commissioned yet.");
231+
Serial.println("Initiate the device discovery in your Matter environment.");
232+
Serial.println("Commission it to your Matter hub with the manual pairing code or QR code");
233+
Serial.printf("Manual pairing code: %s\r\n", Matter.getManualPairingCode().c_str());
234+
Serial.printf("QR code URL: %s\r\n", Matter.getOnboardingQRCodeUrl().c_str());
235+
// waits for Matter Light Commissioning.
236+
while (!Matter.isDeviceCommissioned()) {
237+
delay(5000);
238+
Serial.println("Matter Fabric not commissioned yet. Waiting for commissioning.");
239+
}
240+
}
241+
Serial.println("Matter Node is commissioned and connected to Wi-Fi.");
242+
Serial.println("====> Decommissioning in 60 seconds. <====");
243+
delay(60000);
244+
Matter.decommission();
245+
Serial.println("Matter Node is decommissioned. Commsssioning widget shall start over.");
246+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"fqbn_append": "PartitionScheme=huge_app",
3+
"requires": [
4+
"CONFIG_SOC_WIFI_SUPPORTED=y",
5+
"CONFIG_ESP_MATTER_ENABLE_DATA_MODEL=y"
6+
]
7+
}

libraries/Matter/src/Matter.cpp

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ constexpr auto k_timeout_seconds = 300;
2929
static bool _matter_has_started = false;
3030
static node::config_t node_config;
3131
static node_t *deviceNode = NULL;
32+
ArduinoMatter::matterEventCB ArduinoMatter::_matterEventCB = NULL;
3233

3334
// This callback is called for every attribute update. The callback implementation shall
3435
// handle the desired attributes and return an appropriate error code. If the attribute
@@ -89,21 +90,21 @@ static esp_err_t app_identification_cb(identification::callback_type_t type, uin
8990
static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg) {
9091
switch (event->Type) {
9192
case chip::DeviceLayer::DeviceEventType::kInterfaceIpAddressChanged:
92-
log_i(
93+
log_d(
9394
"Interface %s Address changed", event->InterfaceIpAddressChanged.Type == chip::DeviceLayer::InterfaceIpChangeType::kIpV4_Assigned ? "IPv4" : "IPV6"
9495
);
9596
break;
96-
case chip::DeviceLayer::DeviceEventType::kCommissioningComplete: log_i("Commissioning complete"); break;
97-
case chip::DeviceLayer::DeviceEventType::kFailSafeTimerExpired: log_i("Commissioning failed, fail safe timer expired"); break;
98-
case chip::DeviceLayer::DeviceEventType::kCommissioningSessionStarted: log_i("Commissioning session started"); break;
99-
case chip::DeviceLayer::DeviceEventType::kCommissioningSessionStopped: log_i("Commissioning session stopped"); break;
100-
case chip::DeviceLayer::DeviceEventType::kCommissioningWindowOpened: log_i("Commissioning window opened"); break;
101-
case chip::DeviceLayer::DeviceEventType::kCommissioningWindowClosed: log_i("Commissioning window closed"); break;
97+
case chip::DeviceLayer::DeviceEventType::kCommissioningComplete: log_d("Commissioning complete"); break;
98+
case chip::DeviceLayer::DeviceEventType::kFailSafeTimerExpired: log_d("Commissioning failed, fail safe timer expired"); break;
99+
case chip::DeviceLayer::DeviceEventType::kCommissioningSessionStarted: log_d("Commissioning session started"); break;
100+
case chip::DeviceLayer::DeviceEventType::kCommissioningSessionStopped: log_d("Commissioning session stopped"); break;
101+
case chip::DeviceLayer::DeviceEventType::kCommissioningWindowOpened: log_d("Commissioning window opened"); break;
102+
case chip::DeviceLayer::DeviceEventType::kCommissioningWindowClosed: log_d("Commissioning window closed"); break;
102103
case chip::DeviceLayer::DeviceEventType::kFabricRemoved:
103104
{
104-
log_i("Fabric removed successfully");
105+
log_d("Fabric removed successfully");
105106
if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) {
106-
log_i("No fabric left, opening commissioning window");
107+
log_d("No fabric left, opening commissioning window");
107108
chip::CommissioningWindowManager &commissionMgr = chip::Server::GetInstance().GetCommissioningWindowManager();
108109
constexpr auto kTimeoutSeconds = chip::System::Clock::Seconds16(k_timeout_seconds);
109110
if (!commissionMgr.IsCommissioningWindowOpen()) {
@@ -116,12 +117,16 @@ static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg) {
116117
}
117118
break;
118119
}
119-
case chip::DeviceLayer::DeviceEventType::kFabricWillBeRemoved: log_i("Fabric will be removed"); break;
120-
case chip::DeviceLayer::DeviceEventType::kFabricUpdated: log_i("Fabric is updated"); break;
121-
case chip::DeviceLayer::DeviceEventType::kFabricCommitted: log_i("Fabric is committed"); break;
122-
case chip::DeviceLayer::DeviceEventType::kBLEDeinitialized: log_i("BLE deinitialized and memory reclaimed"); break;
120+
case chip::DeviceLayer::DeviceEventType::kFabricWillBeRemoved: log_d("Fabric will be removed"); break;
121+
case chip::DeviceLayer::DeviceEventType::kFabricUpdated: log_d("Fabric is updated"); break;
122+
case chip::DeviceLayer::DeviceEventType::kFabricCommitted: log_d("Fabric is committed"); break;
123+
case chip::DeviceLayer::DeviceEventType::kBLEDeinitialized: log_d("BLE deinitialized and memory reclaimed"); break;
123124
default: break;
124125
}
126+
// Check if the user-defined callback is set
127+
if (ArduinoMatter::_matterEventCB != NULL) {
128+
ArduinoMatter::_matterEventCB(static_cast<ArduinoMatter::matterEvent_t>(event->Type), event);
129+
}
125130
}
126131

127132
void ArduinoMatter::_init() {

0 commit comments

Comments
 (0)