Skip to content
Miloš Viktorović
  • Home
  • Coaching
    • Coaching
    • Introduction to Agile
    • Practical (Remote) Agile
  • Posts & Publications
    • Publications
    • Flying
    • Blog
  • Projects
    • Research Project
    • Student IoT kit
    • CODES
  • About
  • Contact

MQTT

As the most prominent protocol for lightweight M2M communication, exploring and understanding the MQTT Paho client library is of paramount importance. For this reason, we have created the MQTT Chat app in python, through we can demonstrate the main features of MQTT communication. For more conceptual understanding of MQTT check M2M communication.

MQTT Chat / Messenger

First of all we would have to import paho-mqtt library:

import paho.mqtt.client as mqtt_client
import paho.mqtt.subscribe as mqtt_subscribe

Secondly we will define some commonly used MQTT parameters as variables

client_id = "Student_X"
mqtt_host = "broker.hivemq.com"
mqtt_port = 1883
publishing_topic = "testtopic/python101-milos/"
subscription_topic = "testtopic/python101-milos/"
qos = 2 # MQTT QoS level

Here we have defined the parameters for connection to the MQTT broker (Host, Port and ClientID) Additionally we have defined the root of the topics we would use to communicate.

On Event functions

As we already know, protocol handles the communication backend, which creates ‘events’ callbacks. These are the ‘reactions’ to the messages coming from the broker. In practice, paho-mqtt client allows specifying your own functions to handle events (Subscribed, Message arrived, Connected, etc.) This is done in the following way:

def on_message(client, userdata, message):
    # print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
    # print("Received message '" + str(message.payload) + "' on topic '"
    #       + message.topic + "' with QoS " + str(message.qos))
    # print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
    global received_messages ## Global required in order to be able to make changes
    received_messages = received_messages + '\n' + str(message.payload)


def on_subscribe(client, userdata, mid, granted_qos):
    global subscribedFlag  ## Global required in order to be able to make changes
    subscribedFlag = True
    print(client, " subscribed!")


def on_unsubscribe(client, userdata, mid):
    global subscribedFlag
    subscribedFlag = False
    print(client, " unsubscribed!")


def on_connect(client, userdata, flags, rc):
    global connectedFlag
    connectedFlag = True
    print(">>>>>>>>>> Success! MQTT connected! >>>>>>>>>>>")


def on_disconnect(client, userdata, rc):
    global connectedFlag
    connectedFlag = False
    print(">>>>>>>>>> Attention! MQTT disconnected! >>>>>>>>>>>")

As you can assume, header of the functions is predefined, and you can find more details in the paho-mqtt library documentation. As far as the ‘body’ of event handling functions, there we have full freedom to insert whatever code we need. In this example we are just setting flags on Connect/Disconnect and Subscribe/Unsubscribe, and printing simple console messages as info. In the on_message, from the other hand instead of printing information, we decided to just append the messages to a string var, as that would be the easiest approach for this example.

Connecting to broker

Connecting to the MQTT broker requires two steps:

  1. Define Client (class)
  2. Invoke ‘connect’ method with required parameters
# creating MQTT client
mqtt = mqtt_client.Client(client_id)
# connecting to MQTT server
mqtt.connect(host=mqtt_host, port=mqtt_port)

This is quite straight-forward action, which is recommended to be done within ‘Try-Except’ block, so that you can handle any possible exceptions that might arise especially due to network issues.

Callback functions

Now, when we have mqtt class created we can assign callback functions, from our ‘On Event functions’. This is done simply by passing function references:

    # Assign event handling functions
    mqtt.on_connect = on_connect
    mqtt.on_disconnect = on_disconnect
    mqtt.on_subscribe = on_subscribe
    mqtt.on_unsubscribe = on_unsubscribe
    mqtt.on_message = on_message  # define function that executes on message arrival

Network Loop

This is the crucial components, as on it’s execution, the actual command messages are being pushed to the MQTT broker. This means that when you call method ‘connect’ (or any other from the mqtt module) it will not be executed until the network loop has been executed. There are various ways to run the network loop. You can let the loop run in regular intervals (in a parallel thread) by initiating loop_start() (and loop_stop(), or you can run the loop infinitely using loop_forever() (for apps that should run for a long time periods). Also you can run the loop manually by calling loop() method. For the purpose of this example we will use

# Executes previous MQTT command by running the network loop  More info : https://pypi.org/project/paho-mqtt/#network-loop
mqtt.loop_start()  # runs the network loop in regular time intervals

More details on loops, read on Paho Python MQTT Client-Understanding The Loop

Subscription

In this example we will subscribe to two topics, as we want to follow both general and private chat. In addition to the topic we have to provide information on QoS (quality-of-service) level.

mqtt.subscribe(
               [(subscription_topic + "all", qos), 
                (subscription_topic + client_id, qos)]
              )  # subscribes to the desired topic

For the purpose of example topic “all” is general chat, and private messages are received through the tomic coresponding tho the client_id

Input

In our example we are using the input() function to obtain message form the ‘user’. Here it is crucial to remember that this function blocks the program until it receives the input. This is not the best way if you’re talking about IoT, but for demonstration purposes we can work with it. We have also used simple string exploration, so that private messages can be distinguished by format @milos Hi Milos! (@receiver Message)

msg_1 = input("Type your message (or leave blank) and press Enter! >>> " + '\n')

        if connectedFlag:
            # print("DEBUG: Trying to publish message!")
            if msg_1 != '':
                ## If we want to send messages to the specific person, we should type message in format "@Student_Y Hello there!"

                if msg_1[0] == '@':  # detects weather the message is intended for the specific receiver
                    if len(msg_1.split(" ", 1)) > 1: # check if the format is proper: "@receiver message"
                        receiver, msg_1 = msg_1.split(" ", 1)  # splits receiver ID from the message
                        receiver = receiver[1:]

In the real IoT scenario, instead input() we would use some non-blocking function like analogRead() or similar. Also whenever we have code like this we should use Try-Except blocks.

Publishing

In order to publish our message(s), we should simply execute publish() method, and let the Network Loop do its job

mqtt.publish(topic = publishing_topic + receiver,
             payload = msg_1,
             qos = qos
             )

Read more…

  • paho-mqtt library
  • Introducing the MQTT Protocol – MQTT Essentials: Part 1
  • MQTT

Recent Posts

  • Schnitzel flight! EHEH – EDRK
    Schnitzel flight! EHEH – EDRK
    03-Sep-2021
  • Private Pilot License – My journey to PPL!
    Private Pilot License – My journey to PPL!
    22-Apr-2021
  • Solo Cross-country Navigation flight (Big Triangle) EHEH ⇒ EHMZ ⇒ EHSE ⇒ EHEH
    Solo Cross-country Navigation flight (Big Triangle) EHEH ⇒ EHMZ ⇒ EHSE ⇒ EHEH
    13-Dec-2020
  • Spin & acrobatics on Super Decathlon
    Spin & acrobatics on Super Decathlon
    19-Oct-2020
  • Flight log EHEH-EHSE (via Rotterdam)
    Flight log EHEH-EHSE (via Rotterdam)
    19-Oct-2020

Recent Posts

  • Schnitzel flight! EHEH – EDRK
  • Private Pilot License – My journey to PPL!
  • Solo Cross-country Navigation flight (Big Triangle) EHEH ⇒ EHMZ ⇒ EHSE ⇒ EHEH

Archives

  • September 2021
  • April 2021
  • December 2020
  • October 2020
  • August 2020
  • June 2020
  • May 2020
  • January 2020
  • May 2019
Milos Viktorovic © 2023
  • Home
  • Coaching
    • Coaching
    • Introduction to Agile
    • Practical (Remote) Agile
  • Posts & Publications
    • Publications
    • Flying
    • Blog
  • Projects
    • Research Project
    • Student IoT kit
    • CODES
  • About
  • Contact