kakopappa / sinric

Amazon Alexa Smart home skill / Google Home Action for ESP8266 / ESP32 / Arduino
https://sinric.com
285 stars 166 forks source link

UNINTENDED TURNING ON OF RELAYS ON START UP #437

Open ajarsco opened 3 years ago

ajarsco commented 3 years ago

When ever my powersupply goes off and comes back up.. all the relays get switched on and not to the previous state .. how can i correct this.. Kindly reply fast..

include

include

include

include // https://github.com/kakopappa/sinric/wiki/How-to-add-dependency-libraries

include // https://github.com/kakopappa/sinric/wiki/How-to-add-dependency-libraries

include

include // https://github.com/bxparks/AceButton

using namespace ace_button; ESP8266WiFiMulti WiFiMulti; WebSocketsClient webSocket; WiFiClient client;

define MyApiKey "" // TODO: Change to your sinric API Key. Your API Key is displayed on sinric.com dashboard

define MySSID "" // TODO: Change to your Wifi network SSID

define MyWifiPassword "" // TODO: Change to your Wifi network Password

define HEARTBEAT_INTERVAL 300000 // 5 Minutes

uint64_t heartbeatTimestamp = 0; bool isConnected = false;

// Switch const int BUTTON1_PIN = 15; const int BUTTON2_PIN = 5; const int BUTTON3_PIN = 4; const int BUTTON4_PIN = 0;

//Relays const int RELAY1_PIN = 2; const int RELAY2_PIN = 14; const int RELAY3_PIN = 12; const int RELAY4_PIN = 13;

//Status LEDs const int LED1 = 16; const int LED2 = 3; const int LED3 = 1;

String device_ID_1 = ""; String device_ID_2 = ""; String device_ID_3 = ""; String device_ID_4 = "";

ButtonConfig config1; AceButton button1(&config1); ButtonConfig config2; AceButton button2(&config2); ButtonConfig config3; AceButton button3(&config3); ButtonConfig config4; AceButton button4(&config4);

void handleEvent1(AceButton, uint8_t, uint8_t); void handleEvent2(AceButton, uint8_t, uint8_t); void handleEvent3(AceButton, uint8_t, uint8_t); void handleEvent4(AceButton, uint8_t, uint8_t);

void setPowerStateOnServer(String deviceId, String value);

// deviceId is the ID assgined to your smart-home-device in sinric.com dashboard. Copy it from dashboard and paste it here

void turnOn(String deviceId) { if (deviceId == device_ID_1) // Device ID of first device { Serial.print("Turn on device id: 1"); Serial.println(deviceId); digitalWrite(RELAY1_PIN, LOW); } if (deviceId == device_ID_2) // Device ID of second device { Serial.print("Turn on device id: 2"); Serial.println(deviceId); digitalWrite(RELAY2_PIN, LOW); } if (deviceId == device_ID_3) // Device ID of third device { Serial.print("Turn on device id: 3 "); Serial.println(deviceId); digitalWrite(RELAY3_PIN, LOW); } if (deviceId == device_ID_4) // Device ID of fourth device { Serial.print("Turn on device id: 4"); Serial.println(deviceId); digitalWrite(RELAY4_PIN, LOW); }

}

void turnOff(String deviceId) { if (deviceId == device_ID_1) // Device ID of first device { Serial.print("Turn off Device ID: "); Serial.println(deviceId); digitalWrite(RELAY1_PIN, HIGH); } if (deviceId == device_ID_2) // Device ID of second device { Serial.print("Turn off Device ID: "); Serial.println(deviceId); digitalWrite(RELAY2_PIN, HIGH); } if (deviceId == device_ID_3) // Device ID of third device { Serial.print("Turn off Device ID: "); Serial.println(deviceId); digitalWrite(RELAY3_PIN, HIGH); } if (deviceId == device_ID_4) // Device ID of fourth device { Serial.print("Turn off Device ID: "); Serial.println(deviceId); digitalWrite(RELAY4_PIN, HIGH); }

}

void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { switch (type) { case WStype_DISCONNECTED: isConnected = false; WiFiMulti.addAP(MySSID, MyWifiPassword); Serial.printf("[WSc] Webservice disconnected from sinric.com!\n"); break; case WStype_CONNECTED: { isConnected = true; Serial.printf("[WSc] Service connected to sinric.com at url: %s\n", payload); Serial.printf("Waiting for commands from sinric.com ...\n"); } break; case WStype_TEXT: { Serial.printf("[WSc] get text: %s\n", payload); // Example payloads

    // For Switch or Light device types
    // {"deviceId": xxxx, "action": "setPowerState", value: "ON"} // https://developer.amazon.com/docs/device-apis/alexa-powercontroller.html

    // For Light device type
    // Look at the light example in github

if ARDUINOJSON_VERSION_MAJOR == 5

    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.parseObject((char*)payload);

endif

if ARDUINOJSON_VERSION_MAJOR == 6

    DynamicJsonDocument json(1024);
    deserializeJson(json, (char*) payload);

endif

    String deviceId = json ["deviceId"];
    String action = json ["action"];

    if (action == "setPowerState") 
    { // Switch or Light
      String value = json ["value"];
      if (value == "ON") {
        turnOn(deviceId);
      } else {
        turnOff(deviceId);
      }
    }
    else if (action == "test") {
      Serial.println("[WSc] received test command from sinric.com");
    }
  }
  break;
case WStype_BIN:
  Serial.printf("[WSc] get binary length: %u\n", length);
  break;

} }

