Python 3 Paho-MQTT发布/订阅的JSON消息无法解析 [英] Python 3 Paho-MQTT Published/Subscribed JSON message won't parse

查看:1088
本文介绍了Python 3 Paho-MQTT发布/订阅的JSON消息无法解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

菜鸟在这里.

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

I have a simple python code that's supposed to subscribe to a topic and publish JSON payload to the same topic using MQTT protocol. But for some reason, I am unable to load the payload as 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.')

推荐答案

这里有两个问题.

您没有处理异常(我猜Paho实际上会在处理程序中忽略它们,以使客户端保持活动状态).这意味着当在json.loads(data_to_pub)中引发异常 时,您永远不会看到此异常,但是由于没有本地except块而退出了该函数.

You're not handling exceptions (and Paho effectively ignores them within handlers, to keep the client alive I guess). This means when the exception is thrown in json.loads(data_to_pub), you're never seeing this but the function is exited as there is no local except block.

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'])

等等,有什么例外吗?

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

Hang on, what exception?

Running this improved version we can now see:

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'在那做什么? ...

Hmmm, what's that b' doing there?...

基本上,您的问题归结为一行

Essentially your problem comes down to one line

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

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

By calling str on the payload of that MqttMessage, which is a bytes object in Python 3, you'll get the stringified version of those bytes, e.g. b'foobar'.

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

This b, of course, makes it invalid JSON now, hence Expecting value: line 1 column 1 (char 0)...

不要拨打str Json.loads也可以处理bytes .所以:

Don't call str! Json.loads can handle bytes too. So:

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

或者,假设使用utf-8编码,我们可以更明确地做到这一点(我更喜欢在字符串中工作):

Or, assuming utf-8 encoding, we can do this more explicitly (I prefer working in strings):

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

希望有帮助!

这篇关于Python 3 Paho-MQTT发布/订阅的JSON消息无法解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