Skip to main content
Version: 0.14

MQTT

The MQTT component handles configuration and status of the outbound MQTT connection. The supported Quality of service level is 1, which guarantees that a message is delivered at least one time to the receiver. Here, you can find how to configure your device to connect to an MQTT server.

A number of features are supported over the MQTT connection:

  • an RPC channel. It can be disabled via the enable_rpc config flag.
  • RPC notifications, identical to notifications emitted over other persistent RPC channels like websocket, controlled with the rpc_ntf configuration flag.
  • Status updates: the entire status payload of components is published on <topic_prefix>/status/<component:id>, controlled with the status_ntf configuration flag.
  • MQTT control interface for components, enabled with the enable_control configuration flag.

MQTT supports the minimal component interface:

It uses the key mqtt when enumerated in objects including multiple component payloads, like Shelly.GetStatus.

Methods

MQTT.SetConfig

PropertyTypeDescription

config

object

Configuration that the method takes

Find more about the config properties in config section

MQTT.GetConfig

Find the MQTT.GetConfig response properties in config section

MQTT.GetStatus

Find the MQTT.GetStatus response properties in status section

Configuration

The configuration of the MQTT component contains information about the credentials and prefix used and the protection and notifications settings of the MQTT connection.

PropertyTypeDescription

enable

boolean

True if MQTT connection is enabled, false otherwise

server

string or null

Host name of the MQTT server. Can be followed by port number - host:port

client_id

string or null

Identifies each MQTT client that connects to an MQTT brokers

ValueDescription

null

Device id is used as client_id

user

string or null

Username

ssl_ca

string or null

Type of the TCP sockets

ValueDescription

null

Plain TCP connection

*

TLS with disabled certificate validation

user_ca.pem

TLS connection verified by the user-provided CA

ca.pem

TLS connection verified by the built-in CA bundle

topic_prefix

string or null

Prefix of the topics on which device publish/subscribe. Limited to 300 characters. Could not start with $ and #, +, %, ? are not allowed.

ValueDescription

null

Device id is used as topic prefix

rpc_ntf

boolean

Enables RPC notifications (NotifyStatus and NotifyEvent) to be published on <device_id|topic_prefix>/events/rpc (<topic_prefix> when a custom prefix is set, <device_id> otherwise). Default value: true.

status_ntf

boolean

Enables publishing the complete component status on <device_id|topic_prefix>/status/<component>:<id> (<topic_prefix> when a custom prefix is set, <device_id> otherwise). The complete status will be published if a signifficant change occurred. Default value: false

use_client_cert

boolean

Enable or diable usage of client certifactes to use MQTT with encription, default: false

enable_control

boolean

Enable the MQTT control feature. Defalut value: true

Status

Through the status of the MQTT component shows whether the device is connected over MQTT.

Properties:

PropertyTypeDescription

connected

boolean

True if the device is MQTT connected, false otherwise

MQTT Setup and usage

Here is a simple scenario to help you connect your device over MQTT.

Note that the setup process is related to the MQTT system component and the communication over MQTT is described in the MQTT RPC channel page.

Step 1: Check your current connection

Firstly, check your current connection over MQTT with the following request:

export SHELLY=10.33.55.152 # IP of your device
curl -X POST -d '{"id":1, "method":"Mqtt.GetStatus"}' http://${SHELLY}/rpc

The response must contain the property connected. If its value is true, then you are already connected over MQTT. If the value is false, proceed with the next step.

Step 2: Check your MQTT connection settings

Now, check your current MQTT configuration through the method:

curl -X POST -d '{"id":1, "method":"Mqtt.GetConfig"}' http://${SHELLY}/rpc

In the response you can see if your connection over MQTT is enabled, as well as find information about the MQTT server set for that device, custom prefixes and security settings. However, you need to check two things here: whether the connection is enabled and whether your server is set correctly. If the answer to any of these questions is no, proceed to the next step, where we will set a new MQTT configuration.

Step 3: Set a new MQTT configuration

The next thing to do is updating the MQTT configuration. To enable the MQTT connection and set a server simultaneously, use the following method:

