HoloLens(1세대) 및 Azure 313: IoT Hub Service

참고

Mixed Reality 아카데미 자습서는 HoloLens(1세대) 및 Mixed Reality 몰입형 헤드셋을 염두에 두고 설계되었습니다. 따라서 이러한 디바이스 개발에 대한 지침을 계속 찾고 있는 개발자를 위해 이러한 자습서를 그대로 두는 것이 중요합니다. 이러한 자습서는 HoloLens 2에 사용되는 최신 도구 집합 또는 상호 작용으로 업데이트되지 않습니다. 대신 지원되는 디바이스에서 계속 작동하도록 유지 관리됩니다. HoloLens 2 위해 개발하는 방법을 보여 줄 새로운 자습서 시리즈가 미래에 게시될 예정입니다. 이 알림은 해당 자습서가 게시될 때 해당 자습서에 대한 링크로 업데이트됩니다.

과정 결과

이 과정에서는 Ubuntu 16.4 운영 체제를 실행하는 가상 머신에서 Azure IoT Hub 서비스를 구현하는 방법을 알아봅니다. 그런 다음 Azure 함수 앱을 사용하여 Ubuntu VM에서 메시지를 수신하고 결과를 Azure Table Service 내에 저장합니다. 그런 다음 Microsoft HoloLens 또는 몰입형(VR) 헤드셋에서 Power BI를 사용하여 이 데이터를 볼 수 있습니다.

이 과정의 내용은 IoT Edge 디바이스에 적용할 수 있지만, 이 과정의 목적을 위해 실제 Edge 디바이스에 액세스할 필요가 없도록 가상 머신 환경에 초점을 맞춥니다.

이 과정을 완료하면 다음을 학습합니다.

  • IoT 디바이스를 나타내는 가상 머신(Ubuntu 16 OS)에 IoT Edge 모듈을 배포합니다.
  • 컨테이너에 저장된 이미지를 분석하는 코드를 사용하여 Azure Custom Vision Tensorflow 모델을 Edge 모듈에 추가합니다.
  • 분석 결과 메시지를 IoT Hub 서비스로 다시 보내도록 모듈을 설정합니다.
  • Azure 함수 앱을 사용하여 Azure 테이블 내에 메시지를 저장합니다.
  • 저장된 메시지를 수집하고 보고서를 만들 도록 Power BI 를 설정합니다.
  • Power BI 내에서 IoT 메시지 데이터를 시각화합니다.

사용할 서비스에는 다음이 포함됩니다.

  • Azure IoT Hub 개발자가 IoT 자산을 연결, 모니터링 및 관리할 수 있는 Microsoft Azure 서비스입니다. 자세한 내용은 Azure IoT Hub 서비스 페이지를 참조하세요.

  • Azure Container Registry 개발자가 다양한 유형의 컨테이너에 대해 컨테이너 이미지를 저장할 수 있는 Microsoft Azure 서비스입니다. 자세한 내용은 Azure Container Registry 서비스 페이지를 참조하세요.

  • Azure Function App 은 개발자가 Azure에서 작은 코드 'functions'를 실행할 수 있는 Microsoft Azure 서비스입니다. 이렇게 하면 많은 이점이 있을 수 있는 로컬 애플리케이션이 아닌 클라우드에 작업을 위임할 수 있습니다. Azure Functions C#, F#, Node.js, Java 및 PHP를 비롯한 여러 개발 언어를 지원합니다. 자세한 내용은 Azure Functions 페이지를 참조하세요.

  • Azure Storage: 테이블 은 개발자가 구조화된 비 SQL 데이터를 클라우드에 저장하여 어디서나 쉽게 액세스할 수 있도록 하는 Microsoft Azure 서비스입니다. 이 서비스는 스키마가 없는 디자인을 자랑하므로 필요에 따라 테이블이 진화할 수 있으므로 매우 유연합니다. 자세한 내용은 Azure 테이블 페이지를 참조하세요.

이 과정에서는 IoT Hub 서비스를 설정 및 사용한 다음 디바이스에서 제공하는 응답을 시각화하는 방법을 설명합니다. 빌드할 수 있는 사용자 지정 IoT Hub 서비스 설정에 이러한 개념을 적용하는 것은 사용자에게 달려 있습니다.

디바이스 지원

과정 HoloLens 몰입형 헤드셋
MR 및 Azure 313: IoT Hub 서비스 ✔️ ✔️

사전 요구 사항

Microsoft HoloLens 포함하여 Mixed Reality 사용하여 개발하기 위한 최신 필수 구성 요소는 도구 설치 문서를 참조하세요.

참고

이 자습서는 Python에 대한 기본 경험이 있는 개발자를 위해 설계되었습니다. 또한 이 문서의 필수 구성 요소 및 서면 지침은 작성 당시 테스트 및 확인된 내용(2018년 7월)을 나타냅니다. 이 과정의 정보가 아래에 나열된 것보다 최신 소프트웨어에서 찾을 수 있는 것과 완벽하게 일치한다고 가정해서는 안 되지만 도구 설치 문서에 나열된 대로 최신 소프트웨어를 자유롭게 사용할 수 있습니다.

다음 하드웨어 및 소프트웨어가 필요합니다.

  • Windows 10 Fall Creators Update 이상, 개발자 모드 사용

    경고

    Windows 10 Home Edition에서는 Hyper-V를 사용하여 Virtual Machine을 실행할 수 없습니다.

  • Windows 10 SDK(최신 버전)

  • HoloLens, 개발자 모드 사용

  • Visual Studio 2017.15.4(Azure Cloud Explorer 액세스하는 데만 사용됨)

  • Azure 및 IoT Hub 서비스에 대한 인터넷 액세스. 자세한 내용은 이 링크를 IoT Hub 서비스 페이지로 이동하세요.

  • Machine Learning 모델 모델을 사용할 준비가 되어 있지 않은 경우 이 과정과 함께 제공되는 모델을 사용할 수 있습니다.

  • Windows 10 개발 컴퓨터에서 사용하도록 설정된 Hyper-V 소프트웨어입니다.

  • 개발 컴퓨터에서 실행되는 Ubuntu(16.4 또는 18.4)를 실행하는 Virtual Machine 또는 Linux(Ubuntu 16.4 또는 18.4)를 실행하는 별도의 컴퓨터를 사용할 수 있습니다. Hyper-V를 사용하여 Windows에서 VM을 만드는 방법에 대한 자세한 내용은 "시작하기 전에" 챕터에서 확인할 수 있습니다.

시작하기 전에

  1. HoloLens를 설정하고 테스트합니다. HoloLens 설정을 지원해야 하는 경우 HoloLens 설정 문서를 참조하세요.
  2. 새 HoloLens 앱 개발을 시작할 때 보정센서 튜닝 을 수행하는 것이 좋습니다(때로는 각 사용자에 대해 이러한 작업을 수행하는 데 도움이 될 수 있음).

보정에 대한 도움말은 HoloLens 보정 문서에 대한 이 링크를 따르세요.

센서 튜닝에 대한 도움말은 HoloLens 센서 튜닝 문서에 대한 링크를 따르세요.

  1. Hyper-V를 사용하여 Ubuntu Virtual Machine을 설정합니다. 다음 리소스는 프로세스에 도움이 됩니다.

    1. 먼저 이 링크를 따라 Ubuntu 16.04.4 LTS(Xenial Xerus) ISO를 다운로드합니다. 64비트 PC(AMD64) 데스크톱 이미지를 선택합니다.
    2. Windows 10 컴퓨터에서 Hyper-V가 사용하도록 설정되어 있는지 확인합니다. 이 링크를 따라 Windows 10 Hyper-V를 설치하고 사용하도록 설정하는 방법에 대한 지침을 확인할 수 있습니다.
    3. Hyper-V를 시작하고 새 Ubuntu VM을 만듭니다. Hyper-V를 사용하여 VM을 만드는 방법에 대한 단계별 가이드에 대해 이 링크를 따를 수 있습니다. "부팅 가능한 이미지 파일에서 운영 체제 설치"를 요청하면 이전에 다운로드한 Ubuntu ISO를 선택합니다.

    참고

    Hyper-V 빠른 만들기를 사용하는 것은 권장되지 않습니다.

1장 - Custom Vision 모델 검색

이 과정을 통해 이미지에서 키보드와 마우스를 감지하는 미리 빌드된 Custom Vision 모델에 액세스할 수 있습니다. 이를 사용하는 경우 2장으로 진행합니다.

그러나 고유한 Custom Vision 모델을 사용하려는 경우 다음 단계를 수행할 수 있습니다.

  1. Custom Vision 프로젝트에서성능 탭으로 이동합니다.

    경고

    모델을 내보내려면 모델이 컴팩트 도메인을 사용해야 합니다. 프로젝트의 설정에서 모델 도메인을 변경할 수 있습니다.

    성능 탭

  2. 내보낼 반복 을 선택하고 내보내기를 클릭합니다. 블레이드가 나타납니다.

    내보내기 블레이드

  3. 블레이드에서 Docker 파일을 클릭합니다.

    docker 선택

  4. 드롭다운 메뉴에서 Linux 를 클릭한 다음 다운로드를 클릭합니다.

    다운로드 클릭

  5. 콘텐츠의 압축을 풉 이 과정의 뒷부분에서 사용합니다.

2장 - Container Registry Service

Container Registry Service는 컨테이너를 호스트하는 데 사용되는 리포지토리입니다.

이 과정에서 빌드하고 사용할 IoT Hub 서비스는Container Registry Service를 참조하여 Edge 디바이스에 배포할 컨테이너를 가져옵니다.

  1. 먼저 이 링크를 따라 Azure Portal에 연결하고 자격 증명으로 로그인합니다.

  2. 리소스 만들기로 이동하여 Container Registry를 찾습니다.

    컨테이너 레지스트리

  3. 만들기를 클릭합니다.

    만들기를 선택할 위치를 보여 주는 스크린샷

  4. 서비스 설정 매개 변수를 설정합니다.

    1. 프로젝트의 이름을 삽입합니다. 이 예제에서는 IoTCRegistry라고 합니다.

    2. 리소스 그룹을 선택하거나 새 리소스 그룹을 만듭니다. 리소스 그룹은 Azure 자산 컬렉션에 대한 액세스를 모니터링, 제어, 프로비전 및 관리, 청구하는 방법을 제공합니다. 단일 프로젝트(예: 이러한 과정)와 연결된 모든 Azure 서비스를 공통 리소스 그룹 아래에 유지하는 것이 좋습니다.

    3. 서비스의 위치를 설정합니다.

    4. 관리 사용자를사용으로 설정합니다.

    5. SKU기본으로 설정합니다.

    SKU를 기본으로 설정하는 위치를 보여 주는 스크린샷

  5. 만들기를 클릭하고 서비스가 만들어질 때까지 기다립니다.

  6. Container Registry를 성공적으로 생성했음을 알리는 알림이 표시되면 리소스로 이동을 클릭하여 서비스 페이지로 리디렉션합니다.

    리소스로 이동을 선택할 위치를 보여 주는 스크린샷

  7. Container Registry Service 페이지에서 액세스 키를 클릭합니다.

  8. 다음 매개 변수를 기록해 둡니다(메모장을 사용할 수 있음).

    1. 로그인 서버
    2. 사용자 이름
    3. 암호

    로그인 서버, 사용자 이름 및 암호 매개 변수를 볼 수 있는 위치를 보여 주는 스크린샷

3장 - IoT Hub 서비스

이제 IoT Hub 서비스의 만들기 및 설정을 시작합니다.

  1. 아직 로그인하지 않은 경우 Azure Portal에 로그인합니다.

  2. 로그인한 후 왼쪽 위 모서리에서 리소스 만들기를 클릭하고 IoT Hub 검색한 다음 Enter 키를 클릭합니다.

열려 있는 모든 항목 창을 보여 주는 스크린샷 검색 결과의 I O T Hub 및 왼쪽 위 모서리에 리소스 만들기가 빨간색 원으로 표시됩니다.

  1. 새 페이지에서는 스토리지 계정 서비스에 대한 설명을 제공합니다. 이 프롬프트의 왼쪽 아래에서 만들기 단추를 클릭하여 이 서비스의 instance 만듭니다.

    I O T Hub 개요 페이지를 보여 주는 스크린샷.

  2. 만들기를 클릭하면 패널이 표시됩니다.

    1. 리소스 그룹을 선택하거나 새 리소스 그룹을 만듭니다. 리소스 그룹은 Azure 자산 컬렉션에 대한 액세스를 모니터링, 제어, 프로비전 및 관리하는 방법을 제공합니다. 단일 프로젝트(예: 이러한 과정)와 연결된 모든 Azure 서비스를 공통 리소스 그룹 아래에 유지하는 것이 좋습니다.

      Azure 리소스 그룹에 대해 자세히 알아보려면 리소스 그룹을 관리하는 방법에 대한 이 링크를 따르세요.

    2. 적절한 위치를 선택합니다(이 과정에서 만든 모든 서비스에서 동일한 위치 사용).

    3. 이 서비스 instance 원하는 이름을 삽입합니다.

  3. 페이지 아래쪽에서 다음: 크기 및 크기 조정을 클릭합니다.

    I O T 허브 기본 사항 페이지를 보여 주는 스크린샷. 다음 크기 및 눈금은 페이지 아래쪽에 빨간색으로 원을 그리게 합니다.

  4. 이 페이지에서 가격 책정 및 크기 조정 계층을 선택합니다(첫 번째 IoT Hub 서비스 instance 경우 무료 계층을 사용할 수 있어야 합니다).

  5. 검토 + 만들기를 클릭합니다.

    I O T 허브 크기 및 크기 조정 페이지를 보여 주는 스크린샷 F 1 무료 계층은 가격 책정 및 배율 계층 필드에서 선택됩니다. 검토 및 만들기는 페이지 아래쪽에 빨간색 원으로 표시됩니다.

  6. 설정을 검토하고 만들기를 클릭합니다.

    I O T 허브 검토 및 만들기 페이지를 보여 주는 스크린샷. 만들기는 페이지 아래쪽에 빨간색으로 원을 그리며 표시됩니다.

  7. IoT Hub 서비스의 성공적인 생성을 알리는 알림이 표시되면 리소스로 이동을 클릭하여 서비스 페이지로 리디렉션합니다.

    배포 성공 알림을 보여 주는 스크린샷 리소스로 이동 단추는 빨간색 원으로 표시됩니다.

  8. 자동 장치 관리 표시될 때까지 왼쪽의 측면 패널을 스크롤하고 IoT Edge 클릭합니다.

    자동 장치 관리 아래 메뉴에서 선택한 I O T Edge를 보여 주는 스크린샷

  9. 오른쪽에 표시되는 창에서 IoT Edge 디바이스 추가를 클릭합니다. 블레이드가 오른쪽에 나타납니다.

  10. 블레이드에서 새 디바이스에 디바이스 ID (선택한 이름)를 제공합니다. 그런 다음 저장을 클릭합니다. 자동 생성이 틱된 경우 기본보조 키가자동으로 생성 됩니다.

    디바이스 추가 페이지를 보여 주는 스크린샷. Edge 디바이스 0 1이 디바이스 ID 필드에 입력됩니다. 키 자동 생성 확인란이 선택되어 있습니다.

  11. 새 디바이스가 나열되는 IoT Edge 디바이스 섹션으로 다시 이동합니다. 새 디바이스를 클릭합니다(아래 이미지에서 빨간색으로 표시됨).

    I O T Edge 디바이스 페이지를 보여 주는 스크린샷 페이지 아래쪽에 있는 Edge 디바이스 옆에 있는 확인란이 선택되어 있습니다.

  12. 표시되는 디바이스 세부 정보 페이지에서 연결 문자열 (기본 키)의 복사본을 가져옵니다.

    디바이스 세부 정보 페이지를 보여 주는 스크린샷 연결 문자열 기본 키는 빨간색 원으로 표시됩니다.

  13. 왼쪽 패널에 돌아가기 공유 액세스 정책을 클릭하여 엽니다.

  14. 표시되는 페이지에서 iothubowner를 클릭하면 화면 오른쪽에 블레이드가 나타납니다.

  15. 나중에 연결 문자열을 디바이스로 설정할 때 사용할 수 있도록 연결 문자열(기본 키)의 메모장에서 기록해 둡 니다.

    설정 아래에 있는 공유 액세스 정책 페이지를 보여 주는 스크린샷 정책에서 I O T 허브 소유자가 선택됩니다. 팝업 창에서 연결 문자열 기본 키 필드는 빨간색 원으로 표시됩니다.

4장 - 개발 환경 설정

IoT Hub Edge용 모듈을 만들고 배포하려면 Windows 10 실행하는 개발 머신에 다음 구성 요소가 설치되어 있어야 합니다.

  1. Windows용 Docker는 다운로드할 수 있는 계정을 만들도록 요청합니다.

    Windows용 docker 다운로드

    중요

    Docker를 실행하려면 Windows 10 PRO, Enterprise 14393 또는 Windows Server 2016 RTM이 필요합니다. 다른 버전의 Windows 10 실행하는 경우 Docker 도구 상자를 사용하여 Docker를 설치해 볼 수 있습니다.

  2. Python 3.6.

    python 3.6 다운로드

  3. Visual Studio Code(VS Code라고도 함).

    VS Code 다운로드

위에서 언급한 소프트웨어를 설치한 후 컴퓨터를 다시 시작해야 합니다.

5장 - Ubuntu 환경 설정

이제 Ubuntu OS를 실행하는 디바이스 설정으로 이동할 수 있습니다. 다음 단계에 따라 필요한 소프트웨어를 설치하고 보드에 컨테이너를 배포합니다.

중요

관리 사용자로 실행하려면 항상 터미널 명령 앞에 sudo 가 있어야 합니다. 즉,

sudo docker \<option> \<command> \<argument>
  1. Ubuntu 터미널을 열고 다음 명령을 사용하여 pip를 설치합니다.

    [! 힌트] 바로 가기 키인 Ctrl + Alt + T를 사용하여 터미널을 매우 쉽게 열 수 있습니다.

        sudo apt-get install python-pip
    
  2. 이 장 전체에서 터미널에서 디바이스 스토리지를 사용할 수 있는 권한을 입력하고 y/n (예 또는 아니요)을 입력하고 'y'를 입력한 다음 Enter 키를 눌러 수락하라는 메시지가 표시될 수 있습니다.

  3. 해당 명령이 완료되면 다음 명령을 사용하여 curl을 설치합니다.

        sudo apt install curl
    
  4. pipcurl이 설치되면 다음 명령을 사용하여 IoT Edge 런타임을 설치합니다. 이는 보드에서 모듈을 배포하고 제어하는 데 필요합니다.

        curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list > ./microsoft-prod.list
    
        sudo cp ./microsoft-prod.list /etc/apt/sources.list.d/
    
        curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
    
        sudo cp ./microsoft.gpg /etc/apt/trusted.gpg.d/
    
        sudo apt-get update
    
        sudo apt-get install moby-engine
    
        sudo apt-get install moby-cli
    
        sudo apt-get update
    
        sudo apt-get install iotedge
    
  5. 이 시점에서 IoT Hub 서비스를 만들 때(14단계, 3장) 디바이스 연결 문자열을 삽입하기 위해 런타임 구성 파일을 열고 메모장에서 적어 두었다는 메시지가 표시됩니다. 터미널에서 다음 줄을 실행하여 해당 파일을 엽니다.

        sudo nano /etc/iotedge/config.yaml
    
  6. 편집할 준비가 된 config.yaml 파일이 표시됩니다.

    경고

    이 파일이 열리면 다소 혼란스러울 수 있습니다. 터미널 자체 내에서 이 파일을 텍스트로 편집합니다.

    1. 키보드의 화살표 키를 사용하여 아래로 스크롤하여(약간 아래로 스크롤해야 함) 포함된 줄에 도달합니다.":

      "<여기에> 디바이스 연결 문자열 추가".

    2. 대괄호를 포함한 대체 줄을 앞에서 적어 두는 디바이스 연결 문자열로 바꿉니다.

  7. 연결 문자열을 배치한 상태에서 키보드에서 Ctrl-X 키를 눌러 파일을 저장합니다. Y를 입력하여 확인하라는 메시지가 표시됩니다. 그런 다음 Enter 키를 눌러 확인합니다. 일반 터미널로 돌아갑니다.

  8. 이러한 명령이 모두 성공적으로 실행되면 IoT Edge 런타임을 설치합니다. 초기화되면 디바이스가 전원을 공급할 때마다 런타임이 자체적으로 시작되고 백그라운드에 앉아 IoT Hub 서비스에서 모듈이 배포될 때까지 기다립니다.

  9. 다음 명령줄을 실행하여 IoT Edge 런타임을 초기화합니다.

        sudo systemctl restart iotedge
    

    중요

    .yaml 파일 또는 위의 설정을 변경하는 경우 터미널 내에서 위의 다시 시작 줄을 다시 실행해야 합니다.

  10. 다음 명령줄을 실행하여 IoT Edge 런타임 상태 확인합니다. 런타임은 상태 활성(실행 중)이 녹색 텍스트로 표시되어야 합니다.

        sudo systemctl status iotedge
    
  11. Ctrl-C 키를 눌러 상태 페이지를 종료합니다. 다음 명령을 입력하여 IoT Edge 런타임이 컨테이너를 올바르게 당기는지 확인할 수 있습니다.

        sudo docker ps
    
  12. 컨테이너가 2개인 목록이 표시됩니다. 이러한 모듈은 IoT Hub Service(edgeAgent 및 edgeHub)에서 자동으로 생성되는 기본 모듈입니다. 사용자 고유의 모듈을 만들고 배포하면 기본 모듈 아래에 이 모듈이 목록에 표시됩니다.

6장 - 확장 설치

중요

다음 몇 챕터(6-9)는 Windows 10 컴퓨터에서 수행되어야 합니다.

  1. VS Code를 엽니다.

  2. VS Code의 왼쪽 막대에서 확장 (정사각형) 단추를 클릭하여 확장 패널을 엽니다.

  3. 아래 이미지와 같이 다음 확장을 검색하고 설치합니다.

    1. Azure IoT Edge
    2. Azure IoT Toolkit
    3. Docker

    확장 창을 보여 주는 스크린샷 Azure I O T Edge, Azure I O T Toolkit 및 Docker는 빨간색으로 동그라미를 빙글빙글 돌고 있습니다.

  4. 확장이 설치되면 VS Code를 닫고 다시 엽니다.

  5. VS Code를 한 번 더 열면통합 터미널보기>로 이동합니다.

  6. 이제 Cookiecutter를 설치합니다. 터미널에서 다음 bash 명령을 실행합니다.

        pip install --upgrade --user cookiecutter
    

    [! HINT] 이 명령에 문제가 있는 경우:

    1. VS Code 및/또는 컴퓨터를 다시 시작합니다.
    2. VS Code 터미널을 Python 설치에 사용한 터미널(예: Powershell)으로 전환해야 할 수 있습니다(특히 Python 환경이 컴퓨터에 이미 설치된 경우). 터미널이 열리면 터미널 오른쪽에 드롭다운 메뉴가 표시됩니다. 드롭다운 메뉴에서 선택된 1개 Powershell을 보여 주는 스크린샷
    3. Python 설치 경로가 컴퓨터에 환경 변수로 추가되었는지 확인합니다. Cookiecutter는 동일한 위치 경로의 일부여야 합니다. 환경 변수에 대한 자세한 내용은 이 링크를 따르세요.
  7. Cookiecutter 설치가 완료되면 시스템 환경 내에서 Cookiecutter가 명령으로 인식되도록 컴퓨터를 다시 시작해야 합니다.

7장 - 컨테이너 솔루션 만들기

이 시점에서 컨테이너 레지스트리로 푸시하려면 모듈을 사용하여 컨테이너를 만들어야 합니다. 컨테이너를 푸시한 후에는 IoT Hub Edge 서비스를 사용하여 IoT Edge 런타임을 실행하는 디바이스에 배포합니다.

  1. VS Code에서명령 팔레트보기를> 클릭합니다.

  2. 색상표에서 Azure IoT Edge: 새 IoT Edge 솔루션을 검색하고 실행합니다.

  3. 솔루션을 만들 위치를 찾습니다. Enter 키를 눌러 위치를 수락합니다.

  4. 솔루션에 이름을 지정합니다. Enter 키를 눌러 제공된 이름을 확인합니다.

  5. 이제 솔루션에 대한 템플릿 프레임워크를 선택하라는 메시지가 표시됩니다. Python 모듈을 클릭합니다. Enter 키를 눌러 이 선택을 확인합니다.

  6. 모듈에 이름을 지정합니다. Enter 키를 눌러 모듈의 이름을 확인합니다. 나중에 사용되므로 모듈 이름의 메모장(메모장 포함)을 작성해야 합니다.

  7. 미리 빌드된 Docker 이미지 리포지토리 주소가 색상표에 표시됩니다. 다음과 같이 표시됩니다.

    localhost:5000/-모듈의 이름입니다.

  8. localhost:5000을 삭제하고 그 자리에 Container Registry로그인 서버 주소를 삽입합니다. 이 주소는 Container Registry Service를 만들 때 기록했습니다(8단계, 2장). Enter 키를 눌러 주소를 확인합니다.

  9. 이때 Python 모듈에 대한 템플릿이 포함된 솔루션이 만들어지고 해당 구조가 화면 왼쪽에 VS Code의 탐색 탭에 표시됩니다. 탐색 탭이 열려 있지 않으면 왼쪽의 막대에서 맨 위 단추를 클릭하여 열 수 있습니다.

    2개의 누적 용지와 유사한 탐색 탭 단추를 보여 주는 스크린샷.

  10. 이 챕터의 마지막 단계는 탐색 탭 내에서 .env 파일을 클릭하고 열고 Container Registry사용자 이름과암호를 추가하는 것입니다. 이 파일은 git에서 무시되지만 컨테이너를 빌드할 때 는 Container Registry Service에 액세스하도록 자격 증명을 설정합니다.

    컨테이너 레지스트리 사용자 이름이 줄 1에 입력되고 컨테이너 레지스트리 암호가 줄 2에 입력된 명령 창을 보여 주는 스크린샷

8장 - 컨테이너 솔루션 편집

이제 다음 파일을 업데이트하여 컨테이너 솔루션을 완료합니다.

  • 기본.py python 스크립트입니다.
  • 를requirements.txt.
  • deployment.template.json.
  • Dockerfile.amd64

그런 다음 python 스크립트에서 이미지가 Custom Vision 모델과 일치하도록 검사 데 사용하는 images 폴더를 만듭니다. 마지막으로 모델을 읽는 데 도움이 되는 labels.txt 파일과 모델인 model.pb 파일을 추가합니다.

  1. VS Code가 열려 있는 상태에서 모듈 폴더로 이동하고 기본.py라는 스크립트를 찾습니다. 이 로그를 두 번 클릭하여 엽니다.

  2. 파일의 내용을 삭제하고 다음 코드를 삽입합니다.

    # Copyright (c) Microsoft. All rights reserved.
    # Licensed under the MIT license. See LICENSE file in the project root for
    # full license information.
    
    import random
    import sched, time
    import sys
    import iothub_client
    from iothub_client import IoTHubModuleClient, IoTHubClientError, IoTHubTransportProvider
    from iothub_client import IoTHubMessage, IoTHubMessageDispositionResult, IoTHubError
    import json
    import os
    import tensorflow as tf
    import os
    from PIL import Image
    import numpy as np
    import cv2
    
    # messageTimeout - the maximum time in milliseconds until a message times out.
    # The timeout period starts at IoTHubModuleClient.send_event_async.
    # By default, messages do not expire.
    MESSAGE_TIMEOUT = 10000
    
    # global counters
    RECEIVE_CALLBACKS = 0
    SEND_CALLBACKS = 0
    
    TEMPERATURE_THRESHOLD = 25
    TWIN_CALLBACKS = 0
    
    # Choose HTTP, AMQP or MQTT as transport protocol.  Currently only MQTT is supported.
    PROTOCOL = IoTHubTransportProvider.MQTT
    
    
    # Callback received when the message that we're forwarding is processed.
    def send_confirmation_callback(message, result, user_context):
        global SEND_CALLBACKS
        print ( "Confirmation[%d] received for message with result = %s" % (user_context, result) )
        map_properties = message.properties()
        key_value_pair = map_properties.get_internals()
        print ( "    Properties: %s" % key_value_pair )
        SEND_CALLBACKS += 1
        print ( "    Total calls confirmed: %d" % SEND_CALLBACKS )
    
    
    def convert_to_opencv(image):
        # RGB -> BGR conversion is performed as well.
        r,g,b = np.array(image).T
        opencv_image = np.array([b,g,r]).transpose()
        return opencv_image
    
    def crop_center(img,cropx,cropy):
        h, w = img.shape[:2]
        startx = w//2-(cropx//2)
        starty = h//2-(cropy//2)
        return img[starty:starty+cropy, startx:startx+cropx]
    
    def resize_down_to_1600_max_dim(image):
        h, w = image.shape[:2]
        if (h < 1600 and w < 1600):
            return image
    
        new_size = (1600 * w // h, 1600) if (h > w) else (1600, 1600 * h // w)
        return cv2.resize(image, new_size, interpolation = cv2.INTER_LINEAR)
    
    def resize_to_256_square(image):
        h, w = image.shape[:2]
        return cv2.resize(image, (256, 256), interpolation = cv2.INTER_LINEAR)
    
    def update_orientation(image):
        exif_orientation_tag = 0x0112
        if hasattr(image, '_getexif'):
            exif = image._getexif()
            if (exif != None and exif_orientation_tag in exif):
                orientation = exif.get(exif_orientation_tag, 1)
                # orientation is 1 based, shift to zero based and flip/transpose based on 0-based values
                orientation -= 1
                if orientation >= 4:
                    image = image.transpose(Image.TRANSPOSE)
                if orientation == 2 or orientation == 3 or orientation == 6 or orientation == 7:
                    image = image.transpose(Image.FLIP_TOP_BOTTOM)
                if orientation == 1 or orientation == 2 or orientation == 5 or orientation == 6:
                    image = image.transpose(Image.FLIP_LEFT_RIGHT)
        return image
    
    
    def analyse(hubManager):
    
        messages_sent = 0;
    
        while True:
            #def send_message():
            print ("Load the model into the project")
            # These names are part of the model and cannot be changed.
            output_layer = 'loss:0'
            input_node = 'Placeholder:0'
    
            graph_def = tf.GraphDef()
            labels = []
    
            labels_filename = "labels.txt"
            filename = "model.pb"
    
            # Import the TF graph
            with tf.gfile.FastGFile(filename, 'rb') as f:
                graph_def.ParseFromString(f.read())
                tf.import_graph_def(graph_def, name='')
    
            # Create a list of labels
            with open(labels_filename, 'rt') as lf:
                for l in lf:
                    labels.append(l.strip())
            print ("Model loaded into the project")
    
            results_dic = dict()
    
            # create the JSON to be sent as a message
            json_message = ''
    
            # Iterate through images 
            print ("List of images to analyse:")
            for file in os.listdir('images'):
                print(file)
    
                image = Image.open("images/" + file)
    
                # Update orientation based on EXIF tags, if the file has orientation info.
                image = update_orientation(image)
    
                # Convert to OpenCV format
                image = convert_to_opencv(image)
    
                # If the image has either w or h greater than 1600 we resize it down respecting
                # aspect ratio such that the largest dimension is 1600
                image = resize_down_to_1600_max_dim(image)
    
                # We next get the largest center square
                h, w = image.shape[:2]
                min_dim = min(w,h)
                max_square_image = crop_center(image, min_dim, min_dim)
    
                # Resize that square down to 256x256
                augmented_image = resize_to_256_square(max_square_image)
    
                # The compact models have a network size of 227x227, the model requires this size.
                network_input_size = 227
    
                # Crop the center for the specified network_input_Size
                augmented_image = crop_center(augmented_image, network_input_size, network_input_size)
    
                try:
                    with tf.Session() as sess:     
                        prob_tensor = sess.graph.get_tensor_by_name(output_layer)
                        predictions, = sess.run(prob_tensor, {input_node: [augmented_image] })
                except Exception as identifier:
                    print ("Identifier error: ", identifier)
    
                print ("Print the highest probability label")
                highest_probability_index = np.argmax(predictions)
                print('FINAL RESULT! Classified as: ' + labels[highest_probability_index])
    
                l = labels[highest_probability_index]
    
                results_dic[file] = l
    
                # Or you can print out all of the results mapping labels to probabilities.
                label_index = 0
                for p in predictions:
                    truncated_probablity = np.float64(round(p,8))
                    print (labels[label_index], truncated_probablity)
                    label_index += 1
    
            print("Results dictionary")
            print(results_dic)
    
            json_message = json.dumps(results_dic)
            print("Json result")
            print(json_message)
    
            # Initialize a new message
            message = IoTHubMessage(bytearray(json_message, 'utf8'))
    
            hubManager.send_event_to_output("output1", message, 0)
    
            messages_sent += 1
            print("Message sent! - Total: " + str(messages_sent))      
            print('----------------------------')
    
            # This is the wait time before repeating the analysis
            # Currently set to 10 seconds
            time.sleep(10)
    
    
    class HubManager(object):
    
        def __init__(
                self,
                protocol=IoTHubTransportProvider.MQTT):
            self.client_protocol = protocol
            self.client = IoTHubModuleClient()
            self.client.create_from_environment(protocol)
    
            # set the time until a message times out
            self.client.set_option("messageTimeout", MESSAGE_TIMEOUT)
    
        # Forwards the message received onto the next stage in the process.
        def forward_event_to_output(self, outputQueueName, event, send_context):
            self.client.send_event_async(
                outputQueueName, event, send_confirmation_callback, send_context)
    
        def send_event_to_output(self, outputQueueName, event, send_context):
            self.client.send_event_async(outputQueueName, event, send_confirmation_callback, send_context)
    
    def main(protocol):
        try:
            hub_manager = HubManager(protocol)
            analyse(hub_manager)
            while True:
                time.sleep(1)
    
        except IoTHubError as iothub_error:
            print ( "Unexpected error %s from IoTHub" % iothub_error )
            return
        except KeyboardInterrupt:
            print ( "IoTHubModuleClient sample stopped" )
    
    if __name__ == '__main__':
        main(PROTOCOL)
    
  3. requirements.txt이라는 파일을 열고 해당 콘텐츠를 다음으로 대체합니다.

    azure-iothub-device-client==1.4.0.0b3
    opencv-python==3.3.1.11
    tensorflow==1.8.0
    pillow==5.1.0
    
  4. deployment.template.json이라는 파일을 열고 아래 지침에 따라 해당 콘텐츠를 대체합니다.

    1. 고유한 고유한 JSON 구조가 있으므로 예제를 복사하는 대신 직접 편집해야 합니다. 이 작업을 쉽게 수행하려면 아래 이미지를 가이드로 사용합니다.

    2. 사용자와 다르게 보이지만 변경해서는 안 되는 영역은 노란색으로 강조 표시됩니다.

    3. 삭제해야 하는 섹션은 빨간색으로 강조 표시됩니다.

    4. 올바른 대괄호를 삭제하고 쉼표도 제거해야 합니다.

      12~15줄, 49~57줄, 67줄이 노란색으로 원을 그리는 코드 줄을 보여 주는 스크린샷 코드 줄 39-48 및 줄 66은 빨간색 원으로 표시됩니다.

    5. 완료된 JSON은 사용자 이름/암호/모듈 이름/모듈 참조와 고유한 차이점이 있는 다음 이미지와 같아야 합니다.

      원을 그리는 빨간색 선이 삭제된 명령 창을 보여 주는 스크린샷

  5. Dockerfile.amd64라는 파일을 열고 해당 콘텐츠를 다음으로 대체합니다.

    FROM ubuntu:xenial
    
    WORKDIR /app
    
    RUN apt-get update && \
        apt-get install -y --no-install-recommends libcurl4-openssl-dev python-pip libboost-python-dev && \
        rm -rf /var/lib/apt/lists/* 
    RUN pip install --upgrade pip
    RUN pip install setuptools
    
    COPY requirements.txt ./
    RUN pip install -r requirements.txt
    
    RUN pip install pillow
    RUN pip install numpy
    
    RUN apt-get update && apt-get install -y \ 
        pkg-config \
        python-dev \ 
        python-opencv \ 
        libopencv-dev \ 
        libav-tools  \ 
        libjpeg-dev \ 
        libpng-dev \ 
        libtiff-dev \ 
        libjasper-dev \ 
        python-numpy \ 
        python-pycurl \ 
        python-opencv
    
    
    RUN pip install opencv-python
    RUN pip install tensorflow
    RUN pip install --upgrade tensorflow
    
    COPY . .
    
    RUN useradd -ms /bin/bash moduleuser
    USER moduleuser
    
    CMD [ "python", "-u", "./main.py" ]
    
    
  6. 모듈 아래의 폴더를 마우스 오른쪽 단추로 클릭하고(이전에 제공한 이름을 가지며, 예제에서는 pythonmodule이라고 함) 새 폴더를 클릭합니다. 폴더 이미지의 이름을 지정 합니다.

  7. 폴더 내에 마우스 또는 키보드가 포함된 일부 이미지를 추가합니다. Tensorflow 모델에서 분석할 이미지입니다.

    경고

    사용자 고유의 모델을 사용하는 경우 사용자 고유의 모델 데이터를 반영하도록 이를 변경해야 합니다.

  8. 이제 1장에서 이전에 다운로드했거나 사용자 고유의 Custom Vision 서비스에서 만든 model 폴더에서 labels.txtmodel.pb 파일을 검색해야 합니다. 파일이 있으면 다른 파일과 함께 솔루션 내에 배치합니다. 최종 결과는 아래 이미지와 같아야 합니다.

    Explorer 창을 보여 주는 스크린샷 python 모듈 폴더가 열려 있습니다.

9장 - 솔루션을 컨테이너로 패키지

  1. 이제 파일을 컨테이너로 "패키지"하고 Azure Container Registry 푸시할 준비가 되었습니다. VS Code 내에서 통합 터미널(통합 터미널보기> 또는 Ctrl+`)을 열고 다음 줄을 사용하여 Docker에 로그인합니다(명령 값을 Azure Container Registry(ACR)의 자격 증명으로 대체).

        docker login -u <ACR username> -p <ACR password> <ACR login server>
    
  2. deployment.template.json 파일을 마우스 오른쪽 단추로 클릭하고 솔루션 IoT Edge 빌드를 클릭합니다. 이 빌드 프로세스는 디바이스에 따라 상당한 시간이 걸리므로 대기할 준비를 합니다. 빌드 프로세스가 완료되면 config라는 새 폴더 내에 deployment.json 파일이 만들어집니다.

    빨간색 원을 그리는 구성 폴더 및 배포 점 제이슨 파일을 보여 주는 스크린샷.

  3. 명령 팔레트를 다시 열고 Azure: 로그인을 검색합니다. Azure 계정 자격 증명을 사용하여 프롬프트를 따릅니다. VS Code는 복사 및 열기 옵션을 제공합니다. 그러면 곧 필요한 디바이스 코드를 복사하고 기본 웹 브라우저를 엽니다. 메시지가 표시되면 디바이스 코드를 붙여넣어 머신을 인증합니다.

    복사 및 열기

  4. 로그인하면 탐색 패널의 아래쪽에 Azure IoT Hub 디바이스라는 새 섹션이 표시됩니다. 이 섹션을 클릭하여 확장합니다.

    에지 디바이스

  5. 디바이스가 여기에 없는 경우 Azure IoT Hub 디바이스를 마우스 오른쪽 단추로 클릭한 다음 연결 문자열 IoT Hub 설정을 클릭해야 합니다. 그러면 VS Code 맨 위에 있는 명령 팔레트 에서 연결 문자열을 입력하라는 메시지가 표시됩니다. 이 문자열은 챕터 3의 끝에서 적어 두어 본 연결 문자열입니다. 문자열을 복사한 후 Enter 키를 누릅니다.

  6. 디바이스가 로드되고 표시됩니다. 디바이스 이름을 마우스 오른쪽 단추로 클릭한 다음 단일 디바이스에 대한 배포 만들기를 클릭합니다.

    오른쪽 클릭 메뉴를 보여 주는 스크린샷 단일 디바이스에 대한 배포 만들기가 강조 표시됩니다.

  7. config 폴더로 이동한 다음 deployment.json 파일을 선택할 수 있는 파일 탐색기 프롬프트가 표시됩니다. 해당 파일을 선택한 상태에서 Edge 배포 매니페스트 선택 단추를 클릭합니다.

    파일 탐색기 창을 보여 주는 스크린샷 배포 점 제이슨 파일이 선택되고 Edge 배포 매니페스트 선택이 빨간색 원으로 표시됩니다.

  8. 이 시점에서 Azure Container Registry 컨테이너를 모듈로 배포하여 디바이스에 효과적으로 배포할 수 있는 매니페스트를 IoT HubService에 제공했습니다.

  9. 디바이스에서 IoT Hub 보낸 메시지를 보려면 Azure IoT Hub 디바이스 섹션의 Explorer 패널에서 디바이스 이름을 다시 마우스 오른쪽 단추로 클릭하고 D2C 메시지 모니터링 시작을 클릭합니다. 디바이스에서 보낸 메시지가 VS 터미널에 표시되어야 합니다. 시간이 좀 걸릴 수 있으므로 인내심을 가져야 합니다. 디버깅 및 배포가 성공했는지 확인하려면 다음 챕터를 참조하세요.

이제 이 모듈은 이미지 폴더의 이미지 간을 반복하고 각 반복을 사용하여 분석합니다. 이는 기본 기계 학습 모델이 IoT Edge 디바이스 환경에서 작동하도록 하는 방법에 대한 데모일 뿐입니다.

이 예제의 기능을 확장하려면 여러 가지 방법으로 진행할 수 있습니다. 한 가지 방법은 디바이스에 연결된 웹캠에서 사진을 캡처하고 images 폴더에 이미지를 저장하는 컨테이너에 일부 코드를 포함할 수 있습니다.

또 다른 방법은 IoT 디바이스에서 컨테이너로 이미지를 복사하는 것입니다. 이 작업을 수행하는 실용적인 방법은 IoT 디바이스 터미널에서 다음 명령을 실행하는 것입니다(프로세스를 자동화하려는 경우 작은 앱이 작업을 수행할 수 있음). 파일이 저장된 폴더 위치에서 수동으로 실행하여 이 명령을 테스트할 수 있습니다.

    sudo docker cp <filename> <modulename>:/app/images/<a name of your choice>

10장 - IoT Edge 런타임 디버깅

다음은 Ubuntu 디바이스에서 IoT Edge 런타임의 메시징 활동을 모니터링하고 디버그하는 데 도움이 되는 명령줄 및 팁 목록입니다.

  • 다음 명령줄을 실행하여 IoT Edge 런타임 상태 확인합니다.

        sudo systemctl status iotedge
    

    참고

    Ctrl + C를 눌러 상태 보기를 완료해야 합니다.

  • 현재 배포된 컨테이너를 나열합니다. IoT Hub Service에서 컨테이너를 성공적으로 배포한 경우 다음 명령줄을 실행하여 컨테이너가 표시됩니다.

        sudo iotedge list
    

    또는

        sudo docker ps
    

    참고

    위의 방법은 목록에 표시되는 것처럼 모듈이 성공적으로 배포되었는지 여부를 검사 좋은 방법입니다. 그렇지 않으면 edgeHubedgeAgent 표시됩니다.

  • 컨테이너의 코드 로그를 표시하려면 다음 명령줄을 실행합니다.

        journalctl -u iotedge
    

IoT Edge 런타임을 관리하는 유용한 명령:

  • 호스트의 모든 컨테이너를 삭제하려면 다음을 수행합니다.

        sudo docker rm -f $(sudo docker ps -aq)
    
  • IoT Edge 런타임을 중지하려면 다음을 수행합니다.

        sudo systemctl stop iotedge
    

11장 - Table Service 만들기

스토리지 리소스를 만들어 Azure Tables Service를 만드는 Azure Portal로 다시 이동합니다.

  1. 아직 로그인하지 않은 경우 Azure Portal에 로그인합니다.

  2. 로그인한 후 왼쪽 위 모서리에 있는 리소스 만들기를 클릭하고 Storage 계정을 검색한 다음 Enter 키를 눌러 검색을 시작합니다.

  3. 나타나면 목록에서 스토리지 계정 - Blob, 파일, 테이블, 큐 를 클릭합니다.

    새 창을 보여 주는 스크린샷 스토리지가 검색 창에 입력됩니다. 기능에서 Storage 계정 Blob, 파일, 테이블, 큐는 빨간색 원으로 표시됩니다.

  4. 새 페이지에서는 스토리지 계정 서비스에 대한 설명을 제공합니다. 이 프롬프트의 왼쪽 아래에서 만들기 단추를 클릭하여 이 서비스의 instance 만듭니다.

    스토리지 계정 페이지를 보여 주는 스크린샷. 페이지 아래쪽에 있는 만들기 단추가 빨간색 원으로 표시됩니다.

  5. 만들기를 클릭하면 패널이 표시됩니다.

    1. 이 서비스 instance 원하는 이름을 삽입합니다(모두 소문자여야 합니다).

    2. 배포 모델의 경우 리소스 관리자를 클릭합니다.

    3. 계정 종류에 대해 드롭다운 메뉴를 사용하여 스토리지(범용 v1)를 클릭합니다.

    4. 적절한 위치를 클릭합니다.

    5. 복제 드롭다운 메뉴의 경우 RA-GRS(읽기 액세스 지역 중복 스토리지)를 클릭합니다.

    6. 성능을 위해 표준을 클릭합니다.

    7. 보안 전송 필요 섹션 내에서 사용 안 함을 클릭합니다.

    8. 구독 드롭다운 메뉴에서 적절한 구독을 클릭합니다.

    9. 리소스 그룹을 선택하거나 새 리소스 그룹을 만듭니다. 리소스 그룹은 Azure 자산 컬렉션에 대한 액세스를 모니터링, 제어, 프로비전 및 관리, 청구하는 방법을 제공합니다. 단일 프로젝트(예: 이러한 과정)와 연결된 모든 Azure 서비스를 공통 리소스 그룹 아래에 유지하는 것이 좋습니다.

      Azure 리소스 그룹에 대해 자세히 알아보려면 리소스 그룹을 관리하는 방법에 대한 이 링크를 따르세요.

    10. 가상 네트워크를사용 안 함으로 둡니다(옵션인 경우).

    11. 만들기를 클릭합니다.

      스토리지 세부 정보 입력

  6. 만들기를 클릭하면 서비스가 만들어질 때까지 기다려야 합니다. 이 작업은 1분 정도 걸릴 수 있습니다.

  7. 서비스 instance 만들어지면 포털에 알림이 표시됩니다. 알림을 클릭하여 새 서비스 instance 탐색합니다.

    새 스토리지 알림

  8. 알림에서 리소스로 이동 단추를 클릭하면 새 Storage 서비스 instance 개요 페이지로 이동합니다.

    배포 성공 알림을 보여 주는 스크린샷 리소스로 이동 단추는 빨간색 원으로 표시됩니다.

  9. 개요 페이지의 오른쪽에서 테이블을 클릭합니다.

    테이블

  10. 오른쪽 패널이 변경되어 새 테이블을 추가해야 하는 Table Service 정보가 표시됩니다. 왼쪽 위 모서리에 있는 + 테이블 단추를 클릭하여 이 작업을 수행합니다.

    테이블 열기

  11. 테이블 이름을 입력해야 하는 새 페이지가 표시됩니다. 이 이름은 이후 챕터(함수 앱 및 Power BI 만들기)에서 애플리케이션의 데이터를 참조하는 데 사용할 이름입니다. IoTMessages를 이름으로 삽입하고(이 문서의 뒷부분에서 사용할 때 직접 선택할 수 있습니다. 기억하기만 하면 됩니다) 확인을 클릭합니다.

  12. 새 테이블이 만들어지면 테이블 서비스 페이지(아래쪽)에서 볼 수 있습니다.

    테이블이 나열된 Table Service 페이지를 보여 주는 스크린샷

  13. 이제 액세스 키를 클릭하고 Storage 계정 이름 의 복사본을 가져옵니다(메모장을 사용). Azure Function App을 만들 때 이 과정의 뒷부분에서 이러한 값을 사용합니다.

    설정 아래에 있는 액세스 키 페이지를 보여 주는 스크린샷 Storage 계정 이름 필드와 키 필드는 빨간색 원으로 표시됩니다.

  14. 왼쪽 패널을 다시 사용하여 테이블 서비스 섹션으로 스크롤하고 테이블 (또는 최신 포털의 테이블 찾아보기)을 클릭하고 테이블 URL 의 복사본을 가져옵니다(메모장을 사용). 이 과정의 뒷부분에서 테이블을 Power BI 애플리케이션에 연결할 때 이 값을 사용합니다.

    테이블 서비스 아래에 있는 테이블 페이지를 보여 주는 스크린샷 I O T 메시지 테이블의 U R L은 빨간색 원으로 표시됩니다.

12장 - Azure 테이블 완료

이제 Table Service 스토리지 계정이 설정되었으므로 정보를 저장하고 검색하는 데 사용할 데이터를 추가할 차례입니다. 테이블 편집은 Visual Studio를 통해 수행할 수 있습니다.

  1. Visual Studio를 엽니다(Visual Studio Code 아님).

  2. 메뉴에서클라우드 Explorer보기를> 클릭합니다.

    클라우드 탐색기 열기

  3. 클라우드 Explorer 도킹된 항목으로 열립니다(로드하는 데 시간이 걸릴 수 있으므로 인내심을 가져야 합니다).

    경고

    스토리지 계정을 만드는 데 사용한 구독이 표시되지 않는 경우 다음이 있는지 확인합니다.

    • Azure Portal에 사용한 계정과 동일한 계정에 로그인했습니다.

    • 계정 관리 페이지에서 구독을 선택했습니다(계정 설정에서 필터를 적용해야 할 수 있음).

      구독 찾기

  4. Azure Cloud Services가 표시됩니다. 스토리지 계정을 찾고 왼쪽에 있는 화살표를 클릭하여 계정을 확장합니다.

    스토리지 계정 열기

  5. 확장되면 새로 만든 Storage 계정을 사용할 수 있어야 합니다. 저장소 왼쪽에 있는 화살표를 클릭한 다음 확장되면 테이블을 찾아 옆에 있는 화살표를 클릭하여 마지막 챕터에서 만든 테이블을 표시합니다. 테이블을 두 번 클릭합니다.

  6. Visual Studio 창의 가운데에 테이블이 열립니다. (더하기)가 있는 + 테이블 아이콘을 클릭합니다.

    새 테이블 추가

  7. 엔터티 추가를 묻는 창이 나타납니다. 엔터티에는 세 개의 속성이 있지만 하나의 엔터티만 만듭니다. 테이블에서 데이터를 찾는 데 사용되므로 PartitionKeyRowKey 가 이미 제공된 것을 알 수 있습니다.

    파티션 및 행 키

  8. 다음 값을 업데이트합니다.

    • 이름: PartitionKey, 값: PK_IoTMessages

    • 이름: RowKey, 값: RK_1_IoTMessages

  9. 그런 다음, 속성 추가 ( 엔터티 추가 창의 왼쪽 아래)를 클릭하고 다음 속성을 추가합니다.

    • MessageContent문자열로 값을 비워 둡니다.
  10. 테이블은 아래 이미지의 테이블과 일치해야 합니다.

    올바른 값 추가

    참고

    엔터티에 행 키의 숫자 1이 있는 이유는 이 과정을 더 실험하려는 경우 메시지를 더 추가할 수 있기 때문입니다.

  11. 작업이 끝나면 확인을 클릭합니다. 이제 테이블을 사용할 준비가 되었습니다.

13장 - Azure 함수 앱 만들기

이제 이전 챕터에서 만든 Table Service에 IoT Edge 디바이스 메시지를 저장하기 위해 IoT Hub 서비스에서 호출되는 Azure Function App을 만들어야 합니다.

먼저 Azure Function에서 필요한 라이브러리를 로드할 수 있는 파일을 만들어야 합니다.

  1. 메모장을 엽니다(Windows 키를 누르고 메모장을 입력).

    메모장 열기

  2. 메모장을 연 상태에서 아래에 JSON 구조를 삽입합니다. 이렇게 하면 데스크톱에 project.json으로 저장합니다. 이 파일은 함수에서 사용할 라이브러리를 정의합니다. NuGet을 사용한 경우 친숙해 보입니다.

    경고

    명명이 올바른 것이 중요합니다. .txt파일 확장 명이 없는지 확인합니다. 참조는 아래를 참조하세요.

    JSON 저장

    {
    "frameworks": {
        "net46":{
        "dependencies": {
            "WindowsAzure.Storage": "9.2.0"
        }
        }
    }
    }
    
  3. Azure Portal에 로그인합니다.

  4. 로그인한 후 왼쪽 위 모서리에서 리소스 만들기를 클릭하고 함수 앱을 검색한 다음 Enter 키를 눌러 검색합니다. 결과에서 함수 앱을 클릭하여 새 패널을 엽니다.

    함수 앱 검색

  5. 새 패널은 함수 App Service에 대한 설명을 제공합니다. 이 패널의 왼쪽 아래에서 만들기 단추를 클릭하여 이 서비스와의 연결을 만듭니다.

    함수 앱 instance

  6. 만들기를 클릭하면 다음을 입력합니다.

    1. 앱 이름에 이 서비스 instance 원하는 이름을 삽입합니다.

    2. 구독을 선택합니다.

    3. 적합한 가격 책정 계층을 선택합니다. 함수 App Service 처음 만드는 경우 무료 계층을 사용할 수 있어야 합니다.

    4. 리소스 그룹을 선택하거나 새 리소스 그룹을 만듭니다. 리소스 그룹은 Azure 자산 컬렉션에 대한 액세스를 모니터링, 제어, 프로비전 및 관리, 청구하는 방법을 제공합니다. 단일 프로젝트(예: 이러한 과정)와 연결된 모든 Azure 서비스를 공통 리소스 그룹 아래에 유지하는 것이 좋습니다.

      Azure 리소스 그룹에 대해 자세히 알아보려면 리소스 그룹을 관리하는 방법에 대한 이 링크를 따르세요.

    5. OS의 경우 의도한 플랫폼이므로 Windows를 클릭합니다.

    6. 호스팅 계획을 선택합니다(이 자습서에서는 소비 계획을 사용합니다.)

    7. 위치를 선택합니다(이전 단계에서 빌드한 스토리지와 동일한 위치 선택)

    8. Storage 섹션의 경우 이전 단계에서 만든 Storage 서비스를 선택해야 합니다.

    9. 이 앱에는 Application Insights가 필요하지 않으므로 자유롭게 십시오.

    10. 만들기를 클릭합니다.

      새 instance 만들기

  7. 만들기를 클릭하면 서비스가 만들어질 때까지 기다려야 합니다. 이 작업은 1분 정도 걸릴 수 있습니다.

  8. 서비스 instance 만들어지면 포털에 알림이 표시됩니다.

    새 알림

  9. 배포가 성공하면 알림을 클릭합니다(완료됨).

  10. 알림에서 리소스로 이동 단추를 클릭하여 새 서비스 instance 탐색합니다.

    배포 성공 알림 창을 보여 주는 스크린샷 리소스로 이동 단추는 빨간색 원으로 표시됩니다.

  11. 새 패널의 왼쪽에서 함수 옆에 있는 + (더하기) 아이콘을 클릭하여 새 함수를 만듭니다.

    Function Apps 페이지를 보여 주는 스크린샷 Functions 옆의 왼쪽 메뉴에서 더하기 기호는 빨간색 원으로 표시됩니다.

  12. 중앙 패널 내에 함수 만들기 창이 나타납니다. 아래로 스크롤하여 사용자 지정 함수를 클릭합니다.

    함수 만들기 창의 아래쪽을 보여 주는 스크린샷 사용자 지정 함수는 빨간색 원으로 표시됩니다.

  13. IoT Hub(이벤트 허브)를 찾을 때까지 다음 페이지를 아래로 스크롤한 다음 클릭합니다.

    빨간색 원을 그리는 I O T Hub 이벤트 허브 상자를 보여 주는 스크린샷

  14. IoT Hub(이벤트 허브) 블레이드에서 언어C#으로 설정한 다음 새로 만들기를 클릭합니다.

    새 함수 페이지를 보여 주는 스크린샷 언어 필드에서 C sharp가 선택됩니다. 새로 만들기는 이벤트 허브 연결 옵션 옆에 빨간색으로 표시됩니다.

  15. 표시되는 창에서 IoT Hub 선택되어 있고 IoT Hub 필드의 이름이 이전에 만든 IoT Hub 서비스의 이름(8단계, 3장)과 일치하는지 확인합니다. 그런 다음 선택 단추를 클릭합니다.

    열린 I O T 허브 탭을 보여 주는 스크린샷. I O T 허브 및 끝점 필드는 빨간색 원으로 표시됩니다.

  16. IoT Hub(이벤트 허브) 블레이드로 돌아가서 만들기를 클릭합니다.

    새 함수 페이지를 보여 주는 스크린샷 만들기 단추는 페이지 아래쪽에 빨간색으로 원을 그립니다.

  17. 함수 편집기로 리디렉션됩니다.

    함수 편집기 페이지를 보여 주는 스크린샷 함수는 왼쪽 메뉴에서 선택됩니다.

  18. 코드의 모든 코드를 삭제하고 다음으로 바꿉다.

    #r "Microsoft.WindowsAzure.Storage"
    #r "NewtonSoft.Json"
    
    using System;
    using Microsoft.WindowsAzure.Storage;
    using Microsoft.WindowsAzure.Storage.Table;
    using Newtonsoft.Json;
    using System.Threading.Tasks;
    
    public static async Task Run(string myIoTHubMessage, TraceWriter log)
    {
        log.Info($"C# IoT Hub trigger function processed a message: {myIoTHubMessage}");
    
        //RowKey of the table object to be changed
        string tableName = "IoTMessages";
        string tableURL = "https://iothubmrstorage.table.core.windows.net/IoTMessages";
    
        // If you did not name your Storage Service as suggested in the course, change the name here with the one you chose.
        string storageAccountName = "iotedgestor"; 
    
        string storageAccountKey = "<Insert your Storage Key here>";   
    
        string partitionKey = "PK_IoTMessages";
        string rowKey = "RK_1_IoTMessages";
    
        Microsoft.WindowsAzure.Storage.Auth.StorageCredentials storageCredentials =
            new Microsoft.WindowsAzure.Storage.Auth.StorageCredentials(storageAccountName, storageAccountKey);
    
        CloudStorageAccount storageAccount = new CloudStorageAccount(storageCredentials, true);
    
        // Create the table client.
        CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
    
        // Get a reference to a table named "IoTMessages"
        CloudTable messageTable = tableClient.GetTableReference(tableName);
    
        //Retrieve the table object by its RowKey
        TableOperation operation = TableOperation.Retrieve<MessageEntity>(partitionKey, rowKey);
        TableResult result = await messageTable.ExecuteAsync(operation);
    
        //Create a MessageEntity so to set its parameters
        MessageEntity messageEntity = (MessageEntity)result.Result;
    
        messageEntity.MessageContent = myIoTHubMessage;
        messageEntity.PartitionKey = partitionKey;
        messageEntity.RowKey = rowKey;
    
        //Replace the table appropriate table Entity with the value of the MessageEntity Ccass structure.
        operation = TableOperation.Replace(messageEntity);
    
        // Execute the insert operation.
        await messageTable.ExecuteAsync(operation);
    }
    
    // This MessageEntity structure which will represent a Table Entity
    public class MessageEntity : TableEntity
    {
        public string Type { get; set; }
        public string MessageContent { get; set; }   
    }
    
  19. 스토리지 계정에서 찾을 수 있는 적절한 값(각각 11단계 및 13단계의테이블스토리지 값)에 해당하도록 다음 변수를 변경합니다.

    • tableName- 스토리지 계정에있는 테이블의 이름을 사용합니다.
    • tableURL- 테이블 의 URL이 스토리지 계정에 있습니다.
    • storageAccountName - 스토리지 계정 이름에 해당하는 값의 이름을 사용합니다.
    • storageAccountKey- 이전에 만든 Storage Service에서 가져온 키를 사용합니다.

    명령 프롬프트를 보여 주는 스크린샷 줄 15, 16, 19 및 21은 빨간색 원으로 표시됩니다.

  20. 코드가 있는 상태에서 저장을 클릭합니다.

  21. 그런 다음 페이지의 오른쪽에 있는 (화살표) 아이콘을 클릭합니다 < .

    Function Apps 페이지를 보여 주는 스크린샷

  22. 패널이 오른쪽에서 안쪽으로 밉니다. 해당 패널에서 업로드를 클릭하면 파일 브라우저 가 나타납니다.

  23. 이전에 메모장에서 만든 project.json 파일로 이동하여 클릭한 다음 열기 단추를 클릭합니다. 이 파일은 함수에서 사용할 라이브러리를 정의합니다.

    파일 보기 아래에 빨간색 원을 그리는 업로드 단추를 보여 주는 스크린샷 파일 브라우저에서 프로젝트 점 제이슨이 선택됩니다.

  24. 파일이 업로드되면 오른쪽 패널에 표시됩니다. 클릭하면 함수 편집기 내에서 열립니다. 다음 이미지와 정확히 같아야 합니다.

    함수 앱 페이지를 보여 주는 스크린샷 왼쪽 메뉴의 통합은 빨간색 원으로 표시됩니다.

  25. 이 시점에서 함수의 기능을 테스트하여 테이블에 메시지를 저장하는 것이 좋습니다. 창의 오른쪽 위에서 테스트를 클릭합니다.

    Function Apps 페이지를 보여 주는 스크린샷 오른쪽 위에서 테스트하고 왼쪽 아래 모서리에 있는 실행 단추가 빨간색 원으로 표시됩니다.

  26. 위의 이미지와 같이 요청 본문에 메시지를 삽입하고 실행을 클릭합니다.

  27. 함수가 실행되어 결과 상태 표시됩니다(출력 창 위에 녹색 상태 202 수락됨이 표시됩니다. 이는 성공적으로 호출되었음을 의미함).

    출력 결과

14장 - 활성 메시지 보기

이제 Visual Studio(Visual Studio Code 아님)를 열면 MessageContent 문자열 영역에 저장되므로 테스트 메시지 결과를 시각화할 수 있습니다.

Microsoft Visual Studio에서 열린 I O T 메시지 테이블 탭을 보여 주는 스크린샷

Table Service 및 함수 앱을 사용하면 Ubuntu 디바이스 메시지가 IoTMessages 테이블에 표시됩니다. 아직 실행되지 않은 경우 디바이스를 다시 시작하고 Visual Studio Cloud Explorer 사용하여 테이블 내에서 디바이스 및 모듈의 결과 메시지를 볼 수 있습니다.

데이터 시각화

15장 - Power BI 설정

IOT 디바이스에서 데이터를 시각화하려면 Power BI (데스크톱 버전)를 설정하여 방금 만든 Table Service에서 데이터를 수집합니다. 그러면 Power BI의 HoloLens 버전이 해당 데이터를 사용하여 결과를 시각화합니다.

  1. Microsoft Store on Windows 10 열고 Power BI Desktop 검색합니다.

    Microsoft Store 창을 보여 주는 스크린샷 검색 창에 Power BI가 입력되고 Power BI Desktop이 빨간색으로 동그라미를 빙글빙글 빙글 돌고 있습니다.

  2. 애플리케이션을 다운로드합니다. 다운로드가 완료되면 엽니다.

  3. Microsoft 365 계정으로 Power BI에 로그인합니다. 등록을 위해 브라우저로 리디렉션될 수 있습니다. 등록되면 Power BI 앱으로 돌아가서 다시 로그인합니다.

  4. 데이터 가져오기를 클릭한 다음 자세히...를 클릭합니다.

    Power BI Desktop을 보여 주는 스크린샷 데이터 가져오기 드롭다운 메뉴에서 더 많은 것이 빨간색으로 원을 그리고 있습니다.

  5. Azure, Azure Table Storage를 클릭한 다음 연결을 클릭합니다.

    데이터 가져오기 창을 보여 주는 스크린샷 Azure Table Storage는 Azure 메뉴 옵션에서 선택됩니다. 오른쪽 아래 모서리에 있는 연결 단추가 빨간색 원으로 표시됩니다.

  6. Table Service를 만드는 동안 이전에 수집한 테이블 URL (11장 13단계)을 삽입하라는 메시지가 표시됩니다. URL을 삽입한 후 테이블 "하위 폴더"(이 과정에서 IoTMessages)를 참조하는 경로 부분을 삭제합니다. 최종 결과는 아래 이미지에 표시되어야 합니다. 그런 다음, 확인을 클릭합니다.

    Azure Table Storage 대화 상자를 보여 주는 스크린샷 계정 이름 또는 U R L 필드에 U R L을 입력합니다.

  7. Table Storage를 만드는 동안 앞에서 기록한 스토리지 키 (11장 11단계)를 삽입하라는 메시지가 표시됩니다. 그런 다음 연결을 클릭합니다.

    Azure Table Storage 계정 키 페이지를 보여 주는 스크린샷

  8. 탐색기 패널이 표시되고 테이블 옆에 있는 상자를 선택하고 로드를 클릭합니다.

    탐색기 패널을 보여 주는 스크린샷 I O T 메시지 파일 옆에 있는 상자가 선택되어 있습니다.

  9. 이제 테이블이 Power BI에 로드되었지만 값을 표시하려면 쿼리가 필요합니다. 이렇게 하려면 화면 오른쪽의 필드 패널 에 있는 테이블 이름을 마우스 오른쪽 단추로 클릭합니다. 그런 다음 쿼리 편집을 클릭합니다.

    필드 패널을 보여 주는 스크린샷 편집 쿼리는 I O T 메시지 오른쪽 단추 클릭 메뉴에서 빨간색으로 동그라미로 표시됩니다.

  10. Power Query 편집기 새 창으로 열리고 테이블이 표시됩니다. 테이블의 콘텐츠 열 내에서 Record라는 단어를 클릭하여 저장된 콘텐츠를 시각화합니다.

    Power Query 편집기 창을 보여 주는 스크린샷 콘텐츠 아래에서 레코드는 빨간색으로 동그라미를 빙글빙글 돌고 있습니다.

  11. 창의 왼쪽 위에 있는 테이블로를 클릭합니다.

    Power Query 편집기 변환 탭을 보여 주는 스크린샷 왼쪽 위 모서리에 있는 Into Table은 빨간색 원으로 표시됩니다.

  12. 닫기 & 적용을 클릭합니다.

    Power Query 편집기 홈 탭을 보여 주는 스크린샷 닫기 및 적용은 빨간색 원으로 표시됩니다.

  13. 쿼리 로드가 완료되면 필드 패널의 화면 오른쪽에서 NameValue 매개 변수에 해당하는 상자를 체크하여 MessageContent 열 콘텐츠를 시각화합니다.

    필드 패널을 보여 주는 스크린샷 I O T 메시지에서 이름 및 값이 선택됩니다. 이름 및 값 열이 있는 팝업 창이 빨간색 원으로 표시됩니다.

  14. 창의 왼쪽 위에 있는 파란색 디스크 아이콘 을 클릭하여 원하는 폴더에 작업을 저장합니다.

    Power BI Desktop을 보여 주는 스크린샷 왼쪽 위 모서리에 있는 파란색 디스크가 빨간색으로 동그라미를 빙글빙글 돌고 있습니다. 다른 이름으로 저장 대화 상자가 열리고 저장 단추가 빨간색 원으로 표시됩니다.

  15. 이제 게시 단추를 클릭하여 테이블을 작업 영역에 업로드할 수 있습니다. 메시지가 표시되면 내 작업 영역을 클릭하고 선택을 클릭합니다. 제출의 성공적인 결과가 표시되기를 기다립니다.

    빨간색 원을 그리는 게시를 보여 주는 스크린샷 Power BI에 게시 대화 상자의 대상 선택에서 내 작업 영역이 선택됩니다.

    Power BI에 게시가 성공했음을 나타내는 알림을 보여 주는 스크린샷

경고

다음 챕터는 HoloLens 관련입니다. Power BI는 현재 몰입형 애플리케이션으로 사용할 수 없습니다. 그러나 데스크톱 앱을 통해 Windows Mixed Reality 포털(클리프 하우스)에서 데스크톱 버전을 실행할 수 있습니다.

16장 - HoloLens에 Power BI 데이터 표시

  1. HoloLens에서 애플리케이션 목록의 아이콘을 탭하여 Microsoft Store에 로그인합니다.

    탐색 창에서 Microsoft Store 아이콘 주위에 빨간색 원을 그리는 Holo Lens가 표시됩니다.

  2. Power BI 애플리케이션을 검색한 다음 다운로드합니다.

    Microsoft Store 페이지를 보여 주는 Holo Lens 디스플레이입니다. 스크롤 도구가 선택되고 검색 창에 전원 B가 입력됩니다.

  3. 애플리케이션 목록에서 Power BI 를 시작합니다.

  4. Power BI 에서 Microsoft 365 계정에 로그인하도록 요청할 수 있습니다.

  5. 앱 내에서 작업 영역은 아래 이미지와 같이 기본적으로 표시됩니다. 그렇지 않으면 창 왼쪽에 있는 작업 영역 아이콘을 클릭하기만 하면 됩니다.

    Microsoft Power BI 페이지를 보여 주는 Holo Lens 디스플레이 위쪽에서 끌어서기 도구가 선택되어 있습니다. 그림과 유사한 작업 영역 아이콘이 빨간색으로 동그라미를 친다. 보고서 아래의 I O T Edge 테이블은 빨간색으로 동그라미를 빙글빙글 돌고 있습니다.

IoT Hub 애플리케이션 완료

축하합니다. 시뮬레이션된 Virtual Machine Edge 디바이스를 사용하여 IoT Hub 서비스를 만들었습니다. 디바이스는 Power BI로 읽고 Microsoft HoloLens 내에서 시각화되는 Azure 함수 앱에서 용이하게 하는 Azure Table Service에 기계 학습 모델의 결과를 전달할 수 있습니다.

Microsoft Power BI 페이지를 보여 주는 Holo Lens 디스플레이

보너스 연습

연습 1

테이블에 저장된 메시징 구조를 확장하고 그래프로 표시합니다. 나중에 표시되도록 더 많은 데이터를 수집하고 동일한 테이블에 저장할 수 있습니다.

연습 2

분석할 카메라를 통해 이미지를 캡처할 수 있도록 IoT 보드에 배포할 추가 "카메라 캡처" 모듈을 만듭니다.