Tutorials

Shelly Devices and MQTT: Setup, Topics and RPC

Connect Shelly Gen1 and Gen2/Plus/Pro devices to an MQTT broker: settings, TLS, topic structure, control commands and RPC over MQTT, with test commands.

Updated · 8 min read

Shelly Devices and MQTT: Setup, Topics and RPC

Shelly devices speak MQTT natively: open the device's web UI, enable MQTT, enter your broker's host, port and credentials, and the relay starts publishing its state and accepting commands. What differs is the topic layout. Gen1 devices (Shelly 1, 2.5, Plug S, H&T…) use a fixed shellies/... tree with plain-text commands, while Gen2, Plus, Pro and Gen3 devices use a JSON-RPC API that you can call over MQTT.

This tutorial covers both generations: the settings, the topics you will see, how to send commands, and how to verify everything from the command line before you wire it into Home Assistant, openHAB or your own code.

Which generation do you have?

Gen1Gen2 / Plus / Pro / Gen3
ExamplesShelly 1, 1PM, 2.5, Plug S, Dimmer 2, H&TPlus 1PM, Plus Plug S, Pro 4PM, 1 Mini Gen3
MQTT settingsInternet & Security → Advanced – Developer SettingsSettings → MQTT (Networks → MQTT on newer UIs)
Default prefixshellies/<model>-<id><model>-<id> (e.g. shellyplus1pm-a8032ab12345)
PayloadsPlain text (on, off, numbers)JSON (status objects, RPC frames)
Cloud while MQTT is onDisabledCan stay enabled
TLSFirmware-dependentBuilt-in CA bundle, no validation, or your own CA

The device ID is derived from the MAC address. You will find it in the web UI under device info, or simply subscribe to # once the device is connected and read it from the first topics that arrive.

Gen1 setup

In the Gen1 web UI open Internet & Security → Advanced – Developer Settings and tick Enable action execution via MQTT. Fill in:

  • Server: broker.connectmq.com:1883
  • Username / Password: your broker credentials
  • Use custom MQTT prefix (optional): for example testmqtt/shelly/hallway instead of shellies/shelly1-A1B2C3
  • Clean session, Keep alive (60 s is fine), Max QoS and Retain: retain is useful so a dashboard sees the last relay state immediately

Save, and the device reboots its MQTT connection. Remember that this turns off Shelly Cloud on Gen1 devices.

Gen1 topics

Typical Gen1 topics (Shelly 1PM)
shellies/shelly1pm-A1B2C3/online            true | false   (Last Will)
shellies/shelly1pm-A1B2C3/relay/0           on | off
shellies/shelly1pm-A1B2C3/relay/0/power     instantaneous power in W
shellies/shelly1pm-A1B2C3/relay/0/energy    energy counter (watt-minutes)
shellies/shelly1pm-A1B2C3/input/0           0 | 1
shellies/shelly1pm-A1B2C3/temperature       internal temperature in °C
shellies/shelly1pm-A1B2C3/relay/0/command   ← publish on | off | toggle
shellies/announce                           device announces itself (JSON)
shellies/command                            ← publish announce | update

Commands are plain strings. To switch the relay, publish on to .../relay/0/command; the device answers by publishing the new value on .../relay/0. Publishing announce to shellies/command makes every Gen1 device on the broker report its ID, IP and firmware — a handy discovery trick. Rollers use roller/0/command with open, close, stop, and roller/0/command/pos with a percentage.

Battery devices such as the H&T sleep most of the time: they wake up, publish sensor/temperature and sensor/humidity, and disconnect. Make the subscriber side rely on retained values, not on the device being online.

Gen2, Plus and Pro setup

Open Settings → MQTT and enable it:

  • Server: broker.connectmq.com:8883 (or :1883 without TLS)
  • Client ID: defaults to the device ID; keep it unique — see MQTT client ID best practices
  • Username / Password
  • SSL/TLS: No TLS, TLS no validation, TLS with default CA (use this for public certificates) or TLS with user CA
  • MQTT Prefix: defaults to the device ID; set e.g. testmqtt/shelly/plug1
  • RPC status notifications over MQTT: publishes events to <prefix>/events/rpc
  • Generic status update over MQTT: publishes component status to <prefix>/status/<component>
  • Enable MQTT Control: accepts simple commands on <prefix>/command/...

