Home Automation with Alexa. Voice commands with IoT emulated... | by Marcelo Rovai | Towards Data Science

A few years ago, I explored how to use Alexa, an intelligent personal assistant made popular by the Amazon Echo and Echo-Dot, in Home Automation projects:
When IoT Meets AI: Home Automation With Alexa and NodeMCU and
Alexa — NodeMCU: WeMo Emulation Made Simple
Alexa is capable of voice interaction, music playback, making to-do lists, setting alarms, streaming podcasts, playing audiobooks, and providing weather, traffic, and other real-time information. Alexa can also control several smart devices using itself as a home automation hub. We will use on this project, the “Echo Dot”, which allows users to activate the device using a wake-word, such as “Alexa” or “Computer”, as in “Star Trek!.
In the home automation space, Alexa can interact with several different devices like Philips Hue, Belkin Wemo, Sonoff, etc. We emulated WeMo devices on previous projects, using the fauxmoESP library, which seems outdated and not adequately maintained nowadays. Here we will use Espalexa, an easy to use Arduino library compatible with both ESP8266 and ESP32.
The below block diagram shows what will be developed on our project:
The below video shows how the project will look like at the end:
At Arduino IDE Preferences → Additional boards Manager URLs enter with:
https://dl.espressif.com/dl/package_esp32_index.json, http://arduino.esp8266.com/stable/package_esp8266com_index.json
Next, at Arduino IDE Tools/Boards Manager, Install boards:
In this project, we will use the NodeMCU, but the code could be easily adapted to also work with ESP32. So, let’s also install it:
The ESP8266 NodeMCU Pinout:
Espalexa allows you to set a range of values (e.g., Brightness, Temperature) and optionally a color, additionally to standard on/off control. For example, you can say — — “Alexa, turn the light to 75% “.
Espalexa emulates parts of the SSDP protocol and the Philips hue API, just enough to be discovered and controlled by Alexa.
By default, it’s possible to add up to a total of 10 devices because each device “slot” occupies memory, even if no device is initialized. You can change the maximum number of devices by adding, for example:
#define ESPALEXA_MAXDEVICES 20
before calling the library:
#include <Espalexa.h>
It is recommended to set MAXDEVICES to the exact number of devices you want to add to optimize memory usage.
To install the library, go to Arduino IDE Tools/Manage Libraries, and enter with espalexa:
Our Home Automation project will be created having four smart devices working that can be individually remotely controlled. But suppose that we want to group our devices to be used in our home. What should be done?
For example, suppose that our home has two rooms:
Bed Room
Living Room
Now, suppose that you want to have one lamp and one outlet in each room. So, let’s group our four devices, as shown in the block diagram (at this article introduction):
Bed Room
Light 2
Outlet 1 (Fan)
Living Room
Light1
Outlet 2 (Buzzer)
Ou Home Automation Project will be more or less like this:
For testing purposes, four color LEDs will be used as “IoT devices”. They should be installed as shown in the diagram and listed below:
==> Red LED (Light1) ==> NodeMCU D1 (GPIO5) — Living Room
==> Green LED (Outlet1) ==> NodeMCU D2 (GPIO4) — Living Room
==> Blue LED (Light2) ==> NodeMCU D5 (GPIO14) — Bed Room
==> Yellow LED (Outlet2) ==> NodeMCU D6 (GPIO12) — Bed Room
The LEDs red and green will simulate the devices installed on “Living Room,” and LEDs blue and yellow will simulate the ones installed on “Bed Room.”
First, we must call the libraries:
#include <ESP8266WiFi.h>#include <Espalexa.h>
Following for NodeMCU pins definitions to be connected to devices (at test phase will be LEDs and at final project, Relays inputs):
#define RelayPin1 5  //D1#define RelayPin2 4  //D2#define RelayPin3 14 //D5#define RelayPin4 12 //D6
Once we have 4 devices, at least 4 direct callback functions should be defined:
void device1Changed(uint8_t brightness);void device2Changed(uint8_t brightness);void device3Changed(uint8_t brightness);void device4Changed(uint8_t brightness);
The brightness parameter contains the new device state (0:off, 255:on, 1–254:dimmed) that will be sent by Alexa when that callback function is called.
But the callback function can be any function to be executed under Alexa command, so we will define here three additional special functions to be called that will handle multiple IoT devices:
void devFunc1Changed(uint8_t brightness);void devFunc2Changed(uint8_t brightness);void devFunc3Changed(uint8_t brightness);
The above callback functions will be associated with:
All Home Devices (Light1, Light2, Outlet1, and Outlet2)
Living Room (Light1 and Outlet1)
Bed Room (Light2 and Outlet2)
So, Alexa will in fact handle seven “IoT devices”. For each one of them, we must define a unique name to be called by Alexa:
// device namesString Device_1_Name = "Red light";String Device_2_Name = "Green light";String Device_3_Name = "Blue light";String Device_4_Name = "Yellow light";// device_function namesString Dev_Func_1_Name = "Living Room";String Dev_Func_2_Name = "Bed Room";String Dev_Func_3_Name = "All Home Devices";
During testing phase, we will call the LEDs by “{its color} Light”. On our final project we can changed those variables by its final name (“Light 1”, “Outlet2”, etc).
The last but not least, we should declare the variables to be used by espalexa:
Espalexa espalexa;
and for communication:
boolean connectWifi();boolean wifiConnected = false;const char* ssid = "YOUR SSID HERE";const char* password = "YOUR PASSWORD HERE";
On Setup phase, you should besides the usual pin and serial bald-rate definitions and communication start procedures, have each one of the IoT devices with its name properly associated and espalexa started:
// Define your devices here.espalexa.addDevice(Device_1_Name, device1Changed);espalexa.addDevice(Device_2_Name, device2Changed);espalexa.addDevice(Device_3_Name, device3Changed);espalexa.addDevice(Device_4_Name, device4Changed);// Define your devices functions here.espalexa.addDevice(Dev_Func_1_Name, devFunc1Changed);espalexa.addDevice(Dev_Func_2_Name, devFunc2Changed);espalexa.addDevice(Dev_Func_3_Name, devFunc3Changed);espalexa.begin();
The loop function should be very simple:
void loop(){  espalexa.loop();  delay(1);}
The last procedure will be creating of callback functions, or better, what must be done when Alexa sent a command.
The below callback function could be adapted for all four IoT devices:
void deviceNChanged(uint8_t brightness){  //Control the device   if (brightness == 255)    {      digitalWrite(RelayPinN, HIGH);      Serial.println("DeviceN ON");    }  else  {    digitalWrite(RelayPinN, LOW);    Serial.println("DeviceN OFF");  }}
Changing “N” on the above code by 1, 2, 3, and 4 will have the four direct callback functions. Remember that brightness parameter sent by Alexa, contains the new device state that will be:
0 ==> OFF;
255 ==> ON
1 to 254 ==> “dimmed light”.
We can expand the above simple ON-OFF function for a special function where a light intensity can be controlled. We will do this for the device1 (the Red LED):
void device1Changed(uint8_t brightness){  //Control the device  if (brightness == 255)  {    digitalWrite(RelayPin1, HIGH);    Serial.println("Device1 ON");  }  else if (brightness == 0)  {    digitalWrite(RelayPin1, LOW);    Serial.println("Device1 OFF");  }  else  {    int brigh_perc = (brightness/255.)*100;    analogWrite(RelayPin1, brightness);    Serial.print("Device1 Brightness: ");    Serial.print(brigh_perc);    Serial.println("%");  }}
Remember that the NodeMCU has PWM outputs that can be used with Arduino analogWrite() function. If an ESP32 is used, the PWM function should be created once the analogWrite() is not available.
The complete code can be downloaded from my GitHub: Alexa_NodeMCU_Home_Automation
Do not forget to change the dummy wifi credentials with your own.
Once you compile the code on Arduino IDE and upload it to the NodeMCU, you can see the messages exchanged on the Serial monitor. Once the NodeMCU is connected to your wifi, a similar message (with your network data) should appear:
We consider that you already have an Alexa adequately installed on the same network where your NodeMcu is connected.
Now, let’s ask Alexa to find your devices. There are two methods to do it:
Using the Alexa App in your Smartphone
Asking Alexa to do it directly using voice command, like: “Alexa, discovery devices”.
After 45 seconds, you should receive Alexa confirmation that seven devices were found. You can see than on the App “Light tab” as below:
Once Alexa has discovered your devices, you can give her voice commands, as shown below:
The below screenshot shows the Serial monitor response.
Instead of LEDs and resistors, the Outputs GPIOs should be connected to the 4-Channel Relay model as below:
Do not power the Relay-Module directly from the NodeMcu 5V output pin. Use an external Power supply for that instead. A 1A Power Supply should be enough. Confirm with the Relay-Module manufacturer if another version is used. Do not forget to connect the GNDs all together.
In principle, the same code developed for testing can be used, BUT you must confirm the Relay-Module’s logic. For example, in the above module, you should keep the inputs “Open” or HIGH, changing to LOW to activate the Relay output. So, the code must be changed accordantly.
During setup() phase, define GPIOs outputs as HIGH
On CallBack functions change HIGH for LOW and vice-versa
You can confirm that relays are working properly by both, the sound of output relay closing and from a red led in the module.
Once everything is correctly working is the time for complete installation of our “smart devices”, which are two fixed “Lamps” and 2 “general Outlets”, let’s rename them appropriately:
Light One
Light Two
Outlet One
Outlet Two
// device namesString Device_1_Name = "Light One"; String Device_2_Name = "Light Two";String Device_3_Name = "Outlet One";String Device_4_Name = "Outlet Two";
As shown on the video at the start of this tutorial, to complete our project, connect some devices to be controlled by relays. In my case, I use two LEDs as lamps and attach a fan on outlet 1 and a buzzer on outlet 2 (to simulate a device like a radio, for example). The below diagram shows the appliances installed.
Note that you can install real AC Lamps and appliances to be controlled using Alexa once the relays can handle them.
Starting from the concept of emulating simple IoT devices, as WeMo or Philips Hue, we also used Alexa to “trigger” more complex functions, “the Device Functions”. On those functions, multiple outputs were used as a group of the devices split by rooms.
In my tutorial, Computer, Firing All Weapons, some of Star Trek Enterprise weapons, as Photon Torpedos and Phasers, were simulated using such functions.
This is a powerful tool to be explored in the IoT field, where a simple voice command can trigger more complex processes using microcontrollers, as can be observed on below video (Here "Computer" wake-word was used instead "Alexa"):
As always, I hope this project can help others find their way in the exciting world of electronics and IoT!
Please visit my GitHub for updated files: Alexa_NodeMCU_Home_Automation
For more projects, please visit my blog: MJRoBot.org
Saludos from the south of the world!
See you at my next article!