0

I'm trying to wrap an existing MQTT client with a helper class.

The functions defined by paho.mqtt.client defined as follows:

def on_connect(client, userdata, flags, rc):
def on_message( client, userdata, msg):

The wrapper class looks as follows:

import paho.mqtt.client as mqtt

HOST = ''
PORT = 1883

class MqttHandler:
    def __init__(self):
        self.client = mqtt.Client()
        self.client.connect(HOST, PORT)
        # How can I direct those callbacks into the class functions?
        self.client.on_connect = on_connect 
        self.client.on_message = on_message 
        self.client.loop_forever()

    def terminate(self):
        self.client.disconnect()

    def on_connect(self, client, userdata, flags, rc):
        pass

    def on_message(self, client, userdata, msg):
        pass

The paho.mqtt.client on_connect property is expecting a function with a signature of a non class function (without the leading self variable), how can I redirect those callbacks into my class functions?

Pynchia
  • 10,996
  • 5
  • 34
  • 43
Aviran
  • 5,160
  • 7
  • 44
  • 76

1 Answers1

0

EDIT

Actually, the lambda function is not needed if you do as @juanpa.arrivillaga replied and follow @Pynchia 's instructions.

It will work if you do:

self.client.on_connect = self.on_connect

I missed the fact that you were not doing self. in your question.

Thanks Pynchia your question, made me think better.


A lambda function would work on this case:

import paho.mqtt.client as mqtt

HOST = ''
PORT = 1883

class MqttHandler:
    def __init__(self):
        self.client = mqtt.Client()
        self.client.connect(HOST, PORT)
        # How can I direct those callbacks into the class functions?
        self.client.on_connect = lambda client, userdata, flags, rc: self.on_connect(client, userdata, flags, rc) 
        self.client.on_message = lambda client, userdata, msg: self.on_message(client, userdata, msg) 
        self.client.loop_forever()

    def terminate(self):
        self.client.disconnect()

    def on_connect(self, client, userdata, flags, rc):
        pass

    def on_message(self, client, userdata, msg):
        pass

The reason for the lambda function to work in this specific case is that paho.mqtt.client.on_connect expects a function with a signature of a non class function.

In other words, the expected signature for on_connect must be: client, userdata, flags, rc, but MqttHandler.on_connect signature is self, client, userdata, flags, rc.

The lambda in this case will allow you to invoke the instance method using it's own self statically, adding the other args dynamically.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
luigibertaco
  • 1,112
  • 5
  • 21