Tutoriales

Dispositivos Shelly y MQTT: configuración, topics y RPC

Conecta dispositivos Shelly Gen1 y Gen2/Plus/Pro a un broker MQTT: ajustes, TLS, estructura de topics, comandos de control y RPC sobre MQTT, con pruebas.

Actualizado · 8 min de lectura

Dispositivos Shelly y MQTT: configuración, topics y RPC

Los dispositivos Shelly hablan MQTT de forma nativa: abres la interfaz web del dispositivo, activas MQTT, introduces host, puerto y credenciales de tu broker, y el relé empieza a publicar su estado y a aceptar comandos. Lo que cambia es la estructura de topics. Los Gen1 (Shelly 1, 2.5, Plug S, H&T…) usan un árbol fijo shellies/... con comandos en texto plano, mientras que los Gen2, Plus, Pro y Gen3 usan una API JSON-RPC que puedes invocar por MQTT.

Este tutorial cubre ambas generaciones: los ajustes, los topics que verás, cómo enviar comandos y cómo verificarlo todo desde la línea de comandos antes de integrarlo en Home Assistant, openHAB o tu propio código.

¿Qué generación tienes?

Gen1Gen2 / Plus / Pro / Gen3
EjemplosShelly 1, 1PM, 2.5, Plug S, Dimmer 2, H&TPlus 1PM, Plus Plug S, Pro 4PM, 1 Mini Gen3
Ajustes MQTTInternet & Security → Advanced – Developer SettingsSettings → MQTT (Networks → MQTT en interfaces nuevas)
Prefijo por defectoshellies/<modelo>-<id><modelo>-<id> (p. ej. shellyplus1pm-a8032ab12345)
PayloadsTexto plano (on, off, números)JSON (objetos de estado, tramas RPC)
Nube con MQTT activoDesactivadaPuede seguir activa
TLSDepende del firmwareBundle de CA integrado, sin validación o tu propia CA

El ID del dispositivo se deriva de la dirección MAC. Lo encontrarás en la información del dispositivo en la interfaz web, o simplemente suscríbete a # cuando el dispositivo esté conectado y léelo en los primeros topics que lleguen.

Configuración Gen1

En la interfaz web Gen1 abre Internet & Security → Advanced – Developer Settings y marca Enable action execution via MQTT. Rellena:

  • Server: broker.connectmq.com:1883
  • Username / Password: las credenciales de tu broker
  • Use custom MQTT prefix (opcional): por ejemplo testmqtt/shelly/hallway en lugar de shellies/shelly1-A1B2C3
  • Clean session, Keep alive (60 s está bien), Max QoS y Retain: retain es útil para que un dashboard vea al instante el último estado del relé

Guarda y el dispositivo reinicia su conexión MQTT. Recuerda que en Gen1 esto desactiva Shelly Cloud.

Topics Gen1

Topics típicos Gen1 (Shelly 1PM)
shellies/shelly1pm-A1B2C3/online            true | false   (Last Will)
shellies/shelly1pm-A1B2C3/relay/0           on | off
shellies/shelly1pm-A1B2C3/relay/0/power     potencia instantánea en W
shellies/shelly1pm-A1B2C3/relay/0/energy    contador de energía (vatios-minuto)
shellies/shelly1pm-A1B2C3/input/0           0 | 1
shellies/shelly1pm-A1B2C3/temperature       temperatura interna en °C
shellies/shelly1pm-A1B2C3/relay/0/command   ← publicar on | off | toggle
shellies/announce                           el dispositivo se anuncia (JSON)
shellies/command                            ← publicar announce | update

Los comandos son cadenas de texto. Para conmutar el relé, publica on en .../relay/0/command; el dispositivo responde publicando el nuevo valor en .../relay/0. Publicar announce en shellies/command hace que todos los Gen1 del broker informen de su ID, IP y firmware, un truco práctico de descubrimiento. Las persianas usan roller/0/command con open, close, stop, y roller/0/command/pos con un porcentaje.

Los dispositivos a batería como el H&T duermen casi todo el tiempo: se despiertan, publican sensor/temperature y sensor/humidity y se desconectan. Haz que el lado suscriptor dependa de valores retenidos, no de que el dispositivo esté en línea.

Configuración Gen2, Plus y Pro

Abre Settings → MQTT y actívalo:

  • Server: broker.connectmq.com:8883 (o :1883 sin TLS)
  • Client ID: por defecto es el ID del dispositivo; mantenlo único, consulta buenas prácticas de client ID MQTT
  • Username / Password
  • SSL/TLS: No TLS, TLS no validation, TLS with default CA (úsalo con certificados públicos) o TLS with user CA
  • MQTT Prefix: por defecto el ID del dispositivo; pon por ejemplo testmqtt/shelly/plug1
  • RPC status notifications over MQTT: publica eventos en <prefijo>/events/rpc
  • Generic status update over MQTT: publica el estado de cada componente en <prefijo>/status/<componente>
  • Enable MQTT Control: acepta comandos simples en <prefijo>/command/...

Tras cambiar los ajustes MQTT hace falta reiniciar. También puedes hacer toda la configuración sin la interfaz, llamando a la API RPC por HTTP:

Configurar MQTT en un Gen2 vía HTTP RPC
curl -s -X POST http://192.168.1.50/rpc/MQTT.SetConfig \
  -d '{"config":{"enable":true,"server":"broker.connectmq.com:8883","ssl_ca":"ca.pem",
       "user":"username","pass":"password","topic_prefix":"testmqtt/shelly/plug1",
       "rpc_ntf":true,"status_ntf":true,"enable_control":true}}'

curl -s -X POST http://192.168.1.50/rpc/Shelly.Reboot

"ssl_ca": "ca.pem" selecciona el bundle de CA integrado; "*" desactiva la validación y "user_ca.pem" usa un certificado que hayas subido. Evita "*" fuera de un laboratorio; consulta cómo probar una conexión TLS.

Topics Gen2

Topics Gen2 con el prefijo testmqtt/shelly/plug1
testmqtt/shelly/plug1/online              true | false   (Last Will)
testmqtt/shelly/plug1/status/switch:0     {"id":0,"output":true,"apower":12.4,...}
testmqtt/shelly/plug1/events/rpc          {"method":"NotifyStatus","params":{...}}
testmqtt/shelly/plug1/command             ← publicar status_update
testmqtt/shelly/plug1/command/switch:0    ← publicar on | off | toggle
testmqtt/shelly/plug1/rpc                 ← publicar peticiones JSON-RPC

Los componentes se direccionan como tipo:índice: switch:0, input:1, cover:0, temperature:100. Con Generic status update activo, el estado completo de cada componente llega a su propio topic, que es el formato más fácil de consumir. events/rpc transporta deltas NotifyStatus y mensajes NotifyEvent (pulsaciones de botón, por ejemplo).

RPC sobre MQTT

Cada método Gen2 que puedes llamar por HTTP también funciona por MQTT. Publica una trama JSON-RPC en <prefijo>/rpc; el dispositivo responde en <src>/rpc, donde src es el valor que pusiste en la petición. Es el clásico patrón petición/respuesta.

Petición publicada en testmqtt/shelly/plug1/rpc
{"id": 1, "src": "testmqtt/shelly/cli", "method": "Switch.Set", "params": {"id": 0, "on": true}}
Respuesta en testmqtt/shelly/cli/rpc
{"id": 1, "src": "shellyplusplugs-a8032ab12345", "dst": "testmqtt/shelly/cli", "result": {"was_on": false}}

Métodos útiles: Shelly.GetStatus, Shelly.GetDeviceInfo, Switch.Toggle, Switch.GetStatus, Cover.GoToPosition, Sys.SetConfig. Los errores vuelven con un objeto error (code y message) en lugar de result.

Aquí tienes un pequeño helper en Python (paho-mqtt 2.x) que envía una llamada RPC y espera la respuesta correspondiente:

shelly_rpc.py
import json, os, threading
import paho.mqtt.client as mqtt

PREFIX = "testmqtt/shelly/plug1"
SRC = "testmqtt/shelly/cli"
done = threading.Event()

def on_connect(client, userdata, flags, reason_code, properties):
    client.subscribe(f"{SRC}/rpc", qos=1)

def on_subscribe(client, userdata, mid, reason_codes, properties):
    req = {"id": 1, "src": SRC, "method": "Shelly.GetStatus"}
    client.publish(f"{PREFIX}/rpc", json.dumps(req), qos=1)

