[Fixed]-How to use paho mqtt client in django?

23👍

Update:

If you need Django running in multiple threads then to publish messages from your Django app you can use helper functions from Publish module of Paho – https://eclipse.org/paho/clients/python/docs/#id17
You don’t need to create an instance of mqtt client and start a loop in this case. And to subscribe to some topic consider running mqtt client as a standalone script and import there needed modules of your Django app (and don’t forget to setup the Django environment in the script).


The answer below is good only if you run Django in a single thread, which is not usual in production.

Create mqtt.py in your application folder and put all related code there. For example:

import paho.mqtt.client as mqtt

def on_connect(client, userdata, rc):
    client.subscribe("$SYS/#")

def on_message(client, userdata, msg):
    # Do something
    pass

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

client.connect("iot.eclipse.org", 1883, 60)

Don’t call loop_forever() here!

Then in your application __init__.py call loop_start():

from . import mqtt

mqtt.client.loop_start()

Using loop_start() instead of loop_forever() will give you not blocking background thread.

2👍

If you are using ASGI in your Django application you can use MQTTAsgi.

It’s a complete protocol server for Django and MQTT.

Edit: Full disclosure I’m the author of MQTTAsgi.

Edit 2: To utilize the mqtt protocol server you can run your application, first you need to create a MQTT consumer:

from mqttasgi.consumers import MqttConsumer
class MyMqttConsumer(MqttConsumer):

    async def connect(self):
        await self.subscribe('my/testing/topic', 2)

    async def receive(self, mqtt_message):
        print('Received a message at topic:', mqtt_mesage['topic'])
        print('With payload', mqtt_message['payload'])
        print('And QOS:', mqtt_message['qos'])
        pass

    async def disconnect(self):
        await self.unsubscribe('my/testing/topic')

Then you should add this protocol to the protocol router:

application = ProtocolTypeRouter({
      'websocket': AllowedHostsOriginValidator(URLRouter([
          url('.*', WebsocketConsumer)
      ])),
      'mqtt': MyMqttConsumer,
      ....
    })

Then you can run the mqtt protocol server with*:

mqttasgi -H localhost -p 1883 my_application.asgi:application

*Assuming the broker is in localhost and port 1883.

Thanks for the comments!

Leave a comment