IoT Automation

rtl_433 MQTT Guide: Capture 433 MHz Weather Sensors and Door Contacts

Turn a cheap SDR dongle into a 433 MHz receiver with rtl_433, publish weather stations and door contacts over MQTT, and relay only your own sensors to a private broker over TLS.

USB SDR dongle receiving wireless sensor signals and forwarding them as rtl_433 mqtt messages
Run this on your own MQTT brokerGet a private, managed MQTT broker on the Free plan and start from ready-made code samples.
Try it free Code samples No card required

With rtl_433 MQTT output, a low-cost USB SDR dongle becomes a receiver for hundreds of wireless devices: weather stations, pool thermometers, door contacts, tyre pressure sensors and more. In this guide you will install rtl_433, publish decoded readings straight to a public test broker, and then build a small relay that forwards only your own sensors to a private broker over TLS.

How rtl_433 Works

Many inexpensive sensors transmit short, unencrypted bursts on 433.92 MHz (or 868 MHz in parts of Europe, 915 MHz in the Americas). They do not pair with anything; they simply broadcast every 30 to 60 seconds and hope a receiver is listening. rtl_433 is an open-source program that listens through an RTL2832U-based SDR dongle, demodulates those bursts and decodes them with more than 200 built-in protocol decoders.

Each decoded message becomes a structured record, for example:

{"time":"2026-10-16T09:41:07","model":"Acurite-Tower","id":11524,"channel":"A","battery_ok":1,"temperature_C":18.4,"humidity":61}

From there, MQTT is the natural way to distribute it. Home automation, dashboards and databases all subscribe to the broker instead of each needing their own radio. If you want a refresher on that model, see what an MQTT broker does.

Hardware and Installation

You need:

  • An RTL2832U SDR dongle. Models with a TCXO (temperature-compensated oscillator) stay on frequency better as they warm up.
  • The antenna that came with it, or a simple quarter-wave wire: about 17 cm for 433 MHz.
  • A Raspberry Pi or any Linux machine.

On Debian or Raspberry Pi OS, the package is in the standard repositories:

sudo apt update
sudo apt install rtl-433

The kernel's DVB-T driver can claim the dongle first. If rtl_433 reports that the device is busy, blacklist it:

echo 'blacklist dvb_usb_rtl28xxu' | sudo tee /etc/modprobe.d/blacklist-rtl.conf
sudo modprobe -r dvb_usb_rtl28xxu

Run rtl_433 with no arguments. It listens on 433.92 MHz and prints every decoded message. Leave it running for a few minutes and note the model and id of the sensors you own; you will almost certainly see a neighbour's devices too.

For 868 MHz sensors, use rtl_433 -f 868M -s 1024k.

Step 1: Send rtl_433 Data to MQTT on a Public Broker

rtl_433 has a built-in MQTT output. To try it, use the free public MQTT broker at broker.connectmq.com with a random topic prefix. Everything there is readable by anyone, which is acceptable for weather data in a test but not for anything you would mind sharing.

rtl_433 -C si -M time:iso \
  -F "mqtt://broker.connectmq.com:1883,retain=0,events=connectmq/demo/r5n2xc/rtl[/model][/id]"

What the options do:

Option Meaning
-C si Convert units to metric
-M time:iso ISO 8601 timestamps
mqtt://host:port MQTT output; mqtts:// enables TLS on 8883
retain=0 Do not retain messages
events=... One JSON message per reading, on a topic expanded with [/model] and [/id]

Watch the result:

mosquitto_sub -h broker.connectmq.com -p 1883 -i watch-r5n2xc \
  -t 'connectmq/demo/r5n2xc/#' -v

events vs devices format

rtl_433 offers three MQTT formats. events sends the whole JSON record as one message. devices splits every field into its own topic, such as .../temperature_C, which is convenient for simple consumers but multiplies the message count. states publishes periodic state summaries. On the public broker, prefer events: it keeps you well under the limit of 10 messages per second per client, and the topic depth stays within eight levels.

By default rtl_433 also publishes an availability topic with a retained online and a Last Will of offline, under its base topic.

Step 2: Why Production Needs a Relay

The built-in output is great for testing, but it has two limits for a private broker:

  1. Client ID. rtl_433 generates its own client ID (rtl_433- followed by a hash) and offers no option to set it. ConnectMQ, like many hosted brokers, issues a client ID bound to your username and password, so the built-in output cannot present it.
  2. Filtering. rtl_433 publishes everything it hears, including your neighbours' devices. You usually want an allowlist.

The solution is to let rtl_433 write JSON lines to standard output and pipe them into a small relay that publishes with your own credentials, client ID, topic layout and filter.

Step 3: Build the rtl_433 MQTT Relay

Save this as /opt/rtl/rtl_relay.py. It uses paho-mqtt 2.x:

#!/usr/bin/env python3
import json
import os
import sys

import paho.mqtt.client as mqtt

HOST = os.getenv("MQTT_HOST", "broker.connectmq.com")
PORT = int(os.getenv("MQTT_PORT", "8883"))
USER = os.environ["MQTT_USER"]
PASSWORD = os.environ["MQTT_PASSWORD"]
CLIENT_ID = os.environ["MQTT_CLIENT_ID"]
BASE = os.getenv("MQTT_BASE", "home/rtl433")

# Only forward sensors you own: "model:id"
ALLOW = {"Acurite-Tower:11524", "Generic-Remote:4521"}

def on_connect(client, userdata, flags, reason_code, properties):
    print("connected:", reason_code, flush=True)
    client.publish(f"{BASE}/status", "online", qos=1, retain=True)

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID)
client.username_pw_set(USER, PASSWORD)
client.tls_set()
client.will_set(f"{BASE}/status", "offline", qos=1, retain=True)
client.on_connect = on_connect
client.reconnect_delay_set(min_delay=1, max_delay=60)
client.connect(HOST, PORT, keepalive=60)
client.loop_start()

for line in sys.stdin:
    line = line.strip()
    if not line.startswith("{"):
        continue
    try:
        msg = json.loads(line)
    except ValueError:
        continue
    key = f"{msg.get('model')}:{msg.get('id')}"
    if key not in ALLOW:
        continue
    topic = f"{BASE}/{msg['model']}/{msg['id']}"
    client.publish(topic, json.dumps(msg), qos=1, retain=True)

client.loop_stop()
client.disconnect()

Run it in a pipe:

export MQTT_USER=YOUR_USERNAME MQTT_PASSWORD=YOUR_PASSWORD MQTT_CLIENT_ID=YOUR_CLIENT_ID
rtl_433 -C si -M time:iso -F json | python3 /opt/rtl/rtl_relay.py

Readings are retained, so a dashboard that opens later still shows the last temperature immediately. The status topic tells consumers whether the receiver itself is alive. If you see lines arriving in bursts rather than one by one, put stdbuf -oL in front of rtl_433 to force line buffering.

Choosing a topic layout

The relay publishes each sensor to home/rtl433/<model>/<id>, which keeps topics stable and easy to subscribe to with wildcards such as home/rtl433/+/+. If you prefer friendlier names, replace the allowlist set with a dictionary that maps model:id to a name like garden or freezer, and publish to home/rtl433/garden instead. Friendly names also make it painless to swap a dead sensor: update one dictionary entry, and every dashboard keeps working.

Step 4: Run It as a Service

Create /etc/systemd/system/rtl433-mqtt.service:

[Unit]
Description=rtl_433 to MQTT relay
After=network-online.target
Wants=network-online.target

[Service]
Environment=MQTT_USER=YOUR_USERNAME
Environment=MQTT_PASSWORD=YOUR_PASSWORD
Environment=MQTT_CLIENT_ID=YOUR_CLIENT_ID
ExecStart=/bin/sh -c 'stdbuf -oL rtl_433 -C si -M time:iso -F json | /usr/bin/python3 /opt/rtl/rtl_relay.py'
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Enable it with sudo systemctl enable --now rtl433-mqtt and follow logs with journalctl -u rtl433-mqtt -f. Restrict the unit file's permissions, or move the secrets to an EnvironmentFile readable only by root.

Practical Pitfalls

  • IDs change after a battery swap. Many cheap sensors pick a random ID at power-up. Keep the allowlist in a config file so updating it is quick.
  • Door contacts are not security devices. 433 MHz sensors are unencrypted and easy to replay or jam. Use them for convenience automations, not alarms.
  • Antenna placement beats software. Missing readings are almost always a reception problem; move the dongle away from USB 3 ports and noisy power supplies with a short extension cable.
  • Duplicates are normal. Most sensors repeat each burst several times. Deduplicate in your consumer if you count events.

Where the Data Goes Next

Once readings are on the broker, any MQTT client can use them. Feed them into a time-series database with Telegraf, show them in Grafana, or combine them with an ESP32 station from the DIY weather station guide. Zigbee and Z-Wave networks can share the same broker; see the Z-Wave JS UI MQTT guide and the IoT automation overview. The rtl_433 project's own documentation, including the full list of decoders, is on GitHub.

A hosted MQTT broker such as ConnectMQ is a good fit here: the relay keeps one outbound TLS connection, retained messages hold the latest reading for each sensor, and the portal's threshold alert rules can flag a freezer sensor that drifts too warm.

Put Your 433 MHz Sensors on ConnectMQ

Create a free Serverless broker at app.connectmq.com with no credit card, copy the generated username, password and client ID into the relay's environment, and watch your sensors appear in the live topic explorer.

Frequently Asked Questions

Does rtl_433 support MQTT natively?

Yes. The -F mqtt://host:port,... output publishes events, per-field device topics or states, and mqtts:// enables TLS. It does not let you set the client ID, which is why a relay is useful for brokers that bind client IDs to credentials.

Which SDR dongle works with rtl_433?

Any RTL2832U-based dongle works. Models with a temperature-compensated oscillator stay on frequency better over time.

How do I stop rtl_433 publishing my neighbours' sensors?

Filter by model and id. The relay in this guide forwards only an allowlist of sensors you own.

Can rtl_433 receive 868 MHz sensors?

Yes. Start it with -f 868M -s 1024k, provided your dongle and antenna cover that band.

Related articles

Zigbee2MQTT Setup Guide: From Coordinator to Dashboard

Install Zigbee2MQTT with Docker, configure the coordinator and MQTT connection, pair and rename devices, control them over MQTT and view their states on a dashboard, testing first on a free public broker.

7 min read

All articles →

Your private MQTT broker is a few clicks away

Create an account, get your broker credentials and connect your first device — no servers to install, patch or scale.