繁体   English   中英

python JSON 格式无效

[英]python JSON format invalid

我正在尝试获取流入 Azure IoT 中心的日期和时间,以使我能够使用 Azure DX 作为时间序列进行分析。 我可以得到温度和湿度(此时湿度只是一个随机数)。 如果我使用此代码,一切正常,JSON 格式正确并流入 IoT 中心和 Azure DX:

代码的基础取自此处的 Microsoft 示例 - https://github.com/Azure-Samples/azure-iot-samples-python/blob/master/iot-hub/Quickstarts/simulated-device/SimulatedDeviceSync.py

import asyncio
import random
from azure.iot.device import Message
from azure.iot.device.aio import IoTHubDeviceClient
import time
from datetime import datetime
from w1thermsensor import W1ThermSensor
sensor = W1ThermSensor()
import json

CONNECTION_STRING = "xxxxx"
HUMIDITY = 60

MSG_TXT = '{{"temperature": {temperature},"humidity": {humidity}}}'

async def main():

    try:
        # Create instance of the device client
        client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)

        print("Simulated device started. Press Ctrl-C to exit")
        while True:

            humidity = round(HUMIDITY + (random.random() * 20), 2)
            temperature = sensor.get_temperature()

            msg_txt_formatted = MSG_TXT.format(temperature=temperature, humidity=humidity)
            message = Message(msg_txt_formatted)

            # Send a message to the IoT hub
            print(f"Sending message: {message}")
            await client.send_message(message)
            await asyncio.sleep(1)

    except KeyboardInterrupt:
        print("Simulated device stopped")

if __name__ == '__main__':
    asyncio.run(main())

JSON 格式有效且运行良好 -

{ "temperature": 7, "humidity": 66.09 }

如果我尝试添加这样的日期/时间字段:

import asyncio
import random
from azure.iot.device import Message
from azure.iot.device.aio import IoTHubDeviceClient
import time
from datetime import datetime
from w1thermsensor import W1ThermSensor
sensor = W1ThermSensor()
import json


CONNECTION_STRING = "xxxxx"
HUMIDITY = 60

x = datetime.now()
timesent = str(x)


MSG_TXT = '{{"temperature": {temperature},"humidity": {humidity},"timesent": {timesent}}}'

async def main():

    try:
        # Create instance of the device client
        client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)

        print("Simulated device started. Press Ctrl-C to exit")
        while True:

            humidity = round(HUMIDITY + (random.random() * 20), 2)
            temperature = sensor.get_temperature()

            msg_txt_formatted = MSG_TXT.format(temperature=temperature, humidity=humidity, timesent=timesent)
            message = Message(msg_txt_formatted)

            # Send a message to the IoT hub
            print(f"Sending message: {message}")
            await client.send_message(message)
            await asyncio.sleep(1)

    except KeyboardInterrupt:
        print("Simulated device stopped")

if __name__ == '__main__':
    asyncio.run(main())

来自 JSON 的 output 不再有效,Azure DX 将不再是 map。我得到的无效 JSON 是:

"{\"temperature\": 7,\"humidity\": 72.88, \"timesent\": 2022-11-08 14:21:04.021812}"

我怀疑这与日期/时间被格式化为字符串有关,但我完全迷路了。

有人知道我如何发送这些数据吗?

@JoeHo,感谢您指出帮助您解决问题的资源。 我在这里发布解决方案,以便其他面临类似问题的社区成员受益。 对代码进行以下修改帮助我解决了这个问题。

def json_serial(obj):
    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    raise TypeError ("Type %s not serializable" % type(obj))
x = datetime.now().isoformat();
timesent = dumps(datetime.now(), default=json_serial);
MSG_TXT = '{{"temperature": {temperature},"humidity": {humidity}, "timesent": {timesent}}}'

我在 Azure 数据浏览器上的表格定义了以下字段定义。

.create table jsondata (temperature: real, humidity: real, timesent: datetime)

我的数据映射查询如下

.create table jsondata ingestion json mapping 'jsonMapping' '[{"column":"humidity","path":"$.humidity","datatype":"real"},{"column":"temperature","path":"$.temperature","datatype":"real"}, {"column":"timesent","path":"$.timesent","datatype":"datetime"}]'

然后,我使用以下资源中概述的步骤将 Azure Data Explorer 表连接到 IoT Hub Connect Azure Data Explorer table to IoT hub

当我执行该程序时,我可以看到 Azure IoT 中心遥测数据流毫无问题地绑定到 Azure 数据浏览器表。

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM