Alexa, ask the sensor for the humidity in the basement …
As we moved into a newly built house a while ago, we wanted to keep track of the humidity in the three rooms of our basement, as it seemed to be a little bit too high in the beginning. One could simply buy a humidity sensor with a display, put it in the basement and check it from time to time, but why not quickly build something yourself?
As we have a few Amazon Echos at home, it would be much simpler to ask Alexa for the current measurements instead of having to walk down to the basement every time. Additionally I also had some spare boards with an ESP32 chip (which provides I/O Ports and Wi-Fi connectivity) and some DHT22 Sensors (which can measure the temperature and humidity) at home, so it should not take that long to build a working prototype?
Now we have the ESP32, the DHT22 Sensor and the Echo, but how do we connect everything? On the ESP32 you have various choices of what Firmware/Platform you can run. I opted for MongooseOS (it popped up in the Technology Radar some time ago) as it has a good AWS integration (also for other cloud providers) and you can write your code easily in JavaScript. As it has a straight forward integration with AWS IoT, we are going to push or sensor data to a Device Shadow. If we ask Alexa for the latest measurements we can then simply get them from the Device Shadow. This is what our setup will look like in the end:
Let’s start on the left side and see how we wire everything up and get the measurements to the device shadow.
Preparing the ESP32, DHT22 and AWS IoT
First we have to wire the ESP32 and the DHT22. As I have the module version it only has 3 pins we have to wire. If you have the plain sensor, you might additionally need some resistor.
+-------+--------+
| ESP32 | DHT22 |
+-------+--------+
| 3,3V | + |
| GND | - |
| 32 | Data |
+-------+--------+
Now let’s take a look at the software we need to run on the ESP32. As mentioned before we are going to use MongooseOS. To use it we need to install the mos
utility:
# on macOS (for other OS see here)
brew tap cesanta/mos
brew install mos
Once that is done we can take a look at the code we need. To build the firmware have to create a manifest which defines some metadata, our dependencies and where our source files are, that is called mos.yml
(similar to a pom.xml or package.json). Then we have to write our code. We will put it in a file called init.js
, as this will be automatically executed after booting up:
The code itself is rather easy and short. First we load all the modules we need (line 1–3), then we create an instance of the DHT to access our sensor (line 5) and finally a timer (line 8) that ensures we push an update to a device shadow (line 12) every 5 minutes.
You can find the complete code on GitHub, so before we continue to build the firmware you might want to clone it:
git clone git@github.com:comsysto/alexa-aws-iot-esp32-dht22-lab.git
To build the firmware just go to the folder esp32
in the repository and execute:
# if you have installed docker:
mos build --platform esp32 --local
# if not, you can use the cloud build:
mos build --platform esp32
Once the firmware is built, we can flash the ESP32. To do so connect it to your computer, figure out the port it is connected to (on macOS usually something like /dev/...usb....
) and then execute
mos flash --port /dev/YOUR-USB-PORT-HERE # e.g. /dev/cu.SLAB_USBtoUART
Now we have the software itself running on our ESP32, but we have not yet connected it to our Wi-Fi, and neither we have configured anything regarding the AWS connectivity. Both configurations are again done via mos
:
mos wifi YOUR-SSID-HERE YOUR-PW-HERE --port /dev/YOUR-USB-PORT-HERE
Prerequisite to configure AWS IoT is an AWS account and you need to have the AWS CLI installed. Then you can execute:
mos aws-iot-setup --aws-region=eu-west-1 --port=/dev/YOUR-USB-PORT-HERE
We can now verify if the setup was successful by checking if it was created on AWS with aws --region=eu-west-1 iot list-things
. The output should look similar to this:
As the software on the ESP32 is already running, we should have some values in our device shadow:
aws --region eu-west-1 iot-data get-thing-shadow --thing-name esp32_AAAAAA shadow.json
The shadow.json
should look similar to this:
I prepared three ESP32 like this, one for each room in the basement.
Now we can move on and start to create the Alexa Skill.
Create the Alexa Skill
Before we start implementing the Skill, we should think about how we would like to interact with Alexa. Each interaction starts with Alexa,
followed by a verb like ask
then the skill invocation name
followed by what should be handled by the given skill, e.g.:
Alexa, ask the sensor for the humidity in the cellar storeroom.
As mentioned before we have 3 rooms in our basement and the sensors provide measurements for temperature and humidity. So we have 2 parameters in that sentence (called slots
in the Alexa terminology) that we have to evaluate to give the user the correct answer.
Now we can start to create the Skill in the Alexa Developer Console (you need an account here as well).
To keep things very simple, we create an Alexa Hosted Skill. Just go to https://developer.amazon.com/alexa/console/ask/create-new-skill to create a new Skill.
As a Skill name
choose whatever you like, select Custom
for the Model and Alexa-Hosted (Node.js)
for the backend.
First thing we have to configure is the Skill Invocation Name
(select Invocation in the left menu)
The Skill Invocation Name
is then used by Alexa to figure out that the request should be handled by your skill. Alexa, ask [your skill invocation name] ...
Next thing we have to create are the Slot Types
, so we can handle the different rooms and types of measurements in an easier way later:
We create one Slot called rooms
for the 3 rooms we would like to ask for (cellar storeroom, workshop, boiler room):
And the second slot called measurements
for humidity and temperature:
With the defined Slot Types we can now create the intents
to actually tell our skill what to do. Therefore we will create one intent with the name GetMeasurementForRoom
:
In the Intent Slots
section we configure the two slots created before and then add some Sample Utterances
which use these slots:
Once this is done, we can save and build the model and continue with the code for the Lambda. All one has to do is to implement a handler with two methods:
canHandle(handlerInput)
to check if the request can be handledhandle(handlerInput)
to handle the request if canHandle returnedtrue
You can find an example of how the handerInput
will look like in our case here. To check if we can handle the request, we verify that the type
of the request is IntentRequest
and that the name of the intent is GetMeasurementForRoom
:
To handle the request, we implement the handle
method.
First we check the slots that are provided in the request, to know what the user requested, then we get the data from the Sensor/Device Shadow and finally we generate the speech output for the user.
To get the sensor data, we use IotData
of the AWS SDK. As we have to authenticate to get the data from the Device Shadow, we need the STS
(Security Token Service) to get credentials.
To use the STS and to access the Device Shadow we have to create a Role in IAM that allows a Lambda function to access other AWS services. The policy attached to that role allows at least to get the thing shadow from our resources (Device Shadows):
You can find the complete code of the Lambda in the alexa-skill
folder of the git repo you cloned before.
Once everything is in place, we can deploy the code and test it in the Alexa Developer Console.
At this stage it is also possible to test it on your Echo if you registered the device with the same E-Mail as you have created your Alexa Developer Console Account with.
As you have seen, with the given tools it is fairly easy to create a basic IoT Prototype and an Alexa Skill with just a few lines of JavaScript Code and some very affordable hardware. Of course, this it is not ready for any productive use, but good enough to play with at home.
In the current state we can just access the latest values reported by the devices, but it might be far more interesting to see how the measurements evolve over time or to get notifications if the values cross a given threshold. But we will take a look at this next time.
We at Comsysto Reply develop sophisticated and innovative software solutions with great passion. We take care of projects holistically and with full transparency: you get everything from one source.
This blogpost is published by Comsysto Reply GmbH