---
tags: iot
---
# IoT Lab 2: MQTT with Python
This lab aims to offer you an hands-on experience with MQTT. You will perform experiments that will allow you to learn how to “publish” data and “subscribe” to get data.
## Section 1: Basic MQTT
**regarding the clients**:
In this section you will work with MQTT using the MQTT Paho library for Python. The documentation of the MQTT Paho API is here.
You have to first install it using:
`
$ sudo python -m pip install paho-mqtt
`
**regarding the broker:**
In this session we will use a public broker. There are various public brokers (also called sandboxes) in the Internet. For example:
* iot.eclipse.org (https://iot.eclipse.org/getting-started#sandboxes)
* test.mosquitto.org (http://test.mosquitto.org/)
* broker.hivemq.com (https://www.hivemq.com/public-mqtt-broker/)
A more or less updated list is available here: https://github.com/mqtt/mqtt.github.io/wiki/public_brokers
:::info
BTW, it’s very easy to install one’s own broker (see for example https://mosquitto.org/download/).
:::
**A simple subscriber**
The code of the simplest subscriber is the one below.
```python=
#!/usr/bin/env python
# File: sisub.py
import paho.mqtt.client as mqtt
THE_BROKER = "test.mosquitto.org"
THE_TOPIC = "$SYS/#"
CLIENT_ID = ""
# The callback for when the client receives a CONNACK
# response from the server.
def on_connect(client, userdata, flags, rc):
print("Connected to ", client._host, "port: ", client._port)
print("Flags: ", flags, "returned code: ", rc)
client.subscribe(THE_TOPIC, qos=0)
# The callback for when a message is received from the server.
def on_message(client, userdata, msg):
print("sisub: msg received with topic: {} and payload: {}".format(msg.topic, str(msg.payload)))
client = mqtt.Client(client_id=CLIENT_ID,
clean_session=True,
userdata=None,
protocol=mqtt.MQTTv311,
transport="tcp")
client.on_connect = on_connect
client.on_message = on_message
client.username_pw_set(None, password=None)
client.connect(THE_BROKER, port=1883, keepalive=60)
# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
client.loop_forever()
```
This code connects to the broker "test.mosquitto.org" and subscribes to topic "$SYS/#"
:::info
:question: 1. Execute o código acima e explique o resultado obtido.
:::
**A simple producer**
The code of the simplest producer is the one below.
```python=
#!/usr/bin/env python
# File: sipub.py
import random
import time
import paho.mqtt.client as mqtt
THE_BROKER = "test.mosquitto.org"
THE_TOPIC = "ufrn/test"
CLIENT_ID = ""
# The callback for when the client receives a CONNACK
# response from the server.
def on_connect(client, userdata, flags, rc):
print("Connected to ", client._host, "port: ", client._port)
print("Flags: ", flags, "returned code: ", rc)
# The callback for when a message is published.
def on_publish(client, userdata, mid):
print("sipub: msg published (mid={})".format(mid))
client = mqtt.Client(client_id=CLIENT_ID,
clean_session=True,
userdata=None,
protocol=mqtt.MQTTv311,
transport="tcp")
client.on_connect = on_connect
client.on_publish = on_publish
client.username_pw_set(None, password=None)
client.connect(THE_BROKER, port=1883, keepalive=60)
client.loop_start()
while True:
msg_to_be_sent = random.randint(0, 100)
client.publish(THE_TOPIC,
payload=msg_to_be_sent,
qos=0,
retain=False)
time.sleep(5)
client.loop_stop()
```
This code connects to the broker `test.mosquitto.org` and periodically publishes random values to topic `ufrn/test`
:::info
:question: 2. Execute o código acima e explique o resultado obtido.
:question: 3. Modifique `sisub.py` para obter os dados enviados por `sipub.py`.
:::
## Some basic test
**one to many communication**
MQTT is very useful when we have to distribute the same piece of information to various users… but we have to be careful with topics.
For example, using the code from Question_3, set as `topic` for the `subscriber` the value `i/LOVE/Python` and execute it.
Now modify the code of the `producer` so that it uses the same topic (i.e., `i/love/python`) and as the message use the text that you want. Execute the `producer`
:::info
:question: 4. Descreva o resultado obtido
:::
**Retained messages:**
Normally, if a publisher publishes a message to a topic, and no one is subscribed to that topic the message is simply discarded by the broker. If you want your broker to remember the last published message, you’ll have to use the `retained` option.
Only one message is retained per topic. The next message published on that topic replaces the retained message for that topic.
Modify the `loop_start/loop_stop` section of `sipub.py` like indicated below:
```python=
#!/usr/bin/env python
client.loop_start()
msg_to_be_sent = "__whatevertextyouwant__"
client.publish(THE_TOPIC,
payload=msg_to_be_sent,
qos=0,
retain=False)
client.loop_stop()
```
Try now the following cases, but **remember to always execute the “subscriber” AFTER the “producer**” in all cases:
:::info
:question: 5. Experimente os seguintes casos:
* Poste uma mensagem com a opção retida definida como "Falso". O que o “assinante” recebe?
* Publique uma mensagem com a opção retida definida como "True". O que o “assinante” recebe?
* Publique várias mensagens (diferentes) com a opção de retidas em “True” antes de ativar o “assinante”. O que o “assinante” recebe?
:::
Finally, how do you remove or delete a retained message? You have to publish a blank message with the retain flag set to true. Try it.
:::info
Exercício final…
:question: 6.- Crie grupos de dois ou três membros. Crie um aplicativo de chat bem básico, onde todas as mensagens postadas de qualquer um dos membros são recebidas apenas pelos membros do mesmo grupo.
ler texto do teclado em python pode ser feito com:
name = input("Enter text: ")
:::