다음을 통해 공유


Device Update에 구성 요소 등록

이 문서에서는 IoT Hub 구성 요소 열거자에 대한 Device Update 구현의 예제를 보여 줍니다. 이 예제를 참조하여 IoT 디바이스에 대한 사용자 지정 구성 요소 열거자를 구현할 수 있습니다. 구성 요소는 호스트 디바이스와 컴퍼지션 관계가 있는 디바이스 수준 바로 아래의 ID입니다.

이 문서에서는 Contoso Virtual Vacuum이라는 가상 IoT 디바이스를 사용하는 구성 요소 열거자를 보여 줍니다. 구성 요소 열거자는 프록시 업데이트 기능을 구현하는 데 사용됩니다.

프록시 업데이트를 사용하면 단일 무선 배포를 통해 동일한 IoT 디바이스 또는 IoT 디바이스에 연결된 여러 센서에서 여러 구성 요소를 업데이트할 수 있습니다. 프록시 업데이트는 구성 요소를 업데이트하기 위한 설치 순서를 지원합니다. 또한 사전 설치, 설치 및 사후 설치 기능을 사용하여 다단계 업데이트를 지원합니다.

프록시 업데이트가 적용되는 사용 사례는 다음과 같습니다.

  • 디바이스의 파티션을 특정 업데이트 파일의 대상으로 지정합니다.
  • 디바이스의 앱 또는 구성 요소를 특정 업데이트 파일의 대상으로 지정합니다.
  • 네트워크 프로토콜(예: USB 또는 CAN 버스)을 통해 IoT 디바이스에 연결된 센서를 특정 업데이트 파일의 대상으로 지정합니다.

자세한 내용은 프록시 업데이트 및 다중 구성 요소 업데이트를 참조하세요.

Device Update 에이전트는 호스트 디바이스에서 실행됩니다. 각 업데이트를 특정 구성 요소 또는 동일한 하드웨어 클래스의 구성 요소 그룹으로 보낼 수 있습니다(즉, 동일한 소프트웨어 또는 펌웨어 업데이트 필요).

구성 요소 열거자란?

구성 요소 열거자는 호스트 디바이스의 Azure IoT Hub 연결을 통한 무선 업데이트에 필요한 모든 구성 요소에 대한 정보를 제공하는 Device Update 에이전트의 확장입니다.

Device Update 에이전트는 디바이스와 구성 요소와 관련이 없습니다. 그 자체로 에이전트는 업데이트 시 호스트 디바이스의 구성 요소(또는 연결된 구성 요소)에 관해 아무것도 알지 못합니다.

프록시 업데이트를 사용하도록 설정하려면 디바이스 작성기에서 업데이트할 수 있는 디바이스의 모든 구성 요소를 식별하고 고유한 이름을 각 구성 요소에 할당해야 합니다. 또한 동일한 하드웨어 클래스의 구성 요소에 그룹 이름을 할당하면 동일한 그룹의 모든 구성 요소에 동일한 업데이트를 설치할 수 있습니다. 그런 다음, 업데이트 콘텐츠 처리기에서 업데이트를 설치하고 올바른 구성 요소에 적용할 수 있습니다.

프록시 업데이트 흐름을 보여 주는 다이어그램

프록시 업데이트 흐름의 각 부분에 대한 책임은 다음과 같습니다.

  • 디바이스 작성기

    • 디바이스를 디자인하고 빌드합니다.

    • Device Update 에이전트와 해당 종속성을 통합합니다.

    • 디바이스별 구성 요소 열거자 확장을 구현하고 Device Update 에이전트에 등록합니다.

      구성 요소 열거자는 구성 요소 인벤토리 또는 구성 파일의 정보를 사용하여 동적 데이터(예: 펌웨어 버전, 연결 상태, 하드웨어 ID)로 정적 구성 요소 데이터(Device Update 필요)를 보강합니다.

    • 디바이스에 있거나 디바이스에 연결된 하나 이상의 구성 요소를 대상으로 하는 하나 이상의 자식 업데이트를 포함하는 프록시 업데이트를 만듭니다.

    • 솔루션 운영자에게 업데이트를 보냅니다.

  • 솔루션 운영자

    • 업데이트 및 매니페스트를 Device Update 서비스로 가져옵니다.

    • 디바이스 그룹에 업데이트를 배포합니다.

  • Device Update 에이전트

    • 디바이스 쌍 또는 모듈 쌍을 통해 IoT Hub에서 업데이트 정보를 가져옵니다.

    • 단계 처리기를 호출하여 디바이스에서 하나 이상의 구성 요소에 대한 의도된 프록시 업데이트를 처리합니다.

      이 문서의 예제에는 host-fw-1.1motors-fw-1.1의 두 가지 업데이트가 있습니다. 각 자식 업데이트를 위해 부모 단계 처리기는 자식 단계 처리기를 호출하여 자식 업데이트의 매니페스트 파일에 지정된 Compatibilities 속성과 일치하는 모든 구성 요소를 열거합니다. 다음으로, 처리기는 모든 대상 구성 요소에 대한 자식 업데이트를 다운로드, 설치, 적용합니다.

      일치하는 구성 요소를 가져오기 위해 자식 업데이트는 구성 요소 열거자가 제공하는 SelectComponents API를 호출합니다. 일치하는 구성 요소가 없으면 자식 업데이트를 건너뜁니다.

    • 부모 및 자식 업데이트에서 모든 업데이트 결과를 수집하고 해당 결과를 IoT Hub에 보고합니다.

  • 자식 단계 처리기

    • 자식 업데이트 콘텐츠와 호환되는 구성 요소 인스턴스 목록을 반복합니다. 자세한 내용은 단계 처리기를 참조하세요.

