Automatización IoT

Guía de rtl_433 con MQTT: captura estaciones meteorológicas y contactos de puerta de 433 MHz

Convierte un dongle SDR barato en un receptor de 433 MHz con rtl_433, publica estaciones meteorológicas y contactos de puerta por MQTT y reenvía solo tus propios sensores a un broker privado con TLS.

Dongle SDR USB recibiendo señales de sensores inalámbricos y reenviándolas como mensajes rtl_433 mqtt
Pruébalo en tu propio broker MQTTConsigue un broker MQTT privado y gestionado con el plan Free y empieza con ejemplos de código listos para usar.
Pruébalo gratis Ejemplos de código Sin tarjeta

Con la salida rtl_433 MQTT, un dongle SDR USB de bajo coste se convierte en un receptor para cientos de dispositivos inalámbricos: estaciones meteorológicas, termómetros de piscina, contactos de puerta, sensores de presión de neumáticos y mucho más. En esta guía instalarás rtl_433, publicarás las lecturas decodificadas directamente en el servidor MQTT público gratuito y después construirás un pequeño relé que reenvía solo tus propios sensores a un broker privado con TLS.

Cómo funciona rtl_433

Muchos sensores económicos transmiten ráfagas cortas y sin cifrar en 433,92 MHz (u 868 MHz en partes de Europa y 915 MHz en América). No se emparejan con nada; simplemente emiten cada 30 a 60 segundos con la esperanza de que haya un receptor escuchando. rtl_433 es un programa de código abierto que escucha a través de un dongle SDR basado en RTL2832U, demodula esas ráfagas y las decodifica con más de 200 decodificadores de protocolo integrados.

Cada mensaje decodificado se convierte en un registro estructurado, por ejemplo:

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

A partir de ahí, MQTT es la forma natural de distribuirlo. La domótica, los paneles y las bases de datos se suscriben al broker en lugar de necesitar cada uno su propia radio. Si quieres repasar ese modelo, consulta qué hace un broker MQTT.

Hardware e instalación

Necesitas:

  • Un dongle SDR RTL2832U. Los modelos con TCXO (oscilador compensado en temperatura) se mantienen mejor en frecuencia a medida que se calientan.
  • La antena que venía con él, o un sencillo hilo de cuarto de onda: unos 17 cm para 433 MHz.
  • Una Raspberry Pi o cualquier máquina Linux.

En Debian o Raspberry Pi OS, el paquete está en los repositorios estándar:

sudo apt update
sudo apt install rtl-433

El driver DVB-T del kernel puede apropiarse antes del dongle. Si rtl_433 informa de que el dispositivo está ocupado, ponlo en la lista negra:

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

Ejecuta rtl_433 sin argumentos. Escucha en 433,92 MHz e imprime cada mensaje decodificado. Déjalo funcionando unos minutos y anota el model y el id de los sensores que te pertenecen; casi seguro que también verás los dispositivos de algún vecino.

Para sensores de 868 MHz, usa rtl_433 -f 868M -s 1024k.

Paso 1: enviar datos de rtl_433 a MQTT en un broker público

rtl_433 incluye una salida MQTT integrada. Para probarla, usa el servidor MQTT público gratuito en broker.connectmq.com con un prefijo de topic aleatorio; está pensado para pruebas y prototipos, no para datos de producción. Todo lo que se publica allí puede leerlo cualquiera, lo cual es aceptable para datos meteorológicos en una prueba, pero no para nada que te importe compartir.

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

Qué hacen las opciones:

Opción Significado
-C si Convierte las unidades al sistema métrico
-M time:iso Marcas de tiempo ISO 8601
mqtt://host:port Salida MQTT; mqtts:// activa TLS en el 8883
retain=0 No retener los mensajes
events=... Un mensaje JSON por lectura, en un topic ampliado con [/model] y [/id]

Observa el resultado:

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

Formato events frente a devices

rtl_433 ofrece tres formatos MQTT. events envía el registro JSON completo como un único mensaje. devices separa cada campo en su propio topic, como .../temperature_C, lo que resulta cómodo para consumidores sencillos pero multiplica el número de mensajes. states publica resúmenes periódicos de estado. En el broker público, es preferible events: te mantiene muy por debajo del límite de 10 mensajes por segundo por cliente, y la profundidad de los topics no pasa de ocho niveles.

Por defecto, rtl_433 también publica un topic availability con un online retenido y un Last Will de offline, bajo su topic base.

Paso 2: por qué producción necesita un relé

La salida integrada es estupenda para pruebas, pero tiene dos limitaciones con un broker privado:

  1. Client ID. rtl_433 genera su propio client ID (rtl_433- seguido de un hash) y no ofrece ninguna opción para fijarlo. ConnectMQ, como muchos brokers alojados, emite un client ID vinculado a tu usuario y contraseña, así que la salida integrada no puede presentarlo.
  2. Filtrado. rtl_433 publica todo lo que oye, incluidos los dispositivos de tus vecinos. Normalmente querrás una lista de permitidos.

