Skip to main content

Azure Digital Twin入门 - 使用Azure Function作为数据输入Input

分类:  Azure物联网 标签:  #Azure # #Digitial Twin 发布于: 2023-06-15 20:35:19

我们之前的文章已经学习了Azure Digital Twin的基本概念和基本操作方法,我们本节使用Azure Function作为媒介将Azure Digital Twin和实际的IoT Hub设备相关联起来。

我们先说一下基本的理论:如果我们需要将某个设备的遥测数据和Azure Digital Twin中的Digital Twin连接起来,首先要做的是在定义数字模型的时候,对这个模型中的数据要定义类型为Telemetry的数据,例如:

如下是定义的是属性和遥测:PHValue是遥测类型,查看器定义"@type":"Telemetry", 但是PHValueSensorName是属性:

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:com:example:PHValueSensor;1",
  "@type": "Interface",
  "displayName": "PHValueSensor",
  "contents": [
    {
      "@type": "Telemetry",
      "name": "PHValue",
      "schema": "double"
    },

    {
      "@type": "Property",
      "name": "PHValueSensorName",
      "schema": "string"
    },

    {
      "@type": "Property",
      "name": "PHValueSensorCode",
      "schema": "string"
    }
  ]
}

属性和遥测最重要的区别在于:

属性的值是长期被保存在Azure Digital Twin的实例存储里,但是遥测数据只具有较短的生成周期,而且在Azure Digital Twin里也没有遥测数据的历史数据,遥测数据如果需要进一步处理,我们需要将它分流出去给它的服务做进一步的处理。

如果我们需要将实体资产或者设备上的遥测数据和Digital Twin连接起来,我们还需要另外一个辅助服务:Azure Function, 我们使用Azure Function作为其他Azure输入服务和Digital Twin之间的媒介。

我们这个实例中计划是使用Azure IoT Hub中的设备遥测数据,该设备代表实际生产中的实体设备,将这个设备和它存在Azure Digital Twin中的Digital Twin对应起来。建议我们给在IoT Hub中的设备和Digital Twin赋予同样的Id, 例如设备的IdPHValueSensor-1, 那么Digital TwinId也为PhValueSensor-1

配置Azure IoT HubAzure funciton

我们需要先进行必要的配置,主要分为如下四个步骤:

  • 创建Azure function, 并启用functionSystem Managed Identity
  • Azure Digital Twins实例上赋予Azure functionSystem Managed Identity角色Azure Digital Twins Data Owner
  • 编写Azure Function代码,并发布到Azure
  • 配置Azure IoT Hub设备数据遥测事件路由到Azure function Endpoint上。
  • Azure IoT Hub中添加设备,主要保持设备idAzure Digital TwinsDigital Twins的ID一致,这不是必须的,但是可以减少您的代码量。

创建Azure Function并启用System managed Identity

Azure Function作为一个Azure IoT HubAzure Digital Twins中间的媒介,我们需要在创建Azure Functioni之后启用System Managed Identity, 如下图:

注意
是为Azure Function启动System Managed Identity


按照步骤操作就可以了,需要注意的是启动用System Managed Identity之后的名字和Azure function的名字是一样的。

Azure Digital Twins上赋予Azure function角色权限

需要注意的是我们需要的是Azure Digital Twins Data Owner, 如下图:



这样就可以直接从Azure function上通过DefaultAzureCredential直接通过Azure Digital TwinsHost Url来访问实例。

编写Azure function的代码

使用Visual Studio来创建一个Azure Function的项目,然后添加一个Function,使用如下的代码:

using Azure;
using Azure.Core.Pipeline;
using Azure.DigitalTwins.Core;
using Azure.Identity;
using Azure.Messaging.EventGrid;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.EventGrid;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Net.Http;

namespace SampleFunctionsApp
{
    public class ProcessHubToDTEvents
    {
        private static readonly HttpClient httpClient = new HttpClient();
        //定义Azure Digital Twin的实例Host Url
        private static string adtServiceUrl = Environment.GetEnvironmentVariable("ADT_SERVICE_URL");

        //Function的名字,并使用`EventGrid`的`Trigger`。
        [FunctionName("ProcessHubToDTEvents")]
        public async void Run([EventGridTrigger]EventGridEvent eventGridEvent, ILogger log)
        {


            //我们之前已经启用了System Managed Identity, 并从`Azure Digital Twin`上赋予了该Identity权限
            //因此代码里中直接使用默认的认证方式。
            var credentials = new DefaultAzureCredential();
            DigitalTwinsClient client = new DigitalTwinsClient(
                new Uri(adtServiceUrl), credentials, new DigitalTwinsClientOptions
                { Transport = new HttpClientTransport(httpClient) });
            log.LogInformation($"ADT service client connection created.");

            if (eventGridEvent != null && eventGridEvent.Data != null)
            {
                log.LogInformation(eventGridEvent.Data.ToString());

                //从遥测数据中读取设备id和PHP值
                JObject deviceMessage = (JObject)JsonConvert.DeserializeObject(eventGridEvent.Data.ToString());
                string deviceId = (string)deviceMessage["systemProperties"]["iothub-connection-device-id"];
                var PHValue = deviceMessage["body"]["PHValue"];

                log.LogInformation($"Device:{deviceId} PHValue is:{PHValue}");

                //更新设备的PH值
                var updateTwinData = new JsonPatchDocument();
                updateTwinData.AppendReplace("/PHValue", PHValue.Value<double>());
                await client.UpdateDigitalTwinAsync(deviceId, updateTwinData);
            }
        }
    }
}

编译并部署该Azure FunctionAzure Function之后,打开Azure funciton的配置页,添加配置变量ADT_SERVICE_URL, 值为Azure Digital Twins的Host Url。别忘记了协议是https

配置Azure IoT Hub设备遥测事件到Azure function

需要注意,在这之前必须先发布Azure funciton, 然后使用如下图来配置:


点击+ Event Subscription之后:


依次完成从1-5之后,选择function:


一定需要注意的是要选择对你定义的function名字。

按照这个步骤配置成功。

现在只剩下最后一步,您可以添加设备,并向设备发送遥测数据,即可以观察到详细的数据了,如果您想自己动手实验一遍,您可以参考官方的文档:
https://docs.microsoft.com/en-us/azure/digital-twins/tutorial-end-to-end