Проблема с потоком при подписке на MQTT в Python с использованием Paho MQTT

У меня есть программа на Python, которая слушает тему MQTT и должна обработать сообщение. Я указываю ряд аргументов из командной строки, чтобы оценить сообщение по-разному.

import argparse
import datetime
import json

import paho.mqtt.client as mqtt

### MQTT Functions
def on_connect(mqttc, obj, flags, rc):
    print("Connected! - " + str(rc))

def on_message(mqttc, obj, msg):
    print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload))

def on_publish(mqttc, obj, mid):
    print("Published! "+str(mid))

def on_subscribe(mqttc, obj, mid, granted_qos):
    print("Subscribed! - "+str(mid)+" "+str(granted_qos))

def on_log(mqttc, obj, level, string):
    print(string)

if __name__ == "__main__":
    # Handle args
    parser = argparse.ArgumentParser(
        description='This is to be usedin conjunction with the WifiScanner on a Raspberry Pi')
    parser.add_argument('--topic', metavar='base/sub', type=str, nargs='?', help='Full topic to listen to. (Example "proximity/sensor")', default="proximity/#")
    parser.add_argument('--host', metavar='url', type=str, nargs='?',
                        help='UQL of MQTT server.')
    parser.add_argument('--graph', metavar='True/False', type=bool, nargs='?', help='Whether to print the data.', default=True)
    parser.add_argument('--timeout', metavar='sec', type=int, nargs='?', help='How long the device will be remembered', default=10)
    args = parser.parse_args()
    # MQTT
    mqttc = mqtt.Client()
    # mqttc.on_message = on_message
    mqttc.on_connect = on_connect
    mqttc.on_publish = on_publish
    mqttc.on_subscribe = on_subscribe
    # Uncomment to enable debug messages
    #mqttc.on_log = on_log
    mqttc.connect(args.host, 1883, 60)
    mqttc.subscribe(args.topic, 0)
    # Start to listen    
    while True:
        print mqttc.loop()

Проблема в том, что я не могу найти простой способ передать аргументы командной строки on_message Перезвоните. Поэтому я попытался использовать возвращаемое значение .loop, Однако, когда я пытаюсь выйти, используя Ctrl+Z (работает только прерывание клавиатуры), он не выходит из потоков MQTT и оставляет их работающими.

В документации и примерах нет примера того, как обрабатывать сообщения вне on_message обратный вызов и как правильно выйти.

Так что любая помощь в устранении этой проблемы будет очень признательна.

заранее спасибо

3 ответа

Вы могли бы использовать userdata аргумент от Client() конструктор. Это заканчивается передачей каждому обратному вызову.

Исправлено, спасибо James Mills

Размещены обратные вызовы внутри класса:

class Receiver:
    def __init__(self, graph, timeout):
        self.graph = graph
        self.timeout = timeout

    def on_connect(self, mqttc, obj, flags, rc):
        print("Connected! - " + str(rc))

    def on_message(self, mqttc, obj, msg):
        print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload))

    def on_publish(self, mqttc, obj, mid):
        print("Published! "+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)

а затем настроить его как

mqttc.on_message = receiver.on_message

Вот еще один пример использования classess в Paho.

import paho.mqtt.client as mqtt
class client1:

    def on_connect(self, master, obj, flags, rc):
        self.master.subscribe('/temperature123')


    def on_message(self, master, obj, msg):
        print(str(msg.payload))

    def __init__(self,master):
        self.master=master
        self.master.on_connect=self.on_connect
        self.master.on_message=self.on_message
        self.master.connect("test.mosquitto.org",1883,60)

client=mqtt.Client()
ob1=client1(client)
client.loop_forever()
Другие вопросы по тегам