curl -X POST -d '{"id":1, "method":"Mqtt.SetConfig", "params":{"config":{"enable":true, "server":"broker.hivemq.com:1883"}}}' http://${SHELLY}/rpc

This will let you connect to the public MQTT server broker.hivemq.com on port 1883. In case you want to set connection to another server, just change the value of the property server in the request above.

Note that, if in step 2 you have found out that the connection is not enabled, but the server is set properly, you can omit the part with "server":"broker.hivemq.com:1883", and vice versa - if the connection is enabled, but the server set is incorrect, you can omit "enable":true.

The response will indicate that you have to reboot your device to apply the new configuration.

Step 4: Reboot you device

Now, reboot your Shelly:

curl -X POST -d '{"id":1, "method":"Shelly.Reboot"}' http://${SHELLY}/rpc

Wait until your device boots again. After that the new settings must be activated.

Step 5: Check if MQTT connection is working

Lastly, let's check the status of the MQTT connection once again (as in step 1):

export SHELLY=10.33.55.152 # IP of your device
curl -X POST -d '{"id":1, "method":"Mqtt.GetStatus"}' http://${SHELLY}/rpc

If you have followed these steps properly, then the property connected in the result must have value true.

Step 6: Receive notifications over MQTT

Now, let's see the communication over MQTT in action. For this to happen, subscribe to the MQTT topic <shelly-id>/events/rpc, where you must replace shelly-id with your device's ID. For example, shellypro4pm-f008d1d8b8b8/events/rpc:

export MQTT_SERVER="broker.hivemq.com"
export MQTT_PORT=1883
export SHELLY_ID="shellypro4pm-f008d1d8b8b8" # The <shelly-id> of your device
mosquitto_sub -h ${MQTT_SERVER} -p ${MQTT_PORT} -t ${SHELLY_ID}/events/rpc

If you have subscribed to the topic correctly, you will start receiving notifications here.

Step 7: Subscribe for messages on connecting and disconnecting over MQTT

Open new tab in your terminal and subscribe to the topic <shelly-id>/online:

export MQTT_SERVER="broker.hivemq.com"
export MQTT_PORT=1883
export SHELLY_ID="shellypro4pm-f008d1d8b8b8" # The <shelly-id> of your device
mosquitto_sub -h ${MQTT_SERVER} -p ${MQTT_PORT} -t ${SHELLY_ID}/online

You will be able to receive the messages:

  • true when the device connects to the broker (for example, after reboot)
  • LWT(Last Will Testament) false in case it is forced to disconnect abruptly

Now, plug off your device. You will receive a message false indicating the device was disconnected abruptly.

Plug on the device again. Again, on the <shelly-id>/online topic you will receive a message true to notify you for the reconnection. Then, open the window where you subscribed to the topic <shelly-id>/events/rpc. There you should be able to see some new notifications regarding the reconnection of your device.

Step 8: Send request and receive response

Here you will send a request and you will name the source of this request mynewtopic. Then the response to this request will be published on topic mynewtopic/rpc. Note that, as stated on the RPC channel page, you can choose whatever <src> you wish for your request. So, the sources user_1 and mynewtopic that you can see throughout the docs are just examples and not something unchangeable. Also note the rpc last segment of the topic where the response will be published. This segment will be always concatenated.

Now, open a terminal window and this time subscribe to the topic mynewtopic/rpc to be able to receive the response after the request is sent:

export MQTT_SERVER="broker.hivemq.com"
export MQTT_PORT=1883
export SHELLY_ID="shellypro4pm-f008d1d8b8b8" # The <shelly-id> of your device
mosquitto_sub -h ${MQTT_SERVER} -p ${MQTT_PORT} -t mynewtopic/rpc

Then, let's send the request. In a new terminal publish the following request on the topic <shelly-id>/rpc:

export MQTT_SERVER="broker.hivemq.com"
export MQTT_PORT=1883
export SHELLY_ID="shellypro4pm-f008d1d8b8b8" # The <shelly-id> of your device
mosquitto_pub -h ${MQTT_SERVER} -p ${MQTT_PORT} -t ${SHELLY_ID}/rpc \
-m '{"id":123, "src":"mynewtopic", "method":"Shelly.GetStatus"}'

This request invokes the method Shelly.GetStatus and, as already explained, you set the source to be mynewtopic.

After you send this request, you can look at the terminal window in which you subscribed for the topic mynewtopic/rpc. There you should be able to see the response to the Shelly.GetStatus method.

If you want to implement more complex topic scheme here is an example how this can be achieved by tweaking the examples above:

Subscription
export MQTT_SERVER="mosquitto12"
export MQTT_PORT=1883
export SHELLY_ID="shellypro4pm-f008d1d8b8b8" # The <shelly-id> of your device
mosquitto_sub -h ${MQTT_SERVER} -p ${MQTT_PORT} -t devices/${SHELLY_ID}/messages/events/rpc
RPC call
export MQTT_SERVER="mosquitto12"
export MQTT_PORT=1883
export SHELLY_ID="shellypro4pm-f008d1d8b8b8" # The <shelly-id> of your device
mosquitto_pub -h ${MQTT_SERVER} -p ${MQTT_PORT} -t ${SHELLY_ID}/rpc \
-m '{"id":"Shelly.GetStatus", "src":"devices/'${SHELLY_ID}'/messages/events", "method":"Shelly.GetStatus"}'

The response will contain a payload with attributes id, src - the Shelly ID, dst the value of src in the above mqtt pub call.

Step 9: Configure a device over MQTT

Now we can start setting up the device over MQTT. We'll be using the setup from the previous example to send commands over MQTT for configuring the schedules on the device.

If we prepare the JSON packet to be sent to a device in a file:

schedule.json
{
"id": 1,
"src": "mynewtopic",
"method": "Schedule.Create",
"params": {
"timespec": "0 0 22 * * MON",
"calls": [{ "method": "Switch.Set", "params":{"id":0,"on":true} }]
}
}
mosquitto_pub -h ${MQTT_SERVER} -p ${MQTT_PORT} -t ${SHELLY_ID}/rpc -f schedule.json

On our topic we set in src property we receive

{
"id": 1,
"src": "shellyplus1pm-c4dd5787708c",
"dst": "mynewtopic",
"result": { "id": 4 }
}

Let's check the list of schedules on the device:

mosquitto_pub -h ${MQTT_SERVER} -p ${MQTT_PORT} -t ${SHELLY_ID}/rpc  -m '{"id":1, "src":"mynewtopic", "method":"Schedule.List"}'
{
"id": "Shelly.GetStatus",
"src": "shellyplus1pm-c4dd5787708c",
"dst": "mynewtopic",
"result": {
"jobs": [
{
"id": 1,
"enable": true,
"timespec": "0 0 22 * * MON",
"calls": [{ "method": "Switch.Set", "params": { "id": 0, "on": true } }]
}
]
}
}

Step 10: Generate periodic updates over MQTT using Shelly Script

Since version 0.9.0

Sometimes there is a need to periodically update state by publishing to a topic. As our devices are trying to limit network chatter we have limited the cases where devices will proactively publish notifications.

By using Shelly Script you can have such device specific behavior:

//sample object
let status = {
operational: true,
activeEndpoint: "http://192.168.1.17"
};

//publish to topic every 1000ms
let notifyTimer = Timer.set(
1000,
true,
function() {
MQTT.publish("/system/device-id/status", JSON.stringify(status), 0, false);
}
);

Step 11: Use MQTT with mTLS support

Since version 0.12.0

To use MQTT with mTLS support the device must have the proper certificates to allow the connection to be verified and accepted by the server. You need the authority certificate ca.crt, the the client certifacte client.crt and the client private key client.key.

Use the following RPC methods:

  • Shelly.PutUserCA RPC method, upload the ca.crt to the device.
  • Shelly.PutPutTLSClientCert RPC method, upload the client.crt to the device.
  • Shelly.PutTLSClientKey RPC method, upload the client.key to the device.

When all certificates are available on the device, the device must be configured to use them in order to make a successful connection.

Use MQTT.SetConfig and configure ssl_ca to be user_ca.pem. Use MQTT.SetConfig and configure use_client_cert to be true.

