您现在访问的是微软AZURE全球版技术文档网站,若需要访问由世纪互联运营的MICROSOFT AZURE中国区技术文档网站,请访问 https://docs.azure.cn.

教程:使用 Azure 数字孪生预览版预配大楼并监视工作条件Tutorial: Provision your building and monitor working conditions with Azure Digital Twins Preview

本教程演示如何使用 Azure 数字孪生预览版来监视空间是否达到理想的温度条件和舒适度。This tutorial demonstrates how to use Azure Digital Twins Preview to monitor your spaces for desired temperature conditions and comfort level. 配置示例大楼以后,即可根据本教程中的步骤预配大楼并针对传感器数据运行自定义函数。After you configure your sample building, you can provision your building and run custom functions on your sensor data by using the steps in this tutorial.

本教程介绍如何执行下列操作:In this tutorial, you learn how to:

  • 定义要监视的条件。Define conditions to monitor.
  • 创建用户定义函数 (UDF)。Create a user-defined function (UDF).
  • 模拟传感器数据。Simulate sensor data.
  • 获取用户定义函数的结果。Get results of a user-defined function.

先决条件Prerequisites

本教程假定你已完成 Azure 数字孪生设置This tutorial assumes that you have finished your Azure Digital Twins setup. 在继续操作之前,请确保已具备以下条件:Before proceeding, make sure that you have:

定义要监视的条件Define conditions to monitor

可以定义一组需要在设备或传感器数据中监视的具体条件,称为“匹配程序”。 You can define a set of specific conditions to monitor in the device or sensor data, called matchers. 然后可以定义名为“用户定义函数”的函数。 You can then define functions called user-defined functions. 用户定义函数用于在匹配程序所指定的条件符合的时候对来自空间和设备的数据执行自定义逻辑。User-defined functions execute custom logic on data that comes from your spaces and devices, when the conditions specified by the matchers occur. 有关详细信息,请阅读数据处理和用户定义的函数For more information, read Data processing and user-defined functions.

occupancy-quickstart 示例项目中,通过 Visual Studio Code 打开 src\actions\provisionSample.yaml 文件。From the occupancy-quickstart sample project, open the file src\actions\provisionSample.yaml in Visual Studio Code. 请注意以类型 matchers 开头的节。Note the section that begins with the type matchers. 此类型下的每个条目使用指定的名称创建一个匹配程序。Each entry under this type creates a matcher with the specified Name. 该匹配程序用于监视类型为 dataTypeValue 的传感器。The matcher will monitor a sensor of type dataTypeValue. 请注意它与名为“专注室 A1”的空间的关系,该专注室有一个“设备”节点, ,节点中包含一些传感器。Notice how it relates to the space named Focus Room A1, which has a devices node that contains a few sensors. 若要预配一个匹配程序,用于跟踪这其中的一个传感器,则请确保其 dataTypeValue 与该传感器的 dataType 匹配。To provision a matcher that will track one of these sensors, make sure that its dataTypeValue matches the sensor's dataType.

在现有匹配程序下面添加以下匹配程序。Add the following matcher below the existing matchers. 确保各个键对齐且空格不被制表符替换。Make sure the keys are aligned and spaces are not replaced by tabs. 这些行也存在 provisionSample.yaml 文件中,属于已注释掉的行。These lines are also present in the provisionSample.yaml file as commented-out lines. 可以取消注释这些行,方法是删除每一行前面的 # 字符。You can uncomment them by removing the # character in front of each line.

      - name: Matcher Temperature
        dataTypeValue: Temperature

此匹配程序会跟踪已在第一个教程中添加的 SAMPLE_SENSOR_TEMPERATURE 传感器。This matcher will track the SAMPLE_SENSOR_TEMPERATURE sensor that you added in the first tutorial.

创建用户定义函数Create a user-defined function

