Okay, I wanted to install one of these handy Wemo emulators in the junction box of my dining room pendant lamp. This posed a small problem. If there were an issue with the wifi, there would be no way to turn on the lamp. The onboard switch would be buried inside the electrical box.
So I decided to make a variation of the code that switches the relay on at startup. In doing so, the light can be switched on at any time by simply toggling the wall switch from OFF to ON. It also makes it convenient for anyone unfamiliar with your IoT system, since the wall switch will behave in a traditional manner. I commented out lines controlling the onboard LED, since it would never be visible, anyway. EDIT: Fixed the startup button sync problem, with the help of @costas.
/* Extends the capabilities of witnessmenow's awesome WEMO emulator library to work with Blynk, IFTTT,
* and physical switches.
*
* This version is intended for use in line with an existing wall switch. The relay is set to ON at
* startup. In this situation, if wifi stops working, the existing wall switch can be used to turn the
* relay ON and OFF.
*
* OTA update capabiliity is hardware dependent (needs adequate memory), but does't cause any
* problems for devices that don't support it.
*
* Wemo Emulator and WiFi Manager libraries:
* https://github.com/witnessmenow/esp8266-alexa-wemo-emulator
* https://github.com/tzapu/WiFiManager
*
* In order to control a multitude of devices with a single Blynk dashboard, each ESP8266
* should be programmed with a unique virtual pin assignment, corresponding to a Blynk switch.
*
* For IFTTT control, use the Maker Channel with the following settings:
* URL: http://blynk-cloud.com:8080/YOUR_TOKEN/V1 Substitute your own token and vitual pin
* Method: PUT
* Content type: application/json
* Body: {"1"] Use 1 for ON, 0 for OFF, 2 for toggle
*/
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <WiFiManager.h>
#include <ESP8266WebServer.h>
#include <BlynkSimpleEsp8266.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <SimpleTimer.h>
#include "WemoSwitch.h"
#include "WemoManager.h"
#include "CallbackFunction.h"
#define VPIN V1 //Use a unique virtual pin for each device using the same token / dashboard
char auth[] = "YOUR_TOKEN"; //Get token from Blynk
//on/off callbacks
void lightOn();
void lightOff();
WemoManager wemoManager;
WemoSwitch *light = NULL;
boolean LampState = 1;
boolean SwitchReset = true; //Flag indicating that the hardware button has been released
const int TacSwitch = 0; //Pin for hardware momentary switch. Pin 0 on Sonoff
const int RelayPin = 12; //Relay switching pin. Relay is pin 12 on the SonOff
//const int LED = 13; //ON / OFF indicator LED. Onboard LED is 13 on Sonoff
SimpleTimer timer;
void setup(){
pinMode(RelayPin, OUTPUT);
//pinMode(LED, OUTPUT);
pinMode(TacSwitch, INPUT_PULLUP);
delay(10);
digitalWrite(RelayPin, HIGH); // Turn relay ON when unit is powered on
//digitalWrite(LED, LOW);
Serial.begin(115200);
WiFiManager wifi; //WiFiManager intialization.
wifi.autoConnect("FakeWemo"); //Create AP, if necessary
wemoManager.begin();
// Format: Alexa invocation name, local port no, on callback, off callback
light = new WemoSwitch("SonOfWemo", 80, lightOn, lightOff);
wemoManager.addDevice(*light);
Blynk.config(auth);
ArduinoOTA.begin();
// Wait for the connection to Blynk, and sync the dashboard button state
while (Blynk.connect() != true && millis() < 10000){
}
Blynk.virtualWrite(VPIN, HIGH);
Blynk.syncVirtual(VPIN);
timer.setInterval(100, ButtonCheck);
}
void loop()
{
wemoManager.serverLoop();
Blynk.run();
ArduinoOTA.handle();
timer.run();
}
// Toggle the relay on
void lightOn() {
Serial.println("Switch 1 turn on ...");
digitalWrite(RelayPin, HIGH);
//digitalWrite(LED, HIGH);
LampState = 1;
Blynk.virtualWrite(VPIN, HIGH); // Sync the Blynk button widget state
}
// Toggle the relay off
void lightOff() {
Serial.println("Switch 1 turn off ...");
digitalWrite(RelayPin, LOW);
//digitalWrite(LED, LOW);
LampState = 0;
Blynk.virtualWrite(VPIN, LOW); // Sync the Blynk button widget state
}
// Handle switch changes originating on the Blynk app
BLYNK_WRITE(VPIN){
int SwitchStatus = param.asInt();
Serial.println("Blynk switch activated");
// For use with IFTTT, toggle the relay by sending a "2"
if (SwitchStatus == 2){
ToggleRelay();
}
else if (SwitchStatus){
lightOn();
}
else lightOff();
}
// Handle hardware switch activation
void ButtonCheck(){
// look for new button press
boolean SwitchState = (digitalRead(TacSwitch));
// toggle the switch if there's a new button press
if (SwitchState == LOW && SwitchReset == true){
Serial.println("Hardware switch activated");
ToggleRelay();
SwitchReset = false; // Flag that indicates the physical button hasn't been released
delay(50); //debounce
}
else if (SwitchState){
SwitchReset = true; // reset flag the physical button release
}
}
void ToggleRelay(){
if (LampState){
lightOff();
}
else lightOn();
}