Skip to main content

MQTT & home automation

rtl_433 is a C command-line decoder for ISM-band devices (433.92 / 315 / 345 / 868 / 915 MHz) received through RTL-SDR or SoapySDR hardware. Once a device is decoded, the data does not have to stay on the console: the -F (output format) flag can stream every event straight to an MQTT broker, an InfluxDB time-series database, syslog, or a flat file. This page covers the MQTT output driver and its topic structure, how those topics flow into Home Assistant, and how to feed the same stream into InfluxDB and Grafana.

note

All output drivers can run at the same time. You may pass -F more than once — for example -F mqtt -F "influx://..." — so the same decode is published to MQTT and written to InfluxDB in a single rtl_433 process. Without any -F option the default output is log and kv (key/value records) on the console; adding an explicit -F does not remove that default unless you also pass -F null.

The -F output formats

rtl_433 -F help prints the supported output drivers. The full set is:

[ -F log | kv | json | csv | mqtt | influx | syslog | trigger | rtl_tcp | http | null | help ]

Most drivers accept an optional :<filename> (write to a file, e.g. -F csv:log.csv) or a network target. The three drivers relevant to home automation are mqtt, influx, and the JSON payloads they carry.

MQTT output (-F mqtt)

The MQTT driver connects to a broker and publishes each decoded event as a JSON message. The verified syntax is:

-F mqtt[s][:[//]host[:port][,<options>]]

The default target is localhost:1883. Use mqtts instead of mqtt to open a TLS connection. A minimal local invocation:

rtl_433 -F mqtt

An explicit broker with authentication and an unretained event topic:

rtl_433 -F "mqtt://localhost:1883,user=USERNAME,pass=PASSWORD,retain=0,devices=rtl_433[/id]"
tip

Credentials can be kept out of process listings and shell history by exporting the MQTT_USERNAME and MQTT_PASSWORD environment variables instead of inlining user= / pass=. The driver reads them automatically when the inline options are absent.

MQTT options

The options after the comma configure the connection and which topics are published.

OptionPurposeDefault
user=<name>Broker username(none)
pass=<secret>Broker password(none)
retain[=0|1]Set the MQTT retain flag on published messages0
qos=<n>MQTT quality-of-service levelbroker default
base=<topic>Root topic prefix for all sub-topicsrtl_433/HOSTNAME
availabilityPublish an online/offline availability message<base>/availability
eventsPublish the full JSON event<base>/events
statesPublish JSON state data<base>/states
devicesPublish per-device nested topics<base>/devices[/type][/model][/subtype][/channel][/id]

For TLS connections (mqtts), the certificate options are:

rtl_433 -F "mqtts://broker,tls_cert=<path>,tls_key=<path>,tls_ca_cert=<path>"

Topic structure

The events and states topics carry the complete event as a single JSON document, which is convenient for logging and for consumers that parse JSON themselves. The devices topic instead expands a template into a topic hierarchy, where the bracketed placeholders are filled in from the decoded fields and dropped when a field is absent:

<base>/devices[/type][/model][/subtype][/channel][/id]

So a thermo-hygrometer reported as model Prologue-TH with subtype 5, on channel 1, with id 9, on a host named debian publishes under a topic such as:

rtl_433/debian/devices/Prologue-TH/5/1/9/temperature_C

Each individual measurement (temperature_C, humidity, battery_ok, …) becomes its own leaf topic carrying a plain scalar value. That one-value-per-topic layout is what makes the devices form ideal for dashboards and for Home Assistant's MQTT sensor configuration.

info

Field names follow the rtl_433 data model: sensor readings use a <Type>_<Unit> convention (temperature_C, pressure_hPa, wind_avg_km_h), and battery health is reported as battery_ok in the range 0–1. Pass -C si or -C customary to convert units at the source (for example to add temperature_F).

Home Assistant integration

There are two common ways to bring rtl_433 events into Home Assistant over MQTT.

1. Manual MQTT sensors. Point rtl_433 at the same broker Home Assistant uses, publish with the devices topic template so each measurement is its own leaf topic, then declare HA mqtt sensors that subscribe to those topics. Because each topic holds a bare value, no JSON template is required:

# Illustrative example — Home Assistant configuration.yaml
mqtt:
sensor:
- name: "Backyard Temperature"
state_topic: "rtl_433/debian/devices/Prologue-TH/5/1/9/temperature_C"
unit_of_measurement: "°C"
device_class: temperature
- name: "Backyard Humidity"
state_topic: "rtl_433/debian/devices/Prologue-TH/5/1/9/humidity"
unit_of_measurement: "%"
device_class: humidity

2. MQTT auto-discovery. Instead of hand-writing sensors, a bridge script subscribes to the rtl_433 JSON event topic (<base>/events) and republishes Home Assistant MQTT Discovery config messages, so new 433 MHz sensors appear automatically as devices with separate temperature, humidity, and battery entities. The rtl_433 project ships a companion helper for exactly this pattern in its examples/ folder, and the community maintains a Home Assistant add-on that packages rtl_433 with auto-discovery.

tip

Run rtl_433 with the JSON event topic enabled (-F mqtt, which publishes <base>/events) when using an auto-discovery bridge — the bridge needs the full JSON document to derive entity names, units, and device classes, which the per-leaf devices topics do not carry.

InfluxDB & Grafana pipelines

For long-term storage and graphing, write the same events to InfluxDB and visualize with Grafana. rtl_433 has a native influx output driver, so no MQTT hop is required for the time-series path.

For InfluxDB 2.x (line-protocol write API), the verified syntax is:

rtl_433 -F "influx://localhost:9999/api/v2/write?org=<org>&bucket=<bucket>,token=<authtoken>"

For InfluxDB 1.x:

rtl_433 -F "influx://localhost:8086/write?db=<db>&p=<password>&u=<user>"

A typical home-automation host runs all three outputs at once — console for debugging, MQTT for Home Assistant, and InfluxDB for history:

# Illustrative example — one process, three sinks
rtl_433 -F log \
-F "mqtt://broker.local,user=rtl,pass=secret,devices=rtl_433[/id]" \
-F "influx://influx.local:9999/api/v2/write?org=home&bucket=sensors,token=$INFLUX_TOKEN"

Once data lands in InfluxDB, Grafana reads it through its InfluxDB data source — the rtl_433 docs note that Grafana is supported via the InfluxDB output pipeline rather than a direct driver. From there you build panels on fields such as temperature_C, humidity, and battery_ok.

note

The rtl_433 documentation describes these network outputs as intended for a trusted local network — they make no inherent security guarantees. Put the broker, InfluxDB, and Grafana behind your LAN or a VPN, and use mqtts with TLS certificates when crossing untrusted segments.

Sources