//#outline ENABLE_DEBUG
#ifdef ENABLE_DEBUG
#outline DEBUG_ESP_PORT Serial
#outline NODEBUG_WEBSOCKETS
#outline NDEBUG
#endif
#embody <Arduino.h>
#embody <WiFi.h>
#embody “SinricPro.h”
#embody “SinricProSwitch.h”
#embody <map>
#outline WIFI_SSID “YOUR-WIFI-NAME”
#outline WIFI_PASS “YOUR-WIFI-PASSWORD”
#outline APP_KEY “YOUR-APP-KEY” // Ought to look like “de0bxxxx-1x3x-4x3x-ax2x-5dabxxxxxxxx”
#outline APP_SECRET “YOUR-APP-SECRET” // Ought to look like “5f36xxxx-x3x7-4x3x-xexe-e86724a9xxxx-4c4axxxx-3x3x-x5xe-x9x3-333d65xxxxxx”
//Enter the system IDs right here
#outline device_ID_1 “SWITCH_ID_NO_1_HERE”
#outline device_ID_2 “SWITCH_ID_NO_2_HERE”
#outline device_ID_3 “SWITCH_ID_NO_3_HERE”
#outline device_ID_4 “SWITCH_ID_NO_4_HERE”
// outline the GPIO related with Relays and switches
#outline RelayPin1 23 //D23
#outline RelayPin2 22 //D22
#outline RelayPin3 21 //D21
#outline RelayPin4 19 //D19
#outline SwitchPin1 13 //D13
#outline SwitchPin2 12 //D12
#outline SwitchPin3 14 //D14
#outline SwitchPin4 27 //D27
#outline wifiLed 2 //D2
// remark the following line if you use toggle switches as a substitute of tactile buttons
//#outline TACTILE_BUTTON 1
#outline BAUD_RATE 9600
#outline DEBOUNCE_TIME 250
typedef struct { // struct for the std::map beneath
int relayPIN;
int flipSwitchPIN;
} deviceConfig_t;
// this is the primary configuration
// please put in your deviceId, the PIN for Relay and PIN for flipSwitch
// this can be up to N units...relying on how a lot pin‘s accessible on your system ;)
// proper now we have 4 devicesIds going to 4 relays and 4 flip switches to swap the relay manually
std::map<String, deviceConfig_t> units = {
//{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 beneath
String deviceId;
bool lastFlipSwitchState;
unsigned lengthy lastFlipSwitchChange;
} flipSwitchConfig_t;
std::map<int, flipSwitchConfig_t> flipSwitches; // this map is used to map flipSwitch PINs to deviceId and dealing with debounce and final flipSwitch state checks
// it will be setup in “setupFlipSwitches” operate, utilizing informations from units map
void setupRelays() {
for (auto &system : units) { // for every system (relay, flipSwitch mixture)
int relayPIN = system.second.relayPIN; // get the relay pin
pinMode(relayPIN, OUTPUT); // set relay pin to OUTPUT
digitalWrite(relayPIN, HIGH);
}
}
void setupFlipSwitches() {
for (auto &system : units) { // for every system (relay / flipSwitch mixture)
flipSwitchConfig_t flipSwitchConfig; // create a new flipSwitch configuration
flipSwitchConfig.deviceId = system.first; // set the deviceId
flipSwitchConfig.lastFlipSwitchChange = 0; // set debounce time
flipSwitchConfig.lastFlipSwitchState = true; // set lastFlipSwitchState to false (LOW)—
int flipSwitchPIN = system.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: %srn”, deviceId.c_str(), state ? “on” : “off”);
int relayPIN = units[deviceId].relayPIN; // get the relay pin for corresponding system
digitalWrite(relayPIN, !state); // set the new relay state
return true;
}
void handleFlipSwitches() {
unsigned lengthy actualMillis = millis(); // get precise millis
for (auto &flipSwitch : flipSwitches) { // for every flipSwitch in flipSwitches map
unsigned lengthy lastFlipSwitchChange = flipSwitch.second.lastFlipSwitchChange; // get the timestamp when flipSwitch was pressed final time (used to debounce / restrict occasions)
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); // learn the present flipSwitch state
if (flipSwitchState != lastFlipSwitchState) { // if the flipSwitchState has modified...
#ifdef TACTILE_BUTTON
if (flipSwitchState) { // if the tactile button is pressed
#endif
flipSwitch.second.lastFlipSwitchChange = actualMillis; // replace lastFlipSwitchChange time
String deviceId = flipSwitch.second.deviceId; // get the deviceId from config
int relayPIN = units[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 Swap system from SinricPro
mySwitch.sendPowerStateEvent(!newRelayState); // ship the occasion
#ifdef TACTILE_BUTTON
}
#endif
flipSwitch.second.lastFlipSwitchState = flipSwitchState; // replace lastFlipSwitchState
}
}
}
}
void setupWiFi()
{
Serial.printf(“rn[Wifi]: Connecting”);
WiFi.start(WIFI_SSID, WIFI_PASS);
whereas (WiFi.standing() != WL_CONNECTED)
{
Serial.printf(“.”);
delay(250);
}
digitalWrite(wifiLed, HIGH);
Serial.printf(“related!rn[WiFi]: IP-Handle is %srn”, WiFi.localIP().toString().c_str());
}
void setupSinricPro()
{
for (auto &system : units)
{
const char *deviceId = system.first.c_str();
SinricProSwitch &mySwitch = SinricPro[deviceId];
mySwitch.onPowerState(onPowerState);
}
SinricPro.start(APP_KEY, APP_SECRET);
SinricPro.restoreDeviceStates(true);
}
void setup()
{
Serial.start(BAUD_RATE);
pinMode(wifiLed, OUTPUT);
digitalWrite(wifiLed, LOW);
setupRelays();
setupFlipSwitches();
setupWiFi();
setupSinricPro();
}
void loop()
{
SinricPro.deal with();
handleFlipSwitches();
}