How can we use MQTTv5 in client_sub-class.py or a class which inherits mqtt.Client
I modified client_sub-class.py to use MQTTv5 like below.
However I got an error.
Is there any way to use MQTTv5 for a class which inherits mqtt.Client class?
My code (MQTTv5 version of client_sub-class.py).
import paho.mqtt.client as mqtt
import json
from paho.mqtt.packettypes import PacketTypes
class MyMQTTClass(mqtt.Client):
def on_connect(self, mqttc, obj, flags, rc, props): # props is necessary for MQTTv5
print("Connected: '"+str(flags)+"',"+ f"obj:{obj}"+" '"+str(rc)+"', '"+str(props))
def on_connect_fail(self, mqttc, obj):
print("Connect failed")
def on_message(self, mqttc, obj, msg):
# Get the response properties, abort if they're not given
props = msg.properties
if not hasattr(props, 'ResponseTopic') or not hasattr(props, 'CorrelationData'):
print("No reply requested")
return
corr_id = props.CorrelationData
reply_to = props.ResponseTopic
# The command parameters are in the payload
nums = json.loads(msg.payload)
# The requested command is at the end of the topic
res = 0
# Now we have the result, res, so send it back on the 'reply_to'
# topic using the same correlation ID as the request.
print("Sending response "+str(res)+" on '"+reply_to+"': "+str(corr_id))
props = mqtt.Properties(PacketTypes.PUBLISH)
props.CorrelationData = corr_id
payload = json.dumps(res)
mqttc.publish(reply_to, payload, qos=1, properties=props)
def on_publish(self, mqttc, obj, mid):
print("mid: "+str(mid))
def on_subscribe(self, mqttc, obj, mid, granted_qos):
print("Subscribed: "+str(mid)+" "+str(granted_qos))
def on_log(self, mqttc, obj, level, string):
print(string)
def run(self):
self.connect("broker", 1883, 60)
self.subscribe("/cmd/camera/shutter", qos=1) # このqosの値は0でいいのかも?
rc = 0
while rc == 0:
rc = self.loop()
return rc
if __name__ == "__main__":
mqttc = MyMQTTClass(client_id="my_mqtt_class", protocol=mqtt.MQTTv5)
rc = mqttc.run()
print("rc: "+str(rc))
Error I got.
client_1 | Sending CONNECT (u0, p0, wr0, wq0, wf0, c1, k60) client_id=b''
client_1 | Sending SUBSCRIBE (d0, m1) [(b'/cmd/camera/shutter', 1)]
client_1 | Received CONNACK (0, 0)
client_1 | Caught exception in on_connect: on_connect() missing 1 required positional argument: 'props'
client_1 | Traceback (most recent call last):
client_1 | File "main.py", line 4, in <module>
client_1 | rc = mqttc.run()
client_1 | File "/clients/nodes/camera_node.py", line 70, in run
client_1 | rc = self.loop()
client_1 | File "/root/.local/share/virtualenvs/clients-ClhoSkV5/lib/python3.8/site-packages/paho/mqtt/client.py", line 1120, in loop
client_1 | return self._loop(timeout)
client_1 | File "/root/.local/share/virtualenvs/clients-ClhoSkV5/lib/python3.8/site-packages/paho/mqtt/client.py", line 1164, in _loop
client_1 | rc = self.loop_read()
client_1 | File "/root/.local/share/virtualenvs/clients-ClhoSkV5/lib/python3.8/site-packages/paho/mqtt/client.py", line 1556, in loop_read
client_1 | rc = self._packet_read()
client_1 | File "/root/.local/share/virtualenvs/clients-ClhoSkV5/lib/python3.8/site-packages/paho/mqtt/client.py", line 2439, in _packet_read
client_1 | rc = self._packet_handle()
client_1 | File "/root/.local/share/virtualenvs/clients-ClhoSkV5/lib/python3.8/site-packages/paho/mqtt/client.py", line 3039, in _packet_handle
client_1 | return self._handle_connack()
client_1 | File "/root/.local/share/virtualenvs/clients-ClhoSkV5/lib/python3.8/site-packages/paho/mqtt/client.py", line 3138, in _handle_connack
client_1 | on_connect(
client_1 | TypeError: on_connect() missing 1 required positional argument: 'props'
Have you tried initializing the mqtt.Client class and passing the MQTTv5 as the init argument? Adding the following line of code to the init_ function might be able to specify it. mqtt.Client.init(self, protocol=M!TTv5)
Hi no it doesn't work with above code, it shows this error: "AttributeError: type object 'Client' has no attribute 'init'"
more over it has a typing error I corrected it: mqtt.Client.init(self, protocol=MQTTv5)
Solution is in TTN forum please refer: https://www.thethingsnetwork.org/forum/t/problem-retrieving-data-using-tts-mqtt-tab-py/53924/2
Of course it does not work because it is mqtt.Client.__init__()
How I have done in my application is something like this
class MyClient (mqtt.Client):
def __init__(self):
mqtt.Client.__init__(self, protocol=MQTTv5)
Based on the above I believe this is probably resolved. However to test I ran the below which appeared to work fine. If you are still having issues please feel free to reopen with more details.
import paho.mqtt.client as mqtt
import json
from paho.mqtt.packettypes import PacketTypes
class MyMQTTClass(mqtt.Client):
def on_connect(self, mqttc, obj, flags, rc, props): # props is necessary for MQTTv5
print("Connected: '"+str(flags)+"',"+ f"obj:{obj}"+" '"+str(rc)+"', '"+str(props))
def on_connect_fail(self, mqttc, obj):
print("Connect failed")
def on_message(self, mqttc, obj, msg):
# Get the response properties, abort if they're not given
props = msg.properties
if not hasattr(props, 'ResponseTopic') or not hasattr(props, 'CorrelationData'):
print("No reply requested")
return
corr_id = props.CorrelationData
reply_to = props.ResponseTopic
# The command parameters are in the payload
nums = json.loads(msg.payload)
# The requested command is at the end of the topic
res = 0
# Now we have the result, res, so send it back on the 'reply_to'
# topic using the same correlation ID as the request.
print("Sending response "+str(res)+" on '"+reply_to+"': "+str(corr_id))
props = mqtt.Properties(PacketTypes.PUBLISH)
props.CorrelationData = corr_id
payload = json.dumps(res)
mqttc.publish(reply_to, payload, qos=1, properties=props)
def on_publish(self, mqttc, obj, mid):
print("mid: "+str(mid))
def on_subscribe(self, mqttc, userdata, mid, reasonCodes, properties):
print("Subscribed: "+str(mid)+" "+str(reasonCodes))
def on_log(self, mqttc, obj, level, string):
print(string)
def run(self):
self.connect("mosquitto", 1883, 60)
self.subscribe("/cmd/camera/shutter", qos=1) # このqosの値は0でいいのかも?
rc = 0
while rc == 0:
rc = self.loop()
return rc
if __name__ == "__main__":
mqttc = MyMQTTClass(client_id="my_mqtt_class", protocol=mqtt.MQTTv5)
rc = mqttc.run()
print("rc: "+str(rc))
Note: This is part of an exercise to clean up old issues so that the project can move forwards. Due to the number of issues being worked through mistakes will be made; please feel free to reopen this issue (or comment) if you believe it's been closed in error.