Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ set(ARDUINO_LIBRARY_OpenThread_SRCS
libraries/OpenThread/src/OThreadCLI_Util.cpp)

set(ARDUINO_LIBRARY_Matter_SRCS
libraries/Matter/src/MatterOnOffLight.cpp
libraries/Matter/src/MatterEndpoints/MatterOnOffLight.cpp
libraries/Matter/src/MatterEndpoints/MatterDimmableLight.cpp
libraries/Matter/src/Matter.cpp)

set(ARDUINO_LIBRARY_PPP_SRCS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

// List of Matter Endpoints for this Node
// On/Off Light Endpoint
#include <MatterOnOffLight.h>
#include <MatterEndpoints/MatterOnOffLight.h>
MatterOnOffLight OnOffLight;

// WiFi is manually set and started
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

// List of Matter Endpoints for this Node
// There will be 3 On/Off Light Endpoints in the same Node
#include <MatterOnOffLight.h>
#include <MatterEndpoints/MatterOnOffLight.h>
MatterOnOffLight OnOffLight1;
MatterOnOffLight OnOffLight2;
MatterOnOffLight OnOffLight3;
Expand Down
157 changes: 157 additions & 0 deletions libraries/Matter/examples/MatterDimmableLight/MatterDimmableLight.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// Matter Manager
#include <Matter.h>
#include <WiFi.h>
#include <Preferences.h>

// List of Matter Endpoints for this Node
// Dimmable Light Endpoint
#include <MatterEndpoints/MatterDimmableLight.h>
MatterDimmableLight DimmableLight;

// it will keep last OnOff & Brightness state stored, using Preferences
Preferences lastStatePref;

// set your board RGB LED pin here
#ifdef RGB_BUILTIN
const uint8_t ledPin = RGB_BUILTIN;
#else
const uint8_t ledPin = 2; // Set your pin here if your board has not defined LED_BUILTIN
#warning "Do not forget to set the RGB LED pin"
#endif

// set your board USER BUTTON pin here
const uint8_t buttonPin = 0; // Set your pin here. Using BOOT Button. C6/C3 use GPIO9.

// WiFi is manually set and started
const char *ssid = "your-ssid"; // Change this to your WiFi SSID
const char *password = "your-password"; // Change this to your WiFi password

// Set the RGB LED Light based on the current state of the Dimmable Light
void setRGBLight(bool state, uint8_t brightness) {
Serial.printf("Setting Light to State: %s and Brightness: %d\r\n", DimmableLight ? "ON" : "OFF", brightness);
if (state) {
rgbLedWrite(ledPin, brightness, brightness, brightness);
} else {
digitalWrite(ledPin, LOW);
}
}

// Matter Protocol Endpoint On-Off Change Callback
bool setLightOnOff(bool state) {
Serial.printf("User Callback :: New Light State = %s\r\n", state ? "ON" : "OFF");
setRGBLight(state, DimmableLight.getBrightness());
// store last OnOff state for when the Light is restarted / power goes off
lastStatePref.putBool("lastOnOffState", state);
// This callback must return the success state to Matter core
return true;
}

// Matter Protocol Endpoint Brightness Change Callback
bool setLightBrightness(uint8_t brightness) {
Serial.printf("User Callback :: New Light Brigthness = %.2f%% [Val = %d]\r\n", ((float) brightness * 100) / MatterDimmableLight::MAX_BRIGHTNESS, brightness);
setRGBLight(DimmableLight.getOnOff(), brightness);
// store last Brightness for when the Light is restarted / power goes off
lastStatePref.putUChar("lastBrightness", brightness);
// This callback must return the success state to Matter core
return true;
}

void setup() {
// Initialize the USER BUTTON (Boot button) GPIO that will act as a toggle switch
pinMode(buttonPin, INPUT_PULLUP);
// Initialize the LED (light) GPIO and Matter End Point
pinMode(ledPin, OUTPUT);

Serial.begin(115200);
while (!Serial) {
delay(100);
}

// We start by connecting to a WiFi network
Serial.print("Connecting to ");
Serial.println(ssid);
// enable IPv6
WiFi.enableIPv6(true);
// Manually connect to WiFi
WiFi.begin(ssid, password);
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\r\nWiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
delay(500);

// Initialize Matter EndPoint
lastStatePref.begin("matterLight", false);
bool lastOnOffState = lastStatePref.getBool("lastOnOffState", true);
uint8_t lastBrightness = lastStatePref.getUChar("lastBrightness", 15); // default brightness = 12%
DimmableLight.begin(lastOnOffState, lastBrightness);
DimmableLight.onChangeOnOff(setLightOnOff);
DimmableLight.onChangeBrightness(setLightBrightness);

// Matter beginning - Last step, after all EndPoints are initialized
Matter.begin();
// This may be a restart of a already commissioned Matter accessory
if (Matter.isDeviceCommissioned()) {
Serial.println("Matter Node is commissioned and connected to Wi-Fi. Ready for use.");
Serial.printf("Initial state: %s | brightness: %d\r\n", DimmableLight ? "ON" : "OFF", DimmableLight.getBrightness());
setLightOnOff(DimmableLight.getOnOff()); // configure the Light based on initial state
setLightBrightness(DimmableLight.getBrightness()); // configure the Light based on initial brightness
}
}
// Button control
uint32_t button_time_stamp = 0; // debouncing control
bool button_state = false; // false = released | true = pressed
const uint32_t debouceTime = 250; // button debouncing time (ms)
const uint32_t decommissioningTimeout = 10000; // keep the button pressed for 10s to decommission the light

void loop() {
// Check Matter Light Commissioning state, which may change during execution of loop()
if (!Matter.isDeviceCommissioned()) {
Serial.println("");
Serial.println("Matter Node is not commissioned yet.");
Serial.println("Initiate the device discovery in your Matter environment.");
Serial.println("Commission it to your Matter hub with the manual pairing code or QR code");
Serial.printf("Manual pairing code: %s\r\n", Matter.getManualPairingCode().c_str());
Serial.printf("QR code URL: %s\r\n", Matter.getOnboardingQRCodeUrl().c_str());
// waits for Matter Light Commissioning.
uint32_t timeCount = 0;
while (!Matter.isDeviceCommissioned()) {
delay(100);
if ((timeCount++ % 50) == 0) { // 50*100ms = 5 sec
Serial.println("Matter Node not commissioned yet. Waiting for commissioning.");
}
}
Serial.printf("Initial state: %s | brightness: %d\r\n", DimmableLight ? "ON" : "OFF", DimmableLight.getBrightness());
setLightOnOff(DimmableLight.getOnOff()); // configure the Light based on initial state
setLightBrightness(DimmableLight.getBrightness()); // configure the Light based on initial brightness
Serial.println("Matter Node is commissioned and connected to Wi-Fi. Ready for use.");
}

// A button is also used to control the light
// Check if the button has been pressed
if (digitalRead(buttonPin) == LOW && !button_state) {
// deals with button debouncing
button_time_stamp = millis(); // record the time while the button is pressed.
button_state = true; // pressed.
}

// Onboard User Button is used as a Light toggle switch or to decommission it
uint32_t time_diff = millis() - button_time_stamp;
if (button_state && time_diff > debouceTime && digitalRead(buttonPin) == HIGH) {
button_state = false; // released
// Toggle button is released - toggle the light
Serial.println("User button released. Toggling Light!");
DimmableLight.toggle(); // Matter Controller also can see the change

// Factory reset is triggered if the button is pressed longer than 10 seconds
if (time_diff > decommissioningTimeout) {
Serial.println("Decommissioning the Light Matter Accessory. It shall be commissioned again.");
DimmableLight = false; // turn the light off
Matter.decommission();
}
}
}
7 changes: 7 additions & 0 deletions libraries/Matter/examples/MatterDimmableLight/ci.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"fqbn_append": "PartitionScheme=huge_app",
"requires": [
"CONFIG_SOC_WIFI_SUPPORTED=y",
"CONFIG_ESP_MATTER_ENABLE_DATA_MODEL=y"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

// List of Matter Endpoints for this Node
// On/Off Light Endpoint
#include <MatterOnOffLight.h>
#include <MatterEndpoints/MatterOnOffLight.h>
MatterOnOffLight OnOffLight;

// it will keep last OnOff state stored, using Preferences
Expand Down
13 changes: 7 additions & 6 deletions libraries/Matter/src/Matter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,26 @@ esp_err_t matter_light_attribute_update(
static esp_err_t app_attribute_update_cb(
attribute::callback_type_t type, uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id, esp_matter_attr_val_t *val, void *priv_data
) {
log_d("Attribute update callback: type: %u, endpoint: %u, cluster: %u, attribute: %u, val: %u", type, endpoint_id, cluster_id, attribute_id, val->val.u32);
esp_err_t err = ESP_OK;
MatterEndPoint *ep = (MatterEndPoint *)priv_data; // endpoint pointer to base class
switch (type) {
case PRE_UPDATE: // Callback before updating the value in the database
log_i("Attribute update callback: PRE_UPDATE");
log_v("Attribute update callback: PRE_UPDATE");
if (ep != NULL) {
err = ep->attributeChangeCB(endpoint_id, cluster_id, attribute_id, val) ? ESP_OK : ESP_FAIL;
}
break;
case POST_UPDATE: // Callback after updating the value in the database
log_i("Attribute update callback: POST_UPDATE");
log_v("Attribute update callback: POST_UPDATE");
break;
case READ: // Callback for reading the attribute value. This is used when the `ATTRIBUTE_FLAG_OVERRIDE` is set.
log_i("Attribute update callback: READ");
log_v("Attribute update callback: READ");
break;
case WRITE: // Callback for writing the attribute value. This is used when the `ATTRIBUTE_FLAG_OVERRIDE` is set.
log_i("Attribute update callback: WRITE");
log_v("Attribute update callback: WRITE");
break;
default: log_i("Attribute update callback: Unknown type %d", type);
default: log_v("Attribute update callback: Unknown type %d", type);
}
return err;
}
Expand Down Expand Up @@ -114,7 +115,7 @@ void ArduinoMatter::_init() {

void ArduinoMatter::begin() {
if (!_matter_has_started) {
log_w("No Matter endpoint has been created. Please create an endpoint first.");
log_e("No Matter endpoint has been created. Please create an endpoint first.");
return;
}

Expand Down
1 change: 1 addition & 0 deletions libraries/Matter/src/Matter.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class ArduinoMatter {

// list of Matter EndPoints Friend Classes
friend class MatterOnOffLight;
friend class MatterDimmableLight;

protected:
static void _init();
Expand Down
Loading
Loading