Amazon Echo ESP8266 control, with natural speech commands

For about a month, I’ve been using Blynk with the IFTTT Maker Channel to connect projects to my Amazon echo. The thing that bugs me is that the Maker Channel requires the use of the word “trigger.” This makes for some awkward commands. Instead of saying “Alexa, turn on the bedroom lights,” I’m forced to say “Alexa, TRIGGER the bedroom lights on.”

However, the Echo has native integration with certain products (among them, the Belkin Wemo) that allow natural voice commands. The downside is that a Wemo switch is $50, and isn’t programmable. Thankfully, some clever folks have written code for the ESP8266 that allows it to emulate the Wemo, giving seamless integration with the Echo, and one in particular is written as a library that appears to be compatible with Blynk. Now, I can use natural voice commands, physical inputs, or Blynk to control the ESP. Using WiFiManager for provisioning, the code is pretty dead simple, too (EDIT - replaced with latest version. New features and options described in comments):

/*
 * 
 * Witnessmenow's ESP8266 Wemo Emulator library is an awesome way to build an IoT device on 
 * the cheap, and its direct integration with Alexa / Echo means that voice control can
 * be done with natural sounding commands. However, it is limited by its reliance solely on
 * voice control, as it doesnt work with the official Wemo app. It also provided no affordance
 * for toggling the switch when an internet connection was unavailable. 
 * 
 * With just a bit of additional code, devices can be made controllable by the Blynk app, hardware 
 * switches, IFTTT event triggers,and of course, Alexa. Toss in OTA updates and Tzapulica's 
 * WiFiManager for easy provisioning, and you've got a really versatile, easy to use device. 
 * 
 * 
 * OTA updates are hardware dependent, but don't seem to 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.
 * 
 * The onboard LED is set to ON when the relay is off. This made sense to me, if you're looking 
 * for the physical switch in a dark room. 
 * 
 * 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
 */
 
#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 = 0;
boolean SwitchReset = true;   //Flag indicating that the hardware button has been released

const int TacSwitch = 0;      //Pin for hardware momentary switch. On when grounded. 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()      
{
  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);

  pinMode(RelayPin, OUTPUT);
  pinMode(LED, OUTPUT);
  pinMode(TacSwitch, INPUT_PULLUP);
  delay(10);
  digitalWrite(RelayPin, LOW);
  digitalWrite(LED, LOW);
  

  Blynk.config(auth);
  ArduinoOTA.begin();

  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 && SwitchReset == true){
    Serial.println("Hardware switch activated");
    if (LampState){
      lightOff();
    }
    else{
      lightOn();
    }

    // Flag that indicates the physical button hasn't been released
    SwitchReset = false;
    delay(50);            //debounce
  }
  else if (SwitchState){
    // reset flag the physical button release
    SwitchReset = true;
  }
}


void ToggleRelay(){
  LampState = !LampState;

  if (LampState){
    lightOn();
  }
  else lightOff();
}

The Wemo emulator library can be found here: https://github.com/witnessmenow/esp8266-alexa-wemo-emulator

Yes, I realize that I’m breaking the Blynk rules by having additional code in the main loop, but it works!

12 Likes

Wow! That’s a hack! :clap::clap::clap:

Wow this makes me want to go buy an Alexa!!! Great work and thanks for sharing!

Nah that’s okay. You often have to put initialisers in to the loop().

The Echo Dot is only $49. That’s a pretty low entry point for voice control of your home. If you’re just looking to toggle things on and off, the ITEAD Sonoff switches are only about $5 apiece. They’re ESP8266 based, and really easy to reprogram. Hint: the relay is attached to pin 12.

1 Like

Can you have Alexa return data as voice?

I don’t think so.

I’m sorry, Ben. I’m afraid I can’t do that.

4 Likes
2 Likes

haha :joy: Should’ve put manual override Dave.

I’ve improved the code with hardware switching capability, better synchronization with Blynk, OTA updates and a few other goodies. Obviously it’ll run on any ESP8266 board, but I’m finding the ITEAD Sonoff devices are about the simplest and cheapest solution ($5). AC power goes in. Switched AC power goes out. Booyah!

/*
 * 
 * Witnessmenow's ESP8266 Wemo Emulator library is an awesome way to build an IoT device on 
 * the cheap, and its direct integration with Alexa / Echo means that voice control can
 * be done with natural sounding commands. However, it is limited by its reliance solely on
 * voice control, as it doesnt work with the official Wemo app. It also provided no affordance
 * for toggling the switch when an internet connection was unavailable. 
 * 
 * With just a bit of additional code, devices can be made controllable by the Blynk app, hardware 
 * switches, IFTTT event triggers,and of course, Alexa. Toss in OTA updates and Tzapulica's 
 * WiFiManager for easy provisioning, and you've got a really versatile, easy to use device. 
 * 
 * 
 * OTA updates are hardware dependent, but don't seem to 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.
 * 
 * The onboard LED is set to ON when the relay is off. This made sense to me, if you're looking 
 * for the physical switch in a dark room. 
 * 
 * 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
 */
 
#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 = 0;
boolean SwitchReset = true;   //Flag indicating that the hardware button has been released

