AWS IoT 디바이스 섀도우 데모 애플리케이션
중요
이 데모는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 여기서 시작하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드 섹션을 참조하세요.
소개
이 데모에서는 AWS IoT 디바이스 섀도우 라이브러리를 사용하여 AWS 디바이스 섀도우 서비스에 연결하는 방법을 보여줍니다. coreMQTT 라이브러리를 사용하여 TLS(상호 인증)를 통해 AWS IoT MQTT 브로커 및 coreJSON 라이브러리 파서에 대한 MQTT 연결을 설정하여 AWS 섀도우 서비스에서 수신한 섀도우 문서를 파싱합니다. 데모에서는 섀도우 문서 업데이트 방법, 섀도우 문서 삭제 방법 등 기본적인 섀도우 작업을 보여줍니다. 또한 coreMQTT 라이브러리에 콜백 함수를 등록하여 AWS IoT 디바이스 섀도우 서비스에서 전송되는 섀도우 /update 및 /update/delta 메시지와 같은 메시지를 처리하는 방법도 보여줍니다.
이 데모는 섀도우 문서(상태) 업데이트 요청과 업데이트 응답이 동일한 애플리케이션에서 수행되므로 학습용으로만 사용됩니다. 실제 프로덕션 시나리오에서는 디바이스가 현재 연결되어 있지 않더라도 외부 애플리케이션이 원격으로 디바이스 상태 업데이트를 요청합니다. 디바이스가 연결되어 있으면 업데이트 요청을 확인합니다.
참고
FreeRTOS 데모를 설정하고 실행하려면 FreeRTOS 시작하기의 단계를 따릅니다.
기능
이 데모에서는 원격 디바이스 상태 전환을 시뮬레이션하는 섀도우 /update 및 /update/delta 콜백을 보여주는 일련의 예제를 반복하는 단일 애플리케이션 태스크를 생성합니다. 새 desired 상태가 포함된 섀도우 업데이트를 전송하고 디바이스가 새 desired 상태에 대한 응답으로 reported 상태를 변경할 때까지 기다립니다. 또한 섀도우 /update 콜백은 변화하는 섀도우 상태를 인쇄하는 데 사용됩니다. 또한 이 데모에서는 AWS IoT MQTT 브로커에 대한 보안 MQTT 연결을 사용하며 디바이스 섀도우에서 powerOn 상태를 가정합니다.
데모는 다음 작업을 수행합니다.
-
shadow_demo_helpers.c의 헬퍼 함수를 사용하여 MQTT 연결을 설정합니다. -
AWS IoT 디바이스 섀도우 라이브러리에 정의된 매크로를 사용하여 디바이스 섀도우 작업에 사용할 MQTT 주제 문자열을 어셈블합니다.
-
디바이스 섀도우를 삭제하는 데 사용되는 MQTT 주제에 게시하여 기존 디바이스 섀도우를 삭제합니다.
-
shadow_demo_helpers.c의 헬퍼 함수를 사용하여/update/delta,/update/accepted및/update/rejected에 대한 MQTT 주제를 구독합니다. -
powerOn의 헬퍼 함수를 사용하여 원하는shadow_demo_helpers.c상태를 게시합니다. 그러면/update/delta메시지가 디바이스로 전송됩니다. -
prvEventCallback에서 들어오는 MQTT 메시지를 처리하고, AWS IoT 디바이스 섀도우 라이브러리(Shadow_MatchTopic)에 정의된 함수를 사용하여 메시지가 디바이스 섀도우와 관련이 있는지 확인합니다. 메시지가 디바이스 섀도우/update/delta메시지인 경우 메인 데모 함수는 보고된 상태를 업데이트하는 두 번째 메시지를powerOn에 게시합니다./update/accepted메시지가 수신되면clientToken이 이전에 업데이트 메시지에 게시된 것과 동일한지 확인합니다. 그러면 데모가 종료됩니다.
데모는 파일 또는 GitHubfreertos/demos/device_shadow_for_aws/shadow_demo_main.c
다음 스크린샷은 데모가 성공할 경우 예상되는 출력을 보여줍니다.
AWS IoT MQTT 브로커에 연결
AWS IoT MQTT 브로커에 연결하기 위해 coreMQTT 상호 인증 데모의 MQTT_Connect()와 동일한 메서드를 사용합니다.
섀도우 문서 삭제
섀도우 문서를 삭제하려면 AWS IoT 디바이스 섀도우 라이브러리에 정의된 매크로를 사용하여 빈 메시지와 함께 xPublishToTopic을 호출합니다. 그러면 MQTT_Publish를 사용하여 /delete 주제에 게시합니다. 다음 코드 섹션은 prvShadowDemoTask 함수에서 이 작업이 어떻게 이루어지는지 보여줍니다.
/* First of all, try to delete any Shadow document in the cloud. */ returnStatus = PublishToTopic( SHADOW_TOPIC_STRING_DELETE( THING_NAME ), SHADOW_TOPIC_LENGTH_DELETE( THING_NAME_LENGTH ), pcUpdateDocument, 0U );
섀도우 주제 구독
AWS IoT 브로커로부터 섀도우 변경에 대한 알림을 받으려면 디바이스 섀도우 주제를 구독합니다. 디바이스 섀도우 주제는 디바이스 섀도우 라이브러리에 정의된 매크로에 의해 어셈블됩니다. 다음 코드 섹션은 prvShadowDemoTask 함수에서 이 작업이 어떻게 이루어지는지 보여줍니다.
/* Then try to subscribe shadow topics. */ if( returnStatus == EXIT_SUCCESS ) { returnStatus = SubscribeToTopic( SHADOW_TOPIC_STRING_UPDATE_DELTA( THING_NAME ), SHADOW_TOPIC_LENGTH_UPDATE_DELTA( THING_NAME_LENGTH ) ); } if( returnStatus == EXIT_SUCCESS ) { returnStatus = SubscribeToTopic( SHADOW_TOPIC_STRING_UPDATE_ACCEPTED( THING_NAME ), SHADOW_TOPIC_LENGTH_UPDATE_ACCEPTED( THING_NAME_LENGTH ) ); } if( returnStatus == EXIT_SUCCESS ) { returnStatus = SubscribeToTopic( SHADOW_TOPIC_STRING_UPDATE_REJECTED( THING_NAME ), SHADOW_TOPIC_LENGTH_UPDATE_REJECTED( THING_NAME_LENGTH ) ); }
섀도우 업데이트 전송
섀도우 업데이트를 전송하기 위해 이 데모는 디바이스 섀도우 라이브러리에 정의된 매크로를 사용하여 JSON 형식 메시지와 함께 xPublishToTopic을 호출합니다. 그러면 MQTT_Publish를 사용하여 /delete 주제에 게시합니다. 다음 코드 섹션은 prvShadowDemoTask 함수에서 이 작업이 어떻게 이루어지는지 보여줍니다.
#define SHADOW_REPORTED_JSON \ "{" \ "\"state\":{" \ "\"reported\":{" \ "\"powerOn\":%01d" \ "}" \ "}," \ "\"clientToken\":\"%06lu\"" \ "}" snprintf( pcUpdateDocument, SHADOW_REPORTED_JSON_LENGTH + 1, SHADOW_REPORTED_JSON, ( int ) ulCurrentPowerOnState, ( long unsigned ) ulClientToken ); xPublishToTopic( SHADOW_TOPIC_STRING_UPDATE( THING_NAME ), SHADOW_TOPIC_LENGTH_UPDATE( THING_NAME_LENGTH ), pcUpdateDocument, ( SHADOW_DESIRED_JSON_LENGTH + 1 ) );
섀도우 델타 메시지 및 섀도우 업데이트 메시지 처리
MQTT_Init 함수를 사용하여 coreMQTT 클라이언트 라이브러리
이 콜백 함수는 들어오는 패킷이 MQTT_PACKET_TYPE_PUBLISH 유형임을 확인하고 디바이스 섀도우 라이브러리 API Shadow_MatchTopic을 사용하여 들어오는 메시지가 섀도우 메시지임을 확인합니다.
들어오는 메시지가 ShadowMessageTypeUpdateDelta 유형의 섀도우 메시지인 경우에는 prvUpdateDeltaHandlerprvUpdateDeltaHandler는 coreJSON 라이브러리를 사용하여 메시지를 파싱해 powerOn 상태에 대한 델타 값을 가져오고 이를 로컬에서 유지 관리되는 현재 디바이스 상태와 비교합니다. 두 값이 다를 경우 섀도우 문서의 새 powerOn 상태 값을 반영하도록 로컬 디바이스 상태가 업데이트됩니다.
들어오는 메시지가 ShadowMessageTypeUpdateAccepted 유형의 섀도우 메시지인 경우에는 prvUpdateAcceptedHandlerprvUpdateAcceptedHandler는 coreJSON 라이브러리를 사용하여 메시지를 파싱해 메시지에서 clientToken을 가져옵니다. 이 핸들러 함수는 JSON 메시지의 클라이언트 토큰이 애플리케이션에서 사용하는 클라이언트 토큰과 일치하는지 확인합니다. 일치하지 않을 경우 함수는 경고 메시지를 로그합니다.