Using The Python MQTT-SN Client

There is a Python client included with the RSMB src files. You can download the RSMB ( Really small message broker here here.

The client is written in python2.7 and consists of 4 files.

MQTT-SN-python-client-files

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.

objects

The function is called from the MSQTTInternal.py script.

The MSQTTInternal.py script handles the incoming packet in the receive function.

receive-function

The receive function is called as part of a loop or manually.

Normally it is started from the call function (at bottom) which itself is started from the MQTTClient script when you do a client.start().

call-function

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.

Note: the functions are called from the client class

The observe if statement which is part of the receive decides if the message type just received matches what we are looking for.

observe-function

The main file is the MQTTSNclient.py file. The file has two classes the callback and the Client classes.

The MQTTSNclient.py file that comes with the package has a sample script at the bottom.

However it is better to use the file as a module and remove the same script form the file.

So I would create as new file e.g. my test script and do :

import MQTTSNclient.callback as callback
import MQTTSNclient.Client as Client

at the top.

If you do edit this file then you should take a copy of it first.

Included Example Code

The example code that you find at the end of the file is meant to test a simple subscribe and publish.

mqttsn-example-code

You will need to edit this as it assumes that the client and server are on the same host and also for some reason uses port 1885.

You will need to match this to your broker. See Installing and configuring the RSMB broker.

There is also a second script that is commented out the start is show below:

mqttsn-example-1

The first part is meant to listen for advertising packets to get the gateway address.

This will probably not work as the multicast doesn’t appear correct in the start function.

The following code should work:

  def start(self):
    m_group="225.0.18.83"
    m_port=1884
    self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    self.sock.settimeout(0.01)

    group = socket.inet_aton(m_group)
    mreq = struct.pack('4sL', group, socket.INADDR_ANY)  
    self.sock.bind(('',m_port))
    self.sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
    
    self.startReceiver()

In addition make sure the broker/gateway is broadcasting.

The config file for the broker should look like that below:mqtt-sn-broker-config

Quick notes:

  1. The self.startReceiver() call is the loop() in the MQTT client. It is called automatically when you connect but you can use the start() method as well.
  2. The callbacks are registered with a single call aclient.registerCallback(Callback()) you can edit the callback functions as needed.
  3. When publishing you need to use a topic id (number) and not a name (string). You first need to register the topic name and the register function returns a topic_id which you then use when you publish. e.g.
    topic_id=aclient.register("house/sensor1")
    aclient.publish(topic_id,message)
  4. Instead of registering you could also subscribe using the topic name. The subscribe method returns a tuple (returncode,topic_id) e.g.
    rc,topic_id=aclient.subscribe("house/sensor1")
    aclient.publish(topic_id,message)
  5. Client Pings aren’t implemented. You need to do that yourself.
  6. I have ported it to python3 but the files have lots of print statements that I have used to try and understand how it works. If you want them then use the contact form and I’ll email them.

Related Tutorials

Facebooktwittergoogle_plusredditpinterestlinkedinmail

Leave a Reply

Your email address will not be published. Required fields are marked *