# 9. Containerized MQTT clients
###### tags: `corsounipd2022`
:::info
You can execute the code either in your computer or online:
* online. Create an account in https://repl.it
![](https://i.imgur.com/oW5EJIc.png)
* or in your computer. You must have python3 installed and the `paho-mqtt` library:
```
$ sudo pip3 install paho-mqtt
```
The documentation of the MQTT Paho API is here: https://www.eclipse.org/paho/clients/python/docs/
:::
:::info
The code of this section is [here ![](https://i.imgur.com/5Un0gCm.jpg =40x)](https://www.dropbox.com/sh/u73b82rr9crtzwt/AAALzsmqKDWiGLGu4wqW5eqga?dl=0)
:::
# A web client
For the experiment you will use an MQTT client that can be used in any OS, it's called MQTT-explorer:
![](https://i.imgur.com/F8IPtvN.png)
You have to install it from here: http://mqtt-explorer.com
## Connecting to a public broker
There are various public MQTT brokers, for example:
* broker.hivemq.com
* broker.mqttdashboard.com
* test.mosquitto.org
* mqtt.eclipseprojects.io
In this session we will use the one offered by HiveMQ (broker.hivemq.com). Fill in the data as indicated below:
![MQTT client](https://i.imgur.com/BJWDHby.png)
Then click on ```ADVANCED```, and add a topic:
![](https://i.imgur.com/DSLEVh0.png)
if you want you can assing your own client ID. Now click on ```BACK```, and then on ```CONNECT```. You will start seeing something like this:
![](https://i.imgur.com/vKfrVBA.png)
# Programming MQTT
## A simple subscriber
File `sisub.py` cointains the code of a simple python subscriber. This code connects to a public broker and subscribes to topic `$SYS/#`.
$> python3 sisub.py
:::info
The same can be tested with the MQTT-Explorer
:::
### A simple producer
File `sipub.py` cointains the code of a simple python producer. This code connects to a public broker and periodically publishes random values to topic `"PMtest/rndvalue"`
$> python3 sipub.py
:::success
Check if it is working using the MQTT-Explorer... how?
:::
:::info
Check now with the previous code `sisub.py`. What you have to modify of it?
:::
## Getting data from TTN
[The Things Network uses MQTT](https://www.thethingsnetwork.org/docs/applications/mqtt/index.html) to publish device activations and messages, but also allows you to publish a message for a specific device in response.
You will now read the values of two LoRaWAN sensors that are periodically sending their data to the TTN Network Server from the GRC lab.
![](https://i.imgur.com/4zEsurt.jpg =300x)
The basic data we need is the following:
```
Broker: eu1.cloud.thethings.network
Username: lopys2ttn@ttn
Password: NNSXS.A55Z2P4YCHH2RQ7ONQVXFCX2IPMPJQLXAPKQSWQ.A5AB4GALMW623GZMJEWNIVRQSMRMZF4CHDBTTEQYRAOFKBH35G2A
Topic: v3/+/devices/#
```
As a first example we will modify the code of `sisub.py` to get the raw information from TTN, see file `sisubttn1.py`in the repository.
$> python3 sisubttn1.py
The structure of the raw message is:
:::success
```
{
"end_device_ids": {
"device_id": "lopy4sense2",
"application_ids": {
"application_id": "lopys2ttn"
},
"dev_eui": "70B3D5499608A244",
"join_eui": "0000000000000000",
"dev_addr": "260B43DA"
},
"correlation_ids": [
"as:up:01FXTGDC6TQXGTZH98H4Y6GM9P",
"gs:conn:01FXHXEGDMRRZATNNSWW65HXNK",
"gs:up:host:01FXHXEGDWRG04REYV4BQVT42V",
"gs:uplink:01FXTGDC01G90BWY69T2B77QVN",
"ns:uplink:01FXTGDC01XEXV3088WCQV21AS",
"rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01FXTGDC01MS322H19W0DZWHBA",
"rpc:/ttn.lorawan.v3.NsAs/HandleUplink:01FXTGDC6T7ED46SCJT58CDJHV"
],
"received_at": "2022-03-10T18:10:47.131017155Z",
"uplink_message": {
"session_key_id": "AX8BHqGvSx0QOpMF/Qk6ZQ==",
"f_port": 2,
"f_cnt": 27774,
"frm_payload": "QeLVyEIFhDg/+kgv",
"decoded_payload": {
"humidity": 33.379119873046875,
"lux": 1.9553278684616089,
"temperature": 28.354385375976562
},
"rx_metadata": [
{
"gateway_ids": {
"gateway_id": "rak-918100h46011026402",
"eui": "AC1F09FFFE059482"
},
"timestamp": 569230277,
"rssi": -136,
"channel_rssi": -136,
"snr": -22,
"uplink_token": "CiQKIgoWcmFrLTkxODEwMGg0NjAxMTAyNjQwMhIIrB8J//4FlIIQxYe3jwIaDAim/qiRBhCh76mzAyCI85LGyMdB",
"channel_index": 7
},
{
"gateway_ids": {
"gateway_id": "main-gtw-grc",
"eui": "B827EBFFFE7FE28A"
},
"time": "2022-03-10T18:10:46.897854Z",
"timestamp": 2408760916,
"rssi": -3,
"channel_rssi": -3,
"snr": 8.2,
"location": {
"latitude": 39.482534878470204,
"longitude": -0.3463913363006933,
"altitude": 9,
"source": "SOURCE_REGISTRY"
},
"uplink_token": "ChoKGAoMbWFpbi1ndHctZ3JjEgi4J+v//n/iihDUjMv8CBoMCKb+qJEGEP3Q1bgDIKDw2qqN/UEqDAim/qiRBhCw1JCsAw==",
"channel_index": 2
},
{
"gateway_ids": {
"gateway_id": "rak-gtw-grc",
"eui": "B827EBFFFE336296"
},
"timestamp": 1238159932,
"rssi": -87,
"channel_rssi": -87,
"snr": 7.5,
"location": {
"latitude": 39.48272119427445,
"longitude": -0.3471749450839346,
"altitude": 9,
"source": "SOURCE_REGISTRY"
},
"uplink_token": "ChkKFwoLcmFrLWd0dy1ncmMSCLgn6//+M2KWELyks84EGgwIpv6okQYQ9q+RugMg4PTUwITbQQ==",
"channel_index": 2
},
{
"gateway_ids": {
"gateway_id": "itaca-upv",
"eui": "3133303725006A00"
},
"time": "2022-03-10T18:10:52.116796Z",
"timestamp": 1518319934,
"rssi": -103,
"channel_rssi": -103,
"snr": 3.25,
"location": {
"latitude": 39.47876459,
"longitude": -0.33391551,
"altitude": 25,
"source": "SOURCE_REGISTRY"
},
"uplink_token": "ChcKFQoJaXRhY2EtdXB2EggxMzA3JQBqABC+8v7TBRoMCKb+qJEGELvPuc0DILC0rpeY40EqCwis/qiRBhDg1Ng3",
"channel_index": 2
}
],
"settings": {
"data_rate": {
"lora": {
"bandwidth": 125000,
"spreading_factor": 12
}
},
"coding_rate": "4/5",
"frequency": "868500000",
"timestamp": 569230277
},
"received_at": "2022-03-10T18:10:46.913939546Z",
"consumed_airtime": "1.482752s",
"network_ids": {
"net_id": "000013",
"tenant_id": "ttn",
"cluster_id": "ttn-eu1"
}
}
}
...
```
:::
Now we can sligtly modify the code to get a specific piece of information, see file `sisubttn2.py`in the repository.
$> python3 sisubttn2.py
To get sometthing like this:
```
Got these values >> temp=23.078 hum=-1.000 lux=32.235
Got these values >> temp=28.000 hum=-1.000 lux=34.714
```
:::danger
OK, so now, what if we want to "containerize" this app so that simply running as: `docker run -t mysubttn` we get the result above?
Which is the content of the Dockerfile?
:::