The MQTT-SN client used here is the client from the RSMB source files but upgraded to python 3 and modified to work in a similar fashion to the Paho MQTT client.
You should note it is still a work in progress so I would be grateful if you would let me know of any problems with it.
Downloads are at the end.
The client consists of 4 files.
You can copy these source files into the site packages folder under a suitable folder (e.g mqtt-sn) or alternatively set the path in your scripts to access the client.
Client Files Overview
The MQTTSN.py handles the packet packing and unpacking, and you don’t need to edit this.
It has a very important function right at the end called unpackPacket() shown below:
def unpackPacket((buffer, address)): if MessageType(buffer) != None: packet = objects[MessageType(buffer)]() packet.unpack(buffer) else: packet = None return packet, address
This function extracts the message Type from the received packet and calls the appropriate function to decode the packet.
Note: objects is a list of message type names and is just above the function.
The function is called from the MSQTTInternal.py script.
The MSQTTInternal.py script handles the incoming packet in the receive function.
The receive function is called as part of a loop or can be called manually.
Normally it is started from the call function (at bottom of script ) which itself is started from the MQTTClient script when you do a client.start() or client.loop_start()
This is the loop() as per the MQTT client
This file also has two important functions at the top. They are lookfor() and waitfor.
These functions basically look for a message type and wait for a message type they are generally used as follows:
look for CONNACK
wait for CONNACK
Note: You need to do a lookfor before a waitfor or the waitfor will always fail.
The observe if statement which is part of the receive decides if the message type just received matches what we are looking for.
Underneath you will see a collection of if and if else statements which look for packet type and then call the appropriate callback function if available
The main file is the MQTTSNclient.py file.
The file has two classes the callback and the Client classes.
You will need to include it at the top of you scripts using:
import MQTTSNclient.callback as callback import MQTTSNclient.Client as Client
Note : MQTTSNclient is the folder that contains the scripts.
Example Usage Publish and Subscribe Script
The following script subscribes to a topic and publishes messages on the same topic and displays the published and received messages.
We start with the imports.
Notice the sys.path call which you will need to set depending on where you place the MQTT-SN client files.
Now we create the connection:
Notice the use of lookfor() followed by waitfor(). You should also notice flags like client.connected_flag=False.
This follows the same style as used in the MQTT client and so you could use the following to replace the lookfor and waitfor sections.
I’ve shown the alternative code using the flags that are set in the callback functions as per the mqtt client.
The callback functions are in the MQTTSNclient script but can be overridden in the script as I’ve done with the messgeArrived callback which we see later.
Now we subscribe and get the topic_id which we use when we publish.
But first we have to start a loop to process the callbacks.
The messgeArrived callback is overridden in the script as shown below
The script output is shown below:
Video – RSMB and Python MQTT-SN Client Demo
The following example scripts are included:
- The pub_sub-sn.py script from above.
- A standalone publish script publish-sn.py that uses the topic registration to publish.
- A publish script that publishes without a connection. (quick_publish_sn.py)
- A standalone subscribe script that subscribes to a topic and displays received messages in a continuous loop
- A Gateway discovery script which finds a gateway and published to it (gateway.py)
- A multicast scan test script. Change the port and multicast group to see messages on that group/port (multicast-scan.py)