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 thestatus_ntf
configuration flag. - MQTT control interface for components, enabled with the
enable_control
configuration flag.
MQTT
supports the minimal component interface:
MQTT.SetConfig
to update the component's configurationMQTT.GetConfig
to obtain the component's configurationMQTT.GetStatus
to obtain the component's status
It uses the key mqtt
when enumerated in objects including multiple component payloads, like Shelly.GetStatus
.
Methods
MQTT.SetConfig
Property | Type | Description |
---|---|---|
| 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.
Property | Type | Description | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
| boolean | True if MQTT connection is enabled, false otherwise | ||||||||||
| string or null | Host name of the MQTT server. Can be followed by port number - | ||||||||||
| string or null | Identifies each MQTT client that connects to an MQTT brokers
| ||||||||||
| string or null | Username | ||||||||||
| string or null | Type of the TCP sockets
| ||||||||||
| string or null | Prefix of the topics on which device publish/subscribe. Limited to 300 characters. Could not start with
| ||||||||||
| boolean | Enables RPC notifications ( | ||||||||||
| boolean | Enables publishing the complete component status on | ||||||||||
| boolean | Enable or diable usage of client certifactes to use MQTT with encription, default: | ||||||||||
| boolean | Enable the MQTT control feature. Defalut value: |
Status
Through the status of the MQTT component shows whether the device is connected over MQTT.
Properties:
Property | Type | Description |
---|---|---|
| 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:
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
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:
{
"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 theca.crt
to the device.Shelly.PutPutTLSClientCert
RPC method, upload theclient.crt
to the device.Shelly.PutTLSClientKey
RPC method, upload theclient.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 toannounce
<topic_prefix>/status
the entire device status as response tostatus_update
published on<...>/command
<topic_prefix>/announce
Shelly's device info in response toannounce
<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 statusannounce
- causes information as returned fromShelly.GetDeviceInfo
to be published on theannounce
topics
<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
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.
- MQTT.SetConfig HTTP GET Request
- MQTT.SetConfig Curl Request
- MQTT.SetConfig Mos Request
http://192.168.33.1/rpc/MQTT.SetConfig?config={"enable":true,"server":"broker.hivemq.com:1883"}
curl -X POST -d '{"id":1,"method":"MQTT.SetConfig","params":{"config":{"enable":true,"server":"broker.hivemq.com:1883"}}}' http://${SHELLY}/rpc
mos --port ${PORT} call MQTT.SetConfig '{"config":{"enable":true,"server":"broker.hivemq.com:1883"}}'
Response
- MQTT.SetConfig HTTP GET Response
- MQTT.SetConfig Curl Response
- MQTT.SetConfig Mos Response
{
"restart_required": true
}
{
"id": 1,
"src": "shellypro1-84cca87c1f90",
"params": {
"restart_required": true
}
}
{
"restart_required": true
}
MQTT.GetConfig example
- MQTT.GetConfig HTTP GET Request
- MQTT.GetConfig Curl Request
- MQTT.GetConfig Mos Request
http://192.168.33.1/rpc/MQTT.GetConfig
curl -X POST -d '{"id":1,"method":"MQTT.GetConfig"}' http://${SHELLY}/rpc
mos --port ${PORT} call MQTT.GetConfig
Response
- MQTT.GetConfig HTTP GET Response
- MQTT.GetConfig Curl Response
- MQTT.GetConfig Mos 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
}
{
"id": 1,
"src": "shellypro1-84cca87c1f90",
"params": {
"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
}
}
{
"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
- MQTT.GetStatus HTTP GET Request
- MQTT.GetStatus Curl Request
- MQTT.GetStatus Mos Request
http://192.168.33.1/rpc/MQTT.GetStatus
curl -X POST -d '{"id":1,"method":"MQTT.GetStatus"}' http://${SHELLY}/rpc
mos --port ${PORT} call MQTT.GetStatus
Response
- MQTT.GetStatus HTTP GET Response
- MQTT.GetStatus Curl Response
- MQTT.GetStatus Mos Response
{
"connected": false
}
{
"id": 1,
"src": "shellypro1-84cca87c1f90",
"params": {
"connected": false
}
}
{
"connected": false
}
Send command over MQTT example:
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
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
{
"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
}
}