

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

# AWS IoT 자습서
<a name="iot-tutorials"></a>

자 AWS IoT 습서는 두 가지 목표를 지원하기 위해 두 가지 학습 경로로 나뉩니다. 목표에 가장 적합한 학습 경로를 선택하세요.
+ 

**AWS IoT 솔루션 아이디어를 테스트하거나 보여주기 위해 proof-of-concept 구축하려고 합니다.**  
디바이스에서 AWS IoT Device Client를 사용하는 일반적인 IoT 작업 및 애플리케이션을 시연하려면 [AWS IoT Device Client를 사용하여 데모 빌드](iot-tutorials-dc-intro.md) 학습 경로를 따르세요. AWS IoT Device Client는 자체 클라우드 리소스를 적용하여 최소한의 개발로 end-to-end 솔루션을 시연할 수 있는 디바이스 소프트웨어를 제공합니다.

   AWS IoT Device Client에 대한 자세한 내용은 [AWS IoT Device Client](https://github.com/awslabs/aws-iot-device-client#readme)를 참조하세요.
+ 

**솔루션을 배포하기 위해 프로덕션 소프트웨어를 구축하는 방법에 대해 알아보려는 경우**  
 AWS IoT 디바이스 SDK를 사용하여 특정 요구 사항을 충족하는 자체 솔루션 소프트웨어를 생성하려면 [AWS IoT 디바이스 SDKs를 사용하여 솔루션 구축](iot-tutorials-sdk-intro.md) 학습 경로를 따르세요.

  사용 가능한 AWS IoT 디바이스 SDKs[AWS IoT 디바이스 SDK](iot-sdks.md#iot-device-sdks). AWS SDKs. [AWS](https://aws.amazon.com/tools/) 

**Topics**
+ [AWS IoT Device Client를 사용하여 데모 빌드](iot-tutorials-dc-intro.md)
+ [AWS IoT 디바이스 SDKs를 사용하여 솔루션 구축](iot-tutorials-sdk-intro.md)

# AWS IoT Device Client를 사용하여 데모 빌드
<a name="iot-tutorials-dc-intro"></a>

이 학습 경로의 자습서에서는 AWS IoT Device Client를 사용하여 데모 소프트웨어를 개발하는 단계를 안내합니다. AWS IoT Device Client는 IoT 디바이스에서 실행되는 소프트웨어를 제공하여 내장된 IoT 솔루션의 측면을 테스트하고 보여줍니다 AWS IoT.

이 자습서의 목표는 디바이스 소프트웨어를 개발하기 전에가 솔루션을 AWS IoT 지원한다고 확신할 수 있도록 탐색 및 실험을 용이하게 하는 것입니다.

**이 자습서에서 배울 내용:**
+ 에서 IoT 디바이스로 사용할 Raspberry Pi를 준비하는 방법 AWS IoT
+ 디바이스에서 AWS IoT Device Client를 사용하여 AWS IoT 기능을 시연하는 방법

이 학습 경로에서는 자체 Raspberry Pi에 AWS IoT Device Client를 설치하고 클라우드에서 AWS IoT 리소스를 생성하여 IoT 솔루션 아이디어를 보여줍니다. 이 학습 경로의 튜토리얼은 Raspberry Pi를 사용하여 기능을 보여주면서 다른 디바이스에 이들을 적용하는 데 도움이 되는 목표와 절차를 설명합니다.

## AWS IoT Device Client로 데모를 빌드하기 위한 사전 조건
<a name="iot-dc-tutorial-overview"></a>

이 섹션에서는 이 학습 경로에서 튜토리얼을 시작하기 전에 갖추어야 할 사항에 대해 설명합니다.

**이 학습 경로의 튜토리얼을 완료하려면 다음이 필요합니다.**
+ 

**의 경우 AWS 계정**  
기존가 있는 AWS 계정경우를 사용할 수 있지만 이러한 자습서에서 AWS IoT 사용하는 기능을 사용하려면 추가 역할 또는 권한을 추가해야 할 수 있습니다.

  새를 생성해야 하는 경우 섹션을 AWS 계정참조하세요[설정 AWS 계정](setting-up.md).
+ 

**Raspberry Pi 또는 호환되는 IoT 디바이스**  
튜토리얼에서는 다양한 폼 팩터로 제공되는 [Raspberry Pi](https://www.raspberrypi.org/)를 사용합니다. Raspberry Pi는 일반적으로 많이 사용하며 비교적 저렴한 데모 디바이스입니다. 튜토리얼은 [Raspberry Pi 3 모델 B\$1](https://www.raspberrypi.com/products/raspberry-pi-3-model-b-plus/), [Raspberry Pi 4 모델 B](https://www.raspberrypi.com/products/raspberry-pi-4-model-b/) 및 Ubuntu Server 20.04 LTS(HVM)를 실행하는 Amazon EC2 인스턴스에서 테스트되었습니다. 를 사용하고 명령을 AWS CLI 실행하려면 최신 버전의 Raspberry Pi OS([Raspberry Pi OS(64비트)](https://www.raspberrypi.com/software/operating-systems/) 또는 OS Lite)를 사용하는 것이 좋습니다. 이전 버전의 OS는 작동하지만 테스트되지 않았습니다.
**참고**  
튜토리얼은 각 단계의 목표를 설명하여 당사에서 시도하지 않은 IoT 하드웨어에 적응하는 데 도움이 됩니다. 그러나 다른 디바이스에 적용하는 방법을 구체적으로 설명하지는 않습니다.
+ 

**IoT 디바이스의 운영 체제에 대한 이해**  
이 튜토리얼의 단계에서는 Raspberry Pi에서 지원하는 명령줄 인터페이스에서 기본 Linux 명령 및 작업을 사용하는 데 익숙하다고 가정합니다. 이러한 작업에 익숙하지 않은 경우 튜토리얼을 완료하는 데 더 많은 시간을 할애해야 할 수 있습니다. 

  이 튜토리얼을 완료하려면 다음 방법에 대한 이해가 필요합니다.
  + 부품 조립 및 연결, 필요한 전원에 디바이스 연결, 메모리 카드 설치 및 제거와 같은 기본 디바이스 작업을 안전하게 수행합니다.
  + 시스템 소프트웨어 및 파일을 디바이스에 업로드하고 다운로드합니다. 디바이스에서 microSD 카드와 같은 이동식 저장 디바이스를 사용하지 않는 경우 디바이스에 연결하고 시스템 소프트웨어와 파일을 디바이스에 업로드 및 다운로드하는 방법을 알아야 합니다.
  + 디바이스를 사용하려는 네트워크에 연결합니다.
  + SSH 터미널 또는 유사한 프로그램을 사용하여 다른 컴퓨터에서 디바이스에 연결합니다.
  + 명령줄 인터페이스를 사용하여 디바이스에 있는 파일 및 디렉터리의 생성, 복사, 이동, 이름 변경 및 권한 설정을 수행합니다.
  + 디바이스에 새 프로그램을 설치합니다.
  + FTP 또는 SCP와 같은 도구를 사용하여 디바이스와 파일을 주고받습니다.
+ 

**IoT 솔루션을 위한 개발 및 테스트 환경**  
튜토리얼에서는 필요한 소프트웨어와 하드웨어를 설명합니다. 그러나 튜토리얼에서는 명시적으로 설명되지 않은 작업을 수행할 수 있다고 가정합니다. 이러한 하드웨어 및 작업의 예는 다음과 같습니다.
  + 

**파일을 다운로드하고 저장할 로컬 호스트 컴퓨터**  
Raspberry Pi의 경우 일반적으로 microSD 메모리 카드를 읽고 쓸 수 있는 개인용 컴퓨터 또는 랩톱입니다. 로컬 호스트 컴퓨터는
    + 인터넷에 연결되어 있어야 합니다.
    + [AWS CLI](https://aws.amazon.com//cli/)를 설치하고 구성합니다.
    +  AWS 콘솔을 지원하는 웹 브라우저가 있어야 합니다.
  + 

**로컬 호스트 컴퓨터를 디바이스에 연결하여 통신하고, 명령을 입력하고, 파일을 전송하는 방법**  
Raspberry Pi에서 이는 종종 로컬 호스트 컴퓨터의 SSH 및 SCP를 사용하여 수행됩니다.
  + 

**IoT 디바이스에 연결할 모니터 및 키보드**  
이들은 도움이 될 수 있지만 튜토리얼을 완료하는 데 필수 사항은 아닙니다.
  + 

**로컬 호스트 컴퓨터와 IoT 디바이스가 인터넷에 연결하는 방법**  
인터넷에 연결된 라우터 또는 게이트웨이에 대한 유선 또는 무선 네트워크 연결일 수 있습니다. 로컬 호스트도 Raspberry Pi에 연결할 수 있어야 합니다. 이를 위해서는 동일한 LAN에 있어야 합니다. 튜토리얼에서는 특정 디바이스 또는 디바이스 구성에 대해 이를 설정하는 방법을 보여줄 수 없지만 이 연결을 테스트하는 방법은 보여줍니다.
  + 

**LAN 라우터에 액세스하여 연결된 디바이스 보기**  
이 학습 경로의 튜토리얼을 완료하려면 IoT 디바이스의 IP 주소를 찾을 수 있어야 합니다.

    LAN에서는 디바이스가 연결된 네트워크 라우터의 관리자 인터페이스에 액세스하여 이를 수행할 수 있습니다. 라우터에서 디바이스에 고정 IP 주소를 할당할 수 있으면 디바이스가 다시 시작될 때마다 재연결을 간소화할 수 있습니다.

    디바이스에 키보드와 모니터가 연결되어 있는 경우 **ifconfig**는 디바이스의 IP 주소를 표시할 수 있습니다.

    이러한 옵션이 없는 경우 재시작할 때마다 디바이스의 IP 주소를 식별하는 방법을 찾아야 합니다.

모든 자료를 준비한 후 [자습서: Device Client용 AWS IoT 디바이스 준비](iot-dc-prepare-device.md) 섹션으로 진행합니다.

**Topics**
+ [AWS IoT Device Client로 데모를 빌드하기 위한 사전 조건](#iot-dc-tutorial-overview)
+ [자습서: Device Client용 AWS IoT 디바이스 준비](iot-dc-prepare-device.md)
+ [자습서: AWS IoT Device Client 설치 및 구성](iot-dc-install-dc.md)
+ [자습서: AWS IoT Device Client와의 MQTT 메시지 통신 시연](iot-dc-testconn.md)
+ [자습서: AWS IoT Device Client를 사용하여 원격 작업(작업) 시연](iot-dc-runjobs.md)
+ [자습서: AWS IoT Device Client 자습서를 실행한 후 정리](iot-dc-cleanup.md)

# 자습서: Device Client용 AWS IoT 디바이스 준비
<a name="iot-dc-prepare-device"></a>

이 튜토리얼에서는 이 학습 경로의 후속 튜토리얼을 위한 준비를 위해 Raspberry Pi를 초기화하는 과정을 안내합니다.

이 튜토리얼의 목표는 현재 버전의 디바이스 운영 체제를 설치하고 개발 환경의 컨텍스트에서 디바이스와 통신할 수 있는지 확인하는 것입니다.

**사전 조건**  
이 자습서를 시작하기 전에 [AWS IoT Device Client로 데모를 빌드하기 위한 사전 조건](iot-tutorials-dc-intro.md#iot-dc-tutorial-overview)에 나열된 항목을 사용할 수 있고 사용할 준비가 되었는지 확인하세요.

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

**이 자습서에서 배울 내용은 다음과 같습니다.**
+ 디바이스의 운영 체제 설치 및 업데이트입니다.
+ 자습서를 실행하는 데 필요한 추가 소프트웨어를 설치하고 확인합니다.
+ 디바이스의 연결을 테스트하고 필요한 인증서를 설치합니다.

이 자습서를 완료한 후 다음 자습서에서는 Device Client를 사용하는 데모를 위해 AWS IoT 디바이스를 준비합니다.

**Topics**
+ [디바이스의 운영 체제 설치 및 업데이트](iot-dc-prepare-device-sys.md)
+ [디바이스에 필요한 소프트웨어 설치 및 확인](iot-dc-prepare-device-sw.md)
+ [디바이스 테스트 및 Amazon CA 인증서 저장](iot-dc-prepare-device-test.md)

# 디바이스의 운영 체제 설치 및 업데이트
<a name="iot-dc-prepare-device-sys"></a>

이 섹션의 절차에서는 Raspberry Pi가 시스템 드라이브에 사용하는 microSD 카드를 초기화하는 방법을 설명합니다. Raspberry Pi의 microSD 카드에는 운영 체제(OS) 소프트웨어와 애플리케이션 파일 스토리지 공간이 있습니다. Raspberry Pi를 사용하지 않는 경우 디바이스의 지침에 따라 디바이스의 운영 체제 소프트웨어를 설치하고 업데이트합니다.

이 섹션을 완료한 후에는 IoT 디바이스를 시작하고 로컬 호스트 컴퓨터의 터미널 프로그램에서 연결할 수 있어야 합니다.

**필수 장비:**
+ 로컬 개발 및 테스트 환경
+ 인터넷에 연결할 수 있는 Raspberry Pi 또는 IoT 디바이스
+ 최소 8GB 용량의 microSD 메모리 카드 또는 OS 및 필요한 소프트웨어를 위한 충분한 스토리지.
**참고**  
이러한 연습을 위해 microSD 카드를 선택할 때 필요한 만큼 크지만 가능한 한 작은 카드를 선택합니다.  
작은 SD 카드는 백업 및 업데이트가 더 빠릅니다. Raspberry Pi에서는 이 튜토리얼을 위해 8GB 이상의 microSD 카드가 필요하지 않습니다. 특정 애플리케이션에 더 많은 공간이 필요한 경우 이 튜토리얼에서 저장하는 더 작은 이미지 파일로 더 큰 카드의 파일 시스템 크기를 조정하여 선택한 카드의 지원되는 공간을 모두 사용할 수 있습니다.

**옵션 장비:**
+ Raspberry Pi에 연결된 USB 키보드
+ HDMI 모니터 및 Raspberry Pi에 모니터를 연결하는 케이블

**Topics**
+ [microSD 카드에 디바이스의 운영 체제 로드](#iot-dc-prepare-device-sys-step1)
+ [새로운 운영 체제로 IoT 디바이스 시작](#iot-dc-prepare-device-sys-step2)
+ [디바이스에 로컬 호스트 컴퓨터 연결](#iot-dc-prepare-device-sys-step3)

## microSD 카드에 디바이스의 운영 체제 로드
<a name="iot-dc-prepare-device-sys-step1"></a>

이 절차는 로컬 호스트 컴퓨터를 사용하여 디바이스의 운영 체제를 microSD 카드에 로드합니다.

**참고**  
디바이스가 운영 체제에 이동식 저장 매체를 사용하지 않는 경우 해당 디바이스에 대한 절차를 사용하여 운영 체제를 설치하고 [새로운 운영 체제로 IoT 디바이스 시작](#iot-dc-prepare-device-sys-step2) 섹션으로 진행합니다.

**Raspberry Pi에 운영 체제를 설치하려면**

1. 로컬 호스트 컴퓨터에서 사용하려는 Raspberry Pi 운영 체제 이미지를 다운로드하고 압축을 풉니다. 최신 버전은 [https://www.raspberrypi.com/software/operating-systems/](https://www.raspberrypi.com/software/operating-systems/)에서 구할 수 있습니다.

**Raspberry Pi OS 버전 선택**  
이 학습 경로의 이들 튜토리얼을 지원하는 가장 작은 버전이기 때문에 이 튜토리얼에서는 **Raspberry Pi OS Lite** 버전을 사용합니다. 이 버전의 Raspberry Pi OS에는 명령줄 인터페이스만 있고 그래픽 사용자 인터페이스는 없습니다. 그래픽 사용자 인터페이스가 있는 최신 Raspberry Pi OS 버전도 이 튜토리얼에서도 사용할 수 있습니다. 그러나 이 학습 경로에 설명된 절차는 명령줄 인터페이스만 사용하여 Raspberry Pi에서 작업을 수행합니다.

1. microSD 카드를 로컬 호스트 컴퓨터에 삽입합니다.

1. SD 카드 이미징 도구를 사용하여 압축을 푼 OS 이미지 파일을 microSD 카드에 씁니다.

1. microSD 카드에 Raspberry Pi OS 이미지를 쓴 후

   1. 명령줄 창 또는 파일 탐색기 창에서 microSD 카드의 BOOT 파티션을 엽니다.

   1. microSD 카드의 BOOT 파티션 루트 디렉터리에 파일 확장자와 내용이 없는 `ssh`라는 빈 파일을 생성합니다. 이 파일은 Raspberry Pi가 처음 시작할 때 SSH 통신을 사용 설정하도록 지시합니다.

1. microSD 카드를 꺼내고 로컬 호스트 컴퓨터에서 안전하게 제거합니다.

[새로운 운영 체제로 IoT 디바이스 시작](#iot-dc-prepare-device-sys-step2)에 사용할 microSD 카드가 준비되었습니다.

## 새로운 운영 체제로 IoT 디바이스 시작
<a name="iot-dc-prepare-device-sys-step2"></a>

이 절차는 microSD 카드를 설치하고 다운로드한 운영 체제를 사용하여 처음으로 Raspberry Pi를 시작합니다.

**새로운 운영 체제로 IoT 디바이스를 시작하려면**

1. 디바이스의 전원을 분리한 상태에서 이전 단계인 [microSD 카드에 디바이스의 운영 체제 로드](#iot-dc-prepare-device-sys-step1)의 microSD 카드를 Raspberry Pi에 삽입합니다.

1. 네트워크에 디바이스를 연결합니다.

1. 이 튜토리얼은 SSH 터미널을 사용하여 로컬 호스트 컴퓨터에서 Raspberry Pi와 상호 작용합니다.

   기기와 직접 상호 작용하려면 다음을 수행합니다.

   1. 로컬 호스트 컴퓨터의 터미널 창을 Raspberry Pi에 연결하기 전에 HDMI 모니터를 연결하여 Raspberry Pi의 콘솔 메시지를 확인합니다.

   1. Raspberry Pi와 직접 상호 작용하려면 Raspberry Pi에 USB 키보드를 연결합니다.

1. Raspberry Pi에 전원을 연결하고 초기화될 때까지 1분 정도 기다립니다.

   Raspberry Pi에 모니터가 연결되어 있으면 모니터에서 시작 프로세스를 볼 수 있습니다.

1. 

   디바이스의 IP 주소 찾기:
   + Raspberry Pi에 HDMI 모니터를 연결한 경우 모니터에 표시된 메시지에 IP 주소가 나타납니다.
   + Raspberry Pi가 연결된 라우터에 액세스할 수 있는 경우 라우터의 관리 인터페이스에서 주소를 확인할 수 있습니다.

Raspberry Pi의 IP 주소가 있으면 [디바이스에 로컬 호스트 컴퓨터 연결](#iot-dc-prepare-device-sys-step3) 준비가 된 것입니다.

## 디바이스에 로컬 호스트 컴퓨터 연결
<a name="iot-dc-prepare-device-sys-step3"></a>

이 절차에서는 로컬 호스트 컴퓨터의 터미널 프로그램을 사용하여 Raspberry Pi에 연결하고 기본 암호를 변경합니다.

**디바이스에 로컬 호스트 컴퓨터를 연결하려면**

1. 

   로컬 호스트 컴퓨터에서 SSH 터미널 프로그램을 엽니다.
   + Windows: `PuTTY`
   + Linux/macOS: `Terminal`
**참고**  
PuTTY는 Windows에 자동으로 설치되지 않습니다. 컴퓨터에 없으면 다운로드하여 설치해야 할 수 있습니다.

1. 터미널 프로그램을 Raspberry Pi의 IP 주소에 연결하고 기본 자격 증명을 사용하여 로그인합니다.

   ```
   username: pi
   password: raspberry
   ```

1. Raspberry Pi에 로그인한 후 `pi` 사용자의 암호를 변경합니다.

   ```
   passwd
   ```

   프롬프트에 따라 암호를 변경합니다.

   ```
   Changing password for pi.
   Current password: raspberry
   New password: YourNewPassword
   Retype new password: YourNewPassword
   passwd: password updated successfully
   ```

터미널 창에 Raspberry Pi의 명령줄 프롬프트가 표시되고 암호가 변경되면 [디바이스에 필요한 소프트웨어 설치 및 확인](iot-dc-prepare-device-sw.md)으로 진행할 준비가 된 것입니다.

# 디바이스에 필요한 소프트웨어 설치 및 확인
<a name="iot-dc-prepare-device-sw"></a>

이 섹션의 절차는 [이전 섹션에서 계속](iot-dc-prepare-device-sys.md)되어 Raspberry Pi의 운영 체제를 최신 상태로 유지하고 다음 섹션에서 AWS IoT Device Client를 빌드하고 설치하는 데 사용할 소프트웨어를 Raspberry Pi에 설치합니다.

이 섹션을 완료하면 Raspberry Pi에 최신 운영 체제와 이 학습 경로의 튜토리얼에 필요한 소프트웨어가 설치되고 해당 위치에 맞게 구성됩니다.

**필수 장비:**
+ [이전 섹션](iot-dc-prepare-device-sys.md)의 로컬 개발 및 테스트 환경
+ [이전 섹션](iot-dc-prepare-device-sys.md)에서 사용한 Raspberry Pi
+ [이전 섹션](iot-dc-prepare-device-sys.md)의 microSD 메모리 카드

**참고**  
Raspberry Pi 모델 3\$1 및 Raspberry Pi 모델 4는 이 학습 경로에 설명된 모든 명령을 수행할 수 있습니다. IoT 디바이스가 소프트웨어를 컴파일하거나를 실행할 수 없는 경우 로컬 호스트 컴퓨터에 필요한 컴파일러를 설치하여 소프트웨어를 빌드한 다음 IoT 디바이스로 전송해야 할 AWS Command Line Interface수 있습니다. 디바이스용 소프트웨어를 설치하고 빌드하는 방법에 대한 자세한 내용은 디바이스 소프트웨어의 설명서를 참조하세요.

**Topics**
+ [운영 체제 소프트웨어 업데이트](#iot-dc-prepare-device-sw-step1)
+ [필요한 애플리케이션 및 라이브러리 설치](#iot-dc-prepare-device-sw-step2)
+ [(선택 사항) microSD 카드 이미지 저장](#iot-dc-prepare-device-sw-step3)

## 운영 체제 소프트웨어 업데이트
<a name="iot-dc-prepare-device-sw-step1"></a>

이 절차는 운영 체제 소프트웨어를 업데이트합니다.

**Raspberry Pi에서 운영 체제 소프트웨어를 업데이트하려면**

로컬 호스트 컴퓨터의 터미널 창에서 다음 단계를 수행합니다.

1. 다음 명령을 입력하여 Raspberry Pi의 시스템 소프트웨어를 업데이트합니다.

   ```
   sudo apt-get -y update
   sudo apt-get -y upgrade
   sudo apt-get -y autoremove
   ```

1. Raspberry Pi의 로캘 및 시간대 설정을 업데이트합니다(선택 사항).

   이 명령을 입력하여 디바이스의 로캘 및 시간대 설정을 업데이트합니다.

   ```
   sudo raspi-config
   ```

   1. 디바이스의 로캘을 설정하려면

      1. **Raspberry Pi 소프트웨어 구성 도구(raspi-config)(Raspberry Pi Software Configuration Tool (raspi-config))** 화면에서 옵션 **5**를 선택합니다.

         **`5 Localisation Options Configure language and regional settings`**

         Tab 키를 사용하여 **<선택>(<Select>)**으로 이동하고 space bar를 누릅니다.

      1. 현지화 옵션 메뉴에서 **L1** 옵션을 선택합니다.

         **`L1 Locale Configure language and regional settings`**

         Tab 키를 사용하여 **<선택>(<Select>)**으로 이동하고 space bar를 누릅니다.

      1. 로캘 옵션 목록에서 화살표 키를 사용하여 스크롤하고 space bar를 사용하여 원하는 로캘을 표시하여 Raspberry Pi에 설치하려는 로캘을 선택합니다.

         미국에서는 **`en_US.UTF-8`**을 선택하는 것이 좋습니다.

      1. 디바이스의 로케일을 선택한 후 Tab 키를 사용하여 **<확인>(<OK>)**을 선택한 다음 space bar를 눌러 **로캘 구성(Configuring locales)** 확인 페이지를 표시합니다.

   1. 디바이스의 시간대를 설정하려면

      1. **raspi-config** 화면에서 옵션 **5**를 선택합니다.

         **`5 Localisation Options Configure language and regional settings`**

         Tab 키를 사용하여 **<선택>(<Select>)**으로 이동하고 space bar를 누릅니다.

      1. 현지화 옵션 메뉴에서 화살표 키를 사용하여 옵션 **L2**를 선택합니다.

         **`L2 time zone Configure time zone`**

         Tab 키를 사용하여 **<선택>(<Select>)**으로 이동하고 space bar를 누릅니다.

      1. **tzdata 구성(Configuring tzdata)** 메뉴의 목록에서 해당하는 지리적 영역을 선택합니다.

         Tab 키를 사용하여 **<확인>(<OK>)**으로 이동하고 space bar를 누릅니다.

      1. 도시 목록에서 화살표 키를 사용하여 해당 시간대의 도시를 선택합니다.

         시간대를 설정하려면 Tab 키를 사용하여 **<확인>(<OK>)**으로 이동하고 space bar를 누릅니다.

   1. 설정 업데이트가 완료되면 Tab 키를 사용하여 **<마침>(<Finish>)**으로 이동한 후 space bar를 눌러 **raspi-config** 앱을 닫습니다.

1. 이 명령을 입력하여 Raspberry Pi를 다시 시작합니다.

   ```
   sudo shutdown -r 0
   ```

1. Raspberry Pi가 다시 시작될 때까지 기다립니다.

1. Raspberry Pi를 다시 시작한 후 로컬 호스트 컴퓨터의 터미널 창을 Raspberry Pi에 다시 연결합니다.

이제 Raspberry Pi 시스템 소프트웨어가 구성되었으며 [필요한 애플리케이션 및 라이브러리 설치](#iot-dc-prepare-device-sw-step2)로 진행할 준비가 된 것입니다.

## 필요한 애플리케이션 및 라이브러리 설치
<a name="iot-dc-prepare-device-sw-step2"></a>

이 절차는 후속 튜토리얼에서 사용하는 애플리케이션 소프트웨어 및 라이브러리를 설치합니다.

Raspberry Pi를 사용 중이거나 IoT 디바이스에서 필요한 소프트웨어를 컴파일할 수 있는 경우 로컬 호스트 컴퓨터의 터미널 창에서 다음 단계를 수행합니다. 로컬 호스트 컴퓨터에서 IoT 디바이스용 소프트웨어를 컴파일해야 하는 경우 디바이스에서 이러한 단계를 수행하는 방법은 IoT 디바이스용 소프트웨어 설명서를 참조하세요.

**Raspberry Pi에 어플리케이션 소프트웨어 및 라이브러리를 설치하려면**

1. 이 명령을 입력하여 애플리케이션 소프트웨어 및 라이브러리를 설치합니다.

   ```
   sudo apt-get -y install build-essential libssl-dev cmake unzip git python3-pip
   ```

1. 이 명령을 입력하여 올바른 버전의 소프트웨어가 설치되었는지 확인합니다.

   ```
   gcc --version
   cmake --version
   openssl version
   git --version
   ```

1. 

   다음 버전의 애플리케이션 소프트웨어가 설치되어 있는지 확인합니다.
   + `gcc`: 9.3.0 이상
   + `cmake`: 3.10.x 이상
   + `OpenSSL`: 1.1.1 이상
   + `git`: 2.20.1 이상

Raspberry Pi에 필요한 어플리케이션 소프트웨어의 허용 가능한 버전이 있는 경우 [(선택 사항) microSD 카드 이미지 저장](#iot-dc-prepare-device-sw-step3)으로 진행할 준비가 된 것입니다.

## (선택 사항) microSD 카드 이미지 저장
<a name="iot-dc-prepare-device-sw-step3"></a>

이 학습 경로의 튜토리얼 전체에 Raspberry Pi의 microSD 카드 이미지 사본을 로컬 호스트 컴퓨터의 파일에 저장하는 절차가 있습니다. 권장되지만 필수 태스크는 아닙니다. 제안된 위치에 microSD 카드 이미지를 저장하면 이 학습 경로에서 저장 시점 이전의 절차를 건너뛸 수 있으므로 다시 시도해야 할 경우 시간을 절약할 수 있습니다. microSD 카드 이미지를 주기적으로 저장하지 않으면 microSD 카드가 손상되었거나 실수로 앱 또는 해당 설정을 잘못 구성한 경우 처음부터 학습 경로의 튜토리얼을 다시 시작해야 할 수 있습니다.

이 시점에서 Raspberry Pi의 microSD 카드에는 업데이트된 OS와 기본 어플리케이션 소프트웨어가 로드되어 있습니다. 지금 microSD 카드의 내용을 파일에 저장하면 이전 단계를 완료하는 데 걸리는 시간을 절약할 수 있습니다. 디바이스의 microSD 카드 이미지의 현재 이미지가 있으면 소프트웨어를 처음부터 설치하고 업데이트할 필요 없이 이 시점부터 시작하여 튜토리얼 또는 절차를 계속하거나 다시 시도할 수 있습니다.

**파일에 microSD 카드 이미지를 저장하려면**

1. 이 명령을 입력하여 Raspberry Pi를 종료합니다.

   ```
   sudo shutdown -h 0
   ```

1. Raspberry Pi가 완전히 종료되면 전원을 분리합니다.

1. Raspberry Pi에서 microSD 카드를 제거합니다.

1. 로컬 호스트 컴퓨터에서 

   1. microSD 카드를 삽입합니다.

   1. SD 카드 이미징 도구를 사용하여 microSD 카드의 이미지를 파일에 저장합니다.

   1. microSD 카드의 이미지를 저장한 후 로컬 호스트 컴퓨터에서 카드를 꺼냅니다.

1. Raspberry Pi의 전원을 분리한 상태에서 microSD 카드를 Raspberry Pi에 삽입합니다.

1. Raspberry Pi에 전원을 공급합니다.

1. 1분 정도 기다린 후 로컬 호스트 컴퓨터에서 Raspberry Pi에 연결된 로컬 호스트 컴퓨터의 터미널 창을 다시 연결한 다음 Raspberry Pi에 로그인합니다.

# 디바이스 테스트 및 Amazon CA 인증서 저장
<a name="iot-dc-prepare-device-test"></a>

이 섹션의 절차는 [이전 섹션에서](iot-dc-prepare-device-sw.md) 계속되어 AWS Command Line Interface 및 연결을 인증하는 데 사용되는 인증 기관 인증서를 설치합니다 AWS IoT Core.

이 섹션을 완료하면 Raspberry Pi에 AWS IoT Device Client를 설치하는 데 필요한 시스템 소프트웨어가 있고 인터넷에 연결되어 있음을 알 수 있습니다.

**필수 장비:**
+ [이전 섹션](iot-dc-prepare-device-sw.md)의 로컬 개발 및 테스트 환경
+ [이전 섹션](iot-dc-prepare-device-sw.md)에서 사용한 Raspberry Pi
+ [이전 섹션](iot-dc-prepare-device-sw.md)의 microSD 메모리 카드

**Topics**
+ [설치 AWS Command Line Interface](#iot-dc-prepare-device-test-step1)
+ [자격 AWS 계정 증명 구성](#iot-dc-prepare-device-test-step2)
+ [Amazon 루트 CA 인증서 다운로드](#iot-dc-prepare-device-test-step3)
+ [(선택 사항) microSD 카드 이미지 저장](#iot-dc-prepare-device-test-step4)

## 설치 AWS Command Line Interface
<a name="iot-dc-prepare-device-test-step1"></a>

이 절차에서는 Raspberry Pi AWS CLI 에를 설치합니다.

Raspberry Pi를 사용 중이거나 IoT 장치에서 소프트웨어를 컴파일할 수 있는 경우 로컬 호스트 컴퓨터의 터미널 창에서 다음 단계를 수행합니다. 로컬 호스트 컴퓨터에서 IoT 디바이스용 소프트웨어를 컴파일해야 하는 경우 IoT 디바이스에 대한 소프트웨어 설명서에서 필요한 라이브러리에 대한 정보를 검토합니다.

**Raspberry Pi AWS CLI 에를 설치하려면**

1. 다음 명령을 실행하여 AWS CLI를 다운로드하고 설치합니다.

   ```
   export PATH=$PATH:~/.local/bin # configures the path to include the directory with the AWS CLI
   git clone https://github.com/aws/aws-cli.git # download the AWS CLI code from GitHub
   cd aws-cli && git checkout v2 # go to the directory with the repo and checkout version 2
   pip3 install -r requirements.txt # install the prerequisite software
   ```

1. 이 명령을 실행하여를 설치합니다 AWS CLI. 이 명령을 완료하는 데 최대 15분이 소요될 수 있습니다.

   ```
   pip3 install . # install the AWS CLI 
   ```

1. 이 명령을 실행하여 올바른 버전의가 설치 AWS CLI 되었는지 확인합니다.

   ```
   aws --version
   ```

   의 버전은 2.2 이상이어야 AWS CLI 합니다.

에 현재 버전이 AWS CLI 표시되면 로 계속 진행할 준비가 된 것입니다[자격 AWS 계정 증명 구성](#iot-dc-prepare-device-test-step2).

## 자격 AWS 계정 증명 구성
<a name="iot-dc-prepare-device-test-step2"></a>

이 절차에서는 자격 AWS 계정 증명을 얻고 Raspberry Pi에서 사용할 자격 증명을 추가합니다.

**디바이스에 AWS 계정 자격 증명을 추가하려면**

1. 에서 **액세스 키 ID** 및 **보안 액세스 키를** 가져 AWS 계정 와 디바이스 AWS CLI 에서를 인증합니다.

    AWS IAM을 처음 사용하는 경우 [ https://aws.amazon.com/premiumsupport/knowledge-center/create-access-key/ ](https://aws.amazon.com/premiumsupport/knowledge-center/create-access-key/) 콘솔에서 실행하여 디바이스에서 사용할 IAM 자격 증명을 AWS 생성하는 AWS 프로세스를 설명합니다.

1. Raspberry Pi에 연결된 로컬 호스트 컴퓨터의 터미널 창에서 디바이스의 **액세스 키 ID(Access Key ID)** 및 **비밀 액세스 키(Secret Access Key)** 자격 증명을 사용하여 다음을 수행합니다.

   1. 다음 명령을 사용하여 AWS 구성 앱을 실행합니다.

      ```
      aws configure
      ```

   1. 메시지가 표시되면 자격 증명 및 구성 정보를 입력합니다.

      ```
      AWS Access Key ID: your Access Key ID
      AWS Secret Access Key: your Secret Access Key
      Default region name: your AWS 리전 code
      Default output format: json
      ```

1. 이 명령을 실행하여 AWS 계정 및 AWS IoT Core 엔드포인트에 대한 디바이스의 액세스를 테스트합니다.

   ```
   aws iot describe-endpoint --endpoint-type iot:Data-ATS
   ```

   이 예제와 같이 AWS 계정특정 AWS IoT 데이터 엔드포인트를 반환해야 합니다.

   ```
   {
       "endpointAddress": "a3EXAMPLEffp-ats.iot.us-west-2.amazonaws.com"
   }
   ```

 AWS 계정특정 AWS IoT 데이터 엔드포인트가 표시되면 Raspberry Pi에를 계속할 수 있는 연결 및 권한이 있습니다[Amazon 루트 CA 인증서 다운로드](#iot-dc-prepare-device-test-step3).

**중요**  
이제 자격 AWS 계정 증명이 Raspberry Pi의 microSD 카드에 저장됩니다. 이렇게 하면 향후 사용자 및이 자습서에서 생성할 소프트웨어와의 상호 작용이 AWS 쉬워지지만 기본적으로이 단계 이후에 만든 microSD 카드 이미지에도 저장되고 복제됩니다.  
자격 AWS 계정 증명의 보안을 보호하려면 microSD 카드 이미지를 더 저장하기 전에를 `aws configure` 다시 실행하고 **액세스 키 ID** 및 **보안 액세스 키**에 임의의 문자를 입력하여 자격 증명을 삭제하여 자격 AWS 계정 증명이 손상되지 않도록 하는 것이 좋습니다.  
실수로 자격 증명을 저장한 경우 AWS IAM 콘솔에서 자격 AWS 계정 증명을 비활성화할 수 있습니다.

## Amazon 루트 CA 인증서 다운로드
<a name="iot-dc-prepare-device-test-step3"></a>

이 절차는 Amazon 루트 인증 기관(CA)의 인증서 사본을 다운로드하고 저장합니다. 이 인증서를 다운로드하면 다음 튜토리얼에서 사용할 수 있도록 저장되며 AWS 서비스와의 디바이스 연결도 테스트합니다.

**Amazon 루트 CA 인증서를 다운로드하고 저장하려면**

1. 이 명령을 실행하여 인증서 디렉터리를 생성합니다.

   ```
   mkdir ~/certs
   ```

1. 이 명령을 실행하여 Amazon Root CA 인증서를 다운로드합니다.

   ```
   curl -o ~/certs/AmazonRootCA1.pem https://www.amazontrust.com/repository/AmazonRootCA1.pem
   ```

1. 이 명령을 실행하여 인증서 디렉터리와 해당 파일에 대한 액세스를 설정합니다.

   ```
   chmod 745 ~
   chmod 700 ~/certs
   chmod 644 ~/certs/AmazonRootCA1.pem
   ```

1. 이 명령을 실행하여 새 디렉터리에서 CA 인증서 파일을 확인합니다.

   ```
   ls -l ~/certs
   ```

   다음과 같은 항목이 표시되어야 합니다. 날짜와 시간은 다릅니다. 그러나 파일 크기와 기타 모든 정보는 여기에 표시된 것과 동일해야 합니다.

   ```
   -rw-r--r-- 1 pi pi 1188 Oct 28 13:02 AmazonRootCA1.pem
   ```

   파일 크기가 `1188`이 아닌 경우 **curl** 명령 파라미터를 확인합니다. 잘못된 파일을 다운로드했을 수 있습니다.

## (선택 사항) microSD 카드 이미지 저장
<a name="iot-dc-prepare-device-test-step4"></a>

이 시점에서 Raspberry Pi의 microSD 카드에는 업데이트된 OS와 기본 어플리케이션 소프트웨어가 로드되어 있습니다.

**파일에 microSD 카드 이미지를 저장하려면**

1. 로컬 호스트 컴퓨터의 터미널 창에서 AWS 자격 증명을 지웁니다.

   1. 다음 명령을 사용하여 AWS 구성 앱을 실행합니다.

      ```
      aws configure
      ```

   1. 메시지가 나타나면 자격 증명을 바꿉니다. **Enter** 키를 눌러 **기본 영역 이름(Default region name)**과 **기본 출력 형식(Default output format)**을 그대로 둘 수 있습니다.

      ```
      AWS Access Key ID [****************YT2H]: XYXYXYXYX
      AWS Secret Access Key [****************9plH]: XYXYXYXYX
      Default region name [us-west-2]: 
      Default output format [json]:
      ```

1. 이 명령을 입력하여 Raspberry Pi를 종료합니다.

   ```
   sudo shutdown -h 0
   ```

1. Raspberry Pi가 완전히 종료되면 전원 커넥터를 분리합니다.

1. 디바이스에서 microSD 카드를 분리합니다.

1. 로컬 호스트 컴퓨터에서 

   1. microSD 카드를 삽입합니다.

   1. SD 카드 이미징 도구를 사용하여 microSD 카드의 이미지를 파일에 저장합니다.

   1. microSD 카드의 이미지를 저장한 후 로컬 호스트 컴퓨터에서 카드를 꺼냅니다.

1. Raspberry Pi의 전원을 분리한 상태에서 microSD 카드를 Raspberry Pi에 삽입합니다.

1. 디바이스에 전원을 공급합니다.

1. 약 1분 후 로컬 호스트 컴퓨터에서 터미널 창 세션을 다시 시작하고 디바이스에 로그인합니다.

   **자격 AWS 계정 증명을 아직 다시 입력하지 마세요.**

다시 시작하고 Raspberry Pi에 로그인하면 [자습서: AWS IoT Device Client 설치 및 구성](iot-dc-install-dc.md)으로 진행할 준비가 된 것입니다.

# 자습서: AWS IoT Device Client 설치 및 구성
<a name="iot-dc-install-dc"></a>

이 자습서에서는 AWS IoT Device Client의 설치 및 구성과이 데모 및 기타 데모에서 사용할 AWS IoT 리소스 생성을 안내합니다.

**이 자습서를 시작하려면:**
+ [이전 튜토리얼](iot-dc-prepare-device.md)의 로컬 호스트 컴퓨터와 Raspberry Pi를 준비합니다.

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

**이 주제를 마치면**
+ IoT 디바이스는 다른 AWS IoT Device Client 데모에서 바로 사용할 수 있습니다.
+ IoT 디바이스를 프로비저닝했습니다 AWS IoT Core.
+ 디바이스에 AWS IoT Device Client를 다운로드하고 설치했습니다.
+ 이후 튜토리얼에서 사용할 수 있는 디바이스의 microSD 카드 이미지를 저장했습니다.

**필수 장비:**
+ [이전 섹션](iot-dc-prepare-device-test.md)의 로컬 개발 및 테스트 환경
+ [이전 섹션](iot-dc-prepare-device-test.md)에서 사용한 Raspberry Pi
+ [이전 섹션](iot-dc-prepare-device-test.md)에서 사용한 Raspberry Pi의 microSD 메모리 카드

**Topics**
+ [AWS IoT Device Client 다운로드 및 저장](iot-dc-install-download.md)
+ [에서 Raspberry Pi 프로비저닝 AWS IoT](iot-dc-install-provision.md)
+ [연결을 테스트하도록 AWS IoT Device Client 구성](iot-dc-install-configure.md)

# AWS IoT Device Client 다운로드 및 저장
<a name="iot-dc-install-download"></a>

이 섹션의 절차에서는 AWS IoT Device Client를 다운로드하고 컴파일한 다음 Raspberry Pi에 설치합니다. 설치를 테스트한 후 나중에 튜토리얼을 다시 시도할 때 사용할 수 있도록 Raspberry Pi의 microSD 카드 이미지를 저장할 수 있습니다.

**Topics**
+ [AWS IoT Device Client 다운로드 및 빌드](#iot-dc-install-dc-download)
+ [튜토리얼에서 사용하는 디렉터리 생성](#iot-dc-install-dc-files)
+ [(선택 사항) microSD 카드 이미지 저장](#iot-dc-install-dc-save)

## AWS IoT Device Client 다운로드 및 빌드
<a name="iot-dc-install-dc-download"></a>

이 절차에서는 Raspberry Pi에 AWS IoT Device Client를 설치합니다.

Raspberry Pi에 연결된 로컬 호스트 컴퓨터의 터미널 창에서 다음 명령을 수행합니다.

**Raspberry Pi에 AWS IoT Device Client를 설치하려면**

1. 다음 명령을 입력하여 Raspberry Pi에서 AWS IoT Device Client를 다운로드하고 빌드합니다.

   ```
   cd ~
   git clone https://github.com/awslabs/aws-iot-device-client aws-iot-device-client
   mkdir ~/aws-iot-device-client/build && cd ~/aws-iot-device-client/build
   cmake ../
   ```

1. 이 명령을 실행하여 AWS IoT Device Client를 빌드합니다. 이 명령을 완료하는 데 최대 15분이 소요될 수 있습니다.

   ```
   cmake --build . --target aws-iot-device-client
   ```

    AWS IoT Device Client 컴파일로 표시되는 경고 메시지는 무시할 수 있습니다.

   이 자습서는 **gcc**2021년 10월 30일 Raspberry Pi OS(bullseye)의 , 버전(Raspbian 10.2.1-6\$1rpi1) 10.2.1 20210110, 2021년 5월 7일 Raspberry Pi OS(buster)의 **gcc**버전(Raspbian 8.3.0-6\$1rpi1) 8.3.0에 구축된 AWS IoT Device Client로 테스트되었습니다.

1.  AWS IoT Device Client 빌드가 완료되면이 명령을 실행하여 테스트합니다.

   ```
   ./aws-iot-device-client --help
   ```

 AWS IoT Device Client에 대한 명령줄 도움말이 표시되면 AWS IoT Device Client가 성공적으로 빌드되었으며 사용할 준비가 된 것입니다.

## 튜토리얼에서 사용하는 디렉터리 생성
<a name="iot-dc-install-dc-files"></a>

이 절차에서는 이 학습 경로의 튜토리얼에서 사용하는 파일을 저장하는 데 사용할 디렉터리를 Raspberry Pi에 생성합니다.

**이 학습 경로의 튜토리얼에서 사용하는 디렉터리를 생성하려면**

1. 이 명령을 실행하여 필요한 디렉터리를 생성합니다.

   ```
   mkdir ~/dc-configs
   mkdir ~/policies
   mkdir ~/messages
   mkdir ~/certs/testconn
   mkdir ~/certs/pubsub
   mkdir ~/certs/jobs
   ```

1. 이 명령을 실행하여 새 디렉터리에 대한 권한을 설정합니다.

   ```
   chmod 745 ~
   chmod 700 ~/certs/testconn
   chmod 700 ~/certs/pubsub
   chmod 700 ~/certs/jobs
   ```

이러한 디렉터리를 생성하고 해당 권한을 설정한 후 [(선택 사항) microSD 카드 이미지 저장](#iot-dc-install-dc-save)으로 진행합니다.

## (선택 사항) microSD 카드 이미지 저장
<a name="iot-dc-install-dc-save"></a>

이때 Raspberry Pi의 microSD 카드에는 업데이트된 OS, 기본 애플리케이션 소프트웨어 및 AWS IoT Device Client가 있습니다.

이 연습과 튜토리얼을 다시 시도하기 위해 돌아와서 이 절차에서 저장한 microSD 카드 이미지를 새 microSD 카드에 기록하여 이전 절차를 건너뛰고 [에서 Raspberry Pi 프로비저닝 AWS IoT](iot-dc-install-provision.md)부터 튜토리얼을 계속할 수 있습니다.

**파일에 microSD 카드 이미지를 저장하려면**

Raspberry Pi에 연결된 로컬 호스트 컴퓨터의 터미널 창에서

1. 자격 AWS 계정 증명이 저장되지 않았는지 확인합니다.

   1. 다음 명령을 사용하여 AWS 구성 앱을 실행합니다.

      ```
      aws configure
      ```

   1. 자격 증명이 저장된 경우(프롬프트에 표시되는 경우) 여기에 표시된 대로 메시지가 나타나면 **XYXYXYXYX** 문자열을 입력합니다. **기본 리전 이름(Default region name)**과 **기본 출력 형식(Default output format)**을 비워 둡니다.

      ```
      AWS Access Key ID [****************YXYX]: XYXYXYXYX
      AWS Secret Access Key [****************YXYX]: XYXYXYXYX
      Default region name: 
      Default output format:
      ```

1. 이 명령을 입력하여 Raspberry Pi를 종료합니다.

   ```
   sudo shutdown -h 0
   ```

1. Raspberry Pi가 완전히 종료되면 전원 커넥터를 분리합니다.

1. 디바이스에서 microSD 카드를 분리합니다.

1. 로컬 호스트 컴퓨터에서 

   1. microSD 카드를 삽입합니다.

   1. SD 카드 이미징 도구를 사용하여 microSD 카드의 이미지를 파일에 저장합니다.

   1. microSD 카드의 이미지를 저장한 후 로컬 호스트 컴퓨터에서 카드를 꺼냅니다.

[에서 Raspberry Pi 프로비저닝 AWS IoT](iot-dc-install-provision.md)에서 이 microSD 카드를 계속 사용할 수 있습니다.

# 에서 Raspberry Pi 프로비저닝 AWS IoT
<a name="iot-dc-install-provision"></a>

이 섹션의 절차는 및 AWS IoT Device Client가 AWS CLI 설치된 저장된 microSD 이미지로 시작하고 Raspberry Pi를 프로비저닝하는 AWS IoT 리소스 및 디바이스 인증서를 생성합니다 AWS IoT.

## Raspberry Pi에 microSD 카드를 설치합니다.
<a name="iot-dc-install-dc-restore"></a>

이 절차에서는 필요한 소프트웨어가 로드되고 Raspberry Pi에 구성된 microSD 카드를 설치하고이 학습 경로의 자습서를 계속할 수 AWS 계정 있도록를 구성합니다.

이 학습 경로의 연습 및 튜토리얼에 필요한 소프트웨어가 있는 [(선택 사항) microSD 카드 이미지 저장](iot-dc-install-download.md#iot-dc-install-dc-save)의 microSD 카드를 사용합니다.

**Raspberry Pi에 microSD 카드를 설치하려면**

1. Raspberry Pi의 전원을 분리한 상태에서 microSD 카드를 Raspberry Pi에 삽입합니다.

1. Raspberry Pi에 전원을 공급합니다.

1. 약 1분 후 로컬 호스트 컴퓨터에서 터미널 창 세션을 다시 시작하고 Raspberry Pi에 로그인합니다.

1. 로컬 호스트 컴퓨터의 터미널 창에서 Raspberry Pi의 **액세스 키 ID(Access Key ID)** 및 **비밀 액세스 키(Secret Access Key)** 자격 증명을 사용하여

   1. 다음 명령을 사용하여 AWS 구성 앱을 실행합니다.

      ```
      aws configure
      ```

   1. 메시지가 표시되면 자격 AWS 계정 증명 및 구성 정보를 입력합니다.

      ```
      AWS Access Key ID [****************YXYX]: your Access Key ID
      AWS Secret Access Key [****************YXYX]: your Secret Access Key
      Default region name [us-west-2]: your AWS 리전 code
      Default output format [json]: json
      ```

자격 AWS 계정 증명을 복원한 후에는 로 계속 진행할 준비가 된 것입니다[에서 디바이스 프로비저닝 AWS IoT Core](#iot-dc-install-dc-provision).

## 에서 디바이스 프로비저닝 AWS IoT Core
<a name="iot-dc-install-dc-provision"></a>

이 섹션의 절차에서는 Raspberry Pi를 프로비저닝하는 AWS IoT 리소스를 생성합니다 AWS IoT. 이러한 리소스를 생성할 때 다양한 정보를 기록하라는 메시지가 나타납니다. 이 정보는 다음 절차에서 AWS IoT Device Client 구성에 사용됩니다.

Raspberry Pi가 함께 작동하려면 프로비저닝해야 AWS IoT합니다. 프로비저닝은 Raspberry Pi를 IoT 디바이스로 지원하는 데 필요한 AWS IoT 리소스를 생성하고 구성하는 프로세스입니다.

Raspberry Pi의 전원을 켜고 다시 시작한 상태에서 로컬 호스트 컴퓨터의 터미널 창을 Raspberry Pi에 연결하고 이 절차를 완료합니다.

**Topics**
+ [디바이스 인증서 파일 생성 및 다운로드](#iot-dc-install-dc-provision-certs)
+ [AWS IoT 리소스 생성](#iot-dc-install-dc-provision-resources)

### 디바이스 인증서 파일 생성 및 다운로드
<a name="iot-dc-install-dc-provision-certs"></a>

이 절차는 이 데모에 대한 디바이스 인증서 파일을 생성합니다.

**Raspberry Pi에 대한 디바이스 인증서 파일을 생성하고 다운로드하려면**

1. 로컬 호스트 컴퓨터의 터미널 창에서 이 명령을 입력하여 디바이스에 대한 디바이스 인증서 파일을 생성합니다.

   ```
   mkdir ~/certs/testconn
   aws iot create-keys-and-certificate \
   --set-as-active \
   --certificate-pem-outfile "~/certs/testconn/device.pem.crt" \
   --public-key-outfile "~/certs/testconn/public.pem.key" \
   --private-key-outfile "~/certs/testconn/private.pem.key"
   ```

   이 명령은 다음과 같은 응답을 반환합니다. 나중에 사용하기 위해 `certificateArn` 값을 적어 둡니다.

   ```
   {
       "certificateArn": "arn:aws:iot:us-west-2:57EXAMPLE833:cert/76e7e4edb3e52f52334be2f387a06145b2aa4c7fcd810f3aea2d92abc227d269",
       "certificateId": "76e7e4edb3e52f5233EXAMPLE7a06145b2aa4c7fcd810f3aea2d92abc227d269",
       "certificatePem": "-----BEGIN CERTIFICATE-----\nMIIDWTCCAkGgAwIBAgI_SHORTENED_FOR_EXAMPLE_Lgn4jfgtS\n-----END CERTIFICATE-----\n",
       "keyPair": {
           "PublicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BA_SHORTENED_FOR_EXAMPLE_ImwIDAQAB\n-----END PUBLIC KEY-----\n",
           "PrivateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQE_SHORTENED_FOR_EXAMPLE_T9RoDiukY\n-----END RSA PRIVATE KEY-----\n"
       }
   }
   ```

1. 이 명령을 입력하여 인증서 디렉터리와 해당 파일에 대한 권한을 설정합니다.

   ```
   chmod 745 ~
   chmod 700 ~/certs/testconn
   chmod 644 ~/certs/testconn/*
   chmod 600 ~/certs/testconn/private.pem.key
   ```

1. 이 명령을 실행하여 인증서 디렉터리 및 파일에 대한 권한을 검토합니다.

   ```
   ls -l ~/certs/testconn
   ```

   명령의 출력은 파일 날짜와 시간이 다르다는 점을 제외하고 여기에 표시되는 것과 같아야 합니다.

   ```
   -rw-r--r-- 1 pi pi 1220 Oct 28 13:02 device.pem.crt
   -rw------- 1 pi pi 1675 Oct 28 13:02 private.pem.key
   -rw-r--r-- 1 pi pi  451 Oct 28 13:02 public.pem.key
   ```

이 시점에서 Raspberry Pi에 디바이스 인증서 파일이 설치되어 있고 [AWS IoT 리소스 생성](#iot-dc-install-dc-provision-resources)을 계속할 수 있습니다.

### AWS IoT 리소스 생성
<a name="iot-dc-install-dc-provision-resources"></a>

이 절차에서는 디바이스가 AWS IoT 기능 및 서비스에 액세스하는 데 필요한 리소스를 생성 AWS IoT 하여에 디바이스를 프로비저닝합니다.

**에서 디바이스를 프로비저닝하려면 AWS IoT**

1. 로컬 호스트 컴퓨터의 터미널 창에서 이 명령을 입력하여 AWS 계정의 디바이스 데이터 엔드포인트 주소를 가져옵니다.

   ```
   aws iot describe-endpoint --endpoint-type IoT:Data-ATS
   ```

   이전 단계의 명령에서 다음과 같은 응답이 반환됩니다. 나중에 사용하기 위해 `endpointAddress` 값을 적어 둡니다.

   ```
   {
       "endpointAddress": "a3qjEXAMPLEffp-ats.iot.us-west-2.amazonaws.com"
   }
   ```

1. Raspberry Pi에 대한 AWS IoT 사물 리소스를 생성하려면이 명령을 입력합니다.

   ```
   aws iot create-thing --thing-name "DevCliTestThing"
   ```

    AWS IoT 사물 리소스가 생성된 경우 명령은 이와 같은 응답을 반환합니다.

   ```
   {
       "thingName": "DevCliTestThing",
       "thingArn": "arn:aws:iot:us-west-2:57EXAMPLE833:thing/DevCliTestThing",
       "thingId": "8ea78707-32c3-4f8a-9232-14bEXAMPLEfd"
   }
   ```

1. 터미널 창에서

   1. `nano` 등의 텍스트 편집기를 엽니다.

   1. 이 JSON 정책 문서를 복사하여 열려 있는 텍스트 편집기에 붙여 넣습니다.  
****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Publish",
                      "iot:Subscribe",
                      "iot:Receive",
                      "iot:Connect"
                  ],
                  "Resource": [
                      "*"
                  ]
              }
          ]
      }
      ```
**참고**  
이 정책 문서는 모든 리소스에 연결, 수신, 게시 및 구독을 위한 권한을 충분히 부여합니다. 일반적으로 정책은 특정 리소스에만 특정 작업을 수행할 수 있는 권한만 부여합니다. 그러나 초기 디바이스 연결 테스트의 경우 이 테스트 중 액세스 문제 발생 가능성을 최소화하기 위해 이 지나치게 일반적이고 허용적인 정책이 사용됩니다. 후속 튜토리얼에서는 정책 설계의 더 나은 사례를 보여주기 위해 보다 좁은 범위의 정책 문서를 사용할 것입니다.

   1. 텍스트 편집기에서 파일을 **\$1/policies/dev\$1cli\$1test\$1thing\$1policy.json**으로 저장합니다.

1. 이전 단계의 정책 문서를 사용하여 AWS IoT 정책을 생성하려면이 명령을 실행합니다.

   ```
   aws iot create-policy \
   --policy-name "DevCliTestThingPolicy" \
   --policy-document "file://~/policies/dev_cli_test_thing_policy.json"
   ```

   정책이 생성되면 명령에서 다음과 같은 응답을 반환합니다.

   ```
   {
       "policyName": "DevCliTestThingPolicy",
       "policyArn": "arn:aws:iot:us-west-2:57EXAMPLE833:policy/DevCliTestThingPolicy",
       "policyDocument": "{\n    \"Version\": \"2012-10-17\",		 	 	 \n    \"Statement\": [\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"iot:Publish\",\n                \"iot:Subscribe\",\n                \"iot:Receive\",\n                \"iot:Connect\"\n            ],\n            \"Resource\": [\n                \"*\"\n            ]\n        }\n    ]\n}\n",
       "policyVersionId": "1"
   }
   ```

1. 이 명령을 실행하여 디바이스 인증서에 정책을 연결합니다. `certificateArn`을 이전에 저장한 `certificateArn` 값으로 바꿉니다.

   ```
   aws iot attach-policy \
   --policy-name "DevCliTestThingPolicy" \
   --target "certificateArn"
   ```

   성공한 경우 이 명령은 아무 것도 반환하지 않습니다.

1. 이 명령을 실행하여 디바이스 인증서를 AWS IoT 사물 리소스에 연결합니다. `certificateArn`을 이전에 저장한 `certificateArn` 값으로 바꿉니다.

   ```
   aws iot attach-thing-principal \
   --thing-name "DevCliTestThing" \
   --principal "certificateArn"
   ```

   성공한 경우 이 명령은 아무 것도 반환하지 않습니다.

에서 디바이스를 성공적으로 프로비저닝 AWS IoT했으면 로 계속 진행할 준비가 된 것입니다[연결을 테스트하도록 AWS IoT Device Client 구성](iot-dc-install-configure.md).

# 연결을 테스트하도록 AWS IoT Device Client 구성
<a name="iot-dc-install-configure"></a>

이 섹션의 절차는 Raspberry Pi에서 MQTT 메시지를 게시하도록 AWS IoT Device Client를 구성합니다.

**Topics**
+ [구성 파일 생성](#iot-dc-install-dc-configure-step1)
+ [MQTT 테스트 클라이언트 열기](#iot-dc-install-dc-configure-step2)
+ [AWS IoT 디바이스 클라이언트 실행](#iot-dc-install-dc-configure-step3)

## 구성 파일 생성
<a name="iot-dc-install-dc-configure-step1"></a>

이 절차에서는 AWS IoT Device Client를 테스트하는 구성 파일을 생성합니다.

**AWS IoT Device Client를 테스트하기 위한 구성 파일을 생성하려면**
+ Raspberry Pi에 연결된 로컬 호스트 컴퓨터의 터미널 창에서

  1. 이 명령을 입력하여 구성 파일에 대한 디렉터리를 생성하고 디렉터리에 대한 권한을 설정합니다.

     ```
     mkdir ~/dc-configs
     chmod 745 ~/dc-configs
     ```

  1. `nano` 등의 텍스트 편집기를 엽니다.

  1. 이 JSON 문서를 복사하여 열려 있는 텍스트 편집기에 붙여 넣습니다.

     ```
     {
       "endpoint": "a3qEXAMPLEaffp-ats.iot.us-west-2.amazonaws.com",
       "cert": "~/certs/testconn/device.pem.crt",
       "key": "~/certs/testconn/private.pem.key",
       "root-ca": "~/certs/AmazonRootCA1.pem",
       "thing-name": "DevCliTestThing",
       "logging": {
         "enable-sdk-logging": true,
         "level": "DEBUG",
         "type": "STDOUT",
         "file": ""
       },
       "jobs": {
         "enabled": false,
         "handler-directory": ""
       },
       "tunneling": {
         "enabled": false
       },
       "device-defender": {
         "enabled": false,
         "interval": 300
       },
       "fleet-provisioning": {
         "enabled": false,
         "template-name": "",
         "template-parameters": "",
         "csr-file": "",
         "device-key": ""
       },
       "samples": {
         "pub-sub": {
           "enabled": true,
           "publish-topic": "test/dc/pubtopic",
           "publish-file": "",
           "subscribe-topic": "test/dc/subtopic",
           "subscribe-file": ""
         }
       },
       "config-shadow": {
         "enabled": false
       },
       "sample-shadow": {
         "enabled": false,
         "shadow-name": "",
         "shadow-input-file": "",
         "shadow-output-file": ""
       }
     }
     ```

  1. *엔드포인트* 값을에서 찾 AWS 계정 은의 디바이스 데이터 엔드포인트로 바꿉니다[에서 디바이스 프로비저닝 AWS IoT Core](iot-dc-install-provision.md#iot-dc-install-dc-provision).

  1. 텍스트 편집기에서 파일을 **\$1/dc-configs/dc-testconn-config.json**으로 저장합니다.

  1. 이 명령을 실행하여 새로운 구성 파일에 대한 권한을 설정합니다.

     ```
     chmod 644 ~/dc-configs/dc-testconn-config.json
     ```

파일을 저장한 후에는 [MQTT 테스트 클라이언트 열기](#iot-dc-install-dc-configure-step2)로 진행할 준비가 된 것입니다.

## MQTT 테스트 클라이언트 열기
<a name="iot-dc-install-dc-configure-step2"></a>

이 절차는 AWS IoT 콘솔에서 **MQTT 테스트 클라이언트**가 실행될 때 AWS IoT Device Client가 게시하는 MQTT 메시지를 구독하도록 준비합니다.

**모든 MQTT 메시지를 구독하도록 **MQTT 테스트 클라이언트(MQTT test client)**를 준비하려면**

1. 로컬 호스트 컴퓨터의 [AWS IoT 콘솔](https://console.aws.amazon.com//iot/home#/test)에서 **MQTT 테스트 클라이언트(MQTT test client)**를 선택합니다.

1. **주제 구독** 탭의 **주제 필터**에 **\$1**(파운드 기호 1개)를 입력하고 **구독**을 선택하여 모든 MQTT 주제를 구독합니다.

1. **구독(Subscriptions)** 레이블 아래에 **\$1**(파운드 기호 1개)가 표시되는지 확인합니다.

[AWS IoT 디바이스 클라이언트 실행](#iot-dc-install-dc-configure-step3)으로 진행하면서 **MQTT 테스트 클라이언트(MQTT test client)**가 열려 있는 창을 그대로 둡니다.

## AWS IoT 디바이스 클라이언트 실행
<a name="iot-dc-install-dc-configure-step3"></a>

이 절차는 AWS IoT Device Client를 실행하여 MQTT **테스트 클라이언트가 수신하고 표시하는 단일 MQTT** 메시지를 게시합니다.

**AWS IoT Device Client에서 MQTT 메시지를 보내려면**

1. 이 절차를 수행하는 동안 Raspberry Pi에 연결된 터미널 창과 **MQTT 테스트 클라이언트(MQTT test client)**가 있는 창이 모두 표시되는지 확인합니다.

1. 터미널 창에서 다음 명령을 입력하여에서 생성된 구성 파일을 사용하여 AWS IoT Device Client를 실행합니다[구성 파일 생성](#iot-dc-install-dc-configure-step1).

   ```
   cd ~/aws-iot-device-client/build
   ./aws-iot-device-client --config-file ~/dc-configs/dc-testconn-config.json
   ```

   터미널 창에서 AWS IoT Device Client는 정보 메시지와 실행 시 발생하는 오류를 표시합니다.

   터미널 창에 오류가 표시되지 않으면 **MQTT 테스트 클라이언트(MQTT test client)**를 검토합니다.

1. **MQTT 테스트 클라이언트**의 구독 창에서 `test/dc/pubtopic` 메시지 주제로 *Hello World\$1* 메시지가 전송되었음을 확인할 수 있습니다.

1.  AWS IoT Device Client에 오류가 표시되지 않고 *Hello World\$1*가 **MQTT 테스트 클라이언트**의 `test/dc/pubtopic` 메시지로 전송된 것을 볼 수 있는 경우 성공적인 연결을 입증한 것입니다.

1. 터미널 창에서 **^C** (Ctrl-C)를 입력하여 AWS IoT Device Client를 중지합니다.

 AWS IoT 디바이스 클라이언트가 Raspberry Pi에서 올바르게 실행되고 있고와 통신할 수 있음을 입증한 후에는 로 계속 AWS IoT진행할 수 있습니다[자습서: AWS IoT Device Client와의 MQTT 메시지 통신 시연](iot-dc-testconn.md).

# 자습서: AWS IoT Device Client와의 MQTT 메시지 통신 시연
<a name="iot-dc-testconn"></a>

이 자습서에서는 AWS IoT Device Client가 IoT 솔루션에서 일반적으로 사용되는 MQTT 메시지를 구독하고 게시하는 방법을 보여줍니다.

**이 자습서를 시작하려면:**
+ [이전 섹션](iot-dc-install-dc.md)에서 사용한 대로 로컬 호스트 컴퓨터와 Raspberry Pi를 구성합니다.

   AWS IoT Device Client를 설치한 후 microSD 카드 이미지를 저장한 경우 해당 이미지와 함께 microSD 카드를 Raspberry Pi와 함께 사용할 수 있습니다.
+ 이전에이 데모를 실행한 적이 있는 경우 [2단계: AWS IoT Device Client로 데모를 빌드한 AWS 계정 후 정리](iot-dc-cleanup.md#iot-dc-cleanup-cloud)를 검토하여 이전 실행에서 생성한 모든 AWS IoT 리소스를 삭제하여 중복 리소스 오류를 방지합니다.

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

**이 주제를 마치면**
+ IoT 디바이스가의 MQTT 메시지를 구독 AWS IoT 하고 MQTT 메시지를 게시할 수 있는 다양한 방법을 보여드렸습니다 AWS IoT.

**필수 장비:**
+ [이전 섹션](iot-dc-install-dc.md)의 로컬 개발 및 테스트 환경
+ [이전 섹션](iot-dc-install-dc.md)에서 사용한 Raspberry Pi
+ [이전 섹션](iot-dc-install-dc.md)에서 사용한 Raspberry Pi의 microSD 메모리 카드

**Topics**
+ [MQTT 메시지 통신 시연을 위해 Raspberry Pi 준비](iot-dc-testconn-provision.md)
+ [AWS IoT Device Client를 사용하여 메시지 게시 시연](iot-dc-testconn-publish.md)
+ [AWS IoT Device Client를 사용하여 메시지 구독 시연](iot-dc-testconn-subscribe.md)

# MQTT 메시지 통신 시연을 위해 Raspberry Pi 준비
<a name="iot-dc-testconn-provision"></a>

이 절차에서는 AWS IoT 및 Raspberry Pi에 리소스를 생성하여 AWS IoT Device Client를 사용한 MQTT 메시지 통신을 보여줍니다.

**Topics**
+ [인증서 파일을 생성하여 MQTT 통신을 시연합니다.](#iot-dc-testconn-provision-certs)
+ [MQTT 통신을 시연하기 위해 디바이스 프로비저닝](#iot-dc-testconn-provision-aws)
+ [MQTT 통신을 보여주도록 AWS IoT Device Client 구성 파일 및 MQTT 테스트 클라이언트 구성](#iot-dc-testconn-provision-dc-config)

## 인증서 파일을 생성하여 MQTT 통신을 시연합니다.
<a name="iot-dc-testconn-provision-certs"></a>

이 절차는 이 데모에 대한 디바이스 인증서 파일을 생성합니다.

**Raspberry Pi에 대한 디바이스 인증서 파일을 생성하고 다운로드하려면**



1. 로컬 호스트 컴퓨터의 터미널 창에서 다음 명령을 입력하여 디바이스에 대한 디바이스 인증서 파일을 만듭니다.

   ```
   mkdir ~/certs/pubsub
   aws iot create-keys-and-certificate \
   --set-as-active \
   --certificate-pem-outfile "~/certs/pubsub/device.pem.crt" \
   --public-key-outfile "~/certs/pubsub/public.pem.key" \
   --private-key-outfile "~/certs/pubsub/private.pem.key"
   ```

   이 명령은 다음과 같은 응답을 반환합니다. 나중에 사용할 수 있도록 `certificateArn` 값을 저장합니다.

   ```
   {
   "certificateArn": "arn:aws:iot:us-west-2:57EXAMPLE833:cert/76e7e4edb3e52f52334be2f387a06145b2aa4c7fcd810f3aea2d92abc227d269",
   "certificateId": "76e7e4edb3e52f5233EXAMPLE7a06145b2aa4c7fcd810f3aea2d92abc227d269",
   "certificatePem": "-----BEGIN CERTIFICATE-----\nMIIDWTCCAkGgAwIBAgI_SHORTENED_FOR_EXAMPLE_Lgn4jfgtS\n-----END CERTIFICATE-----\n",
   "keyPair": {
       "PublicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BA_SHORTENED_FOR_EXAMPLE_ImwIDAQAB\n-----END PUBLIC KEY-----\n",
       "PrivateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQE_SHORTENED_FOR_EXAMPLE_T9RoDiukY\n-----END RSA PRIVATE KEY-----\n"
   }
   }
   ```

1. 이 명령을 입력하여 인증서 디렉터리와 해당 파일에 대한 권한을 설정합니다.

   ```
   chmod 700 ~/certs/pubsub
   chmod 644 ~/certs/pubsub/*
   chmod 600 ~/certs/pubsub/private.pem.key
   ```

1. 이 명령을 실행하여 인증서 디렉터리 및 파일에 대한 권한을 검토합니다.

   ```
   ls -l ~/certs/pubsub
   ```

   명령의 출력은 파일 날짜와 시간이 다르다는 점을 제외하고 여기에 표시되는 것과 같아야 합니다.

   ```
   -rw-r--r-- 1 pi pi 1220 Oct 28 13:02 device.pem.crt
   -rw------- 1 pi pi 1675 Oct 28 13:02 private.pem.key
   -rw-r--r-- 1 pi pi  451 Oct 28 13:02 public.pem.key
   ```

1. 이 명령을 입력하여 로그 파일의 디렉터리를 생성합니다.

   ```
   mkdir ~/.aws-iot-device-client
   mkdir ~/.aws-iot-device-client/log
   chmod 745 ~/.aws-iot-device-client/log
   echo " " > ~/.aws-iot-device-client/log/aws-iot-device-client.log
   echo " " > ~/.aws-iot-device-client/log/pubsub_rx_msgs.log
   chmod 600 ~/.aws-iot-device-client/log/*
   ```

## MQTT 통신을 시연하기 위해 디바이스 프로비저닝
<a name="iot-dc-testconn-provision-aws"></a>

이 섹션에서는에서 Raspberry Pi를 프로비저닝하는 AWS IoT 리소스를 생성합니다 AWS IoT.

**AWS IoT에서 디바이스를 프로비저닝하려면**

1. 로컬 호스트 컴퓨터의 터미널 창에서 이 명령을 입력하여 AWS 계정의 디바이스 데이터 엔드포인트 주소를 가져옵니다.

   ```
   aws iot describe-endpoint --endpoint-type IoT:Data-ATS
   ```

   엔드포인트 값은 이전 튜토리얼에서 이 명령을 실행한 이후로 변경되지 않았습니다. 여기에서 명령을 다시 실행하면 데이터 엔드포인트 값을 쉽게 찾아 이 튜토리얼에서 사용하는 구성 파일에 붙여 넣을 수 있습니다.

   이전 단계의 명령에서 다음과 같은 응답이 반환됩니다. 나중에 사용하기 위해 `endpointAddress` 값을 적어 둡니다.

   ```
   {
   "endpointAddress": "a3qjEXAMPLEffp-ats.iot.us-west-2.amazonaws.com"
   }
   ```

1. Raspberry Pi에 대한 새 AWS IoT 사물 리소스를 생성하려면이 명령을 입력합니다.

   ```
   aws iot create-thing --thing-name "PubSubTestThing"
   ```

    AWS IoT 사물 리소스는 클라우드에서 디바이스를 *가상*으로 표현하기 때문에에서 여러 용도로 AWS IoT 사용할 여러 사물 리소스를 생성할 수 있습니다. 모두 동일한 물리적 IoT 디바이스에서 사용하여 디바이스의 다양한 속성을 나타낼 수 있습니다.

   이 튜토리얼에서는 Raspberry Pi를 표현하기 위해 한 번에 하나의 사물 리소스만 사용합니다. 이렇게 하면이 자습서에서는 다양한 데모를 나타내므로 데모용 AWS IoT 리소스를 생성한 후 돌아가서 각각에 대해 특별히 생성한 리소스를 사용하여 데모를 반복할 수 있습니다.

    AWS IoT 사물 리소스가 생성된 경우 명령은 이와 같은 응답을 반환합니다.

   ```
   {
   "thingName": "PubSubTestThing",
   "thingArn": "arn:aws:iot:us-west-2:57EXAMPLE833:thing/PubSubTestThing",
   "thingId": "8ea78707-32c3-4f8a-9232-14bEXAMPLEfd"
   }
   ```

1. 터미널 창에서

   1. `nano` 등의 텍스트 편집기를 엽니다.

   1. 이 JSON 문서를 복사하여 열려 있는 텍스트 편집기에 붙여 넣습니다.  
****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Connect"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:client/PubSubTestThing"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Publish"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topic/test/dc/pubtopic"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Subscribe"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topicfilter/test/dc/subtopic"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Receive"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topic/test/dc/subtopic"
                  ]
              }
          ]
      }
      ```

   1. 편집기의 정책 문서의 각 `Resource` 섹션에서 *us-west-2:57EXAMPLE833*을 , 콜론 문자(:) 및 12자리 AWS 계정 숫자 AWS 리전로 바꿉니다.

   1. 텍스트 편집기에서 파일을 **\$1/policies/pubsub\$1test\$1thing\$1policy.json**으로 저장합니다.

1. 이전 단계의 정책 문서를 사용하여 AWS IoT 정책을 생성하려면이 명령을 실행합니다.

   ```
   aws iot create-policy \
   --policy-name "PubSubTestThingPolicy" \
   --policy-document "file://~/policies/pubsub_test_thing_policy.json"
   ```

   정책이 생성되면 명령에서 다음과 같은 응답을 반환합니다.

   ```
   {
                                       "policyName": "PubSubTestThingPolicy",
                                       "policyArn": "arn:aws:iot:us-west-2:57EXAMPLE833:policy/PubSubTestThingPolicy",
                                       "policyDocument": "{\n\"Version\": \"2012-10-17\",		 	 	 \n\"Statement\": [\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Connect\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:client/PubSubTestThing\"\n]\n},\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Publish\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/pubtopic\"\n]\n},\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Subscribe\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:topicfilter/test/dc/subtopic\"\n]\n},\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Receive\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/*\"\n]\n}\n]\n}\n",
                                       "policyVersionId": "1"
                                       }
   ```

1. 이 명령을 실행하여 디바이스 인증서에 정책을 연결합니다. `certificateArn`을 이 섹션에서 이전에 저장한 `certificateArn` 값으로 바꿉니다.

   ```
   aws iot attach-policy \
   --policy-name "PubSubTestThingPolicy" \
   --target "certificateArn"
   ```

   성공한 경우 이 명령은 아무 것도 반환하지 않습니다.

1. 이 명령을 실행하여 AWS IoT 사물 리소스에 디바이스 인증서를 연결합니다. `certificateArn`을 이 섹션에서 이전에 저장한 `certificateArn` 값으로 바꿉니다.

   ```
   aws iot attach-thing-principal \
   --thing-name "PubSubTestThing" \
   --principal "certificateArn"
   ```

   성공한 경우 이 명령은 아무 것도 반환하지 않습니다.

에서 디바이스를 성공적으로 프로비저닝하면 로 계속 진행할 준비가 된 AWS IoT것입니다[MQTT 통신을 보여주도록 AWS IoT Device Client 구성 파일 및 MQTT 테스트 클라이언트 구성](#iot-dc-testconn-provision-dc-config).

## MQTT 통신을 보여주도록 AWS IoT Device Client 구성 파일 및 MQTT 테스트 클라이언트 구성
<a name="iot-dc-testconn-provision-dc-config"></a>

이 절차에서는 AWS IoT Device Client를 테스트하는 구성 파일을 생성합니다.

**AWS IoT Device Client를 테스트하기 위한 구성 파일을 생성하려면**

1. Raspberry Pi에 연결된 로컬 호스트 컴퓨터의 터미널 창에서

   1. `nano` 등의 텍스트 편집기를 엽니다.

   1. 이 JSON 문서를 복사하여 열려 있는 텍스트 편집기에 붙여 넣습니다.

      ```
      {
        "endpoint": "a3qEXAMPLEaffp-ats.iot.us-west-2.amazonaws.com",
        "cert": "~/certs/pubsub/device.pem.crt",
        "key": "~/certs/pubsub/private.pem.key",
        "root-ca": "~/certs/AmazonRootCA1.pem",
        "thing-name": "PubSubTestThing",
        "logging": {
          "enable-sdk-logging": true,
          "level": "DEBUG",
          "type": "STDOUT",
          "file": ""
        },
        "jobs": {
          "enabled": false,
          "handler-directory": ""
        },
        "tunneling": {
          "enabled": false
        },
        "device-defender": {
          "enabled": false,
          "interval": 300
        },
        "fleet-provisioning": {
          "enabled": false,
          "template-name": "",
          "template-parameters": "",
          "csr-file": "",
          "device-key": ""
        },
        "samples": {
          "pub-sub": {
            "enabled": true,
            "publish-topic": "test/dc/pubtopic",
            "publish-file": "",
            "subscribe-topic": "test/dc/subtopic",
            "subscribe-file": "~/.aws-iot-device-client/log/pubsub_rx_msgs.log"
          }
        },
        "config-shadow": {
          "enabled": false
        },
        "sample-shadow": {
          "enabled": false,
          "shadow-name": "",
          "shadow-input-file": "",
          "shadow-output-file": ""
        }
      }
      ```

   1. *엔드포인트* 값을에서 찾 AWS 계정 은의 디바이스 데이터 엔드포인트로 바꿉니다[에서 디바이스 프로비저닝 AWS IoT Core](iot-dc-install-provision.md#iot-dc-install-dc-provision).

   1. 텍스트 편집기에서 파일을 **\$1/dc-configs/dc-pubsub-config.json**으로 저장합니다.

   1. 이 명령을 실행하여 새로운 구성 파일에 대한 권한을 설정합니다.

      ```
      chmod 644 ~/dc-configs/dc-pubsub-config.json
      ```

1. 모든 MQTT 메시지를 구독하도록 **MQTT 테스트 클라이언트(MQTT test client)**를 준비하려면

   1. 로컬 호스트 컴퓨터의 [AWS IoT 콘솔](https://console.aws.amazon.com//iot/home#/test)에서 **MQTT 테스트 클라이언트(MQTT test client)**를 선택합니다.

   1. **주제 구독(Subscribe to a topic)** 탭의 **주제 필터(Topic filter)**에 **\$1**(파운드 기호 1개)를 입력하고 **구독(Subscribe)**을 선택합니다.

   1. **구독(Subscriptions)** 레이블 아래에 **\$1**(파운드 기호 1개)가 표시되는지 확인합니다.

   이 자습서를 진행하면서 **MQTT 테스트 클라이언트(MQTT test client)**가 열려 있는 창을 그대로 둡니다.

파일을 저장하고 **MQTT 테스트 클라이언트(MQTT test client)**를 구성한 후 [AWS IoT Device Client를 사용하여 메시지 게시 시연](iot-dc-testconn-publish.md)으로 진행할 준비가 된 것입니다.

# AWS IoT Device Client를 사용하여 메시지 게시 시연
<a name="iot-dc-testconn-publish"></a>

이 섹션의 절차는 AWS IoT Device Client가 기본 및 사용자 지정 MQTT 메시지를 보내는 방법을 보여줍니다.

이러한 연습을 위해 이전 단계에서 생성한 정책의 이러한 정책 설명은 Raspberry Pi에 다음 작업을 수행할 수 있는 권한을 부여합니다.
+ 

**`iot:Connect`**  
 AWS IoT Device Client를 실행하는 Raspberry Pi`PubSubTestThing`인 라는 클라이언트에 연결할 권한을 부여합니다.

  ```
      {
        "Effect": "Allow",
        "Action": [
          "iot:Connect"
        ],
        "Resource": [
          "arn:aws:iot:us-west-2:57EXAMPLE833:client/PubSubTestThing"
        ]
      }
  ```
+ 

**`iot:Publish`**  
Raspberry Pi에 `test/dc/pubtopic`의 MQTT 주제가 있는 메시지를 게시할 수 있는 권한을 부여합니다.

  ```
      {
        "Effect": "Allow",
        "Action": [
          "iot:Publish"
        ],
        "Resource": [
          "arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/pubtopic"
        ]
      }
  ```

  `iot:Publish` 작업은 리소스 배열에 나열된 MQTT 주제에 게시할 수 있는 권한을 부여합니다. 이러한 메시지의 *내용*은 정책 설명에 의해 제어되지 않습니다.

## AWS IoT Device Client를 사용하여 기본 메시지 게시
<a name="iot-dc-testconn-publish-default"></a>

이 절차는 AWS IoT Device Client를 실행하여 MQTT **테스트 클라이언트가 수신하고 표시하는 단일 기본 MQTT** 메시지를 게시합니다.

**AWS IoT Device Client에서 기본 MQTT 메시지를 보내려면**

1. 이 절차를 수행하는 동안 Raspberry Pi에 연결된 로컬 호스트 컴퓨터의 터미널 창과 **MQTT 테스트 클라이언트(MQTT test client)**가 있는 창이 모두 표시되는지 확인합니다.

1. 터미널 창에서 다음 명령을 입력하여에서 생성된 구성 파일을 사용하여 AWS IoT Device Client를 실행합니다[구성 파일 생성](iot-dc-install-configure.md#iot-dc-install-dc-configure-step1).

   ```
   cd ~/aws-iot-device-client/build
   ./aws-iot-device-client --config-file ~/dc-configs/dc-pubsub-config.json
   ```

   터미널 창에서 AWS IoT Device Client는 정보 메시지와 실행 시 발생하는 오류를 표시합니다.

   터미널 창에 오류가 표시되지 않으면 **MQTT 테스트 클라이언트(MQTT test client)**를 검토합니다.

1. **MQTT 테스트 클라이언트**의 **구독** 창에서 `test/dc/pubtopic` 메시지 주제로 *Hello World\$1* 메시지가 전송되었음을 확인할 수 있습니다.

1.  AWS IoT Device Client에 오류가 표시되지 않고 *Hello World\$1*가 **MQTT 테스트 클라이언트**의 `test/dc/pubtopic` 메시지로 전송된 것을 볼 수 있는 경우 성공적인 연결을 입증한 것입니다.

1. 터미널 창에서 **^C** (Ctrl-C)를 입력하여 AWS IoT Device Client를 중지합니다.

 AWS IoT Device Client가 기본 MQTT 메시지를 게시했음을 입증한 후 로 계속 진행할 수 있습니다[AWS IoT Device Client를 사용하여 사용자 지정 메시지 게시](#iot-dc-testconn-publish-custom).

## AWS IoT Device Client를 사용하여 사용자 지정 메시지 게시
<a name="iot-dc-testconn-publish-custom"></a>

이 섹션의 절차에서는 사용자 정의 MQTT 메시지를 생성한 다음 AWS IoT Device Client를 실행하여 **MQTT 테스트 클라이언트(MQTT test client)**가 수신하고 표시할 수 있도록 사용자 정의 MQTT 메시지를 한 번 게시합니다.

### AWS IoT Device Client에 대한 사용자 지정 MQTT 메시지 생성
<a name="iot-dc-testconn-publish-custom-create"></a>

Raspberry Pi에 연결된 로컬 호스트 컴퓨터의 터미널 창에서 다음 단계를 수행합니다.

**AWS IoT Device Client가 게시할 사용자 지정 메시지를 생성하려면**

1. 터미널 창에서 `nano` 등의 텍스트 편집기를 엽니다.

1. 텍스트 편집기에 다음 JSON 문서를 복사하여 붙여 넣습니다. 이는 AWS IoT Device Client가 게시하는 MQTT 메시지 페이로드입니다.

   ```
   {
     "temperature": 28,
     "humidity": 80,
     "barometer": 1013,
     "wind": {
       "velocity": 22,
       "bearing": 255
     }
   }
   ```

1. 텍스트 편집기의 내용을 **\$1/messages/sample-ws-message.json**으로 저장합니다.

1. 다음 명령을 입력하여 방금 생성한 메시지 파일의 권한을 설정합니다.

   ```
   chmod 600 ~/messages/*
   ```

**AWS IoT Device Client가 사용자 지정 메시지를 전송하는 데 사용할 구성 파일을 생성하려면**

1. 터미널 창의와 같은 텍스트 편집기에서 기존 AWS IoT Device Client 구성 파일을 `nano`엽니다**\$1/dc-configs/dc-pubsub-config.json**.

1. 다음과 같이 `samples` 객체를 편집합니다. 이 파일의 다른 부분은 변경할 필요가 없습니다.

   ```
     "samples": {
       "pub-sub": {
         "enabled": true,
         "publish-topic": "test/dc/pubtopic",
         "publish-file": "~/messages/sample-ws-message.json",
         "subscribe-topic": "test/dc/subtopic",
         "subscribe-file": "~/.aws-iot-device-client/log/pubsub_rx_msgs.log"
   ```

1. 텍스트 편집기의 내용을 **\$1/dc-configs/dc-pubsub-custom-config.json**으로 저장합니다.

1. 이 명령을 실행하여 새로운 구성 파일에 대한 권한을 설정합니다.

   ```
   chmod 644 ~/dc-configs/dc-pubsub-custom-config.json
   ```

### AWS IoT Device Client를 사용하여 사용자 지정 MQTT 메시지 게시
<a name="iot-dc-testconn-publish-custom-publish"></a>

이 변경 사항은 MQTT 메시지 페이로드의 *내용*에만 영향을 주므로 현재 정책이 계속 작동합니다. 그러나 *MQTT 주제*(`~/dc-configs/dc-pubsub-custom-config.json`의 `publish-topic` 값으로 정의됨)가 변경된 경우 Raspberry Pi가 새 MQTT 주제에 게시할 수 있도록 `iot::Publish` 정책 설명도 수정해야 합니다.

**AWS IoT Device Client에서 MQTT 메시지를 보내려면**

1. 이 절차를 수행하는 동안 터미널 창과 **MQTT 테스트 클라이언트(MQTT test client)**가 있는 창이 모두 표시되는지 확인합니다. 또한 **MQTT 테스트 클라이언트(MQTT test client)**가 여전히 **\$1** 주제 필터를 구독하고 있는지 확인합니다. 그렇지 않은 경우 **\$1** 주제 필터를 다시 구독합니다.

1. 터미널 창에서 이 명령을 입력하여 [구성 파일 생성](iot-dc-install-configure.md#iot-dc-install-dc-configure-step1)에서 생성한 config 파일을 사용하여 AWS IoT Device Client를 실행합니다.

   ```
   cd ~/aws-iot-device-client/build
   ./aws-iot-device-client --config-file ~/dc-configs/dc-pubsub-custom-config.json
   ```

   터미널 창에서 AWS IoT Device Client는 정보 메시지와 실행 시 발생하는 오류를 표시합니다.

   터미널 창에 오류가 표시되지 않으면 MQTT 테스트 클라이언트(MQTT test client)를 검토합니다.

1. **MQTT 테스트 클라이언트**의 **구독** 창에서 `test/dc/pubtopic` 메시지 주제로 사용자 정의 메시지 페이로드가 전송되었음을 확인할 수 있습니다.

1.  AWS IoT Device Client에 오류가 표시되지 않고 **MQTT 테스트 클라이언트**의 메시지에 게시한 사용자 지정 `test/dc/pubtopic` 메시지 페이로드가 표시되면 사용자 지정 메시지를 성공적으로 게시한 것입니다.

1. 터미널 창에서 **^C** (Ctrl-C)를 입력하여 AWS IoT Device Client를 중지합니다.

 AWS IoT Device Client가 사용자 지정 메시지 페이로드를 게시했음을 입증한 후 로 계속 진행할 수 있습니다[AWS IoT Device Client를 사용하여 메시지 구독 시연](iot-dc-testconn-subscribe.md).

# AWS IoT Device Client를 사용하여 메시지 구독 시연
<a name="iot-dc-testconn-subscribe"></a>

이 섹션에서는 두 가지 유형의 메시지 구독을 보여줍니다.
+ 단일 주제 구독
+ 와일드카드 주제 구독

이러한 연습을 위해 생성한 정책의 이러한 정책 설명은 Raspberry Pi에 다음 작업을 수행할 수 있는 권한을 부여합니다.
+ 

**`iot:Receive`**  
 AWS IoT Device Client에 `Resource` 객체에 이름이 지정된 주제와 일치하는 MQTT 주제를 수신할 수 있는 권한을 부여합니다.

  ```
      {
        "Effect": "Allow",
        "Action": [
          "iot:Receive"
        ],
        "Resource": [
          "arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/subtopic"
        ]
      }
  ```
+ 

**`iot:Subscribe`**  
 AWS IoT Device Client에 `Resource` 객체에 이름이 지정된 것과 일치하는 MQTT 주제 필터를 구독할 수 있는 권한을 부여합니다.

  ```
      {
        "Effect": "Allow",
        "Action": [
          "iot:Subscribe"
        ],
        "Resource": [
          "arn:aws:iot:us-west-2:57EXAMPLE833:topicfilter/test/dc/subtopic"
        ]
      }
  ```

## 단일 MQTT 메시지 주제 구독
<a name="iot-dc-testconn-subscribe-simple-topic"></a>

이 절차에서는 AWS IoT Device Client가 MQTT 메시지를 구독하고 로깅하는 방법을 보여줍니다.

Raspberry Pi에 연결된 로컬 호스트 컴퓨터의 터미널 창에서 **\$1/dc-configs/dc-pubsub-custom-config.json**의 내용을 나열하거나 텍스트 편집기에서 파일을 열어 내용을 검토합니다. 다음과 같은 `samples` 객체를 찾습니다.

```
  "samples": {
    "pub-sub": {
      "enabled": true,
      "publish-topic": "test/dc/pubtopic",
      "publish-file": "~/messages/sample-ws-message.json",
      "subscribe-topic": "test/dc/subtopic",
      "subscribe-file": "~/.aws-iot-device-client/log/pubsub_rx_msgs.log"
```

`subscribe-topic` 값은 AWS IoT Device Client가 실행 시 구독할 MQTT 주제입니다. AWS IoT Device Client는이 구독에서 수신한 메시지 페이로드를 `subscribe-file` 값에 라는 파일에 씁니다.

**AWS IoT Device Client에서 MQTT 메시지 주제를 구독하려면**

1. 이 절차를 수행하는 동안 터미널 창과 MQTT 테스트 클라이언트(MQTT test client)가 있는 창이 모두 표시되는지 확인합니다. 또한 **MQTT 테스트 클라이언트(MQTT test client)**가 여전히 **\$1** 주제 필터를 구독하고 있는지 확인합니다. 그렇지 않은 경우 **\$1** 주제 필터를 다시 구독합니다.

1. 터미널 창에서 다음 명령을 입력하여에서 생성된 구성 파일을 사용하여 AWS IoT Device Client를 실행합니다[구성 파일 생성](iot-dc-install-configure.md#iot-dc-install-dc-configure-step1).

   ```
   cd ~/aws-iot-device-client/build
   ./aws-iot-device-client --config-file ~/dc-configs/dc-pubsub-custom-config.json
   ```

   터미널 창에서 AWS IoT Device Client는 정보 메시지와 실행 시 발생하는 오류를 표시합니다.

   터미널 창에 오류가 표시되지 않으면 AWS IoT 콘솔에서 계속합니다.

1.  AWS IoT 콘솔의 **MQTT 테스트 클라이언트**에서 **주제에 게시** 탭을 선택합니다.

1. **주제 이름(Topic name)**에 **test/dc/subtopic**을 입력합니다.

1. **메시지 페이로드(Message payload)**에서 메시지 내용을 검토합니다.

1. **게시(Publish)**를 선택하여 MQTT 메시지를 게시합니다.

1. 터미널 창에서 다음과 같은 AWS IoT Device Client에서 *받은 메시지 * 항목을 확인합니다.

   ```
   2021-11-10T16:02:20.890Z [DEBUG] {samples/PubSubFeature.cpp}: Message received on subscribe topic, size: 45 bytes
   ```

1. *메시지가 수신*되었음을 보여주는 메시지 수신 항목이 표시되면 **^C** (Ctrl-C)를 입력하여 AWS IoT Device Client를 중지합니다.

1. 이 명령을 입력하여 메시지 로그 파일의 끝을 보고 **MQTT 테스트 클라이언트(MQTT test client)**에서 게시한 메시지를 확인합니다.

   ```
   tail ~/.aws-iot-device-client/log/pubsub_rx_msgs.log
   ```

로그 파일에서 메시지를 보고 AWS IoT Device Client가 MQTT 테스트 클라이언트에서 게시한 메시지를 수신했음을 보여줍니다.

## 와일드카드 문자를 사용하여 여러 MQTT 메시지 주제 구독
<a name="iot-dc-testconn-subscribe-wild-topic"></a>

이 절차는 AWS IoT Device Client가 와일드카드 문자를 사용하여 MQTT 메시지를 구독하고 로깅하는 방법을 보여줍니다. 이를 위해 다음을 수행합니다.

1.  AWS IoT Device Client가 MQTT 주제를 구독하는 데 사용하는 주제 필터를 업데이트합니다.

1. 새 구독을 허용하도록 디바이스에서 사용하는 정책을 업데이트합니다.

1.  AWS IoT Device Client를 실행하고 MQTT 테스트 콘솔에서 메시지를 게시합니다.

**와일드카드 MQTT 주제 필터를 사용하여 여러 MQTT 메시지 주제를 구독하는 구성 파일을 생성하려면**

1. Raspberry Pi에 연결된 로컬 호스트 컴퓨터의 터미널 창에서 편집을 위해 **\$1/dc-configs/dc-pubsub-custom-config.json**을 열고 `samples` 객체를 찾습니다.

1. 텍스트 편집기에서 `samples` 객체를 찾고 `subscribe-topic` 값을 다음과 같이 업데이트합니다.

   ```
     "samples": {
       "pub-sub": {
         "enabled": true,
         "publish-topic": "test/dc/pubtopic",
         "publish-file": "~/messages/sample-ws-message.json",
         "subscribe-topic": "test/dc/#",
         "subscribe-file": "~/.aws-iot-device-client/log/pubsub_rx_msgs.log"
   ```

   새 `subscribe-topic` 값은 끝에 MQTT 와일드카드 문자가 있는 [MQTT 주제 필터](topics.md#topicfilters)입니다. 이는 `test/dc/`로 시작하는 모든 MQTT 주제에 대한 구독을 설명합니다. AWS IoT Device Client는이 구독에서 수신한 메시지 페이로드를의 파일에 씁니다`subscribe-file`.

1. 수정된 구성 파일을 **\$1/dc-configs/dc-pubsub-wild-config.json**으로 저장하고 편집기를 종료합니다.

**여러 MQTT 메시지 주제 구독 및 수신을 허용하도록 Raspberry Pi에서 사용하는 정책을 수정하려면**

1. Raspberry Pi에 연결된 로컬 호스트 컴퓨터의 터미널 창에서 즐겨 사용하는 텍스트 편집기에서 편집을 위해 **\$1/policies/pubsub\$1test\$1thing\$1policy.json**을 연 다음 파일에서 `iot::Subscribe` 및 `iot::Receive` 정책 설명을 찾습니다.

1. `iot::Subscribe` 정책 설명에서 Resource 개체의 문자열을 업데이트하여 `subtopic`을 `*`로 바꾸면 다음과 같이 됩니다.

   ```
       {
         "Effect": "Allow",
         "Action": [
           "iot:Subscribe"
         ],
         "Resource": [
           "arn:aws:iot:us-west-2:57EXAMPLE833:topicfilter/test/dc/*"
         ]
       }
   ```
**참고**  
[MQTT 주제 필터 와일드 카드 문자](topics.md#topicfilters)는 `+`(더하기 기호)와 `#`(파운드 기호)입니다. 끝에 `#`이 있는 구독 요청은 `#` 문자 앞에 오는 문자열(예: 이 경우 `test/dc/`)로 시작하는 모든 주제를 구독합니다.  
그러나 이 구독 권한을 부여하는 정책 설명의 리소스 값은 주제 필터 ARN에서 `#`(파운드 기호) 대신 `*`(별표)를 사용해야 합니다. 이는 정책 프로세서가 MQTT에서 사용하는 것과 다른 와일드카드 문자를 사용하기 때문입니다.  
정책의 주제 및 주제 필터에 와일드카드 문자 사용에 대한 자세한 내용은 [MQTT 및 AWS IoT Core 정책에서 와일드카드 문자 사용](pub-sub-policy.md#pub-sub-policy-cert) 섹션을 참조하세요.

1. `iot::Receive` 정책 설명에서 Resource 개체의 문자열을 업데이트하여 `subtopic`을 `*`로 바꾸면 다음과 같이 됩니다.

   ```
       {
         "Effect": "Allow",
         "Action": [
           "iot:Receive"
         ],
         "Resource": [
           "arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/*"
         ]
       }
   ```

1. 업데이트된 정책 문서를 **\$1/policies/pubsub\$1wild\$1test\$1thing\$1policy.json**으로 저장하고 편집기를 종료합니다.

1. 이 명령을 입력하여 새 리소스 정의를 사용하도록 이 튜토리얼의 정책을 업데이트합니다.

   ```
   aws iot create-policy-version \
   --set-as-default \
   --policy-name "PubSubTestThingPolicy" \
   --policy-document "file://~/policies/pubsub_wild_test_thing_policy.json"
   ```

   명령이 성공하면 다음과 같은 응답이 반환됩니다. `policyVersionId`는 이제 `2`로, 이 정책의 두 번째 버전임을 나타냅니다.

   정책을 성공적으로 업데이트했으면 다음 절차로 진행할 수 있습니다.

   ```
   {
       "policyArn": "arn:aws:iot:us-west-2:57EXAMPLE833:policy/PubSubTestThingPolicy",
       "policyDocument": "{\n  \"Version\": \"2012-10-17\",		 	 	 \n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"iot:Connect\"\n      ],\n      \"Resource\": [\n        \"arn:aws:iot:us-west-2:57EXAMPLE833:client/PubSubTestThing\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"iot:Publish\"\n      ],\n      \"Resource\": [\n        \"arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/pubtopic\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"iot:Subscribe\"\n      ],\n      \"Resource\": [\n        \"arn:aws:iot:us-west-2:57EXAMPLE833:topicfilter/test/dc/*\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"iot:Receive\"\n      ],\n      \"Resource\": [\n        \"arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/*\"\n      ]\n    }\n  ]\n}\n",
       "policyVersionId": "2",
       "isDefaultVersion": true
   }
   ```

   정책 버전이 너무 많아 새 버전을 저장할 수 없다는 오류가 발생하면 이 명령을 입력하여 정책의 현재 버전을 나열합니다. 이 명령이 반환하는 목록을 검토하여 삭제할 수 있는 정책 버전을 찾습니다.

   ```
   aws iot list-policy-versions --policy-name "PubSubTestThingPolicy"
   ```

   이 명령을 입력하여 더 이상 필요 없는 버전을 삭제합니다. 기본 정책 버전은 삭제할 수 없습니다. 기본 정책 버전은 `isDefaultVersion` 값이 `true`인 버전입니다.

   ```
   aws iot delete-policy-version \
   --policy-name "PubSubTestThingPolicy" \
   --policy-version-id policyId
   ```

   정책 버전을 삭제한 후 이 단계를 다시 시도합니다.

업데이트된 구성 파일 및 정책을 사용하면 AWS IoT Device Client를 사용하여 와일드카드 구독을 시연할 준비가 된 것입니다.

**AWS IoT Device Client가 여러 MQTT 메시지 주제를 구독하고 수신하는 방법을 보여주는 방법**

1. **MQTT 테스트 클라이언트(MQTT test client)**에서 구독을 확인합니다. **MQTT 테스트 클라이언트**가 **\$1** 주제 필터를 구독하는 경우 다음 단계로 진행합니다. 그렇지 않은 경우 **MQTT 테스트 클라이언트**의 **주제 구독** 탭에 있는 **주제 필터**에 **\$1**(파운드 기호)를 입력한 다음 **구독**을 선택하여 이를 구독합니다.

1. Raspberry Pi에 연결된 로컬 호스트 컴퓨터의 터미널 창에서 이 명령을 입력하여 AWS IoT Device Client를 시작합니다.

   ```
   cd ~/aws-iot-device-client/build
   ./aws-iot-device-client --config-file ~/dc-configs/dc-pubsub-wild-config.json
   ```

1. 로컬 호스트 컴퓨터의 터미널 창에서 AWS IoT Device Client 출력을 보면서 **MQTT 테스트 클라이언트**로 돌아갑니다. **주제에 게시(Publish to a topic)** 탭의 **주제 이름(Topic name)**에 **test/dc/subtopic**을 입력한 다음 **게시(Publish)**를 선택합니다.

1. 터미널 창에서 다음과 같은 메시지를 찾아 메시지가 수신되었는지 확인합니다.

   ```
   2021-11-10T16:34:20.101Z [DEBUG] {samples/PubSubFeature.cpp}: Message received on subscribe topic, size: 76 bytes
   ```

1. 로컬 호스트 컴퓨터의 터미널 창에서 AWS IoT Device Client 출력을 보면서 **MQTT 테스트 클라이언트**로 돌아갑니다. **주제에 게시(Publish to a topic)** 탭의 **주제 이름(Topic name)**에 **test/dc/subtopic2**을 입력한 다음 **게시(Publish)**를 선택합니다.

1. 터미널 창에서 다음과 같은 메시지를 찾아 메시지가 수신되었는지 확인합니다.

   ```
   2021-11-10T16:34:32.078Z [DEBUG] {samples/PubSubFeature.cpp}: Message received on subscribe topic, size: 77 bytes
   ```

1. 두 메시지가 모두 수신되었음을 확인하는 메시지가 표시되면 **^C** (Ctrl-C)를 입력하여 AWS IoT Device Client를 중지합니다.

1. 이 명령을 입력하여 메시지 로그 파일의 끝을 보고 **MQTT 테스트 클라이언트(MQTT test client)**에서 게시한 메시지를 확인합니다.

   ```
   tail -n 20 ~/.aws-iot-device-client/log/pubsub_rx_msgs.log
   ```
**참고**  
로그 파일에는 메시지 페이로드만 포함됩니다. 수신한 메시지 로그 파일에는 메시지 주제가 기록되지 않습니다.  
수신된 로그에 AWS IoT Device Client가 게시한 메시지가 표시될 수도 있습니다. 이는 와일드카드 주제 필터에 해당 메시지 주제가 포함되어 있으며, 게시된 메시지가 구독자에게 전송되기 전에 메시지 브로커가 구독 요청을 처리할 수도 있기 때문입니다.

로그 파일의 항목은 메시지가 수신되었음을 보여줍니다. 다른 주제 이름을 사용하여 이 절차를 반복할 수 있습니다. 주제 이름이 `test/dc/`로 시작하는 모든 메시지는 수신되고 로그되어야 합니다. 주제 이름이 다른 텍스트로 시작하는 메시지는 무시됩니다.

 AWS IoT Device Client가 MQTT 메시지를 게시하고 구독하는 방법을 보여준 후 로 계속 진행합니다[자습서: AWS IoT Device Client를 사용하여 원격 작업(작업) 시연](iot-dc-runjobs.md).

# 자습서: AWS IoT Device Client를 사용하여 원격 작업(작업) 시연
<a name="iot-dc-runjobs"></a>

이 튜토리얼에서는 IoT 디바이스에 원격 작업을 전송하는 방법을 보여주기 위해 작업을 구성하고 Raspberry Pi에 배포합니다.

**이 자습서를 시작하려면:**
+ [이전 섹션](iot-dc-testconn.md)에서 사용한 대로 로컬 호스트 컴퓨터와 Raspberry Pi를 구성합니다.
+ 이전 섹션의 자습서를 완료하지 않은 경우에 AWS IoT Device Client를 설치한 후 저장한 이미지가 있는 microSD 카드와 함께 Raspberry Pi를 사용하여이 자습서를 시도할 수 있습니다[(선택 사항) microSD 카드 이미지 저장](iot-dc-install-download.md#iot-dc-install-dc-save).
+ 이전에이 데모를 실행한 적이 있는 경우 [2단계: AWS IoT Device Client로 데모를 빌드한 AWS 계정 후 정리](iot-dc-cleanup.md#iot-dc-cleanup-cloud)를 검토하여 이전 실행에서 생성한 모든 AWS IoT 리소스를 삭제하여 중복 리소스 오류를 방지합니다.

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

**이 주제를 마치면**
+ IoT 디바이스가를 AWS IoT Core 사용하여에서 관리하는 원격 작업을 실행할 수 있는 다양한 방법을 보여 주었을 것입니다 AWS IoT .

**필수 장비:**
+ [이전 섹션](iot-dc-install-dc.md)에서 테스트한 로컬 개발 및 테스트 환경
+ [이전 섹션](iot-dc-install-dc.md)에서 테스트한 Raspberry Pi
+ [이전 섹션](iot-dc-install-dc.md)에서 테스트한 Raspberry Pi의 microSD 메모리 카드

**Topics**
+ [작업을 실행할 Raspberry Pi 준비](iot-dc-runjobs-prepare.md)
+ [AWS IoT Device Client를 AWS IoT 사용하여에서 작업 생성 및 실행](iot-dc-runjobs-prepare-define.md)

# 작업을 실행할 Raspberry Pi 준비
<a name="iot-dc-runjobs-prepare"></a>

이 섹션의 절차에서는 AWS IoT Device Client를 사용하여 작업을 실행하도록 Raspberry Pi를 준비하는 방법을 설명합니다.

**참고**  
이러한 절차는 디바이스에 따라 다릅니다. 동시에 여러 디바이스로 이 섹션의 절차를 수행하려면 각 디바이스에 고유한 정책과 고유한 디바이스별 인증서 및 사물 이름이 필요합니다. 각 디바이스에 고유한 리소스를 제공하려면 절차에 설명된 대로 디바이스별 요소를 변경하면서 각 디바이스에 대해 이 절차를 한 번 수행합니다.

**Topics**
+ [Raspberry Pi를 프로비저닝하여 직업 시연](#iot-dc-runjobs-prepare-provision)
+ [작업 에이전트를 실행하도록 AWS IoT Device Client 구성](#iot-dc-runjobs-prepare-config)

## Raspberry Pi를 프로비저닝하여 직업 시연
<a name="iot-dc-runjobs-prepare-provision"></a>

이 섹션의 절차는 Raspberry Pi에 대한 AWS IoT 리소스 및 디바이스 인증서를 생성 AWS IoT 하여에서 Raspberry Pi를 프로비저닝합니다.

**Topics**
+ [디바이스 인증서 파일을 생성하고 다운로드하여 AWS IoT 작업 시연](#iot-dc-runjobs-prepare-cert)
+ [AWS IoT 작업을 시연하기 위한 AWS IoT 리소스 생성](#iot-dc-runjobs-prepare-iot)

### 디바이스 인증서 파일을 생성하고 다운로드하여 AWS IoT 작업 시연
<a name="iot-dc-runjobs-prepare-cert"></a>

이 절차는 이 데모에 대한 디바이스 인증서 파일을 생성합니다.

여러 디바이스를 준비하는 경우 각 디바이스에서 이 절차를 수행해야 합니다.

**Raspberry Pi에 대한 디바이스 인증서 파일을 생성하고 다운로드하려면**

Raspberry Pi에 연결된 로컬 호스트 컴퓨터의 터미널 창에서 이 명령을 입력합니다.

1. 다음 명령을 입력하여 디바이스에 대한 디바이스 인증서 파일을 만듭니다.

   ```
   aws iot create-keys-and-certificate \
   --set-as-active \
   --certificate-pem-outfile "~/certs/jobs/device.pem.crt" \
   --public-key-outfile "~/certs/jobs/public.pem.key" \
   --private-key-outfile "~/certs/jobs/private.pem.key"
   ```

   이 명령은 다음과 같은 응답을 반환합니다. 나중에 사용할 수 있도록 `certificateArn` 값을 저장합니다.

   ```
   {
   "certificateArn": "arn:aws:iot:us-west-2:57EXAMPLE833:cert/76e7e4edb3e52f52334be2f387a06145b2aa4c7fcd810f3aea2d92abc227d269",
   "certificateId": "76e7e4edb3e52f5233EXAMPLE7a06145b2aa4c7fcd810f3aea2d92abc227d269",
   "certificatePem": "-----BEGIN CERTIFICATE-----\nMIIDWTCCAkGgAwIBAgI_SHORTENED_FOR_EXAMPLE_Lgn4jfgtS\n-----END CERTIFICATE-----\n",
   "keyPair": {
       "PublicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BA_SHORTENED_FOR_EXAMPLE_ImwIDAQAB\n-----END PUBLIC KEY-----\n",
       "PrivateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQE_SHORTENED_FOR_EXAMPLE_T9RoDiukY\n-----END RSA PRIVATE KEY-----\n"
   }
   }
   ```

1. 이 명령을 입력하여 인증서 디렉터리와 해당 파일에 대한 권한을 설정합니다.

   ```
   chmod 700 ~/certs/jobs
   chmod 644 ~/certs/jobs/*
   chmod 600 ~/certs/jobs/private.pem.key
   ```

1. 이 명령을 실행하여 인증서 디렉터리 및 파일에 대한 권한을 검토합니다.

   ```
   ls -l ~/certs/jobs
   ```

   명령의 출력은 파일 날짜와 시간이 다르다는 점을 제외하고 여기에 표시되는 것과 같아야 합니다.

   ```
   -rw-r--r-- 1 pi pi 1220 Oct 28 13:02 device.pem.crt
   -rw------- 1 pi pi 1675 Oct 28 13:02 private.pem.key
   -rw-r--r-- 1 pi pi  451 Oct 28 13:02 public.pem.key
   ```

디바이스 인증서 파일을 Raspberry Pi에 다운로드했으면 [Raspberry Pi를 프로비저닝하여 직업 시연](#iot-dc-runjobs-prepare-provision)으로 진행할 준비가 된 것입니다.

### AWS IoT 작업을 시연하기 위한 AWS IoT 리소스 생성
<a name="iot-dc-runjobs-prepare-iot"></a>

이 디바이스에 대한 AWS IoT 리소스를 생성합니다.

여러 디바이스를 준비하는 경우 각 디바이스에 대해 이 절차를 수행해야 합니다.



**AWS IoT에서 디바이스를 프로비저닝하려면**

Raspberry Pi에 연결된 로컬 호스트 컴퓨터의 터미널 창에서

1. 다음 명령을 입력하여 AWS 계정에 대한 디바이스 데이터 엔드포인트의 주소를 가져옵니다.

   ```
   aws iot describe-endpoint --endpoint-type IoT:Data-ATS
   ```

   엔드포인트 값은 이 명령을 마지막으로 실행한 이후로 변경되지 않았습니다. 여기에서 명령을 다시 실행하면 데이터 엔드포인트 값을 쉽게 찾아 이 자습서에서 사용하는 구성 파일에 붙여 넣을 수 있습니다.

   **describe-endpoint** 명령은 다음과 같은 응답을 반환합니다. 나중에 사용하기 위해 `endpointAddress` 값을 적어 둡니다.

   ```
   {
   "endpointAddress": "a3qjEXAMPLEffp-ats.iot.us-west-2.amazonaws.com"
   }
   ```

1. *uniqueThingName*을 디바이스의 고유 이름으로 바꿉니다. 여러 디바이스에서 이 튜토리얼을 수행하려면 각 디바이스에 고유한 이름을 지정합니다. 예: **TestDevice01**, **TestDevice02** 등.

   Raspberry Pi에 대한 새 AWS IoT 사물 리소스를 생성하려면이 명령을 입력합니다.

   ```
   aws iot create-thing --thing-name "uniqueThingName"
   ```

    AWS IoT 사물 리소스는 클라우드에서 디바이스를 *가상*으로 표현하기 때문에에서 여러 용도로 AWS IoT 사용할 여러 사물 리소스를 생성할 수 있습니다. 모두 동일한 물리적 IoT 디바이스에서 사용하여 디바이스의 다양한 속성을 나타낼 수 있습니다.
**참고**  
여러 장치에 대한 정책을 보호하려는 경우 고정 사물 이름인 `uniqueThingName` 대신 `${iot:Thing.ThingName}`을 사용할 수 있습니다.

   이 튜토리얼에서는 디바이스당 한 번에 하나의 사물 리소스만 사용합니다. 이렇게 하면이 자습서에서는 다양한 데모를 나타내므로 데모용 AWS IoT 리소스를 생성한 후 돌아가서 각각에 대해 특별히 생성한 리소스를 사용하여 데모를 반복할 수 있습니다.

    AWS IoT 사물 리소스가 생성된 경우 명령은 이와 같은 응답을 반환합니다. 나중에 이 디바이스에서 실행할 작업을 생성할 때 사용할 `thingArn` 값을 기록합니다.

   ```
   {
   "thingName": "uniqueThingName",
   "thingArn": "arn:aws:iot:us-west-2:57EXAMPLE833:thing/uniqueThingName",
   "thingId": "8ea78707-32c3-4f8a-9232-14bEXAMPLEfd"
   }
   ```

1. 터미널 창에서

   1. `nano` 등의 텍스트 편집기를 엽니다.

   1. 이 JSON 문서를 복사하여 열려 있는 텍스트 편집기에 붙여 넣습니다.  
****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Connect"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:client/uniqueThingName"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Publish"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topic/test/dc/pubtopic",
                      "arn:aws:iot:us-west-2:123456789012:topic/$aws/events/job/*",
                      "arn:aws:iot:us-west-2:123456789012:topic/$aws/events/jobExecution/*",
                      "arn:aws:iot:us-west-2:123456789012:topic/$aws/things/uniqueThingName/jobs/*"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Subscribe"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topicfilter/test/dc/subtopic",
                      "arn:aws:iot:us-west-2:123456789012:topic/$aws/events/jobExecution/*",
                      "arn:aws:iot:us-west-2:123456789012:topicfilter/$aws/things/uniqueThingName/jobs/*"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Receive"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topic/test/dc/subtopic",
                      "arn:aws:iot:us-west-2:123456789012:topic/$aws/things/uniqueThingName/jobs/*"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:DescribeJobExecution",
                      "iot:GetPendingJobExecutions",
                      "iot:StartNextPendingJobExecution",
                      "iot:UpdateJobExecution"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topic/$aws/things/uniqueThingName"
                  ]
              }
          ]
      }
      ```

   1. 편집기에서 모든 정책 설명 `Resource` 섹션의 *us-west-2:57EXAMPLE833*을 AWS 리전, 콜론 문자(:) 및 12자리 AWS 계정 번호로 바꿉니다.

   1. 편집기의 모든 정책 설명에서 *uniqueThingName*을 이 사물 리소스에 지정한 사물 이름으로 바꿉니다.

   1. 텍스트 편집기에서 파일을 **\$1/policies/jobs\$1test\$1thing\$1policy.json**으로 저장합니다.

      여러 디바이스에 대해 이 절차를 실행하는 경우 파일을 각 디바이스에 이 파일 이름으로 저장합니다.

1. *uniqueThingName*을 디바이스의 사물 이름으로 바꾼 다음이 명령을 실행하여 해당 디바이스에 맞는 AWS IoT 정책을 생성합니다.

   ```
   aws iot create-policy \
   --policy-name "JobTestPolicyForuniqueThingName" \
   --policy-document "file://~/policies/jobs_test_thing_policy.json"
   ```

   정책이 생성되면 명령에서 다음과 같은 응답을 반환합니다.  
****  

   ```
   {
       "policyName": "JobTestPolicyForuniqueThingName",
       "policyArn": "arn:aws:iot:us-west-2:57EXAMPLE833:policy/JobTestPolicyForuniqueThingName",
       "policyDocument": "{\n\"Version\": \"2012-10-17\",\n\"Statement\": [\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Connect\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:client/PubSubTestThing\"\n]\n},\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Publish\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/pubtopic\"\n]\n},\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Subscribe\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:topicfilter/test/dc/subtopic\"\n]\n},\n{\n\"Effect\": \"Allow\",\n\"Action\": [\n\"iot:Receive\"\n],\n\"Resource\": [\n\"arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/*\"\n]\n}\n]\n}\n",
       "policyVersionId": "1"
   }
   ```

1. *uniqueThingName*을 디바이스의 사물 이름으로 바꾸고 `certificateArn`을 이 디바이스에 대해 이 섹션 앞부분에서 저장한 `certificateArn` 값으로 바꾼 다음 이 명령을 실행하여 정책을 디바이스 인증서에 연결합니다.

   ```
   aws iot attach-policy \
   --policy-name "JobTestPolicyForuniqueThingName" \
   --target "certificateArn"
   ```

   성공한 경우 이 명령은 아무 것도 반환하지 않습니다.

1.  *uniqueThingName*을 디바이스의 사물 이름으로 바꾸고이 섹션`certificateArn`의 앞부분에서 저장한 `certificateArn` 값으로 바꾼 다음이 명령을 실행하여 디바이스 인증서를 AWS IoT 사물 리소스에 연결합니다.

   ```
   aws iot attach-thing-principal \
   --thing-name "uniqueThingName" \
   --principal "certificateArn"
   ```

   성공한 경우 이 명령은 아무 것도 반환하지 않습니다.

Raspberry Pi를 성공적으로 프로비저닝한 후에는 테스트에서 다른 Raspberry Pi에 대해 이 섹션을 반복할 준비가 된 것입니다. 모든 디바이스가 프로비저닝된 경우 [작업 에이전트를 실행하도록 AWS IoT Device Client 구성](#iot-dc-runjobs-prepare-config)으로 진행합니다.

## 작업 에이전트를 실행하도록 AWS IoT Device Client 구성
<a name="iot-dc-runjobs-prepare-config"></a>

이 절차에서는 AWS IoT Device Client가 작업 에이전트를 실행할 수 있는 구성 파일을 생성합니다.

참고: 여러 디바이스를 준비하는 경우 각 디바이스에서 이 절차를 수행해야 합니다.

**AWS IoT Device Client를 테스트하는 구성 파일을 생성하려면:**

1. Raspberry Pi에 연결된 로컬 호스트 컴퓨터의 터미널 창에서

   1. `nano` 등의 텍스트 편집기를 엽니다.

   1. 이 JSON 문서를 복사하여 열려 있는 텍스트 편집기에 붙여 넣습니다.

      ```
      {
        "endpoint": "a3qEXAMPLEaffp-ats.iot.us-west-2.amazonaws.com",
        "cert": "~/certs/jobs/device.pem.crt",
        "key": "~/certs/jobs/private.pem.key",
        "root-ca": "~/certs/AmazonRootCA1.pem",
        "thing-name": "uniqueThingName",
        "logging": {
          "enable-sdk-logging": true,
          "level": "DEBUG",
          "type": "STDOUT",
          "file": ""
        },
        "jobs": {
          "enabled": true,
          "handler-directory": ""
        },
        "tunneling": {
          "enabled": false
        },
        "device-defender": {
          "enabled": false,
          "interval": 300
        },
        "fleet-provisioning": {
          "enabled": false,
          "template-name": "",
          "template-parameters": "",
          "csr-file": "",
          "device-key": ""
        },
        "samples": {
          "pub-sub": {
            "enabled": false,
            "publish-topic": "",
            "publish-file": "",
            "subscribe-topic": "",
            "subscribe-file": ""
          }
        },
        "config-shadow": {
          "enabled": false
        },
        "sample-shadow": {
          "enabled": false,
          "shadow-name": "",
          "shadow-input-file": "",
          "shadow-output-file": ""
        }
      }
      ```

   1. *엔드포인트* 값을에서 찾 AWS 계정 은의 디바이스 데이터 엔드포인트 값으로 바꿉니다[에서 디바이스 프로비저닝 AWS IoT Core](iot-dc-install-provision.md#iot-dc-install-dc-provision).

   1. *uniqueThingName*을 이 디바이스에 사용한 사물 이름으로 바꿉니다.

   1. 텍스트 편집기에서 파일을 **\$1/dc-configs/dc-jobs-config.json**으로 저장합니다.

1. 이 명령을 실행하여 새로운 구성 파일의 파일 권한을 설정합니다.

   ```
   chmod 644 ~/dc-configs/dc-jobs-config.json
   ```

이 테스트에는 **MQTT 테스트 클라이언트(MQTT test client)**를 사용하지 않습니다. 디바이스가 작업 관련 MQTT 메시지를와 교환하는 동안 AWS IoT작업 진행률 메시지는 작업을 실행하는 디바이스와만 교환됩니다. 작업 진행률 메시지는 작업을 실행하는 디바이스와만 교환되므로 AWS IoT 콘솔과 같은 다른 디바이스에서 메시지를 구독할 수 없습니다.

구성 파일을 저장한 후에는 [AWS IoT Device Client를 AWS IoT 사용하여에서 작업 생성 및 실행](iot-dc-runjobs-prepare-define.md) 단계를 진행할 준비가 된 것입니다.

# AWS IoT Device Client를 AWS IoT 사용하여에서 작업 생성 및 실행
<a name="iot-dc-runjobs-prepare-define"></a>

이 섹션의 절차에서는 작업 문서와 AWS IoT 작업 리소스를 생성합니다. 작업 리소스를 생성한 후는 작업 에이전트가 작업 문서를 디바이스 또는 클라이언트에 적용하는 지정된 작업 대상으로 작업 문서를 AWS IoT 보냅니다.

**Topics**
+ [IoT 작업의 작업 문서 생성 및 저장](#iot-dc-runjobs-prepare-define-jobdoc)
+ [하나의 IoT 디바이스에 AWS IoT 대해에서 작업 실행](#iot-dc-runjobs-prepare-define-job)

## IoT 작업의 작업 문서 생성 및 저장
<a name="iot-dc-runjobs-prepare-define-jobdoc"></a>

이 절차에서는 작업 리소스에 포함할 간단한 AWS IoT 작업 문서를 생성합니다. 이 작업 문서는 작업 대상에서 “Hello world\$1”를 표시합니다.

**작업 문서를 생성하고 저장하려면**

1. 작업 문서를 저장할 Amazon S3 버킷을 선택합니다. 이를 위해 사용할 기존 Amazon S3 버킷이 없는 경우에는 버킷을 생성해야 합니다. Amazon S3 버킷을 생성하는 방법에 대한 자세한 내용은 [Amazon S3 시작하기](https://docs.aws.amazon.com//AmazonS3/latest/userguide/GetStartedWithS3.html)의 주제를 참조하세요.

1. 이 작업에 대한 작업 문서 생성 및 저장

   1. 로컬 호스트 컴퓨터에서 텍스트 편집기를 엽니다.

   1. 이 텍스트를 복사하여 편집기에 붙여 넣습니다.

      ```
      {
          "operation": "echo",
          "args": ["Hello world!"]
      }
      ```

   1. 로컬 호스트 컴퓨터에서 편집기의 내용을 **hello-world-job.json**이라는 파일에 저장합니다.

   1. 파일이 올바르게 저장되었는지 확인합니다. 일부 텍스트 편집기는 텍스트 파일을 저장할 때 파일 이름에 자동으로 `.txt`를 추가합니다. 편집기에서 파일 이름에 `.txt`를 추가한 경우 계속하기 전에 파일 이름을 수정합니다.

1. *path\$1to\$1file*을 **hello-world-job.json**의 경로로 바꾸고(현재 디렉터리에 없는 경우) *s3\$1bucket\$1name*을 선택한 버킷에 대한 Amazon S3 버킷 경로로 바꾼 다음 이 명령을 실행하여 작업 문서를 Amazon S3 버킷에 넣습니다.

   ```
   aws s3api put-object \
   --key hello-world-job.json \
   --body path_to_file/hello-world-job.json --bucket s3_bucket_name
   ```

   Amazon S3에 저장한 작업 문서를 식별하는 작업 문서 URL은 다음 URL에서 *s3\$1bucket\$1name* 및 *AWS\$1region*을 바꿔서 결정됩니다. 나중에 *job\$1document\$1path*로 사용할 결과 URL을 기록합니다.

   ```
   https://s3_bucket_name.s3.AWS_Region.amazonaws.com/hello-world-job.json
   ```
**참고**  
AWS 보안은 AWS 계정예를 들어 브라우저를 사용하여 외부에서이 URL을 열 수 없도록 합니다. URL은 기본적으로 파일에 액세스할 수 있는 AWS IoT 작업 엔진에서 사용됩니다. 프로덕션 환경에서는 AWS IoT 서비스에 Amazon S3에 저장된 작업 문서에 대한 액세스 권한이 있는지 확인해야 합니다.

작업 문서의 URL을 저장한 후 [하나의 IoT 디바이스에 AWS IoT 대해에서 작업 실행](#iot-dc-runjobs-prepare-define-job)으로 진행합니다.

## 하나의 IoT 디바이스에 AWS IoT 대해에서 작업 실행
<a name="iot-dc-runjobs-prepare-define-job"></a>

이 섹션의 절차는 Raspberry Pi에서 AWS IoT Device Client를 시작하여 디바이스에서 작업 에이전트를 실행하고 작업이 실행될 때까지 기다립니다. 또한에서 작업 리소스를 생성 AWS IoT하여 IoT 디바이스로 작업을 전송하고 실행합니다.

**참고**  
이 절차는 단일 디바이스에서만 작업을 실행합니다.

**Raspberry Pi에서 작업 에이전트를 시작하려면**

1. Raspberry Pi에 연결된 로컬 호스트 컴퓨터의 터미널 창에서이 명령을 실행하여 AWS IoT Device Client를 시작합니다.

   ```
   cd ~/aws-iot-device-client/build
   ./aws-iot-device-client --config-file ~/dc-configs/dc-jobs-config.json
   ```

1. 터미널 창에서 AWS IoT Device Client 및가 이러한 메시지를 표시하는지 확인합니다.

   ```
   2021-11-15T18:45:56.708Z [INFO]  {Main.cpp}: Jobs is enabled
                         .
                         .
                         .
   2021-11-15T18:45:56.708Z [INFO]  {Main.cpp}: Client base has been notified that Jobs has started
   2021-11-15T18:45:56.708Z [INFO]  {JobsFeature.cpp}: Running Jobs!
   2021-11-15T18:45:56.708Z [DEBUG] {JobsFeature.cpp}: Attempting to subscribe to startNextPendingJobExecution accepted and rejected
   2021-11-15T18:45:56.708Z [DEBUG] {JobsFeature.cpp}: Attempting to subscribe to nextJobChanged events
   2021-11-15T18:45:56.708Z [DEBUG] {JobsFeature.cpp}: Attempting to subscribe to updateJobExecutionStatusAccepted for jobId +
   2021-11-15T18:45:56.738Z [DEBUG] {JobsFeature.cpp}: Ack received for SubscribeToUpdateJobExecutionAccepted with code {0}
   2021-11-15T18:45:56.739Z [DEBUG] {JobsFeature.cpp}: Attempting to subscribe to updateJobExecutionStatusRejected for jobId +
   2021-11-15T18:45:56.753Z [DEBUG] {JobsFeature.cpp}: Ack received for SubscribeToNextJobChanged with code {0}
   2021-11-15T18:45:56.760Z [DEBUG] {JobsFeature.cpp}: Ack received for SubscribeToStartNextJobRejected with code {0}
   2021-11-15T18:45:56.776Z [DEBUG] {JobsFeature.cpp}: Ack received for SubscribeToStartNextJobAccepted with code {0}
   2021-11-15T18:45:56.776Z [DEBUG] {JobsFeature.cpp}: Ack received for SubscribeToUpdateJobExecutionRejected with code {0}
   2021-11-15T18:45:56.777Z [DEBUG] {JobsFeature.cpp}: Publishing startNextPendingJobExecutionRequest
   2021-11-15T18:45:56.785Z [DEBUG] {JobsFeature.cpp}: Ack received for StartNextPendingJobPub with code {0}
   2021-11-15T18:45:56.785Z [INFO]  {JobsFeature.cpp}: No pending jobs are scheduled, waiting for the next incoming job
   ```

1. 터미널 창에서 이 메시지가 표시되면 다음 절차로 진행하고 작업 리소스를 생성합니다. 목록의 마지막 항목이 아닐 수도 있습니다.

   ```
   2021-11-15T18:45:56.785Z [INFO]  {JobsFeature.cpp}: No pending jobs are scheduled, waiting for the next incoming job
   ```

**AWS IoT 작업 리소스를 생성하려면**

1. 로컬 호스트 컴퓨터에서

   1. *job\$1document\$1url*을 [IoT 작업의 작업 문서 생성 및 저장](#iot-dc-runjobs-prepare-define-jobdoc)의 작업 문서 URL로 바꿉니다.

   1. *thing\$1arn*을 디바이스에 대해 생성한 사물 리소스의 ARN으로 바꾼 다음 이 명령을 실행합니다.

      ```
      aws iot create-job \
      --job-id hello-world-job-1 \
      --document-source "job_document_url" \
      --targets "thing_arn" \
      --target-selection SNAPSHOT
      ```

      성공하면 명령이 다음과 같은 결과를 반환합니다.

      ```
      {
        "jobArn": "arn:aws:iot:us-west-2:57EXAMPLE833:job/hello-world-job-1",
        "jobId": "hello-world-job-1"
      }
      ```

1. 터미널 창에 다음과 같이 AWS IoT Device Client의 출력이 표시됩니다.

   ```
   2021-11-15T18:02:26.688Z [INFO]  {JobsFeature.cpp}: No pending jobs are scheduled, waiting for the next incoming job
   2021-11-15T18:10:24.890Z [DEBUG] {JobsFeature.cpp}: Job ids differ
   2021-11-15T18:10:24.890Z [INFO]  {JobsFeature.cpp}: Executing job: hello-world-job-1
   2021-11-15T18:10:24.890Z [DEBUG] {JobsFeature.cpp}: Attempting to update job execution status!
   2021-11-15T18:10:24.890Z [DEBUG] {JobsFeature.cpp}: Not including stdout with the status details
   2021-11-15T18:10:24.890Z [DEBUG] {JobsFeature.cpp}: Not including stderr with the status details
   2021-11-15T18:10:24.890Z [DEBUG] {JobsFeature.cpp}: Assuming executable is in PATH
   2021-11-15T18:10:24.890Z [INFO]  {JobsFeature.cpp}: About to execute: echo Hello world!
   2021-11-15T18:10:24.890Z [DEBUG] {Retry.cpp}: Retryable function starting, it will retry until success
   2021-11-15T18:10:24.890Z [DEBUG] {JobsFeature.cpp}: Created EphermalPromise for ClientToken 3TEWba9Xj6 in the updateJobExecution promises map
   2021-11-15T18:10:24.890Z [DEBUG] {JobEngine.cpp}: Child process now running
   2021-11-15T18:10:24.890Z [DEBUG] {JobEngine.cpp}: Child process about to call execvp
   2021-11-15T18:10:24.890Z [DEBUG] {JobEngine.cpp}: Parent process now running, child PID is 16737
   2021-11-15T18:10:24.891Z [DEBUG] {16737}: Hello world!
   2021-11-15T18:10:24.891Z [DEBUG] {JobEngine.cpp}: JobEngine finished waiting for child process, returning 0
   2021-11-15T18:10:24.891Z [INFO]  {JobsFeature.cpp}: Job exited with status: 0
   2021-11-15T18:10:24.891Z [INFO]  {JobsFeature.cpp}: Job executed successfully!
   2021-11-15T18:10:24.891Z [DEBUG] {JobsFeature.cpp}: Attempting to update job execution status!
   2021-11-15T18:10:24.891Z [DEBUG] {JobsFeature.cpp}: Not including stdout with the status details
   2021-11-15T18:10:24.891Z [DEBUG] {JobsFeature.cpp}: Not including stderr with the status details
   2021-11-15T18:10:24.892Z [DEBUG] {Retry.cpp}: Retryable function starting, it will retry until success
   2021-11-15T18:10:24.892Z [DEBUG] {JobsFeature.cpp}: Created EphermalPromise for ClientToken GmQ0HTzWGg in the updateJobExecution promises map
   2021-11-15T18:10:24.905Z [DEBUG] {JobsFeature.cpp}: Ack received for PublishUpdateJobExecutionStatus with code {0}
   2021-11-15T18:10:24.905Z [DEBUG] {JobsFeature.cpp}: Removing ClientToken 3TEWba9Xj6 from the updateJobExecution promises map
   2021-11-15T18:10:24.905Z [DEBUG] {JobsFeature.cpp}: Success response after UpdateJobExecution for job hello-world-job-1
   2021-11-15T18:10:24.917Z [DEBUG] {JobsFeature.cpp}: Ack received for PublishUpdateJobExecutionStatus with code {0}
   2021-11-15T18:10:24.918Z [DEBUG] {JobsFeature.cpp}: Removing ClientToken GmQ0HTzWGg from the updateJobExecution promises map
   2021-11-15T18:10:24.918Z [DEBUG] {JobsFeature.cpp}: Success response after UpdateJobExecution for job hello-world-job-1
   2021-11-15T18:10:25.861Z [INFO]  {JobsFeature.cpp}: No pending jobs are scheduled, waiting for the next incoming job
   ```

1.  AWS IoT Device Client가 실행 중이고 작업을 기다리는 동안 `job-id` 값을 변경하고 1단계**create-job**에서를 다시 실행하여 다른 작업을 제출할 수 있습니다.

작업 실행이 완료되면 터미널 창에서 ^C (control-C)를 입력하여 AWS IoT Device Client를 중지합니다.

# 자습서: AWS IoT Device Client 자습서를 실행한 후 정리
<a name="iot-dc-cleanup"></a>

이 튜토리얼의 절차는 이 학습 경로의 튜토리얼을 완료하는 동안 생성한 파일과 리소스를 제거하는 과정을 안내합니다.

**Topics**
+ [1단계: Device Client로 데모를 빌드한 후 AWS IoT 디바이스 정리](#iot-dc-cleanup-devices)
+ [2단계: AWS IoT Device Client로 데모를 빌드한 AWS 계정 후 정리](#iot-dc-cleanup-cloud)

## 1단계: Device Client로 데모를 빌드한 후 AWS IoT 디바이스 정리
<a name="iot-dc-cleanup-devices"></a>

이 튜토리얼에서는 이 학습 경로에서 데모를 빌드한 후 microSD 카드를 정리하는 방법에 대한 두 가지 옵션을 설명합니다. 필요한 보안 수준을 제공하는 옵션을 선택합니다.

디바이스의 microSD 카드를 정리해도 생성한 AWS IoT 리소스는 제거되지 않습니다. 디바이스의 microSD 카드를 정리한 후 AWS IoT 리소스를 정리하려면의 자습서를 검토해야 합니다[2단계: AWS IoT Device Client로 데모를 빌드한 AWS 계정 후 정리](#iot-dc-cleanup-cloud).

### 옵션 1: microSD 카드를 다시 써서 정리
<a name="iot-dc-cleanup-devices-flash"></a>

이 학습 경로의 튜토리얼을 완료한 후 microSD 카드를 지우는 가장 쉽고 철저한 방법은 디바이스를 처음 준비할 때 생성한 저장된 이미지 파일로 microSD 카드를 덮어쓰는 것입니다.

이 절차에서는 로컬 호스트 컴퓨터를 사용하여 저장된 microSD 카드 이미지를 microSD 카드에 씁니다.

**참고**  
디바이스에서 운영 체제에 이동식 저장 매체를 사용하지 않는 경우 해당 디바이스에 대한 절차를 참조하세요.

**microSD 카드에 새 이미지를 쓰려면**

1. 로컬 호스트 컴퓨터에서 microSD 카드에 쓸 저장된 microSD 카드 이미지를 찾습니다.

1. microSD 카드를 로컬 호스트 컴퓨터에 삽입합니다.

1. SD 카드 이미징 도구를 사용하여 선택한 이미지 파일을 microSD 카드에 씁니다.

1. Raspberry Pi OS 이미지를 microSD 카드에 쓴 후 microSD 카드를 꺼내 로컬 호스트 컴퓨터에서 안전하게 제거합니다.

microSD 카드를 사용할 준비가 되었습니다.

### 옵션 2: 사용자 디렉터리를 삭제하여 정리
<a name="iot-dc-cleanup-devices-dirs"></a>

튜토리얼을 완료한 후 microSD 카드 이미지를 다시 쓰지 않고 microSD 카드를 지우려면 사용자 디렉터리를 개별적으로 삭제합니다. 이 방법은 설치되었을 수 있는 시스템 파일을 제거하지 않기 때문에 저장된 이미지에서 microSD 카드를 다시 쓰는 것만큼 철저하지 않습니다.

사용자 디렉터리 제거만으로도 충분하다면 이 절차를 따를 수 있습니다.

**디바이스에서 이 학습 경로의 사용자 디렉터리를 삭제하려면**

1. 이 명령을 실행하여 디바이스에 연결된 터미널 창에서 이 학습 경로에 생성된 사용자 디렉터리, 하위 디렉터리 및 모든 파일을 삭제합니다.
**참고**  
이러한 디렉터리와 파일을 삭제하면 튜토리얼을 다시 완료하지 않고 데모를 실행할 수 없게 됩니다.

   ```
   rm -Rf ~/dc-configs
   rm -Rf ~/policies
   rm -Rf ~/messages
   rm -Rf ~/certs
   rm -Rf ~/.aws-iot-device-client
   ```

1. 이 명령을 실행하여 디바이스에 연결된 터미널 창에서 애플리케이션 소스 디렉터리 및 파일을 삭제합니다.
**참고**  
이 명령은 프로그램을 제거하지 않습니다. 프로그램 빌드 및 설치에 사용된 소스 파일만 제거합니다. 이러한 파일을 삭제한 후에는 AWS CLI 및 AWS IoT Device Client가 작동하지 않을 수 있습니다.

   ```
   rm -Rf ~/aws-cli
   rm -Rf ~/aws
   rm -Rf ~/aws-iot-device-client
   ```

## 2단계: AWS IoT Device Client로 데모를 빌드한 AWS 계정 후 정리
<a name="iot-dc-cleanup-cloud"></a>

이 절차는이 학습 경로의 자습서를 완료하는 동안 생성한 AWS 리소스를 식별하고 제거하는 데 도움이 됩니다.

### AWS IoT 리소스 정리
<a name="iot-dc-cleanup-cloud-iot"></a>

이 절차는이 학습 경로의 자습서를 완료하는 동안 생성한 AWS IoT 리소스를 식별하고 제거하는 데 도움이 됩니다.


**AWS IoT 이 학습 경로에 생성된 리소스**  

| 자습서 | 사물 리소스 | 정책 리소스 | 
| --- | --- | --- | 
|  [자습서: AWS IoT Device Client 설치 및 구성](iot-dc-install-dc.md)  |  **DevCliTestThing**  | DevCliTestThingPolicy | 
|  [자습서: AWS IoT Device Client와의 MQTT 메시지 통신 시연](iot-dc-testconn.md)  |  **PubSubTestThing**  | PubSubTestThingPolicy | 
|  [자습서: AWS IoT Device Client를 사용하여 원격 작업(작업) 시연](iot-dc-runjobs.md)  | 사용자 정의(여러 개 있을 수 있음) |  *사용자 정의*(여러 개 있을 수 있음)  | 

**AWS IoT 리소스를 삭제하려면 생성한 각 사물 리소스에 대해이 절차를 따릅니다.**

1. `thing_name`을 삭제하려는 사물 리소스의 이름으로 바꾼 다음 이 명령을 실행하여 로컬 호스트 컴퓨터에서 사물 리소스에 연결된 인증서를 나열합니다.

   ```
   aws iot list-thing-principals --thing-name thing_name
   ```

   이 명령은 연결된 인증서를 나열하는 이와 같은 응답을 반환합니다.`thing_name` 대부분의 경우 목록에 인증서가 하나만 있습니다.

   ```
   {
       "principals": [
           "arn:aws:iot:us-west-2:57EXAMPLE833:cert/23853eea3cf0edc7f8a69c74abeafa27b2b52823cab5b3e156295e94b26ae8ac"
       ]
   }
   ```

1. 이전 명령으로 나열된 각 인증서에 대해

   1. `certificate_ID`를 이전 명령의 인증서 ID로 바꿉니다. 인증서 ID는 이전 명령에서 반환된 ARN에서 `cert/` 뒤에 오는 영숫자 문자입니다. 그런 다음 이 명령을 실행하여 인증서를 비활성화합니다.

      ```
      aws iot update-certificate --new-status INACTIVE --certificate-id certificate_ID
      ```

      성공한 경우 이 명령은 아무 것도 반환하지 않습니다.

   1. `certificate_ARN`을 이전에 반환된 인증서 목록의 인증서 ARN으로 바꾼 다음 이 명령을 실행하여 이 인증서에 연결된 정책을 나열합니다.

      ```
      aws iot list-attached-policies --target certificate_ARN
      ```

      이 명령은 인증서에 연결된 정책을 나열하는 이와 같은 응답을 반환합니다. 대부분의 경우 목록에 정책이 하나만 있습니다.

      ```
      {
          "policies": [
              {
                  "policyName": "DevCliTestThingPolicy",
                  "policyArn": "arn:aws:iot:us-west-2:57EXAMPLE833:policy/DevCliTestThingPolicy"
              }
          ]
      }
      ```

   1. 인증서에 연결된 각 정책에 대해:

      1. `policy_name`을 이전 명령의 `policyName` 값으로 바꾸고 `certificate_ARN`을 인증서 ARN으로 바꾼 다음 이 명령을 실행하여 인증서에서 정책을 분리합니다.

         ```
         aws iot detach-policy --policy-name policy_name --target certificate_ARN
         ```

         성공한 경우 이 명령은 아무 것도 반환하지 않습니다.

      1. `policy_name`을 `policyName` 값으로 바꾼 다음 이 명령을 실행하여 정책이 추가 인증서에 연결되어 있는지 확인합니다.

         ```
         aws iot list-targets-for-policy --policy-name policy_name
         ```

         명령이 이와 같은 빈 목록을 반환하는 경우 정책은 인증서에 연결되지 않은 것입니다. 계속해서 정책 버전을 나열합니다. 정책에 연결된 인증서가 여전히 있는 경우 **detach-thing-principal** 단계를 계속합니다.

         ```
         {
             "targets": []
         }
         ```

      1. `policy_name`을 `policyName` 값으로 바꾼 다음 이 명령을 실행하여 정책 버전을 확인합니다. 정책을 삭제하려면 버전이 하나만 있어야 합니다.

         ```
         aws iot list-policy-versions --policy-name policy_name
         ```

         이 예와 같이 정책에 버전이 하나만 있는 경우 지금 **delete-policy** 단계로 건너뛰고 정책을 삭제할 수 있습니다.

         ```
         {
             "policyVersions": [
                 {
                     "versionId": "1",
                     "isDefaultVersion": true,
                     "createDate": "2021-11-18T01:02:46.778000+00:00"
                 }
             ]
         }
         ```

         이 예와 같이 정책에 여러 버전이 있는 경우 `isDefaultVersion` 값이 `false`인 정책 버전을 삭제해야 정책을 삭제할 수 있습니다.

         ```
         {
             "policyVersions": [
                 {
                     "versionId": "2",
                     "isDefaultVersion": true,
                     "createDate": "2021-11-18T01:52:04.423000+00:00"
                 },
                 {
                     "versionId": "1",
                     "isDefaultVersion": false,
                     "createDate": "2021-11-18T01:30:18.083000+00:00"
                 }
             ]
         }
         ```

         정책 버전을 삭제해야 하는 경우 `policy_name`을 `policyName` 값으로 바꾸고 `version_ID`를 이전 명령의 `versionId` 값으로 바꾼 다음 이 명령을 실행하여 정책 버전을 삭제합니다.

         ```
         aws iot delete-policy-version --policy-name policy_name --policy-version-id version_ID
         ```

         성공한 경우 이 명령은 아무 것도 반환하지 않습니다.

         정책 버전을 삭제한 후 정책에 정책 버전이 하나만 있을 때까지 이 단계를 반복합니다.

      1. `policy_name`을 `policyName` 값으로 바꾼 다음 이 명령을 실행하여 정책을 삭제합니다.

         ```
         aws iot delete-policy --policy-name policy_name
         ```

   1. `thing_name`을 사물의 이름으로 바꾸고 `certificate_ARN`을 인증서의 ARN으로 바꾼 다음, 이 명령을 실행하여 사물 리소스에서 인증서를 분리합니다.

      ```
      aws iot detach-thing-principal --thing-name thing_name --principal certificate_ARN
      ```

      성공한 경우 이 명령은 아무 것도 반환하지 않습니다.

   1. `certificate_ID`를 이전 명령의 인증서 ID로 바꿉니다. 인증서 ID는 이전 명령에서 반환된 ARN에서 `cert/` 뒤에 오는 영숫자 문자입니다. 그런 다음 이 명령을 실행하여 인증서 리소스를 삭제합니다.

      ```
      aws iot delete-certificate --certificate-id certificate_ID
      ```

      성공한 경우 이 명령은 아무 것도 반환하지 않습니다.

1. `thing_name`을 사물의 이름으로 바꾼 다음 이 명령을 실행하여 사물을 삭제합니다.

   ```
   aws iot delete-thing --thing-name thing_name
   ```

   성공한 경우 이 명령은 아무 것도 반환하지 않습니다.

### AWS 리소스 정리
<a name="iot-dc-cleanup-cloud-aws"></a>

이 절차는이 학습 경로의 자습서를 완료하는 동안 생성한 다른 AWS 리소스를 식별하고 제거하는 데 도움이 됩니다.


**이 학습 경로에 생성된 기타 AWS 리소스**  

| 자습서 | 리소스 유형 | 리소스 이름 또는 ID | 
| --- | --- | --- | 
|  [자습서: AWS IoT Device Client를 사용하여 원격 작업(작업) 시연](iot-dc-runjobs.md)  | Amazon S3 객체 | hello-world-job.json | 
|  [자습서: AWS IoT Device Client를 사용하여 원격 작업(작업) 시연](iot-dc-runjobs.md)  |  AWS IoT 작업 리소스  | 사용자 정의 | 

**이 학습 경로에서 생성된 AWS 리소스를 삭제하려면**

1. 이 학습 경로에서 생성된 작업을 삭제하려면

   1. 이 명령을 실행하여의 작업을 나열합니다 AWS 계정.

      ```
      aws iot list-jobs
      ```

      명령은 다음과 AWS 리전 같은 및의 AWS IoT 작업 목록을 반환합니다 AWS 계정 .

      ```
      {
          "jobs": [
              {
                  "jobArn": "arn:aws:iot:us-west-2:57EXAMPLE833:job/hello-world-job-2",
                  "jobId": "hello-world-job-2",
                  "targetSelection": "SNAPSHOT",
                  "status": "COMPLETED",
                  "createdAt": "2021-11-16T23:40:36.825000+00:00",
                  "lastUpdatedAt": "2021-11-16T23:40:41.375000+00:00",
                  "completedAt": "2021-11-16T23:40:41.375000+00:00"
              },
              {
                  "jobArn": "arn:aws:iot:us-west-2:57EXAMPLE833:job/hello-world-job-1",
                  "jobId": "hello-world-job-1",
                  "targetSelection": "SNAPSHOT",
                  "status": "COMPLETED",
                  "createdAt": "2021-11-16T23:35:26.381000+00:00",
                  "lastUpdatedAt": "2021-11-16T23:35:29.239000+00:00",
                  "completedAt": "2021-11-16T23:35:29.239000+00:00"
              }
          ]
      }
      ```

   1. 목록에서이 학습 경로에서 생성한 작업으로 인식하는 각 작업에 대해를 삭제할 작업의 `jobId` 값으로 `jobId` 바꾼 다음이 명령을 실행하여 AWS IoT 작업을 삭제합니다.

      ```
      aws iot delete-job --job-id jobId
      ```

      명령이 성공하면 아무 것도 반환하지 않습니다.

1. 이 학습 경로의 Amazon S3 버킷에 저장한 작업 문서를 삭제하려면

   1. `bucket`을 사용한 버킷의 이름으로 바꾼 다음 이 명령을 실행하여 사용한 Amazon S3 버킷의 객체를 나열합니다.

      ```
      aws s3api list-objects --bucket bucket
      ```

      이 명령은 다음과 같은 버킷의 Amazon S3 객체 목록을 반환합니다.

      ```
      {
          "Contents": [
              {
                  "Key": "hello-world-job.json",
                  "LastModified": "2021-11-18T03:02:12+00:00",
                  "ETag": "\"868c8bc3f56b5787964764d4b18ed5ef\"",
                  "Size": 54,
                  "StorageClass": "STANDARD",
                  "Owner": {
                      "DisplayName": "EXAMPLE",
                      "ID": "e9e3d6ec1EXAMPLEf5bfb5e6bd0a2b6ed03884d1ed392a82ad011c144736a4ee"
                  }
              },
              {
                  "Key": "iot_job_firmware_update.json",
                  "LastModified": "2021-04-13T21:57:07+00:00",
                  "ETag": "\"7c68c591949391791ecf625253658c61\"",
                  "Size": 66,
                  "StorageClass": "STANDARD",
                  "Owner": {
                      "DisplayName": "EXAMPLE",
                      "ID": "e9e3d6ec1EXAMPLEf5bfb5e6bd0a2b6ed03884d1ed392a82ad011c144736a4ee"
                  }
              },
              {
                  "Key": "order66.json",
                  "LastModified": "2021-04-13T21:57:07+00:00",
                  "ETag": "\"bca60d5380b88e1a70cc27d321caba72\"",
                  "Size": 29,
                  "StorageClass": "STANDARD",
                  "Owner": {
                      "DisplayName": "EXAMPLE",
                      "ID": "e9e3d6ec1EXAMPLEf5bfb5e6bd0a2b6ed03884d1ed392a82ad011c144736a4ee"
                  }
              }
          ]
      }
      ```

   1. 목록에서 이 학습 경로에서 생성한 객체로 인식한 각 객체에 대해 `bucket`을 버킷 이름으로 바꾸고, `key`를 삭제할 객체의 키 값으로 바꾼 다음 이 명령을 실행하여 Amazon S3 객체를 삭제합니다.

      ```
       aws s3api delete-object --bucket bucket --key key
      ```

      명령이 성공하면 아무 것도 반환하지 않습니다.

이 학습 경로를 완료하는 동안 생성한 모든 AWS 리소스와 객체를 삭제한 후 자습서를 다시 시작하고 반복할 수 있습니다.

# AWS IoT 디바이스 SDKs를 사용하여 솔루션 구축
<a name="iot-tutorials-sdk-intro"></a>

이 섹션의 자습서에서는를 사용하여 프로덕션 환경에 배포할 수 있는 IoT 솔루션을 개발하는 단계를 안내합니다 AWS IoT.

이 자습서는 AWS IoT 디바이스 SDKs를 사용하고 안전하고 신뢰할 수 있는 솔루션을 만드는 데 도움이 되도록 적용되는 개념을 자세히 설명[AWS IoT Device Client를 사용하여 데모 빌드](iot-tutorials-dc-intro.md)하기 때문에 섹션의 자습서보다 완료하는 데 더 많은 시간이 걸릴 수 있습니다.

## AWS IoT 디바이스 SDKs로 솔루션 구축 시작
<a name="iot-sdk-tutorial-overview"></a>

이 자습서에서는 다양한 AWS IoT 시나리오를 안내합니다. 해당하는 경우 자습서에서는 AWS IoT 디바이스 SDKs를 사용합니다.

**Topics**
+ [AWS IoT 디바이스 SDKs로 솔루션 구축 시작](#iot-sdk-tutorial-overview)
+ [자습서: Device SDK를 AWS IoT Core 사용하여에 AWS IoT 디바이스 연결](sdk-tutorials.md)
+ [디바이스 데이터를 다른 서비스로 라우팅하는 AWS IoT 규칙 생성](iot-rules-tutorial.md)
+ [디바이스 섀도우로 디바이스가 오프라인 상태일 때 디바이스 상태 유지](iot-shadows-tutorial.md)
+ [자습서:에 대한 사용자 지정 권한 부여자 생성 AWS IoT Core](custom-auth-tutorial.md)
+ [자습서: AWS IoT 및 Raspberry Pi를 사용하여 토양 수분 모니터링](iot-moisture-tutorial.md)

# 자습서: Device SDK를 AWS IoT Core 사용하여에 AWS IoT 디바이스 연결
<a name="sdk-tutorials"></a>

이 자습서에서는 데이터를 주고 받을 수 AWS IoT Core 있도록 디바이스를에 연결하는 방법을 보여줍니다 AWS IoT. 이 자습서를 완료하면 디바이스가에 연결되도록 구성 AWS IoT Core 되고 디바이스가 통신하는 방식을 이해할 수 있습니다 AWS IoT.

**Topics**
+ [필수 조건](#sdk-tutorials-prereq)
+ [용 디바이스 준비 AWS IoT](#sdk-tutorials-prepare)
+ [MQTT 프로토콜 검토](#sdk-tutorials-mqtt-review)
+ [pubsub.py Device SDK 샘플 앱 검토](#sdk-tutorials-explore-sample)
+ [디바이스 연결 및와 통신 AWS IoT Core](#sdk-tutorials-experiment)
+ [결과 검토](#sdk-tutorials-conclusion)
+ [자습서: AWS IoT Device SDK for Embedded C 사용](iot-embedded-c-sdk.md)

## 필수 조건
<a name="sdk-tutorials-prereq"></a>

이 자습서를 시작하기 전에 다음 사항을 준비해야 합니다.
+ 

**[AWS IoT Core 자습서 시작하기](iot-gs.md) 완료**  
[디바이스 구성](configure-device.md)해야 하는 해당 자습서의 섹션에서 디바이스에 대한 [Raspberry Pi 또는 다른 디바이스 연결](connecting-to-existing-device.md) 옵션을 선택하고 Python 언어 옵션을 사용하여 디바이스를 구성합니다.
**참고**  
이 자습서에서도 사용하므로 해당 자습서에서 사용하는 터미널 창을 계속 열어 둡니다.
+ 

**AWS IoT Device SDK v2 for Python을 실행할 수 있는 디바이스입니다.**  
이 자습서에서는 비교적 강력한 디바이스가 필요한 Python 코드 예제를 사용하여 디바이스를 AWS IoT Core 에 연결하는 방법을 보여줍니다. 리소스가 제한된 디바이스로 작업하는 경우 이러한 코드 예제는 해당 디바이스에서 작동하지 않을 수 있습니다. 이 경우 [자습서: AWS IoT Device SDK for Embedded C 사용](iot-embedded-c-sdk.md) 자습서를 통해 더욱 성공적으로 수행할 수 있습니다.
+ 

**디바이스에 연결하는 데 필요한 정보를 얻었습니다.**  
디바이스를 연결하려면 사물 이름 AWS IoT, 호스트 이름 및 포트 번호에 대한 정보가 있어야 합니다.
**참고**  
사용자 지정 인증을 사용하여 디바이스를 AWS IoT Core에 연결할 수도 있습니다. 권한 부여자 Lambda 함수에 전달하는 연결 데이터는 사용하는 프로토콜에 따라 다릅니다.
  + **사물 이름**: 연결하려는 AWS IoT 사물의 이름입니다. 를 디바이스로 AWS IoT 사물로 등록해야 합니다. 자세한 내용은 [를 사용하여 디바이스 관리 AWS IoT](iot-thing-management.md) 단원을 참조하십시오.
  + **호스트 이름**: 계정별 IoT 엔드포인트의 호스트 이름입니다.
  + **포트 번호**: 연결하려는 포트 번호입니다.

   AWS IoT Python SDK의 `configureEndpoint` 메서드를 사용하여 호스트 이름과 포트 번호를 구성할 수 있습니다.

  ```
  myAWSIoTMQTTClient.configureEndpoint("random.iot.region.amazonaws.com", 8883)
  ```

## 용 디바이스 준비 AWS IoT
<a name="sdk-tutorials-prepare"></a>

[AWS IoT Core 자습서 시작하기](iot-gs.md)에서는 디바이스와 AWS 계정이 통신할 수 있도록 준비했습니다. 이 섹션에서는 모든 디바이스 연결에 적용되는 준비의 측면을 검토합니다 AWS IoT Core.

디바이스가 AWS IoT Core에 연결하려면 다음 사항이 필요합니다.

1. **AWS 계정**이 있어야 합니다.

   의 절차에서는 아직 생성하지 않은 AWS 계정 경우를 생성하는 방법을 [설정 AWS 계정](setting-up.md) 설명합니다.

1. 해당 계정에서는 AWS 계정 및 리전의 디바이스에 대해 다음과 같은 **AWS IoT 리소스**가 정의되어 있어야 합니다.

   [AWS IoT 리소스 생성](create-iot-resources.md)의 절차에서는 AWS 계정 및 리전의 디바이스에 대해 이러한 리소스를 생성하는 방법을 설명합니다.
   +  AWS IoT 에 등록되고 디바이스 인증을 위해 활성화된 **디바이스 인증서**.

     인증서는 종종 **AWS IoT 사물 객체**와 함께 만들어지고 연결됩니다. 디바이스를 연결하는 데 사물 객체는 필요하지 않지만 디바이스 AWS IoT에서 추가 AWS IoT 기능을 사용할 수 있습니다.
   + 디바이스 인증서에 연결된 **정책**으로,에 연결하고 원하는 모든 작업을 AWS IoT Core 수행할 수 있는 권한을 부여합니다.

1.  AWS 계정의 디바이스 엔드포인트에 액세스할 수 있는 **인터넷 연결**.

   디바이스 엔드포인트는에 설명되어 [AWS IoT 디바이스 데이터 및 서비스 엔드포인트](iot-connect-devices.md#iot-connect-device-endpoints) 있으며 [AWS IoT 콘솔의 설정 페이지에서](https://console.aws.amazon.com/iot/home#/settings) 확인할 수 있습니다.

1.  AWS IoT Device SDK와 같은 **통신 소프트웨어**. 이 자습서에서는 [AWS IoT 디바이스 SDK v2 for Python](https://github.com/aws/aws-iot-device-sdk-python-v2#aws-iot-device-sdk-v2-for-python)을 사용합니다.

## MQTT 프로토콜 검토
<a name="sdk-tutorials-mqtt-review"></a>

샘플 앱에 대해 이야기하기 전에 MQTT 프로토콜을 이해하는 것이 도움이 됩니다. MQTT 프로토콜은 HTTP 등의 다른 네트워크 통신 프로토콜에 비해 몇 가지 이점을 제공하므로 IoT 디바이스에서 널리 사용됩니다. 이 섹션에서는 이 자습서에 적용되는 MQTT의 주요 측면을 검토합니다. MQTTT를 HTTP와 비교하는 방법에 대한 자세한 내용은 [디바이스 통신을 위한 애플리케이션 프로토콜 선택](protocols.md#protocol-selection) 단원을 참조하세요.

**MQTT는 게시/구독 통신 모델을 사용합니다.**  
MQTT 프로토콜은 호스트와 게시/구독 통신 모델을 사용합니다. 이 모델은 HTTP가 사용하는 요청/응답 모델과 다릅니다. MQTT를 사용하면 디바이스가 고유한 클라이언트 ID로 식별되는 호스트와의 세션을 설정합니다. 데이터를 전송하기 위해 디바이스는 주제별로 식별되는 메시지를 호스트의 메시지 브로커에 게시합니다. 메시지 브로커로부터 메시지를 수신하기 위해 디바이스는 구독 요청의 주제 필터를 메시지 브로커에 전송하여 주제를 구독합니다.

**영구 세션을 지원하는 MQTT**  
메시지 브로커는 디바이스에서 메시지를 수신하고 해당 디바이스를 구독한 디바이스에 메시지를 게시합니다. [영구 세션](mqtt.md#mqtt-persistent-sessions)(초기 디바이스의 연결이 끊어진 경우에도 활성 상태로 유지되는 세션)을 사용하면 디바이스는 연결이 끊긴 동안 게시된 메시지를 검색할 수 있습니다. 디바이스 측에서 MQTT는 서비스 품질 수준([QoS](mqtt.md#mqtt-qos))를 사용하여 호스트가 디바이스에서 전송한 메시지를 수신하도록 합니다.

## pubsub.py Device SDK 샘플 앱 검토
<a name="sdk-tutorials-explore-sample"></a>

이 섹션에서는 이 자습서에 사용된 **AWS IoT Device SDK v2 for Python**의 `pubsub.py` 샘플 앱을 검토합니다. 여기서는 MQTT 메시지를 게시하고 구독 AWS IoT Core 하기 위해에 연결하는 방법을 살펴보겠습니다. 다음 섹션에서는 디바이스가 어떻게 연결되고 통신하는지 탐색하는 데 도움이 되는 몇 가지 연습을 제공합니다 AWS IoT Core.

**`pubsub.py` 샘플 앱은 AWS IoT Core MQTT 연결의 다음 측면을 보여줍니다.**
+ [통신 프로토콜](#sdk-tutorials-explore-protocols)
+ [영구 세션](#sdk-tutorials-explore-persistent)
+ [서비스 품질](#sdk-tutorials-explore-qos)
+ [메시지 게시](#sdk-tutorials-explore-publish)
+ [메시지 구독](#sdk-tutorials-explore-subscribe)
+ [디바이스 연결 해제 및 재연결](#sdk-tutorials-explore-connect)

### 통신 프로토콜
<a name="sdk-tutorials-explore-protocols"></a>

`pubsub.py` 샘플에서는 MQTT 및 MQTT over WSS 프로토콜을 사용하는 MQTT 연결을 보여 줍니다. [AWS 공통 런타임(AWS CRT)](https://github.com/awslabs/aws-crt-python#aws-crt-python) 라이브러리는 하위 수준의 통신 프로토콜을 지원하며 Python용 AWS IoT Device SDK v2에 포함되어 있습니다.

#### MQTT
<a name="sdk-tutorials-explore-mqtt"></a>

`pubsub.py` 샘플은 MQTT 프로토콜을 AWS IoT Core 사용하여 와의 연결을 설정[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` (여기에 표시됨)를 호출합니다.는 X.509 인증서 및 TLS v1.2를 `mtls_from_path` 사용하여 디바이스를 인증합니다. 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 디바이스 엔드포인트  
샘플 앱에서 이 값은 명령줄에서 전달됩니다.

`cert_filepath`  
디바이스의 인증서 파일 경로  
샘플 앱에서 이 값은 명령줄에서 전달됩니다.

`pri_key_filepath`  
인증서 파일을 사용하여 만든 디바이스의 개인 키 파일에 대한 경로  
샘플 앱에서 이 값은 명령줄에서 전달됩니다.

`ca_filepath`  
루트 CA 파일의 경로. MQTT 서버가 trust store에 없는 인증서를 사용하는 경우에만 필요합니다.  
샘플 앱에서 이 값은 명령줄에서 전달됩니다.

`client_bootstrap`  
소켓 통신 활동을 처리하는 공통 런타임 객체  
샘플 앱에서 이 객체는 `mqtt_connection_builder.mtls_from_path`를 호출하기 전에 인스턴스화됩니다.

`on_connection_interrupted``on_connection_resumed`  
디바이스의 연결이 중단되고 재개될 때 호출할 콜백 함수

`client_id`  
 AWS 리전에서 이 디바이스를 고유하게 식별하는 ID  
샘플 앱에서 이 값은 명령줄에서 전달됩니다.

`clean_session`  
새 영구 세션을 시작할지, 아니면 존재하는 경우 기존 세션에 다시 연결할지 여부

`keep_alive_secs`  
`CONNECT` 요청을 전송할 연결 유지 값(초)입니다. 이 간격으로 ping이 자동으로 전송됩니다. 이 값의 1.5배 후에도 서버가 ping을 받지 못하면 연결이 끊어진 것으로 간주합니다.

#### MQTT over WSS
<a name="sdk-tutorials-explore-mqtt-wss"></a>

`pubsub.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 와의 연결을 설정합니다. `websockets_with_default_aws_signing`은 디바이스를 인증하기 위해 [Signature V4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html)를 사용하여 WSS를 통한 MQTT 연결을 만듭니다.

```
mqtt_connection = mqtt_connection_builder.websockets_with_default_aws_signing(
    endpoint=args.endpoint,
    client_bootstrap=client_bootstrap,
    region=args.signing_region,
    credentials_provider=credentials_provider,
    websocket_proxy_options=proxy_options,
    ca_filepath=args.ca_file,
    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_bootstrap`  
소켓 통신 활동을 처리하는 공통 런타임 객체  
샘플 앱에서 이 객체는 `mqtt_connection_builder.websockets_with_default_aws_signing`를 호출하기 전에 인스턴스화됩니다.

`region`  
 AWS Signature V4 인증에 사용되는 서명 리전입니다. `pubsub.py`에서 명령줄에 입력된 파라미터를 전달합니다.  
샘플 앱에서 이 값은 명령줄에서 전달됩니다.

`credentials_provider`  
인증에 사용하기 위해 제공된 AWS 자격 증명  
샘플 앱에서 이 객체는 `mqtt_connection_builder.websockets_with_default_aws_signing`을 호출하기 전에 인스턴스화됩니다.

`websocket_proxy_options`  
HTTP 프록시 옵션(프록시 호스트를 사용하는 경우)  
샘플 앱에서 이 값은 `mqtt_connection_builder.websockets_with_default_aws_signing`을 호출하기 전에 초기화됩니다.

`ca_filepath`  
루트 CA 파일의 경로. MQTT 서버가 trust store에 없는 인증서를 사용하는 경우에만 필요합니다.  
샘플 앱에서 이 값은 명령줄에서 전달됩니다.

`on_connection_interrupted``on_connection_resumed`  
디바이스의 연결이 중단되고 재개될 때 호출할 콜백 함수

`client_id`  
 AWS 리전에서 이 디바이스를 고유하게 식별하는 ID.  
샘플 앱에서 이 값은 명령줄에서 전달됩니다.

`clean_session`  
새 영구 세션을 시작할지, 아니면 존재하는 경우 기존 세션에 다시 연결할지 여부

`keep_alive_secs`  
`CONNECT` 요청을 전송할 연결 유지 값(초)입니다. 이 간격으로 ping이 자동으로 전송됩니다. 이 값의 1.5배 후에도 서버가 ping을 받지 못하면 연결이 끊어진 것으로 간주합니다.

#### HTTPS
<a name="sdk-tutorials-explore-https"></a>

HTTPS는 어떤가요?는 HTTPS 요청을 게시하는 디바이스를 AWS IoT Core 지원합니다. 프로그래밍 관점에서 디바이스는 다른 애플리케이션과 마찬가지로 AWS IoT Core 에 HTTPS 요청을 전송합니다. 디바이스에서 HTTP 메시지를 전송하는 Python 프로그램의 예는 Python의 `requests` 라이브러리를 사용하는 [HTTPS 코드 예](http.md#codeexample)를 참조하세요. 이 예제에서는가 메시지를 MQTT 메시지로 해석하도록 AWS IoT Core HTTPS를 AWS IoT Core 사용하여에 메시지를 보냅니다.

는 디바이스의 HTTPS 요청을 AWS IoT Core 지원하지만 디바이스 통신에 사용할 프로토콜을 정보에 입각하여 결정할 수 [디바이스 통신을 위한 애플리케이션 프로토콜 선택](protocols.md#protocol-selection) 있도록에 대한 정보를 검토해야 합니다.

### 영구 세션
<a name="sdk-tutorials-explore-persistent"></a>

샘플 앱에서 `clean_session` 파라미터를 `False`로 설정하면 연결이 지속되어야 함을 나타냅니다. 실제로 이것은 이 호출에 의해 열린 연결이 존재하는 경우 기존 영구 세션에 다시 연결된다는 것을 의미합니다. 그렇지 않으면 새 영구 세션을 만들고 연결합니다.

영구 세션에서는 디바이스가 연결되어 있지 않은 동안 디바이스로 전송되는 메시지가 메시지 브로커에 의해 저장됩니다. 디바이스가 영구 세션에 다시 연결되면 메시지 브로커는 디바이스가 구독한 저장된 메시지를 디바이스에 전송합니다.

영구 세션이 없으면 디바이스가 연결되어 있지 않은 동안 전송된 메시지를 수신하지 않습니다. 사용할 옵션은 애플리케이션에 따라 다르고 디바이스가 연결되지 않은 동안 발생하는 메시지를 전달해야 하는지 여부에 따라 다릅니다. 자세한 내용은 [MQTT 지속적 세션](mqtt.md#mqtt-persistent-sessions) 단원을 참조하세요.

### 서비스 품질
<a name="sdk-tutorials-explore-qos"></a>

디바이스가 메시지를 게시하고 구독하면 선호하는 서비스 품질(QoS)을 설정할 수 있습니다.는 게시 및 구독 작업에 대해 QoS 수준 0 및 1을 AWS IoT 지원합니다. 의 QoS 수준에 대한 자세한 내용은 섹션을 AWS IoT참조하세요[MQTT 서비스 품질(QoS) 옵션](mqtt.md#mqtt-qos).

Python용 AWS CRT 런타임은 지원하는 QoS 수준에 대해 다음 상수를 정의합니다.


**Python 서비스 품질 수준**  

| MQTT QoS 수준 | SDK에서 사용하는 Python 기호 값 | 설명 | 
| --- | --- | --- | 
| QoS 수준 0 | mqtt.QoS.AT\$1MOST\$1ONCE | 수신 여부에 관계없이 메시지 전송을 한 번만 시도합니다. 예를 들어 디바이스가 연결되어 있지 않거나 네트워크 오류가 있는 경우 메시지가 전혀 전송되지 않을 수 있습니다. | 
| QoS 수준 1 | mqtt.QoS.AT\$1LEAST\$1ONCE | 메시지는 PUBACK 승인이 수신될 때까지 반복적으로 전송됩니다. | 

샘플 앱에서 게시 및 구독 요청은 QoS 수준 1(`mqtt.QoS.AT_LEAST_ONCE`)로 수행됩니다.
+ 

**게시 중 QoS**  
디바이스가 QoS 수준 1의 메시지를 게시하면 메시지 브로커로부터 `PUBACK` 응답을 받을 때까지 메시지를 반복해서 전송합니다. 디바이스가 연결되어 있지 않으면 메시지가 다시 연결한 후 전송되도록 대기열에 저장됩니다.
+ 

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

### 메시지 게시
<a name="sdk-tutorials-explore-publish"></a>

연결을 성공적으로 설정하면 AWS IoT Core디바이스가 메시지를 게시할 수 있습니다. `pubsub.py` 샘플은 `mqtt_connection` 객체의 `publish` 작업을 호출하여 이를 수행합니다.

```
mqtt_connection.publish(
    topic=args.topic,
    payload=message,
    qos=mqtt.QoS.AT_LEAST_ONCE
)
```

`topic`  
메시지를 식별하는 메시지의 주제 이름  
샘플 앱에서 이 이름은 명령줄에서 전달됩니다.

`payload`  
문자열로 형식이 지정된 메시지 페이로드(예: JSON 문서)  
샘플 앱에서 이것은 명령줄에서 전달됩니다.  
JSON 문서는 일반적인 페이로드 형식이며 다른 AWS IoT 서비스에서 인식하는 형식이지만 메시지 페이로드의 데이터 형식은 게시자와 구독자가 동의하는 모든 형식일 수 있습니다. 그러나 다른 AWS IoT 서비스는 경우에 따라 대부분의 작업에 대해 JSON 및 CBOR만 인식합니다.

`qos`  
이 메시지의 QoS 수준

### 메시지 구독
<a name="sdk-tutorials-explore-subscribe"></a>

 AWS IoT 및 기타 서비스 및 디바이스에서 메시지를 수신하기 위해 디바이스는 주제 이름으로 해당 메시지를 구독합니다. 디바이스는 [주제 이름](topics.md#topicnames)을 지정하여 개별 메시지를 구독하고 와일드카드 문자를 포함할 수 있는 [주제 필터](topics.md#topicfilters)를 지정하여 메시지 그룹을 구독할 수 있습니다. `pubsub.py` 샘플은 여기에 표시된 코드를 사용하여 메시지를 구독하고 콜백 함수를 등록하여 메시지를 받은 후 처리합니다.

```
subscribe_future, packet_id = mqtt_connection.subscribe(
    topic=args.topic,
    qos=mqtt.QoS.AT_LEAST_ONCE,
    callback=on_message_received
)
subscribe_result = subscribe_future.result()
```

`topic`  
구독할 주제. 주제 이름 또는 주제 필터일 수 있습니다.  
샘플 앱에서 이것은 명령줄에서 전달됩니다.

`qos`  
디바이스 연결이 끊어지는 동안 메시지 브로커가 이러한 메시지를 저장할지 여부입니다.  
값이 `mqtt.QoS.AT_LEAST_ONCE`(QoS 수준 1)이면 연결이 생성될 때 영구 세션을 지정해야 합니다(`clean_session=False`).

`callback`  
구독된 메시지를 처리하기 위해 호출할 함수.

`mqtt_connection.subscribe` 함수는 미래의 패킷과 패킷 ID를 반환합니다. 구독 요청이 성공적으로 시작된 경우 반환된 패킷 ID는 0보다 큽니다. 구독이 메시지 브로커에 의해 수신 및 등록되었는지 확인하려면 코드 예제와 같이 비동기 작업의 결과가 반환될 때까지 기다려야 합니다.

**콜백 함수**  
`pubsub.py` 샘플의 콜백은 디바이스가 수신한 구독 메시지를 처리합니다.

```
def on_message_received(topic, payload, **kwargs):
    print("Received message from topic '{}': {}".format(topic, payload))
    global received_count
    received_count += 1
    if received_count == args.count:
        received_all_event.set()
```

`topic`  
메시지의 주제  
주제 필터를 구독한 경우에도 수신된 메시지의 특정 주제 이름입니다.

`payload`  
메시지 페이로드  
이 형식은 애플리케이션에 따라 다릅니다.

`kwargs`  
[https://awslabs.github.io/aws-crt-python/api/mqtt.html#awscrt.mqtt.Connection.subscribe](https://awslabs.github.io/aws-crt-python/api/mqtt.html#awscrt.mqtt.Connection.subscribe)에 설명된 대로 가능한 추가 인수입니다.

`pubsub.py` 샘플에서 `on_message_received`는 주제와 해당 페이로드만 표시합니다. 또한 한도에 도달한 후 프로그램을 종료하기 위해 수신된 메시지 수를 계산합니다.

앱은 주제 및 페이로드를 평가하여 수행할 작업을 결정합니다.

### 디바이스 연결 해제 및 재연결
<a name="sdk-tutorials-explore-connect"></a>

`pubsub.py` 샘플에는 디바이스의 연결이 끊어지고 연결이 다시 설정될 때 호출되는 콜백 함수가 포함되어 있습니다. 디바이스에서 이러한 이벤트에 대해 수행하는 작업은 애플리케이션에 따라 다릅니다.

디바이스가 처음으로 연결되면 수신할 주제를 구독해야 합니다. 디바이스가 다시 연결될 때 디바이스의 세션이 있으면 구독이 복원되고 해당 구독에서 저장된 메시지가 다시 연결되면 디바이스로 전송됩니다.

디바이스가 다시 연결될 때 디바이스의 세션이 더 이상 존재하지 않으면 구독을 다시 구독해야 합니다. 영구 세션은 수명이 제한되어 있으며 디바이스의 연결이 너무 오래 끊어지면 만료될 수 있습니다.

## 디바이스 연결 및와 통신 AWS IoT Core
<a name="sdk-tutorials-experiment"></a>

이 섹션에서는 디바이스를 AWS IoT Core에 연결하는 다양한 측면을 탐색하는 데 도움이 되는 몇 가지 연습을 제공합니다. 이 연습에서는 AWS IoT 콘솔에서 [MQTT 테스트 클라이언트](https://console.aws.amazon.com/iot/home#/test)를 사용하여 디바이스가 게시하는 내용을 확인하고 디바이스에 메시지를 게시합니다. 이 연습에서는 [AWS IoT Device SDK v2 for Python](https://github.com/aws/aws-iot-device-sdk-python-v2/tree/master/samples#sample-apps-for-the-aws-iot-device-sdk-v2-for-python)의 [https://github.com/aws/aws-iot-device-sdk-python-v2/blob/master/samples/pubsub.py](https://github.com/aws/aws-iot-device-sdk-python-v2/blob/master/samples/pubsub.py) 샘플을 사용하고 [AWS IoT Core 자습서 시작하기](iot-gs.md) 자습서의 경험을 바탕으로 빌드합니다.

**Topics**
+ [와일드카드 주제 필터 구독](#sdk-tutorials-experiment-wild)
+ [주제 필터 구독 처리](#sdk-tutorials-experiment-process)
+ [디바이스에서 메시지 게시](#sdk-tutorials-experiment-publish)

이러한 연습의 경우 먼저 `pubsub.py` 샘플 프로그램에서 시작합니다.

**참고**  
이 연습에서는 [AWS IoT Core 자습서 시작하기](iot-gs.md) 자습서를 완료하고 해당 자습서에서 디바이스의 터미널 창을 사용한다고 가정합니다.

### 와일드카드 주제 필터 구독
<a name="sdk-tutorials-experiment-wild"></a>

이 연습에서는 와일드카드 주제 필터를 구독하고 메시지 주제에 따라 수신된 메시지를 처리하기 위해 `pubsub.py`를 호출하는 데 사용되는 명령줄을 수정합니다.

#### 연습 절차
<a name="sdk-tutorials-experiment-wild-steps"></a>

이 연습에서는 디바이스에 온도 컨트롤과 조명 컨트롤이 있다고 가정합니다. 이러한 주제 이름을 사용하여 해당 주제에 대한 메시지를 식별합니다.

1. 연습을 시작하기 전에 디바이스의 [AWS IoT Core 자습서 시작하기](iot-gs.md) 자습서에서 이 명령을 실행하여 연습에 필요한 모든 것이 준비되었는지 확인하세요.

   ```
   cd ~/aws-iot-device-sdk-python-v2/samples
   python3 pubsub.py --topic topic_1 --ca_file ~/certs/Amazon-root-CA-1.pem --cert ~/certs/device.pem.crt --key ~/certs/private.pem.key --endpoint your-iot-endpoint
   ```

   [시작하기 자습서](connecting-to-existing-device.md#gs-device-node-app-run)에서 본 것과 동일한 출력이 표시되어야 합니다.

1. 이 연습에서는 다음 명령행 파라미터를 변경합니다.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/iot/latest/developerguide/sdk-tutorials.html)

   초기 명령줄을 이렇게 변경하면 이 명령줄이 생성됩니다. 디바이스의 터미널 창에 이 명령을 입력합니다.

   ```
   python3 pubsub.py --message "" --count 2 --topic device/+/details --ca_file ~/certs/Amazon-root-CA-1.pem --cert ~/certs/device.pem.crt --key ~/certs/private.pem.key --endpoint your-iot-endpoint
   ```

   프로그램은 다음과 같이 표시되어야 합니다.

   ```
   Connecting to a3qexamplesffp-ats.iot.us-west-2.amazonaws.com with client ID 'test-24d7cdcc-cc01-458c-8488-2d05849691e1'...
   Connected!
   Subscribing to topic 'device/+/details'...
   Subscribed with QoS.AT_LEAST_ONCE
   Waiting for all messages to be received...
   ```

   터미널에 이와 같은 항목이 표시되면 디바이스가 준비되고 주제 이름이 `device`(으)로 시작하고 `/detail`(으)로 끝나는 메시지를 수신 대기 중인 것입니다. 그럼 테스트해 보겠습니다.

1. 다음은 디바이스에서 수신할 수 있는 몇 가지 메시지입니다.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/iot/latest/developerguide/sdk-tutorials.html)

1.  AWS IoT 콘솔에서 MQTT 테스트 클라이언트를 사용하여 이전 단계에서 설명한 메시지를 디바이스로 전송합니다.

   1.  AWS IoT 콘솔에서 [MQTT 테스트 클라이언트](https://console.aws.amazon.com/iot/home#/test)를 엽니다.

   1. **주제 구독(Subscribe to a topic)**의 **Subscription topic field(구독 주제 필드)**에 주제 필터 **device/\$1/details**를 입력한 다음 **주제 구독(Subscribe to topic)**을 선택합니다.

   1. MQTT 테스트 클라이언트의 **구독(Subscriptions)** 열에서 **device/\$1/details**를 선택합니다.

   1. 앞의 표에 있는 각 주제에 대해 MQTT 테스트 클라이언트에서 다음을 수행합니다.

      1. **게시(Publish)**에서 테이블의 **주제 이름(Topic name)** 열에 있는 값을 입력합니다.

      1. 주제 이름 아래의 메시지 페이로드 필드에 테이블의 **메시지 페이로드(Message payload)** 열에 있는 값을 입력합니다.

      1. `pubsub.py`가 실행 중인 터미널 창을 살펴보고 MQTT 테스트 클라이언트에서 **주제에 게시(Publish to topic)**를 선택합니다.

      터미널 창에서 `pubsub.py`가 메시지를 수신했음을 확인해야 합니다.

#### 연습 결과
<a name="sdk-tutorials-experiment-wild-result"></a>

`pubsub.py`를 통해 와일드카드 주제 필터를 사용하여 메시지를 구독하고 수신하여 터미널 창에 표시했습니다. 단일 주제 필터를 구독하고 두 개의 개별 주제가 있는 메시지를 처리하기 위해 콜백 함수가 호출된 방법에 주목하세요.

### 주제 필터 구독 처리
<a name="sdk-tutorials-experiment-process"></a>

이전 연습을 기반으로 `pubsub.py` 샘플 앱을 수정하여 메시지 주제를 평가하고 주제를 기반으로 구독된 메시지를 처리합니다.

#### 연습 절차
<a name="sdk-tutorials-experiment-process-steps"></a>

**메시지 주제를 평가하려면**

1. `pubsub.py`를 `pubsub2.py`에 복사합니다.

1. 즐겨 사용하는 텍스트 편집기나 IDE에서 `pubsub2.py`를 엽니다.

1. `pubsub2.py`에서 `on_message_received` 함수를 찾습니다.

1. `on_message_received`에서 `print("Received message`로 시작하는 줄 뒤와 `global received_count`로 시작하는 줄 앞에 다음 코드를 삽입합니다.

   ```
       topic_parsed = False
       if "/" in topic:
           parsed_topic = topic.split("/")
           if len(parsed_topic) == 3:
               # this topic has the correct format
               if (parsed_topic[0] == 'device') and (parsed_topic[2] == 'details'):
                   # this is a topic we care about, so check the 2nd element
                   if (parsed_topic[1] == 'temp'):
                       print("Received temperature request: {}".format(payload))
                       topic_parsed = True
                   if (parsed_topic[1] == 'light'):
                       print("Received light request: {}".format(payload))
                       topic_parsed = True
       if not topic_parsed:
           print("Unrecognized message topic.")
   ```

1. 변경 사항을 저장하고 이 명령줄을 사용하여 수정된 프로그램을 실행합니다.

   ```
   python3 pubsub2.py --message "" --count 2 --topic device/+/details --ca_file ~/certs/Amazon-root-CA-1.pem --cert ~/certs/device.pem.crt --key ~/certs/private.pem.key --endpoint your-iot-endpoint
   ```

1.  AWS IoT 콘솔에서 [MQTT 테스트 클라이언트](https://console.aws.amazon.com/iot/home#/test)를 엽니다.

1. **주제 구독(Subscribe to a topic)**의 **Subscription topic field(구독 주제 필드)**에 주제 필터 **device/\$1/details**를 입력한 다음 **주제 구독(Subscribe to topic)**을 선택합니다.

1. MQTT 테스트 클라이언트의 **구독(Subscriptions)** 열에서 **device/\$1/details**를 선택합니다.

1. 이 표에 있는 각 주제에 대해 MQTT 테스트 클라이언트에서 다음을 수행합니다.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/iot/latest/developerguide/sdk-tutorials.html)

   1. **게시(Publish)**에서 테이블의 **주제 이름(Topic name)** 열에 있는 값을 입력합니다.

   1. 주제 이름 아래의 메시지 페이로드 필드에 테이블의 **메시지 페이로드(Message payload)** 열에 있는 값을 입력합니다.

   1. `pubsub.py`가 실행 중인 터미널 창을 살펴보고 MQTT 테스트 클라이언트에서 **주제에 게시(Publish to topic)**를 선택합니다.

   터미널 창에서 `pubsub.py`가 메시지를 수신했음을 확인해야 합니다.

터미널 창에서 이와 유사한 결과가 나타날 것입니다.

```
Connecting to a3qexamplesffp-ats.iot.us-west-2.amazonaws.com with client ID 'test-af794be0-7542-45a0-b0af-0b0ea7474517'...
Connected!
Subscribing to topic 'device/+/details'...
Subscribed with QoS.AT_LEAST_ONCE
Waiting for all messages to be received...
Received message from topic 'device/light/details': b'{ "desiredLight": 100, "currentLight": 50 }'
Received light request: b'{ "desiredLight": 100, "currentLight": 50 }'
Received message from topic 'device/temp/details': b'{ "desiredTemp": 20, "currentTemp": 15 }'
Received temperature request: b'{ "desiredTemp": 20, "currentTemp": 15 }'
2 message(s) received.
Disconnecting...
Disconnected!
```

#### 연습 결과
<a name="sdk-tutorials-experiment-process-result"></a>

이 연습에서는 샘플 앱이 콜백 함수에서 여러 메시지를 인식하고 처리할 수 있도록 코드를 추가했습니다. 이를 통해 디바이스가 메시지를 수신하고 이에 대한 조치를 취할 수 있습니다.

디바이스에서 여러 메시지를 수신하고 처리하는 또 다른 방법은 서로 다른 메시지를 별도로 구독하고 각 구독을 자체 콜백 함수에 할당하는 것입니다.

### 디바이스에서 메시지 게시
<a name="sdk-tutorials-experiment-publish"></a>

pubsub.py 샘플 앱을 사용하여 디바이스에서 메시지를 게시할 수 있습니다. 메시지를 그대로 게시하지만 메시지를 JSON 문서로 읽을 수 없습니다. 이 연습에서는 읽을 수 있는 메시지 페이로드에 JSON 문서를 게시할 수 있도록 샘플 앱을 수정합니다 AWS IoT Core.

#### 연습 절차
<a name="sdk-tutorials-experiment-publish-steps"></a>

이 연습에서는 `device/data` 주제와 함께 다음 메시지가 전송됩니다.

```
{
    "timestamp": 1601048303,
    "sensorId": 28,
    "sensorData": [
        {
        "sensorName": "Wind speed",
        "sensorValue": 34.2211224
        }
    ]
}
```

**이 연습에서 발생한 메시지를 모니터링하기 위해 MQTT 테스트 클라이언트를 준비하려면**

1. **주제 구독(Subscribe to a topic)**의 **Subscription topic field(구독 주제 필드)**에 주제 필터 **device/data**를 입력한 다음 **주제 구독(Subscribe to topic)**을 선택합니다.

1. MQTT 테스트 클라이언트의 **구독(Subscriptions)** 열에서 **device/data**를 선택합니다.

1. MQTT 테스트 클라이언트 창을 열어 두고 디바이스의 메시지를 기다립니다.

**pubsub.py 샘플 앱을 사용하여 JSON 문서를 전송하려면**

1. 디바이스에서 `pubsub.py`를 `pubsub3.py`로 복사합니다.

1. 게시하는 메시지의 형식을 변경하도록 `pubsub3.py`를 편집합니다.

   1. 텍스트 편집기에서 `pubsub3.py`을(를) 엽니다.

   1. 다음 코드 행을 찾습니다.

      `message = "{} [{}]".format(message_string, publish_count)`

   1. 다음과 같이 변경하세요.

      `message = "{}".format(message_string)`

   1. 다음 코드 행을 찾습니다.

      `message_json = json.dumps(message)`

   1. 다음과 같이 변경하세요.

      `message = "{}".json.dumps(json.loads(message))`

   1. 변경 내용을 저장합니다.

1. 디바이스에서 이 명령을 실행하여 메시지를 두 번 전송합니다.

   ```
   python3 pubsub3.py  --ca_file ~/certs/Amazon-root-CA-1.pem  --cert ~/certs/device.pem.crt  --key ~/certs/private.pem.key  --topic device/data  --count 2 --message '{"timestamp":1601048303,"sensorId":28,"sensorData":[{"sensorName":"Wind speed","sensorValue":34.2211224}]}'  --endpoint your-iot-endpoint
   ```

1. MQTT 테스트 클라이언트에서 다음과 같이 메시지 페이로드에서 JSON 문서를 해석하고 형식을 지정했는지 확인합니다.  
![\[AWS IoT 콘솔의 MQTT 클라이언트에 JSON 메시지 페이로드가 표시되는 방법을 보여주는 이미지입니다.\]](http://docs.aws.amazon.com/ko_kr/iot/latest/developerguide/images/mqtt-test-client-output.png)

기본적으로 `pubsub3.py`는 전송하는 메시지도 구독합니다. 앱의 출력에서 메시지를 수신한 것을 볼 수 있습니다. 터미널 창은 다음과 유사해야 합니다.

```
Connecting to a3qEXAMPLEsffp-ats.iot.us-west-2.amazonaws.com with client ID 'test-5cff18ae-1e92-4c38-a9d4-7b9771afc52f'...
Connected!
Subscribing to topic 'device/data'...
Subscribed with QoS.AT_LEAST_ONCE
Sending 2 message(s)
Publishing message to topic 'device/data': {"timestamp":1601048303,"sensorId":28,"sensorData":[{"sensorName":"Wind speed","sensorValue":34.2211224}]}
Received message from topic 'device/data': b'{"timestamp":1601048303,"sensorId":28,"sensorData":[{"sensorName":"Wind speed","sensorValue":34.2211224}]}'
Publishing message to topic 'device/data': {"timestamp":1601048303,"sensorId":28,"sensorData":[{"sensorName":"Wind speed","sensorValue":34.2211224}]}
Received message from topic 'device/data': b'{"timestamp":1601048303,"sensorId":28,"sensorData":[{"sensorName":"Wind speed","sensorValue":34.2211224}]}'
2 message(s) received.
Disconnecting...
Disconnected!
```

#### 연습 결과
<a name="sdk-tutorials-experiment-publish-result"></a>

이를 통해 디바이스는에 보낼 메시지를 생성 AWS IoT Core 하여 기본 연결을 테스트하고가 처리할 디바이스 메시지를 제공할 수 AWS IoT Core 있습니다. 예를 들어이 앱을 사용하여 디바이스에서 테스트 데이터를 전송하여 AWS IoT 규칙 작업을 테스트할 수 있습니다.

## 결과 검토
<a name="sdk-tutorials-conclusion"></a>

이 자습서의 예제는 디바이스가 AWS IoT 솔루션의 기본 부분 AWS IoT Core인와 통신하는 방법의 기본 사항에 대한 실습 경험을 제공합니다. 디바이스와 통신할 수 있는 경우 서비스 및 디바이스가 AWS 작동할 AWS IoT Core수 있는 다른 디바이스에 메시지를 전달할 수 있습니다. 마찬가지로 AWS 서비스 및 기타 디바이스는 디바이스로 다시 전송되는 메시지를 생성하는 정보를 처리할 수 있습니다.

 AWS IoT Core 더 자세히 살펴볼 준비가 되면 다음 자습서를 시도해 보세요.
+ [자습서: Amazon SNS 알림 전송](iot-sns-rule.md)
+ [자습서: DynamoDB 테이블에 디바이스 데이터 저장](iot-ddb-rule.md)
+ [자습서: AWS Lambda 함수를 사용하여 알림 형식 지정](iot-lambda-rule.md)

# 자습서: AWS IoT Device SDK for Embedded C 사용
<a name="iot-embedded-c-sdk"></a>

이 섹션에서는 AWS IoT Device SDK for Embedded C를 실행하는 방법에 대해 설명합니다.

**Topics**
+ [1단계: AWS IoT Device SDK for Embedded C 설치](#install-embedded-c-sdk)
+ [2단계: 샘플 앱 구성](#iot-c-sdk-app-config)
+ [3단계: 샘플 애플리케이션 빌드 및 실행](#iot-c-sdk-app-run)

## 1단계: AWS IoT Device SDK for Embedded C 설치
<a name="install-embedded-c-sdk"></a>

AWS IoT Device SDK for Embedded C는 일반적으로 최적화된 C 언어 런타임을 필요로 하는 리소스 제약 디바이스를 대상으로 합니다. 모든 운영 체제에서 SDK를 사용하고, 모든 프로세서 유형(예: MCU 및 MPU)에서 호스팅할 수 있습니다. 더 많은 메모리 및 처리 리소스를 사용할 수 있는 경우, 상위 순위의 AWS IoT 디바이스 및 모바일 SDK(예: C\$1\$1, Java, JavaScript 및 Python) 중 하나를 사용하도록 하세요.

일반적으로 AWS IoT Device SDK for Embedded C는 임베디드 운영 체제를 실행하는 MCU 또는 저사양의 MPU를 사용하는 시스템용입니다. 이 섹션의 프로그래밍 예제에서는 디바이스가 Linux를 사용한다고 가정합니다.

**Example**  

1. [GitHub](https://github.com/aws/aws-iot-device-sdk-embedded-C)에서 AWS IoT Device SDK for Embedded C를 디바이스로 다운로드하세요.

   ```
   git clone https://github.com/aws/aws-iot-device-sdk-embedded-c.git --recurse-submodules
   ```

   그러면 현재 디렉토리에 `aws-iot-device-sdk-embedded-c`라는 디렉터리가 생성됩니다.

1. 해당 디렉터리로 이동하여 최신 릴리스를 체크아웃합니다. 최신 릴리스 태그는 [github.com/aws/aws-iot-device-sdk-embedded-C/tags](https://github.com/aws/aws-iot-device-sdk-embedded-C/tags)를 참조하세요.

   ```
   cd aws-iot-device-sdk-embedded-c
   git checkout latest-release-tag
   ```

1. OpenSSL 버전 1.1.0 이상을 설치합니다. OpenSSL 개발 라이브러리는 패키지 관리자를 통해 설치될 때 일반적으로 ‘libssl-dev’ 또는 ‘openssl-devel’이라고 합니다.

   ```
   sudo apt-get install libssl-dev
   ```

## 2단계: 샘플 앱 구성
<a name="iot-c-sdk-app-config"></a>

AWS IoT Device SDK for Embedded C에는 사용자가 시도할 수 있는 샘플 애플리케이션이 포함되어 있습니다. 간단한 설명을 위해 이 자습서에서는 `mqtt_demo_mutual_auth` 애플리케이션을 사용합니다. 이 애플리케이션은 AWS IoT Core 메시지 브로커에 연결하여 MQTT 주제를 구독하고 게시하는 방법을 보여줍니다.

1. [AWS IoT Core 자습서 시작하기](iot-gs.md)에서 만든 인증서와 개인 키를 `build/bin/certificates` 디렉터리에 복사합니다.
**참고**  
디바이스 및 루트 CA 인증서는 만료 또는 취소될 수 있습니다. 인증서가 만료되거나 취소되면 새 CA 인증서 또는 프라이빗 키와 디바이스 인증서를 디바이스에 복사해야 합니다.

1. 개인 AWS IoT Core 엔드포인트, 프라이빗 키, 인증서 및 루트 CA 인증서를 사용하여 샘플을 구성해야 합니다. `aws-iot-device-sdk-embedded-c/demos/mqtt/mqtt_demo_mutual_auth` 디렉터리로 이동합니다.

   AWS CLI를 설치한 경우 이 명령을 사용하여 계정의 엔드포인트 URL을 찾을 수 있습니다.

   ```
   aws iot describe-endpoint --endpoint-type iot:Data-ATS
   ```

   AWS CLI를 설치하지 않은 경우 [AWS IoT 콘솔](https://console.aws.amazon.com/iot/home)을 엽니다. 탐색 창에서 **Manage(관리)**를 선택한 다음 **Things(사물)**를 선택합니다. 디바이스에서 IoT 사물을 선택한 다음 **상호 작용(Interact)**을 선택합니다. 사물 세부 정보 페이지의 **HTTPS** 섹션에 엔드포인트가 표시됩니다.

1. `demo_config.h` 파일을 열어 다음의 값을 업데이트합니다.  
AWS\$1IOT\$1ENDPOINT  
개인 엔드포인트입니다.  
CLIENT\$1CERT\$1PATH  
인증서 파일 경로(예: `certificates/device.pem.crt"`)입니다.  
CLIENT\$1PRIVATE\$1KEY\$1PATH  
프라이빗 키 파일 이름(예: `certificates/private.pem.key`)입니다.

   다음 예를 참조하세요.

   ```
   // Get from demo_config.h
   // =================================================
   #define AWS_IOT_ENDPOINT               "my-endpoint-ats.iot.us-east-1.amazonaws.com"
   #define AWS_MQTT_PORT                  8883
   #define CLIENT_IDENTIFIER              "testclient"
   #define ROOT_CA_CERT_PATH              "certificates/AmazonRootCA1.crt"
   #define CLIENT_CERT_PATH               "certificates/my-device-cert.pem.crt"
   #define CLIENT_PRIVATE_KEY_PATH        "certificates/my-device-private-key.pem.key"
   // =================================================
   ```

1. 이 명령을 사용하여 디바이스에 CMake가 설치되어 있는지 확인하세요.

   ```
   cmake --version
   ```

   컴파일러에 대한 버전 정보가 표시되면 다음 섹션을 계속 진행할 수 있습니다.

   오류가 발생하거나 정보가 표시되지 않는 경우 이 명령을 사용하여 cmake 패키지를 설치해야 합니다.

   ```
   sudo apt-get install cmake
   ```

   **cmake --version** 명령을 다시 실행하고 CMake가 설치되었으며 계속할 준비가 되었는지 확인합니다.

1. 이 명령을 사용하여 디바이스에 개발 도구가 설치되어 있는지 확인하세요.

   ```
   gcc --version
   ```

   컴파일러에 대한 버전 정보가 표시되면 다음 섹션을 계속 진행할 수 있습니다.

   오류가 발생하거나 컴파일러 정보가 표시되지 않는 경우 이 명령을 사용하여 `build-essential` 패키지를 설치해야 합니다.

   ```
   sudo apt-get install build-essential
   ```

   **gcc --version** 명령을 다시 실행하고 빌드 도구가 설치되었으며 계속할 준비가 되었는지 확인합니다.

## 3단계: 샘플 애플리케이션 빌드 및 실행
<a name="iot-c-sdk-app-run"></a>

이 절차에서는 디바이스에서 `mqtt_demo_mutual_auth` 애플리케이션을 생성하고 AWS IoT Device SDK for Embedded C를 사용하여 [AWS IoT 콘솔](https://console.aws.amazon.com/iot/home)에 연결하는 방법을 설명합니다.

**AWS IoT Device SDK for Embedded C 샘플 애플리케이션을 실행하려면**

1. `aws-iot-device-sdk-embedded-c`로 이동하여 빌드 디렉터리를 생성합니다.

   ```
   mkdir build && cd build
   ```

1. 다음 CMake 명령을 입력하여 빌드에 필요한 Makefile을 생성합니다.

   ```
   cmake ..  
   ```

1. 다음 명령어를 입력하여 실행 가능한 앱 파일을 빌드합니다.

   ```
   make
   ```

1. 이 명령으로 `mqtt_demo_mutual_auth` 앱을 실행합니다.

   ```
   cd bin
   ./mqtt_demo_mutual_auth
   ```

   다음과 유사한 출력 화면이 표시되어야 합니다.  
![\[AWS IoT Device SDK for Embedded C 샘플 애플리케이션을 실행하기 위한 명령줄 출력입니다.\]](http://docs.aws.amazon.com/ko_kr/iot/latest/developerguide/images/successful-run2.png)

이제 디바이스가 AWS IoT Device SDK for Embedded C를 사용하여 AWS IoT에 연결되었습니다.

AWS IoT 콘솔을 사용하여 샘플 앱이 게시하는 MQTT 메시지를 확인할 수도 있습니다. [AWS IoT 콘솔](https://console.aws.amazon.com/iot/home)에서 MQTT 클라이언트를 사용하는 방법에 대한 내용은 [MQTT 클라이언트를 사용하여 AWS IoT MQTT 메시지 보기](view-mqtt-messages.md) 단원을 참조하세요.

# 디바이스 데이터를 다른 서비스로 라우팅하는 AWS IoT 규칙 생성
<a name="iot-rules-tutorial"></a>

이 자습서에서는 보다 일반적인 AWS IoT 규칙 작업 중 일부를 사용하여 규칙을 생성하고 테스트하는 방법을 보여줍니다.

AWS IoT 규칙은 디바이스에서 다른 AWS 서비스로 데이터를 전송합니다. 이들은 특정 MQTT 메시지를 수신하고, 메시지 페이로드의 데이터를 형식화한 다음 결과를 다른 AWS 서비스로 전송합니다.

Lambda 함수 또는 더 복잡한 규칙을 사용하는 규칙을 만드는 것이 목표인 경우에도 여기에 표시된 순서대로 시도해 보는 것이 좋습니다. 자습서는 기본적인 것부터 복잡한 것의 순서로 제공됩니다. 새로운 개념을 점진적으로 제시하여 특정 자습서가 없는 규칙 작업을 만드는 데 사용할 수 있는 개념을 익힐 수 있습니다.

**참고**  
AWS IoT 규칙은 IoT 디바이스에서 다른 AWS 서비스로 데이터를 전송하는 데 도움이 됩니다. 그러나 이를 성공적으로 수행하려면 데이터를 전송하려는 다른 서비스에 대한 실무 지식이 필요합니다. 이 자습서에서는 작업을 완료하는 데 필요한 정보를 제공하지만 솔루션에서 데이터를 사용하기 전에 데이터를 전송할 서비스에 대해 자세히 알아보는 것이 도움이 될 수 있습니다. 다른 AWS 서비스에 대한 자세한 설명은이 자습서의 범위를 벗어납니다.

**자습서 시나리오 개요**  
이 자습서의 시나리오는 주기적으로 데이터를 게시하는 기상 센서 디바이스의 시나리오입니다. 이 가상 시스템에는 많은 센서 디바이스가 있습니다. 그러나 이 섹션의 자습서에서는 단일 디바이스에 초점을 맞추면서 여러 센서를 수용할 수 있는 방법을 보여 줍니다.

이 섹션의 자습서에서는 AWS IoT 규칙을 사용하여이 가상 기상 센서 디바이스 시스템으로 다음 작업을 수행하는 방법을 보여줍니다.
+ 

**[자습서: MQTT 메시지 재게시](iot-repub-rule.md)**  
이 자습서에서는 기상 센서에서 받은 MQTT 메시지를 센서 ID와 온도 값만 포함하는 메시지로 다시 게시하는 방법을 보여 줍니다. AWS IoT Core 서비스만 사용하고 간단한 SQL 쿼리와 MQTT 클라이언트를 사용하여 규칙을 테스트하는 방법을 보여줍니다.
+ 

**[자습서: Amazon SNS 알림 전송](iot-sns-rule.md)**  
이 자습서에서는 기상 센서 디바이스의 값이 특정 값을 초과할 때 SNS 메시지를 전송하는 방법을 보여 줍니다. 이전 자습서에 제시된 개념을 기반으로 하며 다른 AWS 서비스인 [Amazon Simple Notification Service](https://docs.aws.amazon.com//sns/latest/dg/welcome.html)(Amazon SNS)로 작업하는 방법을 추가합니다.

  Amazon SNS를 처음 사용한다면 이 자습서를 시작하기 전에 [시작하기](https://docs.aws.amazon.com//sns/latest/dg/sns-getting-started.html) 연습을 검토합니다.
+ 

**[자습서: DynamoDB 테이블에 디바이스 데이터 저장](iot-ddb-rule.md)**  
이 자습서에서는 기상 센서 디바이스의 데이터를 데이터베이스 테이블에 저장하는 방법을 보여 줍니다. 규칙 쿼리 문과 대체 템플릿을 사용하여 대상 서비스에 대한 [Amazon DynamoDB](https://docs.aws.amazon.com//amazondynamodb/latest/developerguide/Introduction.html) 메시지 데이터 형식을 지정합니다.

  DynamoDB를 처음 사용한다면 이 자습서를 시작하기 전에 [시작하기](https://docs.aws.amazon.com//amazondynamodb/latest/developerguide/GettingStartedDynamoDB.html) 연습을 검토합니다.
+ 

**[자습서: AWS Lambda 함수를 사용하여 알림 형식 지정](iot-lambda-rule.md)**  
이 자습서에서는 Lambda 함수를 호출하여 디바이스 데이터를 다시 형식 지정한 다음 문자 메시지로 전송하는 방법을 보여 줍니다. [AWS Lambda](https://docs.aws.amazon.com//lambda/latest/dg/welcome.html) 함수에 Python 스크립트 및 AWS SDK 함수를 추가하여 날씨 센서 디바이스의 메시지 페이로드 데이터로 형식을 지정하고 문자 메시지를 전송합니다.

  Lambda를 처음 사용한다면 이 자습서를 시작하기 전에 [시작하기](https://docs.aws.amazon.com//lambda/latest/dg/getting-started.html) 연습을 검토합니다.

**AWS IoT 규칙 개요**  
이러한 모든 자습서가 AWS IoT 규칙을 생성합니다.

디바이스에서 다른 AWS 서비스로 데이터를 전송하는 AWS IoT 규칙의 경우 다음을 사용합니다.


+ 다음으로 구성된 규칙 쿼리 문입니다.
  + 메시지 페이로드에서 데이터를 선택하고 형식을 지정하는 SQL SELECT 절
  + 사용할 메시지를 식별하는 주제 필터(규칙 쿼리 문의 FROM 객체)
  + 작동할 조건을 지정하는 선택적 조건문(SQL WHERE 절)
+ 하나 이상의 규칙 작업

디바이스는 MQTT 주제에 메시지를 게시합니다. SQL SELECT 문의 주제 필터는 규칙을 적용할 MQTT 주제를 식별합니다. SQL SELECT 문에 지정된 필드는 규칙 작업에 사용할 수신 MQTT 메시지 페이로드의 데이터 형식을 지정합니다. 규칙 작업의 전체 목록은 [AWS IoT 규칙 작업](iot-rule-actions.md) 단원을 참조하세요.

**Topics**
+ [자습서: MQTT 메시지 재게시](iot-repub-rule.md)
+ [자습서: Amazon SNS 알림 전송](iot-sns-rule.md)
+ [자습서: DynamoDB 테이블에 디바이스 데이터 저장](iot-ddb-rule.md)
+ [자습서: AWS Lambda 함수를 사용하여 알림 형식 지정](iot-lambda-rule.md)

# 자습서: MQTT 메시지 재게시
<a name="iot-repub-rule"></a>

이 자습서에서는 지정된 MQTT 메시지가 수신될 때 MQTT 메시지를 게시하는 AWS IoT 규칙을 생성하는 방법을 보여줍니다. 수신 메시지 페이로드는 게시되기 전에 규칙에 의해 수정될 수 있습니다. 이를 통해 디바이스나 펌웨어를 변경할 필요 없이 특정 애플리케이션에 맞는 메시지를 생성할 수 있습니다. 규칙의 필터링 측면을 사용하여 특정 조건이 충족되는 경우에만 메시지를 게시할 수도 있습니다.

규칙에 의해 다시 게시된 메시지는 다른 AWS IoT 디바이스 또는 클라이언트에서 보낸 메시지처럼 작동합니다. 디바이스는 다른 MQTT 메시지 주제를 구독할 수 있는 것과 동일한 방식으로 다시 게시된 메시지를 구독할 수 있습니다.

**이 자습서에서 배울 내용:**
+ 규칙 쿼리 문에서 간단한 SQL 쿼리 및 함수를 사용하는 방법
+ MQTT 클라이언트를 사용하여 AWS IoT 규칙을 테스트하는 방법

이 자습서는 완료하는 데 약 30분 걸립니다.

**Topics**
+ [MQTT 주제 및 AWS IoT 규칙 검토](#iot-repub-rule-mqtt)
+ [1단계: MQTT 메시지를 다시 게시하는 AWS IoT 규칙 생성](#iot-repub-rule-define)
+ [2단계: 새 규칙 테스트](#iot-repub-rule-test)
+ [3단계: 결과 및 다음 단계 검토](#iot-repub-rule-review)

**이 자습서를 시작하기 전에 다음 사항을 확인해야 합니다.**
+ 

**[설정 AWS 계정](setting-up.md)**  
이 자습서를 완료하려면 AWS 계정 및 AWS IoT 콘솔이 필요합니다.
+ 

**검토된 [MQTT 클라이언트를 사용하여 AWS IoT MQTT 메시지 보기](view-mqtt-messages.md)**  
MQTT 클라이언트를 사용하여 주제를 구독하고 게시할 수 있는지 확인하세요. 이 절차에서는 MQTT 클라이언트를 사용하여 새 규칙을 테스트합니다.

## MQTT 주제 및 AWS IoT 규칙 검토
<a name="iot-repub-rule-mqtt"></a>

 AWS IoT 규칙에 대해 설명하기 전에 MQTT 프로토콜을 이해하는 데 도움이 됩니다. IoT 솔루션에서 MQTT 프로토콜은 HTTP와 같은 다른 네트워크 통신 프로토콜에 비해 몇 가지 이점을 제공하므로 IoT 디바이스에서 널리 사용됩니다. 이 섹션에서는 이 자습서에 적용되는 MQTT의 주요 측면을 검토합니다. MQTTT를 HTTP와 비교하는 방법에 대한 자세한 내용은 [디바이스 통신을 위한 애플리케이션 프로토콜 선택](protocols.md#protocol-selection) 단원을 참조하세요.

**MQTT 프로토콜**  
MQTT 프로토콜은 호스트와 게시/구독 통신 모델을 사용합니다. 데이터를 전송하기 위해 디바이스는 주제로 식별되는 메시지를 AWS IoT 메시지 브로커에 게시합니다. 메시지 브로커로부터 메시지를 수신하기 위해 디바이스는 구독 요청의 주제 필터를 메시지 브로커에 전송하여 수신할 주제를 구독합니다. AWS IoT 규칙 엔진은 메시지 브로커에서 MQTT 메시지를 수신합니다.

**AWS IoT 규칙**  
AWS IoT 규칙은 규칙 쿼리 문과 하나 이상의 규칙 작업으로 구성됩니다. AWS IoT 규칙 엔진이 MQTT 메시지를 수신하면 이러한 요소는 다음과 같이 메시지에 작동합니다.
+ 

**규칙 쿼리 문**  
규칙의 쿼리 문은 사용할 MQTT 주제를 설명하고, 메시지 페이로드의 데이터를 해석하며, 널리 사용되는 SQL 데이터베이스에서 사용하는 문과 유사한 SQL 문에 설명된 대로 데이터의 형식을 지정합니다. 쿼리 문의 결과는 규칙의 작업으로 전송되는 데이터입니다.
+ 

**규칙 작업**  
규칙의 각 규칙 작업은 규칙의 쿼리 문에서 발생하는 데이터에 적용됩니다.는 [많은 규칙 작업을](iot-rule-actions.md) AWS IoT 지원합니다. 그러나 이 자습서에서는 쿼리 문의 결과를 특정 주제가 포함된 MQTT 메시지로 게시하는 [재게시](republish-rule-action.md) 규칙 작업에 집중할 것입니다.

## 1단계: MQTT 메시지를 다시 게시하는 AWS IoT 규칙 생성
<a name="iot-repub-rule-define"></a>

이 자습서에서 생성할 AWS IoT 규칙은 *device\$1id*가 메시지를 전송한 디바이스의 ID인 `device/device_id/data` MQTT 주제를 구독합니다. 이러한 주제는 [주제 필터](topics.md#topicfilters)에 의해 `device/+/data`로 설명됩니다. 여기서 `+`는 두 개의 슬래시 문자 사이의 모든 문자열과 일치하는 와일드카드 문자입니다.

규칙은 일치하는 주제에서 메시지를 수신하면 `device_id` 및 `temperature` 값을 `device/data/temp` 주제가 있는 새 MQTT 메시지로 다시 게시합니다.

예를 들어, `device/22/data` 주제가 있는 MQTT 메시지의 페이로드는 다음과 같습니다.

```
{
  "temperature": 28,
  "humidity": 80,
  "barometer": 1013,
  "wind": {
    "velocity": 22,
    "bearing": 255
  }
}
```

규칙은 메시지 페이로드에서 `temperature` 값을 가져오고 주제에서 `device_id`를 가져와 다음과 같은 `device/data/temp` 주제 및 메시지 페이로드가 있는 MQTT 메시지로 다시 게시합니다.

```
{
  "device_id": "22",
  "temperature": 28
}
```

이 규칙을 사용할 경우 디바이스의 ID와 온도 데이터만 필요한 디바이스는 해당 정보만 수신하기 위해 `device/data/temp` 주제를 구독합니다.

**MQTT 메시지를 다시 게시하는 규칙을 생성하려면**

1. [AWS IoT 콘솔의 **규칙** 허브를](https://console.aws.amazon.com//iot/home#/rulehub) 엽니다.

1. **규칙**에서 **생성**을 선택하고 새 규칙 생성을 시작합니다.

1. **규칙 생성**의 상단 부분에서:

   1. **이름**에 규칙 이름을 입력합니다. 본 자습서에서는 이름을 **republish\$1temp**로 지정합니다.

      규칙 이름은 계정 및 지역 내에서 고유해야 하며 공백을 포함할 수 없습니다. 이 이름에 밑줄 문자를 사용하여 규칙 이름의 두 단어를 구분했습니다.

   1.  **설명**에서 규칙을 설명합니다.

      의미 있는 설명은 이 규칙이 수행하는 작업과 규칙을 생성한 이유를 기억하는 데 도움이 됩니다. 설명은 필요한 만큼 길어질 수 있으므로 가능한 한 자세하게 설명하세요.

1. **규칙 생성**의 **규칙 쿼리 문**에서:

   1.  **SQL 버전 사용**에서 **2016-03-23**을(를) 선택합니다.

   1. **규칙 쿼리 문** 편집 상자에 쿼리 문을 입력합니다.

      ```
      SELECT topic(2) as device_id, temperature FROM 'device/+/data'
      ```

      이 문은 다음을 수행합니다.
      + `device/+/data` 주제 필터와 일치하는 주제가 있는 MQTT 메시지를 수신합니다.
      + 주제 문자열에서 두 번째 요소를 선택하여 `device_id` 필드에 할당합니다.
      + 메시지 페이로드에서 `temperature` 값 필드를 선택하여 `temperature` 필드에 할당합니다.

1. **하나 이상의 작업 설정**에서:

   1. 이 규칙에 대한 규칙 작업 목록을 열려면 **작업 추가**를 선택합니다.

   1. **작업 선택**에서 ** AWS IoT 주제에 메시지 다시 게시를** 선택합니다.

   1. 작업 목록 하단에서 **구성 작업**을 선택하여 선택한 작업의 구성 페이지를 엽니다.

1. **구성 작업**에서:

   1.  **주제**에 **device/data/temp**를 입력합니다. 이 규칙이 게시할 메시지의 MQTT 주제입니다.

   1.  **서비스 품질(QoS)**에서 **0 - 메시지가 0번 이상 전송됨**을 선택합니다.

   1.  **이 작업을 수행할 수 있는 AWS IoT 액세스 권한을 부여할 역할 선택 또는 생성**에서:

      1.  **역할 생성**을 선택합니다. **새 역할 생성** 대화 상자가 열립니다.

      1. 새 역할을 설명하는 이름을 입력합니다. 본 자습서에서는 **republish\$1role**을 사용합니다.

         새 역할을 만들면 규칙 작업을 수행할 올바른 정책이 만들어지고 새 역할에 연결됩니다. 이 규칙 작업의 주제를 변경하거나 다른 규칙 작업에서 이 역할을 사용하는 경우 새 주제 또는 작업에 권한을 부여하도록 해당 역할에 대한 정책을 업데이트해야 합니다. 기존 역할을 업데이트하려면 이 섹션의 **역할 업데이트**를 선택합니다.

      1. **역할 생성**을 선택하여 역할을 생성하고 대화 상자를 닫습니다.

   1. **작업 추가**를 선택하여 규칙에 작업을 추가하고 **규칙 생성** 페이지로 이동합니다.

1. 이제 ** AWS IoT 주제에 메시지 다시 게시** 작업이 **하나 이상의 작업 설정에** 나열됩니다.

   새 작업 타일의 ** AWS IoT 주제에 메시지 재게시** 아래에서 재게시 작업으로 게시할 주제를 볼 수 있습니다.

   이 규칙 작업은 이 규칙에 추가할 유일한 규칙 작업입니다.

1. **규칙 생성**에서 하단으로 스크롤하고 **규칙 생성**을 선택하여 규칙을 생성하고 이 단계를 완료합니다.

## 2단계: 새 규칙 테스트
<a name="iot-repub-rule-test"></a>

새 규칙을 테스트하려면 MQTT 클라이언트를 사용하여 이 규칙에서 사용하는 MQTT 메시지를 게시하고 구독합니다.

새 창에서 [AWS IoT 콘솔의 MQTT 클라이언트](https://console.aws.amazon.com//iot/home#/test)를 엽니다. 이렇게 하면 MQTT 클라이언트의 구성을 그대로 유지하면서 규칙을 편집할 수 있습니다. MQTT 클라이언트는 콘솔의 다른 페이지로 이동하기 위해 나가면 구독 또는 메시지 로그를 유지하지 않습니다.

**MQTT 클라이언트를 사용하여 규칙을 테스트하려면**

1. [AWS IoT 콘솔의 MQTT 클라이언트](https://console.aws.amazon.com//iot/home#/test)에서 입력 주제(이 경우 `device/+/data`)를 구독합니다.

   1. MQTT 클라이언트에서 **구독** 아래에서 **주제 구독**을 선택합니다.

   1. **구독 주제**에 입력 주제 필터 **device/\$1/data**의 주제를 입력합니다.

   1. 나머지 필드는 기본 설정을 유지합니다.

   1. **주제 구독**을 선택합니다.

      **구독** 열의 **주제 게시** 아래에 **device/\$1/data**가 나타납니다.

1. 규칙에서 게시할 주제 `device/data/temp`를 구독합니다.

   1. **구독** 아래에서 **주제 구독**을 다시 선택하고, **구독 주제**에 다시 게시된 메시지의 주제 **device/data/temp**를 입력합니다.

   1. 나머지 필드는 기본 설정을 유지합니다.

   1. **주제 구독**을 선택합니다.

      **구독** 열의 **device/\$1/data**에서 **device/data/temp**가 나타납니다.

1. 특정 디바이스 ID **device/22/data**로 입력 주제에 메시지를 게시합니다. 와일드카드 문자가 포함된 MQTT 항목에는 게시할 수 없습니다.

   1. MQTT 클라이언트의 **구독** 아래에서 **주제 게시**를 선택합니다.

   1. **게시** 필드에 입력 주제 이름 **device/22/data**를 입력합니다.

   1. 여기에 표시된 샘플 데이터를 복사하고 주제 이름 아래의 편집 상자에 샘플 데이터를 붙여 넣습니다.

      ```
      {
        "temperature": 28,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. MQTT 메시지를 전송하려면 **주제 게시**를 선택합니다.

1. 전송한 메시지를 검토합니다.

   1. MQTT 클라이언트의 **구독** 아래에서 이전에 구독한 두 주제 옆에 녹색 점이 있습니다.

      녹색 점은 마지막으로 메시지를 본 이후 하나 이상의 새 메시지가 수신되었음을 나타냅니다.

   1. **구독** 아래에서 **device/\$1/data**를 선택하여 메시지 페이로드가 방금 게시한 것과 일치하고 다음과 같이 표시되는지 확인하세요.

      ```
      {
        "temperature": 28,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. **구독** 아래에서 **device/data/temp**를 선택하여 게시된 메시지 페이로드가 다음과 같이 표시되는지 확인하세요.

      ```
      {
        "device_id": "22",  
        "temperature": 28
      }
      ```

      `device_id` 값은 따옴표로 묶인 문자열이고 `temperature` 값은 숫자여야 합니다. 이는 [https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-function-topic](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-function-topic) 함수가 입력 메시지의 주제 이름에서 문자열을 추출하는 반면 `temperature` 값은 입력 메시지의 페이로드에서 숫자 값을 사용하기 때문입니다.

      `device_id` 값을 숫자 값으로 만들려면 규칙 쿼리 문에서 `topic(2)`를 다음으로 바꿉니다.

      ```
      cast(topic(2) AS DECIMAL)
      ```

      `topic(2)` 값을 숫자 값으로 캐스팅하는 것은 주제의 해당 부분에 숫자만 포함된 경우에만 작동합니다.

1. **device/data/temp** 주제에 올바른 메시지가 게시되었으면 규칙이 작동한 것입니다. 다음 섹션에서 재게시 규칙 작업에 대해 자세히 알아볼 수 있는 내용을 확인하세요.

   **device/\$1/data** 또는 **device/data/temp** 주제에 올바른 메시지가 게시되었음을 확인할 수 없는 경우 문제 해결 팁을 확인하세요.

### 재게시 메시지 규칙 문제 해결
<a name="iot-repub-rule-trouble"></a>

다음은 예상한 결과가 표시되지 않는 경우에 대비하여 확인해야 할 몇 가지 사항입니다.
+ 

**오류 배너가 있음**  
입력 메시지를 게시할 때 오류가 나타나면 먼저 해당 오류를 수정하세요. 다음 단계는 해당 오류를 수정하는 데 도움이 될 수 있습니다.
+ 

**MQTT 클라이언트에서 입력 메시지가 표시되지 않음**  
`device/+/data` 주제 필터를 구독한 경우 입력 메시지를 `device/22/data` 주제에 게시할 때마다 절차에 설명된 대로 해당 메시지가 MQTT 클라이언트에 나타나야 합니다.

**확인해야 할 사항**
  + 

**구독한 주제 필터 확인**  
절차에 설명된 대로 입력 메시지 주제를 구독한 경우 게시할 때마다 입력 메시지의 복사본이 표시되어야 합니다.

    메시지가 표시되지 않으면 구독한 주제 이름을 확인하고 게시한 주제와 비교합니다. 주제 이름은 대소문자를 구분하며 구독한 주제는 메시지 페이로드를 게시한 주제와 동일해야 합니다.
  + 

**메시지 게시 함수 확인**  
MQTT 클라이언트의 **구독**에서 **device/\$1/data**를 선택하고 게시 메시지의 주제를 확인한 다음 **주제에 게시**를 선택합니다. 주제 아래의 편집 상자에서 메시지 페이로드가 메시지 목록에 나타납니다.
+ 

**MQTT 클라이언트에서 다시 게시된 메시지가 표시되지 않음**  
규칙이 작동하려면 메시지를 수신하고 다시 게시하도록 권한을 부여하는 올바른 정책이 있어야 하며 메시지를 수신해야 합니다.

**확인해야 할 사항**
  + 

**MQTT 클라이언트 AWS 리전 의 및 생성한 규칙을 확인합니다.**  
MQTT 클라이언트를 실행 중인 콘솔은 생성한 규칙과 동일한 AWS 리전에 있어야 합니다.
  + 

**규칙 쿼리 문의 입력 메시지 주제 확인**  
규칙이 작동하려면 규칙 쿼리 문의 FROM 절에 있는 주제 필터와 일치하는 주제 이름이 포함된 메시지를 받아야 합니다.

    MQTT 클라이언트에 있는 주제의 철자와 함께 규칙 쿼리 문에서 주제 필터의 철자를 확인하세요. 주제 이름은 대/소문자를 구분하며 메시지의 주제는 규칙 쿼리 문의 주제 필터와 일치해야 합니다.
  + 

**입력 메시지 페이로드의 내용 확인**  
규칙이 작동하려면 SELECT 문에서 선언된 메시지 페이로드에서 데이터 필드를 찾아야 합니다.

    MQTT 클라이언트에 있는 메시지 페이로드의 철자와 함께 규칙 쿼리 명령문의 `temperature` 필드 철자를 확인하세요. 필드 이름은 대소문자를 구분하며 규칙 쿼리 문의 `temperature` 필드는 메시지 페이로드의 `temperature` 필드와 동일해야 합니다.

    메시지 페이로드의 JSON 문서의 형식이 올바른지 확인하세요. JSON에 쉼표 누락과 같은 오류가 있으면 규칙에서 읽을 수 없습니다.
  + 

**규칙 동작에서 다시 게시된 메시지 주제 확인**  
재게시 규칙 작업에서 새 메시지를 게시하는 주제는 MQTT 클라이언트에서 구독한 주제와 일치해야 합니다.

    콘솔에서 만든 규칙을 열고 규칙 작업이 메시지를 다시 게시할 주제를 확인합니다.
  + 

**규칙에서 사용 중인 역할 확인**  
규칙 작업에는 원래 주제를 받고 새 주제를 게시할 수 있는 권한이 있어야 합니다.

    메시지 데이터를 수신하고 다시 게시하도록 규칙을 인증하는 정책은 사용된 주제에 따라 다릅니다. 메시지 데이터를 다시 게시하는 데 사용되는 주제를 변경하는 경우 규칙 작업의 역할을 업데이트하여 현재 주제와 일치하도록 정책을 업데이트해야 합니다.

    문제가 의심되는 경우 규칙 재게시 작업을 편집하고 새 역할을 만듭니다. 규칙 작업에 의해 생성된 새 역할에는 이러한 작업을 수행하는 데 필요한 권한이 부여됩니다.

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

**이 자습서에서는**
+ 간단한 SQL 쿼리와 규칙 쿼리 문에서 몇 가지 함수를 사용하여 새 MQTT 메시지를 생성했습니다.
+ 새 메시지를 다시 게시 하는 규칙을 만들었습니다.
+ MQTT 클라이언트를 사용하여 AWS IoT 규칙을 테스트했습니다.

**다음 단계**  
이 규칙을 사용하여 몇 가지 메시지를 다시 게시한 후 이 규칙을 실험하여 자습서의 일부 측면을 변경하면 다시 게시된 메시지에 어떤 영향을 주는지 확인해 보세요. 다음은 시작하는 데 도움이 될 몇 가지 아이디어입니다.
+ 입력 메시지의 주제에서 *device\$1id*를 변경하고 다시 게시된 메시지 페이로드의 영향을 관찰합니다.
+ 규칙 쿼리 문에서 선택한 필드를 변경하고 다시 게시된 메시지 페이로드의 영향을 관찰합니다.
+ 이 시리즈의 다음 자습서를 사용해 보고 [자습서: Amazon SNS 알림 전송](iot-sns-rule.md)의 방법을 알아봅니다.

이 자습서에서 사용되는 규칙 다시 게시 작업은 규칙 쿼리 문을 디버깅하는 데 도움이 될 수도 있습니다. 예를 들어 규칙에 이 작업을 추가하여 규칙 쿼리 문이 규칙 작업에 사용되는 데이터의 서식을 지정하는 방법을 확인할 수 있습니다.

# 자습서: Amazon SNS 알림 전송
<a name="iot-sns-rule"></a>

이 자습서에서는 MQTT 메시지 데이터를 SMS 문자 메시지로 전송할 수 있도록 Amazon SNS 주제로 전송하는 AWS IoT 규칙을 생성하는 방법을 보여줍니다.

이 자습서에서는 온도가 규칙에 설정된 값을 초과할 때마다 기후 센서에서 Amazon SNS 주제의 모든 구독자에게 메시지 데이터를 전송하는 규칙을 생성합니다. 이 규칙은 보고된 온도가 규칙에 의해 설정된 값을 초과할 때를 감지하고 디바이스 ID, 보고된 온도 및 초과된 온도 제한만 포함하는 새 메시지 페이로드를 생성합니다. 이 규칙은 새 메시지 페이로드를 JSON 문서로 SNS 주제에 전송하여 모든 구독자에게 SNS 주제를 알립니다.

**이 자습서에서 배울 내용:**
+ Amazon SNS 알림을 생성하고 테스트하는 방법
+  AWS IoT 규칙에서 Amazon SNS 알림을 호출하는 방법
+ 규칙 쿼리 문에서 간단한 SQL 쿼리 및 함수를 사용하는 방법
+ MQTT 클라이언트를 사용하여 AWS IoT 규칙을 테스트하는 방법

이 자습서는 완료하는 데 약 30분 걸립니다.

**Topics**
+ [1단계: SMS 문자 메시지를 전송하는 Amazon SNS 주제 생성](#iot-sns-rule-create-sns-topic)
+ [2단계: 텍스트 메시지를 전송하는 AWS IoT 규칙 생성](#iot-sns-rule-create-rule)
+ [3단계: AWS IoT 규칙 및 Amazon SNS 알림 테스트](#iot-sns-rule-test-rule)
+ [4단계: 결과 및 다음 단계 검토](#iot-sns-rule-review-results)

**이 자습서를 시작하기 전에 다음 사항을 확인해야 합니다.**
+ 

**[설정 AWS 계정](setting-up.md)**  
이 자습서를 완료하려면 AWS 계정 및 AWS IoT 콘솔이 필요합니다.
+ 

**검토된 [MQTT 클라이언트를 사용하여 AWS IoT MQTT 메시지 보기](view-mqtt-messages.md)**  
MQTT 클라이언트를 사용하여 주제를 구독하고 게시할 수 있는지 확인하세요. 이 절차에서는 MQTT 클라이언트를 사용하여 새 규칙을 테스트합니다.
+ 

**[Amazon Simple Notification Service](https://docs.aws.amazon.com//sns/latest/dg/welcome.html)를 검토했습니다.**  
이전에 Amazon SNS 사용한 적이 없는 경우 [Amazon SNS 액세스 설정](https://docs.aws.amazon.com//sns/latest/dg/sns-setting-up.html)을 검토합니다. 다른 AWS IoT 자습서를 이미 완료한 경우가 AWS 계정 이미 올바르게 구성되어 있어야 합니다.

## 1단계: SMS 문자 메시지를 전송하는 Amazon SNS 주제 생성
<a name="iot-sns-rule-create-sns-topic"></a>

이 절차에서는 날씨 센서가 메시지 데이터를 보낼 수 있는 Amazon SNS 주제를 생성하는 방법을 설명합니다. 그러면 Amazon SNS 주제가 SMS 텍스트 메시지를 통해 모든 구독자에게 초과된 온도 제한을 알립니다.

**SMS 문자 메시지를 전송하는 Amazon SNS 주제를 생성하려면**

1. **Amazon SNS 주제를 생성합니다.**

   1. [Amazon SNS 콘솔](https://console.aws.amazon.com//sns/home)에 로그인합니다.

   1. 왼쪽 탐색 창에서 **주제**를 선택합니다.

   1. **주제(Topics)** 페이지에서 **새 주제 생성(Create new topic)**을 선택합니다.

   1. **세부 정보**에서 **표준** 유형을 선택합니다. 기본적으로 콘솔은 FIFO 주제를 만듭니다.

   1. **이름**에 SNS 주제 이름을 입력합니다. 이 자습서에서는 **high\$1temp\$1notice**을 입력합니다.

   1. 페이지 끝으로 스크롤하고 **주제 생성**을 선택합니다.

      콘솔에 새 주제의 **세부 정보** 페이지가 열립니다.

1. **Amazon SNS 구독을 생성합니다.**
**참고**  
이 구독에서 사용하는 전화번호는 이 자습서에서 전송할 메시지에서 문자 메시지 요금을 부과할 수 있습니다.

   1. **high\$1temp\$1notice** 주제 세부 정보 페이지에서 **구독 생성(Create subscription)**을 선택합니다.

   1. **구독 생성**에 있는 **세부 정보** 섹션의 **프로토콜** 목록에서 **SMS**를 선택합니다.

   1. **엔드포인트**에 문자 메시지를 받을 수 있는 전화 번호를 입력합니다. `+`로 시작하고 국가 및 지역 코드를 포함하고 다른 구두점은 포함하지 않도록 입력해야 합니다.

   1. **구독 생성**을 선택합니다.

1. **Amazon SNS 알림을 테스트합니다.**

   1. [Amazon SNS 콘솔](https://console.aws.amazon.com//sns/home)의 왼쪽 탐색 창에서 **주제**를 선택합니다.

   1. 주제의 세부 정보 페이지를 열려면 **주제**의 주제 목록에서 **high\$1temp\$1notice**를 선택합니다.

   1. **주제에 메시지 게시(Publish message to topic)** 페이지를 열려면 **high\$1temp\$1notice** 세부 정보 페이지에서 **메시지 게시(Publish message)**를 선택합니다.

   1. **주제에 메시지 게시(Publish message to topic)**에 있는 **메시지 본문** 섹션에서 **엔드포인트로 전송할 메시지 본문(Message body to send to the endpoint)**에 짧은 메시지를 입력합니다.

   1. 페이지의 하단으로 스크롤하고 **메시지 게시(Publish message)**를 선택합니다.

   1. 구독을 만들 때 이전에 사용한 번호가 있는 전화에서 메시지가 수신되었는지 확인하세요.

   테스트 메시지를 받지 못한 경우 전화 번호와 휴대 전화 설정을 다시 확인하세요.

   자습서를 계속하기 전에 [Amazon SNS 콘솔](https://console.aws.amazon.com//sns/home)에서 테스트 메시지를 게시할 수 있는지 확인하세요.

## 2단계: 텍스트 메시지를 전송하는 AWS IoT 규칙 생성
<a name="iot-sns-rule-create-rule"></a>

이 자습서에서 생성할 AWS IoT 규칙은 메시지를 전송한 디바이스의 ID`device_id`가 인 `device/device_id/data` MQTT 주제를 구독합니다. 이러한 주제는 주제 필터에서 `device/+/data`로 설명됩니다. 여기서 `+`는 두 개의 슬래시 문자 사이의 모든 문자열과 일치하는 와일드카드 문자입니다. 이 규칙은 메시지 페이로드의 `temperature` 필드 값도 테스트합니다.

규칙이 일치하는 주제로부터 메시지를 수신하면 주제 이름에서 `device_id`, 메시지 페이로드에서 `temperature` 값을 가져와 테스트 중인 제한에 대한 상수 값을 추가하고 이러한 값을 JSON 문서로 Amazon SNS 알림 주제에 전송합니다.

 예를 들어, 기상 센서 디바이스 번호 32의 MQTT 메시지는 `device/32/data` 주제를 사용하고 다음과 같은 메시지 페이로드가 있습니다.

```
{
  "temperature": 38,
  "humidity": 80,
  "barometer": 1013,
  "wind": {
    "velocity": 22,
    "bearing": 255
  }
}
```

규칙의 규칙 쿼리 문은 메시지 페이로드에서 `temperature` 값을 가져오고 주제 이름에서 `device_id`를 가져오고 상수 `max_temperature` 값을 추가하여 다음과 같은 메시지 페이로드를 Amazon SNS 주제로 전송합니다.

```
{
  "device_id": "32",
  "reported_temperature": 38,
  "max_temperature": 30
}
```

**제한 초과 온도 값을 감지하고 Amazon SNS 주제로 전송할 데이터를 생성하는 AWS IoT 규칙을 생성하려면**

1. [AWS IoT 콘솔의 **규칙** 허브를](https://console.aws.amazon.com//iot/home#/rulehub) 엽니다.

1. 이것이 첫 번째 규칙인 경우 **생성** 또는 **규칙 생성**을 선택합니다.

1. **규칙 생성(Create a rule)**에서:

   1. **이름(Name)**에 **temp\$1limit\$1notify**를 입력합니다.

      규칙 이름은 AWS 계정 및 리전 내에서 고유해야 하며 공백을 가질 수 없습니다. 이 이름에 밑줄 문자를 사용하여 규칙 이름의 단어를 구분했습니다.

   1. **설명**에서 규칙을 설명합니다.

      의미 있는 설명을 사용하면 이 규칙이 수행하는 작업과 규칙을 만든 이유를 쉽게 기억할 수 있습니다. 설명은 필요한 만큼 길어질 수 있으므로 가능한 한 자세하게 설명하세요.

1. **규칙 생성**의 **규칙 쿼리 문**에서:

   1.  **SQL 버전 사용**에서 **2016-03-23**을 선택합니다.

   1. **규칙 쿼리 문** 편집 상자에 쿼리 문을 입력합니다.

      ```
      SELECT topic(2) as device_id, 
          temperature as reported_temperature, 
          30 as max_temperature 
        FROM 'device/+/data' 
        WHERE temperature > 30
      ```

      이 문은 다음을 수행합니다.
      + `device/+/data` 주제 필터와 일치하고 `temperature` 값이 30보다 큰 주제가 있는 MQTT 메시지를 수신 대기합니다.
      + 주제 문자열에서 두 번째 요소를 선택하여 `device_id` 필드에 할당합니다.
      + 메시지 페이로드에서 `temperature` 값 필드를 선택하여 `reported_temperature` 필드에 할당합니다.
      + 한계 값을 나타내는 상수 값 `30`을 생성하고 `max_temperature` 필드에 할당합니다.

1. 이 규칙에 대한 규칙 작업 목록을 열려면 **하나 이상의 작업 설정(Set one or more actions)**에서 **작업 추가(Add action)**를 선택합니다.

1. **Select an action(작업 선택)**에서 **SNS 푸시 알림으로 메시지 전송(Send a message as an SNS push notification)**을 선택합니다.

1. 작업 목록 하단에서 선택한 작업의 구성 페이지를 열려면 **구성 작업**을 선택합니다.

1. **구성 작업**에서:

   1. **SNS 대상**에서 **선택(Select)**을 클릭하고 **high\$1temp\$1notice**라는 이름의 SNS 주제를 찾은 다음 **선택(Select)**을 클릭합니다.

   1. **메시지 형식(Message format)**에서 **RAW**를 선택합니다.

   1. **이 작업을 수행할 수 있는 AWS IoT 액세스 권한을 부여할 역할 선택 또는 생성**에서 **역할 생성을** 선택합니다.

   1. **새 역할 생성**에서 **이름**에 새 역할의 고유 이름을 입력합니다. 본 자습서에서는 **sns\$1rule\$1role**를 사용합니다.

   1. **역할 생성**을 선택합니다.

   이 자습서를 반복하거나 기존 역할을 재사용하는 경우 계속 진행하기 전에 **역할 업데이트**를 선택합니다. 그러면 SNS 대상에서 작동하도록 역할의 정책 문서가 업데이트됩니다.

1. **작업 추가**를 선택하여 **규칙 생성** 페이지로 이동합니다.

   새 작업의 타일에서 **SNS 푸시 알림으로 메시지 전송하기(Send a message as an SNS push notification)** 아래에서 규칙이 호출할 SNS 주제를 볼 수 있습니다.

   이 규칙 작업은 이 규칙에 추가할 유일한 규칙 작업입니다.

1. 규칙을 생성하고 이 단계를 완료하려면 **규칙 생성(Create a rule)**에서 하단으로 스크롤하여 **규칙 생성(Create rule)**을 선택합니다.

## 3단계: AWS IoT 규칙 및 Amazon SNS 알림 테스트
<a name="iot-sns-rule-test-rule"></a>

새 규칙을 테스트하려면 MQTT 클라이언트를 사용하여 이 규칙에서 사용하는 MQTT 메시지를 게시하고 구독합니다.

새 창에서 [AWS IoT 콘솔의 MQTT 클라이언트](https://console.aws.amazon.com//iot/home#/test)를 엽니다. 이렇게 하면 MQTT 클라이언트의 구성을 그대로 유지하면서 규칙을 편집할 수 있습니다. 콘솔의 다른 페이지로 이동하기 위해 MQTT 클라이언트를 나가면 구독이나 메시지 로그가 유지되지 않습니다.

**MQTT 클라이언트를 사용하여 규칙을 테스트하려면**

1. [AWS IoT 콘솔의 MQTT 클라이언트](https://console.aws.amazon.com//iot/home#/test)에서 입력 주제(이 경우 `device/+/data`)를 구독합니다.

   1. MQTT 클라이언트에서 **구독** 아래에서 **주제 구독**을 선택합니다.

   1. **구독 주제**에 입력 주제 필터 **device/\$1/data**의 주제를 입력합니다.

   1. 나머지 필드는 기본 설정을 유지합니다.

   1. **주제 구독**을 선택합니다.

      **구독** 열의 **주제 게시** 아래에 **device/\$1/data**가 나타납니다.

1. 특정 디바이스 ID **device/32/data**로 입력 주제에 메시지를 게시합니다. 와일드카드 문자가 포함된 MQTT 항목에는 게시할 수 없습니다.

   1. MQTT 클라이언트의 **구독** 아래에서 **주제 게시**를 선택합니다.

   1. **게시** 필드에 입력 주제 이름 **device/32/data**를 입력합니다.

   1. 여기에 표시된 샘플 데이터를 복사하고 주제 이름 아래의 편집 상자에 샘플 데이터를 붙여 넣습니다.

      ```
      {
        "temperature": 38,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. **주제에 게시**를 선택하여 MQTT 메시지를 게시합니다.

1. 문자 메시지가 전송되었는지 확인합니다.

   1. MQTT 클라이언트의 **구독** 아래에서 이전에 구독한 주제 옆에 녹색 점이 있습니다.

      녹색 점은 마지막으로 메시지를 보았을 때 하나 이상의 새 메시지가 수신되었음을 나타냅니다.

   1. **구독** 아래에서 **device/\$1/data**를 선택하여 메시지 페이로드가 방금 게시한 것과 일치하고 다음과 같이 표시되는지 확인하세요.

      ```
      {
        "temperature": 38,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. SNS 주제를 구독하는 데 사용한 전화를 확인하고 메시지 페이로드의 내용이 다음과 같이 표시되는지 확인합니다.

      ```
      {"device_id":"32","reported_temperature":38,"max_temperature":30}
      ```

      `device_id` 값은 따옴표로 묶인 문자열이고 `temperature` 값은 숫자여야 합니다. 이는 [https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-function-topic](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-function-topic) 함수가 입력 메시지의 주제 이름에서 문자열을 추출하는 반면 `temperature` 값은 입력 메시지의 페이로드에서 숫자 값을 사용하기 때문입니다.

      `device_id` 값을 숫자 값으로 만들려면 규칙 쿼리 문에서 `topic(2)`를 다음으로 바꿉니다.

      ```
      cast(topic(2) AS DECIMAL)
      ```

      주제의 해당 부분에 숫자만 포함된 경우에만 `topic(2)` 값을 숫자 `DECIMAL` 값으로 캐스팅할 수 있다는 점을 유의하세요.

1. 온도가 한계를 초과하지 않는 MQTT 메시지를 전송해보세요.

   1. MQTT 클라이언트의 **구독** 아래에서 **주제 게시**를 선택합니다.

   1. **게시** 필드에 입력 주제 이름 **device/33/data**를 입력합니다.

   1. 여기에 표시된 샘플 데이터를 복사하고 주제 이름 아래의 편집 상자에 샘플 데이터를 붙여 넣습니다.

      ```
      {
        "temperature": 28,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. MQTT 메시지를 전송하려면 **주제 게시**를 선택합니다.

   **device/\$1/data** 구독에서 전송한 메시지가 표시되어야 합니다. 그러나 온도 값이 규칙 쿼리 문에서 최대 온도보다 낮기 때문에 문자 메시지를 받지 않아야 합니다.

   올바른 동작이 표시되지 않으면 문제 해결 팁을 확인합니다.

### SNS 메시지 규칙 문제 해결
<a name="iot-sns-rule-trouble"></a>

예상한 결과가 표시되지 않는 경우를 대비하여 확인해야 할 몇 가지 사항이 있습니다.
+ 

**오류 배너가 있음**  
입력 메시지를 게시할 때 오류가 나타나면 먼저 해당 오류를 수정하세요. 다음 단계는 해당 오류를 수정하는 데 도움이 될 수 있습니다.
+ 

**MQTT 클라이언트에서 입력 메시지가 표시되지 않음**  
`device/+/data` 주제 필터를 구독한 경우 입력 메시지를 `device/22/data` 주제에 게시할 때마다 절차에 설명된 대로 해당 메시지가 MQTT 클라이언트에 나타나야 합니다.

**확인해야 할 사항**
  + 

**구독한 주제 필터 확인**  
절차에 설명된 대로 입력 메시지 주제를 구독한 경우 게시할 때마다 입력 메시지의 복사본이 표시되어야 합니다.

    메시지가 표시되지 않으면 구독한 주제 이름을 확인하고 게시한 주제와 비교합니다. 주제 이름은 대소문자를 구분하며 구독한 주제는 메시지 페이로드를 게시한 주제와 동일해야 합니다.
  + 

**메시지 게시 함수 확인**  
MQTT 클라이언트의 **구독**에서 **device/\$1/data**를 선택하고 게시 메시지의 주제를 확인한 다음 **주제에 게시**를 선택합니다. 주제 아래의 편집 상자에서 메시지 페이로드가 메시지 목록에 나타납니다.
+ 

**SMS 메시지가 수신되지 않음**  
규칙이 작동하려면 메시지를 수신하고 SNS 알림을 전송할 수 있도록 권한을 부여하는 올바른 정책이 있어야 하며 메시지를 수신해야 합니다.

**확인해야 할 사항**
  + 

**MQTT 클라이언트 AWS 리전 의 및 생성한 규칙을 확인합니다.**  
MQTT 클라이언트를 실행 중인 콘솔은 생성한 규칙과 동일한 AWS 리전에 있어야 합니다.
  + 

**메시지 페이로드의 온도 값이 테스트 임계값을 초과하는지 확인**  
규칙 쿼리 문에 정의된 대로 온도 값이 30보다 작거나 같으면 규칙은 해당 작업을 수행하지 않습니다.
  + 

**규칙 쿼리 문의 입력 메시지 주제 확인**  
규칙이 작동하려면 규칙 쿼리 문의 FROM 절에 있는 주제 필터와 일치하는 주제 이름이 포함된 메시지를 받아야 합니다.

    MQTT 클라이언트에 있는 주제의 철자와 함께 규칙 쿼리 문에서 주제 필터의 철자를 확인하세요. 주제 이름은 대/소문자를 구분하며 메시지의 주제는 규칙 쿼리 문의 주제 필터와 일치해야 합니다.
  + 

**입력 메시지 페이로드의 내용 확인**  
규칙이 작동하려면 SELECT 문에서 선언된 메시지 페이로드에서 데이터 필드를 찾아야 합니다.

    MQTT 클라이언트에 있는 메시지 페이로드의 철자와 함께 규칙 쿼리 명령문의 `temperature` 필드 철자를 확인하세요. 필드 이름은 대소문자를 구분하며 규칙 쿼리 문의 `temperature` 필드는 메시지 페이로드의 `temperature` 필드와 동일해야 합니다.

    메시지 페이로드의 JSON 문서의 형식이 올바른지 확인하세요. JSON에 쉼표 누락과 같은 오류가 있으면 규칙에서 읽을 수 없습니다.
  + 

**규칙 동작에서 다시 게시된 메시지 주제 확인**  
재게시 규칙 작업에서 새 메시지를 게시하는 주제는 MQTT 클라이언트에서 구독한 주제와 일치해야 합니다.

    콘솔에서 만든 규칙을 열고 규칙 작업이 메시지를 다시 게시할 주제를 확인합니다.
  + 

**규칙에서 사용 중인 역할 확인**  
규칙 작업에는 원래 주제를 받고 새 주제를 게시할 수 있는 권한이 있어야 합니다.

    메시지 데이터를 수신하고 다시 게시하도록 규칙을 인증하는 정책은 사용된 주제에 따라 다릅니다. 메시지 데이터를 다시 게시하는 데 사용되는 주제를 변경하는 경우 규칙 작업의 역할을 업데이트하여 현재 주제와 일치하도록 정책을 업데이트해야 합니다.

    문제가 의심되는 경우 규칙 재게시 작업을 편집하고 새 역할을 만듭니다. 규칙 작업에 의해 생성된 새 역할에는 이러한 작업을 수행하는 데 필요한 권한이 부여됩니다.

## 4단계: 결과 및 다음 단계 검토
<a name="iot-sns-rule-review-results"></a>

**이 자습서에서**
+ Amazon SNS 알림 주제 및 구독을 생성하고 테스트했습니다.
+ 규칙 쿼리 문에서 간단한 SQL 쿼리 및 함수를 사용하여 알림에 대한 새 메시지를 만들었습니다.
+ 사용자 지정 메시지 페이로드를 사용한 Amazon SNS 알림을 보내는 AWS IoT 규칙을 생성했습니다.
+ MQTT 클라이언트를 사용하여 AWS IoT 규칙을 테스트했습니다.

**다음 단계**  
이 규칙을 사용하여 몇 가지 문자 메시지를 전송한 후 이 규칙을 실험하여 자습서의 일부 측면을 변경하면 메시지가 전송되는 시기에 영향을 받는지 확인하세요. 다음은 시작하는 데 도움이 될 몇 가지 아이디어입니다.
+ 입력 메시지의 주제에서 *device\$1id*를 변경하고 문자 메시지 내용의 영향을 관찰합니다.
+ 규칙 쿼리 문에서 선택한 필드를 변경하고 텍스트 메시지 내용의 영향을 관찰합니다.
+ 최대 온도 대신 최소 온도에 대한 테스트 규칙 쿼리 문에서 테스트를 변경합니다. `max_temperature` 이름을 변경하는 것을 잊지 마세요\$1
+ SNS 알림이 전송될 때 MQTT 메시지를 전송하기 위한 재게시 규칙 작업을 추가합니다.
+ 이 시리즈의 다음 자습서를 사용해 보고 [자습서: DynamoDB 테이블에 디바이스 데이터 저장](iot-ddb-rule.md)의 방법을 알아봅니다.

# 자습서: DynamoDB 테이블에 디바이스 데이터 저장
<a name="iot-ddb-rule"></a>

이 자습서에서는 DynamoDB 테이블로 메시지 데이터를 보내는 AWS IoT 규칙을 생성하는 방법을 보여줍니다.

이 자습서에서는 가상 기상 센서 디바이스에서 DynamoDB 테이블로 메시지 데이터를 전송하는 규칙을 생성합니다. 이 규칙은 여러 기상 센서의 데이터를 단일 데이터베이스 테이블에 추가할 수 있도록 포맷합니다.

**이 자습서에서 배울 내용**
+ DynamoDB 테이블 생성 방법
+  AWS IoT 규칙에서 DynamoDB 테이블로 메시지 데이터를 보내는 방법
+  AWS IoT 규칙에서 대체 템플릿을 사용하는 방법
+ 규칙 쿼리 문에서 간단한 SQL 쿼리 및 함수를 사용하는 방법
+ MQTT 클라이언트를 사용하여 AWS IoT 규칙을 테스트하는 방법

이 자습서는 완료하는 데 약 30분 걸립니다.

**Topics**
+ [1단계: 이 자습서를 위한 DynamoDB 테이블 생성](#iot-ddb-rule-ddb-table)
+ [2단계: DynamoDB 테이블로 데이터를 전송하는 AWS IoT 규칙 생성](#iot-ddb-rule-topic-rule)
+ [3단계: AWS IoT 규칙 및 DynamoDB 테이블 테스트](#iot-ddb-rule-test)
+ [4단계: 결과 및 다음 단계 검토](#iot-ddb-rule-review)

**이 자습서를 시작하기 전에 다음 사항을 확인해야 합니다.**
+ 

**[설정 AWS 계정](setting-up.md)**  
이 자습서를 완료하려면 AWS 계정 및 AWS IoT 콘솔이 필요합니다.
+ 

**검토된 [MQTT 클라이언트를 사용하여 AWS IoT MQTT 메시지 보기](view-mqtt-messages.md)**  
MQTT 클라이언트를 사용하여 주제를 구독하고 게시할 수 있는지 확인하세요. 이 절차에서는 MQTT 클라이언트를 사용하여 새 규칙을 테스트합니다.
+ 

**[Amazon DynamoDB](https://docs.aws.amazon.com//amazondynamodb/latest/developerguide/Introduction.html) 개요를 검토했습니다.**  
이전에 DynamoDB 를 사용하지 않았다면 DynamoDB의 기본 개념과 운영에 익숙해지도록 [DynamoDB 시작하기](https://docs.aws.amazon.com//amazondynamodb/latest/developerguide/GettingStartedDynamoDB.html)를 검토하세요.

## 1단계: 이 자습서를 위한 DynamoDB 테이블 생성
<a name="iot-ddb-rule-ddb-table"></a>

이 자습서에서는 다음과 같은 속성이 포함된 DynamoDB 테이블을 만들어 가상 기상 센서 디바이스의 데이터를 기록합니다.
+ `sample_time`은 기본 키이며 샘플이 기록된 시간을 설명합니다.
+ `device_id`는 정렬 키이며 샘플을 제공한 디바이스를 설명합니다.
+ `device_data`는 디바이스에서 수신되고 규칙 쿼리 문에 의해 형식이 지정된 데이터입니다.

**이 자습서용 DynamoDB 테이블을 생성하려면**

1. [DynamoDB 콘솔](https://console.aws.amazon.com//dynamodb/home)을 열고 **테이블 생성**을 선택합니다.

1. **테이블 생성(Create table)**에서

   1.  **테이블 이름**에 테이블 이름 **wx\$1data**를 입력합니다.

   1. **파티션 키(Partition key)**에 **sample\$1time**을 입력하고 필드 옆에 있는 옵션 목록에서 **Number**를 선택합니다.

   1. **정렬 키(Sort key)**에 **device\$1id**를 입력하고 필드 옆에 있는 옵션 목록에서 **Number**를 선택합니다.

   1. 페이지 하단에서 **생성(Create)**을 선택합니다.

나중에 DynamoDB 규칙 작업을 구성할 때 `device_data`를 정의합니다.

## 2단계: DynamoDB 테이블로 데이터를 전송하는 AWS IoT 규칙 생성
<a name="iot-ddb-rule-topic-rule"></a>

이 단계에서는 규칙 쿼리 문을 사용하여 가상 기상 센서 디바이스의 데이터 형식을 데이터베이스 테이블에 기록하도록 지정합니다.

기상 센서 디바이스에서 받은 샘플 메시지 페이로드는 다음과 같습니다.

```
{
  "temperature": 28,
  "humidity": 80,
  "barometer": 1013,
  "wind": {
    "velocity": 22,
    "bearing": 255
  }
}
```

데이터베이스 항목의 경우 규칙 쿼리 문을 사용하여 메시지 페이로드의 구조를 다음과 같이 병합합니다.

```
{
  "temperature": 28,
  "humidity": 80,
  "barometer": 1013,
  "wind_velocity": 22,
  "wind_bearing": 255
}
```

이 규칙에서는 몇 가지 [대체 템플릿](iot-substitution-templates.md)을(를) 사용합니다. 대체 템플릿은 함수 및 메시지 데이터에서 동적 값을 삽입할 수 있는 표현식입니다.

**DynamoDB 테이블로 데이터를 전송하는 AWS IoT 규칙을 생성하려면**

1. [AWS IoT 콘솔의 규칙 허브](https://console.aws.amazon.com//iot/home#/rulehub)를 엽니다. 또는 내에서 AWS IoT AWS Management Console 홈페이지를 열고 **메시지 라우팅>규칙**으로 이동할 수 있습니다.

1. **규칙(Rules)**에서 새 규칙 생성을 시작하려면 **규칙 생성(Create rule)**을 선택합니다.

1. **규칙 속성(Rule properties)**에서

   1. **규칙 이름(Rule name)**에 **wx\$1data\$1ddb**를 입력합니다.

      규칙 이름은 AWS 계정 및 리전 내에서 고유해야 하며 공백을 가질 수 없습니다. 이 이름에 밑줄 문자를 사용하여 규칙 이름의 두 단어를 구분했습니다.

   1. **규칙 설명(Rule description)**에서 규칙을 설명합니다.

      의미 있는 설명을 사용하면 이 규칙이 수행하는 작업과 규칙을 만든 이유를 쉽게 기억할 수 있습니다. 설명은 필요한 만큼 길어질 수 있으므로 가능한 한 자세하게 설명하세요.

1. **다음**을 선택하여 계속 진행합니다.

1. **SQL 문(SQL statement)**에서

   1. **SQL 버전(SQL version)**에서 **2016-03-23**을 선택합니다.

   1. **SQL 문(SQL statement)** 편집 상자에 문을 입력합니다.

      ```
      SELECT temperature, humidity, barometer,
        wind.velocity as wind_velocity,
        wind.bearing as wind_bearing,
      FROM 'device/+/data'
      ```

      이 문은 다음을 수행합니다.
      + `device/+/data` 주제 필터와 일치하는 주제가 있는 MQTT 메시지를 수신합니다.
      + `wind` 속성의 요소를 개별 속성으로 형식화합니다.
      + `temperature`, `humidity` 및 `barometer` 속성은 변경되지 않은 상태로 전달합니다.

1. **다음**을 선택하여 계속 진행합니다.

1. **규칙 작업(Rule actions)**에서

   1. 이 규칙에 대한 규칙 작업 목록을 열려면 **작업 1(Action 1)**에서 **DynamoDB**를 선택합니다.
**참고**  
규칙 작업으로 DynamoDBv2가 아니라 DynamoDB를 선택해야 합니다.

   1. **테이블 이름**에서 이전 단계에서 생성한 DynamoDB 테이블의 이름 **wx\$1data**를 선택합니다.

      **파티션 키 유형(Partition key type)** 및 **정렬 키 유형(Sort key type)** 필드는 DynamoDB 테이블의 값으로 채워집니다.

   1. **파티션 키**에서 **sample\$1time**를 입력합니다.

   1. **파티션 키 값**에 **\$1\$1timestamp()\$1**를 입력합니다.

      이것은 이 규칙에서 사용할 첫 번째 [대체 템플릿](iot-substitution-templates.md)입니다. 메시지 페이로드의 값을 사용하는 대신 timestamp 함수에서 반환된 값을 사용합니다. 자세한 내용은 *AWS IoT Core 개발자 안내서*의 [timestamp](iot-sql-functions.md#iot-function-timestamp)를 참조하세요.

   1. **정렬 키(Sort key)**에 **device\$1id**를 입력합니다.

   1. **정렬 키 값**에 **\$1\$1cast(topic(2) AS DECIMAL)\$1**를 입력합니다.

      이것은 이 규칙에서 사용할 두 번째 [대체 템플릿](iot-substitution-templates.md)입니다. 키의 숫자 형식과 일치하도록 DECIMAL 값으로 캐스트한 후 디바이스 ID인 주제 이름에 두 번째 요소의 값을 삽입합니다. 주제에 대한 자세한 내용은 *AWS IoT Core 개발자 안내서*의 [topic](iot-sql-functions.md#iot-function-topic)을 참조하세요. 캐스팅에 대한 자세한 내용은 *AWS IoT Core 개발자 안내서*의 [cast](iot-sql-functions.md#iot-sql-function-cast)를 참조하세요.

   1. **이 열에 메시지 데이터 쓰기**에 **device\$1data**를 입력합니다.

      그러면 DynamoDB 테이블에 `device_data` 열이 생성됩니다.

   1. **작업**은 비워 둡니다.

   1. **IAM role**(IAM 역할)에서 **Create new role**(새 역할 생성)을 선택합니다.

   1. **Create role**(역할 생성) 대화 상자에서 **Role name**(역할 이름)에 **wx\$1ddb\$1role**을 입력합니다. 이 새 역할에는 'aws-iot-rule'이라는 접두사가 붙은 정책이 자동으로 포함되며, 이 정책을 통해 **wx\$1data\$1ddb** 규칙이 사용자가 생성한 **wx\$1data** DynamoDB 테이블로 데이터를 전송할 수 있습니다.

   1. **IAM 역할(IAM role)**에서 **wx\$1ddb\$1role**을 선택합니다.

   1. 페이지 하단에서 **다음(Next)**을 선택합니다.

1. **검토 및 생성(Review and create)** 페이지 하단에서 **생성(Create)**을 선택하여 규칙을 생성합니다.

## 3단계: AWS IoT 규칙 및 DynamoDB 테이블 테스트
<a name="iot-ddb-rule-test"></a>

새 규칙을 테스트하려면 MQTT 클라이언트를 사용하여 이 테스트에 사용된 MQTT 메시지를 게시하고 구독합니다.

새 창에서 [AWS IoT 콘솔의 MQTT 클라이언트](https://console.aws.amazon.com//iot/home#/test)를 엽니다. 이렇게 하면 MQTT 클라이언트의 구성을 그대로 유지하면서 규칙을 편집할 수 있습니다. MQTT 클라이언트는 콘솔의 다른 페이지로 이동하기 위해 나가면 구독 또는 메시지 로그를 유지하지 않습니다. 또한 규칙이 보내는 새 항목을 보려면 콘솔의 [DynamoDB Tables 허브에 별도의 AWS IoT 콘솔](https://console.aws.amazon.com//dynamodb/home#tables:) 창을 열어야 합니다.

**MQTT 클라이언트를 사용하여 규칙을 테스트하려면**

1. [AWS IoT 콘솔의 MQTT 클라이언트](https://console.aws.amazon.com//iot/home#/test)에서 입력 주제(`device/+/data`)를 구독합니다.

   1. MQTT 클라이언트에서 **주제 구독(Subscribe to a topic)**을 선택합니다.

   1. **주제 필터**에 입력 주제 필터의 주제(**device/\$1/data**)를 입력합니다.

   1. **구독**을 선택합니다.

1. 이제 특정 디바이스 ID **device/22/data**로 입력 주제에 메시지를 게시합니다. 와일드카드 문자가 포함된 MQTT 항목에는 게시할 수 없습니다.

   1. MQTT 클라이언트에서 **주제에 게시(Publish to a topic)**를 선택합니다.

   1. **주제 이름(Topic name)**에 주제 이름(**device/22/data**)을 입력합니다.

   1. **메시지 페이로드**에 다음 샘플 데이터를 입력합니다.

      ```
      {
        "temperature": 28,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. MQTT 메시지를 게시하려면 **게시**를 선택합니다.

   1. 이제 MQTT 클라이언트에서 **주제 구독(Subscribe to a topic)**을 선택합니다. **구독** 열에서 **device/\$1/data** 구독을 선택합니다. 이전 단계의 샘플 데이터가 나타나는지 확인합니다.

1. 규칙에서 생성한 DynamoDB 테이블의 행을 보려면 선택합니다.

   1. [AWS IoT 콘솔의 DynamoDB 테이블 허브에서](https://console.aws.amazon.com//dynamodb/home#tables:) **wx\$1data**를 선택한 다음 **항목** 탭을 선택합니다.

      **항목(Items)** 탭이 이미 사용 중인 경우 테이블 헤더의 오른쪽 상단 모서리에서 새로 고침 아이콘을 선택하여 디스플레이를 새로 고쳐야 할 수 있습니다.

   1. 테이블의 **sample\$1time** 값은 링크이며 하나를 엽니다. 방금 첫 번째 메시지를 전송한 경우 이는 목록에 있는 유일한 메시지입니다.

      이 링크는 테이블의 해당 행에 있는 모든 데이터를 표시합니다.

   1. **device\$1data** 항목을 확장하여 규칙 쿼리 문에서 생성된 데이터를 확인합니다.

   1. 이 디스플레이에서 사용할 수 있는 데이터의 다양한 표현을 살펴보세요. 이 디스플레이에서 데이터를 편집할 수도 있습니다.

   1. 이 데이터 행 검토를 마친 후 변경 사항을 저장하려면 **저장**을 선택하고 변경 사항을 저장하지 않고 종료하려면 **취소**를 선택합니다.

올바른 동작이 표시되지 않으면 문제 해결 팁을 확인합니다.

### DynamoDB 규칙 문제 해결
<a name="iot-ddb-rule-trouble"></a>

다음은 예상한 결과가 표시되지 않는 경우에 대비하여 확인해야 할 몇 가지 사항입니다.
+ 

**오류 배너가 있음**  
입력 메시지를 게시할 때 오류가 나타나면 먼저 해당 오류를 수정하세요. 다음 단계는 해당 오류를 수정하는 데 도움이 될 수 있습니다.
+ 

**MQTT 클라이언트에서 입력 메시지가 표시되지 않음**  
`device/+/data` 주제 필터를 구독한 경우 입력 메시지를 `device/22/data` 주제에 게시할 때마다 절차에 설명된 대로 해당 메시지가 MQTT 클라이언트에 나타나야 합니다.

**확인해야 할 사항**
  + 

**구독한 주제 필터 확인**  
절차에 설명된 대로 입력 메시지 주제를 구독한 경우 게시할 때마다 입력 메시지의 복사본이 표시되어야 합니다.

    메시지가 표시되지 않으면 구독한 주제 이름을 확인하고 게시한 주제와 비교합니다. 주제 이름은 대소문자를 구분하며 구독한 주제는 메시지 페이로드를 게시한 주제와 동일해야 합니다.
  + 

**메시지 게시 함수 확인**  
MQTT 클라이언트의 **구독**에서 **device/\$1/data**를 선택하고 게시 메시지의 주제를 확인한 다음 **주제에 게시**를 선택합니다. 주제 아래의 편집 상자에서 메시지 페이로드가 메시지 목록에 나타납니다.
+ 

**DynamoDB 테이블에 데이터가 표시되지 않음**  
가장 먼저 할 일은 테이블 헤더의 오른쪽 상단 모서리에 있는 새로 고침 아이콘을 선택하여 디스플레이를 새로 고치는 것입니다. 찾고있는 데이터가 표시되지 않으면 다음을 확인하세요.

**확인해야 할 사항**
  + 

**MQTT 클라이언트 AWS 리전 의 및 생성한 규칙을 확인합니다.**  
MQTT 클라이언트를 실행 중인 콘솔은 생성한 규칙과 동일한 AWS 리전에 있어야 합니다.
  + 

**규칙 쿼리 문의 입력 메시지 주제 확인**  
규칙이 작동하려면 규칙 쿼리 문의 FROM 절에 있는 주제 필터와 일치하는 주제 이름이 포함된 메시지를 받아야 합니다.

    MQTT 클라이언트에 있는 주제의 철자와 함께 규칙 쿼리 문에서 주제 필터의 철자를 확인하세요. 주제 이름은 대/소문자를 구분하며 메시지의 주제는 규칙 쿼리 문의 주제 필터와 일치해야 합니다.
  + 

**입력 메시지 페이로드의 내용 확인**  
규칙이 작동하려면 SELECT 문에서 선언된 메시지 페이로드에서 데이터 필드를 찾아야 합니다.

    MQTT 클라이언트에 있는 메시지 페이로드의 철자와 함께 규칙 쿼리 명령문의 `temperature` 필드 철자를 확인하세요. 필드 이름은 대소문자를 구분하며 규칙 쿼리 문의 `temperature` 필드는 메시지 페이로드의 `temperature` 필드와 동일해야 합니다.

    메시지 페이로드의 JSON 문서의 형식이 올바른지 확인하세요. JSON에 쉼표 누락과 같은 오류가 있으면 규칙에서 읽을 수 없습니다.
  + 

**규칙 작업에 사용된 키 및 필드 이름 확인**  
주제 규칙에 사용되는 필드 이름은 게시된 메시지의 JSON 메시지 페이로드에 있는 필드 이름과 일치해야 합니다.

    콘솔에서 생성한 규칙을 열고 MQTT 클라이언트에서 사용된 규칙 작업 구성의 필드 이름을 확인합니다.
  + 

**규칙에서 사용 중인 역할 확인**  
규칙 작업에는 원래 주제를 받고 새 주제를 게시할 수 있는 권한이 있어야 합니다.

    메시지 데이터를 수신하고 DynamoDB 테이블을 업데이트하도록 규칙을 인증하는 정책은 사용된 주제에 따라 다릅니다. 규칙에 사용되는 주제 또는 DynamoDB 테이블 이름을 변경하는 경우 규칙 작업의 역할을 업데이트하여 해당 정책을 일치하도록 업데이트해야 합니다.

    문제가 의심되는 경우 규칙 작업을 편집하고 새 역할을 만듭니다. 규칙 작업에 의해 생성된 새 역할에는 이러한 작업을 수행하는 데 필요한 권한이 부여됩니다.

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

이 규칙을 사용하여 DynamoDB 테이블로 몇 개의 메시지를 전송한 후 이를 실험하여 자습서의 일부 측면을 변경하면 테이블에 기록된 데이터에 어떤 영향을 주는지 확인하세요. 다음은 시작하는 데 도움이 될 몇 가지 아이디어입니다.
+ 입력 메시지의 주제에서 *device\$1id*를 변경하고 데이터의 영향을 관찰합니다. 이 기능을 사용하여 여러 기상 센서의 수신 데이터를 시뮬레이션할 수 있습니다.
+ 규칙 쿼리 문에서 선택한 필드를 변경하고 데이터의 영향을 관찰합니다. 이 옵션을 사용하여 테이블에 저장된 데이터를 필터링할 수 있습니다.
+ 테이블에 추가된 각 행에 대해 MQTT 메시지를 전송하려면 재게시 규칙 작업을 추가합니다. 디버깅에 사용할 수 있습니다.

이 자습서를 완료했으면 [자습서: AWS Lambda 함수를 사용하여 알림 형식 지정](iot-lambda-rule.md) 섹션을 확인합니다.

# 자습서: AWS Lambda 함수를 사용하여 알림 형식 지정
<a name="iot-lambda-rule"></a>

이 자습서에서는 형식 지정 및 다른 AWS 서비스로 전송을 위해 AWS Lambda 작업에 MQTT 메시지 데이터를 전송하는 방법을 보여줍니다. 이 자습서에서 AWS Lambda 작업은 AWS SDK를 사용하여에 대한 자습서에서 생성한 Amazon SNS 주제로 형식이 지정된 메시지를 보냅니다[자습서: Amazon SNS 알림 전송](iot-sns-rule.md).

[자습서: Amazon SNS 알림 전송](iot-sns-rule.md) 수행 방법에 대한 자습서에서는 규칙의 쿼리 문에서 발생한 JSON 문서가 문자 메시지의 본문으로 전송되었습니다. 결과는 다음 예제와 같은 문자 메시지입니다.

```
{"device_id":"32","reported_temperature":38,"max_temperature":30}
```

이 자습서에서는 AWS Lambda 규칙 작업을 사용하여 규칙 쿼리 문의 데이터를 다음과 같은 친숙한 형식으로 포맷하는 AWS Lambda 함수를 호출합니다.

```
Device 32 reports a temperature of 38, which exceeds the limit of 30.
```

이 자습서에서 생성할 AWS Lambda 함수는 규칙 쿼리 문의 데이터를 사용하여 메시지 문자열의 형식을 지정하고 AWS SDK의 [SNS 게시](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sns.html#SNS.Client.publish) 함수를 호출하여 알림을 생성합니다.

**이 자습서에서 배울 내용**
+  AWS Lambda 함수를 생성하고 테스트하는 방법
+  AWS Lambda 함수에서 AWS SDK를 사용하여 Amazon SNS 알림을 게시하는 방법
+ 규칙 쿼리 문에서 간단한 SQL 쿼리 및 함수를 사용하는 방법
+ MQTT 클라이언트를 사용하여 AWS IoT 규칙을 테스트하는 방법

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

**Topics**
+ [1단계: 텍스트 메시지를 보내는 AWS Lambda 함수 생성](#iot-lambda-rule-create-lambda)
+ [2단계: AWS IoT 규칙 작업을 사용하여 AWS Lambda 규칙 생성](#iot-lambda-rule-create-rule)
+ [3단계: AWS IoT 규칙 및 AWS Lambda 규칙 작업 테스트](#iot-lambda-rule-test-rule)
+ [4단계: 결과 및 다음 단계 검토](#iot-lambda-rule-next-steps)

**이 자습서를 시작하기 전에 다음 사항을 확인해야 합니다.**
+ 

**[설정 AWS 계정](setting-up.md)**  
이 자습서를 완료하려면 AWS 계정 및 AWS IoT 콘솔이 필요합니다.
+ 

**검토된 [MQTT 클라이언트를 사용하여 AWS IoT MQTT 메시지 보기](view-mqtt-messages.md)**  
MQTT 클라이언트를 사용하여 주제를 구독하고 게시할 수 있는지 확인하세요. 이 절차에서는 MQTT 클라이언트를 사용하여 새 규칙을 테스트합니다.
+ 

**이 섹션의 다른 규칙 자습서를 완료했습니다.**  
이 자습서에는 [자습서: Amazon SNS 알림 전송](iot-sns-rule.md) 수행 방법에 대한 자습서에서 생성한 SNS 알림 주제가 필요합니다. 또한 이 섹션의 다른 규칙 관련 자습서를 완료했다고 가정합니다.
+ 

**[AWS Lambda](https://docs.aws.amazon.com//lambda/latest/dg/welcome.html) 개요를 검토했습니다.**  
 AWS Lambda 이전에를 사용한 적이 없는 경우 [AWS Lambda](https://docs.aws.amazon.com//lambda/latest/dg/welcome.html) 및 [Lambda 시작하기를](https://docs.aws.amazon.com//lambda/latest/dg/getting-started.html) 검토하여 해당 용어와 개념을 알아봅니다.

## 1단계: 텍스트 메시지를 보내는 AWS Lambda 함수 생성
<a name="iot-lambda-rule-create-lambda"></a>

이 자습서의 AWS Lambda 함수는 규칙 쿼리 문의 결과를 수신하고 요소를 텍스트 문자열에 삽입한 다음 결과 문자열을 Amazon SNS에 알림의 메시지로 보냅니다.

규칙 작업을 사용하여 AWS IoT 알림을 보내는 방법에 대한 자습서[자습서: Amazon SNS 알림 전송](iot-sns-rule.md)와 달리이 자습서에서는 AWS SDK의 함수를 사용하여 Lambda 함수에서 알림을 보냅니다. 그러나 이 자습서에서 사용된 실제 Amazon SNS 알림 주제는 [자습서: Amazon SNS 알림 전송](iot-sns-rule.md) 수행 방법에 대한 자습서에서 사용한 것과 동일합니다.

**텍스트 메시지를 보내는 AWS Lambda 함수를 생성하려면**

1. 새 AWS Lambda 함수를 생성합니다.

   1. [AWS Lambda 콘솔](https://console.aws.amazon.com//lambda/home)에서 **함수 생성**을 선택합니다.

   1. **함수 생성(Create function)**에서 **블루프린트 사용(Use a blueprint)**을 선택합니다.

      **hello-world-python** 블루프린트를 검색하여 선택한 다음 **구성**을 선택합니다.

   1. **기본 정보(Basic information)**에서:

      1. **Function name(함수 이름)**에 이 함수 이름(**format-high-temp-notification**)을 입력합니다.

      1. **실행 역할**에서 ** AWS 정책 템플릿에서 새 역할 생성을** 선택합니다.

      1. 역할 이름에 새 역할의 이름(**format-high-temp-notification-role**)을 입력합니다.

      1. **정책 템플릿 - *선택 사항***에서 **Amazon SNS 게시 정책**을 검색하고 선택합니다.

      1. **함수 생성**을 선택합니다.

1. 블루프린트 코드를 수정하여 Amazon SNS 알림의 형식을 지정하고 전송합니다.

   1. 함수를 생성한 후에는 **format-high-temp-notification** 세부 정보 페이지를 참조하세요. 그렇지 않은 경우 [Lambda **함수**](https://console.aws.amazon.com//lambda/home#/functions) 페이지에서 엽니다.

   1. **format-high-temp-notification** 세부 정보 페이지에서 **구성(Configuration)** 탭을 선택하고 **함수 코드(Function code)** 패널로 스크롤합니다.

   1. **함수 코드(Function code)** 창의 **환경(Environment)** 창에서 Python 파일(`lambda_function.py`)을 선택합니다.

   1. **함수 코드(Function code)** 창에서 블루프린트의 원본 프로그램 코드를 모두 삭제하고 이 코드로 교체합니다.다.

      ```
      import boto3
      #
      #   expects event parameter to contain:
      #   {
      #       "device_id": "32",
      #       "reported_temperature": 38,
      #       "max_temperature": 30,
      #       "notify_topic_arn": "arn:aws:sns:us-east-1:57EXAMPLE833:high_temp_notice"
      #   }
      # 
      #   sends a plain text string to be used in a text message
      #
      #      "Device {0} reports a temperature of {1}, which exceeds the limit of {2}."
      #   
      #   where:
      #       {0} is the device_id value
      #       {1} is the reported_temperature value
      #       {2} is the max_temperature value
      #
      def lambda_handler(event, context):
      
          # Create an SNS client to send notification
          sns = boto3.client('sns')
      
          # Format text message from data
          message_text = "Device {0} reports a temperature of {1}, which exceeds the limit of {2}.".format(
                  str(event['device_id']),
                  str(event['reported_temperature']),
                  str(event['max_temperature'])
              )
      
          # Publish the formatted message
          response = sns.publish(
                  TopicArn = event['notify_topic_arn'],
                  Message = message_text
              )
      
          return response
      ```

   1. **배포(Deploy)**를 선택합니다.

1. 새 창에서 [자습서: Amazon SNS 알림 전송](iot-sns-rule.md) 수행 방법에 대한 자습서에서 Amazon SNS 주제의 Amazon 리소스 이름(ARN)을 조회합니다.

   1. 새 창에서 [Amazon SNS 콘솔의 주제 페이지](https://console.aws.amazon.com//sns/v3/home#/topics)를 엽니다.

   1. **주제** 페이지에서 Amazon SNS 주제 목록에서 **high\$1temp\$1notice** 알림 주제를 찾습니다.

   1. 다음 단계에서 사용할 **high\$1temp\$1notice** 알림 주제의 **ARN**을 찾습니다.

1. Lambda 함수에 대한 테스트 케이스 생성

   1. 콘솔의 [Lambda **함수**](https://console.aws.amazon.com//lambda/home#/functions) 페이지에서 **format-high-temp-notification** 세부 정보 페이지 오른쪽 상단 모서리에 있는 **테스트 이벤트 선택(Select a test event)**(비활성화된 것처럼 보이더라도)을 선택한 다음 **테스트 이벤트 구성(Configure test events)**을 선택합니다.

   1. **테스트 이벤트 구성(Configure test event)**에서 **새 테스트 이벤트 구성(Create new test event)**을 선택합니다.

   1. **이벤트 이름**에 **SampleRuleOutput**을 입력합니다.

   1. JSON 편집기에서 **이벤트 이름** 아래에 이 샘플 JSON 문서를 붙여 넣습니다. 다음은 AWS IoT 규칙이 Lambda 함수로 전송할 항목의 예입니다.

      ```
      {
        "device_id": "32",
        "reported_temperature": 38,
        "max_temperature": 30,
        "notify_topic_arn": "arn:aws:sns:us-east-1:57EXAMPLE833:high_temp_notice"
      }
      ```

   1. **high\$1temp\$1notice** 알림 주제의 **ARN**이 있는 창을 참조하여 ARN 값을 복사합니다.

   1. JSON 편집기의 `notify_topic_arn` 값을 알림 주제의 ARN으로 바꿉니다.

       AWS IoT 규칙을 생성할 때 이 ARN 값을 다시 사용할 수 있도록 이 창을 열어 두세요.

   1. **생성(Create)**을 선택합니다.

1. 샘플 데이터로 함수를 테스트합니다.

   1. **format-high-temp-notification** 세부 정보 페이지의 오른쪽 상단 모서리에서 **SampleRuleOutput**이 **테스트(Test)** 버튼 옆에 나타나는지 확인합니다. 그렇지 않은 경우 사용 가능한 테스트 이벤트 목록에서 선택합니다.

   1. 함수에 샘플 규칙 출력 메시지를 전송하려면 **테스트(Test)**를 선택합니다.

함수와 알림이 모두 작동하면 알림을 구독한 휴대 전화에서 문자 메시지를 받습니다.

휴대 전화에서 문자 메시지를 받지 못한 경우 작업 결과를 확인하세요. **함수 코드** 패널의 **실행 결과** 탭에서 응답을 검토하여 발생한 오류를 찾습니다. 함수가 휴대폰으로 알림을 전송할 때까지 다음 단계로 이행하지 마세요.

## 2단계: AWS IoT 규칙 작업을 사용하여 AWS Lambda 규칙 생성
<a name="iot-lambda-rule-create-rule"></a>

이 단계에서는 규칙 쿼리 문을 사용하여 가상 기상 센서 디바이스의 데이터 형식을 Lambda 함수로 전송하여 문자 메시지를 형식 지정하고 전송합니다.

기상 디바이스에서 받은 샘플 메시지 페이로드는 다음과 같습니다.

```
{
  "temperature": 28,
  "humidity": 80,
  "barometer": 1013,
  "wind": {
    "velocity": 22,
    "bearing": 255
  }
}
```

이 규칙에서는 규칙 쿼리 문을 사용하여 다음과 같은 Lambda 함수에 대한 메시지 페이로드를 만듭니다.

```
{
  "device_id": "32",
  "reported_temperature": 38,
  "max_temperature": 30,
  "notify_topic_arn": "arn:aws:sns:us-east-1:57EXAMPLE833:high_temp_notice"
}
```

여기에는 Lambda 함수가 올바른 문자 메시지로 형식을 지정하고 전송하는 데 필요한 모든 정보가 들어 있습니다.

**Lambda 함수를 호출하는 AWS IoT 규칙을 생성하려면**

1. [AWS IoT 콘솔의 **규칙** 허브를](https://console.aws.amazon.com//iot/home#/rulehub) 엽니다.

1. **규칙**에서 새 규칙 생성을 시작하려면 **생성**을 선택합니다.

1. **규칙 생성**의 상단 부분에서:

   1. **이름**에 규칙 이름 **wx\$1friendly\$1text**를 입력합니다.

      규칙 이름은 AWS 계정 및 리전 내에서 고유해야 하며 공백을 가질 수 없습니다. 이 이름에 밑줄 문자를 사용하여 규칙 이름의 두 단어를 구분했습니다.

   1.  **설명**에서 규칙을 설명합니다.

      의미 있는 설명을 사용하면 이 규칙이 수행하는 작업과 규칙을 만든 이유를 쉽게 기억할 수 있습니다. 설명은 필요한 만큼 길어질 수 있으므로 가능한 한 자세하게 설명하세요.

1. **규칙 생성**의 **규칙 쿼리 문**에서:

   1.  **SQL 버전 사용**에서 **2016-03-23**을(를) 선택합니다.

   1. **규칙 쿼리 문** 편집 상자에 쿼리 문을 입력합니다.

      ```
      SELECT 
        cast(topic(2) AS DECIMAL) as device_id, 
        temperature as reported_temperature,
        30 as max_temperature,
        'arn:aws:sns:us-east-1:57EXAMPLE833:high_temp_notice' as notify_topic_arn
      FROM 'device/+/data' WHERE temperature > 30
      ```

      이 문은 다음을 수행합니다.
      + `device/+/data` 주제 필터와 일치하고 `temperature` 값이 30보다 큰 주제가 있는 MQTT 메시지를 수신 대기합니다.
      + 주제 문자열에서 두 번째 요소를 선택하고 10진수로 변환한 다음 `device_id` 필드에 할당합니다.
      + 메시지 페이로드에서 `temperature` 값 필드를 선택하여 `reported_temperature` 필드에 할당합니다.
      + 한계 값을 나타내는 상수 값 `30`을 생성하고 `max_temperature` 필드에 할당합니다.
      + `notify_topic_arn` 필드에 대한 상수 값을 만듭니다.

   1. **high\$1temp\$1notice** 알림 주제의 **ARN**이 있는 창을 참조하여 ARN 값을 복사합니다.

   1. 규칙 쿼리 문 편집기의 ARN 값(*arn:aws:sns:us-east-1:57EXAMPLE833:high\$1temp\$1notice*)을 알림 주제의 ARN으로 바꿉니다.

1. **하나 이상의 작업 설정**에서:

   1. 이 규칙에 대한 규칙 작업 목록을 열려면 **작업 추가**를 선택합니다.

   1. **작업 선택(Select an action)**에서 **Lambda 함수로 메시지 전송하기(Send a message to a Lambda function)**를 선택합니다.

   1. 작업 목록 하단에서 선택한 작업의 구성 페이지를 열려면 **구성 작업**을 선택합니다.

1. **구성 작업**에서:

   1. **함수 이름**에서 **선택(Select)**을 클릭합니다.

   1. **format-high-temp-notification**을 선택합니다.

   1. **작업 구성(Configure action)** 하단에서 **작업 추가(Add action)**를 선택합니다.

   1. 규칙을 생성하려면 **규칙 생성(Create a rule)** 하단에서 **규칙 생성(Create rule)**을 선택합니다.

## 3단계: AWS IoT 규칙 및 AWS Lambda 규칙 작업 테스트
<a name="iot-lambda-rule-test-rule"></a>

새 규칙을 테스트하려면 MQTT 클라이언트를 사용하여 이 규칙에서 사용하는 MQTT 메시지를 게시하고 구독합니다.

새 창에서 [AWS IoT 콘솔의 MQTT 클라이언트](https://console.aws.amazon.com//iot/home#/test)를 엽니다. 이제 MQTT 클라이언트의 구성을 그대로 유지하면서 규칙을 편집할 수 있습니다. MQTT 클라이언트를 떠나 콘솔의 다른 페이지로 이동하면 구독 또는 메시지 로그가 손실됩니다.

**MQTT 클라이언트를 사용하여 규칙을 테스트하려면**

1. [AWS IoT 콘솔의 MQTT 클라이언트](https://console.aws.amazon.com//iot/home#/test)에서 입력 주제(이 경우 `device/+/data`)를 구독합니다.

   1. MQTT 클라이언트에서 **구독** 아래에서 **주제 구독**을 선택합니다.

   1. **구독 주제**에 입력 주제 필터 **device/\$1/data**의 주제를 입력합니다.

   1. 나머지 필드는 기본 설정을 유지합니다.

   1. **주제 구독**을 선택합니다.

      **구독** 열의 **주제 게시** 아래에 **device/\$1/data**가 나타납니다.

1. 특정 디바이스 ID **device/32/data**로 입력 주제에 메시지를 게시합니다. 와일드카드 문자가 포함된 MQTT 항목에는 게시할 수 없습니다.

   1. MQTT 클라이언트의 **구독** 아래에서 **주제 게시**를 선택합니다.

   1. **게시** 필드에 입력 주제 이름 **device/32/data**를 입력합니다.

   1. 여기에 표시된 샘플 데이터를 복사하고 주제 이름 아래의 편집 상자에 샘플 데이터를 붙여 넣습니다.

      ```
      {
        "temperature": 38,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. MQTT 메시지를 게시하려면 **주제에 게시(Publish to topic)**를 선택합니다.

1. 문자 메시지가 전송되었는지 확인합니다.

   1. MQTT 클라이언트의 **구독** 아래에서 이전에 구독한 주제 옆에 녹색 점이 있습니다.

      녹색 점은 마지막으로 메시지를 보았을 때 하나 이상의 새 메시지가 수신되었음을 나타냅니다.

   1. **구독** 아래에서 **device/\$1/data**를 선택하여 메시지 페이로드가 방금 게시한 것과 일치하고 다음과 같이 표시되는지 확인하세요.

      ```
      {
        "temperature": 38,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. SNS 주제를 구독하는 데 사용한 전화를 확인하고 메시지 페이로드의 내용이 다음과 같이 표시되는지 확인합니다.

      ```
      Device 32 reports a temperature of 38, which exceeds the limit of 30.
      ```

      메시지 주제에서 주제 ID 요소를 변경하는 경우 메시지 주제의 해당 요소에 숫자만 포함된 경우에만 `topic(2)` 값을 숫자 값으로 캐스팅할 수 있다는 점을 기억하세요.

1. 온도가 한계를 초과하지 않는 MQTT 메시지를 전송해보세요.

   1. MQTT 클라이언트의 **구독** 아래에서 **주제 게시**를 선택합니다.

   1. **게시** 필드에 입력 주제 이름 **device/33/data**를 입력합니다.

   1. 여기에 표시된 샘플 데이터를 복사하고 주제 이름 아래의 편집 상자에 샘플 데이터를 붙여 넣습니다.

      ```
      {
        "temperature": 28,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. MQTT 메시지를 전송하려면 **주제 게시**를 선택합니다.

   **device/\$1/data** 구독에서 전송한 메시지가 표시되어야 하지만 온도 값이 규칙 쿼리 문에서 최대 온도보다 낮기 때문에 문자 메시지를 받지 않아야 합니다.

   올바른 동작이 표시되지 않으면 문제 해결 팁을 확인합니다.

### AWS Lambda 규칙 및 알림 문제 해결
<a name="iot-lambda-rule-troubleshoot"></a>

예상한 결과가 표시되지 않는 경우를 대비하여 확인해야 할 몇 가지 사항이 있습니다.
+ 

**오류 배너가 있음**  
입력 메시지를 게시할 때 오류가 나타나면 먼저 해당 오류를 수정하세요. 다음 단계는 해당 오류를 수정하는 데 도움이 될 수 있습니다.
+ 

**MQTT 클라이언트에서 입력 메시지가 표시되지 않음**  
`device/+/data` 주제 필터를 구독한 경우 입력 메시지를 `device/32/data` 주제에 게시할 때마다 절차에 설명된 대로 해당 메시지가 MQTT 클라이언트에 나타나야 합니다.

**확인해야 할 사항**
  + 

**구독한 주제 필터 확인**  
절차에 설명된 대로 입력 메시지 주제를 구독한 경우 게시할 때마다 입력 메시지의 복사본이 표시되어야 합니다.

    메시지가 표시되지 않으면 구독한 주제 이름을 확인하고 게시한 주제와 비교합니다. 주제 이름은 대소문자를 구분하며 구독한 주제는 메시지 페이로드를 게시한 주제와 동일해야 합니다.
  + 

**메시지 게시 함수 확인**  
MQTT 클라이언트의 **구독**에서 **device/\$1/data**를 선택하고 게시 메시지의 주제를 확인한 다음 **주제에 게시**를 선택합니다. 주제 아래의 편집 상자에서 메시지 페이로드가 메시지 목록에 나타납니다.
+ 

**SMS 메시지가 수신되지 않음**  
규칙이 작동하려면 메시지를 수신하고 SNS 알림을 전송할 수 있도록 권한을 부여하는 올바른 정책이 있어야 하며 메시지를 수신해야 합니다.

**확인해야 할 사항**
  + 

**MQTT 클라이언트 AWS 리전 의 및 생성한 규칙을 확인합니다.**  
MQTT 클라이언트를 실행 중인 콘솔은 생성한 규칙과 동일한 AWS 리전에 있어야 합니다.
  + 

**메시지 페이로드의 온도 값이 테스트 임계값을 초과하는지 확인**  
규칙 쿼리 문에 정의된 대로 온도 값이 30보다 작거나 같으면 규칙은 해당 작업을 수행하지 않습니다.
  + 

**규칙 쿼리 문의 입력 메시지 주제 확인**  
규칙이 작동하려면 규칙 쿼리 문의 FROM 절에 있는 주제 필터와 일치하는 주제 이름이 포함된 메시지를 받아야 합니다.

    MQTT 클라이언트에 있는 주제의 철자와 함께 규칙 쿼리 문에서 주제 필터의 철자를 확인하세요. 주제 이름은 대/소문자를 구분하며 메시지의 주제는 규칙 쿼리 문의 주제 필터와 일치해야 합니다.
  + 

**입력 메시지 페이로드의 내용 확인**  
규칙이 작동하려면 SELECT 문에서 선언된 메시지 페이로드에서 데이터 필드를 찾아야 합니다.

    MQTT 클라이언트에 있는 메시지 페이로드의 철자와 함께 규칙 쿼리 명령문의 `temperature` 필드 철자를 확인하세요. 필드 이름은 대소문자를 구분하며 규칙 쿼리 문의 `temperature` 필드는 메시지 페이로드의 `temperature` 필드와 동일해야 합니다.

    메시지 페이로드의 JSON 문서의 형식이 올바른지 확인하세요. JSON에 쉼표 누락과 같은 오류가 있으면 규칙에서 읽을 수 없습니다.
  + 

**Amazon SNS 알림 확인**  
[1단계: SMS 문자 메시지를 전송하는 Amazon SNS 주제 생성](iot-sns-rule.md#iot-sns-rule-create-sns-topic)에서 Amazon SNS 알림을 테스트하고 알림을 테스트하여 알림이 작동하는지 확인하는 방법을 설명하는 3단계를 참조하세요.
  + 

**Lambda 함수 확인**  
[1단계: 텍스트 메시지를 보내는 AWS Lambda 함수 생성](#iot-lambda-rule-create-lambda)에서 테스트 데이터를 사용하여 Lambda 함수를 테스트하고 Lambda 함수를 테스트하는 방법을 설명하는 5단계를 참조하세요.
  + 

**규칙에서 사용 중인 역할 확인**  
규칙 작업에는 원래 주제를 받고 새 주제를 게시할 수 있는 권한이 있어야 합니다.

    메시지 데이터를 수신하고 다시 게시하도록 규칙을 인증하는 정책은 사용된 주제에 따라 다릅니다. 메시지 데이터를 다시 게시하는 데 사용되는 주제를 변경하는 경우 규칙 작업의 역할을 업데이트하여 현재 주제와 일치하도록 정책을 업데이트해야 합니다.

    문제가 의심되는 경우 규칙 재게시 작업을 편집하고 새 역할을 만듭니다. 규칙 작업에 의해 생성된 새 역할에는 이러한 작업을 수행하는 데 필요한 권한이 부여됩니다.

## 4단계: 결과 및 다음 단계 검토
<a name="iot-lambda-rule-next-steps"></a>

**이 자습서에서는:**
+ 사용자 지정 메시지 페이로드를 사용한 Amazon SNS 알림을 보낸 Lambda 함수를 호출하는 AWS IoT 규칙을 생성했습니다.
+ 규칙 쿼리 문에서 간단한 SQL 쿼리와 함수를 사용하여 Lambda 함수에 대한 새 메시지 페이로드를 만들었습니다.
+ MQTT 클라이언트를 사용하여 AWS IoT 규칙을 테스트했습니다.

**다음 단계**  
이 규칙을 사용하여 몇 가지 문자 메시지를 전송한 후 이 규칙을 실험하여 자습서의 일부 측면을 변경하면 메시지가 전송되는 시기에 영향을 받는지 확인하세요. 다음은 시작하는 데 도움이 될 몇 가지 아이디어입니다.
+ 입력 메시지의 주제에서 *device\$1id*를 변경하고 문자 메시지 내용의 영향을 관찰합니다.
+ 규칙 쿼리 문에서 선택한 필드를 변경하고, 새 메시지에서 사용하도록 Lambda 함수를 업데이트하고, 문자 메시지 내용의 영향을 관찰합니다.
+ 최대 온도 대신 최소 온도에 대한 테스트 규칙 쿼리 문에서 테스트를 변경합니다. Lambda 함수를 업데이트하여 새 메시지 형식을 지정하고 `max_temperature` 이름을 변경하는 것을 잊지 마세요.
+  AWS IoT 규칙을 개발하고 사용하는 동안 발생할 수 있는 오류를 찾는 방법에 대한 자세한 내용은 섹션을 참조하세요[모니터링 AWS IoT](monitoring_overview.md).

# 디바이스 섀도우로 디바이스가 오프라인 상태일 때 디바이스 상태 유지
<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) 단원을 참조하세요.

# 자습서:에 대한 사용자 지정 권한 부여자 생성 AWS IoT Core
<a name="custom-auth-tutorial"></a>

이 자습서에서는 AWS CLI을(를) 사용하여 사용자 지정 인증을 만들고 유효성을 검사하고 사용하는 단계를 보여 줍니다. 선택적으로 이 자습서를 사용하여 HTTP 게시 API를 통해 AWS IoT Core 에 데이터를 전송할 수 있도록 Postman을 사용할 수 있습니다.

이 자습서에서는 권한 부여 및 인증 논리를 구현하는 샘플 Lambda 함수와 토큰 서명이 활성화된 상태에서 **create-authorizer** 호출을 사용하는 사용자 지정 권한 부여자를 생성하는 방법을 보여줍니다. 그런 다음 권한 부여자는를 사용하여 검증되며**test-invoke-authorizer**, 마지막으로 HTTP 게시 API를 AWS IoT Core 사용하여 테스트 MQTT 주제에 데이터를 전송할 수 있습니다. 샘플 요청은 `x-amz-customauthorizer-name` 헤더를 사용하여 호출할 권한 부여자를 지정하고, 요청 헤더에 토큰 키 이름과 `x-amz-customauthorizer-signature`을(를) 전달합니다.

**이 자습서에서 배울 내용:**
+ Lambda 함수를 사용자 지정 권한 부여 처리기로 만드는 방법
+ 토큰 서명이 활성화된 AWS CLI 를 사용하여 사용자 지정 권한 부여자를 생성하는 방법
+ **test-invoke-authorizer** 명령을 사용하여 사용자 지정 권한 부여자를 테스트 하는 방법
+ [Postman](https://www.postman.com/)을 사용하여 MQTT 항목을 게시하는 방법 및 사용자 정의 권한 부여자로 요청을 검증하는 방법

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

**Topics**
+ [1단계: 사용자 지정 권한 부여자를 위한 Lambda 함수 생성](#custom-auth-tutorial-define)
+ [2단계: 사용자 지정 권한 부여자를 위한 퍼블릭 및 프라이빗 키 페어 생성](#custom-auth-tutorial-keys)
+ [3단계: 사용자 지정 권한 부여자 리소스 및 권한 부여 생성](#custom-auth-tutorial-authorizer)
+ [4단계: test-invoke-authorizer를 호출하여 권한 부여자 테스트](#custom-auth-tutorial-test)
+ [5단계: Postman을 사용하여 MQTT 메시지 게시 테스트](#custom-auth-tutorial-postman)
+ [6단계: MQTT 테스트 클라이언트에서 메시지 보기](#custom-auth-tutorial-testclient)
+ [7단계: 결과 및 다음 단계 검토](#custom-auth-tutorial-review)
+ [8단계: 정리](#custom-auth-tutorial-cleanup)

**이 자습서를 시작하기 전에 다음 사항을 확인해야 합니다.**
+ 

**[설정 AWS 계정](setting-up.md)**  
이 자습서를 완료하려면 AWS 계정 및 AWS IoT 콘솔이 필요합니다.

  이 자습서에 사용하는 계정은 적어도 이러한 AWS 관리형 정책을 포함 할 때 가장 잘 작동합니다.
  + [https://console.aws.amazon.com//iam/home#/policies/arn:aws:iam::aws:policy/IAMFullAccess$jsonEditor](https://console.aws.amazon.com//iam/home#/policies/arn:aws:iam::aws:policy/IAMFullAccess$jsonEditor)
  + [https://console.aws.amazon.com//iam/home#/policies/arn:aws:iam::aws:policy/AWSIoTFullAccess$jsonEditor](https://console.aws.amazon.com//iam/home#/policies/arn:aws:iam::aws:policy/AWSIoTFullAccess$jsonEditor)
  + [https://console.aws.amazon.com//iam/home#/policies/arn:aws:iam::aws:policy/AWSLambda_FullAccess$jsonEditor](https://console.aws.amazon.com//iam/home#/policies/arn:aws:iam::aws:policy/AWSLambda_FullAccess$jsonEditor)
**중요**  
이 자습서에서 사용된 IAM 정책은 프로덕션 구현에서 따라야 하는 것보다 권한이 많습니다. 프로덕션 환경에서는 계정 및 리소스 정책이 필요한 권한만 부여하도록 해야 합니다.  
프로덕션용 IAM 정책을 생성할 때는 사용자 및 역할이 필요로 하는 액세스 수준을 결정한 다음 사용자들이 이러한 작업만 수행할 수 있도록 허용하는 정책을 설계합니다.  
자세한 내용은 [IAM의 보안 모범 사례](https://docs.aws.amazon.com//IAM/latest/UserGuide/best-practices.html)를 참조하세요.
+ 

**를 설치했습니다. AWS CLI**  
설치 방법에 대한 자세한 내용은 CLI 설치를 AWS CLI참조하세요. [AWS](https://docs.aws.amazon.com//cli/latest/userguide/cli-chap-install.html) 이 자습서에는 AWS CLI 버전 `aws-cli/2.1.3 Python/3.7.4 Darwin/18.7.0 exe/x86_64` 이상이 필요합니다.
+ 

**OpenSSL 도구**  
이 자습서의 예제에서는 [LibreSSL 2.6.5](https://www.libressl.org/)를 사용합니다. 이 자습서를 위해서는 [OpenSSL v1.1.1i](https://www.openssl.org/) 도구도 사용할 수 있습니다.
+ 

**[AWS Lambda](https://docs.aws.amazon.com//lambda/latest/dg/welcome.html) 개요 검토**  
 AWS Lambda 이전에를 사용한 적이 없는 경우 [AWS Lambda](https://docs.aws.amazon.com//lambda/latest/dg/welcome.html) 및 [Lambda 시작하기를](https://docs.aws.amazon.com//lambda/latest/dg/getting-started.html) 검토하여 해당 용어와 개념을 알아봅니다.
+ 

**Postman에서 요청을 빌드하는 방법 검토**  
자세한 내용은 [요청 빌드](https://learning.postman.com/docs/sending-requests/requests/) 단원을 참조하세요.
+ 

**이전 자습서의 사용자 지정 권한 부여자 제거**  
에는 한 번에 제한된 수의 사용자 지정 권한 부여자만 구성할 AWS 계정 수 있습니다. 사용자 지정 권한 부여자를 제거하는 방법에 대한 자세한 내용은 [8단계: 정리](#custom-auth-tutorial-cleanup) 단원을 참조하세요.

## 1단계: 사용자 지정 권한 부여자를 위한 Lambda 함수 생성
<a name="custom-auth-tutorial-define"></a>

의 사용자 지정 인증 AWS IoT Core 은 사용자가 생성한 [권한 부여자 리소스를](https://docs.aws.amazon.com//iot/latest/apireference/API_AuthorizerDescription.html) 사용하여 클라이언트를 인증하고 권한을 부여합니다. 이 섹션에서 생성할 함수는 클라이언트가 AWS IoT 리소스에 연결하고 액세스할 때 클라이언트를 인증 AWS IoT Core 하고 승인합니다.

Lambda 함수는 다음 작업을 수행합니다.
+ **test-invoke-authorizer**에서 요청이 오는 경우 `Deny` 작업과 함께 IAM 정책을 반환합니다.
+ 요청이 HTTP를 사용하여 Postma에서 오고 `actionToken` 파라미터 값이 `allow`이면 `Allow` 작업과 함께 IAM 정책을 반환합니다. 그렇지 않은 경우`Deny` 작업과 함께 IAM 정책을 반환합니다.

**사용자 지정 권한 부여자에 대한 Lambda 함수를 생성하려면**

1. [Lambda](https://console.aws.amazon.com//lambda/home#) 콘솔에서 [함수](https://console.aws.amazon.com//lambda/home#/functions)를 엽니다.

1. **함수 생성**을 선택합니다.

1. **처음부터 작성(Author from scratch)**이 선택되어 있는지 확인합니다.

1. **기본 정보**에서

   1. **함수 이름**에 **custom-auth-function**을(를) 입력합니다.

   1. **런타임**에서 **Node.js 18.x**를 확인합니다.

1. **함수 생성**을 선택합니다.

   Lambda는 Node.js 함수와 로그 업로드 권한을 함수에 부여하는 [실행 역할](https://docs.aws.amazon.com//lambda/latest/dg/lambda-intro-execution-role.html)을 생성합니다. Lambda 함수는 함수를 호출할 때 실행 역할을 수임하고 실행 역할을 사용하여 AWS SDK에 대한 자격 증명을 생성하고 이벤트 소스에서 데이터를 읽습니다.

1. [AWS Cloud9](https://docs.aws.amazon.com/cloud9/latest/user-guide/welcome.html) 편집기에서 함수의 코드 및 구성을 보려면 디자이너 창에서 **custom-auth-function**을 선택한 후 편집기 탐색 창에서 **index.js**를 선택합니다.

   Node.js 같은 스크립트 언어의 경우 Lambda는 성공 응답을 반환하는 기본 함수를 포함합니다. 소스 코드가 3MB를 초과하지 않는 한 [AWS Cloud9](https://docs.aws.amazon.com/cloud9/latest/user-guide/welcome.html) 편집기를 사용하여 함수를 편집할 수 있습니다.

1. 다음 코드를 사용하여 편집기에서 **index.js** 코드를 대체합니다.

   ```
   // A simple Lambda function for an authorizer. It demonstrates
   // How to parse a CLI and Http password to generate a response.
   
   export const handler = async (event, context, callback) => {
   
       //Http parameter to initiate allow/deny request
       const HTTP_PARAM_NAME='actionToken';
       const ALLOW_ACTION = 'Allow';
       const DENY_ACTION = 'Deny';
   
       //Event data passed to Lambda function
       var event_str = JSON.stringify(event);
       console.log('Complete event :'+ event_str);
   
       //Read protocolData from the event json passed to Lambda function
       var protocolData = event.protocolData;
       console.log('protocolData value---> ' + protocolData);
   
       //Get the dynamic account ID from function's ARN to be used
       // as full resource for IAM policy
       var ACCOUNT_ID = context.invokedFunctionArn.split(":")[4];
       console.log("ACCOUNT_ID---"+ACCOUNT_ID);
   
       //Get the dynamic region from function's ARN to be used
       // as full resource for IAM policy
       var REGION = context.invokedFunctionArn.split(":")[3];
       console.log("REGION---"+REGION);
   
       //protocolData data will be undefined if testing is done via CLI.
       // This will help to test the set up.
       if (protocolData === undefined) {
   
           //If CLI testing, pass deny action as this is for testing purpose only.
           console.log('Using the test-invoke-authorizer cli for testing only');
           callback(null, generateAuthResponse(DENY_ACTION,ACCOUNT_ID,REGION));
   
       } else{
   
           //Http Testing from Postman
           //Get the query string from the request
           var queryString = event.protocolData.http.queryString;
           console.log('queryString values -- ' + queryString);
           /*         global URLSearchParams       */
           const params = new URLSearchParams(queryString);
           var action = params.get(HTTP_PARAM_NAME);
   
           if(action!=null && action.toLowerCase() === 'allow'){
   
               callback(null, generateAuthResponse(ALLOW_ACTION,ACCOUNT_ID,REGION));
   
           }else{
   
               callback(null, generateAuthResponse(DENY_ACTION,ACCOUNT_ID,REGION));
   
           }
   
       }
   
   };
   
   // Helper function to generate the authorization IAM response.
   var generateAuthResponse = function(effect,ACCOUNT_ID,REGION) {
   
       var full_resource = "arn:aws:iot:"+ REGION + ":" + ACCOUNT_ID + ":*";
       console.log("full_resource---"+full_resource);
   
       var authResponse = {};
       authResponse.isAuthenticated = true;
       authResponse.principalId = 'principalId';
   
       var policyDocument = {};
       policyDocument.Version = '2012-10-17';		 	 	 
       policyDocument.Statement = [];
       var statement = {};
       statement.Action = 'iot:*';
       statement.Effect = effect;
       statement.Resource = full_resource;
       policyDocument.Statement[0] = statement;
       authResponse.policyDocuments = [policyDocument];
       authResponse.disconnectAfterInSeconds = 3600;
       authResponse.refreshAfterInSeconds = 600;
   
       console.log('custom auth policy function called from http');
       console.log('authResponse --> ' + JSON.stringify(authResponse));
       console.log(authResponse.policyDocuments[0]);
   
       return authResponse;
   }
   ```

1. **배포**를 선택합니다.

1. 편집기 위에 **변경 사항 배포됨(Changes deployed)**이 나타나면

   1. 편집기 위의 **함수 개요(Function overview)** 섹션으로 스크롤합니다.

   1. 이 자습서의 후반부에서 사용할 수 있도록 **함수 ARN**을 복사하여 저장해 둡니다.

1.  함수를 테스트합니다.

   1. **테스트** 탭을 선택합니다.

   1. 기본 테스트 설정을 사용하여 **호출(Invoke)**을 선택합니다.

   1. 테스트가 성공한 경우 **실행 결과(Execution results)**에서 **세부 정보(Details)** 보기를 엽니다. 함수가 반환한 정책 문서가 표시되어야 합니다.

      테스트에 실패했거나 정책 문서가 표시되지 않으면 코드를 검토하여 오류를 찾아 수정합니다.

## 2단계: 사용자 지정 권한 부여자를 위한 퍼블릭 및 프라이빗 키 페어 생성
<a name="custom-auth-tutorial-keys"></a>

사용자 지정 권한 부여자를 인증하려면 퍼블릭 및 프라이빗 키가 필요합니다. 이 섹션의 명령은 OpenSSL 도구를 사용하여 이 키 페어를 생성합니다.

**사용자 지정 권한 부여자를 위한 퍼블릭 및 프라이빗 키 페어를 생성하려면**

1. 프라이빗 키 파일을 생성합니다.

   ```
   openssl genrsa -out private-key.pem 4096
   ```

1. 방금 생성한 프라이빗 키 파일을 확인합니다.

   ```
   openssl rsa -check -in private-key.pem -noout
   ```

   명령에 오류가 표시되지 않으면 프라이빗 키 파일이 유효합니다.

1. 퍼블릭 키 파일을 생성합니다.

   ```
   openssl rsa -in private-key.pem -pubout -out public-key.pem
   ```

1. 퍼블릭 키 파일을 확인합니다.

   ```
   openssl pkey -inform PEM -pubin -in public-key.pem -noout
   ```

   명령에 오류가 표시되지 않으면 퍼블릭 키 파일이 유효합니다.

## 3단계: 사용자 지정 권한 부여자 리소스 및 권한 부여 생성
<a name="custom-auth-tutorial-authorizer"></a>

 AWS IoT 사용자 지정 권한 부여자는 이전 단계에서 생성된 모든 요소를 연결하는 리소스입니다. 이 단원에서는 사용자 지정 권한 부여자 리소스를 만들고 이전에 만든 Lambda 함수를 실행할 수 있는 권한을 부여합니다. AWS IoT 콘솔, AWS CLI또는 API를 사용하여 사용자 지정 권한 부여자 리소스를 생성할 수 있습니다 AWS .

이 자습서에서는 사용자 지정 권한 부여자를 하나만 생성하면 됩니다. 이 섹션에서는 AWS IoT 콘솔과를 사용하여를 생성하는 방법을 설명 AWS CLI하므로 가장 편리한 방법을 사용할 수 있습니다. 두 가지 방법으로 생성된 사용자 지정 권한 부여자 리소스 간에는 차이가 없습니다.

### 사용자 지정 권한 부여자 리소스 생성
<a name="custom-auth-tutorial-authorizer-resource"></a>

**다음 옵션 중 하나를 선택하여 사용자 지정 권한 부여자 리소스를 생성합니다.**
+ [AWS IoT 콘솔을 사용하여 사용자 지정 권한 부여자 생성](#create-custom-auth-in-console)
+ [AWS CLI를 사용하여 사용자 지정 권한 부여자 생성](#create-custom-auth-in-cli)

**사용자 지정 권한 부여자를 생성하려면(콘솔)**

1. [AWS IoT 콘솔의 사용자 지정 권한 부여자 페이지를](https://console.aws.amazon.com//iot/home#/authorizerhub) 열고 **권한 부여자 생성을** 선택합니다.

1. **권한 부여자**에서 다음 작업을 수행합니다.

   1. **권한 부여자 이름**에 **my-new-authorizer**를 입력합니다.

   1. **권한 부여자 상태**에서 **활성**을 선택합니다.

   1. **권한 부여자 함수**에서 앞서 생성한 Lambda 함수를 선택합니다.

   1. **토큰 검증 - 선택 사항**에서

      1. **토큰 검증**을 활성화합니다.

      1. **토큰 키 이름**에 **tokenKeyName**을 입력합니다.

      1. **키 추가**를 선택합니다.

      1. **키 이름**에 **FirstKey**를 입력합니다.

      1. **퍼블릭 키**에 `public-key.pem` 파일의 내용을 입력합니다. 파일로부터 `-----BEGIN PUBLIC KEY-----` 및 `-----END PUBLIC KEY-----`이(가) 있는 행을 포함해야 하며, 파일 내용에서 줄 바꿈, 캐리지 리턴 또는 기타 문자를 추가하거나 제거하지 마세요. 입력한 문자열은 이 예제와 유사해야 합니다.

         ```
         -----BEGIN PUBLIC KEY-----
         MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvEBzOk4vhN+3LgslvEWt
         sLCqNmt5Damas3bmiTRvq2gjRJ6KXGTGQChqArAJwL1a9dkS9+maaXC3vc6xzx9z
         QPu/vQOe5tyzz1MsKdmtFGxMqQ3qjEXAMPLEOmqyUKPP5mff58k6ePSfXAnzBH0q
         lg2HioefrpU5OSAnpuRAjYKofKjbc2Vrn6N2G7hV+IfTBvCElf0csalS/Rk4phD5
         oa4Y0GHISRnevypg5C8n9Rrz91PWGqP6M/q5DNJJXjMyleG92hQgu1N696bn5Dw8
         FhedszFa6b2x6xrItZFzewNQkPMLMFhNrQIIyvshtT/F1LVCS5+v8AQ8UGGDfZmv
         QeqAMAF7WgagDMXcfgKSVU8yid2sIm56qsCLMvD2Sq8Lgzpey9N5ON1o1Cvldwvc
         KrJJtgwW6hVqRGuShnownLpgG86M6neZ5sRMbVNZO8OzcobLngJ0Ibw9KkcUdklW
         gvZ6HEJqBY2XE70iEXAMPLETPHzhqvK6Ei1HGxpHsXx6BNft582J1VpgYjXha8oa
         /NN7l7Zbj/euAb41IVtmX8JrD9z613d1iM5L8HluJlUzn62Q+VeNV2tdA7MfPfMC
         8btGYladFAnitThaz6+F0VSBJPu7pZQoLnqyEp5zLMtF+kFl2yOBmGAP0RBivRd9
         JWBUCG0bqcLQPeQyjbXSOfUCAwEAAQ==
         -----END PUBLIC KEY-----
         ```

1. **권한 부여자 생성**을 선택합니다.

1. 사용자 지정 권한 부여자 리소스가 생성된 경우 사용자 지정 권한 부여자 목록이 표시되고 새 사용자 지정 권한 부여자가 목록에 나타나며 다음 섹션으로 이동하여 테스트할 수 있습니다.

   오류가 표시되면 오류를 검토하고 사용자 지정 권한 부여자를 다시 만들고 항목을 다시 확인합니다. 각 사용자 지정 권한 부여자 리소스에는 고유한 이름이 있어야 합니다.

**사용자 지정 권한 부여자를 생성하려면(AWS CLI)**

1. 값을 `authorizer-function-arn` 및 `token-signing-public-keys`(으)로 대체한 후 다음 명령을 실행합니다.

   ```
   aws iot create-authorizer \
   --authorizer-name "my-new-authorizer" \
   --token-key-name "tokenKeyName" \
   --status ACTIVE \
   --no-signing-disabled \
   --authorizer-function-arn "arn:aws:lambda:Region:57EXAMPLE833:function:custom-auth-function" \
   --token-signing-public-keys FirstKey="-----BEGIN PUBLIC KEY-----
   MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvEBzOk4vhN+3LgslvEWt
   sLCqNmt5Damas3bmiTRvq2gjRJ6KXGTGQChqArAJwL1a9dkS9+maaXC3vc6xzx9z
   QPu/vQOe5tyzz1MsKdmtFGxMqQ3qjEXAMPLEOmqyUKPP5mff58k6ePSfXAnzBH0q
   lg2HioefrpU5OSAnpuRAjYKofKjbc2Vrn6N2G7hV+IfTBvCElf0csalS/Rk4phD5
   oa4Y0GHISRnevypg5C8n9Rrz91PWGqP6M/q5DNJJXjMyleG92hQgu1N696bn5Dw8
   FhedszFa6b2x6xrItZFzewNQkPMLMFhNrQIIyvshtT/F1LVCS5+v8AQ8UGGDfZmv
   QeqAMAF7WgagDMXcfgKSVU8yid2sIm56qsCLMvD2Sq8Lgzpey9N5ON1o1Cvldwvc
   KrJJtgwW6hVqRGuShnownLpgG86M6neZ5sRMbVNZO8OzcobLngJ0Ibw9KkcUdklW
   gvZ6HEJqBY2XE70iEXAMPLETPHzhqvK6Ei1HGxpHsXx6BNft582J1VpgYjXha8oa
   /NN7l7Zbj/euAb41IVtmX8JrD9z613d1iM5L8HluJlUzn62Q+VeNV2tdA7MfPfMC
   8btGYladFAnitThaz6+F0VSBJPu7pZQoLnqyEp5zLMtF+kFl2yOBmGAP0RBivRd9
   JWBUCG0bqcLQPeQyjbXSOfUCAwEAAQ==
   -----END PUBLIC KEY-----"
   ```

**위치:**
   + `authorizer-function-arn` 값은 사용자 지정 권한 부여자에 대해 생성한 Lambda 함수의 Amazon 리소스 이름(ARN)입니다.
   + `token-signing-public-keys` 값은 키 이름, **FirstKey** 및 `public-key.pem` 파일의 내용을 포함합니다. 파일로부터 `-----BEGIN PUBLIC KEY-----` 및 `-----END PUBLIC KEY-----`이(가) 있는 행을 포함해야 하며, 파일 내용에서 줄 바꿈, 캐리지 리턴 또는 기타 문자를 추가하거나 제거하지 마세요.

     참고: 퍼블릭 키 값을 변경하면 퍼블릭 키를 사용할 수 없게 되므로 퍼블릭 키를 입력하는 것은 주의해야 합니다.

1. 사용자 지정 권한 부여자가 생성되면 명령은 다음과 같은 새 리소스의 이름 및 ARN을 반환합니다.

   ```
   {
       "authorizerName": "my-new-authorizer",
       "authorizerArn": "arn:aws:iot:Region:57EXAMPLE833:authorizer/my-new-authorizer"
   }
   ```

   다음 단계에서 사용하도록 `authorizerArn` 값을 저장합니다.

   각 사용자 지정 권한 부여자 리소스에는 고유한 이름이 있어야 합니다.

### 사용자 지정 권한 부여자 리소스 권한 부여하기
<a name="custom-auth-tutorial-authorizer-permission"></a>

이 섹션에서는 방금 생성한 사용자 지정 권한 부여자 리소스에 Lambda 함수를 실행할 수 있는 권한을 부여합니다. 권한을 부여하려면 [add-permission](https://docs.aws.amazon.com//cli/latest/reference/lambda/add-permission.html) CLI 명령을 사용할 수 있습니다.

**를 사용하여 Lambda 함수에 권한 부여 AWS CLI**

1. 값을 삽입한 후 다음 명령을 입력합니다. 참고: `statement-id` 값은 고유해야 합니다. 이전에 이 자습서를 실행한 적이 있거나 `ResourceConflictException` 오류가 발생하면, `Id-1234`를 다른 값으로 대체합니다.

   ```
   aws lambda add-permission  \
   --function-name "custom-auth-function" \
   --principal "iot.amazonaws.com" \
   --action "lambda:InvokeFunction" \
   --statement-id "Id-1234" \
   --source-arn authorizerArn
   ```

1. 명령이 성공하면 이 예제와 같은 권한 문이 반환됩니다. 다음 단원을 계속하여 사용자 지정 권한 부여자를 테스트할 수 있습니다.

   ```
   {
       "Statement": "{\"Sid\":\"Id-1234\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"iot.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:Region:57EXAMPLE833:function:custom-auth-function\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:lambda:Region:57EXAMPLE833:function:custom-auth-function\"}}}"
   }
   ```

   명령이 성공하지 못하면 이 예제와 같은 오류가 반환됩니다. 계속하기 전에 오류를 검토하고 수정해야 합니다.

   ```
   An error occurred (AccessDeniedException) when calling the AddPermission operation: User: arn:aws:iam::57EXAMPLE833:user/EXAMPLE-1 is not authorized to perform: lambda:AddPer
   mission on resource: arn:aws:lambda:Region:57EXAMPLE833:function:custom-auth-function
   ```

## 4단계: test-invoke-authorizer를 호출하여 권한 부여자 테스트
<a name="custom-auth-tutorial-test"></a>

이 단원에서 정의된 모든 리소스를 사용해 명령줄에서 test-invoke-authorizer를 호출하여 권한 부여 성공 여부를 테스트합니다.

명령줄에서 권한 부여자를 호출할 때 `protocolData`이(가) 정의되지 않았으므로 권한 부여자는 항상 DENY 문서를 반환합니다. 그러나 이 테스트는 Lambda 함수를 완전히 테스트하지 않더라도 사용자 지정 권한 부여자와 Lambda 함수가 올바르게 구성되었는지 확인합니다.

**를 사용하여 사용자 지정 권한 부여자와 Lambda 함수를 테스트하려면 AWS CLI**

1. 이전 단계에서 생성한 `private-key.pem` 파일이 있는 디렉터리에서 다음 명령을 실행합니다.

   ```
   echo -n "tokenKeyValue" | openssl dgst -sha256 -sign private-key.pem | openssl base64 -A
   ```

   이 명령은 다음 단계에서 사용할 서명 문자열을 만듭니다. 서명 문자열은 다음과 같은 형태입니다.

   ```
   dBwykzlb+fo+JmSGdwoGr8dyC2qB/IyLefJJr+rbCvmu9Jl4KHAA9DG+V+MMWu09YSA86+64Y3Gt4tOykpZqn9mn
   VB1wyxp+0bDZh8hmqUAUH3fwi3fPjBvCa4cwNuLQNqBZzbCvsluv7i2IMjEg+CPY0zrWt1jr9BikgGPDxWkjaeeh
   bQHHTo357TegKs9pP30Uf4TrxypNmFswA5k7QIc01n4bIyRTm90OyZ94R4bdJsHNig1JePgnuOBvMGCEFE09jGjj
   szEHfgAUAQIWXiVGQj16BU1xKpTGSiTAwheLKUjITOEXAMPLECK3aHKYKY+d1vTvdthKtYHBq8MjhzJ0kggbt29V
   QJCb8RilN/P5+vcVniSXWPplyB5jkYs9UvG08REoy64AtizfUhvSul/r/F3VV8ITtQp3aXiUtcspACi6ca+tsDuX
   f3LzCwQQF/YSUy02u5XkWn+sto6KCkpNlkD0wU8gl3+kOzxrthnQ8gEajd5Iylx230iqcXo3osjPha7JDyWM5o+K
   EWckTe91I1mokDr5sJ4JXixvnJTVSx1li49IalW4en1DAkc1a0s2U2UNm236EXAMPLELotyh7h+flFeloZlAWQFH
   xRlXsPqiVKS1ZIUClaZWprh/orDJplpiWfBgBIOgokJIDGP9gwhXIIk7zWrGmWpMK9o=
   ```

   이 서명 문자열을 복사하여 다음 단계에서 사용합니다. 여분의 문자를 포함하거나 남겨 두지 않도록 합니다.

1. 이 명령에서 `token-signature` 값을 이전 단계의 서명 문자열로 바꾸고 이 명령을 실행하여 권한 부여자를 테스트합니다.

   ```
   aws iot test-invoke-authorizer \
   --authorizer-name my-new-authorizer \
   --token tokenKeyValue \
   --token-signature dBwykzlb+fo+JmSGdwoGr8dyC2qB/IyLefJJr+rbCvmu9Jl4KHAA9DG+V+MMWu09YSA86+64Y3Gt4tOykpZqn9mnVB1wyxp+0bDZh8hmqUAUH3fwi3fPjBvCa4cwNuLQNqBZzbCvsluv7i2IMjEg+CPY0zrWt1jr9BikgGPDxWkjaeehbQHHTo357TegKs9pP30Uf4TrxypNmFswA5k7QIc01n4bIyRTm90OyZ94R4bdJsHNig1JePgnuOBvMGCEFE09jGjjszEHfgAUAQIWXiVGQj16BU1xKpTGSiTAwheLKUjITOEXAMPLECK3aHKYKY+d1vTvdthKtYHBq8MjhzJ0kggbt29VQJCb8RilN/P5+vcVniSXWPplyB5jkYs9UvG08REoy64AtizfUhvSul/r/F3VV8ITtQp3aXiUtcspACi6ca+tsDuXf3LzCwQQF/YSUy02u5XkWn+sto6KCkpNlkD0wU8gl3+kOzxrthnQ8gEajd5Iylx230iqcXo3osjPha7JDyWM5o+KEWckTe91I1mokDr5sJ4JXixvnJTVSx1li49IalW4en1DAkc1a0s2U2UNm236EXAMPLELotyh7h+flFeloZlAWQFHxRlXsPqiVKS1ZIUClaZWprh/orDJplpiWfBgBIOgokJIDGP9gwhXIIk7zWrGmWpMK9o=
   ```

   명령이 성공적으로 실행되는 경우 이 예와 같이 사용자 지정 권한 부여자 함수가 생성한 정보가 반환됩니다.

   ```
   {
       "isAuthenticated": true,
       "principalId": "principalId",
       "policyDocuments": [
           "{\"Version\":\"2012-10-17\",		 	 	 \"Statement\":[{\"Action\":\"iot:*\",\"Effect\":\"Deny\",\"Resource\":\"arn:aws:iot:Region:57EXAMPLE833:*\"}]}"
       ],
       "refreshAfterInSeconds": 600,
       "disconnectAfterInSeconds": 3600
   }
   ```

   명령이 오류를 반환하면 오류를 검토하고 이 단원에서 사용한 명령을 다시 확인합니다.

## 5단계: Postman을 사용하여 MQTT 메시지 게시 테스트
<a name="custom-auth-tutorial-postman"></a>

1. 명령줄에서 디바이스 데이터 엔드포인트를 가져오려면 여기에 표시된 대로 [describe-endpoint](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iot/describe-endpoint.html)를 호출합니다.

   ```
   aws iot describe-endpoint --output text --endpoint-type iot:Data-ATS
   ```

   이후 단계에서 *device\$1data\$1endpoint\$1address*로 사용할 수 있도록 이 주소를 저장합니다.

1. 새 Postman 창을 열고 새 HTTP POST 요청을 만듭니다.

   1. 컴퓨터에서 Postman 앱을 엽니다.

   1. Postman의 **파일** 메뉴에서 **새로 만들기…**를 선택합니다.

   1. **새로 만들기(New)** 대화 상자에서 **요청(Request)**을 선택합니다.

   1. 저장 요청에서

      1. **요청 이름**에서 **Custom authorizer test request**을(를) 입력합니다.

      1. **저장할 컬렉션 또는 폴더 선택:**에서 이 요청을 저장할 컬렉션을 선택하거나 만듭니다.

      1. ***collection\$1name*에 저장**을 선택합니다.

1. POST 요청을 생성하여 사용자 지정 권한 부여자를 테스트합니다.

   1. URL 필드 옆의 요청 메소드 선택기에서 **POST**를 선택합니다.

   1. URL 필드에서 이전 단계의 [describe-endpoint](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iot/describe-endpoint.html) 명령의 *device\$1data\$1endpoint\$1address*와 함께 다음 URL을 사용하여 요청에 대한 URL을 생성합니다.

      ```
      https://device_data_endpoint_address:443/topics/test/cust-auth/topic?qos=0&actionToken=allow
      ```

      이 URL에는 AWS IoT에 대한 액세스를 허용하는 정책 문서를 반환하도록 Lambda 함수에 지시하는 `actionToken=allow` 쿼리 파라미터가 포함됩니다. URL을 입력한 후 쿼리 파라미터가 Postman의 **Params** 탭에도 나타납니다.

   1. **Auth** 탭의 **유형(Type)** 필드에서 **No Auth**를 선택합니다.

   1. 헤더(Headers) 탭에서:

      1. **호스트** 키가 선택되어 있으면 이 키를 선택 취소하세요.

      1. 헤더 목록의 맨 아래에 이러한 새 헤더를 추가하고 새 헤더가 선택되었는지 확인합니다. **Host** 값을 *device\$1data\$1endpoint\$1address*로 바꾸고, **x-amz-customauthorizer-signature** 값을 이전 단원에서 **test-invoke-authorize** 명령과 함께 사용한 서명 문자열로 바꿉니다.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/iot/latest/developerguide/custom-auth-tutorial.html)

   1. 본문(Body) 탭에서:

      1. 데이터 형식 옵션 상자에서 **원시(Raw)**를 선택합니다.

      1. 데이터 유형 목록에서 **JavaScript**를 선택합니다.

      1. 텍스트 필드에서 테스트 메시지에 대해 다음 JSON 메시지 페이로드를 입력합니다.

         ```
         {
             "data_mode": "test",
             "vibration": 200,
             "temperature": 40
         }
         ```

1. **전송(Send)**을 선택하여 요청을 전송합니다.

   요청이 성공적이면 다음을 반환합니다.

   ```
   {
       "message": "OK",
       "traceId": "ff35c33f-409a-ea90-b06f-fbEXAMPLE25c"
   }
   ```

   응답이 성공하면 사용자 지정 권한 부여자가에 대한 연결을 허용 AWS IoT 했고 테스트 메시지가의 브로커에 전송되었음을 나타냅니다 AWS IoT Core.

   오류가 반환되면 오류 메시지 *device\$1data\$1endpoint\$1address*, 서명 문자열 및 기타 헤더 값이 포함됩니다.

다음 단원에서 사용하도록 이 요청을 Postman에 유지합니다.

## 6단계: MQTT 테스트 클라이언트에서 메시지 보기
<a name="custom-auth-tutorial-testclient"></a>

이전 단계에서는 Postman을 사용하여 시뮬레이션된 디바이스 메시지를 AWS IoT 에 보냈습니다. 성공 응답은 사용자 지정 권한 부여자가 AWS IoT 에 대한 연결을 허용했으며 서 테스트 메시지가 AWS IoT Core의 브로커에게 전달되었음을 나타냅니다. 이 섹션에서는 AWS IoT 콘솔의 MQTT 테스트 클라이언트를 사용하여 다른 디바이스 및 서비스와 마찬가지로 해당 메시지의 메시지 내용을 확인합니다.

**사용자 지정 권한 부여자가 승인한 테스트 메시지를 보려면**

1.  AWS IoT 콘솔에서 [MQTT 테스트 클라이언트](https://console.aws.amazon.com//iot/home#/test)를 엽니다.

1. **주제 구독(Subscribe to topic)** 탭의 **주제 필터(Topic filter)**에 **test/cust-auth/topic**을(를) 입력합니다. 이는 이전 단원의 Postman 예제에서 사용된 메시지 주제입니다.

1. **구독**을 선택합니다.

   이 창은 다음 단계를 위해 계속 표시되도록 합니다.

1. Postman에서 이전 섹션에 대해 만든 요청에서 **전송(Send)**을 선택합니다.

   응답을 검토하여 성공했는지 확인합니다. 그렇지 않은 경우 이전 단원에서 설명한 대로 오류 문제를 해결하세요.

1. **MQTT 테스트 클라이언트**에서 메시지 주제를 표시하는 새 항목이 표시되고, 확장되면 Postman에서 전송한 요청의 메시지 페이로드가 표시됩니다.

   **MQTT 테스트 클라이언트**에서 메시지가 표시되지 않으면 다음 몇 가지를 확인해야 합니다.
   + Postman 요청이 성공적으로 반환되었는지 확인하세요. 가 연결을 AWS IoT 거부하고 오류를 반환하면 요청의 메시지가 메시지 브로커로 전달되지 않습니다.
   +  AWS IoT 콘솔을 여는 데 AWS 리전 사용되는 AWS 계정 및가 Postman URL에서 사용 중인와 동일한지 확인합니다.
   + 사용자 지정 권한 부여자에 적절한 엔드포인트를 사용하고 있는지 확인합니다. 기본 IoT 엔드포인트는 Lambda 함수와 함께 사용자 지정 권한 부여자를 사용하도록 지원하지 않을 수 있습니다. 그 대신, 도메인 구성을 사용하여 새 엔드포인트를 정의한 다음, 사용자 지정 권한 부여자에 대해 해당 엔드포인트를 지정할 수 있습니다.
   + **MQTT 테스트 클라이언트**에서 주제를 올바르게 입력했는지 확인하세요. 주제 필터는 대소문자를 구분하지 않습니다. 의심스러운 경우 주제를 구독할 수도 있습니다.이 **\$1** 주제는 메시지 브로커를 통과 AWS 계정 하고 콘솔을 여는 데 AWS 리전 사용되는 모든 MQTT 메시지를 구독합니다 AWS IoT .

## 7단계: 결과 및 다음 단계 검토
<a name="custom-auth-tutorial-review"></a>

**이 자습서에서는:**
+ Lambda 함수를 사용자 지정 권한 부여자 처리기로 만들었습니다.
+ 토큰 서명이 활성화된 상태에서 사용자 지정 권한 부여자를 만들었습니다.
+ **test-invoke-authorizer** 명령을 사용하여 사용자 지정 권한 부여자를 테스트했습니다.
+ [Postman](https://www.postman.com/)을 사용하여 MQTT 주제를 게시했고 사용자 지정 권한 부여자로 요청을 검증합니다.
+ **MQTT 테스트 클라이언트**를 사용하여 Postman 테스트에서 전송한 메시지를 보았습니다.

**다음 단계**  
Postman에서 일부 메시지를 전송해 사용자 지정 권한 부여자가 작동하는지 확인한 후 이 자습서의 다양한 측면을 변경하면 결과에 어떤 영향을 미치는지 실험해 보세요. 다음은 시작하는 데 도움이 될 몇 가지 예제입니다.
+ 더 이상 유효하지 않게 서명 문자열을 변경하여 무단 연결 시도가 어떻게 처리되는지 확인합니다. 이 오류 응답과 같은 오류 응답이 나타나야 하며 **MQTT 테스트 클라이언트**에 메시지가 나타나지 않아야 합니다.

  ```
  {
      "message": "Forbidden",
      "traceId": "15969756-a4a4-917c-b47a-5433e25b1356"
  }
  ```
+  AWS IoT 규칙을 개발하고 사용하는 동안 발생할 수 있는 오류를 찾는 방법에 대한 자세한 내용은 섹션을 참조하세요[모니터링 AWS IoT](monitoring_overview.md).

## 8단계: 정리
<a name="custom-auth-tutorial-cleanup"></a>

이 자습서를 반복하려면 일부 사용자 지정 권한 부여자를 제거해야 할 수도 있습니다. 는 한 번에 제한된 수의 사용자 지정 권한 부여자만 구성할 AWS 계정 수 있으며 기존 사용자 지정 권한 부여자를 제거하지 않고 새 권한 부여자를 추가하려고 할 `LimitExceededException` 때를 가져올 수 있습니다.

**사용자 지정 권한 부여자를 제거하려면(콘솔)**

1. [AWS IoT 콘솔의 사용자 지정 권한 부여자 페이지를](https://console.aws.amazon.com//iot/home#/authorizerhub) 열고 사용자 지정 권한 부여자 목록에서 제거할 사용자 지정 권한 부여자를 찾습니다.

1. 사용자 지정 권한 부여자 세부 정보 페이지를 열고 **작업** 메뉴에서 **편집**을 선택합니다.

1. **권한 부여자 활성화**의 선택을 취소한 다음 **업데이트**를 선택합니다.

   활성 상태인 동안에는 사용자 지정 권한 부여자를 삭제할 수 없습니다.

1. 사용자 지정 권한 부여자 세부 정보 페이지에서 **작업** 메뉴를 열고 **삭제**를 선택합니다.

**사용자 지정 권한 부여자를 제거하려면(AWS CLI)**

1. 설치한 사용자 지정 권한 부여자를 나열하고 삭제할 사용자 지정 권한 부여자의 이름을 찾습니다.

   ```
   aws iot list-authorizers 
   ```

1. `Custom_Auth_Name`을 삭제할 사용자 지정 권한 부여자의 `authorizerName`으로 바꾼 후 이 명령을 실행하여, 사용자 지정 권한 부여자를 `inactive`로 설정합니다.

   ```
   aws iot update-authorizer --status INACTIVE --authorizer-name Custom_Auth_Name
   ```

1. `Custom_Auth_Name`을 삭제할 사용자 지정 권한 부여자의 `authorizerName`으로 바꾼 후 이 명령을 실행하여 사용자 지정 권한 부여자를 삭제합니다.

   ```
   aws iot delete-authorizer --authorizer-name Custom_Auth_Name
   ```

# 자습서: AWS IoT 및 Raspberry Pi를 사용하여 토양 수분 모니터링
<a name="iot-moisture-tutorial"></a>

이 자습서에서는 [Raspberry Pi](https://www.raspberrypi.org/), 습도 센서를 사용하고 주택 식물 또는 정원의 토양 습도 수준을 AWS IoT 모니터링하는 방법을 보여줍니다. Raspberry Pi는 센서에서 습도 수준과 온도를 읽은 다음 데이터를 보내는 코드를 실행합니다 AWS IoT. 습도 수준이 임계값 아래로 떨어질 때 Amazon SNS 주제를 구독하는 주소로 이메일을 AWS IoT 보내는 규칙을에서 생성합니다.

**참고**  
이 튜토리얼은 최신이 아닐 수 있습니다. 이 주제가 처음 게시된 이후로 일부 참조가 대체되었을 수 있습니다.

**Contents**
+ [사전 조건](#iot-moisture-prereqs)
+ [설 AWS IoT정](iot-moisture-setup.md)
  + [1단계: AWS IoT 정책 생성](iot-moisture-policy.md)
  + [2단계: AWS IoT 사물, 인증서 및 프라이빗 키 생성](iot-moisture-create-thing.md)
  + [3단계: Amazon SNS 주제 생성 및 구독](iot-moisture-create-sns-topic.md)
  + [4단계: 이메일 전송 AWS IoT 규칙 생성](iot-moisture-create-rule.md)
+ [Raspberry Pi와 습도 센서 설정](iot-moisture-raspi-setup.md)

## 사전 조건
<a name="iot-moisture-prereqs"></a>

이 자습서를 완료하려면 다음이 필요합니다.
+  AWS 계정.
+ 관리자 권한이 있는 IAM 사용자.
+ Windows, macOS, Linux 또는 Unix를 실행하며 [AWS IoT 콘솔](https://console.aws.amazon.com/iot/home)에 액세스할 수 있는 개발 컴퓨터.
+ 최신 [Raspberry Pi OS](https://www.raspberrypi.com/software/operating-systems/)를 실행하는 [Raspberry Pi 3B 또는 4B](https://www.raspberrypi.com/products/). 설치 방법은 Rasberry Pi 웹사이트의 [운영 체제 설치](https://www.raspberrypi.com/documentation/computers/getting-started.html#installing-the-operating-system) 섹션을 참조하세요.
+ Raspberry Pi용 모니터, 키보드, 마우스 및 Wi-Fi 네트워크 또는 이더넷 연결.
+ Raspberry Pi 호환 습도 센서.. 이 자습서에서 사용되는 센서는 [JST 4핀 및 암 소켓 케이블 헤더](https://www.adafruit.com/product/3950)가 있는 [Adafruit STEMMA I2C 정전식 습도 센서](https://www.adafruit.com/product/4026)입니다.

# 설 AWS IoT정
<a name="iot-moisture-setup"></a>

이 자습서를 완료하려면 다음 리소스를 생성해야 합니다. 디바이스를 연결하려면 IoT 사물 AWS IoT, 디바이스 인증서 및 AWS IoT 정책을 생성합니다.
+  AWS IoT 사물입니다.

  사물이란 물리적 디바이스(이 경우는 Rasberry Pi)를 의미하며, 그 안에는 디바이스에 관한 정적 메타데이터가 들어 있습니다.
+ 디바이스 인증서입니다.

  모든 디바이스에는 AWS IoT와 연결하여 인증하는 디바이스 인증서가 있어야 합니다.
+  AWS IoT 정책.

  각 디바이스 인증서에는 하나 이상의 AWS IoT 정책이 연결되어 있습니다. 이러한 정책은 디바이스가 액세스할 수 있는 AWS IoT 리소스를 결정합니다.
+  AWS IoT 루트 CA 인증서입니다.

  디바이스 및 기타 클라이언트는 AWS IoT 루트 CA 인증서를 사용하여 통신 중인 AWS IoT 서버를 인증합니다. 자세한 내용은 [서버 인증](server-authentication.md) 단원을 참조하십시오.
+  AWS IoT 규칙입니다.

  규칙에는 쿼리와 하나 이상의 규칙 작업이 있습니다. 쿼리는 디바이스 메시지에서 데이터를 추출하여 메시지 데이터를 처리해야 할지 여부를 결정합니다. 규칙 작업은 데이터가 쿼리와 일치할 경우에 해야 할 일을 지정합니다.
+ Amazon SNS 주제 및 주제 구독

  규칙은 Raspberry Pi의 습도 데이터를 모니터링합니다. 값이 임계값 미만일 경우에는 Amazon SNS 주제로 메시지를 전송합니다. Amazon SNS에서 주제를 구독하는 모든 이메일 주소로 메시지를 전송합니다.

 



# 1단계: AWS IoT 정책 생성
<a name="iot-moisture-policy"></a>

Raspberry Pi가 연결하고 메시지를 보낼 수 있도록 허용하는 AWS IoT 정책을 생성합니다 AWS IoT.

1. [AWS IoT 콘솔](https://console.aws.amazon.com/iot)에서 **시작하기** 버튼이 표시되면 선택합니다. 또는 탐색 창에서 **Security**(보안)를 확장한 후 **Policies**(정책)를 선택합니다.

1. **You don’t have any policies yet(아직 정책이 없습니다)** 대화 상자가 나타나면 **Create a policy(정책 생성)**를 선택합니다. 그렇지 않은 경우, **생성**을 선택합니다.

1.  AWS IoT 정책의 이름을 입력합니다(예: **MoistureSensorPolicy**).

1. **설명문 추가** 부분에서 기존 정책을 다음 JSON으로 바꿉니다. *리전* 및 *계정을* AWS 리전 및 AWS 계정 번호로 바꿉니다.  
****  

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

1. **생성(Create)**을 선택합니다.

# 2단계: AWS IoT 사물, 인증서 및 프라이빗 키 생성
<a name="iot-moisture-create-thing"></a>

 AWS IoT 레지스트리에 Raspberry Pi를 나타내는 사물을 생성합니다.

1. [AWS IoT 콘솔](https://console.aws.amazon.com/iot/home) 탐색 창에서 **관리**를 선택한 후 **사물**을 선택합니다.

1. **You don't have any things yet(아직 사물이 없습니다)** 대화 상자가 표시되면 **Register a thing(사물 등록)**을 선택합니다. 그렇지 않은 경우, **생성**을 선택합니다.

1. ** AWS IoT 사물 생성** 페이지에서 **단일 사물 생성을** 선택합니다.

1. **디바이스를 디바이스 레지스트리에 추가** 페이지에서 IoT 사물 이름(예: **RaspberryPi**)을 입력하고 **다음**을 선택합니다. 사물을 생성한 후에는 사물 이름을 변경할 수 없습니다. 사물 이름을 변경하려면 새 사물을 생성하고 새 이름을 지정한 다음 이전 사물을 삭제해야 합니다.

1. **사물에 인증서 추가** 페이지에서 **Create certificate(인증서 생성)**를 선택하세요.

1. **다운로드** 링크를 선택하여 인증서, 프라이빗 키 및 루트 CA 인증서를 다운로드합니다.
**중요**  
이 때에만 인증서와 프라이빗 키를 다운로드할 수 있습니다.

1. 인증서를 활성화하려면 **활성화**를 선택합니다. 디바이스를 AWS IoT에 연결하려면 인증서가 활성 상태여야 합니다.

1. **정책 연결**을 선택합니다.

1. **Add a policy for your thing(사물에 정책 추가)**은 **MoistureSensorPolicy**를 선택하고 **사물 등록**을 선택합니다.

# 3단계: Amazon SNS 주제 생성 및 구독
<a name="iot-moisture-create-sns-topic"></a>

Amazon SNS 주제 생성 및 구독

1. [AWS SNS 콘솔](https://console.aws.amazon.com/sns/home)의 탐색 창에서 **주제**를 선택한 다음 **주제 생성**을 선택합니다.

1. 유형을 **표준**으로 선택하고 주제의 이름(예: **MoistureSensorTopic**)을 입력합니다.

1. 주제의 표시 이름을 입력합니다(예: **Moisture Sensor Topic**). 이것이 Amazon SNS 콘솔에서 표시되는 주제의 이름입니다.

1. **주제 생성**을 선택합니다.

1. Amazon SNS 주제 세부 정보 페이지에서 **구독 생성**을 선택합니다.

1. **프로토콜**에서 **이메일**을 선택합니다.

1. **엔드포인트**에 이메일 주소를 입력합니다.

1. **구독 생성**을 선택합니다.

1. 이메일 클라이언트를 열고 제목이 **MoistureSensorTopic**인 메시지를 찾습니다. 이메일을 열고 **구독 확인** 링크를 클릭합니다.
**중요**  
구독을 확인할 때까지 이 Amazon SNS 주제에서 이메일 알림을 수신할 수 없습니다.

입력한 텍스트가 포함된 이메일 메시지를 수신해야 합니다.

# 4단계: 이메일 전송 AWS IoT 규칙 생성
<a name="iot-moisture-create-rule"></a>

 AWS IoT 규칙은 디바이스에서 메시지를 수신할 때 수행할 쿼리와 하나 이상의 작업을 정의합니다. AWS IoT 규칙 엔진은 디바이스에서 보낸 메시지를 수신하고 메시지의 데이터를 사용하여 일부 조치를 취해야 하는지 여부를 결정합니다. 자세한 내용은 [에 대한 규칙 AWS IoT](iot-rules.md) 단원을 참조하십시오.

이 자습서에서는 Raspberry Pi가 `aws/things/RaspberryPi/shadow/update`에 메시지를 게시합니다. 이것은 디바이스와 Thing Shadow 서비스에서 사용하는 내부 MQTT 주제입니다. Raspberry Pi는 다음 형식의 메시지를 게시합니다.

```
{
    "reported": {
        "moisture" : moisture-reading,
        "temp" : temperature-reading
    }
}
```

수신되는 메시지에서 습도와 온도 데이터를 추출하는 쿼리를 생성합니다. 그리고 데이터를 가져와 습도 값이 임계값 미만일 경우 Amazon SNS 주제 구독자에게 전송하는 Amazon SNS 작업도 만듭니다.

**Amazon SNS 규칙 생성**

1. [AWS IoT 콘솔](https://console.aws.amazon.com/iot/home)에서 **메시지 라우팅**을 선택한 다음 **규칙**을 선택합니다. **아직 규칙이 없습니다** 대화 상자가 나타나면 **규칙 생성**을 선택합니다. 또는 **규칙 생성**을 선택합니다.

1. **규칙 속성** 페이지에서 **규칙 이름**(예: **MoistureSensorRule**)을 입력하고 간단한 **규칙 설명**(예: **Sends an alert when soil moisture level readings are too low**)을 제공합니다.

1. **다음**을 선택하고 SQL 문을 구성합니다. **SQL 버전을** **2016-03-23**로 선택하고 다음 AWS IoT SQL 쿼리 문을 입력합니다.

   ```
   SELECT * FROM '$aws/things/RaspberryPi/shadow/update/accepted' WHERE state.reported.moisture < 400
   ```

   이 설명문은 `moisture` 값이 `400` 미만일 때 규칙 작업을 트리거합니다.
**참고**  
다른 값을 사용해야 할 수 있습니다. Raspberry Pi에서 코드를 실행한 후에 센서를 터치하거나, 물 속에 넣거나, 화분에 두면 센서에서 가져온 값을 볼 수 있습니다.

1. **다음**을 선택하고 규칙 작업을 첨부합니다. **작업 1**에서 **단순 알림 서비스**를 선택합니다. 이 규칙 작업에 대한 설명은 **메시지를 SNS 푸시 알림으로 보내기**입니다.

1. **SNS 주제**에서 [3단계: Amazon SNS 주제 생성 및 구독](iot-moisture-create-sns-topic.md), **MoistureSensorTopic**에서 생성한 주제를 선택하고 **메시지 형식**을 **RAW**로 둡니다. **IAM 역할**에서 **새 역할 생성**을 선택합니다. 역할 이름(예: **LowMoistureTopicRole**)을 입력한 후 **역할 생성**을 선택합니다.

1. **다음**을 선택하고 검토한 후 **생성**을 선택하여 규칙을 생성합니다.

# Raspberry Pi와 습도 센서 설정
<a name="iot-moisture-raspi-setup"></a>



Raspberry Pi에 microSD 카드를 삽입하고, 모니터, 키보드, 마우스, 이더넷 케이블(Wi-Fi를 사용하지 않는 경우)을 연결합니다. 전원 케이블은 아직 연결하지 마세요.

JST 점퍼 케이블을 습도 센서에 연결합니다. 점퍼의 반대쪽에 다음 4개 와이어가 있습니다.
+ 녹색: I2C SCL
+ 흰색: I2C SDA
+ 적색: 전원(3.5V)
+ 검은색: 접지

Raspberry Pi를 이더넷 잭으로 오른쪽에 고정합니다. 이 방향에서 상단에 GPIO 핀 열이 2개 있습니다. 습도 센서의 와이어를 핀 하단 열에 다음 순서로 연결합니다. 제일 왼쪽 핀부터 시작하여 적색(전원), 흰색(SDA), 녹색(SCL)을 연결합니다. 핀 하나는 건너뛰고 검은색(접지) 와이어를 연결합니다. 자세한 내용은 [Python 컴퓨터 배선](https://learn.adafruit.com/adafruit-stemma-soil-sensor-i2c-capacitive-moisture-sensor/python-circuitpython-test) 단원을 참조하세요.

전원 케이블을 Raspberry Pi에 연결하고 반대쪽 끝을 벽면 콘센트에 꽂아 전원을 켭니다.

**Raspberry Pi 구성**

1. **Welcome to Raspberry Pi(Raspberry Pi를 소개합니다)**에서 **다음**을 선택합니다.

1. 국가, 언어, 시간대 및 키보드 배열을 선택합니다. **다음**을 선택합니다.

1. Raspberry Pi 암호를 입력하고 **다음**을 선택합니다.

1. Wi-Fi 네트워크를 선택하고 **다음**을 선택합니다. Wi-Fi 네트워크를 사용하지 않을 때는 **건너뛰기**를 선택합니다.

1. **다음**을 선택하고 소프트웨어 업데이트를 확인합니다. 업데이트가 완료되면 **다시 시작**을 클릭하여 Raspberry Pi를 다시 시작합니다.

Raspberry Pi가 시작되면 I2C 인터페이스를 활성화합니다.

1. Raspbian 데스크톱 좌측 상단 모서리에서 Raspberry 아이콘을 클릭하고, **기본 설정**을 선택한 다음 **Raspberry Pi Configuration(Raspberry Pi 구성)**을 선택합니다.

1. **인터페이스** 탭에서 **I2C**의**활성화**를 선택합니다.

1. **확인**을 선택합니다.

CircuitPython의 Adafruit STEMMA 습도 센서용 라이브러리가 작성됩니다. Raspberry Pi에서 이를 실행하려면 Python 3 최신 버전을 설치해야 합니다.

1. 명령 프롬프트에서 다음 명령을 실행하여 Raspberry Pi 소프트웨어를 업데이트합니다.

   `sudo apt-get update`

   `sudo apt-get upgrade`

1. 다음 명령을 실행하여 Phthon 3 설치를 업데이트합니다.

   `sudo pip3 install --upgrade setuptools`

1. 다음 명령을 실행하여 Raspberry Pi GPIO 라이브러리를 설치합니다.

   `pip3 install RPI.GPIO`

1. 다음 명령을 실행하여 Adafruit Blinka 라이브러리를 설치합니다.

   `pip3 install adafruit-blinka`

   자세한 내용은 [Raspberry Pi에서 CircuitPython 라이브러리 설치](https://learn.adafruit.com/circuitpython-on-raspberrypi-linux/installing-circuitpython-on-raspberry-pi)를 참조하세요.

1. 다음 명령을 실행하여 Adafruit Seesaw 라이브러리를 설치합니다.

   `sudo pip3 install adafruit-circuitpython-seesaw`

1. 다음 명령을 실행하여 AWS IoT Device SDK for Python을 설치합니다.

   `pip3 install AWSIoTPythonSDK`

이제 Raspberry Pi에 필요한 라이브러리가 모두 설치되었습니다. **moistureSensor.py**라는 파일을 만들고 다음 Python 코드를 파일에 복사합니다.

```
from adafruit_seesaw.seesaw import Seesaw
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTShadowClient
from board import SCL, SDA

import logging
import time
import json
import argparse
import busio

# Shadow JSON schema:
#
# {
#   "state": {
#       "desired":{
#           "moisture":<INT VALUE>,
#           "temp":<INT VALUE>            
#       }
#   }
# }

# Function called when a shadow is updated
def customShadowCallback_Update(payload, responseStatus, token):

    # Display status and data from update request
    if responseStatus == "timeout":
        print("Update request " + token + " time out!")

    if responseStatus == "accepted":
        payloadDict = json.loads(payload)
        print("~~~~~~~~~~~~~~~~~~~~~~~")
        print("Update request with token: " + token + " accepted!")
        print("moisture: " + str(payloadDict["state"]["reported"]["moisture"]))
        print("temperature: " + str(payloadDict["state"]["reported"]["temp"]))
        print("~~~~~~~~~~~~~~~~~~~~~~~\n\n")

    if responseStatus == "rejected":
        print("Update request " + token + " rejected!")

# Function called when a shadow is deleted
def customShadowCallback_Delete(payload, responseStatus, token):

     # Display status and data from delete request
    if responseStatus == "timeout":
        print("Delete request " + token + " time out!")

    if responseStatus == "accepted":
        print("~~~~~~~~~~~~~~~~~~~~~~~")
        print("Delete request with token: " + token + " accepted!")
        print("~~~~~~~~~~~~~~~~~~~~~~~\n\n")

    if responseStatus == "rejected":
        print("Delete request " + token + " rejected!")


# Read in command-line parameters
def parseArgs():

    parser = argparse.ArgumentParser()
    parser.add_argument("-e", "--endpoint", action="store", required=True, dest="host", help="Your device data endpoint")
    parser.add_argument("-r", "--rootCA", action="store", required=True, dest="rootCAPath", help="Root CA file path")
    parser.add_argument("-c", "--cert", action="store", dest="certificatePath", help="Certificate file path")
    parser.add_argument("-k", "--key", action="store", dest="privateKeyPath", help="Private key file path")
    parser.add_argument("-p", "--port", action="store", dest="port", type=int, help="Port number override")
    parser.add_argument("-n", "--thingName", action="store", dest="thingName", default="Bot", help="Targeted thing name")
    parser.add_argument("-id", "--clientId", action="store", dest="clientId", default="basicShadowUpdater", help="Targeted client id")

    args = parser.parse_args()
    return args


# Configure logging
# AWSIoTMQTTShadowClient writes data to the log
def configureLogging():

    logger = logging.getLogger("AWSIoTPythonSDK.core")
    logger.setLevel(logging.DEBUG)
    streamHandler = logging.StreamHandler()
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    streamHandler.setFormatter(formatter)
    logger.addHandler(streamHandler)


# Parse command line arguments
args = parseArgs()

if not args.certificatePath or not args.privateKeyPath:
    parser.error("Missing credentials for authentication.")
    exit(2)

# If no --port argument is passed, default to 8883
if not args.port: 
    args.port = 8883


# Init AWSIoTMQTTShadowClient
myAWSIoTMQTTShadowClient = None
myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient(args.clientId)
myAWSIoTMQTTShadowClient.configureEndpoint(args.host, args.port)
myAWSIoTMQTTShadowClient.configureCredentials(args.rootCAPath, args.privateKeyPath, args.certificatePath)

# AWSIoTMQTTShadowClient connection configuration
myAWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime(1, 32, 20)
myAWSIoTMQTTShadowClient.configureConnectDisconnectTimeout(10) # 10 sec
myAWSIoTMQTTShadowClient.configureMQTTOperationTimeout(5) # 5 sec

# Initialize Raspberry Pi's I2C interface
i2c_bus = busio.I2C(SCL, SDA)

# Intialize SeeSaw, Adafruit's Circuit Python library
ss = Seesaw(i2c_bus, addr=0x36)

# Connect to AWS IoT
myAWSIoTMQTTShadowClient.connect()

# Create a device shadow handler, use this to update and delete shadow document
deviceShadowHandler = myAWSIoTMQTTShadowClient.createShadowHandlerWithName(args.thingName, True)

# Delete current shadow JSON doc
deviceShadowHandler.shadowDelete(customShadowCallback_Delete, 5)

# Read data from moisture sensor and update shadow
while True:

    # read moisture level through capacitive touch pad
    moistureLevel = ss.moisture_read()

    # read temperature from the temperature sensor
    temp = ss.get_temp()

    # Display moisture and temp readings
    print("Moisture Level: {}".format(moistureLevel))
    print("Temperature: {}".format(temp))
    
    # Create message payload
    payload = {"state":{"reported":{"moisture":str(moistureLevel),"temp":str(temp)}}}

    # Update shadow
    deviceShadowHandler.shadowUpdate(json.dumps(payload), customShadowCallback_Update, 5)
    time.sleep(1)
```

파일을 찾을 수 있는 위치에 파일을 저장합니다. 다음 파라미터로 `moistureSensor.py` 명령줄을 실행할 수 있습니다.

엔드포인트  
사용자 지정 AWS IoT 엔드포인트입니다. 자세한 내용은 [디바이스 섀도우 REST API](device-shadow-rest-api.md) 단원을 참조하십시오.

rootCA  
 AWS IoT 루트 CA 인증서의 전체 경로입니다.

cert  
 AWS IoT 디바이스 인증서의 전체 경로입니다.

키  
 AWS IoT 디바이스 인증서 프라이빗 키의 전체 경로입니다.

thingName  
사물 이름(이 경우는 `RaspberryPi`)입니다.

clientId  
MQTT 클라이언트 ID입니다. `RaspberryPi`를 사용합니다.

명령줄의 모양은 다음과 같아야 합니다.

`python3 moistureSensor.py --endpoint your-endpoint --rootCA ~/certs/AmazonRootCA1.pem --cert ~/certs/raspberrypi-certificate.pem.crt --key ~/certs/raspberrypi-private.pem.key --thingName RaspberryPi --clientId RaspberryPi`

센서를 만지거나, 화분에 넣거나, 물 컵에 넣어 센서가 다양한 습도에 반응하는지 확인해봅니다. 필요할 경우 `MoistureSensorRule`에서 임계값을 변경할 수 있습니다. 습도 센서 판독값이 규칙의 SQL 쿼리 문에 지정된 값 아래로 떨어지면는 Amazon SNS 주제에 메시지를 AWS IoT 게시합니다. 습도와 온도 데이터가 있는 이메일 메시지가 수신되어야 합니다.

Amazon SNS에서 이메일 메시지 수신을 확인한 후에 **CTRL\$1C**를 눌러 Python 프로그램을 저장합니다. Python 프로그램으로 전송되는 메시지로 요금이 발생할 가능성은 적지만 사용 후에는 프로그램을 중지시키는 것이 좋습니다.