可以通过用户定义的函数来自定义传感器数据的处理。You can use user-defined functions to customize the processing of your sensor data. 这些函数是自定义 JavaScript 代码,在符合匹配程序所述的具体条件时,可以在 Azure 数字孪生实例中运行。They're custom JavaScript code that can run within your Azure Digital Twins instance, when specific conditions as described by the matchers occur. 可以为每个需要监视的传感器创建匹配程序和用户定义的函数。You can create matchers and user-defined functions for each sensor that you want to monitor. 有关详细信息,请阅读数据处理和用户定义的函数For more information, read Data processing and user-defined functions.

在示例性的 provisionSample.yaml 文件中,查找以 userdefinedfunctions 类型开头的节。In the sample provisionSample.yaml file, look for a section that begins with the type userdefinedfunctions. 该节预配具有给定名称的用户定义函数。This section provisions a user-defined function with a given Name. 该 UDF 作用于 matcherNames 下的匹配程序的列表。This UDF acts on the list of matchers under matcherNames. 请注意如何以脚本形式提供自己的适用于 UDF 的 JavaScript 文件。Notice how you can provide your own JavaScript file for the UDF as the script.

另请注意名为 roleassignments 的节。Also note the section named roleassignments. 它向用户定义的函数分配“空间管理员”角色。It assigns the Space Administrator role to the user-defined function. 该函数可以通过此角色访问来自任何已预配空间的事件。This role allows it to access the events that come from any of the provisioned spaces.

  1. 配置 UDF,使之包含温度匹配程序,方法是在 provisionSample.yaml 文件的 matcherNames 节点中添加或取消注释以下行:Configure the UDF to include the temperature matcher by adding or uncommenting the following line in the matcherNames node of the provisionSample.yaml file:

            - Matcher Temperature
    
  2. 在编辑器中打开 src\actions\userDefinedFunctions\availability.js 文件。Open the file src\actions\userDefinedFunctions\availability.js in your editor. 这是在 provisionSample.yaml 的 script 元素中引用的文件。This is the file referenced in the script element of provisionSample.yaml. 此文件中的用户定义函数查找符合以下情况的条件:在房间中检测不到移动,以及二氧化碳水平低于 1,000 ppm。The user-defined function in this file looks for conditions when no motion is detected in the room and carbon dioxide levels are below 1,000 ppm.

    请修改 JavaScript 文件,以便监视温度和其他条件。Modify the JavaScript file to monitor temperature and other conditions. 另请添加以下代码行,查找符合以下情况的条件:在房间中检测不到移动,二氧化碳水平低于 1,000 ppm,且温度低于 78 华氏度。Add the following lines of code to look for conditions when no motion is detected in the room, carbon dioxide levels are below 1,000 ppm, and temperature is below 78 degrees Fahrenheit.

    备注

    此节修改 src\actions\userDefinedFunctions\availability.js 文件,因此你可以详细了解如何编写用户定义的函数。This section modifies the file src\actions\userDefinedFunctions\availability.js so you can learn in detail one way to write a user-defined function. 但是,可以选择在设置中直接使用 src\actions\userDefinedFunctions\availabilityForTutorial.js 文件。However, you can choose to directly use the file src\actions\userDefinedFunctions\availabilityForTutorial.js in your setup. 该文件包含本教程所需的所有更改。This file has all the changes required for this tutorial. 如果改用此文件,请确保使用对 src\actions\provisionSample.yaml 中的 script 键来说正确的文件名。If you use this file instead, make sure to use the correct file name for the script key in src\actions\provisionSample.yaml.

    a.a. 在文件顶部 // Add your sensor type here 注释下方,添加下述适用于温度的行:At the top of the file, add the following lines for temperature below the comment // Add your sensor type here:

        var temperatureType = "Temperature";
        var temperatureThreshold = 78;
    

    b.b. 在注释 // Add your sensor variable here 下,在用于定义 var motionSensor 的语句后面添加以下行:Add the following lines after the statement that defines var motionSensor, below the comment // Add your sensor variable here:

       var temperatureSensor = otherSensors.find(function(element) {
           return element.DataType === temperatureType;
       });
    

    c.c. 在注释 // Add your sensor latest value here 下,在用于定义 var carbonDioxideValue 的语句后面添加以下行:Add the following line after the statement that defines var carbonDioxideValue, below the comment // Add your sensor latest value here:

        var temperatureValue = getFloatValue(temperatureSensor.Value().Value);
    

    d.d. 在注释 // Modify this line to monitor your sensor value 下删除以下代码行:Remove the following lines of code from below the comment // Modify this line to monitor your sensor value:

       if(carbonDioxideValue === null || motionValue === null) {
           sendNotification(telemetry.SensorId, "Sensor", "Error: Carbon dioxide or motion are null, returning");
           return;
       }
    

    将它们替换为以下行:Replace them with the following lines:

        if(carbonDioxideValue === null || motionValue === null || temperatureValue === null){
            sendNotification(telemetry.SensorId, "Sensor", "Error: Carbon dioxide, motion, or temperature are null, returning");
            return;
        }
    

    e.e. 在注释 // Modify these lines as per your sensor 下删除以下代码行:Remove the following lines of code from below the comment // Modify these lines as per your sensor:

        var availableFresh = "Room is available and air is fresh";
        var noAvailableOrFresh = "Room is not available or air quality is poor";
    

    将它们替换为以下行:Replace them with the following lines:

        var alert = "Room with fresh air and comfortable temperature is available.";
        var noAlert = "Either room is occupied, or working conditions are not right.";
    

    f.f. 在注释 // Modify this code block for your sensor 后面删除以下 if-else 代码块:Remove the following if-else code block after the comment // Modify this code block for your sensor:

        // If carbonDioxide less than threshold and no presence in the room => log, notify and set parent space computed value
        if(carbonDioxideValue < carbonDioxideThreshold && !presence) {
            log(`${availableFresh}. Carbon Dioxide: ${carbonDioxideValue}. Presence: ${presence}.`);
            setSpaceValue(parentSpace.Id, spaceAvailFresh, availableFresh);
    
            // Set up custom notification for air quality
            parentSpace.Notify(JSON.stringify(availableFresh));
        }
        else {
            log(`${noAvailableOrFresh}. Carbon Dioxide: ${carbonDioxideValue}. Presence: ${presence}.`);
            setSpaceValue(parentSpace.Id, spaceAvailFresh, noAvailableOrFresh);
    
            // Set up custom notification for air quality
            parentSpace.Notify(JSON.stringify(noAvailableOrFresh));
        }
    

    将它替换为以下 if-else 块:And replace it with the following if-else block:

        // If sensor values are within range and room is available
        if(carbonDioxideValue < carbonDioxideThreshold && temperatureValue < temperatureThreshold && !presence) {
            log(`${alert}. Carbon Dioxide: ${carbonDioxideValue}. Temperature: ${temperatureValue}. Presence: ${presence}.`);
    
            // log, notify and set parent space computed value
            setSpaceValue(parentSpace.Id, spaceAvailFresh, alert);
    
            // Set up notification for this alert
            parentSpace.Notify(JSON.stringify(alert));
        }
        else {
            log(`${noAlert}. Carbon Dioxide: ${carbonDioxideValue}. Temperature: ${temperatureValue}. Presence: ${presence}.`);
    
            // log, notify and set parent space computed value
            setSpaceValue(parentSpace.Id, spaceAvailFresh, noAlert);
        }
    

    修改后的 UDF 会查找这样一个条件:房间变得可用且其二氧化碳和温度处于可以容忍的范围内。The modified UDF will look for a condition where a room becomes available and has the carbon dioxide and temperature within tolerable limits. 在此条件得到满足的情况下,它会使用语句 parentSpace.Notify(JSON.stringify(alert)); 生成一个通知。It will generate a notification with the statement parentSpace.Notify(JSON.stringify(alert)); when this condition is met. 不管此条件是否得到满足,它都会设置受监视空间的值,并提供相应的消息。It will set the value of the monitored space regardless of whether the condition is met, with the corresponding message.

    g.g. 保存文件。Save the file.

  3. 打开命令窗口,转到 occupancy-quickstart\src 文件夹。运行以下命令,预配空间智能图和用户定义的函数:Open a command window, and go to the folder occupancy-quickstart\src. Run the following command to provision your spatial intelligence graph and user-defined function:

    dotnet run ProvisionSample
    

    重要

    为了防止对数字孪生管理 API 进行未经授权的访问,occupancy-quickstart 应用程序要求使用 Azure 帐户凭据登录。To prevent unauthorized access to your Digital Twins Management API, the occupancy-quickstart application requires you to sign in with your Azure account credentials. 它会将凭据保存短暂的时间,因此不需要每次运行它时都登录。It saves your credentials for a brief period, so you might not need to sign in every time you run it. 第一次运行此程序时,以及在此之后保存的凭据过期时,应用程序会将你定向到一个登录页并提供一个可在该页上输入的特定于会话的代码。The first time this program runs, and when your saved credentials expire after that, the application directs you to a sign-in page and gives a session-specific code to enter on that page. 请根据提示通过 Azure 帐户登录。Follow the prompts to sign in with your Azure account.

  4. 帐户进行身份验证以后,应用程序就会开始根据 provisionSample.yaml 中的配置创建一个示例空间图。After your account is authenticated, the application starts creating a sample spatial graph as configured in provisionSample.yaml. 等待预配完成。Wait until the provisioning finishes. 将需要几分钟时间。It will take a few minutes. 此后,请观察命令窗口中的消息,注意空间图是如何创建的。After that, observe the messages in the command window and notice how your spatial graph is created. 注意应用程序如何在根节点或 Venue 处创建 IoT 中心。Notice how the application creates an IoT hub at the root node or the Venue.

  5. Devices 节下 ConnectionString 的值从命令窗口中的输出复制到剪贴板。From the output in the command window, copy the value of ConnectionString, under the Devices section, to your clipboard. 在下一部分,需要此值来模拟设备连接。You'll need this value to simulate the device connection in the next section.

    预配示例