프로덕션 환경에서 디바이스 작성기는 기존 처리기를 사용하거나 무선 업데이트에 필요한 모든 설치 프로그램을 호출하는 사용자 지정 처리기를 구현할 수 있습니다. 자세한 내용은 사용자 지정 업데이트 콘텐츠 처리기 구현을 참조하세요.

Virtual Vacuum 구성 요소

이 문서에서는 가상 IoT 디바이스를 사용하여 주요 개념과 기능을 보여 줍니다. Contoso Virtual Vacuum 디바이스는 다음 5개의 논리적 구성 요소로 구성됩니다.

  • 호스트 펌웨어
  • 호스트 부팅 파일 시스템
  • 호스트 루트 파일 시스템
  • 모터 3개(왼쪽 휠, 오른쪽 휠, 진공 청소기)
  • 카메라 2개(전면, 후면)

Contoso Virtual Vacuum 구성 요소를 보여 주는 다이어그램

다음 디렉터리 구조는 구성 요소를 시뮬레이션합니다.

/usr/local/contoso-devices/vacuum-1/hostfw
/usr/local/contoso-devices/vacuum-1/bootfs
/usr/local/contoso-devices/vacuum-1/rootfs
/usr/local/contoso-devices/vacuum-1/motors/0   /* left motor */
/usr/local/contoso-devices/vacuum-1/motors/1   /* right motor */
/usr/local/contoso-devices/vacuum-1/motors/2   /* vacuum motor */
/usr/local/contoso-devices/vacuum-1/cameras/0  /* front camera */
/usr/local/contoso-devices/vacuum-1/cameras/1  /* rear camera */

각 구성 요소의 디렉터리에는 각 구성 요소의 모의 소프트웨어 버전 번호를 저장하는 JSON 파일이 포함됩니다. 예제 JSON 파일은 firmware.jsondiskimage.json입니다.

이 데모에서는 구성 요소의 펌웨어를 업데이트하기 위해 firmware.json 또는 diskimage.json(업데이트 페이로드)을 대상 구성 요소의 디렉터리에 복사합니다.

다음은 예제 firmware.json 파일입니다.

{
    "version": "0.5",
    "description": "This component is generated for testing purposes."
}

참고 항목

Contoso Virtual Vacuum에는 프록시 업데이트 데모를 위한 소프트웨어 또는 펌웨어 버전이 포함됩니다. 다른 기능은 제공하지 않습니다.

구성 요소 열거자 구현(C 언어)

요구 사항

component_enumerator_extension.hpp에 선언된 모든 API를 구현합니다.

함수 인수 반환
char* GetAllComponents() 없음 모든 ComponentInfo 값의 배열을 포함하는 JSON 문자열입니다. 자세한 내용은 예제 반환 값을 참조하세요.
char* SelectComponents(char* selector) 업데이트 대상 구성 요소를 선택하는 데 사용되는 하나 이상의 이름/값 쌍을 포함하는 JSON 문자열입니다. ComponentInfo 값의 배열을 포함하는 JSON 문자열입니다. 자세한 내용은 예제 반환 값을 참조하세요.
void FreeComponentsDataString(char* string) GetAllComponents 또는 SelectComponents 함수에서 이전에 반환된 문자열 버퍼에 대한 포인터입니다. 없음

ComponentInfo

ComponentInfo JSON 문자열에는 다음 속성이 포함되어야 합니다.

이름 형식 설명
id string 구성 요소의 고유 ID(디바이스 범위)입니다. 예를 들어, 하드웨어 일련 번호, 디스크 파티션 ID, 구성 요소의 고유 파일 경로 등이 있습니다.
name string 구성 요소의 논리적 이름입니다. 이 속성은 디바이스 작성기에서 동일한 device 클래스의 모든 디바이스에서 사용할 수 있는 구성 요소에 할당하는 이름입니다.

예를 들어, 모든 Contoso Virtual Vacuum 디바이스에는 왼쪽 휠을 구동하는 모터가 포함됩니다. Contoso는 이 모터가 전역으로 고유할 수 있는 하드웨어 ID 대신 이 구성 요소를 쉽게 참조할 수 있도록 왼쪽 모터를 일반(논리적) 이름으로 할당했습니다.
group string 이 구성 요소가 속한 그룹입니다.

예를 들어, 모든 모터는 모터 그룹에 속할 수 있습니다.
manufacturer string 물리적 하드웨어 구성 요소의 경우 이 속성은 제조업체 또는 공급업체 이름입니다.

디스크 파티션 또는 디렉터리 같은 논리적 구성 요소의 경우 디바이스 작성기의 정의된 값일 수 있습니다.
model string 물리적 하드웨어 구성 요소의 경우 이 속성은 모델 이름입니다.

디스크 파티션 또는 디렉터리와 같은 논리적 구성 요소의 경우 이 속성은 디바이스 작성기에서 정의한 값일 수 있습니다.
properties 개체 선택적 디바이스 관련 속성을 포함하는 JSON 개체입니다.

Contoso Virtual Vacuum 구성 요소를 기반으로 하는 ComponentInfo 코드의 예제는 다음과 같습니다.

{
    "id": "contoso-motor-serial-00000",
    "name": "left-motor",
    "group": "motors",
    "manufacturer": "contoso",
    "model": "virtual-motor",
    "properties": {
        "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/0",
        "firmwareDataFile": "firmware.json",
        "status": "connected",
        "version" : "motor-fw-1.0"
    }
}

예시 반환 값

다음은 GetAllComponents 함수에서 반환된 JSON 문서입니다. Contoso Virtual Vacuum 구성 요소 열거자의 구현 예제를 기반으로 합니다.

{
    "components": [
        {
            "id": "hostfw",
            "name": "hostfw",
            "group": "firmware",
            "manufacturer": "contoso",
            "model": "virtual-firmware",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/hostfw",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "host-fw-1.0"
            }
        },
        {
            "id": "bootfs",
            "name": "bootfs",
            "group": "boot-image",
            "manufacturer": "contoso",
            "model": "virtual-disk",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/bootfs",
                "firmwareDataFile": "diskimage.json",
                "status": "ok",
                "version" : "boot-fs-1.0"
            }
        },
        {
            "id": "rootfs",
            "name": "rootfs",
            "group": "os-image",
            "manufacturer": "contoso",
            "model": "virtual-os",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/rootfs",
                "firmwareDataFile": "diskimage.json",
                "status": "ok",
                "version" : "root-fs-1.0"
            }
        },
        {
            "id": "contoso-motor-serial-00000",
            "name": "left-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/0",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "motor-fw-1.0"
            }
        },
        {
            "id": "contoso-motor-serial-00001",
            "name": "right-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/1",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "motor-fw-1.0"
            }
        },
        {
            "id": "contoso-motor-serial-00002",
            "name": "vacuum-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/2",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "motor-fw-1.0"
            }
        },
        {
            "id": "contoso-camera-serial-00000",
            "name": "front-camera",
            "group": "cameras",
            "manufacturer": "contoso",
            "model": "virtual-camera",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/camera\/0",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "camera-fw-1.0"
            }
        },
        {
            "id": "contoso-camera-serial-00001",
            "name": "rear-camera",
            "group": "cameras",
            "manufacturer": "contoso",
            "model": "virtual-camera",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/camera\/1",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "camera-fw-1.0"
            }
        }
    ]
}

다음 JSON 문서는 SelectComponents 함수에서 반환됩니다. Contoso 구성 요소 열거자의 예제 구현을 기반으로 합니다.

motors 구성 요소 그룹을 선택하기 위한 입력 매개 변수는 다음과 같습니다.

{
    "group" : "motors"
}

매개 변수의 출력은 다음과 같습니다. 모든 구성 요소는 motors 그룹에 속합니다.

{
    "components": [
        {
            "id": "contoso-motor-serial-00000",
            "name": "left-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/0",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "motor-fw-1.0"
            }
        },
        {
            "id": "contoso-motor-serial-00001",
            "name": "right-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/1",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "motor-fw-1.0"
            }
        },
        {
            "id": "contoso-motor-serial-00002",
            "name": "vacuum-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/2",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "motor-fw-1.0"
            }
        }
    ]
}

hostfw라는 단일 구성 요소를 선택하기 위한 입력 매개 변수는 다음과 같습니다.

{
    "name" : "hostfw"
}

hostfw 구성 요소에 대한 매개 변수의 출력은 다음과 같습니다.

{
    "components": [
        {
            "id": "hostfw",
            "name": "hostfw",
            "group": "firmware",
            "manufacturer": "contoso",
            "model": "virtual-firmware",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/hostfw",
                "firmwareDataFile": "firmware.json",
                "status": "ok",
                "version" : "host-fw-1.0"
            }
        }
    ]
}

참고 항목

이전 예제에서는 필요한 경우 name 속성을 통해 선택되는 구성 요소 인스턴스에 최신 업데이트를 보낼 수 있음을 보여 주었습니다. 예를 들어, motor-fw-2.0 업데이트를 vacuum-motor에 배포하지만 left-motorright-motor에서는 motor-fw-1.0을 계속 사용합니다.

인벤토리 파일

Contoso Virtual Vacuum 구성 요소 열거자에 대해 앞에서 보여 준 구현 예제는 component-inventory.json 파일에서 디바이스 관련 구성 요소의 정보를 읽습니다. 이 구현 예제는 데모용으로만 제공됩니다.

프로덕션 시나리오에서 일부 속성은 실제 구성 요소에서 직접 검색해야 합니다. 해당 속성에는 id, manufacturer, model이 포함됩니다.

디바이스 작성기는 namegroup 속성을 정의합니다. 해당 값은 정의된 후에는 변경되지 않아야 합니다. name 속성은 디바이스 내에서 고유해야 합니다.

예제 component-inventory.json 파일

참고 항목

이 파일의 콘텐츠는 GetAllComponents 함수에서 반환된 값과 거의 같습니다. 그러나 이 파일의 ComponentInfo에는 versionstatus 속성이 포함되지 않습니다. 구성 요소 열거자는 런타임에 이러한 속성을 채웁니다.

예를 들어, hostfw의 경우 속성 properties.version 값은 지정된(모의) firmwareDataFile 값(/usr/local/contoso-devices/vacuum-1/hostfw/firmware.json)에서 채워집니다.

{
    "components": [
        {
            "id": "hostfw",
            "name": "hostfw",
            "group": "firmware",
            "manufacturer": "contoso",
            "model": "virtual-firmware",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/hostfw",
                "firmwareDataFile": "firmware.json",
            }
        },
        {
            "id": "bootfs",
            "name": "bootfs",
            "group": "boot-image",
            "manufacturer": "contoso",
            "model": "virtual-disk",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/bootfs",
                "firmwareDataFile": "diskimage.json",
            }
        },
        {
            "id": "rootfs",
            "name": "rootfs",
            "group": "os-image",
            "manufacturer": "contoso",
            "model": "virtual-os",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/rootfs",
                "firmwareDataFile": "diskimage.json",
            }
        },
        {
            "id": "contoso-motor-serial-00000",
            "name": "left-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/0",
                "firmwareDataFile": "firmware.json",
            }
        },
        {
            "id": "contoso-motor-serial-00001",
            "name": "right-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/1",
                "firmwareDataFile": "firmware.json",
            }
        },
        {
            "id": "contoso-motor-serial-00002",
            "name": "vacuum-motor",
            "group": "motors",
            "manufacturer": "contoso",
            "model": "virtual-motor",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/2",
                "firmwareDataFile": "firmware.json",
            }
        },
        {
            "id": "contoso-camera-serial-00000",
            "name": "front-camera",
            "group": "cameras",
            "manufacturer": "contoso",
            "model": "virtual-camera",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/camera\/0",
                "firmwareDataFile": "firmware.json",
            }
        },
        {
            "id": "contoso-camera-serial-00001",
            "name": "rear-camera",
            "group": "cameras",
            "manufacturer": "contoso",
            "model": "virtual-camera",
            "properties": {
                "path": "\/usr\/local\/contoso-devices\/vacuum-1\/camera\/1",
                "firmwareDataFile": "firmware.json",
            }
        }
    ]
}

다음 단계

이 문서의 예제에서는 C를 사용했습니다. C++ 예제 소스 코드를 살펴보려면 다음을 참조하세요.

Contoso Virtual Vacuum 디바이스에 연결된 구성 요소의 다양한 샘플 업데이트는 프록시 업데이트 데모를 참조하세요.