Amazon Echo ESP8266 control, with natural speech commands

I recently picked up a Google Home Mini, and found that it doesn’t have the same direct integration of Wemo devices as the Amazon products. However, it does work very well with IFTTT. In fact, IFTTT’s Google Assistant trigger allows us to create whatever speech trigger we want. We’re no longer limited to “off” and “on!”

With the Google Home products, @dananmo can finally tell his device to “make me a dry martini.”

1 Like

Hahaha thatsis amazing
Am gunna tell my wife to have it as Christmas gift lol

First, thank you Chrome for your great work.
Your code worked perfectly on 2 devices (ESP-01 and D1-Mini) for almost a month. Now, i cannot find devices with Alexa for the life of me. Even worse, both saved devices in Alexa app are not there anymore. Same code, same hardware, nothing changed but Alexa is not discovering any wemo anymore.

The device is set up perfectly and all blynk related works perfect. What could be wrong? I never enabled any skill in alexa app before and still worked perfect as you described. What should i try? And why my devices dissapeared by themselves from Alexa app…?

All Alexa related things already tried (reset, reconfig same wifi; although useless because they were all in the same wifi network, etc)

P.S. i am on local server, but as i said, blynk is more than fine…

I had a similar experience after updating the Alexa app on my iPhone a few weeks ago. My solution was to re-discover my devices using my iPad that still had an earlier version of the app. It found my devices, which in turn populated them on the newer app.

Any Blynkers out there have another solution?

It worked with an older version that i’ve had on a tablet…rediscovering i mean.

HUGE IMPROVEMENTS since the last iteration!!!

I’ve replaced the WemoManager library that I was using with the Espalexa library, which solves several issues:

  1. It’s simpler to implement. One library. One callback.
  2. It resolves the issue that many were having with updated Echo devices not discovering correctly
  3. … and drumroll… It now allows LEVELS! You can specify any level from 0-100%.

For anyone who wants to dim a lamp, open the blinds halfway, or change the volume the stereo (@pavel @jon), it’s now possible. The Espalexa library takes advantage of Hue bulb emulation to expose a “brightness” parameter. That level, however you express it to Alexa, is converted to an unsigned integer 0-255 for us to use however we see fit.

Here’s the code that I used to test the functionality:

/* Wemo / Hue emulation for ESP8266 control with Alexa, Blynk and IFTTT.
 * 
 * https://github.com/tzapu/WiFiManager
 * https://github.com/Aircoookie/Espalexa
 * https://www.blynk.cc/
 * 
 * In order to control multiple devices with a single Blynk dashboard, each ESP8266
 * should be programmed with a unique virtual pin corresponding to a Blynk
 * dashboard widget (switch, slider, step). 
 * 
 * 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 0 for OFF, 1 for ON. For custom levels use 0-255.
 */

#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> 
#include <Espalexa.h>
#include <ArduinoOTA.h>
#include <BlynkSimpleEsp8266.h>

// Blynk token and virtual pin number
#define VPIN V10  //Use a unique virtual pin for each device using the same Blynk token / dashboard
char auth[] = "TOKEN"; //Get token from Blynk

const int OutputPin = D1;      //Relay switching pin. Relay is pin 12 on the SonOff

Espalexa espalexa;

void setup(){ 
  Serial.begin(115200);
  
  WiFiManager wifi; 
  wifi.autoConnect("MyDevice"); // Connect to wifi
 
  espalexa.addDevice("Switch1", UpdateSwitch1); //Parameters: (device name, callback function).
  espalexa.begin();

  pinMode(OutputPin, OUTPUT);
  digitalWrite(OutputPin, LOW); 

  Blynk.config(auth);
  
  ArduinoOTA.begin();
}
 
void loop()
{
   espalexa.loop();
   Blynk.run();
   ArduinoOTA.handle();
}

//------------ Callback functions. Level can be set from 0-255. -------------
void UpdateSwitch1(uint8_t level) {   // Espalexa callback
  SetNewLevel(&level);  
}

BLYNK_WRITE(VPIN){                    // Blynk & IFTTT callback
  uint8_t level = param.asInt();
  SetNewLevel(&level); 
}

