Azure Digital Twins 데이터를 Azure Maps 실내 맵에 통합

이 문서에서는 Azure Digital Twins 데이터를 사용하여 Azure Maps에서 실내 맵에 표시된 정보를 업데이트하는 방법을 보여 줍니다. Azure Digital Twins는 IoT 디바이스 관계의 그래프를 저장하고 여러 엔드포인트에 디바이스 데이터를 라우팅하기 때문에 맵에서 정보 오버레이를 업데이트하는 데 유용한 서비스를 사용할 수 있습니다.

이 가이드에는 다음과 같은 정보가 포함되어 있습니다.

  1. Azure Functions의 함수에 트윈 업데이트 이벤트를 보내도록 Azure Digital Twins 인스턴스 구성
  2. Azure Maps 실내 맵 기능 상태 세트를 업데이트하는 함수 생성
  3. Azure Digital Twins 그래프에서 맵 ID와 기능 상태 세트 ID를 저장합니다.

시작하기

이 섹션에서는 이 문서의 정보에 대한 추가 컨텍스트를 설정합니다.

필수 조건

이 문서를 진행하기 전에 먼저 개별 Azure Digital Twins 및 Azure Maps 리소스를 설정합니다.

  • Azure Digital Twins의 경우: 엔드투엔드 솔루션 연결의 지침에 따라 샘플 트윈 그래프 및 시뮬레이션된 데이터 흐름으로 Azure Digital Twins 인스턴스를 설정합니다.
    • 이 문서에서는 다른 엔드포인트 및 경로를 사용하여 해당 솔루션을 확장합니다. 또한 이 자습서의 함수 앱에 다른 함수를 추가합니다.
  • Azure Maps 경우: Creator를 사용하여 실내 맵 만들기기능 상태 세트 만들기의 지침에 따라 기능 상태 세트가 있는 Azure Maps 실내 맵을 만듭니다.
    • 기능 상태 세트는 방 또는 장비와 같은 데이터 세트 기능에 할당된 동적 속성의 컬렉션(상태)입니다. 위의 Azure Maps 지침에서 기능 상태 세트는 맵에 표시되는 방 상태를 저장합니다.
    • Azure Maps 구독 키, 기능 상태 세트 IDmapConfiguration이 필요합니다.

토폴로지

아래 이미지는 이 자습서의 실내 맵 통합 요소가 더 큰 엔드투엔드 Azure Digital Twins 시나리오에 적합한 경우를 보여 줍니다.

Diagram of Azure services in an end-to-end scenario, highlighting the Indoor Maps Integration piece.

Azure Digital Twins에서 트윈 업데이트 알림 라우팅

Azure Digital Twins 인스턴스는 트윈의 상태가 업데이트될 때마다 트윈 업데이트 이벤트를 내보낼 수 있습니다. 위에 링크된 Azure Digital Twins 엔드투엔드 솔루션 연결에서는 온도계를 사용하여 방의 트윈에 연결된 온도 특성을 업데이트하는 시나리오를 안내합니다. 이 자습서에서는 Azure 함수를 구독하여 트윈의 알림을 업데이트하고 해당 함수를 사용하여 맵을 업데이트하여 해당 솔루션을 확장합니다.

이 패턴은 IoT 디바이스가 아닌 방 트윈에서 직접 읽어 매핑 논리를 업데이트할 필요 없이 온도에 대한 기본 데이터 원본을 유연하게 변경할 수 있도록 합니다. 예를 들어 맵 논리를 업데이트할 필요 없이, 여러 개의 온도계를 추가하거나 다른 방과 온도계를 공유하도록 이 방을 설정할 수 있습니다.

먼저 모든 트윈 업데이트 이벤트를 Event Grid 토픽으로 전달하기 위해 Azure Digital Twins에서 경로를 만듭니다.

  1. 아래의 CLI 명령을 사용하여 Azure Digital Twins 인스턴스에서 이벤트를 수신하는 이벤트 그리드 토픽을 만듭니다.

    az eventgrid topic create --resource-group <your-resource-group-name> --name <your-topic-name> --location <region>
    
  2. 아래의 CLI 명령을 사용하여 Event Grid 토픽을 Azure Digital Twins에 연결하는 엔드포인트를 만듭니다.

    az dt endpoint create eventgrid --endpoint-name <Event-Grid-endpoint-name> --eventgrid-resource-group <Event-Grid-resource-group-name> --eventgrid-topic <your-Event-Grid-topic-name> --dt-name <your-Azure-Digital-Twins-instance-name>
    
  3. Azure Digital Twins에서 경로를 만들어 아래의 CLI 명령을 사용하여 엔드포인트로 트윈 업데이트 이벤트를 보냅니다. 이 명령의 Azure Digital Twins 인스턴스 이름 자리 표시자의 경우 식별 이름 또는 호스트 이름을 사용하여 성능을 높일 수 있습니다.

    참고 항목

    Cloud Shell에는 az dt route, az dt model, az dt twin 명령 그룹에 영향을 주는 알려진 문제가 있습니다.

    이 문제를 해결하려면 명령을 실행하기 전에 Cloud Shell에서 az login을 실행하거나 Cloud Shell 대신 로컬 CLI를 사용합니다. 이에 대한 자세한 내용은 Azure Digital Twins 알려진 문제를 참조하세요.

    az dt route create --dt-name <your-Azure-Digital-Twins-instance-hostname-or-name> --endpoint-name <Event-Grid-endpoint-name> --route-name <my-route> --filter "type = 'Microsoft.DigitalTwins.Twin.Update'"
    

이벤트를 수신하고 맵을 업데이트하는 Azure 함수 만들기