void setup() { Serial.begin(9600);

WiFiMulti.addAP(MySSID, MyWifiPassword); Serial.println(); Serial.print("Connecting to Wifi: "); Serial.println(MySSID);

// Waiting for Wifi connect if (WiFiMulti.run() != WL_CONNECTED) { delay(500); Serial.print("Connecting..."); } if (WiFiMulti.run() == WL_CONNECTED) { Serial.println(""); Serial.print("WiFi connected. "); Serial.print("IP address: "); Serial.println(WiFi.localIP()); }

// Setup button // Button uses the built-in pull up resistor // INPUT_PULLUP so no need a 10K resistor pinMode(BUTTON1_PIN, INPUT_PULLUP); pinMode(BUTTON2_PIN, INPUT_PULLUP); pinMode(BUTTON3_PIN, INPUT_PULLUP); pinMode(BUTTON4_PIN, INPUT_PULLUP);

pinMode(RELAY1_PIN, OUTPUT); pinMode(RELAY2_PIN, OUTPUT); pinMode(RELAY3_PIN, OUTPUT); pinMode(RELAY4_PIN, OUTPUT);

pinMode(LED1, OUTPUT); pinMode(LED2, OUTPUT); pinMode(LED3, OUTPUT);

digitalWrite(LED1, LOW); delay(200); digitalWrite(LED2, LOW); delay(200); digitalWrite(LED3, LOW); delay(200);

digitalWrite(LED1, HIGH); digitalWrite(LED2, HIGH); digitalWrite(LED3, HIGH); delay(500);

digitalWrite(LED1, LOW); delay(200); digitalWrite(LED2, LOW); delay(200); digitalWrite(LED3, LOW); delay(200);

digitalWrite(LED1, HIGH); digitalWrite(LED2, HIGH); digitalWrite(LED3, HIGH);

config1.setEventHandler(button1Handler); config2.setEventHandler(button2Handler); config3.setEventHandler(button3Handler); config4.setEventHandler(button4Handler);

button1.init(BUTTON1_PIN); button2.init(BUTTON2_PIN); button3.init(BUTTON3_PIN); button4.init(BUTTON4_PIN);

// server address, port and URL webSocket.begin("iot.sinric.com", 80, "/");

// event handler webSocket.onEvent(webSocketEvent); webSocket.setAuthorization("apikey", MyApiKey);

// try again every 5000ms if connection has failed webSocket.setReconnectInterval(5000); // If you see 'class WebSocketsClient' has no member named 'setReconnectInterval' error update arduinoWebSockets }

void loop() {

if (WiFiMulti.run() != WL_CONNECTED) { Serial.println("Not Connected"); digitalWrite(LED1, LOW); digitalWrite(LED2, HIGH); digitalWrite(LED3, HIGH); } else { Serial.println(" Connected"); digitalWrite(LED1, LOW); digitalWrite(LED2, LOW); digitalWrite(LED3, LOW); webSocket.loop(); }

button1.check(); button2.check(); button3.check(); button4.check();

if (isConnected) { uint64_t now = millis();

// Send heartbeat in order to avoid disconnections during ISP resetting IPs over night. Thanks @MacSass
if ((now - heartbeatTimestamp) > HEARTBEAT_INTERVAL) {
  heartbeatTimestamp = now;
  webSocket.sendTXT("H");
}

} }

void setPowerStateOnServer(String deviceId, String value) {

if ARDUINOJSON_VERSION_MAJOR == 5

DynamicJsonBuffer jsonBuffer; JsonObject& root = jsonBuffer.createObject();

endif

if ARDUINOJSON_VERSION_MAJOR == 6

DynamicJsonDocument root(1024);

endif

root["deviceId"] = deviceId; root["action"] = "setPowerState"; root["value"] = value; StreamString databuf;

if ARDUINOJSON_VERSION_MAJOR == 5

root.printTo(databuf);

endif

if ARDUINOJSON_VERSION_MAJOR == 6

serializeJson(root, databuf);

endif

webSocket.sendTXT(databuf); }

void button1Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) { Serial.println("EVENT1"); switch (eventType) { case AceButton::kEventPressed: Serial.println("kEventPressed"); setPowerStateOnServer(device_ID_1, "ON"); digitalWrite(RELAY1_PIN, LOW); break; case AceButton::kEventReleased: Serial.println("kEventReleased"); setPowerStateOnServer(device_ID_1, "OFF"); digitalWrite(RELAY1_PIN, HIGH); break; } }

void button2Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) { Serial.println("EVENT2"); switch (eventType) { case AceButton::kEventPressed: Serial.println("kEventPressed"); setPowerStateOnServer(device_ID_2, "ON"); digitalWrite(RELAY2_PIN, LOW); break; case AceButton::kEventReleased: Serial.println("kEventReleased"); setPowerStateOnServer(device_ID_2, "OFF"); digitalWrite(RELAY2_PIN, HIGH); break; } }

void button3Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) { Serial.println("EVENT3"); switch (eventType) { case AceButton::kEventPressed: Serial.println("kEventPressed"); setPowerStateOnServer(device_ID_3, "ON"); digitalWrite(RELAY3_PIN, LOW); break; case AceButton::kEventReleased: Serial.println("kEventReleased"); setPowerStateOnServer(device_ID_3, "OFF"); digitalWrite(RELAY3_PIN, HIGH); break; } }

void button4Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) { Serial.println("EVENT4"); switch (eventType) { case AceButton::kEventPressed: Serial.println("kEventPressed"); setPowerStateOnServer(device_ID_4, "ON"); digitalWrite(RELAY4_PIN, LOW); break; case AceButton::kEventReleased: Serial.println("kEventReleased"); setPowerStateOnServer(device_ID_4, "OFF"); digitalWrite(RELAY4_PIN, HIGH); break; } }

sivar2311 commented 3 years ago

I think you have 2 basic options here:

1) use EEPROM (needs to be implemented by you): You can store the state in eeprom on each state-change. Then in setup() you can read the last known state from eeprom.

2) Switch over to SinricPro Make use of SinricPro.restoreDeviceStates(true) functionality

ajarsco commented 3 years ago

sir, can we use SPIFFS. but I don't know how to use this. can you please show an example used with Sinric

sivar2311 commented 3 years ago

Short answer: Yes, but... SPIFFS is depracted. If you want to use a file-system for this (little task) you should use LittleFS.

Long answer: Yes but... SPIFFS is depracted. If you want to use a file-system for this (little task) you should use LittleFS. Do you really want to use a complete file-system just for storing 4 Bits of information? (4 Relais = 4x true or false = 4 Bits of information needed)

sivar2311 commented 3 years ago

Examples: click here

You don't need an example for Sinric. It's a general thing, which can be used for many purposes.

ajarsco commented 3 years ago

ok sir, then how do we solve this issue. can you give me a simpler solution for this

sivar2311 commented 3 years ago

Simplest solution is: Switch over to SinricPro. The SDK supports restoring the last known state (server sided). Otherwise, choose one of the other suggestet solutions (EEPROM / FileSystem) which is the easiest for you.

ajarsco commented 3 years ago

what if I use Sinric pro, that's only the server side right? But how it will work there can u please show me a sample code example with Sinric pro, so that I can switch over to that

sivar2311 commented 3 years ago

https://github.com/sinricpro/esp8266-esp32-sdk/tree/master/examples/Switch

ajarsco commented 3 years ago

ok sir let me check

ajarsco commented 3 years ago

sir, will this be ok by the SinricPro.restoreDeviceStates(true) code only

ajarsco commented 3 years ago

without any changes in local storage methods, and using the server only can we get restore the device to normal

sir, will this be ok by the SinricPro.restoreDeviceStates(true) code only

sivar2311 commented 3 years ago

Please see full-documentation about restoreDeviceStates()

What do you mean with "device to normal" ??

When restoreDeviceStates is enabled (true): After connection have been established the server will send the last known states for each device as a normal action. So no additonal code here for you, except this one line: SinricPro.restoreDeviceStates(true)

kakopappa commented 3 years ago

When you call this methods the server will send the last known status in the server to client.

On Tue, 11 Aug 2020 at 7:12 PM Boris Jäger notifications@github.com wrote:

Please see full-documentation https://sinricpro.github.io/esp8266-esp32-sdk/class_sinric_pro_class.html#a27a9bb7f1e8bde0f39398649493b6f93 about restoreDeviceStates()

What do you mean with "device to normal" ??

When restoreDeviceStates is enabled (true): After connection have been established the server will send the last known states for each device as a normal action. So no additonal code here for you, except this one line: SinricPro.restoreDeviceStates(true)

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/kakopappa/sinric/issues/437#issuecomment-671908173, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABZAZZUL7U6XYPESAIGDSNDSAEYRLANCNFSM4P2ZQLJA .

ajarsco commented 3 years ago

ok

ajarsco commented 3 years ago

can you give me code for controlling 4 relays and with eeprom. to store data locally

ajarsco commented 3 years ago

kindly reply sir so that I can do with this for now

ajarsco commented 3 years ago

kindly reply sir so that I can do with this for now

I am a beginner so I am not able to write a code from scratch for eeprom

sivar2311 commented 3 years ago

Everything you need to know is inside the git description, full documentation and the provided examples.

We offer you everything so that you can realize your projects. But the work to realize your projects you have to do yourself.

I am willing to help you, if you have specific question about SinricPro. Start with a simple sketch using sinric pro and the provided simple switch examples. Then add more and more code to your project.

About your Edit while i was writing the lines above: As a beginner: Learning and understanding arduino is the first step. For a beginner i recommend to start with much simpler projects than home automation - regardless which home automation system you're using. Analogy: You have to learn to walk before you can run a marathon.

ajarsco commented 3 years ago

sorry sir, I will do it sir

ajarsco commented 3 years ago

include

include

include

include // https://github.com/kakopappa/sinric/wiki/How-to-add-dependency-libraries

include // https://github.com/kakopappa/sinric/wiki/How-to-add-dependency-libraries

include

include

include // https://github.com/bxparks/AceButton

using namespace ace_button; ESP8266WiFiMulti WiFiMulti; WebSocketsClient webSocket; WiFiClient client;

define MyApiKey "" // TODO: Change to your sinric API Key. Your API Key is displayed on sinric.com dashboard

define MySSID "" // TODO: Change to your Wifi network SSID

define MyWifiPassword "" // TODO: Change to your Wifi network Password

define HEARTBEAT_INTERVAL 300000 // 5 Minutes

//#define DEBOUNCE_DELAY 3000 // 3 seconds

uint64_t heartbeatTimestamp = 0; //uint64_t DelayTimer = 0;

bool isConnected = false;

bool Device1Status = false; bool Device2Status = false; bool Device3Status = false; bool Device4Status = false;

// Switch const int BUTTON1_PIN = 15; const int BUTTON2_PIN = 5; const int BUTTON3_PIN = 4; const int BUTTON4_PIN = 0;

