

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 디바이스 섀도우로 디바이스가 오프라인 상태일 때 디바이스 상태 유지
<a name="iot-shadows-tutorial"></a>

이 자습서에서는 AWS IoT 디바이스 섀도우 서비스를 사용하여 디바이스의 상태 정보를 저장하고 업데이트하는 방법을 보여줍니다. JSON 문서인 섀도우 문서는 디바이스, 로컬 앱 또는 서비스에서 게시한 메시지를 기반으로 디바이스 상태의 변화를 보여줍니다. 이 자습서에서 섀도우 문서는 전구의 색상 변화를 보여줍니다. 이 자습서에서는 디바이스가 인터넷에서 연결이 끊어진 경우에도 섀도우가 이 정보를 저장하는 방법과 디바이스가 다시 온라인 상태가 되어 이 정보를 요청할 때 디바이스에 최신 상태 정보를 다시 전달하는 방법도 보여줍니다.

생성하는 데 필요한 AWS IoT 리소스 및 필요한 하드웨어 설정부터 시작하여 여기에 표시된 순서대로 이 자습서를 시도하는 것이 좋습니다. 그러면 개념을 점진적으로 배우는 데도 도움이 됩니다. 이 자습서에서는와 함께 사용할 Raspberry Pi 디바이스를 구성하고 연결하는 방법을 보여줍니다 AWS IoT. 필요한 하드웨어가 없는 경우 자습서를 사용자의 디바이스에 맞게 적용하거나 [Amazon EC2로 가상 디바이스를 생성](creating-a-virtual-thing.md)하여 자습서를 따라할 수 있습니다.

**자습서 시나리오 개요**  
이 자습서의 시나리오는 전구의 색상을 변경하고 해당 데이터를 예약된 섀도우 주제에 게시하는 로컬 앱 또는 서비스입니다. 이 자습서는 [대화형 시작하기 자습서](interactive-demo.md)에 설명된 디바이스 섀도우 기능과 유사하며 Raspberry Pi 디바이스에서 구현됩니다. 이 섹션의 자습서에서는 단일 클래식 섀도우에 초점을 맞추면서 명명된 섀도우 또는 여러 디바이스를 수용할 수 있는 방법을 보여줍니다.

다음 자습서는 AWS IoT 디바이스 섀도우 서비스를 사용하는 방법을 배우는 데 도움이 됩니다.
+ 

**[튜토리얼: 섀도우 애플리케이션 실행을 위해 Raspberry Pi 준비](create-resources-shadow.md)**  
이 자습서에서는 연결을 위해 Raspberry Pi 디바이스를 설정하는 방법을 보여줍니다 AWS IoT. 또한 AWS IoT 정책 문서와 사물 리소스를 생성하고 인증서를 다운로드한 다음 해당 사물 리소스에 정책을 연결합니다. 이 자습서는 완료하는 데 약 30분 소요됩니다.
+ 

**[자습서: 디바이스 SDK 설치 및 디바이스 섀도우용 샘플 애플리케이션 실행](lightbulb-shadow-application.md)**  
이 자습서에서는 필요한 도구, 소프트웨어 및 AWS IoT Device SDK for Python을 설치한 다음 샘플 섀도우 애플리케이션을 실행하는 방법을 보여줍니다. 이 자습서는 [Raspberry Pi 또는 다른 디바이스 연결](connecting-to-existing-device.md)에 제시된 개념을 기반으로 하며 완료하는 데 20분이 소요됩니다.
+ 

**[자습서: 샘플 앱 및 MQTT 테스트 클라이언트를 사용하여 디바이스 섀도우와 상호 작용](interact-lights-device-shadows.md)**  
이 자습서에서는 `shadow.py` 샘플 앱과 **AWS IoT 콘솔**을 사용하여 AWS IoT 디바이스 섀도우와 전구의 상태 변경 간의 상호 작용을 관찰하는 방법을 보여줍니다. 이 자습서에서는 디바이스 섀도우의 예약된 주제에 MQTT 메시지를 전송하는 방법도 보여줍니다. 이 자습서는 완료하는 데 약 45분이 소요됩니다.

**AWS IoT 디바이스 섀도우 개요**  
디바이스 섀도우는 AWS IoT 레지스트리에서 생성한 [사물 리소스](iot-thing-management.md)로 관리되는 디바이스의 지속적인 가상 표현입니다. 섀도우 문서는 디바이스의 현재 상태 정보를 저장하고 검색하는 데 사용되는 JSON 또는 JavaScript 표기법 문서입니다. 디바이스가 인터넷에 연결되어 있는지 여부에 관계없이 섀도우를 사용하여 MQTT 주제 또는 HTTP REST API를 통해 디바이스의 상태를 가져오고 설정할 수 있습니다.

섀도우 문서에는 디바이스 상태의 이러한 측면을 설명하는 `state` 속성이 포함되어 있습니다.
+ `desired`: 앱은 `desired` 객체를 업데이트하여 디바이스 속성에 대해 원하는 상태를 지정합니다.
+ `reported`: 디바이스는 `reported` 객체에 현재 상태를 보고합니다.
+ `delta`: `delta` 객체에서 원하는 상태와 보고된 상태 간의 차이를 AWS IoT 보고합니다.

다음은 섀도우 문서의 예입니다.

```
{
  "state": {
    "desired": {
      "color": "green"
      },
    "reported": {
      "color": "blue"
      },
    "delta": {
      "color": "green"
      }
   }
}
```

