简体   繁体   English

使用 Azure Azure 将有效载荷发送到 IoT Hub 以用于 Azure 数字孪生 Function

[英]Sending payload to IoT Hub for using in Azure Digital Twin using an Azure Function

Apologies for any incorrect formatting, long time since I posted anything on stack overflow.对于任何不正确的格式表示歉意,很长一段时间以来我在堆栈溢出上发布了任何内容。

I'm looking to send a json payload of data to Azure IoT Hub which I am then going to process using an Azure Function App to display real-time telemetry data in Azure Digital Twin.我希望将 json 数据有效负载发送到 Azure IoT 中心,然后我将使用 Azure Function 应用程序对其进行处理,以在 Azure 数字孪生中显示实时遥测数据。

I'm able to post the payload to IoT Hub and view it using the explorer fine, however my function is unable to take this and display this telemetry data in Azure Digital Twin.我可以将有效负载发布到 IoT 中心并使用资源管理器查看它,但是我的 function 无法接收并在 Azure 数字孪生中显示此遥测数据。 From Googling I've found that the json file needs to be utf-8 encrypted and set to application/json, which I think might be the problem with my current attempt at fixing this.从谷歌搜索我发现 json 文件需要加密 utf-8 并设置为 application/json,我认为这可能是我当前尝试修复此问题的问题。

I've included a snipped of the log stream from my azure function app below, as shown the "body" part of the message is scrambled which is why I think it may be an issue in how the payload is encoded:我在下面包含了来自我的 azure function 应用程序的日志 stream 的片段,如图所示消息的“正文”部分被打乱,这就是为什么我认为这可能是有效负载编码方式的问题:

"iothub-message-source":"Telemetry"},"body":"eyJwb3dlciI6ICIxLjciLCAid2luZF9zcGVlZCI6ICIxLjciLCAid2luZF9kaXJlY3Rpb24iOiAiMS43In0="} 2023-01-27T13:39:05Z [Error] Error in ingest function: Cannot access child value on Newtonsoft.Json.Linq.JValue. "iothub-message-source":"Telemetry"},"body":"eyJwb3dlciI6ICIxLjciLCAid2luZF9zcGVlZCI6ICIxLjciLCAid2luZF9kaXJlY3Rpb24iOiAiMS43In0="} 2023-01-27T13:39:05Z [Error] Error in ingest function: Cannot access child value on Newtonsoft.Json.Linq.JValue.

My current test code is below for sending payloads to IoT Hub, with the potential issue being that I'm not encoding the payload properly.我当前的测试代码如下,用于将有效载荷发送到 IoT 中心,潜在的问题是我没有正确编码有效载荷。

import datetime, requests 
import json

deviceID = "JanTestDT"
IoTHubName = "IoTJanTest"
iotHubAPIVer = "2018-04-01"
iotHubRestURI = "https://" + IoTHubName + ".azure-devices.net/devices/" + deviceID +     "/messages/events?api-version=" + iotHubAPIVer
SASToken = 'SharedAccessSignature'

Headers = {}
Headers['Authorization'] = SASToken
Headers['Content-Type'] = "application/json"
Headers['charset'] = "utf-8"

datetime =  datetime.datetime.now()
payload = {
'power': "1.7",
'wind_speed': "1.7",
'wind_direction': "1.7"
}

payload2 = json.dumps(payload, ensure_ascii = False).encode("utf8")

resp = requests.post(iotHubRestURI, data=payload2, headers=Headers)

I've attempted to encode the payload correctly in several different ways including utf-8 within request.post, however this produces an error that a dict cannot be encoded or still has the body encrypted within the Function App log stream unable to decipher it.我试图以几种不同的方式正确编码有效负载,包括 request.post 中的 utf-8,但是这会产生一个错误,即无法对 dict 进行编码,或者仍然在 Function 应用程序日志 stream 中加密主体无法解密它。

Thanks for any help and/or guidance that can be provided on this - happy to elaborate further on anything that is not clear.感谢您对此提供的任何帮助和/或指导 - 很乐意进一步详细说明任何不清楚的地方。

is there any particular reason why you want to use Azure IoT Hub Rest API end point instead of using Python SDK?为什么要使用 Azure IoT Hub Rest API 端点而不是使用 Python SDK 有什么特别的原因吗? Also, even though you see the values in JSON format when viewed through Azure IoT Explorer, the message format when viewed through a storage end point such as blob reveals a different format as you pointed.此外,即使您在通过 Azure IoT Explorer 查看时看到 JSON 格式的值,通过 blob 等存储端点查看时的消息格式也会显示与您指出的不同格式。

I haven't tested the Python code with REST API, but I have a Python SDK that worked for me.我没有用 REST API 测试 Python 代码,但我有一个 Python SDK 对我有用。 Please refer the code sample below请参考下面的代码示例

import os
import random
import time
from datetime import date, datetime
from json import dumps
from azure.iot.device import IoTHubDeviceClient, Message


def json_serial(obj):
    """JSON serializer for objects not serializable by default json code"""

    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    raise TypeError("Type %s not serializable" % type(obj))


CONNECTION_STRING = "<AzureIoTHubDevicePrimaryConnectionString>"
TEMPERATURE = 45.0
HUMIDITY = 60
MSG_TXT = '{{"temperature": {temperature},"humidity": {humidity}, "timesent": {timesent}}}'


def run_telemetry_sample(client):
    print("IoT Hub device sending periodic messages")

    client.connect()

    while True:
        temperature = TEMPERATURE + (random.random() * 15)
        humidity = HUMIDITY + (random.random() * 20)
        x = datetime.now().isoformat()
        timesent = dumps(datetime.now(), default=json_serial)
        msg_txt_formatted = MSG_TXT.format(
            temperature=temperature, humidity=humidity, timesent=timesent)
        message = Message(msg_txt_formatted, content_encoding="utf-8", content_type="application/json")
        
        print("Sending message: {}".format(message))
        client.send_message(message)
        print("Message successfully sent")
        time.sleep(10)


def main():
    print("IoT Hub Quickstart #1 - Simulated device")
    print("Press Ctrl-C to exit")

    client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)

    try:
        run_telemetry_sample(client)
    except KeyboardInterrupt:
        print("IoTHubClient sample stopped by user")
    finally:
        print("Shutting down IoTHubClient")
        client.shutdown()


if __name__ == '__main__':
    main()

You can edit the MSG_TXT variable in the code to match the payload format and pass the values.您可以在代码中编辑 MSG_TXT 变量以匹配负载格式并传递值。 Note that the SDK uses Message class from Azure IoT Device library which has an overload for content type and content encoding.请注意,SDK 使用来自 Azure IoT 设备库的消息 class ,它具有内容类型和内容编码的重载。 Here is how I have passed the overloads in the code message = Message(msg_txt_formatted, content_encoding="utf-8", content_type="application/json")这是我在代码中传递重载的方式message = Message(msg_txt_formatted, content_encoding="utf-8", content_type="application/json")

I have validated the message by routing to a Blob Storage container and could see the telemetry data in the JSON format.我已通过路由到 Blob 存储容器来验证消息,并且可以看到 JSON 格式的遥测数据。 Please refer below image screenshot referring the data captured at end point.请参考下面的图像截图,参考在终点捕获的数据。

在此处输入图像描述

Hope this helps!希望这可以帮助!

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

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