Sinric Pro IOT Automation
/*https://github.com/anokhramesh/SinricProAutomation
circuit diagram -https://drive.google.com/file/d/1vznY-F-vwte55hIPcR9O4M1_2IFw2BtG/view?usp=sharing
https://drive.google.com/file/d/11NEfVZg_silkMByJIQo3Ge5x-ntmNAO3/view?usp=sharing
Download and install the Required Libraries
Download Board ESP8266 NodeMCU : https://github.com/esp8266/Arduino
ArduinoJson Library: https://github.com/bblanchon/ArduinoJson
arduinoWebSockets Library: https://github.com/Links2004/arduinoWebSockets
SinricPro Library: https://sinricpro.github.io/esp8266-esp32-sdk*/
#ifdef ENABLE_DEBUG
#define DEBUG_ESP_PORT Serial
#define NODEBUG_WEBSOCKETS
#define NDEBUG
#endif
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "SinricPro.h"
#include "SinricProSwitch.h"
#include <map>
#define WIFI_SSID "SSID" //Enter your Wifi SSID
#define WIFI_PASS "Password"//Enter your Wifi Password
#define APP_KEY "APP KEY " // Enter the Sinric API KEY"
#define APP_SECRET "APP secret" // Enter the Sinric App secret"
//Enter the device IDs here
#define device_ID_1 "Device ID1"// Enter Sincric Device ID1
#define device_ID_2 "Device ID2"// Enter Sincric Device ID2
#define device_ID_3 "Device ID3"// Enter Sincric Device ID3
#define device_ID_4 "xxxxxxxxxxxxxxxxxxxxxxxx"// Enter Sincric Device ID4
// define the GPIO connected with Relays and switches
#define RelayPin1 5//connect Relay1 to GPIO 5 of NodeMCU(PIN D1)
#define RelayPin2 4 //connect Relay2 to GPIO 4 of NodeMCU(PIN D2)
#define RelayPin3 0 //connect Relay3 to GPIO 0 of NodeMCU(PIN D3)
#define RelayPin4 12 //connect Relay4 to GPIO 12 of NodeMCU(D6)
#define SwitchPin1 2 //connect Push button to GPIO 2 of Node MCU(PIN D4)
#define SwitchPin2 14 //connect Push button to GPIO 14 of Node MCU(PIN D5)
#define SwitchPin3 3 //connect Push button to GPIO 3 of Node MCU(PIN RX)
#define SwitchPin4 13 //connect Push button to GPIO 13 of Node MCU(PIN D7)
#define wifiLed 16 //Builtin blue LED is on GPIO 16 of Node MCU(D0)do not change this pin
// comment the following line if you use a toggle switches instead of tactile buttons
#define TACTILE_BUTTON 1// uncomment this line if using Normaly open Push Button
#define BAUD_RATE 9600// set Baud Rate 9600 on(select also the same baud rate on serial monitor )
#define DEBOUNCE_TIME 250// button debounce time delay 250 milli second
typedef struct { // struct for the std::map below
int relayPIN;
int flipSwitchPIN;
} deviceConfig_t;
// this is the main configuration
// please put in your deviceId, the PIN for Relay and PIN for flipSwitch
// this can be up to N devices...depending on how much pin's available on your device ;)
// right now we have 4 devicesIds going to 4 relays and 4 flip switches to switch the relay manually
std::map<String, deviceConfig_t> devices = {
//{deviceId, {relayPIN, flipSwitchPIN}}
{device_ID_1, { RelayPin1, SwitchPin1 }},
{device_ID_2, { RelayPin2, SwitchPin2 }},
{device_ID_3, { RelayPin3, SwitchPin3 }},
{device_ID_4, { RelayPin4, SwitchPin4 }}
};
typedef struct { // struct for the std::map below
String deviceId;
bool lastFlipSwitchState;
unsigned long lastFlipSwitchChange;
} flipSwitchConfig_t;
std::map<int, flipSwitchConfig_t> flipSwitches; // this map is used to map flipSwitch PINs to deviceId and handling debounce and last flipSwitch state checks
// it will be setup in "setupFlipSwitches" function, using informations from devices map
void setupRelays() {
for (auto &device : devices) { // for each device (relay, flipSwitch combination)
int relayPIN = device.second.relayPIN; // get the relay pin
pinMode(relayPIN, OUTPUT); // set relay pin to OUTPUT
//digitalWrite(relayPIN, HIGH);//at initial keep the relays ON(Low active relay)
digitalWrite(relayPIN, LOW);//at initial keep the relays OFF(High active relay)
}
}
void setupFlipSwitches() {
for (auto &device : devices) { // for each device (relay / flipSwitch combination)
flipSwitchConfig_t flipSwitchConfig; // create a new flipSwitch configuration
flipSwitchConfig.deviceId = device.first; // set the deviceId
flipSwitchConfig.lastFlipSwitchChange = 0; // set debounce time
flipSwitchConfig.lastFlipSwitchState = true; // set lastFlipSwitchState to false (LOW)--
int flipSwitchPIN = device.second.flipSwitchPIN; // get the flipSwitchPIN
flipSwitches[flipSwitchPIN] = flipSwitchConfig; // save the flipSwitch config to flipSwitches map
pinMode(flipSwitchPIN, INPUT_PULLUP); // set the flipSwitch pin to INPUT
}
}
bool onPowerState(String deviceId, bool &state)
{
Serial.printf("%s: %s\r\n", deviceId.c_str(), state ? "on" : "off");
int relayPIN = devices[deviceId].relayPIN; // get the relay pin for corresponding device
//digitalWrite(relayPIN, !state);
digitalWrite(relayPIN, state);// set the new relay state
return true;
}
void handleFlipSwitches() {
unsigned long actualMillis = millis(); // get actual millis
for (auto &flipSwitch : flipSwitches) { // for each flipSwitch in flipSwitches map
unsigned long lastFlipSwitchChange = flipSwitch.second.lastFlipSwitchChange; // get the timestamp when flipSwitch was pressed last time (used to debounce / limit events)
if (actualMillis - lastFlipSwitchChange > DEBOUNCE_TIME) { // if time is > debounce time...
int flipSwitchPIN = flipSwitch.first; // get the flipSwitch pin from configuration
bool lastFlipSwitchState = flipSwitch.second.lastFlipSwitchState; // get the lastFlipSwitchState
bool flipSwitchState = digitalRead(flipSwitchPIN); // read the current flipSwitch state
if (flipSwitchState != lastFlipSwitchState) { // if the flipSwitchState has changed...
#ifdef TACTILE_BUTTON
if (flipSwitchState) { // if the tactile button is pressed
#endif
flipSwitch.second.lastFlipSwitchChange = actualMillis; // update lastFlipSwitchChange time
String deviceId = flipSwitch.second.deviceId; // get the deviceId from config
int relayPIN = devices[deviceId].relayPIN; // get the relayPIN from config
bool newRelayState = !digitalRead(relayPIN); // set the new relay State
digitalWrite(relayPIN, newRelayState); // set the trelay to the new state
SinricProSwitch &mySwitch = SinricPro[deviceId]; // get Switch device from SinricPro
mySwitch.sendPowerStateEvent(!newRelayState); // send the event
#ifdef TACTILE_BUTTON
}
#endif
flipSwitch.second.lastFlipSwitchState = flipSwitchState; // update lastFlipSwitchState
}
}
}
}
void setupWiFi()
{
Serial.printf("\r\n[Wifi]: Connecting");
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED)
{
Serial.printf(".");
delay(250);
}
digitalWrite(wifiLed,HIGH);
Serial.printf("connected!\r\n[WiFi]: IP-Address is %s\r\n", WiFi.localIP().toString().c_str());
}
void setupSinricPro()
{
for (auto &device : devices)
{
const char *deviceId = device.first.c_str();
SinricProSwitch &mySwitch = SinricPro[deviceId];
mySwitch.onPowerState(onPowerState);
}
SinricPro.begin(APP_KEY, APP_SECRET);
SinricPro.restoreDeviceStates(true);
}
void setup()
{
Serial.begin(BAUD_RATE);
pinMode(wifiLed, OUTPUT);
//digitalWrite(wifiLed,HIGH);
setupRelays();
setupFlipSwitches();
setupWiFi();
setupSinricPro();
}
void loop()
{
SinricPro.handle();
handleFlipSwitches();
}
Comments
Post a Comment