def on_message(client, userdata, msg):
    resp = json.loads(msg.payload)
    if resp.get("id") == 1:
        print(json.dumps(resp.get("result", resp.get("error")), indent=2))
        done.set()

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="shelly-rpc-cli")
client.username_pw_set(os.environ["MQTT_USER"], os.environ["MQTT_PASS"])
client.tls_set()
client.on_connect, client.on_subscribe, client.on_message = on_connect, on_subscribe, on_message
client.connect("broker.connectmq.com", 8883)
client.loop_start()
print("ok" if done.wait(10) else "sin respuesta (revisa el prefijo y el ajuste RPC)")
client.loop_stop()

Probar la configuración

Antes de añadir el dispositivo a cualquier software domótico, observa su tráfico directamente:

Ver todo lo que publica un Shelly
mosquitto_sub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -u "$MQTT_USER" -P "$MQTT_PASS" -t 'shellies/#' -t 'testmqtt/shelly/#' -v

Después conmuta el relé desde una segunda terminal y comprueba que el topic de estado lo sigue:

Enviar comandos
# Gen1
mosquitto_pub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -u "$MQTT_USER" -P "$MQTT_PASS" -t 'shellies/shelly1pm-A1B2C3/relay/0/command' -m toggle

# Gen2 con "Enable MQTT Control"
mosquitto_pub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -u "$MQTT_USER" -P "$MQTT_PASS" -t 'testmqtt/shelly/plug1/command/switch:0' -m toggle

Puedes hacer lo mismo en el navegador con el cliente MQTT online: suscríbete al prefijo con #, publica status_update en <prefijo>/command y el dispositivo responde con su estado completo. Si no estás seguro de que un comodín cubra los topics que esperas, pégalos en el topic matcher.

Ver los topics de tu Shelly en el navegador

Si no aparece nada: comprueba que el topic online llegue a ponerse en true, que el puerto coincida con el ajuste TLS (8883 con TLS, 1883 sin él) y que el dispositivo pueda resolver el nombre del broker. Un dispositivo que se reconecta sin parar suele estar peleando con otro cliente que usa el mismo client ID.

Notas de integración

  • Home Assistant: los Shelly se suelen añadir con la integración nativa de Shelly, que no usa MQTT. Si prefieres MQTT, define las entidades a mano o usa un script de discovery; consulta Home Assistant y MQTT.
  • Diseño de topics: un prefijo propio como home/<habitación>/<dispositivo> mantiene Shelly, Tasmota y Zigbee en un árbol coherente; consulta diseño de topics para el hogar inteligente.
  • Estado retenido: activa retain (Gen1) o apóyate en status/... más una petición status_update al arrancar (Gen2) para que los dashboards no muestren "unknown" tras un reinicio.
  • Mezclar generaciones: escribe tus consumidores para ambos formatos o normalízalos en Node-RED antes de que lleguen a tu aplicación.

El soporte MQTT de Shelly es de los más completos del hardware de consumo: topics simples en Gen1 y una API RPC completa en Gen2 y posteriores. Configura un prefijo propio, observa el tráfico con un suscriptor antes de integrar y limita cada dispositivo a sus propios topics.

Preguntas frecuentes

¿Activar MQTT desactiva Shelly Cloud?

En los dispositivos Gen1, sí: al activar MQTT se apaga Shelly Cloud. En los dispositivos Gen2, Plus, Pro y Gen3, MQTT y la conexión a la nube pueden funcionar a la vez.

¿Cuál es el topic MQTT por defecto de un Shelly?

Los Gen1 usan shellies/<modelo>-<deviceid>/..., por ejemplo shellies/shelly1-A1B2C3/relay/0. Los Gen2 y posteriores usan el ID del dispositivo como prefijo, por ejemplo shellyplus1pm-a8032ab12345/status/switch:0. Ambos se pueden sustituir por un prefijo propio.

¿Pueden los Shelly conectarse a un broker MQTT por TLS?

Los Gen2 y posteriores admiten TLS con el bundle de CA integrado, sin validación o con tu propio certificado de CA, así que el puerto 8883 funciona. En Gen1 depende del firmware; lo habitual es el puerto 1883 en una red de confianza.