void SetNewLevel(uint8_t * pLevel){
  Serial.print("New level= ");
  Serial.println(*pLevel);
  
  if (*pLevel) {
    digitalWrite(OutputPin, HIGH); // Use analog.Writes for PWM control
  }
  else  {
    digitalWrite(OutputPin, LOW); 
  }
}

Enjoy!

3 Likes

l have been Waiting for this for a long time! Thank you So much!

whoa! need to test it out ASAP!

Did you try running both WeMo emulator and Espalexa?

Yes, I attached a device with this code to my existing system, which is mostly Wemo emulators, and everything played nicely together.

However, since Espalexa seems to fix problems that folks had with Gen 2 Alexa losing or failing to find their devices, I’m inclined to update all my gadgets to the new code.

A post was split to a new topic: I would like to control the Nodemcu with natural voice commands

Can i use this code to link my esp8266 with my google home ? Because in GH i need a wemo account

Google Home doesn’t have the same native integration as Alexa, but you can connect through IFTTT. Just use IFTTT’s Google Assistant trigger and the Blynk webhook action (instructions in the header comments of the code).

The great thing about Google Home’s IFTTT trigger is that you can specify any phrase, provide alternate phrases, and even create a custom response.

1 Like

Hey,
The code works perfectly. But I have a case usually after power cut the wifi modem takes some time to be up. But the nodemcu immediately creates its own AP and stays there even after the wifi signal is back. in such cases I have connect to the hotspot and do a reset. Have you also faced such issue?

I had a look into the Documentation of WifiManager on Github.I found this:
https://github.com/tzapu/WiFiManager#configuration-portal-timeout

wifiManager.setConfigPortalTimeout(180);

So replacing this

with:

WiFiManager wifiManager;
//sets timeout until configuration portal gets turned off
//useful to make it all retry or go to sleep
//in seconds
wifiManager.setTimeout(180);

//fetches ssid and pass and tries to connect
//if it does not connect it starts an access point with the specified name
//here  "AutoConnectAP"
//and goes into a blocking loop awaiting configuration
if(!wifiManager.autoConnect("AutoConnectAP")) {
Serial.println("failed to connect and hit timeout");
delay(3000);
//reset and try again, or maybe put it to deep sleep
ESP.reset();
delay(5000);
}  

Hope this is helpful to people facing similar problems

1 Like