//Relays const int RELAY1_PIN = 2; const int RELAY2_PIN = 14; const int RELAY3_PIN = 12; const int RELAY4_PIN = 13;

//Status LEDs const int LED1 = 16; const int LED2 = 3; const int LED3 = 1;

String device_ID_1 = ""; String device_ID_2 = ""; String device_ID_3 = ""; String device_ID_4 = "";

ButtonConfig config1; AceButton button1(&config1); ButtonConfig config2; AceButton button2(&config2); ButtonConfig config3; AceButton button3(&config3); ButtonConfig config4; AceButton button4(&config4);

void handleEvent1(AceButton, uint8_t, uint8_t); void handleEvent2(AceButton, uint8_t, uint8_t); void handleEvent3(AceButton, uint8_t, uint8_t); void handleEvent4(AceButton, uint8_t, uint8_t);

void setPowerStateOnServer(String deviceId, String value);

// deviceId is the ID assgined to your smart-home-device in sinric.com dashboard. Copy it from dashboard and paste it here

void turnOn(String deviceId) { bool ShouldCommit = true; if (deviceId == device_ID_1) // Device ID of first device { Serial.print("Turn on device id: "); Serial.println(deviceId); digitalWrite(RELAY1_PIN, LOW); Device1Status = true; EEPROM.write(0,1); //(address, value) } if (deviceId == device_ID_2) // Device ID of second device { Serial.print("Turn on device id: "); Serial.println(deviceId); digitalWrite(RELAY2_PIN, LOW); Device2Status = true; EEPROM.write(1,1); //(address, value) } if (deviceId == device_ID_3) // Device ID of third device { Serial.print("Turn on device id: "); Serial.println(deviceId); digitalWrite(RELAY3_PIN, LOW); Device3Status = true; EEPROM.write(2,1); //(address, value) } if (deviceId == device_ID_4) // Device ID of fourth device { Serial.print("Turn on device id: "); Serial.println(deviceId); digitalWrite(RELAY4_PIN, LOW); Device4Status = true; EEPROM.write(3,1); //(address, value) } else { Serial.print("Turn on for unknown device id: "); Serial.println(deviceId); ShouldCommit = false;
} if (ShouldCommit) EEPROM.commit();

}

void turnOff(String deviceId) { bool ShouldCommit = true; if (deviceId == device_ID_1) // Device ID of first device { Serial.print("Turn off Device ID: "); Serial.println(deviceId); digitalWrite(RELAY1_PIN, HIGH); Device1Status = false; EEPROM.write(0,0); } if (deviceId == device_ID_2) // Device ID of second device { Serial.print("Turn off Device ID: "); Serial.println(deviceId); digitalWrite(RELAY2_PIN, HIGH); Device2Status = false; EEPROM.write(1,0); } if (deviceId == device_ID_3) // Device ID of third device { Serial.print("Turn off Device ID: "); Serial.println(deviceId); digitalWrite(RELAY3_PIN, HIGH); Device3Status = false; EEPROM.write(2,0); } if (deviceId == device_ID_4) // Device ID of fourth device { Serial.print("Turn off Device ID: "); Serial.println(deviceId); digitalWrite(RELAY4_PIN, HIGH); Device4Status = false; EEPROM.write(3,0); } else { Serial.print("Turn off for unknown device id: "); Serial.println(deviceId); ShouldCommit = false;
} if (ShouldCommit) EEPROM.commit();

}

void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { switch (type) { case WStype_DISCONNECTED: isConnected = false; WiFiMulti.addAP(MySSID, MyWifiPassword); Serial.printf("[WSc] Webservice disconnected from sinric.com!\n"); break; case WStype_CONNECTED: { isConnected = true; Serial.printf("[WSc] Service connected to sinric.com at url: %s\n", payload); Serial.printf("Waiting for commands from sinric.com ...\n"); } break; case WStype_TEXT: { Serial.printf("[WSc] get text: %s\n", payload); // Example payloads

    // For Switch or Light device types
    // {"deviceId": xxxx, "action": "setPowerState", value: "ON"} // https://developer.amazon.com/docs/device-apis/alexa-powercontroller.html

    // For Light device type
    // Look at the light example in github

if ARDUINOJSON_VERSION_MAJOR == 5

    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.parseObject((char*)payload);

endif

if ARDUINOJSON_VERSION_MAJOR == 6

    DynamicJsonDocument json(1024);
    deserializeJson(json, (char*) payload);

endif

    String deviceId = json ["deviceId"];
    String action = json ["action"];

    if (action == "setPowerState") { // Switch or Light
      String value = json ["value"];
      if (value == "ON") {
        turnOn(deviceId);
      } else {
        turnOff(deviceId);
      }
    }
    else if (action == "test") {
      Serial.println("[WSc] received test command from sinric.com");
    }
  }
  break;
case WStype_BIN:
  Serial.printf("[WSc] get binary length: %u\n", length);
  break;

} }

void setup() { Serial.begin(115200); EEPROM.begin(4);

WiFiMulti.addAP(MySSID, MyWifiPassword); Serial.println(); Serial.print("Connecting to Wifi: "); Serial.println(MySSID);

// Waiting for Wifi connect if (WiFiMulti.run() != WL_CONNECTED) { delay(500); Serial.print("Connecting..."); } if (WiFiMulti.run() == WL_CONNECTED) { Serial.println(""); Serial.print("WiFi connected. "); Serial.print("IP address: "); Serial.println(WiFi.localIP()); }

// Setup button // Button uses the built-in pull up resistor // INPUT_PULLUP so no need a 10K resistor pinMode(BUTTON1_PIN, INPUT_PULLUP); pinMode(BUTTON2_PIN, INPUT_PULLUP); pinMode(BUTTON3_PIN, INPUT_PULLUP); pinMode(BUTTON4_PIN, INPUT_PULLUP);

pinMode(RELAY1_PIN, OUTPUT); pinMode(RELAY2_PIN, OUTPUT); pinMode(RELAY3_PIN, OUTPUT); pinMode(RELAY4_PIN, OUTPUT);

pinMode(LED1, OUTPUT); pinMode(LED2, OUTPUT); pinMode(LED3, OUTPUT);

//Initial Value if (EEPROM.read(0) == 0) digitalWrite (RELAY1_PIN,HIGH); else digitalWrite (RELAY1_PIN,LOW);

if (EEPROM.read(1) == 0) digitalWrite (RELAY2_PIN,HIGH); else digitalWrite (RELAY2_PIN,LOW);

if (EEPROM.read(2) == 0) digitalWrite (RELAY3_PIN,HIGH); else digitalWrite (RELAY3_PIN,LOW);

if (EEPROM.read(3) == 0) digitalWrite (RELAY4_PIN,HIGH); else digitalWrite (RELAY4_PIN,LOW);

// Wait 30 sec for router to stabilise after power restoration //for(int i=0; i<30; i++) // delay(1000);

digitalWrite(LED1, HIGH); delay(200); digitalWrite(LED2, HIGH); delay(200); digitalWrite(LED3, HIGH); delay(200);

digitalWrite(LED1, LOW); digitalWrite(LED2, LOW); digitalWrite(LED3, LOW); delay(500);

digitalWrite(LED1, HIGH); delay(200); digitalWrite(LED2, HIGH); delay(200); digitalWrite(LED3, HIGH); delay(200);

digitalWrite(LED1, LOW); digitalWrite(LED2, LOW); digitalWrite(LED3, LOW);

config1.setEventHandler(button1Handler); config2.setEventHandler(button2Handler); config3.setEventHandler(button3Handler); config4.setEventHandler(button4Handler);

button1.init(BUTTON1_PIN); button2.init(BUTTON2_PIN); button3.init(BUTTON3_PIN); button4.init(BUTTON4_PIN);

// server address, port and URL webSocket.begin("iot.sinric.com", 80, "/");

// event handler webSocket.onEvent(webSocketEvent); webSocket.setAuthorization("apikey", MyApiKey);

// try again every 5000ms if connection has failed webSocket.setReconnectInterval(5000); // If you see 'class WebSocketsClient' has no member named 'setReconnectInterval' error update arduinoWebSockets }

void loop() {

if (WiFiMulti.run() != WL_CONNECTED) { Serial.println("Not Connected"); digitalWrite(LED1, HIGH); digitalWrite(LED2, LOW); digitalWrite(LED3, LOW); } else { Serial.println(" Connected"); digitalWrite(LED1, HIGH); digitalWrite(LED2, HIGH); digitalWrite(LED3, HIGH); webSocket.loop(); }

button1.check(); button2.check(); button3.check(); button4.check();

if (isConnected) { uint64_t now = millis();

// Send heartbeat in order to avoid disconnections during ISP resetting IPs over night. Thanks @MacSass
if ((now - heartbeatTimestamp) > HEARTBEAT_INTERVAL) {
  heartbeatTimestamp = now;
  webSocket.sendTXT("H");
}

} }

void setPowerStateOnServer(String deviceId, String value) {

if ARDUINOJSON_VERSION_MAJOR == 5

DynamicJsonBuffer jsonBuffer; JsonObject& root = jsonBuffer.createObject();

endif

if ARDUINOJSON_VERSION_MAJOR == 6

DynamicJsonDocument root(1024);

endif

root["deviceId"] = deviceId; root["action"] = "setPowerState"; root["value"] = value; StreamString databuf;

if ARDUINOJSON_VERSION_MAJOR == 5

root.printTo(databuf);

endif

if ARDUINOJSON_VERSION_MAJOR == 6

serializeJson(root, databuf);

endif

webSocket.sendTXT(databuf); }

void button1Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) { Serial.println("EVENT1"); switch (eventType) { case AceButton::kEventPressed: Serial.println("kEventPressed"); setPowerStateOnServer(device_ID_1, "ON"); digitalWrite(RELAY1_PIN, LOW); EEPROM.write(0, 1); break; case AceButton::kEventReleased: Serial.println("kEventReleased"); setPowerStateOnServer(device_ID_1, "OFF"); digitalWrite(RELAY1_PIN, HIGH); EEPROM.write(0, 0); break; EEPROM.commit(); }

}

void button2Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) { Serial.println("EVENT2"); switch (eventType) { case AceButton::kEventPressed: Serial.println("kEventPressed"); setPowerStateOnServer(device_ID_2, "ON"); digitalWrite(RELAY2_PIN, LOW); EEPROM.write(1, 1); break; case AceButton::kEventReleased: Serial.println("kEventReleased"); setPowerStateOnServer(device_ID_2, "OFF"); digitalWrite(RELAY2_PIN, HIGH); EEPROM.write(1, 0); break; EEPROM.commit(); }

}

