sinricpro / esp8266-esp32-sdk

Library for https://sinric.pro - simple way to connect your device to Alexa, Google Home, SmartThings and cloud
https://sinric.pro
Other
230 stars 124 forks source link

manual switch and sinric pro #117

Closed siddroutray17 closed 3 years ago

siddroutray17 commented 3 years ago

How to program using sinric pro in ESP8266/ESP32 such that manual switches can also be incorporated.... I want to use a mechanical switch( pushbutton) and alexa to control my relay using sinric pro

kakopappa commented 3 years ago

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

On Tue, 22 Dec 2020 at 9:07 PM siddroutray17 notifications@github.com wrote:

How to program using sinric pro in ESP8266/ESP32 such that manual switches can also be incorporated.... I want to use a mechanical switch( pushbutton) and alexa to control my relay using sinric pro

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/sinricpro/esp8266-esp32-sdk/issues/117, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABZAZZTCVDAUWTRA7ECZIJ3SWCR3ZANCNFSM4VFVZSNA .

siddroutray17 commented 3 years ago

Thanks for the above code. It works fine with push button. But how can we program sinric pro using normal mechanical (ON/OFF) switch. I am facing problem with the blinking of lights. With sinric I was able to do with Ace button with kEventPressed function.

kakopappa commented 3 years ago

You can still use Ace button with kEventPressed.

void handleEvent(AceButton* /* button */, uint8_t eventType,
    uint8_t /* buttonState */) {
  switch (eventType) {
    case AceButton::kEventPressed:
      Serial.println("kEventPressed");
       **mySwitch.sendPowerStateEvent(myPowerState); // send the new powerState to SinricPro server**
       break;
    case AceButton::kEventReleased:
      Serial.println("kEventReleased");
      break;
  }
}
siddroutray17 commented 3 years ago

The below mentioned code is not working fine. Can you please figure out if there's any bug in it.

#ifdef ENABLE_DEBUG
       #define DEBUG_ESP_PORT Serial
       #define NODEBUG_WEBSOCKETS
       #define NDEBUG
#endif 

#include <Arduino.h>
#ifdef ESP8266 
       #include <ESP8266WiFi.h>
#endif 
#ifdef ESP32   
       #include <WiFi.h>
#endif

#include "SinricPro.h"
#include "SinricProSwitch.h"
#include <AceButton.h>

using namespace ace_button;

#define WIFI_SSID         "**********"    
#define WIFI_PASS         "***********"
#define APP_KEY           "************************"      // Should look like "de0bxxxx-1x3x-4x3x-ax2x-5dabxxxxxxxx"
#define APP_SECRET        "*************************************************************"   // Should look like "5f36xxxx-x3x7-4x3x-xexe-e86724a9xxxx-4c4axxxx-3x3x-x5xe-x9x3-333d65xxxxxx"

#define SWITCH_ID_1       "*****************************"    // Should look like "5dc1564130xxxxxxxxxxxxxx"
#define SWITCH_ID_2        "*****************************"     // Should look like "5dc1564130xxxxxxxxxxxxxx"
#define SWITCH_ID_3        "*****************************"     // Should look like "5dc1564130xxxxxxxxxxxxxx"

#define BAUD_RATE         9600                // Change baudrate to your need

#define BUTTON1_PIN 13   // GPIO for BUTTON (inverted: LOW = pressed, HIGH = released)
#define BUTTON2_PIN 27
#define BUTTON3_PIN 14

#define LED1   23   // GPIO for LED (inverted)
#define LED2   22
#define LED3   18

#define RELAY1_PIN  15
#define RELAY2_PIN  2
#define RELAY3_PIN  4

bool myPowerState1 = false;
bool myPowerState2 = false;
bool myPowerState3 = false;

//unsigned long lastBtnPress = 0;

AceButton button1(BUTTON1_PIN);
AceButton button2(BUTTON2_PIN);
AceButton button3(BUTTON3_PIN);

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

/* bool onPowerState(String deviceId, bool &state) 
 *
 * Callback for setPowerState request
 * parameters
 *  String deviceId (r)
 *    contains deviceId (useful if this callback used by multiple devices)
 *  bool &state (r/w)
 *    contains the requested state (true:on / false:off)
 *    must return the new state
 * 
 * return
 *  true if request should be marked as handled correctly / false if not
 */
bool onPowerState1(const String &deviceId, bool &state) {
  Serial.printf("Device %s turned %s (via SinricPro) \r\n", deviceId.c_str(), state?"on":"off");
  myPowerState1 = state;
  digitalWrite(RELAY1_PIN, myPowerState1?HIGH:LOW);
  return true; // request handled properly
}

bool onPowerState2(const String &deviceId, bool &state) {
  Serial.printf("Device %s turned %s (via SinricPro) \r\n", deviceId.c_str(), state?"on":"off");
  myPowerState2 = state;
  digitalWrite(RELAY2_PIN, myPowerState2?HIGH:LOW);
  return true; // request handled properly
}

bool onPowerState3(const String &deviceId, bool &state) {
  Serial.printf("Device %s turned %s (via SinricPro) \r\n", deviceId.c_str(), state?"on":"off");
  myPowerState3 = state;
  digitalWrite(RELAY3_PIN, myPowerState3?HIGH:LOW);
  return true; // request handled properly
}

// setup function for WiFi connection
void setupWiFi() {
  Serial.printf("\r\n[Wifi]: Connecting");
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  while (WiFi.status() != WL_CONNECTED) {
    Serial.printf(".");
    delay(250);
  }
  Serial.printf("connected!\r\n[WiFi]: IP-Address is %s\r\n", WiFi.localIP().toString().c_str());
}

// setup function for SinricPro
void setupSinricPro() {
  // add device to SinricPro
  SinricProSwitch& mySwitch1 = SinricPro[SWITCH_ID_1];

  // set callback function to device
  mySwitch1.onPowerState(onPowerState1);

  SinricProSwitch& mySwitch2 = SinricPro[SWITCH_ID_2];
  mySwitch2.onPowerState(onPowerState2);

  SinricProSwitch& mySwitch3 = SinricPro[SWITCH_ID_3];
  mySwitch3.onPowerState(onPowerState3);

  // setup SinricPro
  SinricPro.onConnected([](){ Serial.printf("Connected to SinricPro\r\n"); }); 
  SinricPro.onDisconnected([](){ Serial.printf("Disconnected from SinricPro\r\n"); });
  SinricPro.begin(APP_KEY, APP_SECRET);
}

// main setup function
void setup() {
  pinMode(BUTTON1_PIN, INPUT_PULLUP); // GPIO 0 as input, pulled high
  pinMode(BUTTON2_PIN, INPUT_PULLUP);
  pinMode(BUTTON3_PIN, INPUT_PULLUP);

  pinMode(RELAY1_PIN, OUTPUT);
  pinMode(RELAY2_PIN, OUTPUT);
  pinMode(RELAY3_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);

  button1.init(BUTTON1_PIN);
  button1.setEventHandler(handleEvent1);

  button2.init(BUTTON2_PIN);
  button2.setEventHandler(handleEvent2);

  button3.init(BUTTON3_PIN);
  button3.setEventHandler(handleEvent3);

  //button4.init(BUTTON4_PIN);

  Serial.begin(BAUD_RATE); Serial.printf("\r\n\r\n");
  setupWiFi();
  setupSinricPro();
}

void loop() {

  while(1){
  if (WiFi.status() != 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);

  }

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

  SinricPro.handle();
}
}

void handleEvent1(AceButton*  button1, uint8_t eventType, uint8_t buttonState ) {
  Serial.println("EVENT1");
  switch (eventType) {
    case AceButton::kEventPressed:
      {Serial.println("kEventPressed");
       if (myPowerState1) {     // flip myPowerState: if it was true, set it to false, vice versa
       myPowerState1 = false;
       }  else {
       myPowerState1 = true;
       }
       digitalWrite(RELAY1_PIN, myPowerState1?HIGH:LOW); // if myPowerState indicates device turned on: turn on led (builtin led uses inverted logic: LOW = LED ON / HIGH = LED OFF)

       // get Switch device back
       SinricProSwitch& mySwitch1 = SinricPro[SWITCH_ID_1];
       // send powerstate event
       mySwitch1.sendPowerStateEvent(myPowerState1); // send the new powerState to SinricPro server
       //Serial.printf("Device %s turned %s (manually via flashbutton)\r\n",mySwitch1.getDeviceId().toString().c_str(), myPowerState3?"on":"off");
       break;}
    case AceButton::kEventReleased:
      {Serial.println("kEventReleased");
       if (myPowerState1) {     // flip myPowerState: if it was true, set it to false, vice versa
       myPowerState1 = false;
       }  else {
       myPowerState1 = true;
       }
       digitalWrite(RELAY1_PIN, myPowerState1?LOW:HIGH);
       SinricProSwitch& mySwitch1 = SinricPro[SWITCH_ID_1];
       mySwitch1.sendPowerStateEvent(myPowerState1);
       //mySwitch1.getDeviceId().toString().c_str(), myPowerState1?"off":"on");
       break;
  }
  }
}

