Azure Digital Twins로 IoT Hub 원격 분석 수집

이 가이드에서는 IoT Hub에서 디바이스 원격 분석을 수집하여 Azure Digital Twins 인스턴스로 보낼 수 있는 함수를 작성하는 프로세스를 안내합니다.

Azure Digital Twins는 IoT 디바이스 및 기타 원본의 데이터를 기반으로 합니다. Azure Digital Twins에서 사용할 디바이스 데이터의 공통 원본은 IoT Hub입니다.

Azure Digital Twins로 데이터를 수집하는 프로세스는 Azure Functions를 사용하여 만든 함수와 같은 외부 계산 리소스를 설정하는 것입니다. 함수는 데이터를 수신하고 DigitalTwins API를 사용하여 그에 따라 디지털 트윈에서 속성을 설정하거나 원격 분석 이벤트를 발생시킵니다.

이 방법 문서에서는 IoT Hub에서 디바이스 원격 분석을 수집할 수 있는 함수를 작성하는 프로세스를 안내합니다.

필수 조건

이 예를 계속하기 전에 다음 리소스를 필수 구성 요소로 설정해야 합니다.

원격 분석 시나리오 예제

이 방법에서는 Azure의 함수를 사용하여 IoT Hub에서 Azure Digital Twins로 메시지를 보내는 방법을 간략하게 설명합니다. 메시지를 보내는 데 사용할 수 있는 여러 가지 구성 및 일치 전략이 있지만 이 문서의 예에는 다음과 같은 부분이 포함되어 있습니다.

  • IoT Hub의 자동 온도 조절기 디바이스, 알려진 디바이스 ID 사용
  • 디바이스를 나타내는 디지털 트윈, 일치하는 ID 사용

참고 항목

이 예에서는 디바이스 ID와 해당하는 디지털 트윈의 ID 사이에 간단한 ID 일치를 사용하지만, 디바이스에서 해당 트윈(예: 매핑 테이블)으로 보다 정교한 매핑을 제공할 수 있습니다.

자동 온도 조절기 디바이스에서 온도 원격 분석 이벤트를 보낼 때마다 함수는 원격 분석을 처리하고 디지털 트윈의 Temperature 속성을 업데이트해야 합니다. 이 시나리오는 아래 다이어그램에 설명되어 있습니다.

Diagram of IoT Hub device sending Temperature telemetry to a function in Azure, which updates a Temperature property on a twin in Azure Digital Twins.

모델 및 트윈 추가

이 섹션에서는 Azure Digital Twins에서 자동 온도 조절기 디바이스를 나타내고 IoT Hub 정보로 업데이트되는 디지털 트윈을 설정합니다.

자동 온도 조절기 형식 트윈을 만들려면 먼저 자동 온도 조절기 모델을 인스턴스에 업로드해야 합니다. 이 모델은 자동 온도 조절기의 속성을 설명하고 나중에 트윈을 만드는 데 사용됩니다.

모델은 다음과 같습니다.

{
    "@id": "dtmi:contosocom:DigitalTwins:Thermostat;1",
    "@type": "Interface",
    "@context": "dtmi:dtdl:context;3",
    "contents": [
      {
        "@type": "Property",
        "name": "Temperature",
        "schema": "double"
      }
    ]
  }

이 모델을 Twins 인스턴스에 업로드하려면 위 모델을 인라인 JSON으로 업로드하는 다음 Azure CLI 명령을 실행합니다. 브라우저의 Azure Cloud Shell(Bash 환경 사용)에서 또는 CLI가 로컬로 설치된 경우 머신에서 명령을 실행할 수 있습니다. 인스턴스의 호스트 이름에 대한 하나의 자리 표시자가 있습니다(성능이 약간 저하된 인스턴스의 식별 이름을 사용할 수도 있음).

az dt model create --dt-name <instance-hostname-or-name> --models '{  "@id": "dtmi:contosocom:DigitalTwins:Thermostat;1",  "@type": "Interface",  "@context": "dtmi:dtdl:context;2",  "contents": [    {      "@type": "Property",      "name": "Temperature",      "schema": "double"    }  ]}' 

참고 항목

Bash 환경에서 Cloud Shell 이외의 것을 사용하는 경우 올바르게 구문 분석되도록 인라인 JSON에서 특정 문자를 이스케이프 처리해야 할 수 있습니다. 자세한 내용은 다른 셸에서 특수 문자 사용을 참조하세요.

그런 다음 이 모델을 사용하여 하나의 트윈을 만들어야 합니다. 다음 명령을 사용하여 thermostat67이라는 자동 온도 조절기 트윈을 만들고 초기 온도 값으로 0.0을 설정합니다. 인스턴스의 호스트 이름에 대한 하나의 자리 표시자가 있습니다(성능이 약간 저하된 인스턴스의 식별 이름을 사용할 수도 있음).

az dt twin create  --dt-name <instance-hostname-or-name> --dtmi "dtmi:contosocom:DigitalTwins:Thermostat;1" --twin-id thermostat67 --properties '{"Temperature": 0.0}'

트윈이 성공적으로 만들어지면 명령의 CLI 출력은 다음과 같습니다.

{
  "$dtId": "thermostat67",
  "$etag": "W/\"0000000-9735-4f41-98d5-90d68e673e15\"",
  "$metadata": {
    "$model": "dtmi:contosocom:DigitalTwins:Thermostat;1",
    "Temperature": {
      "lastUpdateTime": "2021-09-09T20:32:46.6692326Z"
    }
  },
  "Temperature": 0.0
}

Azure 함수 만들기

이 섹션에서는 Azure 함수를 만들어 Azure Digital Twins에 액세스하고 수신되는 IoT 디바이스 원격 분석 이벤트에 따라 트윈을 업데이트합니다. 아래 단계에 따라 함수를 만들고 게시합니다.

  1. 먼저 Event Grid 트리거 유형의 새 Azure Functions 프로젝트를 만듭니다.

    Visual Studio(지침은 Visual Studio를 사용하여 Azure Functions 개발 참조), Visual Studio Code(지침은 Visual Studio Code를 사용하여 Azure에서 C# 함수 만들기 참조) 또는 Azure CLI(지침은 명령줄에서 Azure에 C# 함수 만들기 참조)를 사용하여 이 작업을 수행할 수 있습니다.

  2. 프로젝트에 다음 패키지를 추가합니다. 명령줄 도구에서 Visual Studio NuGet 패키지 관리자 또는 dotnet add package 명령을 사용할 수 있습니다.

  3. IoTHubtoTwins.cs 프로젝트 내에서 함수를 만듭니다. 다음 코드를 함수에 붙여넣습니다.

    using System;
    using Azure;
    using System.Net.Http;
    using Azure.Core.Pipeline;
    using Azure.DigitalTwins.Core;
    using Azure.Identity;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.EventGrid;
    using Microsoft.Extensions.Logging;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using Azure.Messaging.EventGrid;
    
    namespace IotHubtoTwins
    {
        public class IoTHubtoTwins
        {
            private static readonly string adtInstanceUrl = Environment.GetEnvironmentVariable("ADT_SERVICE_URL");
            private static readonly HttpClient httpClient = new HttpClient();
    
            [FunctionName("IoTHubtoTwins")]
            // While async void should generally be used with caution, it's not uncommon for Azure function apps, since the function app isn't awaiting the task.
    #pragma warning disable AZF0001 // Suppress async void error
            public async void Run([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log)
    #pragma warning restore AZF0001 // Suppress async void error
            {
                if (adtInstanceUrl == null) log.LogError("Application setting \"ADT_SERVICE_URL\" not set");
    
                try
                {
                    // Authenticate with Digital Twins
                    var cred = new DefaultAzureCredential();
                    var client = new DigitalTwinsClient(new Uri(adtInstanceUrl), cred);
                    log.LogInformation($"ADT service client connection created.");
                
                    if (eventGridEvent != null && eventGridEvent.Data != null)
                    {
                        log.LogInformation(eventGridEvent.Data.ToString());
    
                        // <Find_device_ID_and_temperature>
                        JObject deviceMessage = (JObject)JsonConvert.DeserializeObject(eventGridEvent.Data.ToString());
                        string deviceId = (string)deviceMessage["systemProperties"]["iothub-connection-device-id"];
                        var temperature = deviceMessage["body"]["Temperature"];
                        // </Find_device_ID_and_temperature>
    
                        log.LogInformation($"Device:{deviceId} Temperature is:{temperature}");
    
                        // <Update_twin_with_device_temperature>
                        var updateTwinData = new JsonPatchDocument();
                        updateTwinData.AppendReplace("/Temperature", temperature.Value<double>());
                        await client.UpdateDigitalTwinAsync(deviceId, updateTwinData);
                        // </Update_twin_with_device_temperature>
                    }
                }
                catch (Exception ex)
                {
                    log.LogError($"Error in ingest function: {ex.Message}");
                }
            }
        }
    }
    

    함수 코드를 저장합니다.

  4. IoTHubtoTwins.cs 함수가 포함된 프로젝트를 Azure의 함수 앱에 게시합니다.

    Visual Studio를 사용하여 함수를 게시하는 방법에 대한 지침은 Visual Studio를 사용하여 Azure Functions 개발을 참조하세요. Visual Studio Code를 사용하여 함수를 게시하는 방법에 대한 지침은 Visual Studio Code를 사용하여 Azure에서 C# 함수 만들기를 참조하세요. Azure CLI를 사용하여 함수를 게시하는 방법에 대한 지침은 명령줄에서 Azure의 C# 함수 만들기를 참조하세요.

함수 게시 프로세스가 완료되면 Azure CLI 명령을 사용하여 게시에 성공했는지 확인할 수 있습니다. 리소스 그룹에 대한 자리 표시자, 함수 앱의 이름이 있습니다. 명령을 실행하면 IoTHubToTwins 함수에 대한 정보가 출력됩니다.

az functionapp function show --resource-group <your-resource-group> --name <your-function-app> --function-name IoTHubToTwins

함수 앱 구성

Azure Digital Twins에 액세스하려면 함수 앱에 Azure Digital Twins 인스턴스에 액세스할 수 있는 권한이 있는 시스템 할당 관리 ID가 필요합니다. 이 섹션에서는 함수에 대한 액세스 역할을 할당하고 Azure Digital Twins 인스턴스에 액세스할 수 있도록 애플리케이션 설정을 구성하여 설정합니다.

Azure Cloud Shell 또는 로컬 Azure CLI에서 다음 명령을 실행합니다.

참고 항목

이 섹션은 Azure 리소스에 대한 사용자 액세스를 관리할 수 있는 권한(권한 부여 및 위임 포함)이 있는 Azure 사용자가 완료해야 합니다. 이 요구 사항을 충족하는 일반적인 역할은 소유자, 계정 관리자 또는 사용자 액세스 관리자기여자의 조합입니다. Azure Digital Twins 역할의 권한 요구 사항에 대한 자세한 내용은 인스턴스 및 인증 설정을 참조하세요.

액세스 역할 할당

Azure 함수에는 전달자 토큰을 전달해야 합니다. 전달자 토큰이 전달되었는지 확인하려면 함수 앱에 Azure Digital Twins 인스턴스에 대한 Azure Digital Twins 데이터 소유자 역할을 부여합니다. 그러면 함수 앱에 인스턴스에 대한 데이터 평면 작업을 수행할 수 있는 권한이 제공됩니다.

  1. 다음 명령을 사용하여 함수에 대한 시스템 관리 ID를 만듭니다(함수에 이미 있는 경우 이 명령은 세부 정보를 출력함). 출력의 principalId 필드를 기록해 두세요. 이 ID를 사용하여 다음 단계에서 해당 권한을 부여할 수 있도록 함수를 참조합니다.

    az functionapp identity assign --resource-group <your-resource-group> --name <your-function-app-name>	
    
  2. 다음 명령에 principalId 값을 사용하여 함수에 Azure Digital Twins 인스턴스의 Azure Digital Twins 데이터 소유자 역할을 부여합니다.

    az dt role-assignment create --dt-name <your-Azure-Digital-Twins-instance> --assignee "<principal-ID>" --role "Azure Digital Twins Data Owner"
    

애플리케이션 설정 구성

다음으로, 환경 변수를 설정하여 함수에서 Azure Digital Twins 인스턴스의 URL에 액세스할 수 있도록 합니다.

Azure Digital Twins 인스턴스의 URL은 인스턴스의 호스트 이름 앞에 https://가 추가되어 만들어집니다. 인스턴스의 모든 속성과 함께 호스트 이름을 확인하려면 az dt show --dt-name <your-Azure-Digital-Twins-instance> 명령을 실행합니다.

다음 명령은 인스턴스에 액세스해야 할 때마다 함수에서 사용할 인스턴스의 URL에 대한 환경 변수를 설정합니다.

az functionapp config appsettings set --resource-group <your-resource-group> --name <your-function-app-name> --settings "ADT_SERVICE_URL=https://<your-Azure-Digital-Twins-instance-host-name>"

함수를 IoT Hub에 연결

이 섹션에서는 IoT 허브 디바이스 데이터의 이벤트 대상으로 함수를 설정합니다. 이러한 방식으로 함수를 설정하면 IoT Hub의 자동 온도 조절기 디바이스에 있는 데이터가 처리를 위해 Azure 함수에 전송됩니다.

다음 CLI 명령을 사용하여 IoT Hub에서 이벤트 데이터를 IoTHubtoTwins 함수로 보내는 데 사용할 이벤트 구독을 만듭니다. 이벤트 구독의 이름을 입력할 자리 표시자가 있으며 구독 ID, 리소스 그룹, IoT 허브 이름 및 함수 앱의 이름을 입력할 수 있는 자리 표시자도 있습니다.

az eventgrid event-subscription create --name <name-for-hub-event-subscription> --event-delivery-schema eventgridschema --source-resource-id /subscriptions/<your-subscription-ID>/resourceGroups/<your-resource-group>/providers/Microsoft.Devices/IotHubs/<your-IoT-hub> --included-event-types Microsoft.Devices.DeviceTelemetry --endpoint-type azurefunction --endpoint /subscriptions/<your-subscription-ID>/resourceGroups/<your-resource-group>/providers/Microsoft.Web/sites/<your-function-app>/functions/IoTHubtoTwins

출력에는 생성된 이벤트 구독에 대한 정보가 표시됩니다. 결과의 provisioningState 값을 확인하여 작업이 성공적으로 완료되었는지 확인할 수 있습니다.

"provisioningState": "Succeeded",

시뮬레이션된 IoT 데이터로 테스트

엔드투엔드 솔루션 연결의 디바이스 시뮬레이터를 사용하여 새 수신 함수를 테스트할 수 있습니다. DeviceSimulator 프로젝트에는 샘플 온도 데이터를 보내는 시뮬레이션된 자동 온도 조절기 디바이스가 포함되어 있습니다. 디바이스 시뮬레이터를 설정하려면 다음 단계를 수행합니다.

  1. Azure Digital Twins 엔드투엔드 샘플 프로젝트 리포지토리로 이동합니다. 제목 아래에서 코드 찾아보기 단추를 선택하여 컴퓨터에서 샘플 프로젝트를 가져옵니다. 그러면 코드 단추를 선택한 다음, ZIP 다운로드를 선택하여 .zip으로 다운로드할 수 있는 샘플용 GitHub 리포지토리로 이동합니다.

    그러면 .zip 폴더가 digital-twins-samples-master.zip으로 컴퓨터에 다운로드됩니다. 폴더의 압축을 풀고 파일을 추출합니다. DeviceSimulator 프로젝트 폴더를 사용하게 됩니다.

  2. IoT Hub에 시뮬레이션된 디바이스 등록

  3. 시뮬레이션 구성 및 실행

이러한 단계를 완료한 후에는 프로젝트 콘솔 창이 실행되어야 하고 시뮬레이션된 디바이스 원격 분석 데이터를 IoT 허브로 보내야 합니다.

Screenshot of the output from the device simulator project.

결과 유효성 검사

위의 디바이스 시뮬레이터를 실행하는 동안 자동 온도 조절기 디지털 트윈의 온도 값이 변경됩니다. Azure CLI에서 다음 명령을 실행하여 온도 값을 확인합니다. 인스턴스의 호스트 이름에 대한 하나의 자리 표시자가 있습니다(성능이 약간 저하된 인스턴스의 식별 이름을 사용할 수도 있음).

az dt twin query --query-command "SELECT * FROM digitaltwins WHERE \$dtId = 'thermostat67'" --dt-name <instance-hostname-or-name>

참고 항목

Bash 환경에서 Cloud Shell 이외의 것을 사용하는 경우 올바르게 구문 분석되도록 쿼리에서 $ 문자를 이스케이프 처리해야 할 수 있습니다. 자세한 내용은 다른 셸에서 특수 문자 사용을 참조하세요.

출력은 다음과 같이 온도 값을 포함하여 thermostat67 트윈의 세부 정보를 표시해야 합니다.

{
  "result": [
    {
      "$dtId": "thermostat67",
      "$etag": "W/\"dbf2fea8-d3f7-42d0-8037-83730dc2afc5\"",
      "$metadata": {
        "$model": "dtmi:contosocom:DigitalTwins:Thermostat;1",
        "Temperature": {
          "lastUpdateTime": "2021-06-03T17:05:52.0062638Z"
        }
      },
      "Temperature": 70.20518558807913
    }
  ]
}

Temperature 값 변경을 보려면 위의 쿼리 명령을 반복해서 실행합니다.

다음 단계

Azure Digital Twins를 사용한 데이터 수신 및 송신에 대해 알아봅니다.