디바이스 쌍 시작(Node.js)

디바이스 쌍은 메타데이터, 구성, 조건을 비롯한 디바이스 상태 정보를 저장하는 JSON 문서입니다. IoT Hub는 여기에 연결하는 각 디바이스에 대해 하나의 디바이스 쌍을 유지합니다.

참고 항목

이 문서에서 설명하는 기능은 IoT Hub의 표준 계층에서만 사용할 수 있습니다. 기본 및 표준/무료 IoT Hub 계층에 대한 자세한 내용은 솔루션에 적합한 IoT Hub 계층 선택을 참조하세요.

디바이스 쌍의 용도:

  • 솔루션 백 엔드의 디바이스 메타데이터를 저장합니다.

  • 디바이스 앱의 사용 가능한 기능 및 상태(예: 사용된 연결 방법)와 같은 현재 상태 정보를 보고합니다.

  • 디바이스 앱과 백 엔드 앱 간에 장기 실행 워크플로(예: 펌웨어 및 구성 업데이트)의 상태를 동기화합니다.

  • 디바이스 메타데이터, 구성 또는 상태를 쿼리합니다.

디바이스 쌍은 디바이스 구성 및 상태를 동기화하고 쿼리하기 위해 설계되었습니다. 디바이스 쌍을 사용하는 경우를 포함한 디바이스 쌍에 대한 자세한 내용은 디바이스 쌍 이해를 참조하세요.

IoT 허브는 다음 요소를 포함하는 디바이스 쌍을 저장합니다.

  • 태그. 솔루션 백 엔드만 액세스할 수 있는 디바이스 메타데이터입니다.

  • desired 속성. 솔루션 백 엔드에서 수정할 수 있고 디바이스 앱에서 관찰할 수 있는 JSON 개체입니다.

  • reported 속성. 디바이스 앱에서 수정할 수 있고 솔루션 백 엔드에서 읽을 수 있는 JSON 개체입니다.

태그 및 속성은 배열을 포함할 수 없지만 중첩된 개체를 포함할 수 있습니다.

다음 그림은 디바이스 쌍 조직을 보여 줍니다.

디바이스 쌍 개념 다이어그램의 스크린샷

또한 솔루션 백 엔드는 위의 모든 데이터를 기반으로 하는 디바이스 쌍을 쿼리할 수 있습니다. 디바이스 쌍에 대한 자세한 내용은 디바이스 쌍 이해를 참조하세요. 쿼리에 대한 자세한 내용은 IoT Hub 쿼리 언어를 참조하세요.

이 문서는 다음을 수행하는 방법을 보여줍니다.

  • 시뮬레이션된 디바이스 앱을 사용하여 해당 연결 채널을 디바이스 쌍의 reported 속성으로 보고합니다.

  • 이전에 만든 태그 및 속성에 필터를 사용하여 백 엔드 앱에서 디바이스를 쿼리합니다.

이 문서에서는 두 개의 Node.js 콘솔 앱을 만듭니다.

  • AddTagsAndQuery.js: 태그를 추가하고 디바이스 쌍을 쿼리하는 백 엔드 앱입니다.

  • TwinSimulatedDevice.js: IoT 허브에 연결하고 연결 상태를 보고하는 시뮬레이션된 디바이스 앱입니다.

참고 항목

디바이스 및 백 엔드 앱을 빌드하는 데 사용할 수 있는 SDK 도구에 대한 자세한 내용은 Azure IoT SDK를 참조하세요.

필수 조건

이 문서를 완료하려면 다음이 필요합니다.

  • IoT 허브. CLI 또는 Azure Portal을 사용하여 만듭니다.

  • 등록된 디바이스. Azure Portal에 하나를 등록합니다.

  • Node.js 버전 10.0.x 이상.

  • 방화벽에서 포트 8883이 열려 있는지 확인합니다. 이 문서의 디바이스 샘플은 포트 8883을 통해 통신하는 MQTT 프로토콜을 사용합니다. 이 포트는 일부 회사 및 교육용 네트워크 환경에서 차단될 수 있습니다. 이 문제를 해결하는 자세한 내용과 방법은 IoT Hub에 연결(MQTT)을 참조하세요.

IoT Hub 연결 문자열 가져오기

이 문서에서는 디바이스 쌍에 원하는 속성을 추가하고 ID 레지스트리를 쿼리하여 그에 따라 업데이트된 보고된 속성이 있는 모든 디바이스를 찾는 백 엔드 서비스를 만듭니다. 서비스는 디바이스 쌍의 원하는 속성을 수정하려면 서비스 연결 권한이 필요하며, ID 레지스트리를 쿼리하기 위한 레지스트리 읽기 권한이 필요합니다. 이러한 두 가지 권한만 포함하는 기본 공유 액세스 정책은 없으므로 만들어야 합니다.