I am using wemos D1 mini and relay board (4 relays, but for testing I keept everything.
Here is my code

#include <ESP8266WebServer.h>

#include <WiFiManager.h>

#include <DNSServer.h>

#define BLYNK_PRINT Serial // This prints to Serial Monitor
#include <ESP8266WiFi.h>  // for ESP8266
#include <BlynkSimpleEsp8266.h>  // for ESP8266
#include <ESP8266mDNS.h>  // For OTA w/ ESP8266
#include <WiFiUdp.h>  // For OTA
#include <ArduinoOTA.h>  // For OTA

#include "WemoSwitch.h"
#include "WemoManager.h"
#include "CallbackFunction.h"

char auth[] = "xxxx";
char ssid[] = "xxxx";
char pass[] = "xxxx";

//for Alexa

//on/off callbacks
void bedroomlightson();
void bedroomlightsoff();

void loungelightson();
void loungelightsoff();

void gymlightson();
void gymlightsoff();

void tvon();
void tvoff();

void chargeron();
void chargeroff();

void switch1on();
void switch1off();

WemoManager wemoManager;

WemoSwitch *bedroomlights = NULL;
WemoSwitch *loungelights = NULL;
WemoSwitch *gymlights = NULL;
WemoSwitch *tv = NULL;
WemoSwitch *charger = NULL;
WemoSwitch *switch1 = NULL;


const int RelayPin1 = D4;      
const int RelayPin2 = D7;
const int RelayPin3 = D6;
const int RelayPin4 = D5;
const int RelayPin5 = D0;
const int RelayPin6 = D1;

//end Alexa

void setup() {

//Alexa
  pinMode(RelayPin1, OUTPUT);
  digitalWrite(RelayPin1, LOW);   // Turn relay OFF when unit is powered on

  pinMode(RelayPin2, OUTPUT);
  digitalWrite(RelayPin2, LOW);   // Turn relay OFF when unit is powered on

  pinMode(RelayPin3, OUTPUT);
  digitalWrite(RelayPin3, LOW);   // Turn relay OFF when unit is powered on

  pinMode(RelayPin4, OUTPUT);
  digitalWrite(RelayPin4, LOW);   // Turn relay OFF when unit is powered on

  pinMode(RelayPin5, OUTPUT);
  digitalWrite(RelayPin5, LOW);   // Turn relay OFF when unit is powered on

  pinMode(RelayPin6, OUTPUT);
  digitalWrite(RelayPin6, LOW);   // Turn relay OFF when unit is powered on

//end Alexa
  
  Serial.begin(9600);  // BLYNK_PRINT data

//Alexa

  WiFiManager wifi;   //WiFiManager intialization.
  wifi.autoConnect("FakeWemo"); //Create AP, if necessary

  wemoManager.begin();

  // Format: Alexa invocation name, local port no, on callback, off callback

  bedroomlights = new WemoSwitch("bedroom lights", 80, bedroomlightson, bedroomlightsoff);
  loungelights = new WemoSwitch("lounge lights", 81, loungelightson, loungelightsoff);
  gymlights = new WemoSwitch("gym lights", 82, gymlightson, gymlightsoff);
  tv = new WemoSwitch("tv", 83, tvon, tvoff);
  charger = new WemoSwitch("charger", 84, chargeron, chargeroff);
  switch1 = new WemoSwitch("switch 1", 85, switch1on, switch1off);

  wemoManager.addDevice(*bedroomlights);
  wemoManager.addDevice(*loungelights);
  wemoManager.addDevice(*gymlights);
  wemoManager.addDevice(*tv);
  wemoManager.addDevice(*charger);
  wemoManager.addDevice(*switch1);
//end alexa


  WiFi.begin(ssid, pass); 
  Blynk.connect();

  ArduinoOTA.setHostname("Wemos_0518");  // For OTA - Use your own device identifying name
  ArduinoOTA.setPassword("xxxx");

  ArduinoOTA.begin();  // For OTA
}
//Alexa

// Toggle the relay on
void bedroomlightson() 
  {

    digitalWrite(RelayPin1, HIGH);
    Blynk.virtualWrite(V1, HIGH);     // Sync the Blynk button widget state
}

void loungelightson() 

{
    digitalWrite(RelayPin2, HIGH);
    Blynk.virtualWrite(V2, HIGH);     // Sync the Blynk button widget state
}

void gymlightson() 

{
    digitalWrite(RelayPin3, HIGH);
    Blynk.virtualWrite(V3, HIGH);     // Sync the Blynk button widget state
}

void tvon() 

{
    digitalWrite(RelayPin4, HIGH);
    Blynk.virtualWrite(V4, HIGH);     // Sync the Blynk button widget state
}

void chargeron()

{
    digitalWrite(RelayPin5, HIGH);
    Blynk.virtualWrite(V5, HIGH);     // Sync the Blynk button widget state
}

void switch1on() 

{
    digitalWrite(RelayPin6, HIGH);
    Blynk.virtualWrite(V6, HIGH);     // Sync the Blynk button widget state
}

// Toggle the relay off

void bedroomlightsoff() 
{
    digitalWrite(RelayPin1, LOW);
    Blynk.virtualWrite(V1, LOW);      // Sync the Blynk button widget state
}

void loungelightsoff() 
{
    digitalWrite(RelayPin2, LOW);
    Blynk.virtualWrite(V2, LOW);      // Sync the Blynk button widget state
}

void gymlightsoff() 

{
    digitalWrite(RelayPin3, LOW);
    Blynk.virtualWrite(V3, LOW);      // Sync the Blynk button widget state
}

void tvoff() 

{
    digitalWrite(RelayPin4, LOW);
    Blynk.virtualWrite(V4, LOW);      // Sync the Blynk button widget state
}

void chargeroff() 

{
    digitalWrite(RelayPin5, LOW);
    Blynk.virtualWrite(V5, LOW);      // Sync the Blynk button widget state
}

void switch1off() 
{
    digitalWrite(RelayPin6, LOW);
    Blynk.virtualWrite(V6, LOW);      // Sync the Blynk button widget state
    }

// Handle switch changes originating on the Blynk app
BLYNK_WRITE(V1){
  int SwitchStatus1 = param.asInt();
   if (SwitchStatus1 == 1) {
    digitalWrite(RelayPin1, LOW);
  }
  else {
    digitalWrite(RelayPin1, HIGH);
  }
}

BLYNK_WRITE(V2){
  int SwitchStatus2 = param.asInt();
  if (SwitchStatus2 == 1) {
    digitalWrite(RelayPin2, LOW);
  }
  else {
    digitalWrite(RelayPin2, HIGH);
  }
}

BLYNK_WRITE(V3){
  int SwitchStatus3 = param.asInt();
  if (SwitchStatus3 == 1) {
    digitalWrite(RelayPin3, LOW);
  }
  else {
    digitalWrite(RelayPin3, HIGH);
  }
}

BLYNK_WRITE(V4){
  int SwitchStatus4 = param.asInt();
  if (SwitchStatus4 == 1) {
    digitalWrite(RelayPin4, LOW);
  }
  else {
    digitalWrite(RelayPin4, HIGH);
  }
}

BLYNK_WRITE(V5){
  int SwitchStatus5 = param.asInt();
  if (SwitchStatus5 == 1) {
    digitalWrite(RelayPin5, LOW);
  }
  else {
    digitalWrite(RelayPin5, HIGH);
  }
}

BLYNK_WRITE(V6){
  int SwitchStatus6 = param.asInt();
  if (SwitchStatus6 == 1) {
    digitalWrite(RelayPin6, LOW);
  }
  else {
    digitalWrite(RelayPin6, HIGH);
  }

}


//end Alexa
void loop() {
//Alexa
  wemoManager.serverLoop();
//end Alexa
  Blynk.run();
  ArduinoOTA.handle();  // For OTA
}

But when I try to compile the sketch, I get this error:

1 Like

You need to choose how you’re going to connect the wifi. Right now, you’ve got BOTH hard coded provisioning and WiFi Manager built into the sketch. If you’re going to hard code the SSID and password, you’ll have to remove all of the WiFi Manager code.

Otherwise, just leave the provisioning code as it was in the example, and use Blynk.auth(“your_token”) to connect to Blynk. You don’t need Blynk.connect or WiFi.begin.

So I can not have one default wifi network? For example that my home network is always entered and I do not need to reenter it everytime I come in a range of home network (I am using it also in my camper van)

I copied that code on my Wemos D1 mini, didn’t change anything (except auth), but I still get this error :frowning:

The simple answer is “no,” you can’t do both dynamic provisioning and hard-coded provisioning.

However, you could try static provisioning first, and if it’s unable to connect, then run the WiFi manager code. I haven’t tested this, but here’s how I’d probably do it. In the Setup function, I’d try:

WiFi.begin("SSID", "password");

// Create a 10 second timeout for connecting with the saved credentials
int WiFiTimeout = millis() + 10000;
while (WiFi.status() != WL_CONNECTED && WiFiTimeout > millis())
{
  delay(500);
  Serial.print(".");
}

// If it didn't connect before the timeout expired, run WiFi Manager to set up dynamic provisioning
if(WiFi.status() != WL_CONNECTED){
  WiFiManager wifi;
  if(!wifi.autoConnect("FakeWEMO")) {
    Serial.println("Failed to connect.");
    delay(1000);
    ESP.reset(); //reset if new credentials failed.
    delay(1000);
  }
}
 
Blynk.auth("your_token");

Hi @monaco

can you try to upgrade Esp8266 to 2.3.0 version?

hope it work

FYI v2.4.1 is latest version. GitHub - esp8266/Arduino: ESP8266 core for Arduino