简体   繁体   English

python JSON 格式无效

[英]python JSON format invalid

I'm trying to get date and time flowing into Azure IoT hub to enable me to analyze using Azure DX as time series.我正在尝试获取流入 Azure IoT 中心的日期和时间,以使我能够使用 Azure DX 作为时间序列进行分析。 I can get the temperature and humidity (humidity at the moment is just a random number).我可以得到温度和湿度(此时湿度只是一个随机数)。 If I use this code, all works well and the JSON is well formatted and flows into IoT hub and onto Azure DX:如果我使用此代码,一切正常,JSON 格式正确并流入 IoT 中心和 Azure DX:

The basis for the code is taken from the Microsoft examples here - https://github.com/Azure-Samples/azure-iot-samples-python/blob/master/iot-hub/Quickstarts/simulated-device/SimulatedDeviceSync.py代码的基础取自此处的 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())

The JSON format is valid and works well - JSON 格式有效且运行良好 -

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

If I try to add a date/time field like this:如果我尝试添加这样的日期/时间字段:

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())

The output from the JSON is no longer valid and Azure DX will not map. The invalid JSON I get is:来自 JSON 的 output 不再有效,Azure DX 将不再是 map。我得到的无效 JSON 是:

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

I suspect this is something to do with the date/time being formatted as a string, but I'm totally lost.我怀疑这与日期/时间被格式化为字符串有关,但我完全迷路了。

Would anyone have any ideas how I can send this data?有人知道我如何发送这些数据吗?

@JoeHo, thank you for pointing the sources that helped you resolve the issue. @JoeHo,感谢您指出帮助您解决问题的资源。 I am posting the solution here so that other community members facing similar issue would benefit.我在这里发布解决方案,以便其他面临类似问题的社区成员受益。 Making the below modifications to the code helped me resolve the issue.对代码进行以下修改帮助我解决了这个问题。

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}}}'

My table on the Azure data explorer has the following filed definitions defined.我在 Azure 数据浏览器上的表格定义了以下字段定义。

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

My data mapping query is as below我的数据映射查询如下

.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"}]'

I then connected the Azure Data Explorer table to IoT Hub using the steps outlined in the following resource Connect Azure Data Explorer table to IoT hub然后,我使用以下资源中概述的步骤将 Azure Data Explorer 表连接到 IoT Hub Connect Azure Data Explorer table to IoT hub

When I execute the program, I could see the Azure IoT Hub telemetry data flow getting bound to the Azure Data explorer table without any issues.当我执行该程序时,我可以看到 Azure IoT 中心遥测数据流毫无问题地绑定到 Azure 数据浏览器表。

在此处输入图像描述

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

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