La solución es dejar que rtl_433 escriba líneas JSON en la salida estándar y canalizarlas a un pequeño relé que publique con tus propias credenciales, client ID, estructura de topics y filtro.

Paso 3: construir el relé rtl_433 MQTT

Guarda esto como /opt/rtl/rtl_relay.py. Usa 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")

# Reenviar solo los sensores que te pertenecen: "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()

Ejecútalo en una tubería:

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

Las lecturas se retienen, así que un panel que se abra más tarde muestra de inmediato la última temperatura. El topic status indica a los consumidores si el propio receptor está vivo. Si ves que las líneas llegan en ráfagas en lugar de una a una, antepón stdbuf -oL a rtl_433 para forzar el búfer por líneas.

Elegir una estructura de topics

El relé publica cada sensor en home/rtl433/<model>/<id>, lo que mantiene los topics estables y fáciles de suscribir con comodines como home/rtl433/+/+. Si prefieres nombres más legibles, sustituye el conjunto de permitidos por un diccionario que asocie model:id a un nombre como garden o freezer, y publica en home/rtl433/garden. Los nombres legibles también facilitan sustituir un sensor averiado: actualizas una entrada del diccionario y todos los paneles siguen funcionando.

Paso 4: ejecutarlo como servicio

Crea /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

Actívalo con sudo systemctl enable --now rtl433-mqtt y sigue los logs con journalctl -u rtl433-mqtt -f. Restringe los permisos del archivo de la unidad o traslada los secretos a un EnvironmentFile que solo pueda leer root.

Errores prácticos habituales

  • Los ID cambian al cambiar la pila. Muchos sensores baratos eligen un ID aleatorio al encenderse. Guarda la lista de permitidos en un archivo de configuración para poder actualizarla rápidamente.
  • Los contactos de puerta no son dispositivos de seguridad. Los sensores de 433 MHz no están cifrados y es fácil reproducirlos o interferirlos. Úsalos para automatizaciones de comodidad, no para alarmas.
  • La ubicación de la antena importa más que el software. Las lecturas que faltan casi siempre son un problema de recepción; aleja el dongle de los puertos USB 3 y de las fuentes de alimentación ruidosas con un cable alargador corto.
  • Los duplicados son normales. La mayoría de los sensores repiten cada ráfaga varias veces. Elimina duplicados en tu consumidor si cuentas eventos.

Adónde van los datos después

Una vez que las lecturas están en el broker, cualquier cliente MQTT puede usarlas. Envíalas a una base de datos de series temporales con Telegraf, muéstralas en Grafana o combínalas con una estación ESP32 de la guía de estación meteorológica casera. Las redes Zigbee y Z-Wave pueden compartir el mismo broker; consulta la guía de Z-Wave JS UI con MQTT y la visión general de automatización IoT. La documentación del propio proyecto rtl_433, incluida la lista completa de decodificadores, está en GitHub.

Un broker MQTT gestionado como ConnectMQ encaja bien aquí: el relé mantiene una única conexión TLS saliente, los mensajes retenidos guardan la última lectura de cada sensor y las reglas de alerta por umbral del portal pueden avisarte cuando el sensor de un congelador se calienta demasiado.

Lleva tus sensores de 433 MHz a ConnectMQ

Crea gratis un broker Serverless en app.connectmq.com sin tarjeta de crédito, copia el usuario, la contraseña y el client ID generados en el entorno del relé y observa cómo aparecen tus sensores en el explorador de topics en vivo.

Preguntas frecuentes

¿rtl_433 admite MQTT de forma nativa?

Sí. La salida -F mqtt://host:port,... publica eventos, topics de dispositivo por campo o estados, y mqtts:// activa TLS. No permite fijar el client ID, por eso un relé resulta útil con brokers que vinculan los client ID a las credenciales.

¿Qué dongle SDR funciona con rtl_433?

Funciona cualquier dongle basado en RTL2832U. Los modelos con oscilador compensado en temperatura se mantienen mejor en frecuencia con el tiempo.

¿Cómo evito que rtl_433 publique los sensores de mis vecinos?

Filtra por model e id. El relé de esta guía solo reenvía una lista de permitidos con los sensores que te pertenecen.

¿Puede rtl_433 recibir sensores de 868 MHz?

Sí. Inícialo con -f 868M -s 1024k, siempre que tu dongle y tu antena cubran esa banda.

Artículos relacionados

Guía para configurar Zigbee2MQTT: del coordinador al panel

Instala Zigbee2MQTT con Docker, configura el coordinador y la conexión MQTT, empareja y renombra dispositivos, contrólalos por MQTT y consulta sus estados en un panel, probando primero en un servidor MQTT público gratuito.

8 min de lectura

Todos los artículos →

Tu broker MQTT privado, a unos pocos clics

Crea una cuenta, obtén las credenciales de tu broker y conecta tu primer dispositivo, sin servidores que instalar, parchear ni escalar.