Reboot the device in order to activate the new settings. If you have set proper server (default port for secure connection is 8883) and you have the valid certificates, the connection is established.

MQTT Control

Since version 0.14.0

In addition to the MQTT RPC channel, some functional components export a control interface which allows for easier integration with external systems, in cases where a complete RPC client on the peer is not feasible or practical. Publish and subscribe topics are defined which allow direct control of the device over MQTT. They are available when the enable_control flag in the MQTT configuration is set to true. For components which support mqtt control, the common topic pattern is:

  • Shelly will subscribe to the following topics, accepting commands:

    • shellies/command which can be used to send a "broadcast" command to all devices on this MQTT exchange
    • <topic_prefix>/command where <topic_prefix> is usually unique per device
    • <topic_prefix>/command/<component:id> where individual components accept specific commands
  • Shelly publishes on:

    • shellies/announce Shelly's device info in response to announce
    • <topic_prefix>/status the entire device status as response to status_update published on <...>/command
    • <topic_prefix>/announce Shelly's device info in response to announce
    • <topic_prefix>/status/<component:id> the entire component status
    • <topic_prefix>/error/<component:id> an informative error message if an MQTT command could not be processed
  • Commonly-accepted commands are:

    • status_update to trigger the component to publish it's status
    • announce - causes information as returned from Shelly.GetDeviceInfo to be published on the announce topics
note

<topic_prefix> is a custom prefix if set or defaults to <device_id>

Components which support an MQTT control with specific commands:

Examples

MQTT.SetConfig example

caution

In case you want to set a password-protected user in your configuration through MQTT.SetConfig, you must include the property pass: string (specifying the user password), together with the user in the config object. This property is not shown in the response of MQTT.GetConfig to prevent leaking credentials.

http://192.168.33.1/rpc/MQTT.SetConfig?config={"enable":true,"server":"broker.hivemq.com:1883"}

Response

{
"restart_required": true
}

MQTT.GetConfig example

http://192.168.33.1/rpc/MQTT.GetConfig

Response

{
"enable": false,
"server": null,
"user": null,
"topic_prefix": "shellypro1-84cca87c1f90",
"rpc_ntf": true,
"status_ntf": false,
"use_client_cert": false,
"enable_rpc": true,
"enable_control": true
}

MQTT.GetStatus example

http://192.168.33.1/rpc/MQTT.GetStatus

Response

{
"connected": false
}

Send command over MQTT example:

Subscription
export MQTT_SERVER="broker.hivemq.com"
export MQTT_PORT=1883
export SHELLY_ID="shellyplus1-a8032abe54dc" # The <shelly-id> of your device
mosquitto_sub -h ${MQTT_SERVER} -p ${MQTT_PORT} -t ${SHELLY_ID}/status
Send command
export MQTT_SERVER="broker.hivemq.com"
export MQTT_PORT=1883
export SHELLY_ID="shellyplus1-a8032abe54dc" # The <shelly-id> of your device
mosquitto_pub -h ${MQTT_SERVER} -p ${MQTT_PORT} -t ${SHELLY_ID}/command -m status_update
Result
{
"ble": {},
"cloud": {
"connected": false
},
"input:0": {
"id": 0,
"state": false
},
"mqtt": {
"connected": true
},
"script:1": {
"id": 1,
"running": false
},
"switch:0": {
"id": 0,
"source": "init",
"output": false,
"temperature": {
"tC": 46.5,
"tF": 115.8
}
},
"sys": {
"mac": "A8032ABE54DC",
"restart_required": false,
"time": "16:41",
"unixtime": 1675262494,
"uptime": 571,
"ram_size": 234820,
"ram_free": 162244,
"fs_size": 458752,
"fs_free": 110592,
"cfg_rev": 7,
"kvs_rev": 1,
"schedule_rev": 0,
"webhook_rev": 0,
"available_updates": {
"beta": {
"version": "0.13.0-beta1"
},
"stable": {
"version": "0.12.0"
}
}
},
"wifi": {
"sta_ip": "192.168.1.101",
"status": "got ip",
"ssid": "TP-LINK_F862",
"rssi": -68
},
"ws": {
"connected": false
}
}