-
Notifications
You must be signed in to change notification settings - Fork 7.7k
-
I'm Testing MatterOnOffLight.ino example, when the power cut on the device and connected again, the system start misbehaving, the state of physical light not the same as state of UI light.
is much noticeable when you change true to false on this line bool lastOnOffState = lastStatePref.getBool("lastOnOffState", false);.
@SuGlider
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 5 comments 13 replies
-
it seems like the UI is not refreshing when the power cut to match the state of the initial physical state when power comes up. sometimes it continue shows ON on UI but OFF physically
Beta Was this translation helpful? Give feedback.
All reactions
-
The Matter ESP32 firmware sends the information about its state to the Matter Controller.
The Matter Controller talks to the Smartphone APP, which request, at its own time, the status of all connected devices.
I'm sure that the communication from the ESP32 to the Matter Controller happens instantaneously.
The Matter Controller may be an Alexa Echo Dot, or a Google Nest, or an Apple TV.
It is the responsibility of the Smartphone APP to update its own UI.
The ESP32 Firmware just needs to report data to the Matter Controller.
Beta Was this translation helpful? Give feedback.
All reactions
-
@Nezaemmy - I see the issue now. I'll get it fixed.
Beta Was this translation helpful? Give feedback.
All reactions
-
The issue is with Preferences... for some reason, the getBool(char* key, bool defaultVal) that should return defaultVal when the NVS is empty, it alway returns false, making the light to be off in the initial state.
Beta Was this translation helpful? Give feedback.
All reactions
-
The issue is with Preferences... for some reason, the getBool(char* key, bool defaultVal) that should return defaultVal when the NVS is empty, it alway returns false, making the light to be off in the initial state.
@Nezaemmy
OK... The issue here is that NVS already has data stored. When the Sketch is uploaded, NVS is kept in place and it defines initial on_off state. In order to make sure NVS is empty, it is necessary to set "Arduino IDE Menu->Tools->Erase All Flash Before Sketch Upload:" to Enable. This setting will erase NVS and the begin(bool) will always work.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1
-
The issue is with Preferences... for some reason, the getBool(char* key, bool defaultVal) that should return defaultVal when the NVS is empty, it alway returns false, making the light to be off in the initial state.
@Nezaemmy OK... The issue here is that NVS already has data stored. When the Sketch is uploaded, NVS is kept in place and it defines initial on_off state. In order to make sure NVS is empty, it is necessary to set "Arduino IDE Menu->Tools->Erase All Flash Before Sketch Upload:" to
Enable. This setting will erase NVS and thebegin(bool)will always work.
@SuGlider thank you for your guidance.
I have another question, what to change in the code so that the matter device can not remember the last state when matter device is restarted? it is Ok to remember the last state and sometimes also it is not Ok.
Let me give you an example, suppose the power cut on the device at 7:00 PM when the light was ON and the power comes up at midnight automatically the light will be ON.
by referring to the MatterOnOffLight.ino example which line can I change so that the matter device can not remember the last state after restarting the device?
I tried to change this line lastStatePref.putBool("lastOnOffState", !state); and the system started behaving as the issue before where UI is not at the same state as the physical light (UI is not synchronizing with the state of physical light ). I'm using iPhone ios18.1 with esp32s3
Beta Was this translation helpful? Give feedback.
All reactions
-
Preference::putBool(char *nvsDB, bool state) saves the state to the NVS (flash partition).
You can change the code in the setup():
void setup() { // WiFi code etc... // Initialize Matter EndPoint lastStatePref.begin("matterLight", false); // <<<==== just opens NVS Preference data partition bool lastOnOffState = lastStatePref.getBool("lastOnOffState", true); // <<<==== gets value of the last Light State, if no previous value, default will be true if (time_is_between_midnight_and_6am) lastOnOffState = false; // <<<<==== forces lastState to be OFF in certain time conditions OnOffLight.begin(lastOnOffState); // <<<<==== creates the MatterLight with the inital ON-OFF state // rest of code.... }
It is necessary to implement the time_is_between_midnight_and_6am code, but this is the general idea.
Beta Was this translation helpful? Give feedback.
All reactions
-
I tried this option but It isn't working, it is OFF physically but on the UI it is showing ON. it seems like it is OFF physically but internally is ON because to turn ON the physical light again after the power comes up you need to press the button 3 times.
Try to disconnect the board from the power when UI and light are ON and reconnect the board again
I use this to eliminate the time
bool lastOnOffState = lastStatePref.getBool("lastOnOffState", true);
lastOnOffState = false;
OnOffLight.begin(lastOnOffState);
Beta Was this translation helpful? Give feedback.
All reactions
-
@SuGlider I found other issue on MatterOnOffLight.
I created MatterOnOffLight based on time. this is the sketch
#include <Matter.h>
#include <WiFi.h>
#include <Preferences.h>
#include "time.h"
const char *ntpServer1 = "pool.ntp.org";
const char *ntpServer2 = "time.nist.gov";
const long gmtOffset_sec = 3600; //GMT+1
const int daylightOffset_sec = 0;
struct tm timeinfo;
MatterOnOffLight OnOffLight;
// it will keep last OnOff state stored, using Preferences
Preferences lastStatePref;
// set your board LED pin here
#ifdef LED_BUILTIN
const uint8_t ledPin = LED_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 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 = "wifi"; // Change this to your WiFi SSID
const char *password = "password"; // Change this to your WiFi password
// Matter Protocol Endpoint Callback
bool setLightOnOff(bool state) {
Serial.printf("User Callback :: New Light State = %s\r\n", state ? "ON" : "OFF");
if (state) {
digitalWrite(ledPin, HIGH);
} else {
digitalWrite(ledPin, LOW);
}
// 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;
}
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);
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2);
// Initialize Matter EndPoint
lastStatePref.begin("matterLight", false);
bool lastOnOffState = lastStatePref.getBool("lastOnOffState", false);
OnOffLight.begin(lastOnOffState);
OnOffLight.onChange(setLightOnOff);
// 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\r\n", OnOffLight.getOnOff() ? "ON" : "OFF");
OnOffLight.updateAccessory(); // configure the Light based on initial state
}
}
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\r\n", OnOffLight.getOnOff() ? "ON" : "OFF");
OnOffLight.updateAccessory(); // configure the Light based on initial state
Serial.println("Matter Node is commissioned and connected to Wi-Fi. Ready for use.");
}
SwitchTime();
}
void SwitchTime(){
if( WiFi.isConnected() && getLocalTime(&timeinfo)){
if ( timeinfo.tm_hour==14 && timeinfo.tm_min==55 && timeinfo.tm_min<=59){ //Time to turn ON Light
OnOffLight.setOnOff(true); // turn the light on
}
else if ( timeinfo.tm_hour==15 && timeinfo.tm_min==0 && timeinfo.tm_min<5){ //Time to turn OFF Light
OnOffLight.setOnOff(false); // turn the light on
}
}
}
by setting your local time const long gmtOffset_sec = 3600; //GMT+1 my time and settup the time to switch the light
void SwitchTime(){
if( WiFi.isConnected() && getLocalTime(&timeinfo)){
if ( timeinfo.tm_hour==14 && timeinfo.tm_min==55 && timeinfo.tm_min<=59){ //Time to turn ON Light
OnOffLight.setOnOff(true); // turn the light on
}
else if ( timeinfo.tm_hour==15 && timeinfo.tm_min==0 && timeinfo.tm_min<5){ //Time to turn OFF Light
OnOffLight.setOnOff(false); // turn the light on
}
}
}
this example works very well even if you press the reset pin on the board, the light will work again whenever the working time is not over.
-THE ISSUE
if you add any thing to lastOnOffState like lastOnOffState1 the Light can't work.
// Initialize Matter EndPoint
lastStatePref.begin("matterLight", false);
bool lastOnOffState1 = lastStatePref.getBool("lastOnOffState1", false);
OnOffLight.begin(lastOnOffState1);
OnOffLight.onChange(setLightOnOff);
I spend a week figure out the issue.
This change on lastOnOffState con't affect the button switch, it is affecting only time based switch.
Beta Was this translation helpful? Give feedback.
All reactions
-
May I make a suggestion: instead of using 15 different lastOnOffState variables, it could be summarized into just a single 16 bits bitmap.
uint16_t lastOnOffState = lastStatePref.getUShort("lastOnOffState", false);
each bit is a lamp state (bit 0 | 1). Example:
lamp1 is bit 0 ==> lastOnOffState & 0x1 will tell its state
lamp2 is bit 1 ==> lastOnOffState & 0x2 and so on
Generic lastOnOffState & (1 << LampNumber) will indicate any lamp state.
Set and Reset:
Set ON ==> lastOnOffState = lastOnOffState | (1 << LampNumber)
Set OFF ==> lastOnOffState = lastOnOffState & ( ~(1 << LampNumber) )
Beta Was this translation helpful? Give feedback.
All reactions
-
the endpoint that has an autolight based on time doesn't work unless I use lastOnOffState without any addition number
I guess that there are 15 different MatterOnOffLight OnOffLight<1..15> declarations, one for each light. Something like MatterOnOffLight OnOffLight1 to MatterOnOffLight OnOffLight15. Each object has its own begin() and onChange(setLightOnOff<1..15>) with 15 different setLightOnOff<1..15>() functions. Otherwise it is not possible to control each light individually.
Kind of big, but posssible, I think.
Beta Was this translation helpful? Give feedback.
All reactions
-
You can check the code from MatterComposedLights.ino example to see how to create multiple light endpoints, each with its own callback.
Beta Was this translation helpful? Give feedback.
All reactions
-
May I make a suggestion: instead of using 15 different
lastOnOffStatevariables, it could be summarized into just a single 16 bits bitmap.
uint16_t lastOnOffState = lastStatePref.getUShort("lastOnOffState", false);each bit is a lamp state (bit 0 | 1). Example: lamp1 is bit 0 ==>lastOnOffState & 0x1will tell its state lamp2 is bit 1 ==>lastOnOffState & 0x2and so on GenericlastOnOffState & (1 << LampNumber)will indicate any lamp state.Set and Reset: Set ON ==>
lastOnOffState = lastOnOffState | (1 << LampNumber)Set OFF ==>lastOnOffState = lastOnOffState & ( ~(1 << LampNumber) )
Thank you @SuGlider, This option should be a good ideal. May you help me to make the code of 2 endpoints using this opton? I can us it as a reference.
Beta Was this translation helpful? Give feedback.
All reactions
-
the endpoint that has an autolight based on time doesn't work unless I use lastOnOffState without any addition number
I guess that there are 15 different
MatterOnOffLight OnOffLight<1..15>declarations, one for each light. Something likeMatterOnOffLight OnOffLight1toMatterOnOffLight OnOffLight15. Each object has its ownbegin()andonChange(setLightOnOff<1..15>)with 15 differentsetLightOnOff<1..15>()functions. Otherwise it is not possible to control each light individually.Kind of big, but posssible, I think.
Yeah, each endpoint has its own setting. all 15 endpoints are working well. it is only that issue I had on one endpoint. I was wondering, may be the esp32 starts checking from lastOnOffState without index and next checks lastOnOffState with index.
Beta Was this translation helpful? Give feedback.