I’ve had an Acurite Access and some sensors for a couple years, but it bugged me that I couldn’t get this data into Home Assistant, so I finally did something about that.
- Edit 2021-06-24: Modified to have rtl_433 publish to individual topics and removed demux step
This is a complete end-to-end guide of setting up rtl_433 on a Raspberry Pi to read data into MQTT and then into Home Assistant sensors.
For reference, I’m using:
- A Raspberry Pi 2B v1.1 (which also runs my secondary Pihole DNS server)
- A $8 RTL2832U USB tuner (identifies as
ID 0bda:2838 Realtek Semiconductor Corp. RTL2838 DVB-T
)
- Home Assistant and MQTT run on other virtual machines
- My own 3 Acurite Tower temp+humidity sensors, plus a neighbor’s nearby 5-in-1 weather station and another 3-in-1 station.
A lot of this is based on John’s Tech Blog: 433 MHz Signals and Shit
so much thanks to him!
rtl_433 Setup
Building
sudo apt-get install git libtool libusb-1.0.0-dev librtlsdr-dev rtl-sdr build-essential autoconf cmake pkg-config
git clone https://github.com/merbanan/rtl_433.git
cd rtl_433/
mkdir build
cd build
cmake ..
make
sudo make install
Running rtl_433
To test it out, simply run rtl_433
, and if successful you should start seeing sensor data:
It’s pretty simple then to connect it to MQTT:
rtl_433 -F json -M utc -F mqtt://your_mqtt_server,retain=0,events=rtl_433[/model][/id]
You can also specify user=foo,pass=bar
in that connection string.
This streams all sensors to one based on their model and unique id, so for example, rtl_433/Acurite-Tower/8958
.
Running as a service
Create a systemd unit file, and move all the command-line options to a config file to make it easier to deal with:
/etc/systemd/system/rtl_433.service
:
# based on https://github.com/merbanan/rtl_433/issues/1651
[Unit]
Description=RTL_433 service script
StartLimitIntervalSec=5
Documentation=https://github.com/merbanan/rtl_433/README.md
After=syslog.target network.target
[Service]
Type=exec
ExecStart=/usr/local/bin/rtl_433 -c /etc/rtl_433/service.conf
# Restart script if stopped
Restart=always
# Wait 30s before restart
RestartSec=30s
# Tag things in the log
# View with: sudo journalctl -f -u rtl_433 -o cat
SyslogIdentifier=rtl_433
StandardOutput=syslog
StandardError=syslog
[Install]
WantedBy=multi-user.target
/etc/rtl_433/service.conf
:
output json
output mqtt://your_mqtt_server,retain=0,events=rtl_433[/model][/id]
report_meta time:utc
Now you can start with sudo systemctl start rtl_433
and manage it like any other service, and it should auto-start on boot.
Payload Examples
rtl_433/Acurite-Tower/8958
Publishes about every 15-20 seconds:
{
"time":"2021-06-14 03:31:05",
"model":"Acurite-Tower",
"id":8958,
"channel":"A",
"battery_ok":0,
"temperature_C":19.4,
"humidity":41,
"mic":"CHECKSUM"
}
rtl_433/Acurite-5n1/1908
This publishes about every 15-20 seconds, but alternates between two payloads:
{
"time":"2021-06-14 03:24:57",
"model":"Acurite-3n1",
"message_type":32,
"id":824,
"channel":"A",
"sequence_num":0,
"battery_ok":1,
"wind_avg_mi_h":0,
"temperature_F":64.8,
"humidity":87,
"mic":"CHECKSUM"
}
{
"time":"2021-06-14 03:25:17",
"model":"Acurite-5n1",
"message_type":49,
"id":1908,
"channel":"B",
"sequence_num":0,
"battery_ok":1,
"wind_avg_km_h":2.6556,
"wind_dir_deg":202.5,
"rain_in":20.43,
"mic":"CHECKSUM"
}
rtl_433/Acurite-3n1/824
{
"time":"2021-06-14 03:43:01",
"model":"Acurite-3n1",
"message_type":32,
"id":824,
"channel":"A",
"sequence_num":0,
"battery_ok":1,
"wind_avg_mi_h":0,
"temperature_F":64.8,
"humidity":88,
"mic":"CHECKSUM"
}
Home Assistant Config
Optional: Handling message_type
As mentioned above, the “5n1” sensor publishes two different payloads, and this causes some problems. If you are using a sensor value of anything that doesn’t appear in both mesages (such as wind_dir_deg
) it will be unavailable 50% of the time, and same if you’re making use of any attributes on a dashboard. It also just means the attributes constantly change between the two payloads, which is annoying if nothing else.
If you don’t have sensors that do this (or don’t care), this step can be skipped.
Unfortunately, rtl_433 isn’t aware of the message_type
property so can’t handle this natively, but we can use an automation to re-publish these messages to a new topic:
- id: '1624586003695'
alias: RTL433 MQTT message_type Demuxer
description: Split rtl_433/# signals into msg topics, if message_type exists
trigger:
- platform: mqtt
topic: rtl_433/+/+
condition:
- condition: template
value_template: '{{ trigger.payload_json.message_type != null }}'
action:
- service: mqtt.publish
data:
payload: '{{trigger.payload}}'
topic: rtl_433/{{trigger.payload_json.model or "UnknownModel"}}/{{trigger.payload_json.id
or "UnknownId"}}/msg{{trigger.payload_json.message_type}}
mode: single
If a message is received that has a message_type
value, it is republished to a topic such as rtl_433/Acurite-5n1/1908/msg56
. This can be used within the HomeAssistant sensor configuration to avoid all the issues I mentioned.
Sensors
Now getting these back into normal sensors is pretty simple:
- platform: mqtt
name: Outside Temperature (Deck)
device_class: temperature
unit_of_measurement: '°C'
value_template: '{{ value_json.temperature_C }}'
state_topic: rtl_433/Acurite-Tower/8958
json_attributes_topic: rtl_433/Acurite-Tower/8958
- platform: mqtt
name: Outside Temperature
device_class: temperature
unit_of_measurement: '°C'
value_template: '{{ ((value_json.temperature_F - 32) * 5/9) | round(1) }}'
state_topic: rtl_433/Acurite-5n1/1908/msg56
json_attributes_topic: rtl_433/Acurite-5n1/1908/msg56
- platform: mqtt
name: Outside Humidity
device_class: humidity
value_template: '{{ value_json.humidity }}'
state_topic: rtl_433/Acurite-5n1/1908/msg56
- platform: mqtt
name: Outside Wind
unit_of_measurement: 'km/h'
value_template: '{{ value_json.wind_avg_km_h | round(1) }}'
state_topic: rtl_433/Acurite-5n1/1908/msg49
json_attributes_topic: rtl_433/Acurite-5n1/1908/msg49
The sensors are usable just like any other, and include a bunch of extra attributes if you want to make use of those: