Skip to content
Kiat edited this page Nov 12, 2019 · 2 revisions

Notes on MQTT for Newbies

MQTT Message flow

Here is a diagram showing the connection phase and the 4 network transactions required to turn a sonoff device on.

mqtt flow

In a typical setup, you'll have multiple Sonoff's (or other devices using this project's code) on the left hand side.
mqtt flow multiple devices

There are lots of ways to control your devices. One typically uses a laptop/desktop to configure and test your Sonoffs and perhaps a smartphone to keep track of what's happening. In the long run you might want to integrate your device in a home-automation system like node-RED, openHAB, HomeAssistant, HomeBridge, Domoticz, ...

Message Issued by Intent
cmnd devices shown on the right hand side control the Sonoff; set configuration; ask for status
stat the Sonoffs report back status or configuration message}
tele some Sonoffs (like temperature measuring devices) report unsolicited telemetry info at periodic intervals

Programming examples for the Sonoff-MQTT-OTA-Arduino

TL;DR

mosquitto_sub -h mqtt_server_name.com -t stat/my_sonoff/POWER -v    # listen for status
mosquitto_pub -h mqtt_server_name.com -t cmnd/my_sonoff/power -m 1  # turn on the light

General

See the wiki's Command List for the definitive list of operations that you can perform. The first word in the column marked Command is the text that you need to put at the end of a cmnd string when you issue a publication message. The 2nd word is the contents of the payload. If there is no 2nd word, you can simply send an empty payload. For example, the first line on the Commands page reads

Command Version Description
Power Show current power state as On or Off
Power on Turn power On
Power off Turn power Off

To execute these, issue (publish) these MQTT requests

MQTT topic            MQTT payload
cmnd/my_device/power  <empty>
cmnd/my_device/power  on
cmnd/my_device/power  off

The sonoff will respond with these publications:

MQTT topic            MQTT payload
stat/my_device/POWER  ON
stat/my_device/POWER  ON
stat/my_device/POWER  OFF

If you have subscribed to these stat messages, you can be informed of changes on the device.

Connecting to MQTT

You'll need an MQTT server somewhere to communicate with your Sonoff. Some people use publicly available servers, such as iot.eclipse.org. There's a list at http://moxd.io/2015/10/public-mqtt-brokers/

Other people think the MQTT server should reside inside your private LAN. You could use a Raspberry/Orange Pi, or just about any Linux machine as the server/broker; you might even squeeze it into your router if you're using OpenWRT.

Creating your own MQTT server/broker

See these sites: Rufio howto Wingsquare howto Instructables howto on Raspberry Pi

Linux/Cygwin command line

You can install the mosquitto client system using either

[Cygwin] setup mosquitto_client
[Ubuntu/Debian] apt install mosquitto_client
[Centos/Fedora] yum install mosquitto_client

Controlling (Publishing)

You can control the relay in your Sonoff with mosquitto_pub. Suppose your Sonoff topic is "my_house_living_room" and your mqtt broker is "control_central". To turn on the Sonoff, type this on the command line:

mosquitto_pub -h control_central -t cmnd/my_house_living_room/power -m 1

You can turn the Sonoff back off again with:

mosquitto_pub -h control_central -t cmnd/my_house_living_room/power -m 0

If you want to found out what state your sonoff is, issue this command with an empty payload to trigger a status response (see below for how to listen):

mosquitto_pub -h control_central -t cmnd/my_house_living_room/status -n

Listening (Subscribing)

To keep track of your sonoff, just subscribe to messages starting with stat, followed by your topic. For example, to pick up status messages from your sonoff, use

mosquitto_sub -h control_central -t stat/my_house_living_room/STATUS -v

The optional -v will show you the topic and payload.

These Sonoffs can provide specific information if you wish. To just monitor the relay state, try

mosquitto_sub -h control_central -t stat/my_house_living_room/POWER

You can also use wildcards in your subscription. To pick up every message from this sonoff, you can use

mosquitto_sub -h control_central -t stat/my_house_living_room/+

and then some some other code to just pick out the messages you want. If you have a collection of sonoffs, you can listen to them all by either using the group topic

mosquitto_sub -h control_central -t stat/my_house_collection/POWER

or by using a wildcard in the 2nd position

mosquitto_sub -h control_central -t stat/+/POWER

Python

Of course you can always call system() or subprocess() to run the mosquitto_pub and mosquitto_sub command lines as shown above. But if you wish, you can install the paho-mqtt package and communicate with MQTT using Python objects.

Let's turn the lights on, wait a few seconds, turn them off, check the status and wait for a time stamp

import paho.mqtt.client as mqtt, time, sys

last_topic = ""
last_payload = ""

# main
def on_connect(client, userdata, flags, rc):
    print("Connected")
    client.is_connected = True

def on_message(client, userdata, message):
    ''' note: message is a tuple of (topic, payload, qos, retain)'''
    global last_topic, last_payload
    last_topic = message.topic
    last_payload = message.payload
    print("Got a message with topic: [" + last_topic + "] and payload [" + last_payload + "]")

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

client.is_connected = False
client.loop_start()
client.connect("control_central")

time.sleep(6)
if not client.is_connected:
    print("problem connecting to the MQTT server; please check your settings")
    sys.exit(1)

client.subscribe("stat/my_house_living_room/POWER")
client.publish("cmnd/my_house_living_room/power","1")

# wait a little bit
time.sleep(15)
client.publish("cmnd/my_house_living_room/power","0")

# ask for system status
time.sleep(1)
client.subscribe("stat/my_house_living_room/STATUS")
client.publish("cmnd/my_house_living_room/status",None)

# now wait for a time stamp from the sonoff; this could take an hour
client.subscribe("tele/my_house_living_room/+")

while 1:
    if last_topic.startswith("tele/") and last_topic.endswith("TIME"):
        print("the sonoff thinks the time is: "+last_payload)
        break
    time.sleep(5)

client.loop_stop()
client.disconnect()


Ref: Python MQTT

JavaScript

...is anyone interested in writing this section?...

Android phone MQTT Dashboard

The MQTT Dashboard provides the ability to connect and control Sonoff devices directly.

On the first page, enter the details of how your phone should connect to the MQTT broker. On the SUBSCRIBE page, you can create widgets which listen for publications from the Sonoff. A typical subscription for a power controller might be stat/my_device/POWER

You could also pick up all your devices with stat/+/POWER

On the PUBLISH page you can create widgets to toggle or on/off your Sonoff. Typically you'd send a cmnd/my_device/power as the topic, and on or off as the publish value. Note that you can also have separate words on the app's user interface, such as illuminated and extinguished; these are not sent out via MQTT, they're just user interface.

Alternatively, if you're using a home automation system, there may be an Andriod/iOS app to link to your home automation. That's not covered in this how-to.