void button3Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) { Serial.println("EVENT3"); switch (eventType) { case AceButton::kEventPressed: Serial.println("kEventPressed"); setPowerStateOnServer(device_ID_3, "ON"); digitalWrite(RELAY3_PIN, LOW); EEPROM.write(2, 1); break; case AceButton::kEventReleased: Serial.println("kEventReleased"); setPowerStateOnServer(device_ID_3, "OFF"); digitalWrite(RELAY3_PIN, HIGH); EEPROM.write(2, 0); break; EEPROM.commit(); }

}

void button4Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) { Serial.println("EVENT4"); switch (eventType) { case AceButton::kEventPressed: Serial.println("kEventPressed"); setPowerStateOnServer(device_ID_4, "ON"); digitalWrite(RELAY4_PIN, LOW); EEPROM.write(3, 1); break; case AceButton::kEventReleased: Serial.println("kEventReleased"); setPowerStateOnServer(device_ID_4, "OFF"); digitalWrite(RELAY4_PIN, HIGH); EEPROM.write(3, 0); break; EEPROM.commit(); }

}

ajarsco commented 3 years ago

SIR please help, the old state is stored and working only for relay 2 but not happening for others

ajarsco commented 3 years ago

please help me sir

sivar2311 commented 3 years ago

What i would do is, adding some additional Serial.print statements for locating the issue (to check what happened and did it work like you have expected).

Example: In front of each EEPROM write, print it to the serial what you writing to the EEPROM. After each EEPROM write, read the value from the EEPROM and print it to the serial. Then do a test, watch the serial monitor.

Doing this way, you will find the issue by yourself.

Btw: Your code is hard to read. Use the "insert code" functionality or better, upload your code to gist and post a link here.

Edit: And congratulations about implementing the use of EEPROM by yourself!

ajarsco commented 3 years ago