서비스 연결레지스트리 읽기 권한을 부여하는 공유 액세스 정책을 만들고 이 정책에 대한 연결 문자열을 가져오려면 다음 단계를 수행합니다.

  1. Azure Portal에서 리소스 그룹을 선택합니다. 허브가 있는 리소스 그룹을 선택한 다음, 리소스 목록에서 허브를 선택합니다.

  2. 허브의 왼쪽 창에서 공유 액세스 정책을 선택합니다.

  3. 정책 목록 위의 상단 메뉴에서 공유 정책 액세스 정책 추가를 선택합니다.

  4. 오른쪽의 공유 액세스 정책 추가 창에서 정책에 사용할 설명형 이름(예: serviceAndRegistryRead)을 입력합니다. 권한에서 레지스트리 읽기서비스 연결을 선택한 다음 추가를 선택합니다.

    새 공유 액세스 정책을 추가하는 방법을 보여 주는 화면 캡처

  5. 정책 목록에서 새 정책을 선택합니다.

  6. 기본 연결 문자열의 복사 아이콘을 선택하고 값을 저장합니다.

    연결 문자열을 검색하는 방법을 보여 주는 화면 캡처.

IoT Hub 공유 액세스 정책 및 사용 권한에 대한 자세한 내용은 액세스 제어 및 권한을 참조하세요.

보고된 속성을 업데이트하는 디바이스 앱 만들기

이 섹션에서는 허브에 myDeviceId로 연결하는 Node.js 콘솔 앱을 만든 다음, 디바이스 쌍의 reported 속성을 업데이트하여 셀룰러 네트워크를 사용하여 연결되었는지 확인합니다.

  1. reportconnectivity라는 빈 폴더를 새로 만듭니다. reportconnectivity 폴더의 명령 프롬프트에서 다음 명령을 사용하여 package.json 파일을 만듭니다. --yes 매개 변수는 모든 기본값을 허용합니다.

    npm init --yes
    
  2. reportconnectivity 폴더의 명령 프롬프트에서 다음 명령을 실행하여 azure-iot-deviceazure-iot-device-mqtt 패키지를 설치합니다.

    npm install azure-iot-device azure-iot-device-mqtt --save
    
  3. 텍스트 편집기를 사용하여 reportconnectivity 폴더에 새 ReportConnectivity.js 파일을 만듭니다.

  4. ReportConnectivity.js 파일에 다음 코드를 추가합니다. {device connection string}을 IoT Hub에 디바이스를 등록할 때 본 디바이스 연결 문자열로 바꿉니다.

        'use strict';
        var Client = require('azure-iot-device').Client;
        var Protocol = require('azure-iot-device-mqtt').Mqtt;
    
        var connectionString = '{device connection string}';
        var client = Client.fromConnectionString(connectionString, Protocol);
    
        client.open(function(err) {
        if (err) {
            console.error('could not open IotHub client');
        }  else {
            console.log('client opened');
    
            client.getTwin(function(err, twin) {
            if (err) {
                console.error('could not get twin');
            } else {
                var patch = {
                    connectivity: {
                        type: 'cellular'
                    }
                };
    
                twin.properties.reported.update(patch, function(err) {
                    if (err) {
                        console.error('could not update twin');
                    } else {
                        console.log('twin state reported');
                        process.exit();
                    }
                });
            }
            });
        }
        });
    

    Client 개체는 서비스의 디바이스 쌍을 조작하는 데 필요한 모든 메서드를 표시합니다. 이전 코드에서는 Client 개체를 초기화한 후 myDeviceId에 대한 디바이스 쌍을 검색하고, 연결 정보로 reported 속성을 업데이트합니다.

  5. 디바이스 앱 실행

        node ReportConnectivity.js
    

    메시지 twin state reported이 표시되어야 합니다.

  6. 디바이스가 연결 정보를 보고했으므로 두 쿼리 모두에 나타나야 합니다. addtagsandqueryapp 폴더로 돌아가 쿼리를 다시 실행합니다.

        node AddTagsAndQuery.js
    

    이번에는 myDeviceId가 두 쿼리 결과에 모두 나타나야 합니다.

    두 쿼리 결과에 myDeviceId 표시

원하는 속성을 업데이트하고 쌍을 쿼리하는 서비스 앱 만들기

이 섹션에서는 myDeviceId와 연결된 디바이스 쌍에 위치 메타데이터를 추가하는 Node.js 콘솔 앱을 만듭니다. 앱은 미국에 있는 디바이스에 대한 IoT 허브를 쿼리한 다음, 셀룰러 네트워크 연결을 보고하는 디바이스를 쿼리합니다.

  1. addtagsandqueryapp라는 빈 폴더를 새로 만듭니다. addtagsandqueryapp 폴더의 명령 프롬프트에 다음 명령을 사용하여 package.json 파일을 만듭니다. --yes 매개 변수는 모든 기본값을 허용합니다.

    npm init --yes
    
  2. addtagsandqueryapp 폴더의 명령 프롬프트에서 다음 명령을 실행하여 azure-iothub 패키지를 설치합니다.

    npm install azure-iothub --save
    
  3. 텍스트 편집기를 사용하여 addtagsandqueryapp 폴더에 새 AddTagsAndQuery.js 파일을 만듭니다.

  4. AddTagsAndQuery.js 파일에 다음 코드를 추가합니다. {iot hub connection string}IoT Hub 연결 문자열 가져오기에서 복사한 IoT hub 연결 문자열로 바꿉니다.

         'use strict';
         var iothub = require('azure-iothub');
         var connectionString = '{iot hub connection string}';
         var registry = iothub.Registry.fromConnectionString(connectionString);
    
         registry.getTwin('myDeviceId', function(err, twin){
             if (err) {
                 console.error(err.constructor.name + ': ' + err.message);
             } else {
                 var patch = {
                     tags: {
                         location: {
                             region: 'US',
                             plant: 'Redmond43'
                       }
                     }
                 };
    
                 twin.update(patch, function(err) {
                   if (err) {
                     console.error('Could not update twin: ' + err.constructor.name + ': ' + err.message);
                   } else {
                     console.log(twin.deviceId + ' twin updated successfully');
                     queryTwins();
                   }
                 });
             }
         });
    

    레지스트리 개체는 서비스의 디바이스 쌍을 조작하는 데 필요한 모든 메서드를 표시합니다. 이전 코드는 Registry 개체를 초기화한 다음, myDeviceId에 대한 디바이스 쌍을 검색하고, 마지막으로 원하는 위치 정보를 사용해 태그를 업데이트합니다.

    태그를 업데이트한 후에는 queryTwins 함수를 호출합니다.

  5. 다음 코드를 queryTwins 함수를 구현할 AddTagsAndQuery.js 끝 부분에 추가합니다.

         var queryTwins = function() {
             var query = registry.createQuery("SELECT * FROM devices WHERE tags.location.plant = 'Redmond43'", 100);
             query.nextAsTwin(function(err, results) {
                 if (err) {
                     console.error('Failed to fetch the results: ' + err.message);
                 } else {
                     console.log("Devices in Redmond43: " + results.map(function(twin) {return twin.deviceId}).join(','));
                 }
             });
    
             query = registry.createQuery("SELECT * FROM devices WHERE tags.location.plant = 'Redmond43' AND properties.reported.connectivity.type = 'cellular'", 100);
             query.nextAsTwin(function(err, results) {
                 if (err) {
                     console.error('Failed to fetch the results: ' + err.message);
                 } else {
                     console.log("Devices in Redmond43 using cellular network: " + results.map(function(twin) {return twin.deviceId}).join(','));
                 }
             });
         };
    

    이전 코드는 두 개의 쿼리를 실행합니다. 첫 번째는 Redmond43 공장에 위치한 디바이스의 디바이스 쌍만을 선택하고, 두 번째는 또한 셀룰러 네트워크를 통해서 연결된 디바이스만을 선택하기 위해 쿼리를 구체화합니다.

    코드는 query 개체를 만들 때 두 번째 매개 변수에서 반환되는 최대 문서 수를 지정합니다. query 개체에는 모든 결과를 검색하기 위해 여러번 nextAsTwin 메서드를 호출하는 데 사용할 수 있는 hasMoreResults 부울 속성이 들어 있습니다. next라는 메서드는 디바이스 쌍이 아닌 결과(예: 집계 쿼리의 결과)에 대해 사용할 수 있습니다.

  6. 다음으로 애플리케이션을 실행합니다.

        node AddTagsAndQuery.js
    

    Redmond43에 위치한 모든 디바이스를 요청하는 쿼리에 대한 결과로는 하나의 디바이스를 보고 셀룰러 네트워크를 사용하는 디바이스에 대해서는 결과를 제한하는 쿼리에 대한 결과로는 아무 디바이스도 볼 수 없어야 합니다.

    쿼리 결과에서 하나의 디바이스 확인

이 문서에서는 다음 작업을 수행합니다.

  • 백 엔드 앱에서 태그로 디바이스 메타데이터 추가
  • 디바이스 쌍에서 보고된 디바이스 연결 정보
  • SQL과 유사한 IoT Hub 쿼리 언어를 사용하여 디바이스 쌍 정보를 쿼리함

다음 단계

방법을 알아보려면 다음을 참조하세요.