const int TacSwitch = 0;      //Pin for hardware momentary switch. On when grounded. 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()      
{
  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);

  pinMode(RelayPin, OUTPUT);
  pinMode(LED, OUTPUT);
  pinMode(TacSwitch, INPUT_PULLUP);
  delay(10);
  digitalWrite(RelayPin, LOW);
  digitalWrite(LED, LOW);
  

  Blynk.config(auth);
  ArduinoOTA.begin();

  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 && SwitchReset == true){
    Serial.println("Hardware switch activated");
    if (LampState){
      lightOff();
    }
    else{
      lightOn();
    }

    // Flag that indicates the physical button hasn't been released
    SwitchReset = false;
    delay(50);            //debounce
  }
  else if (SwitchState){
    // reset flag the physical button release
    SwitchReset = true;
  }
}


void ToggleRelay(){
  LampState = !LampState;

  if (LampState){
    lightOn();
  }
  else lightOff();
}

8 Likes

Good work there. Thanks a lot for this. This is exactly what I was looking for my home integeration with Amazon Echo.

I am new to this, can you please confirm will it work with ESP8266 as Arduino Uno wifi shield ?

I will be connecting Arduino Uno with ESP8266 and a relay board to control switches.

2 Likes

You’d need to make some significant changes for it to work with the Uno. However, unless you absolutely need the additional pins, the Uno isn’t necessary. The ESP8266 has all the processing power you need.

The simplest hardware to use is the Sonoff switch. Just upload the code, and you’re ready to rock. The Wemos D1 mini with a relay shield is only slightly more complex, and gives you a bunch of additional pins to play with, as well as OTA updating.

This improved code doesn’t compile. Giving:
C:\Users\ilak2k\Documents\Arduino\libraries\ESP8266mDNS/ESP8266mDNS.h:117:3: error: ‘WiFiEventHandler’ does not name a type

WiFiEventHandler _disconnectedHandler;

^

C:\Users\ilak2k\Documents\Arduino\libraries\ESP8266mDNS/ESP8266mDNS.h:118:3: error: ‘WiFiEventHandler’ does not name a type

WiFiEventHandler _gotIPHandler;
Would you suggest some changes to make it work?

It’s working perfectly for me. Are all the necessary libraries up to date?

hello sir
where u put the ssid username and pass to connect to the internt?
i donwload the wifimanager but am lill confused if u can give me hint ?
thank u sir

I picked up a few sonoff’ but how can I connect them to blynk and most importantly connect them to my amazon echo either with ifttt or via some other method?

@cactus . you just say “Alexa search for new devices” and it will do it for you :smiley: or use amazon alexa app.

@dananmo Power up the device. It will broadcast a wifi access point called “FakeWemo”. If you look in your phone’s wifi settings, you should see it listed. Connect your phone (or tablet or computer) to that access point. Wait a few seconds, and a captive portal should pop up. It will have a few options, but you just need the first one, which says “Configure Wifi”. Clicking on it will bring up a list of all local wifi routers. Choose yours, and submit the password. The device should reset itself, and connect itself to your wifi network, using the credentials you just gave it.

1 Like

@cactus Assuming you’ve successfully uploaded the code (with your own Blynk token), and used WiFi Manager to connect the device to your local wifi, the Blynk connection happens automatically. A Blynk button widget assigned to virtual pin 1 should activate the relay.

If you’re using this for multiple devices, use a different virtual pin for each one. To do this, you just need to alter one line of code before uploading. In the line:

#define VPIN V1

… change “V1” to “V2” (or any other virtual pin number). Then, assign that same virtual pin to a new button on your Blynk dashboard.

For connecting to Alexa, go into the Alexa app on your phone / tablet. Under the menu button, find Smart Home > Your devices, and tap “Discover devices.” Alexa should find a WeMo Switch called “SonOfWemo”. Now scroll up to Your Groups, and tap “Create group.” Give the group a name that describes your device, like “bedroom lamp,” and tick the box next to SonOfWemo to add it to this group. Alexa will now recognize that name for your switch.

One really nice thing about these groups is that you can combine several switches under a variety of names. For example, I have a group called “living room” that includes all the devices in my living room. If I say “Alexa, turn on the living room,” all the devices in that group turn on. I have another called “everyting” that includes just about every device in my home. When I head to bed, I just say “Alexa, turn off everything,” and it’s done.

For connecting to IFTTT, go to your IFTTT app or web page, click “My applets.” If your’re on the web page, click on “new applet.” If you’re on the mobile app, it’s the plus sign. Select a new “THIS” trigger. For example, if you want your switch to turn on a lamp every time you get within a certain distance of your home, select the LOCATION trigger, and use it to define that perimeter. When you’re finished, it will ask you to define the “THAT” action channel. Select the MAKER channel, and use the following parameters, which can also be found in the opening comments of the Arduino code:

URL: http://blynk-cloud.com:8080/YOUR_TOKEN/V1
Method: PUT
Content type: application/json
Body: [“1”]

In the URL line, substitute your own Blynk token, and the correct vitual pin, if it’s not V1. In the Body line, a “0” will turn the device off, a “1” will turn it on, and a “2” will toggle it. Use whichever is appropriate for your needs.

4 Likes

For anyone using the Sonoff, this code also changes the onboard reset switch into an ON / OFF toggle.

1 Like