ESP8266 Using MQTT

MQTT

MQTT is a lightweight publish/subscribe messaging transport designed for machine-to-machine “Internet of Things” connectivity. It’s been used in all sorts of industries from home automation and Facebook Messenger mobile app to health care and remote monitoring over satellite links.

Installing MQTT Broker

On Fedora

$ sudo dnf install mosquitto

On Debian based systems

$ sudo apt-get install mosquitto

Starting Mosqiotto and testing

To start mosquitto MQTT broker,

$ mosquitto

It will start the service on your system. You can configure a proper systemd service, for now I’m not doing that.

To test if the broker is working,

$ mosquitto_sub -h localhost -t "Node/msg" 

This will listen for the messages on topic Node/msg.

To publish something on Node/msg topic, run following command in another terminal.

$ mosquitto_pub -h localhost -t "Node/msg" -m "Hello World!"

After this you will see the message “Hello World” printed on the screen where you had executed mosquitto_sub.

This way you can send and recieve the messages using MQTT.

Using MQTT on ESP8266 with micropython

There is a module called umqtt already ther in micropython. To use umqtt, the basic things you have to do are.

from umqtt.simple import MQTTClient # Import MQTT Client.

config = {"server": "192.168.1.2", #IP address of MQTT Broker
          "nodeId": "Node"        #Topic which we need to subscribe to.
         }
def sub_cb(topic, msg):
    print(topic, msg)

c = MQTTClient('umqtt_client', config["server"]) # Initializing the MQTTClient
c.set_callback(sub_cb) #this function will be called when a message is received.
c.connect() #connect to the MQTT Broker/Server.
c.subscribe(b'{}/msg'.format(config['nodeId'])) #subscribe to the specific topic.

# Check for the new mesages that are published.
while True:
    c.check_msg()
    time.sleep(1)
c.disconnect() #once everything is done disconnect from the server.

Now this code will not work until and unless you are connected to the same network as the MQTT Server. So first you need to connect to the network and then connect to the MQTT Server.

Here is the code to connect to the network and then initialize MQTTClient. This code will also publish a message on the given topic when a button is pressed.

from umqtt.simple import MQTTClient
import time
import network
import machine


config = {"wifiSSID": "<your SSID>",
          "wifiPass": "<your password>",
          "ip": "192.168.1.115",
          "nodeId": "Node3"}

inputPin = machine.Pin(15, machine.Pin.IN)
sta = network.WLAN(network.STA_IF)
sta.active(True)
sta.connect(config['wifiSSID'], config['wifiPass'])


def sub_cb(topic, msg):
    print(msg, topic)


def main(server=config['ip']):
    time.sleep(5)
    c = MQTTClient('umqtt_client', server)
    c.set_callback(sub_cb)
    try:
        c.connect()
        print(b'{}/msg'.format(config['nodeId']))
        c.subscribe(b'{}/msg'.format(config['nodeId']))
    except OSError:
        main()

    while True:
        c.check_msg()
        if inputPin.value() == 1:
            c.publish("Node3/msg", "Button Is Pressed")
        else:
            c.publish("Node3/msg", "Button Is Released")
        time.sleep(1)

    c.disconnect()


main()

Listening to messages on gateway in python program.

Now that your ESP8266 node and Mqtt server is set, you might want to access these messages on your edge device which is connected to the internet.

Installing paho-mqtt

$ pip install paho-mqtt

Using paho-mqtt

import paho.mqtt.client as mqtt

# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))

    # Subscribing in on_connect() means that if we lose the connection and
    # reconnect then subscriptions will be renewed.
    client.subscribe("Node3/msg")

# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    print(msg.topic+" "+str(msg.payload))

config = {"ip": "192.168.1.115"}

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

client.connect(config['ip'], 1883)
client.loop_forever()

To publish the message from python you can use

import paho.mqtt.publish as publish
config = {"ip": "192.168.1.115",
          "nodeId": "Node3"}
publish.single(topic='{}/msg'.format(config['nodeId']), payload='Hello From Gateway', hostname=config['ip'])

This way you can communicate between ESP8266 and other devices using MQTT.