Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Matter physical light state is different in light state in UI when power cut #10542

Closed Unanswered
Nezaemmy asked this question in Q&A
Discussion options

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

You must be logged in to vote

Replies: 5 comments 13 replies

Comment options

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

You must be logged in to vote
0 replies
Comment options

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.

You must be logged in to vote
0 replies
Comment options

@Nezaemmy - I see the issue now. I'll get it fixed.

You must be logged in to vote
0 replies
Comment options

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.

You must be logged in to vote
4 replies
Comment options

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.

Comment options

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.

@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

Comment options

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.

Comment options

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);
Comment options

@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.

You must be logged in to vote
9 replies
Comment options

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) )

Comment options

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.

Comment options

You can check the code from MatterComposedLights.ino example to see how to create multiple light endpoints, each with its own callback.

Comment options

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) )

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.

Comment options

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.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /