如何在异步函数python中为hbmqtt添加回调函数

时间:2018-09-19 23:20:34

标签: python mqtt

我写了一个class messenger.py。我试图在订阅方法中添加回调函数。我越来越跟随错误的说法。我使用的是python版本3.7,而hbmqtt版本是最新版本。

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/asyncio/events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
TypeError: 'coroutine' object is not callable

代码:

import asyncio
import logging
from hbmqtt.client import MQTTClient, ClientException, ConnectException
from hbmqtt.mqtt.constants import QOS_0, QOS_1, QOS_2

class Messenger(object):

    def __init__(self, hostname, port=1883):
        self.hostname = hostname
        self.port = port
        self.client = MQTTClient()

    async def subscribe(self, topics, callback):
        """
        topics should be in format
        topics= [
            ('$SYS/broker/uptime', QOS_1),
            ('$SYS/broker/load/#', QOS_2),
            ]
        """
        topic_list = [ x[0] for x in topics]
        packets = []
        await self.client.connect('mqtt://{}:{}'.format(self.hostname, self.port))
        await self.client.subscribe(topics)
        try:
            while True:
                message = await self.client.deliver_message()
                packet = message.publish_packet
                topic_name = packet.variable_header.topic_name
                payload = packet.payload.data.decode('utf-8')
                await callback(topic_name, payload)
                #print("%d: %s => %s" % (i, packet.variable_header.topic_name, packet.payload.data))
                packets.append((packet.variable_header.topic_name, packet.payload.data.decode('utf-8')))
            await self.client.unsubscribe(topic_list)
            await self.client.disconnect()
        except ClientException as ce:
            logger.error("Client exception: %s" % ce)
        return packets

    async def publish(self, topic, payload, qos=QOS_0):
        if not isinstance(payload, bytes):
            payload = payload.encode('utf-8')
        try:
            await self.client.connect('mqtt://{}:{}'.format(self.hostname, self.port))
            message = await self.client.publish(topic, payload, qos=qos)
            #print ('Message: {}'.format(message))
            #print('Published')
            await self.client.disconnect()
        except ConnectException as ce:
            logger.error("Connection exception: %s" % ce)
            asyncio.get_event_loop().stop()

async def mqtt_callback(topic_name, payload):
      print('Topic_name: {} payload:{}'.format(topic_name, payload))

starting start the loop in this fashion

import asyncio
loop = asyncio.get_event_loop()
mq_object = Messenger('localhost')
topics= [('$SYS/broker/uptime', QOS_1),
         ('$SYS/broker/load/#', QOS_2)]
loop.call_soon(mq_object.subscribe(topics, \
            mqtt_callback))
try:
     loop.run_forever()
except Exception as e:
     pass
finally:
    loop.close()

如何关闭在while循环中运行的协程?

0 个答案:

没有答案