ESP-Now with ESPHome
ESP-Now
a wireless communication protocol defined by Espressif, which enables the direct, quick and low-power control of smart devices, without the need of a router
The use-case here is battery-powered sensors. WiFi sensors take several seconds to start,
connect, and send sensor measurements. Seconds don't sound like a long time, but it is
quite a long time in the world of low-power sensors. ESP-Now doesn't need to negotiate a
connection. It can just broadcast data. It seems well-suited for battery-powered sensors
and would be great to use within ESPHome
The issue is there isn't an official component for ESP-Now yet. There are several
BOM
- 2x ESP32 boards
- any sensor for testing, I'll be using an SHT30
Architecture
Because we want our measurements to get into Home Assistant, and Home Assistant lives on WiFi, we'll need to make some sort of bridge so our ESP-Now sensors can talk to WiFi. We also need a way to present our sensors inside Home Assistant.
To accomplish both of those things, I will use an ESP32 as a bridge. The bridge will
connect to our MQTT broker configured for use with Home Assistant. The bridge will also
listen to ESP-Now broadcast messages. The messages will contain enough information in them
to allow the bridge to simulate an MQTT-based sensor
When you include an mqtt block in the ESPHome YAML. It sends two bits of information to the broker regarding the sensors:
- a config string that is JSON with details about the measurement, unit of measurement, type of measurement, etc.
- a state string which is the actual sensor measurement
Our sensor ESP32 will send an ESP-Now message like this:
Each piece of information is delimited by a :.
WiFi Channels
There is some confusion that I wasn't able to sort out. Your WiFi router operates on a particular channel (some jump around). When the bridge connects to the WiFi network, it discovers the channel as part of the connection procedure. Normally you don't need to think much about it, but now we need another wireless protocol to co-exist with the WiFi connection.
ESP-Now also uses channels, although that is where I ran into issues. If I changed the
ESP-Now channel to something other than 0 or 1, it threw errors. So either ESP-Now only
works on channel 0 (not sure what that actually is) or 1, or I just missed something
somewhere. I also had to change my router's WiFi settings to use channel 1. Without the
router change, this won't work. If someone can sort this out, let me know on Discord
1.
Make sure your MQTT broker is set up for Home Assistant. The instructions can be found in the addon inside Home Assistant. You'll probably want to follow the instructions by making a new MQTT user and configuring it as an integration. Or you can use your own and just add it as an integration. When you are done, you'll have an MQTT box in Settings > Devices & Services.
2.
For the bridge, have a look at the ESPHome YAML below.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
Setup the mqtt for your broker. You can change the Home Assistant discovery prefix (if you changed it for some reason), and it will also be used in the MQTT bridge.
3.
For our sensor device, look at the YAML below.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
The ESP-Now component is just the single line of `now_mqtt`. There's no need for the `api` or `wifi` block. The component works by waiting for each sensor to update its state. When that happens, it creates a line similar to the one explained above and sends it out as a broadcast message. No pairing is needed, but this also precludes encryption if that is important for you.
Make any changes for your particular sensors and upload the YAML through the Home Assistant ESPHome addon or the ESPHome command line. You'll start to see the scrolling of sensor measurements and notifications of sending ESP-Now messages. You'll also see those same messages in the bridge serial output, and if you are paying attention to your MQTT broker, you'll see new entries being added.
And most importantly, you'll also see the new sensor inside the MQTT section of Settings -> Devices and Services.
4.
But what can we do with this now, and how is it better than WiFi and MQTT?
Look at this slight modification of the above YAML.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
This particular device can operate on a very small 260 mAh battery for several months. 260 is quite small, so a larger battery can easily get into the year range.
5.
The sensor also has the option to get an on_sent notification. This allows you to enter deep sleep the moment all of the sensor measurements have been sent, saving awake time.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
The code creates a global variable named `sent``. Then it increases the value each time a sensor measurement is sent. If `sent`` equals 5, which in this case is the number of sensors, it goes to sleep for 5 minutes.