void handleEvent2(AceButton*  button, uint8_t eventType, uint8_t buttonState ) {
  Serial.println("EVENT2");
  switch (eventType) {
    case AceButton::kEventPressed:
      {Serial.println("kEventPressed");
       if (myPowerState2) {     // flip myPowerState: if it was true, set it to false, vice versa
       myPowerState2 = false;
       }  else {
       myPowerState2 = true;
       }
       digitalWrite(RELAY2_PIN, myPowerState2?HIGH:LOW); // if myPowerState indicates device turned on: turn on led (builtin led uses inverted logic: LOW = LED ON / HIGH = LED OFF)

       // get Switch device back
       SinricProSwitch& mySwitch2 = SinricPro[SWITCH_ID_2];
       // send powerstate event
       mySwitch2.sendPowerStateEvent(myPowerState2); // send the new powerState to SinricPro server
       //Serial.printf("Device %s turned %s (manually via flashbutton)\r\n", mySwitch2.getDeviceId().toString().c_str(), myPowerState2?"on":"off");
       break;}
    case AceButton::kEventReleased:
      {Serial.println("kEventReleased");
       if (myPowerState2) {     // flip myPowerState: if it was true, set it to false, vice versa
       myPowerState2 = false;
       }  else {
       myPowerState2 = true;
       }
       digitalWrite(RELAY2_PIN, myPowerState2?LOW:HIGH);
       SinricProSwitch& mySwitch2 = SinricPro[SWITCH_ID_2];
       mySwitch2.sendPowerStateEvent(myPowerState2);
       //mySwitch2.getDeviceId().toString().c_str(), myPowerState2?"off":"on");
       break;}
  }
}

void handleEvent3(AceButton*  button, uint8_t eventType, uint8_t buttonState) {
  Serial.println("EVENT3");
  switch (eventType) {
    case AceButton::kEventPressed:
      {Serial.println("kEventPressed");
       if (myPowerState3) {     // flip myPowerState: if it was true, set it to false, vice versa
       myPowerState3 = false;
       }  else {
       myPowerState3 = true;
       }
       digitalWrite(RELAY3_PIN, myPowerState3?HIGH:LOW); // if myPowerState indicates device turned on: turn on led (builtin led uses inverted logic: LOW = LED ON / HIGH = LED OFF)

       // get Switch device back
       SinricProSwitch& mySwitch3 = SinricPro[SWITCH_ID_3];
       // send powerstate event
       mySwitch3.sendPowerStateEvent(myPowerState3); // send the new powerState to SinricPro server
       //Serial.printf("Device %s turned %s (manually via flashbutton)\r\n",mySwitch3.getDeviceId().toString().c_str(), myPowerState3?"on":"off");
       break;}
    case AceButton::kEventReleased:
      {Serial.println("kEventReleased");
       if (myPowerState3) {     // flip myPowerState: if it was true, set it to false, vice versa
       myPowerState3 = false;
       }  else {
       myPowerState3 = true;
       }
       digitalWrite(RELAY3_PIN, myPowerState3?LOW:HIGH);
       SinricProSwitch& mySwitch3 = SinricPro[SWITCH_ID_3];
       mySwitch3.sendPowerStateEvent(myPowerState3);
       //mySwitch3.getDeviceId().toString().c_str(), myPowerState3?"off":"on");

       break;}
  }
}
sivar2311 commented 3 years ago

Hi @siddroutray17!

Please put code into codeblocks, so anyone can read the code cleanly. (I edited your comment). Please give a detailed description. What is the issue??

I have had a rough look at the code.

  1. Please remove the while(1)-loop in the main loop function. This might lead to watchdog reset or other strange behavior.
  2. If you want to print the wifi status, check for a status change, and do only a print when there was a change. Otherwise your Serial monitor will always print "Connected" or "Not Connected"
kakopappa commented 3 years ago

like @sivar2311 said while(1){ } will cause resets unless you call yield()

siddroutray17 commented 3 years ago

Thank you for all your help and guidance. I could successfully figure out the bug and the program is running as per my requirement. Thank you so much again for creating such a beautiful platform.

thermonics commented 2 years ago

hi am working on a home automation system that shows live feedback to sinric pro server through the physical button so after searching I came across your pre-written code. my question is that code is for push-button as toggle switch but I want to attach normal switches which we used in electric board so need push button as push-button not a toggle switch? Hope you'll get what I want to say. this code im using https://github.com/sinricpro/esp8266-esp32-sdk/blob/master/examples/Switch/Switch/Switch.ino

sivar2311 commented 2 years ago

The switch example you mentioned is using push buttons.

The button handling is not part of the sdk.

All you have to do in your manual switch handling function is:

ps.: This issue was closed more than a year ago. I would be grateful if you would open a new issue.