A reboot is required after changing MQTT settings. You can also do the whole configuration without the UI, by calling the RPC API over HTTP:

Configure MQTT on a Gen2 device via 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" selects the built-in CA bundle; "*" disables validation and "user_ca.pem" uses a certificate you uploaded. Avoid "*" outside a lab — see testing a TLS connection.

Gen2 topics

Gen2 topics with prefix 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             ← publish status_update
testmqtt/shelly/plug1/command/switch:0    ← publish on | off | toggle
testmqtt/shelly/plug1/rpc                 ← publish JSON-RPC requests

Components are addressed as type:index — switch:0, input:1, cover:0, temperature:100. With Generic status update on, each component's full status lands on its own topic, which is the easiest format to consume. events/rpc carries NotifyStatus deltas and NotifyEvent messages (button presses, for example).

RPC over MQTT

Every Gen2 method you can call over HTTP also works over MQTT. Publish a JSON-RPC frame to <prefix>/rpc; the device answers on <src>/rpc, where src is the value you put in the request. This is a classic request/response pattern.

Request published to testmqtt/shelly/plug1/rpc
{"id": 1, "src": "testmqtt/shelly/cli", "method": "Switch.Set", "params": {"id": 0, "on": true}}
Response on testmqtt/shelly/cli/rpc
{"id": 1, "src": "shellyplusplugs-a8032ab12345", "dst": "testmqtt/shelly/cli", "result": {"was_on": false}}

Useful methods: Shelly.GetStatus, Shelly.GetDeviceInfo, Switch.Toggle, Switch.GetStatus, Cover.GoToPosition, Sys.SetConfig. Errors come back with an error object (code and message) instead of result.

Here is a small Python helper (paho-mqtt 2.x) that sends an RPC call and waits for the matching response:

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 "no response (check prefix and RPC setting)")
client.loop_stop()

Test the setup

Before adding the device to any home-automation software, watch its traffic directly:

Watch everything a Shelly publishes
mosquitto_sub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -u "$MQTT_USER" -P "$MQTT_PASS" -t 'shellies/#' -t 'testmqtt/shelly/#' -v

Then toggle the relay from a second terminal and check that the state topic follows:

Send commands
# 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 with "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

You can do the same in the browser with the online MQTT client: subscribe to the prefix with #, publish status_update to <prefix>/command and the device responds with its full status. If you are unsure whether a wildcard covers the topics you expect, paste them into the topic matcher.

Watch your Shelly topics in the browser

If nothing appears: check that the online topic ever turns true, that the port matches the TLS setting (8883 with TLS, 1883 without), and that the device can resolve the broker's hostname. A device that keeps reconnecting is often fighting another client with the same client ID.

Integration notes

  • Home Assistant: Shelly devices are usually added with the native Shelly integration, which does not use MQTT. If you prefer MQTT, define entities manually or use a discovery script; see Home Assistant and MQTT.
  • Topic design: a custom prefix such as home/<room>/<device> keeps Shelly, Tasmota and Zigbee devices in one consistent tree — see smart home topic design.
  • Retained state: enable retain (Gen1) or rely on status/... plus a status_update request at startup (Gen2) so dashboards do not show "unknown" after a restart.
  • Mixing generations: write your consumers against both layouts, or normalize them in Node-RED before they reach your application.

Shelly's MQTT support is one of the most complete in consumer hardware: plain topics on Gen1, a full RPC API on Gen2 and later. Configure a custom prefix, watch the traffic with a subscriber before integrating, and lock each device down to its own topics.

Frequently asked questions

Does enabling MQTT disable the Shelly Cloud?

On Gen1 devices, yes: turning on MQTT switches off Shelly Cloud. On Gen2, Plus, Pro and Gen3 devices MQTT and the cloud connection can run at the same time.

What is the default MQTT topic of a Shelly device?

Gen1 devices use shellies/<model>-<deviceid>/..., for example shellies/shelly1-A1B2C3/relay/0. Gen2 and later use the device ID as the topic prefix, for example shellyplus1pm-a8032ab12345/status/switch:0. Both can be replaced with a custom prefix.

Can Shelly devices connect to an MQTT broker over TLS?

Gen2 and later support TLS with the built-in CA bundle, without validation, or with your own CA certificate, so port 8883 works. Gen1 support depends on the firmware; plain port 1883 on a trusted network is the common setup there.