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?
| Gen1 | Gen2 / Plus / Pro / Gen3 | |
|---|---|---|
| Ejemplos | Shelly 1, 1PM, 2.5, Plug S, Dimmer 2, H&T | Plus 1PM, Plus Plug S, Pro 4PM, 1 Mini Gen3 |
| Ajustes MQTT | Internet & Security → Advanced – Developer Settings | Settings → MQTT (Networks → MQTT en interfaces nuevas) |
| Prefijo por defecto | shellies/<modelo>-<id> | <modelo>-<id> (p. ej. shellyplus1pm-a8032ab12345) |
| Payloads | Texto plano (on, off, números) | JSON (objetos de estado, tramas RPC) |
| Nube con MQTT activo | Desactivada | Puede seguir activa |
| TLS | Depende del firmware | Bundle 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/hallwayen lugar deshellies/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
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 | updateLos 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:1883sin 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:
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
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-RPCLos 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.
{"id": 1, "src": "testmqtt/shelly/cli", "method": "Switch.Set", "params": {"id": 0, "on": true}}{"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:
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:
mosquitto_sub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
-u "$MQTT_USER" -P "$MQTT_PASS" -t 'shellies/#' -t 'testmqtt/shelly/#' -vDespués conmuta el relé desde una segunda terminal y comprueba que el topic de estado lo sigue:
# 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 togglePuedes 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ónstatus_updateal 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.



