【问题标题】:Python 3 Paho-MQTT Published/Subscribed JSON message won't parsePython 3 Paho-MQTT 发布/订阅 JSON 消息不会解析
【发布时间】:2018-11-16 08:58:48
【问题描述】:

这里是新手。

我有一个简单的 python 代码,它应该订阅一个主题并使用 MQTT 协议将 JSON 有效负载发布到同一主题。但由于某种原因,我无法将有效负载加载为 JSON!

我在这里做错了什么?

# -*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
import json
mqtt_broker      = '192.168.1.111'
mqtt_topic_one   = 'mqtt_topic/tops_one'
mqtt_topic_two   = 'mqtt_topic/tops_two'

json_data_1      = '''{
    "this_json": "info",
    "data": {
        "multi_keyval": {
            "1": "1",
            "5": "5",
            "15": "15"
        },
        "single_keyval": {
            "single_key": "200"
        }
    }
}'''


def pass_to_func_and_pub(data_to_pub):
    print(data_to_pub)                # --------> This PRINTS
    print(json.loads(data_to_pub))    # --------> This DOES NOT PRINT

    # The following two lines don't work either.
    unpacked_json = json.loads(data_to_pub)
    client.publish(mqtt_topic_two, unpacked_json['this_json'])


def on_connect(client, userdata, flags, rc):
    client.subscribe(mqtt_topic_one)
    client.publish(mqtt_topic_one, json_data_1)


def on_message(client, userdata, msg):
    pass_to_func_and_pub(str(msg.payload))

client = mqtt.Client()

client.on_connect = on_connect
client.on_message = on_message

client.connect(mqtt_broker)
try:
    client.loop_forever()
except KeyboardInterrupt:
    client.disconnect()
    print('MQTT client disconnected, exiting now.')

【问题讨论】:

    标签: python json python-3.x mqtt paho


    【解决方案1】:

    这里有几个问题。

    1。异常处理

    您没有处理异常(并且 Paho 在处理程序中有效地忽略了它们,我猜是为了让客户端保持活力)。这意味着当json.loads(data_to_pub) 中抛出异常 时,您永远不会看到这个,但函数会退出,因为没有本地except 块。

    改进版

    def pass_to_func_and_pub(data_to_pub):
        print("Raw data: ", data_to_pub)
        try:
            unpacked_json = json.loads(data_to_pub)
        except Exception as e:
            print("Couldn't parse raw data: %s" % data_to_pub, e)
        else:
            print("JSON:", unpacked_json)
            client.publish(mqtt_topic_two, unpacked_json['this_json'])
    

    等等,什么例外?

    运行这个改进的版本,我们现在可以看到:

    Couldn't parse raw data: b'{\n "this_json": "info",\n "data": {\n "multi_keyval": {\n "1": "1",\n "5": "5",\n "15": "15"\n },\n "single_keyval": {\n "single_key": "200"\n }\n }\n}' Expecting value: line 1 column 1 (char 0)

    嗯,b' 在那里做什么?...

    2。编码问题

    基本上你的问题归结为一行

    def on_message(client, userdata, msg):
        pass_to_func_and_pub(str(msg.payload))
    

    通过在 MqttMessagepayload 上调用 str这是 Python 3 中的 bytes 对象,您将获得这些字节的字符串化版本,例如b'foobar'.

    这个b,当然,现在使它无效的JSON,因此Expecting value: line 1 column 1 (char 0)...

    固定版本

    不要打电话给strJson.loads can handle bytes too。所以:

    def on_message(client, userdata, msg):
        pass_to_func_and_pub(msg.payload)
    

    或者,假设 utf-8 编码,我们可以更明确地执行此操作(我更喜欢在字符串中工作):

    def on_message(client, userdata, msg):
        pass_to_func_and_pub(msg.payload.decode('utf-8'))
    

    希望有帮助!

    【讨论】:

    • 这个答案很棒,而且效果很好!非常感谢。我没有意识到 Paho 会忽略处理程序中的异常。
    • 太棒了!很高兴它有帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多