`

include

include

include

include

include // https://github.com/kakopappa/sinric/wiki/How-to-add-dependency-libraries

include // https://github.com/kakopappa/sinric/wiki/How-to-add-dependency-libraries

include

include // https://github.com/bxparks/AceButton

using namespace ace_button; ESP8266WiFiMulti WiFiMulti; WebSocketsClient webSocket; WiFiClient client;

define MyApiKey "" // TODO: Change to your sinric API Key. Your API Key is displayed on sinric.com dashboard

define MySSID "" // TODO: Change to your Wifi network SSID

define MyWifiPassword "" // TODO: Change to your Wifi network Password

define HEARTBEAT_INTERVAL 300000 // 5 Minutes

uint64_t heartbeatTimestamp = 0; bool isConnected = false;

// Switch const int BUTTON1_PIN = 15; const int BUTTON2_PIN = 5; const int BUTTON3_PIN = 4; const int BUTTON4_PIN = 0;

//Relays const int RELAY1_PIN = 2; const int RELAY2_PIN = 14; const int RELAY3_PIN = 12; const int RELAY4_PIN = 13;

//Status LEDs const int LED1 = 16; const int LED2 = 3; const int LED3 = 1;

String device_ID_1 = ""; String device_ID_2 = ""; String device_ID_3 = ""; String device_ID_4 = "";

ButtonConfig config1; AceButton button1(&config1); ButtonConfig config2; AceButton button2(&config2); ButtonConfig config3; AceButton button3(&config3); ButtonConfig config4; AceButton button4(&config4);

void handleEvent1(AceButton, uint8_t, uint8_t); void handleEvent2(AceButton, uint8_t, uint8_t); void handleEvent3(AceButton, uint8_t, uint8_t); void handleEvent4(AceButton, uint8_t, uint8_t);

void setPowerStateOnServer(String deviceId, String value);

// deviceId is the ID assgined to your smart-home-device in sinric.com dashboard. Copy it from dashboard and paste it here

void turnOn(String deviceId) { bool ShouldCommit = true;

if (deviceId == device_ID_1) // Device ID of first device { Serial.print("Turn on device id: 1"); Serial.println(deviceId); digitalWrite(RELAY1_PIN, LOW); EEPROM.write(1,1); //(address, value) } if (deviceId == device_ID_2) // Device ID of second device { Serial.print("Turn on device id: 2"); Serial.println(deviceId); digitalWrite(RELAY2_PIN, LOW); EEPROM.write(2,1); //(address, value) } if (deviceId == device_ID_3) // Device ID of third device { Serial.print("Turn on device id: 3 "); Serial.println(deviceId); digitalWrite(RELAY3_PIN, LOW); EEPROM.write(3,1); //(address, value) } if (deviceId == device_ID_4) // Device ID of fourth device { Serial.print("Turn on device id: 4"); Serial.println(deviceId); digitalWrite(RELAY4_PIN, LOW); EEPROM.write(4,1); //(address, value) } else { Serial.print("Turn on for unknown device id: "); Serial.println(deviceId); ShouldCommit = false; } if (ShouldCommit) EEPROM.commit(); }

void turnOff(String deviceId) { bool ShouldCommit = true; if (deviceId == device_ID_1) // Device ID of first device { Serial.print("Turn off Device ID: "); Serial.println(deviceId); digitalWrite(RELAY1_PIN, HIGH); EEPROM.write(1,0); //(address, value) } if (deviceId == device_ID_2) // Device ID of second device { Serial.print("Turn off Device ID: "); Serial.println(deviceId); digitalWrite(RELAY2_PIN, HIGH); EEPROM.write(2,0); //(address, value) } if (deviceId == device_ID_3) // Device ID of third device { Serial.print("Turn off Device ID: "); Serial.println(deviceId); digitalWrite(RELAY3_PIN, HIGH); EEPROM.write(3,0); //(address, value) } if (deviceId == device_ID_4) // Device ID of fourth device { Serial.print("Turn off Device ID: "); Serial.println(deviceId); digitalWrite(RELAY4_PIN, HIGH); EEPROM.write(4,0); //(address, value) } else { Serial.print("Turn off for unknown device id: "); Serial.println(deviceId); ShouldCommit = false; } if (ShouldCommit) EEPROM.commit(); }

void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { switch (type) { case WStype_DISCONNECTED: isConnected = false; WiFiMulti.addAP(MySSID, MyWifiPassword); Serial.printf("[WSc] Webservice disconnected from sinric.com!\n"); break; case WStype_CONNECTED: { isConnected = true; Serial.printf("[WSc] Service connected to sinric.com at url: %s\n", payload); Serial.printf("Waiting for commands from sinric.com ...\n"); } break; case WStype_TEXT: { Serial.printf("[WSc] get text: %s\n", payload); // Example payloads

    // For Switch or Light device types
    // {"deviceId": xxxx, "action": "setPowerState", value: "ON"} // https://developer.amazon.com/docs/device-apis/alexa-powercontroller.html

    // For Light device type
    // Look at the light example in github

if ARDUINOJSON_VERSION_MAJOR == 5

    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.parseObject((char*)payload);

endif

if ARDUINOJSON_VERSION_MAJOR == 6

    DynamicJsonDocument json(1024);
    deserializeJson(json, (char*) payload);

endif

    String deviceId = json ["deviceId"];
    String action = json ["action"];

    if (action == "setPowerState") 
    { // Switch or Light
      String value = json ["value"];
      if (value == "ON") {
        turnOn(deviceId);
      } else {
        turnOff(deviceId);
      }
    }
    else if (action == "test") {
      Serial.println("[WSc] received test command from sinric.com");
    }
  }
  break;
case WStype_BIN:
  Serial.printf("[WSc] get binary length: %u\n", length);
  break;

} }

void setup() { Serial.begin(115200); EEPROM.begin(512); pinMode (RELAY1_PIN, OUTPUT); pinMode (RELAY2_PIN, OUTPUT); pinMode (RELAY3_PIN, OUTPUT); pinMode (RELAY4_PIN, OUTPUT);

if (EEPROM.read(1) == 0) digitalWrite (RELAY1_PIN,HIGH); else digitalWrite (RELAY1_PIN,LOW);

if (EEPROM.read(2) == 0) digitalWrite (RELAY2_PIN,HIGH); else digitalWrite (RELAY2_PIN,LOW); if (EEPROM.read(3) == 0) digitalWrite (RELAY3_PIN,HIGH); else digitalWrite (RELAY3_PIN,LOW); if (EEPROM.read(4) == 0) digitalWrite (RELAY4_PIN,HIGH); else digitalWrite (RELAY4_PIN,LOW);

WiFiMulti.addAP(MySSID, MyWifiPassword); Serial.println(); Serial.print("Connecting to Wifi: "); Serial.println(MySSID);

// Waiting for Wifi connect if (WiFiMulti.run() != WL_CONNECTED) { delay(500); Serial.print("Connecting..."); } if (WiFiMulti.run() == WL_CONNECTED) { Serial.println(""); Serial.print("WiFi connected. "); Serial.print("IP address: "); Serial.println(WiFi.localIP()); }

// Setup button // Button uses the built-in pull up resistor // INPUT_PULLUP so no need a 10K resistor pinMode(BUTTON1_PIN, INPUT_PULLUP); pinMode(BUTTON2_PIN, INPUT_PULLUP); pinMode(BUTTON3_PIN, INPUT_PULLUP); pinMode(BUTTON4_PIN, INPUT_PULLUP);

/pinMode(RELAY1_PIN, OUTPUT); pinMode(RELAY2_PIN, OUTPUT); pinMode(RELAY3_PIN, OUTPUT); pinMode(RELAY4_PIN, OUTPUT);/

pinMode(LED1, OUTPUT); pinMode(LED2, OUTPUT); pinMode(LED3, OUTPUT);

digitalWrite(LED1, HIGH); delay(200); digitalWrite(LED2, HIGH); delay(200); digitalWrite(LED3, HIGH); delay(200);

digitalWrite(LED1, LOW); digitalWrite(LED2, LOW); digitalWrite(LED3, LOW); delay(500);

digitalWrite(LED1, HIGH); delay(200); digitalWrite(LED2, HIGH); delay(200); digitalWrite(LED3, HIGH); delay(200);

digitalWrite(LED1, LOW); digitalWrite(LED2, LOW); digitalWrite(LED3, LOW);

config1.setEventHandler(button1Handler); config2.setEventHandler(button2Handler); config3.setEventHandler(button3Handler); config4.setEventHandler(button4Handler);

button1.init(BUTTON1_PIN); button2.init(BUTTON2_PIN); button3.init(BUTTON3_PIN); button4.init(BUTTON4_PIN);

// server address, port and URL webSocket.begin("iot.sinric.com", 80, "/");

// event handler webSocket.onEvent(webSocketEvent); webSocket.setAuthorization("apikey", MyApiKey);

// try again every 5000ms if connection has failed webSocket.setReconnectInterval(5000); // If you see 'class WebSocketsClient' has no member named 'setReconnectInterval' error update arduinoWebSockets }

void loop() {

if (WiFiMulti.run() != WL_CONNECTED) { Serial.println("Not Connected"); digitalWrite(LED1, HIGH); digitalWrite(LED2, LOW); digitalWrite(LED3, LOW); } else { Serial.println(" Connected"); digitalWrite(LED1, HIGH); digitalWrite(LED2, HIGH); digitalWrite(LED3, HIGH); webSocket.loop(); }

button1.check(); button2.check(); button3.check(); button4.check();

if (isConnected) { uint64_t now = millis();

// Send heartbeat in order to avoid disconnections during ISP resetting IPs over night. Thanks @MacSass
if ((now - heartbeatTimestamp) > HEARTBEAT_INTERVAL) {
  heartbeatTimestamp = now;
  webSocket.sendTXT("H");
}

} }

void setPowerStateOnServer(String deviceId, String value) {

if ARDUINOJSON_VERSION_MAJOR == 5

DynamicJsonBuffer jsonBuffer; JsonObject& root = jsonBuffer.createObject();

endif

if ARDUINOJSON_VERSION_MAJOR == 6

DynamicJsonDocument root(1024);

endif

root["deviceId"] = deviceId; root["action"] = "setPowerState"; root["value"] = value; StreamString databuf;

if ARDUINOJSON_VERSION_MAJOR == 5

root.printTo(databuf);

endif

if ARDUINOJSON_VERSION_MAJOR == 6

serializeJson(root, databuf);

endif

webSocket.sendTXT(databuf); }

void button1Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) { Serial.println("EVENT1"); switch (eventType) { case AceButton::kEventPressed: Serial.println("kEventPressed"); setPowerStateOnServer(device_ID_1, "ON"); digitalWrite(RELAY1_PIN, LOW); break; case AceButton::kEventReleased: Serial.println("kEventReleased"); setPowerStateOnServer(device_ID_1, "OFF"); digitalWrite(RELAY1_PIN, HIGH); break; } }

void button2Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) { Serial.println("EVENT2"); switch (eventType) { case AceButton::kEventPressed: Serial.println("kEventPressed"); setPowerStateOnServer(device_ID_2, "ON"); digitalWrite(RELAY2_PIN, LOW); break; case AceButton::kEventReleased: Serial.println("kEventReleased"); setPowerStateOnServer(device_ID_2, "OFF"); digitalWrite(RELAY2_PIN, HIGH); break; } }

void button3Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) { Serial.println("EVENT3"); switch (eventType) { case AceButton::kEventPressed: Serial.println("kEventPressed"); setPowerStateOnServer(device_ID_3, "ON"); digitalWrite(RELAY3_PIN, LOW); break; case AceButton::kEventReleased: Serial.println("kEventReleased"); setPowerStateOnServer(device_ID_3, "OFF"); digitalWrite(RELAY3_PIN, HIGH); break; } }

void button4Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) { Serial.println("EVENT4"); switch (eventType) { case AceButton::kEventPressed: Serial.println("kEventPressed"); setPowerStateOnServer(device_ID_4, "ON"); digitalWrite(RELAY4_PIN, LOW); break; case AceButton::kEventReleased: Serial.println("kEventReleased"); setPowerStateOnServer(device_ID_4, "OFF"); digitalWrite(RELAY4_PIN, HIGH); break; } }`

