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