# 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

* 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://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:

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:

Then click on ```ADVANCED```, and add a topic:

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:

# 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.

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?
:::