Skip to main content

Azure Digital Twins入门 - 使用Azure Function + Event Grid将数据输出

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

我们前面学习了如何使用Azure function + Azure IoT Hub将具体的设备和它的Digital Twins联系起来,并且使用Event + Azure function作为Azure Digital Twins的数据输入,我们本节使用EventGrid + Azure Function将数据导出。

创建和设置EventGrid

我们登录到Azure Portal之后,在marketplace里搜索Event Grid Topic, 并创建它,创建好了之后,回到Azure Digital Twins, 按照如下图来设置Endpoint, 选取Event Grid, 并指定我们刚刚创建的Event Grid


创建了指定Endpoint了之后,按照如下的图来配置Event Route:


然后在指定的对话框里选择合适的事件:


您可以发现这里可以选择您自己关系的事件。

需要注意的是,我们配置这个部分是已经将Azure Digital Twins的相关事件委托给Event Grid来了,要处理这些事件,并对这些事件做出反应,我们仍然需要Azure Function, 因此接下来我们需要配置Event Grid的输出到Azure Function, 在Azure Portal里找到Event Grid Topic的资源之后,按照如下的步骤来配置:


然后配置界面上可以这样选:


然后在出现的界面上选择Azure function,并设置好就可以了。

编写Function代码

使用Visual Studio创建基于Azure funciton的项目,向这个项目添加一个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;
using System.Threading.Tasks;

namespace SampleFunctionsApp
{
    public static class ProcessDTRoutedData
    {
        private static readonly HttpClient httpClient = new HttpClient();
        //需要在Azure function的配置里添加环境变量:ADT_SERVICE_URL
        private static string adtServiceUrl = Environment.GetEnvironmentVariable("ADT_SERVICE_URL");

        [FunctionName("ProcessDTRoutedData")]
        public static async Task Run([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log)
        {
            log.LogInformation("Start execution");
            DigitalTwinsClient client;
            try
            {
                //请参考之前文章中是如何在function App启用System Managed Identity, 并从ADT实例中赋予角色的。
                var credentials = new DefaultAzureCredential();
                client = new DigitalTwinsClient(new Uri(adtServiceUrl), credentials, new DigitalTwinsClientOptions { Transport = new HttpClientTransport(httpClient) });
                log.LogInformation("ADT service client connection created.");
            }
            catch (Exception e)
            {
                log.LogError($"ADT service client connection failed. {e}");
                return;
            }

            if (client != null)
            {
                if (eventGridEvent != null && eventGridEvent.Data != null)
                {
                    string twinId = eventGridEvent.Subject.ToString();
                    JObject message = (JObject)JsonConvert.DeserializeObject(eventGridEvent.Data.ToString());

                    log.LogInformation($"Reading event from {twinId}: {eventGridEvent.EventType}: {message["data"]}");

                    string parentId = await AdtUtilities.FindParentAsync(client, twinId, "contains", log);
                    if (parentId != null)
                    {
                        // Read properties which values have been changed in each operation
                        foreach (var operation in message["data"]["patch"])
                        {
                            string opValue = (string)operation["op"];
                            if (opValue.Equals("replace"))
                            {
                                string propertyPath = ((string)operation["path"]);

                                if (propertyPath.Equals("/Temperature"))
                                {
                                    await AdtUtilities.UpdateTwinPropertyAsync(client, parentId, propertyPath, operation["value"].Value<float>(), log);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

部署Azure function之后,即可观察到Azure Digital Twins的一些事件被捕捉,并通过Event Grid复制到Azure function中,并反向反馈给Azure Digital Twins的实例。