提示

如果在预配过程中出现类似于“由于线程退出或应用程序请求,I/O 操作已中止”的错误消息,请尝试再次运行该命令。If you get an error message similar to "The I/O operation has been aborted because of either a thread exit or an application request" in the middle of the provisioning, try running the command again. 如果 HTTP 客户端因网络问题而超时,则可能出现这种情况。This might happen if the HTTP client timed out from a network issue.

模拟传感器数据Simulate sensor data

在此部分,需使用示例中名为 device-connectivity 的项目。In this section, you'll use the project named device-connectivity in the sample. 需模拟检测移动、温度和二氧化碳所需的传感器数据。You'll simulate sensor data for detecting motion, temperature, and carbon dioxide. 此项目为传感器生成随机值,然后通过设备连接字符串将其发送到 IoT 中心。This project generates random values for the sensors, and sends them to the IoT hub by using the device connection string.

  1. 在单独的命令窗口中,转到 Azure 数字孪生示例,然后导航到 device-connectivity 文件夹。In a separate command window, go to the Azure Digital Twins sample and then to the device-connectivity folder.

  2. 运行以下命令,确保项目的依赖项正确:Run this command to make sure the dependencies for the project are correct:

    dotnet restore
    
  3. 在编辑器中打开 appsettings.json 文件,编辑以下值:Open the appsettings.json file in your editor, and edit the following values:

    a.a. DeviceConnectionString:在上一部分的输出窗口中分配 ConnectionString 的值。DeviceConnectionString: Assign the value of ConnectionString in the output window from the previous section. 完整地复制引号中的这个字符串,以便模拟器能够正确连接 IoT 中心。Copy this string completely, within the quotes, so the simulator can connect properly with the IoT hub.

    b.b. Sensors 数组中的 HardwareId:由于是模拟已预配到 Azure 数字孪生实例的传感器中的事件,因此此文件中的硬件 ID 和传感器的名称应该与 provisionSample.yaml 文件的 sensors 节点匹配。HardwareId within the Sensors array: Because you're simulating events from sensors provisioned to your Azure Digital Twins instance, the hardware ID and the names of the sensors in this file should match the sensors node of the provisionSample.yaml file.

    为温度传感器添加新条目。Add a new entry for the temperature sensor. appsettings.json 中的 Sensors 节点应该如下所示:The Sensors node in appsettings.json should look like the following:

    "Sensors": [{
      "DataType": "Motion",
      "HardwareId": "SAMPLE_SENSOR_MOTION"
    },{
      "DataType": "CarbonDioxide",
      "HardwareId": "SAMPLE_SENSOR_CARBONDIOXIDE"
    },{
      "DataType": "Temperature",
      "HardwareId": "SAMPLE_SENSOR_TEMPERATURE"
    }]
    
  4. 运行以下命令,开始针对温度、移动和二氧化碳模拟设备事件:Run this command to start simulating device events for temperature, motion, and carbon dioxide:

    dotnet run
    

    备注

    由于模拟示例不直接与数字孪生实例通信,因此不需要你进行身份验证。Because the simulation sample does not directly communicate with your Digital Twins instance, it does not require you to authenticate.