디바이스의 섀도우 문서를 업데이트하려면 [예약된 MQTT 주제](reserved-topics.md#reserved-topics-shadow), HTTP로 `GET`, `UPDATE` 및 `DELETE` 작업을 지원하는 [디바이스 섀도우 REST API](device-shadow-rest-api.md) 및 [AWS IoT CLI](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iot-data/index.html)를 사용합니다.

이전 예에서 `desired` 색상을 `yellow`로 변경하려 한다고 가정합니다. 이렇게 하려면 [UpdateThingShadow](device-shadow-rest-api.md#API_UpdateThingShadow) API에 요청을 전송하거나 [업데이트](device-shadow-mqtt.md#update-pub-sub-topic) 주제 `$aws/things/THING_NAME/shadow/update`에 메시지를 게시하세요.

```
{
  "state": {
    "desired": {
      "color": yellow
    }
  }
}
```

업데이트는 요청에 지정된 필드에만 영향을 미칩니다. 디바이스 섀도우를 성공적으로 업데이트한 후는 새 `desired` 상태를 `delta` 주제에 AWS IoT 게시합니다`$aws/things/THING_NAME/shadow/delta`. 이 경우 섀도우 문서는 다음과 같습니다.

```
{
  "state": {
    "desired": {
      "color": yellow
    },
    "reported": {
      "color": green
    },
    "delta": {
      "color": yellow
      }
  }
}
```

그러면 새 상태가 다음 JSON 메시지`$aws/things/THING_NAME/shadow/update`와 함께 `Update` 주제를 사용하여 AWS IoT 디바이스 섀도우에 보고됩니다.

```
{
  "state": {
    "reported": {
      "color": yellow
    }
  }
}
```

현재 상태 정보를 얻으려면 [GetThingShadow](device-shadow-rest-api.md#API_GetThingShadow) API에 요청을 전송하거나 [Get](device-shadow-mqtt.md#get-pub-sub-topic) 주제 `$aws/things/THING_NAME/shadow/get`에 MQTT 메시지를 게시하세요.

디바이스 섀도우 서비스 사용에 대한 자세한 내용은 [AWS IoT 디바이스 섀도우 서비스](iot-device-shadows.md) 단원을 참조하세요.

디바이스, 앱 및 서비스에서 디바이스 섀도우 사용에 대한 자세한 내용은 [디바이스에서 섀도우 사용](device-shadow-comms-device.md) 및 [앱 및 서비스에서 섀도우 사용](device-shadow-comms-app.md) 단원을 참조하세요.

 AWS IoT 섀도우와의 상호 작용에 대한 자세한 내용은 섹션을 참조하세요[섀도우와의 상호 작용](device-shadow-data-flow.md).

MQTT 예약 주제 및 HTTP REST API에 대한 자세한 내용은 [디바이스 섀도우 MQTT 주제](device-shadow-mqtt.md) 및 [디바이스 섀도우 REST API](device-shadow-rest-api.md) 단원을 참조하세요.

# 튜토리얼: 섀도우 애플리케이션 실행을 위해 Raspberry Pi 준비
<a name="create-resources-shadow"></a>

이 자습서에서는 Raspberry Pi 디바이스를 설정 및 구성하고 디바이스가 MQTT 메시지를 연결하고 교환하는 데 필요한 AWS IoT 리소스를 생성하는 방법을 보여줍니다.

**참고**  
[Amazon EC2를 사용하여 가상 디바이스 생성](creating-a-virtual-thing.md)을(를) 계획 중인 경우 이 페이지를 건너뛰고 [디바이스 구성](configure-device.md)을(를) 계속할 수 있습니다. 가상 사물을 만들 때 이러한 리소스를 만듭니다. Raspberry Pi가 아닌 다른 디바이스를 사용하려는 경우 원하는 디바이스에 맞게 이러한 자습서를 따라해볼 수 있습니다.

**이 자습서에서는 다음을 수행하는 방법을 알아봅니다.**
+ Raspberry Pi 디바이스를 설정하고와 함께 사용하도록 구성합니다 AWS IoT.
+ 디바이스가 서비스와 상호 작용 AWS IoT 할 수 있는 권한을 부여하는 AWS IoT 정책 문서를 생성합니다.
+ X.509 디바이스 인증서 AWS IoT 에서 사물 리소스를 생성한 다음 정책 문서를 연결합니다.

  문제는 AWS IoT 레지스트리에 있는 디바이스의 가상 표현입니다. 인증서는 코어에 디바이스를 인증 AWS IoT 하고 정책 문서는 디바이스가 상호 작용할 수 있는 권한을 부여합니다 AWS IoT.

**이 자습서를 실행하는 방법**  
디바이스 섀도우용 `shadow.py` 샘플 애플리케이션을 실행하려면 AWS IoT에 연결하는 Raspberry Pi 디바이스가 필요합니다. 여기에 나와 있는 순서대로 이 자습서를 따라하여 Raspberry Pi 및 해당 액세서리 설정부터 시작해서 정책을 생성하고, 생성한 사물 리소스에 이 정책을 연결하는 것이 좋습니다. 그런 다음 Raspberry Pi에서 지원하는 그래픽 사용자 인터페이스(GUI)를 사용하여 디바이스의 웹 브라우저에서 AWS IoT 콘솔을 열어이 자습서를 따를 수 있습니다. 그러면 연결을 위해 인증서를 Raspberry Pi에 직접 다운로드할 수 있습니다 AWS IoT.

**이 자습서를 시작하기 전에 다음 사항을 확인해야 합니다.**
+  AWS 계정. 없는 경우 계속하기 전에 [설정 AWS 계정](setting-up.md)에서 설명하는 단계를 완료하세요. 이 자습서를 완료하려면 AWS 계정 및 AWS IoT 콘솔이 필요합니다.
+ Raspberry Pi 및 필요한 해당 액세서리. 다음 사항이 필요합니다.
  + [Raspberry Pi 3 Model B](https://www.raspberrypi.com/products/) 또는 최신 모델. 이 자습서는 이전 버전의 Raspberry Pi에서 작동할 수 있지만 테스트되지 않았습니다.
  + [Raspberry Pi OS(32비트)](https://www.raspberrypi.com/software/operating-systems/) 이상. 최신 버전의 Raspberry Pi OS를 사용하는 것이 좋습니다. 이전 버전의 OS는 작동하지만 테스트되지 않았습니다.
  + 이더넷 또는 Wi-Fi 연결.
  + 키보드, 마우스, 모니터, 케이블 및 전원 공급장치.

이 자습서는 완료하는 데 약 30분 소요됩니다.

## 1단계: Raspberry Pi 디바이스 설정 및 구성
<a name="setup-device-shadow"></a>

이 섹션에서는와 함께 사용할 Raspberry Pi 디바이스를 구성합니다 AWS IoT.

**중요**  
이러한 지침을 다른 디바이스 및 운영 체제에 적용하는 것은 어려울 수 있습니다. 이러한 지침을 해석하고 디바이스에 적용할 수 있을 만큼 디바이스를 잘 이해해야 합니다. 문제가 발생하면 다른 디바이스 옵션(예: [Amazon EC2를 사용하여 가상 디바이스 생성](creating-a-virtual-thing.md) 또는 [Windows 또는 Linux PC 또는 Mac을 AWS IoT 디바이스로 사용](using-laptop-as-device.md)) 중 하나를 대안으로 사용해 볼 수 있습니다.

운영 체제(OS)를 시작하고, 인터넷에 연결하고, 명령줄 인터페이스에서 상호 작용할 수 있도록 Raspberry Pi를 구성해야 합니다. Raspberry Pi와 함께 지원되는 그래픽 사용자 인터페이스(GUI)를 사용하여 AWS IoT 콘솔을 열고이 자습서의 나머지 부분을 실행할 수도 있습니다.

**Raspberry Pi를 설정하려면 다음을 수행합니다.**

1. SD 카드를 Raspberry Pi의 MicroSD 카드 슬롯에 삽입합니다. 일부 SD 카드에는 보드를 부팅한 후 OS 설치 메뉴를 표시하는 설치 관리자가 미리 로드되어 있습니다. Raspberry Pi 이미저를 사용하여 카드에 OS를 설치할 수도 있습니다.

1. Raspberry Pi의 HDMI 포트에 연결하는 HDMI 케이블에 HDMI TV 또는 모니터를 연결합니다.

1. 키보드와 마우스를 Raspberry Pi의 USB 포트에 연결한 다음 전원 어댑터를 연결하여 보드를 부팅합니다.

Raspberry Pi가 부팅된 후, SD 카드에 설치 관리자가 미리 로드된 경우 운영 체제를 설치하는 메뉴가 나타납니다. OS를 설치하는 데 문제가 있는 경우 다음 단계를 시도할 수 있습니다. Raspberry Pi 설정에 대한 자세한 내용은 [Raspberry Pi 설정](https://projects.raspberrypi.org/en/projects/raspberry-pi-setting-up/)을 참조하세요.

**Raspberry Pi 설정에 문제가 있는 경우:**
+ 보드를 부팅하기 전에 SD 카드를 삽입했는지 확인하세요. 보드를 부팅한 후 SD 카드를 연결하면 설치 메뉴가 나타나지 않을 수 있습니다.
+ TV 또는 모니터가 켜져 있고 올바른 입력이 선택되어 있는지 확인합니다.
+ Raspberry Pi 호환 소프트웨어를 사용하고 있는지 확인합니다.

Raspberry Pi OS를 설치하고 구성한 후 Raspberry Pi의 웹 브라우저를 열고 AWS IoT Core 콘솔로 이동하여이 자습서의 나머지 단계를 계속합니다.

 AWS IoT Core 콘솔을 열 수 있으면 Raspberry Pi가 준비되고 로 계속 진행할 수 있습니다[자습서:에서 디바이스 프로비저닝 AWS IoT](shadow-provision-cloud.md).

문제가 계속되거나 추가 도움이 필요한 경우 [Raspberry Pi에 대한 도움말](https://projects.raspberrypi.org/en/projects/raspberry-pi-setting-up/5)을 참조하세요

# 자습서:에서 디바이스 프로비저닝 AWS IoT
<a name="shadow-provision-cloud"></a>

이 섹션에서는 자습서에서 사용할 AWS IoT Core 리소스를 생성합니다.

**Topics**
+ [1단계: 디바이스 섀도우에 대한 AWS IoT 정책 생성](#create-policy-shadow)
+ [2단계: 사물 리소스를 만들고 정책을 사물에 연결](#create-thing-shadow)
+ [3단계: 결과 및 다음 단계 검토](#resources-shadow-review)

## 1단계: 디바이스 섀도우에 대한 AWS IoT 정책 생성
<a name="create-policy-shadow"></a>

X.509 인증서는 디바이스를 인증합니다 AWS IoT Core. AWS IoT 정책은 디바이스가 디바이스 섀도우 서비스에서 사용하는 MQTT 예약 주제를 구독하거나 게시하는 등의 AWS IoT 작업을 수행하도록 허용하는 인증서에 연결됩니다. 디바이스가 연결하고 메시지를 보낼 때 인증서를 제공합니다 AWS IoT Core.

이 절차에서는 디바이스가 예제 프로그램을 실행하는 데 필요한 AWS IoT 작업을 수행하도록 허용하는 정책을 만듭니다. 작업을 수행하는 데 필요한 권한만 부여하는 정책을 생성하는 것이 좋습니다. 먼저 AWS IoT 정책을 생성한 다음 나중에 생성할 디바이스 인증서에 연결합니다.

**AWS IoT 정책을 생성하려면**

1. 왼쪽 메뉴에서 **보안(Secure)**을 선택한 다음 **정책(Policies)**을 선택합니다. 계정에 기존 정책이 있는 경우 **생성(Create)**을 선택하고, 그렇지 않은 경우 **아직 정책이 없습니다(You don’t have a policy yet)** 페이지에서 **정책 생성(Create a policy)**을 선택합니다.

1. **정책 생성** 페이지에서 다음을 수행합니다.

   1. **이름(Name)** 필드에 정책 이름(예: **My\$1Device\$1Shadow\$1policy**)을 입력합니다. 정책 이름에 개인 식별 정보를 사용하면 안 됩니다.

   1. 정책 문서에서, MQTT 예약 주제를 게시하고 구독할 수 있는 권한을 디바이스에 부여하는 연결, 구독, 수신 및 게시 작업을 설명합니다.

      다음 샘플 정책을 복사하여 정책 문서에 붙여넣습니다. `thingname`를 생성할 사물의 이름(예: `My_light_bulb`), `region`를 서비스를 사용 중인 AWS IoT 리전, `account`를 사용자 AWS 계정 번호로 바꿉니다. AWS IoT 정책에 대한 자세한 내용은 섹션을 참조하세요[AWS IoT Core 정책](iot-policies.md).  
****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Publish"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/get",
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/update"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Receive"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/get/accepted",
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/get/rejected",
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/update/accepted",
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/update/rejected",
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/update/delta"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Subscribe"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingname/shadow/get/accepted",
                      "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingname/shadow/get/rejected",
                      "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingname/shadow/update/accepted",
                      "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingname/shadow/update/rejected",
                      "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingname/shadow/update/delta"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": "iot:Connect",
                  "Resource": "arn:aws:iot:us-east-1:123456789012:client/test-*"
              }
          ]
      }
      ```

## 2단계: 사물 리소스를 만들고 정책을 사물에 연결
<a name="create-thing-shadow"></a>

에 연결된 디바이스는 AWS IoT 레지스트리의 *사물 리소스*로 표현할 AWS IoT 수 있습니다. *사물 리소스*는 이 자습서의 전구와 같은 특정 디바이스 또는 논리적 엔터티를 나타냅니다.

에서 사물을 생성하는 방법을 알아보려면에 설명된 단계를 AWS IoT따르세요[사물 객체 만들기](create-iot-resources.md#create-aws-thing). 이 자습서의 단계를 수행할 때 주의해야 할 주요 사항은 다음과 같습니다.

1. **단일 사물 생성(Create a single thing)**을 선택하고 **이름(Name)** 필드에 이전에 정책을 생성할 때 지정한 `thingname`(예: `My_light_bulb`)과 동일한 사물의 이름을 입력합니다.

   사물 이름이 생성된 이후에는 그 이름을 바꿀 수 없습니다. `thingname`이 아닌 다른 이름을 부여했다면 `thingname`이라는 이름으로 새 것을 만들고 이전 것을 삭제하세요.
**참고**  
사물 이름에 개인 식별 정보를 사용하면 안 됩니다. 사물 이름은 암호화되지 않은 통신 및 보고서에 나타날 수 있습니다.

1. **인증서 생성됨(Certificate created\$1)** 페이지의 각 인증서 파일을, 쉽게 찾을 수 있는 위치에 다운로드하는 것이 좋습니다. 샘플 애플리케이션을 실행하려면 이러한 파일을 설치해야 합니다.

   Raspberry Pi의 `home` 디렉터리에 있는 `certs` 하위 디렉터리에 파일을 다운로드하고 다음 표에서 제안하는 대로 각각의 이름을 더 간단한 이름으로 지정하는 것이 좋습니다.  
**인증서 파일 이름**    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/iot/latest/developerguide/shadow-provision-cloud.html)

1. 인증서를 활성화하여 연결을 활성화한 후 **정책 연결을** AWS IoT선택하고 이전에 생성한 정책(예: **My\$1Device\$1Shadow\$1policy**)을 사물에 연결했는지 확인합니다.

   사물을 생성한 후에는 AWS IoT 콘솔의 사물 목록에 사물 리소스가 표시됩니다.

## 3단계: 결과 및 다음 단계 검토
<a name="resources-shadow-review"></a>

**이 자습서에서는 다음을 수행하는 방법을 알아보았습니다.**
+ Raspberry Pi 디바이스 설정 및 구성.
+ 디바이스가 서비스와 상호 작용 AWS IoT 할 수 있도록 권한을 부여하는 AWS IoT 정책 문서를 생성합니다.
+ 사물 리소스 및 연결된 X.509 디바이스 인증서를 만들고 여기에 정책 문서 연결.

**다음 단계**  
이제 Python용 AWS IoT 디바이스 SDK를 설치하고, `shadow.py` 샘플 애플리케이션을 실행하고, 디바이스 섀도우를 사용하여 상태를 제어할 수 있습니다. 이 자습서를 실행하는 방법에 대한 자세한 내용은 [자습서: 디바이스 SDK 설치 및 디바이스 섀도우용 샘플 애플리케이션 실행](lightbulb-shadow-application.md) 단원을 참조하세요.

# 자습서: 디바이스 SDK 설치 및 디바이스 섀도우용 샘플 애플리케이션 실행
<a name="lightbulb-shadow-application"></a>

이 섹션에서는 필요한 소프트웨어와 Python용 AWS IoT Device SDK를 설치하고 `shadow.py` 샘플 애플리케이션을 실행하여 섀도우 문서를 편집하고 섀도우 상태를 제어하는 방법을 보여줍니다.

**이 자습서에서는 다음을 수행하는 방법을 알아봅니다.**
+ 설치된 소프트웨어와 AWS IoT Device SDK for Python을 사용하여 샘플 앱을 실행합니다.
+ 샘플 앱을 사용하여 값을 입력하면 AWS IoT 콘솔에 원하는 값이 게시되도록 하는 방법을 알아봅니다.
+ `shadow.py` 샘플 앱과 MQTT 프로토콜을 사용하여 섀도우 상태를 업데이트하는 방법을 검토합니다.

**이 자습서를 실행하기 전에 다음을 수행합니다.**  
를 설정하고 AWS 계정, Raspberry Pi 디바이스를 구성하고, 디바이스에 디바이스 섀도우 서비스의 MQTT 예약 주제를 게시하고 구독할 수 있는 권한을 부여하는 AWS IoT 사물 및 정책을 생성해야 합니다. 자세한 내용은 [튜토리얼: 섀도우 애플리케이션 실행을 위해 Raspberry Pi 준비](create-resources-shadow.md) 단원을 참조하십시오.

Git, Python 및 AWS IoT Device SDK for Python도 설치해야 합니다. 이 자습서는 자습서 [Raspberry Pi 또는 다른 디바이스 연결](connecting-to-existing-device.md)에 제공된 개념을 기반으로 합니다. 해당 자습서를 시도하지 않은 경우 해당 자습서에 설명된 단계에 따라 인증서 파일 및 Device SDK를 설치한 다음 이 자습서로 돌아와서 `shadow.py` 샘플 앱을 실행하는 것이 좋습니다.

**Topics**
+ [1단계: shadow.py 샘플 앱 실행](#run-sample-application-shadows)
+ [2단계: shadow.py 디바이스 SDK 샘플 앱 검토](#review-shadow-sample-code)
+ [3단계: `shadow.py` 샘플 앱 문제 해결](#shadow-sample-app-troubleshoot)
+ [4단계: 결과 및 다음 단계 검토](#sample-app-shadow-review)

이 자습서는 완료하는 데 약 20분이 소요됩니다.

## 1단계: shadow.py 샘플 앱 실행
<a name="run-sample-application-shadows"></a>

`shadow.py` 샘플 앱을 실행하기 전에 설치한 인증서 파일의 이름과 위치 외에 다음 정보가 필요합니다.


**애플리케이션 파라미터 값**  

|  파라미터  |  값을 찾을 수 있는 위치  | 
| --- | --- | 
| your-iot-thing-name |  에서 이전에 생성한 AWS IoT 사물의 이름입니다[2단계: 사물 리소스를 만들고 정책을 사물에 연결](shadow-provision-cloud.md#create-thing-shadow). 이 값을 찾으려면 [AWS IoT 콘솔](https://console.aws.amazon.com/iot/home)에서 **관리(Manage)**를 선택한 다음 **사물(Things)**을 선택합니다.  | 
| your-iot-endpoint |   *your-iot-endpoint* 값의 형식은 `endpoint_id-ats.iot.region.amazonaws.com`(예: `a3qj468EXAMPLE-ats.iot.us-west-2.amazonaws.com`)입니다. 이 값을 찾으려면: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/iot/latest/developerguide/lightbulb-shadow-application.html)  | 

**샘플 앱 설치 및 실행**

1. 샘플 앱 디렉터리로 이동합니다.

   ```
   cd ~/aws-iot-device-sdk-python-v2/samples/service-clients
   ```

1. 명령줄 창에서 표시된 대로 *your-iot-endpoint* 및 *your-iot-thing-name*을 바꾸고 이 명령을 실행합니다.

   ```
   python3 shadow.py --ca_file ~/certs/Amazon-root-CA-1.pem --cert ~/certs/device.pem.crt --key ~/certs/private.pem.key --endpoint your-iot-endpoint --thing_name your-iot-thing-name
   ```

1. 샘플 앱에서 다음 사항을 확인합니다.

   1. 계정의 AWS IoT 서비스에 연결합니다.

   1. `Delta` 이벤트와 `Update` 및 `Get` 응답을 구독합니다.

   1. 터미널에 원하는 값을 입력하라는 메시지가 표시됩니다.

   1. 다음과 유사한 출력이 표시됩니다.

   ```
   Connecting to a3qEXAMPLEffp-ats.iot.us-west-2.amazonaws.com with client ID 'test-0c8ae2ff-cc87-49d2-a82a-ae7ba1d0ca5a'...
   Connected!
   Subscribing to Delta events...
   Subscribing to Update responses...
   Subscribing to Get responses...
   Requesting current shadow state...
   Launching thread to read user input...
   Finished getting initial shadow state.
   Shadow contains reported value 'off'.
   Enter desired value:
   ```

**참고**  
`shadow.py` 샘플 앱을 실행하는 데 문제가 있는 경우 [3단계: `shadow.py` 샘플 앱 문제 해결](#shadow-sample-app-troubleshoot)을(를) 검토합니다. 문제를 해결하는 데 도움이 될 수 있는 추가 정보를 얻으려면 명령줄에 `--verbosity debug` 파라미터를 추가하여 샘플 앱이 수행 중인 작업에 대한 자세한 메시지를 표시하도록 합니다.

**섀도우 문서에서 값을 입력하고 업데이트를 관찰합니다.**  
터미널에 값을 입력하여 `desired` 값을 업데이트합니다. 이는 `reported` 값도 업데이트합니다. 터미널에 색상 `yellow`를 입력한다고 가정합니다. `reported` 값도 `yellow` 색상으로 업데이트됩니다. 다음은 터미널에 표시되는 메시지를 보여줍니다.

```
Enter desired value:
yellow
Changed local shadow value to 'yellow'.
Updating reported shadow value to 'yellow'...
Update request published.
Finished updating reported shadow value to 'yellow'.
```

이 업데이트 요청을 게시하면 사물 리소스에 대한 기본 클래식 섀도우가 AWS IoT 생성됩니다. 생성한 사물 리소스(예: )에 대한 섀도우 문서를 확인하여 AWS IoT 콘솔의 `reported` 및 `desired` 값에 게시한 업데이트 요청을 관찰할 수 있습니다`My_light_bulb`. 섀도우 문서에서 업데이트를 보려면:

1.  AWS IoT 콘솔에서 **관리를** 선택한 다음 **사물**을 선택합니다.

1. 표시된 사물 목록에서 생성한 사물을 선택하고 **섀도우(Shadows)**를 선택한 다음 **클래식 섀도우(Classic Shadow)**를 선택합니다.

섀도우 문서는 다음과 유사해야 하며, `yellow` 색상으로 설정된 `reported` 및 `desired` 값을 보여줍니다. 이 값들은 문서의 **섀도우 상태** 섹션에 나와 있습니다.

```
{
"desired": {
  "welcome": "aws-iot",
  "color": "yellow"
},
"reported": {
  "welcome": "aws-iot",
  "color": "yellow"
}
}
```

타임스탬프 정보와 요청 버전 번호가 포함된 **메타데이터** 섹션도 표시됩니다.

상태 문서 버전을 사용하면 업데이트하는 디바이스 섀도우 문서가 최신 버전인지 확인할 수 있습니다. 다른 업데이트 요청을 전송하면 버전 번호가 1씩 증가합니다. 업데이트 요청에 버전을 입력하면 상태 문서의 현재 버전이 입력된 버전과 일치하지 않을 경우 서비스가 HTTP 409 충돌 응답 코드와 함께 요청을 거부합니다.

```
{
"metadata": {
  "desired": {
    "welcome": {
      "timestamp": 1620156892
    },
    "color": {
      "timestamp": 1620156893
    }
  },
  "reported": {
    "welcome": {
      "timestamp": 1620156892
    },
    "color": {
      "timestamp": 1620156893
    }
  }
},
"version": 10
}
```

섀도우 문서에 대해 자세히 알아보고 상태 정보의 변경 사항을 관찰하려면 이 자습서의 [4단계: 결과 및 다음 단계 검토](#sample-app-shadow-review) 섹션에 설명된 대로 다음 자습서 [자습서: 샘플 앱 및 MQTT 테스트 클라이언트를 사용하여 디바이스 섀도우와 상호 작용](interact-lights-device-shadows.md)(으)로 진행하세요. 선택적으로 다음 섹션에서 `shadow.py` 샘플 코드 및 이 코드가 MQTT 프로토콜을 사용하는 방법에 대해 알아볼 수도 있습니다.

## 2단계: shadow.py 디바이스 SDK 샘플 앱 검토
<a name="review-shadow-sample-code"></a>

이 섹션에서는 이 자습서에 사용된 **AWS IoT Device SDK v2 for Python**의 `shadow.py` 샘플 앱을 검토합니다. 여기서는 MQTT 및 MQTT over WSS 프로토콜을 AWS IoT Core 사용하여에 연결하는 방법을 살펴보겠습니다. [AWS 공통 런타임(AWS-CRT)](https://github.com/awslabs/aws-crt-python#aws-crt-python) 라이브러리는 하위 수준 통신 프로토콜을 지원하며 Python용 AWS IoT Device SDK v2에 포함되어 있습니다.

이 자습서에서는 WSS를 통해 MQTT 및 MQTT를 사용하지만는 HTTPS 요청을 게시하는 디바이스를 AWS IoT 지원합니다. 디바이스에서 HTTP 메시지를 전송하는 Python 프로그램의 예는 Python의 `requests` 라이브러리를 사용하는 [HTTPS 코드 예](http.md#codeexample)를 참조하세요.

디바이스 통신에 사용할 프로토콜에 대한 정보를 바탕으로 결정을 내릴 수 있는 방법에 대한 자세한 내용은 [디바이스 통신을 위한 애플리케이션 프로토콜 선택](protocols.md#protocol-selection) 단원을 검토하세요.

**MQTT**  
`shadow.py` 샘플은 [https://github.com/awslabs/aws-crt-python/blob/89207bcf1387177034e02fe29e8e469ca45e39b7/awscrt/awsiot_mqtt_connection_builder.py](https://github.com/awslabs/aws-crt-python/blob/89207bcf1387177034e02fe29e8e469ca45e39b7/awscrt/awsiot_mqtt_connection_builder.py)에서 `mtls_from_path`(여기에 표시됨)를 직접 호출해서 MQTT 프로토콜을 사용하여 AWS IoT Core 와의 연결을 설정합니다. `mtls_from_path`는 X.509 인증서와 TLS v1.2를 사용하여 디바이스를 인증합니다. AWS CRT 라이브러리는 해당 연결의 하위 수준 세부 정보를 처리합니다.

```
mqtt_connection = mqtt_connection_builder.mtls_from_path(
  endpoint=args.endpoint,
  cert_filepath=args.cert,
  pri_key_filepath=args.key,
  ca_filepath=args.ca_file,
  client_bootstrap=client_bootstrap,
  on_connection_interrupted=on_connection_interrupted,
  on_connection_resumed=on_connection_resumed,
  client_id=args.client_id,
  clean_session=False,
  keep_alive_secs=6
)
```
+ `endpoint`는 명령줄에서 전달한 AWS IoT 엔드포인트이며 `client_id`는에서이 디바이스를 고유하게 식별하는 ID입니다 AWS 리전.
+ `cert_filepath`,`pri_key_filepath` 및 `ca_filepath`는 디바이스의 인증서 및 프라이빗 키 파일과 루트 CA 파일에 대한 경로입니다.
+ `client_bootstrap`은 소켓 통신 활동을 처리하는 공통 런타임 객체이며 `mqtt_connection_builder.mtls_from_path`를 호출하기 전에 인스턴스화됩니다.
+ `on_connection_interrupted` 및 `on_connection_resumed`는 디바이스의 연결이 중단되었다가 재개될 때 호출하는 콜백 함수입니다.
+ `clean_session`은 새로운 영구 세션을 시작할지 또는 존재하는 경우 기존 세션에 다시 연결할지 여부입니다. `keep_alive_secs`는 `CONNECT` 요청에서 전송할 연결 유지 값(초)입니다. 이 간격으로 ping이 자동으로 전송됩니다. 서버는 이 값의 1.5배 후에 ping을 수신하지 않으면 연결이 끊어지는 것으로 가정합니다.

`shadow.py` 샘플은 또한 [https://github.com/awslabs/aws-crt-python/blob/89207bcf1387177034e02fe29e8e469ca45e39b7/awscrt/awsiot_mqtt_connection_builder.py](https://github.com/awslabs/aws-crt-python/blob/89207bcf1387177034e02fe29e8e469ca45e39b7/awscrt/awsiot_mqtt_connection_builder.py)에서 `websockets_with_default_aws_signing`을 호출하여 WSS를 통해 MQTT 프로토콜을 사용하여 AWS IoT Core 와의 연결을 설정합니다. MQTT over WSS는 MQTT와 동일한 파라미터를 사용하며 다음과 같은 추가 파라미터를 사용합니다.
+ `region`는 Signature V4 인증에 사용되는 AWS 서명 리전이며 `credentials_provider`는 인증에 사용하기 위해 제공되는 AWS 자격 증명입니다. 리전은 명령줄에서 전달되고 `credentials_provider` 객체는 `mqtt_connection_builder.websockets_with_default_aws_signing`을 호출하기 직전에 인스턴스화됩니다.
+ `websocket_proxy_options`는 프록시 호스트를 사용하는 경우 HTTP 프록시 옵션입니다. `shadow.py` 샘플 앱에서 이 값은 `mqtt_connection_builder.websockets_with_default_aws_signing`을 호출하기 직전에 인스턴스화됩니다.

**섀도우 주제 및 이벤트 구독**  
`shadow.py` 샘플은 연결을 설정하려고 시도하고 완전히 연결될 때까지 기다립니다. 연결되어 있지 않으면 명령이 대기열에 저장됩니다. 연결되면 샘플은 델타 이벤트를 구독하고 메시지를 업데이트하고 가져오고 서비스 품질(QoS) 수준이 1(`mqtt.QoS.AT_LEAST_ONCE`)인 메시지를 게시합니다.

디바이스가 QoS 수준 1의 메시지를 구독하면 메시지 브로커는 디바이스로 전송할 수 있을 때까지 디바이스가 구독한 메시지를 저장합니다. 메시지 브로커는 디바이스로부터 `PUBACK` 응답을 받을 때까지 메시지를 다시 전송합니다.

MQTT 프로토콜에 대한 자세한 내용은 [MQTT 프로토콜 검토](sdk-tutorials.md#sdk-tutorials-mqtt-review) 및 [MQTT](mqtt.md) 단원을 참조하세요.

이 자습서에서 사용되는 MQTT, MQTT over WSS, 영구 세션 및 QoS 수준에 대한 자세한 내용은 [pubsub.py Device SDK 샘플 앱 검토](sdk-tutorials.md#sdk-tutorials-explore-sample) 단원을 참조하세요.

## 3단계: `shadow.py` 샘플 앱 문제 해결
<a name="shadow-sample-app-troubleshoot"></a>

`shadow.py` 샘플 앱을 실행하면 터미널에 일부 메시지가 표시되고 `desired` 값을 입력하라는 메시지가 표시되어야 합니다. 프로그램에서 오류가 발생한 경우 오류를 디버깅하려면 먼저 시스템에 올바른 명령을 실행했는지 여부를 확인할 수 있습니다.

경우에 따라 오류 메시지는 연결 문제를 나타내며 `Host name was invalid for dns resolution` 또는 `Connection was closed unexpectedly`와 유사하게 표시될 수 있습니다. 이 경우 확인할 수 있는 사항은 다음과 같습니다.
+ 

**명령에서 엔드포인트 주소 확인**  
샘플 앱을 실행하기 위해 입력한 명령의 `endpoint` 인수(예: `a3qEXAMPLEffp-ats.iot.us-west-2.amazonaws.com`)를 검토하고 **AWS IoT 콘솔**에서 이 값을 확인합니다.

  올바른 값을 사용했는지 확인하려면 다음과 같이 하세요.

  1. **AWS IoT 콘솔**에서 **관리(Manage)**를 선택한 다음 **사물(Things)**을 선택합니다.

  1. 샘플 앱에 대해 만든 사물(예: **My\$1light\$1bulb**)을 선택한 다음 **상호 작용(Interact)**을 선택합니다.

  사물 세부 정보 페이지의 **HTTPS** 섹션에 엔드포인트가 표시됩니다. 또한 `This thing already appears to be connected.`와 같은 메시지가 표시됩니다.
+ 

**인증서 활성화 확인**  
인증서는 디바이스를 인증합니다 AWS IoT Core.

  인증서가 활성 상태인지 확인하려면 다음과 같이 하세요.

  1. **AWS IoT 콘솔**에서 **관리(Manage)**를 선택한 다음 **사물(Things)**을 선택합니다.

  1. 샘플 앱에 대해 만든 사물(예: **My\$1light\$1bulb**)를 선택한 다음 **보안(Security)**을 선택합니다.

  1. 인증서를 선택하고 인증서의 세부 정보 페이지에서 인증서 선택을 선택한 후 인증서의 세부 정보 페이지에서 **작업(Actions)**을 선택합니다.

  드롭다운 목록에서 **활성화(Activate)**를 사용할 수 없고 **비활성화(Deactivate)**만 선택할 수 있는 경우 인증서가 활성화된 것입니다. 그렇지 않은 경우 **활성화(Activate)**를 선택하고 샘플 프로그램을 다시 실행하세요.

  그래도 프로그램이 실행되지 않으면 `certs` 폴더의 인증서 파일 이름을 확인합니다.
+ 

**사물 리소스에 연결된 정책 확인**  
인증서가 디바이스를 인증하는 동안 AWS IoT 정책은 디바이스가 MQTT 예약 주제 구독 또는 게시와 같은 AWS IoT 작업을 수행하도록 허용합니다.

  올바른 정책이 연결되어 있는지 확인하려면 다음과 같이 하세요.

  1. 앞에서 설명한 대로 인증서를 찾은 다음 **정책(Policies)**을 선택합니다.

  1. 표시된 정책을 선택하고, MQTT 예약 주제를 게시하고 구독할 수 있는 권한을 디바이스에 부여하는 `connect`, `subscribe`, `receive` 및 `publish` 작업을 설명하는지 확인하세요.

     샘플 정책은 [1단계: 디바이스 섀도우에 대한 AWS IoT 정책 생성](shadow-provision-cloud.md#create-policy-shadow) 단원을 참조하세요.

  에 연결하는 AWS IoT데 문제가 있음을 나타내는 오류 메시지가 표시되면 정책에 사용 중인 권한 때문일 수 있습니다. 이 경우 AWS IoT 리소스에 대한 전체 액세스를 제공하는 정책으로 시작한 다음 샘플 프로그램을 다시 실행하는 것이 좋습니다. 현재 정책을 편집하거나 현재 정책을 선택하고 **분리(Detach)**를 선택한 다음 전체 액세스 권한을 제공하는 다른 정책을 생성하여 사물 리소스에 연결할 수 있습니다. 나중에 프로그램을 실행하는 데 필요한 작업 및 정책으로만 정책을 제한할 수 있습니다.  
****  

  ```
  {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:*"
            ],
            "Resource": "*"
        }
    ]
  }
  ```
+ 

**Device SDK 설치 확인**  
그래도 프로그램이 실행되지 않으면 Device SDK를 다시 설치하여 SDK 설치가 올바르게 완료되었는지 확인할 수 있습니다.

## 4단계: 결과 및 다음 단계 검토
<a name="sample-app-shadow-review"></a>

**이 자습서에서는 다음을 수행하는 방법을 알아보았습니다.**
+ 필요한 소프트웨어, 도구 및 AWS IoT Device SDK for Python을 설치합니다.
+ 샘플 앱 `shadow.py`가 MQTT 프로토콜을 사용하여 섀도우의 현재 상태를 검색하고 업데이트하는 방식 이해.
+ 디바이스 섀도우용 샘플 앱을 실행하고 AWS IoT 콘솔에서 섀도우 문서에 대한 업데이트를 관찰합니다. 또한 프로그램을 실행할 때 문제를 해결하고 오류를 수정하는 방법을 배웠습니다.

**다음 단계**  
이제 `shadow.py` 샘플 애플리케이션을 실행하고 디바이스 섀도우를 사용하여 상태를 제어할 수 있습니다. AWS IoT 콘솔에서 섀도우 문서에 대한 업데이트를 관찰하고 샘플 앱이 응답하는 델타 이벤트를 관찰할 수 있습니다. MQTT 테스트 클라이언트를 사용하여 예약된 섀도 주제를 구독하고 샘플 프로그램을 실행할 때 주제에서 수신한 메시지를 관찰할 수 있습니다. 이 자습서를 실행하는 방법에 대한 자세한 내용은 [자습서: 샘플 앱 및 MQTT 테스트 클라이언트를 사용하여 디바이스 섀도우와 상호 작용](interact-lights-device-shadows.md) 단원을 참조하세요.

# 자습서: 샘플 앱 및 MQTT 테스트 클라이언트를 사용하여 디바이스 섀도우와 상호 작용
<a name="interact-lights-device-shadows"></a>

`shadow.py` 샘플 앱과 상호 작용하려면 터미널에 `desired` 값에 대한 값을 입력합니다. 예를 들어 신호등과 비슷하고 요청에 AWS IoT 응답하며 보고된 값을 업데이트하는 색상을 지정할 수 있습니다.

**이 자습서에서는 다음을 수행하는 방법을 알아봅니다.**
+ `shadow.py` 샘플 앱을 사용하여 원하는 상태를 지정하고 섀도우의 현재 상태를 업데이트합니다.
+ 섀도우 문서를 편집하여 델타 이벤트를 관찰하고 `shadow.py` 샘플 앱이 델타 이벤트에 응답하는 방식 관찰.
+ MQTT 테스트 클라이언트를 사용하여 섀도우 주제를 구독하고 샘플 프로그램 실행 시 업데이트를 관찰합니다.

**이 자습서를 실행하기 전에 수행해야 할 사항:**  
를 설정하고 AWS 계정, Raspberry Pi 디바이스를 구성하고, 사물과 정책을 생성 AWS IoT 했습니다. 또한 필수 소프트웨어, Device SDK, 인증서 파일을 설치하고 터미널에서 샘플 프로그램을 실행했어야 합니다. 자세한 내용은 이전 자습서 [튜토리얼: 섀도우 애플리케이션 실행을 위해 Raspberry Pi 준비](create-resources-shadow.md) 및 [1단계: shadow.py 샘플 앱 실행](lightbulb-shadow-application.md#run-sample-application-shadows)을(를) 참조하세요. 이들 자습서를 아직 완료하지 않았다면 완료해야 합니다.

**Topics**
+ [1단계: `shadow.py` 샘플 앱을 사용하여 원하는 값 및 보고된 값 업데이트](#update-desired-shadow-sample)
+ [2단계: MQTT 테스트 클라이언트에서 `shadow.py` 샘플 앱의 메시지 보기](#shadow-sample-view-msg)
+ [3단계: 디바이스 섀도우 상호 작용 오류 문제 해결](#shadow-observe-messages-troubleshoot)
+ [4단계: 결과 및 다음 단계 검토](#sample-shadow-review)

이 자습서는 완료하는 데 약 45분이 소요됩니다.

## 1단계: `shadow.py` 샘플 앱을 사용하여 원하는 값 및 보고된 값 업데이트
<a name="update-desired-shadow-sample"></a>

이전 자습서 에서는 단원에 설명된 대로 원하는 값을 입력할 때 AWS IoT 콘솔의 섀도우 문서에 게시된 메시지를 관찰하는 방법을 배[1단계: shadow.py 샘플 앱 실행](lightbulb-shadow-application.md#run-sample-application-shadows)웠습니다[자습서: 디바이스 SDK 설치 및 디바이스 섀도우용 샘플 애플리케이션 실행](lightbulb-shadow-application.md).

이전 예에서 원하는 색상을 `yellow`로 설정했습니다. 각 값을 입력하면 터미널에서 다른 `desired` 값을 입력하라는 메시지가 표시됩니다. 같은 값(`yellow`)을 다시 입력하면 앱이 이를 인식하고 새 `desired` 값을 입력하라는 메시지를 표시합니다.

```
Enter desired value:
yellow
Local value is already 'yellow'.
Enter desired value:
```

이제 색상을 입력한다고 가정합니다`green`.는 요청에 AWS IoT 응답하고 `reported` 값을 로 업데이트합니다`green`. 이런 방식으로 `desired` 상태가 `reported` 상태와 다를 때 업데이트가 발생하여 델타가 발생하게 됩니다.

**`shadow.py` 샘플 앱이 디바이스 섀도우 상호 작용을 시뮬레이션하는 방식:**

1. 터미널에 `desired` 값(예: `yellow`)을 입력하여 원하는 상태를 게시합니다.

1. `desired` 상태가 `reported` 상태(예: `green` 색상)와 다르기 때문에 델타가 발생하고 델타를 구독하는 앱이 이 메시지를 수신합니다.

1. 앱은 메시지에 응답하고 상태를 `desired` 값인 `yellow`로 업데이트합니다.

1. 그런 다음 앱은 디바이스 상태 `yellow`의 새로 보고된 값으로 업데이트 메시지를 게시합니다.

다음은 업데이트 요청이 게시되는 방식을 보여주는, 터미널에 표시되는 메시지입니다.

```
Enter desired value:
green
Changed local shadow value to 'green'.
Updating reported shadow value to 'green'...
Update request published.
Finished updating reported shadow value to 'green'.
```

 AWS IoT 콘솔에서 섀도우 문서는 `reported` 및 `desired` 필드 모두에 `green` 대해 업데이트된 값을 로 반영하고 버전 번호는 1씩 증가합니다. 예를 들어 이전 버전 번호가 10으로 표시된 경우 현재 버전 번호는 11로 표시됩니다.

**참고**  
섀도우를 삭제해도 버전 번호가 0으로 재설정되지는 않습니다. 업데이트 요청을 게시하거나 동일한 이름의 다른 섀도우를 만들 때 섀도우 버전이 1씩 증가하는 것을 볼 수 있습니다.

**델타 이벤트를 관찰하기 위해 섀도우 문서 편집**  
`shadow.py` 샘플 앱도 `delta` 이벤트를 구독하고 `desired` 값이 변경되면 응답합니다. 예를 들어 `desired` 값을 `red` 색상으로 변경할 수 있습니다. 이렇게 하려면 AWS IoT 콘솔에서 **편집**을 클릭하여 섀도우 문서를 편집한 다음 `desired` 값을 로 유지하면서 JSON`red`에서 `reported` 값을 로 설정합니다`green`. 변경 사항을 저장하기 전에 Raspberry Pi에서 터미널을 열어 두면 변경 사항이 발생할 때 터미널에 메시지가 표시됩니다.

```
{
"desired": {
  "welcome": "aws-iot",
  "color": "red"
},
"reported": {
  "welcome": "aws-iot",
  "color": "green"
}
}
```

새 값을 저장한 후 `shadow.py` 샘플 앱은 이 변경에 응답하고 델타를 나타내는 메시지를 터미널에 표시합니다. 그러면 `desired` 값을 입력하라는 프롬프트 아래에 다음 메시지가 표시됩니다.

```
Enter desired value:
Received shadow delta event.
Delta reports that desired value is 'red'. Changing local value...
Changed local shadow value to 'red'.
Updating reported shadow value to 'red'...
Finished updating reported shadow value to 'red'.
Enter desired value:
Update request published.
Finished updating reported shadow value to 'red'.
```

## 2단계: MQTT 테스트 클라이언트에서 `shadow.py` 샘플 앱의 메시지 보기
<a name="shadow-sample-view-msg"></a>

**AWS IoT 콘솔**에서 **MQTT 테스트 클라이언트**를 사용하여 AWS 계정에서 전달되는 MQTT 메시지를 모니터링할 수 있습니다. 디바이스 섀도우 서비스에서 사용하는 예약된 MQTT 주제를 구독하면 샘플 앱을 실행할 때 주제에서 수신한 메시지를 관찰할 수 있습니다.

MQTT 테스트 클라이언트를 아직 사용하지 않았다면 [MQTT 클라이언트를 사용하여 AWS IoT MQTT 메시지 보기](view-mqtt-messages.md)를 검토할 수 있습니다. 이는 MQTT 메시지가 메시지 브로커를 통과할 때 해당 메시지를 보기 위해 **AWS IoT 콘솔**에서 **MQTT 테스트 클라이언트**를 사용하는 방법을 파악하는 데 도움이 됩니다.

1. 

**MQTT 테스트 클라이언트 열기**

   MQTT 테스트 클라이언트의 구성을 잃지 않고 MQTT 주제에서 수신한 메시지를 관찰할 수 있도록 새 창에서 [AWS IoT 콘솔의 MQTT 테스트 클라이언트](https://console.aws.amazon.com//iot/home#/test)를 엽니다. MQTT 테스트 클라이언트는 콘솔의 다른 페이지로 이동하기 위해 나가면 구독 또는 메시지 로그를 유지하지 않습니다. 자습서의이 섹션에서는 AWS IoT 사물의 섀도우 문서와 MQTT 테스트 클라이언트를 별도의 창에서 열어 디바이스 섀도우와의 상호 작용을 보다 쉽게 관찰할 수 있습니다.

1. 

**MQTT 예약 섀도우 주제 구독**

   MQTT 테스트 클라이언트를 사용하여 디바이스 섀도우의 MQTT 예약 주제 이름을 입력하고 `shadow.py` 샘플 앱 실행 시 업데이트를 수신하도록 구독할 수 있습니다. 주제를 구독하려면:

   1. **AWS IoT 콘솔**의 **MQTT 테스트 클라이언트**에서 **주제 구독(Subscribe to a topic)**을 선택합니다.

   1.  **주제 필터(Topic filter)** 섹션에 **\$1aws/things/*thingname*/shadow/update/\$1**을 입력합니다. 여기서 `thingname`은 이전에 생성한 사물 리소스의 이름(예: `My_light_bulb`)입니다

   1. 추가 구성 설정에 대한 기본값을 유지한 후 **구독(Subscribe)**을 선택합니다.

   주제 구독에서 **\$1** 와일드카드를 사용하여 여러 MQTT 주제를 동시에 구독하고 디바이스와 섀도우 간에 교환되는 모든 메시지를 단일 창에서 관찰할 수 있습니다. 와일드카드 문자 및 해당 사용에 대한 자세한 내용은 [MQTT 주제](topics.md) 단원을 참조하세요.

1. 

**`shadow.py` 샘플 프로그램 실행 및 메시지 관찰**

   Raspberry Pi의 명령줄 창에서 프로그램 연결을 끊었다면 샘플 앱을 다시 실행하고 **AWS IoT 콘솔**의 **MQTT 테스트 클라이언트**에서 메시지를 확인합니다.

   1. 다음 명령을 실행하여 샘플 프로그램을 다시 시작하세요. *your-iot-thing-name* 및 *your-iot-endpoint*를 이전에 생성한 AWS IoT 사물의 이름(예: `My_light_bulb`)과 디바이스와 상호 작용할 엔드포인트로 바꿉니다.

      ```
      cd ~/aws-iot-device-sdk-python-v2/samples/service-clients
      python3 shadow.py --ca_file ~/certs/Amazon-root-CA-1.pem --cert ~/certs/device.pem.crt --key ~/certs/private.pem.key --endpoint your-iot-endpoint --thing_name your-iot-thing-name
      ```

      `shadow.py` 샘플 앱이 실행되고 현재 섀도우 상태가 검색됩니다. 섀도우를 삭제했거나 현재 상태를 지운 경우 프로그램은 현재 값을 `off`로 설정한 다음 `desired` 값을 입력하라는 메시지를 표시합니다.

      ```
      Connecting to a3qEXAMPLEffp-ats.iot.us-west-2.amazonaws.com with client ID 'test-0c8ae2ff-cc87-49d2-a82a-ae7ba1d0ca5a'...
      Connected!
      Subscribing to Delta events...
      Subscribing to Update responses...
      Subscribing to Get responses...
      Requesting current shadow state...
      Launching thread to read user input...
      Finished getting initial shadow state.
      Shadow document lacks 'color' property. Setting defaults...
      Changed local shadow value to 'off'.
      Updating reported shadow value to 'off'...
      Update request published.
      Finished updating reported shadow value to 'off'...
      Enter desired value:
      ```

      반면에 프로그램이 실행 중이었고 다시 시작하면 터미널에 최신 색상 값이 보고됩니다. MQTT 테스트 클라이언트에서 **\$1aws/things/*thingname*/shadow/get** 및 **\$1aws/things/*thingname*/shadow/get/accepted** 주제에 대한 업데이트를 볼 수 있습니다.

      보고된 최신 색상이 `green`이라고 가정합니다. 다음은 **\$1aws/things/*thingname*/shadow/get/accepted** JSON 파일의 내용을 보여줍니다.

      ```
      {
      "state": {
        "desired": {
          "welcome": "aws-iot",
          "color": "green"
        },
        "reported": {
          "welcome": "aws-iot",
          "color": "green"
        }
      },
      "metadata": {
        "desired": {
          "welcome": {
            "timestamp": 1620156892
          },
          "color": {
            "timestamp": 1620161643
          }
        },
        "reported": {
          "welcome": {
            "timestamp": 1620156892
          },
          "color": {
            "timestamp": 1620161643
          }
        }
      },
      "version": 10,
      "timestamp": 1620173908
      }
      ```

   1. 터미널에 `desired` 값(예: `yellow`)을 입력합니다. `shadow.py` 샘플 앱은 `reported` 값이 `yellow`로 변경되었음을 보여주는 다음 메시지를 터미널에 응답으로 표시합니다.

      ```
      Enter desired value:
      yellow
      Changed local shadow value to 'yellow'.
      Updating reported shadow value to 'yellow'...
      Update request published.
      Finished updating reported shadow value to 'yellow'.
      ```

      **AWS IoT 콘솔**의 **MQTT 테스트 클라이언트**에서 **구독** 아래에 다음 주제가 메시지를 수신한 것이 표시됩니다.
      + **\$1aws/things/*thingname*/shadow/update**: `desired` 및 `updated` 값이 모두 `yellow` 색상으로 변경되었음을 보여줍니다.
      + **\$1aws/things/*thingname*/shadow/update/accepted**: `desired` 및 `reported` 상태의 현재 값과 해당 메타데이터 및 버전 정보를 보여줍니다.
      + **\$1aws/things/*thingname*/shadow/update/documents**: `desired` 및 `reported` 상태의 이전 및 현재 값과 해당 메타데이터 및 버전 정보를 보여줍니다.

      **\$1aws/things/*thingname*/shadow/update/documents** 문서에도 다른 두 주제에 포함된 정보가 있으므로 이를 검토하여 상태 정보를 볼 수 있습니다. 이전 상태는 `green`으로 설정된 보고 값, 해당 메타데이터 및 버전 정보, 보고 값이 `yellow`로 업데이트된 현재 상태를 보여줍니다.

      ```
      {
      "previous": {
        "state": {
          "desired": {
            "welcome": "aws-iot",
            "color": "green"
          },
          "reported": {
            "welcome": "aws-iot",
            "color": "green"
          }
        },
        "metadata": {
          "desired": {
            "welcome": {
              "timestamp": 1617297888
            },
            "color": {
              "timestamp": 1617297898
            }
          },
          "reported": {
            "welcome": {
              "timestamp": 1617297888
            },
            "color": {
              "timestamp": 1617297898
            }
          }
        },
        "version": 10
      },
      "current": {
        "state": {
          "desired": {
            "welcome": "aws-iot",
            "color": "yellow"
          },
          "reported": {
            "welcome": "aws-iot",
            "color": "yellow"
          }
        },
        "metadata": {
          "desired": {
            "welcome": {
              "timestamp": 1617297888
            },
            "color": {
              "timestamp": 1617297904
            }
          },
          "reported": {
            "welcome": {
              "timestamp": 1617297888
            },
            "color": {
              "timestamp": 1617297904
            }
          }
        },
        "version": 11
      },
      "timestamp": 1617297904
      }
      ```

   1. 이제 다른 `desired` 값을 입력하면 이러한 주제에서 수신한 `reported` 값 및 메시지 업데이트에 대한 추가 변경 사항을 볼 수 있습니다. 버전 번호도 1씩 증가합니다. 예를 들어 값 `green`을 입력하면 이전 상태는 값 `yellow`를 보고하고 현재 상태는 값 `green`을 보고합니다.

1. 

**델타 이벤트를 관찰하기 위해 섀도우 문서 편집**

   델타 주제의 변경 내용을 관찰하려면 AWS IoT 콘솔의 섀도우 문서를 편집합니다. 예를 들어 `desired` 값을 `red` 색상으로 변경할 수 있습니다. 이렇게 하려면 AWS IoT 콘솔에서 **편집**을 선택한 다음 `desired` 값을 로 설정하면서 JSON에서 `reported` 값을 빨간색으로 설정합니다`green`. 변경 사항을 저장하기 전에 터미널에 보고된 델타 메시지가 표시되므로 터미널을 열어 두세요.

   ```
   {
   "desired": {
     "welcome": "aws-iot",
     "color": "red"
   },
   "reported": {
     "welcome": "aws-iot",
     "color": "green"
   }
   }
   ```

   `shadow.py` 샘플 앱은 이 변경에 응답하고 델타를 나타내는 메시지를 터미널에 표시합니다. MQTT 테스트 클라이언트에서 `update` 주제는 `desired` 및 `reported` 값의 변경 사항을 보여주는 메시지를 수신합니다.

   또한 **\$1aws/things/*thingname*/shadow/update/delta** 주제에서 메시지를 수신한 것을 볼 수 있습니다. 메시지를 보려면 **구독(Subscriptions)** 아래에 나열된 이 주제를 선택하세요.

   ```
   {
   "version": 13,
   "timestamp": 1617318480,
   "state": {
     "color": "red"
   },
   "metadata": {
     "color": {
       "timestamp": 1617318480
     }
   }
   }
   ```

## 3단계: 디바이스 섀도우 상호 작용 오류 문제 해결
<a name="shadow-observe-messages-troubleshoot"></a>

섀도우 샘플 앱을 실행할 때 디바이스 섀도우 서비스와의 상호 작용을 관찰하는 데 문제가 발생할 수 있습니다.

프로그램이 성공적으로 실행되어 `desired` 값을 입력하라는 메시지가 표시되는 경우 앞에서 설명한 대로 섀도우 문서와 MQTT 테스트 클라이언트를 사용하여 디바이스 섀도우 상호 작용을 관찰할 수 있어야 합니다. 그러나 상호 작용이 표시되지 않는 경우 확인할 수 있는 몇 가지 사항은 다음과 같습니다.
+ 

**AWS IoT 콘솔에서 사물 이름과 해당 섀도우 확인**  
섀도우 문서에 메시지가 표시되지 않으면 명령을 검토하고 **AWS IoT 콘솔**의 사물 이름과 일치하는지 확인하세요. 사물 리소스를 선택한 다음 **섀도우(Shadows)**를 선택하여 클래식 섀도우가 있는지 여부를 확인할 수도 있습니다. 이 자습서에서는 주로 클래식 섀도우와의 상호 작용에 중점을 둡니다.

   또한 사용한 디바이스가 인터넷에 연결되어 있는지 확인할 수도 있습니다. **AWS IoT 콘솔**에서 이전에 생성한 사물을 선택한 다음 **상호 작용(Interact)**을 선택합니다. 사물 세부 정보 페이지에 `This thing already appears to be connected.`와 같은 메시지가 표시됩니다.
+ 

**구독한 MQTT 예약 주제 확인**  
MQTT 테스트 클라이언트에 메시지가 표시되지 않으면 구독한 주제의 형식이 올바른지 확인합니다. MQTT 디바이스 섀도우 주제의 형식은 **\$1aws/things/*thingname*/shadow/**이며 섀도우에서 수행하려는 작업에 따라 `update`, `get` 또는 `delete`가 뒤따를 수 있습니다. 이 자습서에서는 **\$1aws/things/*thingname*/shadow/\$1** 주제를 사용하므로 테스트 클라이언트의 **주제 필터(Topic filter)** 섹션에서 주제를 구독할 때 올바르게 입력했는지 확인하세요.

  주제 이름을 입력할 때 *사물 이름이* 이전에 생성한 AWS IoT 사물의 이름과 동일한지 확인합니다. 또한 추가 MQTT 주제를 구독하여 업데이트가 성공적으로 수행되었는지 확인할 수 있습니다. 예를 들어 **\$1aws/things/*thingname*/shadow/update/rejected** 주제를 구독하면 업데이트 요청이 실패할 때마다 메시지를 수신하여 연결 문제를 디버깅할 수 있습니다. 예약된 주제에 대한 자세한 내용은 [디바이스 섀도우 MQTT 주제](device-shadow-mqtt.md) 및 [섀도우 주제](reserved-topics.md#reserved-topics-shadow) 단원을 참조하세요.

## 4단계: 결과 및 다음 단계 검토
<a name="sample-shadow-review"></a>

**이 자습서에서는 다음을 수행하는 방법을 알아보았습니다.**
+ `shadow.py` 샘플 앱을 사용하여 원하는 상태를 지정하고 섀도우의 현재 상태 업데이트.
+ 섀도우 문서를 편집하여 델타 이벤트를 관찰하고 `shadow.py` 샘플 앱이 델타 이벤트에 응답하는 방식 관찰.
+ MQTT 테스트 클라이언트를 사용하여 섀도우 주제를 구독하고 샘플 프로그램을 실행할 때 업데이트 관찰.

**다음 단계**  
추가 MQTT 예약 주제를 구독하여 섀도우 애플리케이션에 대한 업데이트를 관찰할 수 있습니다. 예를 들어 **\$1aws/things/*thingname*/shadow/update/accepted** 주제만 구독하는 경우 업데이트가 성공적으로 수행되었을 때 현재 상태 정보만 표시됩니다.

또한 추가 섀도우 주제를 구독하여 문제를 디버그하거나 디바이스 섀도우 상호 작용에 대해 자세히 알아보고 디바이스 섀도우 상호 작용과 관련된 문제를 디버그할 수도 있습니다. 자세한 내용은 [섀도우 주제](reserved-topics.md#reserved-topics-shadow) 및 [디바이스 섀도우 MQTT 주제](device-shadow-mqtt.md) 단원을 참조하세요.

명명된 셰도우를 사용하거나 LED용 Raspberry Pi와 연결된 추가 하드웨어를 사용하여 애플리케이션을 확장하고 터미널에서 전송한 메시지를 사용하여 상태 변경을 관찰하도록 선택할 수도 있습니다.

디바이스 섀도우 서비스에 대한 자세한 내용과 디바이스, 앱 및 서비스에서 서비스를 사용하는 방법에 대한 자세한 내용은 [AWS IoT 디바이스 섀도우 서비스](iot-device-shadows.md), [디바이스에서 섀도우 사용](device-shadow-comms-device.md) 및 [앱 및 서비스에서 섀도우 사용](device-shadow-comms-app.md) 단원을 참조하세요.