Home Automation with Alexa

Voice commands with IoT emulated devices, using the Arduino library Espalexa.

Marcelo Rovai
Towards Data Science

--

Top Image: Echo-Dot 2nd Generation by Amazon — Botton Image: Final Circuit by Author

1. Introduction

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:

Block Diagram — Image by Author

The below video shows how the project will look like at the end:

2. Install ESP boards

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
Arduino IDE Preferences— Print Screen

Next, at Arduino IDE Tools/Boards Manager, Install boards:

Arduino IDE Board Manager — Print Screen

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:

Arduino IDE Board Manager — Print Screen

The ESP8266 NodeMCU Pinout:

ESP8266 NodeMCU Pin-Out — Image by Amazon.com

3. The Espalexa Library

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:

Arduino IDE Library Manager — Print Screen

4. Home Automation prototype

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:

House Prototype and its IoT devices — Image by Author

5. Assembling the HW for testing

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.”

Circuit Diagram — Image by Author

6. Creating our IoT Devices on Arduino IDE

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 names
String 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 names
String 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:

Arduino IDE Serial Monitor Print Screen

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:

Alexa App (Devices tab) — Printscreen

Once Alexa has discovered your devices, you can give her voice commands, as shown below:

The below screenshot shows the Serial monitor response.

Arduino IDE Serial Monitor Print Screen

7. Assembling the Complete HW

Instead of LEDs and resistors, the Outputs GPIOs should be connected to the 4-Channel Relay model as below:

Circuit Diagram — Image by Author

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 names
String 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.

Circuit Diagram — Image by Author

Note that you can install real AC Lamps and appliances to be controlled using Alexa once the relays can handle them.

8. Final Considerations about the “Device Functions”

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.

Block Diagram — Image by Author

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"):

Conclusion

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!

Thank you

Marcelo

--

--

Engineer, MBA, Master in Data Science. Passionate to share knowledge about Data Science and Electronics with focus on Physical Computing, IoT and Robotics.