获取用户定义函数的结果Get results of the user-defined function

每次实例收到设备和传感器数据时,用户定义的函数就会运行。The user-defined function runs every time your instance receives device and sensor data. 此部分查询 Azure 数字孪生实例,以便获取用户定义函数的结果。This section queries your Azure Digital Twins instance to get the results of the user-defined function. 可以以近实时的方式查看何时房间可用、空气清新且温度合适。You'll see in near real time, when a room is available, that the air is fresh and temperature is right.

  1. 打开用于预配示例的命令窗口或新的命令窗口,再次转到示例的 occupancy-quickstart\src 文件夹。Open the command window that you used to provision the sample, or a new command window, and go to the occupancy-quickstart\src folder of the sample again.

  2. 出现提示时,运行以下命令并登录:Run the following command and sign in when prompted:

    dotnet run GetAvailableAndFreshSpaces
    

输出窗口会显示用户定义的函数如何运行,以及如何截获来自设备模拟的事件。The output window shows how the user-defined function runs and intercepts events from the device simulation.

UDF 的输出

如果满足受监视的条件,用户定义的函数会将空间的值设置为我们此前看到的的相关消息。If the monitored condition is met, the user-defined function sets the value of the space with the relevant message, as we saw earlier. 该消息由 GetAvailableAndFreshSpaces 函数输出到控制台。The GetAvailableAndFreshSpaces function prints out the message on the console.

清理资源Clean up resources

如果不希望继续探索 Azure 数字孪生,可以删除本教程中创建的资源:If you want to stop exploring Azure Digital Twins at this point, feel free to delete resources created in this tutorial:

  1. Azure 门户的左菜单中依次选择“所有资源”、 数字孪生资源组、“删除”。 From the left menu in the Azure portal, select All resources, select your Digital Twins resource group, and select Delete.

    提示

    如果在删除数字孪生实例时遇到麻烦,请使用已推出的包含修补程序的服务更新。If you experienced trouble deleting your Digital Twins instance, a service update has been rolled out with the fix. 请重新尝试删除实例。Please retry deleting your instance.

  2. 可以根据需要删除工作计算机上的示例应用程序。If necessary, delete the sample applications on your work machine.

后续步骤Next steps

预配空间并创建用于触发自定义通知的框架以后,即可继续阅读下述教程之一:Now that you have provisioned your spaces and created a framework to trigger custom notifications, you can go to either of the following tutorials: