Unlocking Budget Sensors: Integrating RTL_433 with Home Assistant via MQTT
- #RTL_433
- #MQTT
- #Home_Assistant
- #Sensors
- #RF
- #SDR

Unlocking Budget Sensors: Integrating RTL_433 with Home Assistant via MQTT
Building a comprehensive smart home often involves deploying various sensors for temperature, humidity, door/window status, and more. While many commercial smart home sensors exist, they can become expensive quickly, especially when deploying dozens throughout a property. Fortunately, there's a vast ecosystem of low-cost wireless sensors operating in the 433.92 MHz (and other sub-GHz) bands, often used in consumer devices like weather stations, tire pressure monitors, and cheap alarm sensors.
Enter RTL_433. This powerful software, combined with an inexpensive RTL-SDR (Software Defined Radio) USB dongle, can listen to and decode signals from hundreds of these devices. By piping this decoded data into Home Assistant via MQTT, you can integrate these budget-friendly sensors seamlessly into your automation platform.
What is RTL_433 and Why Use It?
RTL_433 is a generic receiver for 433.92MHz, 868MHz, 315MHz, 303MHz, and other frequencies. It specifically targets devices that don't adhere to standard protocols like Zigbee or Z-Wave, often using simple OOK (On-Off Keying) or FSK (Frequency-Shift Keying) modulation. With an RTL-SDR dongle (commonly available for $10-$30), RTL_433 can receive these signals and decode their payloads into structured data like JSON.
The benefits for a smart home user are significant:
- Cost Savings: Integrate existing or new low-cost sensors (e.g., from Ambient Weather, AcuRite, La Crosse Technology, various alarm sensors).
- Device Variety: Access sensor types not commonly found in standard smart home ecosystems (e.g., tire pressure, soil moisture sensors, specific environmental monitors).
- Local Control: Data is received and processed locally, reducing reliance on manufacturer cloud services.
Prerequisites
To follow this guide, you'll need:
- An RTL-SDR USB dongle (e.g., an RTLSDR v3 is recommended).
- A machine to run RTL_433 (a Raspberry Pi, an old PC, or even the Home Assistant machine itself if it's running Linux or a supported OS). For stability and placement flexibility, a separate low-power machine like a Raspberry Pi is often ideal.
- An MQTT Broker accessible from both the RTL_433 machine and Home Assistant. The Mosquitto Add-on in Home Assistant is a popular choice.
- A running Home Assistant instance.
Step 1: Setting up RTL_433
We'll assume you're setting this up on a Debian-based Linux system like Raspberry Pi OS.
1. Install Dependencies and RTL_433:
sudo apt update
sudo apt install git cmake libusb-1.0-0-dev
git clone https://github.com/merbanan/rtl_433.git
cd rtl_433
cmake .
make
sudo make install
sudo ldconfig
This compiles and installs the latest version from source, which is often recommended for access to the newest device decoders. Alternatively, you might be able to install via package manager:
sudo apt install rtl-433
2. Test the RTL-SDR Dongle and RTL_433:
Plug in the RTL-SDR dongle. You may need to blacklist the default DVB-T drivers to prevent them from claiming the device. Create a file like /etc/modprobe.d/blacklist-rtl.conf
with the following content:
blacklist dvb_usb_rtl28xxu
blacklist rtl2832
blacklist rtl2830
Then reboot or run sudo rmmod dvb_usb_rtl28xxu rtl2832 rtl2830
.
Run RTL_433 without specific parameters to see if it detects the dongle and starts listening:
rtl_433
You should see output indicating it's scanning frequencies and potentially decoding messages if sensors are transmitting nearby.
Step 2: Configuring RTL_433 for MQTT Output
RTL_433 can output data in various formats. For Home Assistant integration, JSON output sent via MQTT is the most flexible.
Identify the protocol IDs you want to listen for. You can run rtl_433 -A
to listen on common frequencies and identify devices transmitting nearby, which often shows the protocol ID. Alternatively, search the RTL_433 documentation or online forums for the specific sensors you have.
Here's an example command to run RTL_433, focusing on specific protocols and sending data to MQTT:
rtl_433 -F json -M utc -M newmodel -T 60 -R 40 -R 10 -R 35 -M level -C customary mqtt://<mqtt_broker_ip>:<port> -u <mqtt_username> -P <mqtt_password> -t rtl_433/+/devices/[model]/[id] -H 600
Let's break down the options:
-F json
: Output data as JSON.-M utc
: Report timestamps in UTC.-M newmodel
: Include a 'model' field in the JSON output, useful for templating in HA.-T 60
: Report the same device only once every 60 seconds (adjust as needed, prevents spamming MQTT).-R 40 -R 10 -R 35
: Enable specific decoders (replace with your device IDs). Remove this option to enable ALL supported decoders (can be noisy).-M level
: Include signal level information (useful for debugging placement).-C customary
: Use customary units (Fahrenheit, inches, etc.) instead of metric (Celsius, meters) if preferred. Omit for metric.mqtt://<mqtt_broker_ip>:<port>
: Your MQTT broker address and port (usually 1883).-u <mqtt_username> -P <mqtt_password>
: Your MQTT broker credentials.-t rtl_433/+/devices/[model]/[id]
: Defines the MQTT topic structure.+
is a wildcard for the system hostname running rtl_433.[model]
and[id]
are substituted by rtl_433 based on the decoded message. This creates unique topics per device.-H 600
: Publish a status message every 600 seconds (10 minutes), indicating rtl_433 is running.
Running as a Service: For reliability, run this command as a systemd service or similar, ensuring it starts on boot and restarts if it crashes.
[Unit]
Description=RTL_433 MQTT Service
After=network.target
[Service]
ExecStart=/usr/local/bin/rtl_433 -F json -M utc -M newmodel -T 60 -R 40 -R 10 -R 35 -M level -C customary mqtt://<mqtt_broker_ip>:1883 -u <mqtt_username> -P <mqtt_password> -t rtl_433/+/devices/[model]/[id] -H 600
Restart=on-failure
User=pi # Or your system's user
[Install]
WantedBy=multi-user.target
Save this as /etc/systemd/system/rtl_433_mqtt.service
(adjust path to rtl_433 binary if needed), then run:
sudo systemctl daemon-reload
sudo systemctl enable rtl_433_mqtt
sudo systemctl start rtl_433_mqtt
sudo systemctl status rtl_433_mqtt
Step 3: Setting up MQTT in Home Assistant
Ensure the MQTT integration is set up in Home Assistant. If using the Mosquitto Add-on, this is usually straightforward. Configure the integration via the UI (Settings -> Devices & Services -> Add Integration -> MQTT), pointing it to your broker and providing credentials.
You can use an MQTT explorer tool (like MQTT Explorer) to connect to your broker and see the messages being published by rtl_433 under the rtl_433/+/#
topics. This is crucial for understanding the message structure and topics for the next step.
Step 4: Integrating Devices in Home Assistant
Since rtl_433 doesn't natively support Home Assistant's MQTT Discovery, you'll typically need to configure devices manually in your Home Assistant configuration.yaml
or split configuration files.
Using the output from your MQTT explorer, examine the JSON payload for your devices. For example, a temperature/humidity sensor might publish something like:
{
"time": "2023-10-27 10:00:00",
"model": "Acurite-00275",
"id": 12345,
"channel": 1,
"temperature_F": 72.5,
"humidity": 45,
"battery_ok": 1,
"mic": "CRC"
}
You can define MQTT sensors in Home Assistant to extract this data:
# In configuration.yaml or a sensors file included from it
mqtt:
sensor:
- name: "Outdoor Temperature"
state_topic: "rtl_433/+/devices/Acurite-00275/12345" # Adjust topic based on your setup
unit_of_measurement: "°F" # Or "°C" if using metric
value_template: "{{ value_json.temperature_F | is_number | default(0) }}" # Safely extract value
device_class: "temperature"
state_class: "measurement"
unique_id: acurite_00275_12345_temperature
expire_after: 3600 # Mark unavailable after 1 hour of no updates
- name: "Outdoor Humidity"
state_topic: "rtl_433/+/devices/Acurite-00275/12345"
unit_of_measurement: "%"
value_template: "{{ value_json.humidity | is_number | default(0) }}"
device_class: "humidity"
state_class: "measurement"
unique_id: acurite_00275_12345_humidity
expire_after: 3600
- name: "Outdoor Battery"
state_topic: "rtl_433/+/devices/Acurite-00275/12345"
value_template: "{{ 'OK' if value_json.battery_ok | int(0) == 1 else 'Low' }}"
unique_id: acurite_00275_12345_battery
expire_after: 3600
Explanation of Configuration:
name
: Friendly name for the sensor in Home Assistant.state_topic
: The exact MQTT topic where the device's JSON payload is published. Use the wildcard+
for the hostname if you used it in the rtl_433 command.unit_of_measurement
: Specifies the unit (essential for graphs and dashboards).value_template
: A Jinja2 template that extracts the desired value from the incoming JSON payload (accessed via thevalue_json
variable).| is_number | default(0)
is a safe way to handle missing or non-numeric values.device_class
,state_class
: Provide hints to Home Assistant for better presentation and long-term statistics.unique_id
: A unique identifier for this sensor entity. Required if you want to manage the entity via the UI after creation. Use a consistent pattern including the model and device ID.expire_after
: (Recommended) If a sensor stops transmitting, this will mark the entity as unavailable after the specified time (in seconds), helping you identify offline devices.
For binary sensors (like door/window contacts):
mqtt:
binary_sensor:
- name: "Garage Door Sensor"
state_topic: "rtl_433/+/devices/Generic-Magnetic-Contact/67890"
payload_on: "CLOSED" # Or whatever value rtl_433 sends when closed
payload_off: "OPEN" # Or whatever value rtl_433 sends when open
value_template: "{{ value_json.state }}" # Adjust based on your payload structure
device_class: "door"
unique_id: generic_contact_67890_door
expire_after: 86400 # Contact sensors might report less often, adjust timeout
After adding configurations, check Home Assistant's configuration (Developer Tools -> YAML -> Check Configuration) and restart Home Assistant (Settings -> System -> Restart) to apply the changes.
Device Integration Tips
- Identify Devices: Run
rtl_433 -A
to discover what's transmitting around you. This helps identify device types and frequencies. - Filtering: Start by listening to all protocols (omit
-R
) to see everything. Then, use-R
with specific protocol IDs to reduce noise and CPU load once you've identified your devices. - Topic Structure: The
-t
option in rtl_433 is flexible. Choose a topic structure that makes sense for you, preferably one that includes the device model and ID for easy identification in Home Assistant. - Parsing Payloads: Use MQTT Explorer to view the exact JSON payload for your devices. This is essential for writing correct
value_template
expressions. Remember Jinja2 syntax and filters (likevalue_json.field_name
,| int
,| float
,| is_number
,| default
). - Device IDs: Be aware that some very cheap sensors might occasionally change their ID after a battery change. Consider if this is a risk for critical automations.
Best Practices for Managing a Reliable System
- Stable Hardware: Use a reliable power supply for your RTL-SDR machine and ensure the dongle has adequate cooling if running continuously in a warm environment.
- Antenna Placement: The range of sub-GHz signals is decent but affected by walls and interference. Experiment with dongle/antenna placement for optimal reception. A small extension cable can help position the dongle away from the computer's USB noise.
- Monitor RTL_433: Ensure the rtl_433 service is running reliably on your separate machine. Set up monitoring (e.g., using Glances or simple scripts) and alerting if the service stops.
- Monitor MQTT: Use the Home Assistant MQTT integration's status or external tools to ensure Home Assistant is connected to the broker.
- Use
expire_after
: This is crucial for sensor reliability. If a sensor fails or goes out of range,expire_after
will mark its entity as unavailable in Home Assistant, allowing you to detect issues. - Separate Configuration: Put your rtl_433 MQTT sensor configurations into a separate file (e.g.,
mqtt_rtl_433_sensors.yaml
) and include it fromconfiguration.yaml
usingmqtt: !include mqtt_rtl_433_sensors.yaml
. This keeps your main configuration file clean.
Conclusion
Integrating RTL_433 with Home Assistant via MQTT opens up a wealth of possibilities for incorporating low-cost wireless sensors into your smart home. While it requires a bit more technical setup than plug-and-play devices, the ability to decode and utilize data from a wide range of inexpensive sensors offers significant value and flexibility. By following these steps and best practices, you can build a more comprehensive, data-rich, and cost-effective smart home ecosystem.

NGC 224
Author bio: