Как получить одноразовое сообщение с MQTT? - PullRequest
0 голосов
/ 13 апреля 2020

Я написал сервис мониторинга для моей системы домашней автоматизации. Одной из вещей, которые я хотел бы отслеживать, являются устройства Zigbee, управляемые Zigbee2MQTT .

Мне нужно извлечь из Zigbee2MQTT настроенные устройства и выполнить некоторые проверки. В идеале в Zigbee2MQTT должен быть синхронный API для получения этой информации, но все это на основе MQTT: - мне нужно подписаться на тему - отправить сообщение в другую тему - и я получу первый топи c Конфигурация.

Мой первый вопрос: есть ли готовое решение для таких одноразовых чехлов? Что-то вроде

response_payload = client.one_shot(response_topic, probe_topic, timeout)

Я верю, что их нет, поэтому я попытался написать свой. Приведенный ниже код не работает, возможно потому, что я никогда не использовал многопоточное соединение MQTT (оно всегда было бесконечным l oop, и такие случаи работали нормально) и не совсем правильно понимаю, как его использовать:

import paho.mqtt.client as mqtt
import time

class GetConfig:

    def __init__(self):
        self.config = None
        self.client = mqtt.Client()
        self.client.on_connect = self.on_connect
        self.client.on_message = self.on_message
        # the connection is threaded so that a timeout check on the (lack of) answer can be done
        self.client.connect_async("mqtt.example.com")
        self.client.loop_start()
        # wait 5 seconds, then fail <-- there was no configuration retrieved
        for _ in range(5):
            time.sleep(1)
        self.client.loop_stop()
        self.client.disconnect()
        raise ValueError('did not get config on time')

    def on_connect(self):
        self.client.subscribe('zigbee2mqtt/bridge/config/devices')
        self.client.publish('zigbee2mqtt/bridge/config/devices/get')

    def on_message(self):
        # we received an answer, the payload will be handled here, then close successfully
        print("received message, closing")
        self.client.loop_stop()
        self.client.disconnect()

GetConfig()

Я всегда получаю исключение ValueError (= нет ответа через 5 секунд), и кажется, что метод on_connect никогда не достигается. Почему?

1 Ответ

1 голос
/ 13 апреля 2020

Подписи на вашем обратном вызове неверны.

(Кроме того, у вас нет пути к успеху, поэтому он всегда будет говорить, что он не удался.)

import paho.mqtt.client as mqtt
import time

class GetConfig:

    def __init__(self):
        self.config = None
        self.got_config = False
        self.client = mqtt.Client()
        self.client.on_connect = self.on_connect
        self.client.on_message = self.on_message
        self.client.connect_async("mqtt.example.com")
        self.client.loop_start()
        for _ in range(5):
            if self.got_config:
                self.disconnect()
                return
            time.sleep(1)
        self.disconnect()
        raise ValueError('did not get config on time')

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

    def on_connect(self, client, userdata, flags, rc):
        self.client.subscribe('zigbee2mqtt/bridge/config/devices')
        self.client.publish('zigbee2mqtt/bridge/config/devices/get')

    def on_message(self, client, userdata, message):
        print(f"received message, closing: {message.payload}")
        self.got_config = True
        self.disconnect()

GetConfig()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...