ajarsco commented 3 years ago

thank you sir, kindly check this code that I have added in insert code method for your better understanding. hope you will find this easier. For certain relays the eeprom works fine and for others It doesn't. also, I think this not at all a reliable one. frequent power outages cannot handle this

sivar2311 commented 3 years ago

Seems it didn't work. Code looks still the same. You didn't add anything to debug (as i mentioned before) ? Just looking at the code won't help here. You have to debug as i have described here

Edit: Add a check for EEPROM.commit and print it to serial log like here

sivar2311 commented 3 years ago

I did a small EEPROM test here You can use it to check if your EEPROM works correctly. The sketch initializes the EEPROM at first run. Then EEPROM address 1..5 will be incremented at each boot up (to a maximum of 19...then roll over)

ajarsco commented 3 years ago

ok sir let me check this and debug it, and I will let you know

sivar2311 commented 3 years ago

Any news here?

ajarsco commented 3 years ago

yes sir I am in an emergency now, I will do it faster

sivar2311 commented 3 years ago

It's okay. I only ask because you seemed to be in a hurry and now there's no answer. But take your time. Emergencies come first!

ajarsco commented 3 years ago

yes sir I will do it soon

ajarsco commented 3 years ago

everything working fine now! but there is issues in reconnecting to the wifi in between..?

I have already used WiFi.setAutoReconnect(true)

why this is happening like this... this issue will remain same if we use sinric.pro also!!

Kindly help me in correcting if I have done any mistakes.

sivar2311 commented 3 years ago

Could be related to weak wifi connection. You can log the WiFi-signal strength to serial monitor:

void logWiFiRSSI() {
  static unsigned long lastMillis = 0;
  unsigned long currentMillis = millis();
  if (currentMillis - lastMillis > 1000) {
    lastMillis = currentMillis;
    Serial.printf("WiFi Signal Strength: %d\r\n", WiFi.RSSI());
  }
}
...
void loop() {
...
  logWiFiRSSI();
...
}

This will print the signal strength once a second. Value should be less than -70 dBm (Values between -30 and -70 are ok, less than -70 wifi strength is not good enough)

ajarsco commented 3 years ago

ok sir, let me check

sivar2311 commented 3 years ago

Got any useful logs?

ajarsco commented 3 years ago

no sir!

ajarsco commented 3 years ago

WiFi have its maximum strength, but also the ESP fails to reconnect after long span connection(around 7-8 hours)