이 섹션에서는 Event Grid 토픽으로 전송된 이벤트를 수신 대기하는 함수를 만듭니다. 이 함수는 이러한 업데이트 알림을 읽고 Azure Maps 기능 상태 세트에 해당 업데이트를 보내서 한 방의 온도를 업데이트합니다.

Azure Digital Twins 자습서 필수 구성 요소에서 Azure 함수 Azure Digital Twins를 저장하는 함수 앱을 만들었습니다. 이제 함수 앱 내에 새 Event Grid 트리거 Azure 함수를 만듭니다.

함수 코드를 다음 코드로 바꿉니다. 이렇게 하면 공간 트윈에 대한 업데이트만 필터링하고 업데이트된 온도를 읽고 해당 정보를 Azure Maps로 보냅니다.

using System;
using System.Threading.Tasks;
using System.Net.Http;
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 updateMaps
{
    public static class ProcessDTUpdatetoMaps
    {
        // Read maps credentials from application settings on function startup
        private static string statesetID = Environment.GetEnvironmentVariable("statesetID");
        private static string subscriptionKey = Environment.GetEnvironmentVariable("subscription-key");
        private static HttpClient httpClient = new HttpClient();

        [FunctionName("ProcessDTUpdatetoMaps")]
        public static async Task Run([EventGridTrigger]EventGridEvent eventGridEvent, ILogger log)
        {
            JObject message = (JObject)JsonConvert.DeserializeObject(eventGridEvent.Data.ToString());
            log.LogInformation($"Reading event from twinID: {eventGridEvent.Subject}: {eventGridEvent.EventType}: {message["data"]}");

            //Parse updates to "space" twins
            if (message["data"]["modelId"].ToString() == "dtmi:contosocom:DigitalTwins:Space;1")
            {
                // Set the ID of the room to be updated in your map.
                // Replace this line with your logic for retrieving featureID.
                string featureID = "UNIT103";

                // Iterate through the properties that have changed
                foreach (var operation in message["data"]["patch"])
                {
                    if (operation["op"].ToString() == "replace" && operation["path"].ToString() == "/Temperature")
                    {
                        // Update the maps feature stateset
                        var postcontent = new JObject(
                            new JProperty(
                                "States",
                                new JArray(
                                    new JObject(
                                        new JProperty("keyName", "temperature"),
                                        new JProperty("value", operation["value"].ToString()),
                                        new JProperty("eventTimestamp", DateTime.UtcNow.ToString("s"))))));

                        var response = await httpClient.PutAsync(
                            $"https://us.atlas.microsoft.com/featurestatesets/{statesetID}/featureStates/{featureID}?api-version=2.0&subscription-key={subscriptionKey}",
                            new StringContent(postcontent.ToString()));


                        log.LogInformation(await response.Content.ReadAsStringAsync());
                    }
                }
            }
        }
    }
}

함수 앱에서 두 개의 환경 변수를 설정해야 합니다. 하나는 Azure Maps 기본 구독 키이고 하나는 Azure Maps 상태 세트 ID입니다.

az functionapp config appsettings set --name <your-function-app-name> --resource-group <your-resource-group> --settings "subscription-key=<your-Azure-Maps-primary-subscription-key>"
az functionapp config appsettings set --name <your-function-app-name> --resource-group <your-resource-group> --settings "statesetID=<your-Azure-Maps-stateset-ID>"

맵에서 라이브 업데이트 보기

라이브 업데이트 온도를 보려면 다음 단계를 수행합니다.

  1. Azure Digital Twins 엔드투엔드 솔루션 연결에서 DeviceSimulator 프로젝트를 실행하여 시뮬레이션된 IoT 데이터 보내기를 시작합니다. 이 프로세스에 대한 지침은 시뮬레이션 구성 및 실행 섹션에 있습니다.
  2. Azure Maps Indoor 모듈을 사용하여 Azure Maps Creator에서 만든 실내 맵을 렌더링할 수 있습니다.
    1. 예제: 사용자 지정 스타일 지정: WebSDK에서 맵 구성 사용(미리 보기)에서 예제 실내 맵 HTML 파일을 복사합니다.
    2. 로컬 HTML 파일에서 subscription key, mapConfiguration, statesetIDregion을 사용자의 값으로 바꿉니다.
    3. 브라우저에서 파일을 엽니다.

두 샘플 모두 호환 범위로 온도를 보내므로 30초마다 맵에 121호 방 업데이트의 색이 표시됩니다.

Screenshot of an office map showing room 121 colored orange.

Azure Digital Twins에 맵 정보 저장

이제 맵 정보를 업데이트하는 하드 코드된 솔루션이 있으므로 Azure Digital Twins 그래프를 사용하여 실내 맵을 업데이트하는 데 필요한 모든 정보를 저장할 수 있습니다. 이 정보에는 각 맵과 위치의 상태 세트 ID, 맵 구독 ID, 기능 ID가 각각 포함됩니다.

이 특정 예제에 대한 솔루션에는 각 최상위 공간에서 상태 세트 ID를 업데이트하고 구독 ID 특성을 매핑하고 기능 ID를 포함하도록 각 방을 업데이트하는 작업이 포함됩니다. 트윈 그래프를 초기화할 때 이러한 값을 한 번 설정한 다음, 각 트윈 업데이트 이벤트에 대해 해당 값을 쿼리해야 합니다.

토폴로지의 구성에 따라 맵의 세분성과 관련하여 서로 다른 수준으로 이러한 세 가지 특성을 저장할 수 있습니다.

다음 단계

트윈 그래프에서 정보를 관리, 업그레이드, 검색하는 방법에 대한 자세한 내용은 다음 참조를 참조하세요.