本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
Amazon IoT Device Shadow 演示应用程序
介绍
本演示演示如何使用Amazon IoTDevice Shadow 库连接到AmazonDevice Shadow 服务. 它使用CoreMqtt 库建立与 TLS(相互身份验证)的 MQTT 连接到Amazon IoTMQTT Broker 和 coreJSON 库解析器来解析从Amazon影子服务。该演示展示了基本的影子操作,例如如何更新影子文档以及如何删除影子文档。该演示还展示了如何在 CoreMQTT 库中注册回调函数来处理影子之类的消息/update
和/update/delta
从发送的消息Amazon IoTDevice Shadow 服务。
此演示仅用作学习练习,因为更新影子文档(状态)和更新响应的请求是由同一个应用程序完成的。在现实的生产场景中,即使设备当前尚未连接,外部应用程序也会请求远程更新设备的状态。设备在连接时将确认更新请求。
要设置和运行 FreeRTOS 演示,请按照中的步骤操作入门.
功能
该演示创建了一个应用程序任务,循环遍历一组演示影子的示例。/update
和/update/delta
模拟切换远程设备状态的回调。它用新的发送影子更新desired
状态并等待设备更改它的reported
州是为了回应新的desired
状态。此外,一个影子/update
callback 用于打印变化的阴影状态。此演示还使用安全的 MQTT 连接到Amazon IoTMQTT 经纪商,并假设有powerOn
状态在设备影子中。
演示执行将以下操作:
-
使用中的帮助函数建立 MQTT 连接
shadow_demo_helpers.c
. -
使用定义的宏为设备影子操作汇编 MQTT 主题字符串Amazon IoTDevice Shadow 库。
-
发布到用于删除设备影子的 MQTT 主题以删除任何现有设备影子。
-
订阅 MQTT 主题
/update/delta
、/update/accepted
和/update/rejected
在中使用帮助函数shadow_demo_helpers.c
. -
发布所需的状态
powerOn
在中使用帮助函数shadow_demo_helpers.c
. 这将导致/update/delta
要发送到设备的消息。 -
在中处理传入的 MQTT 消息
prvEventCallback
,并通过使用由Amazon IoTDevice Shadow 库(Shadow_MatchTopic
)。如果消息是设备影子/update/delta
消息,那么主演示功能将发布第二条消息以将报告的状态更新为powerOn
. 如果/update/accepted
已收到消息,验证它是否具有相同的clientToken
正如之前在更新消息中发布的那样。这将标志着演示的结束。

您可以在文件中找到演示文件中
或者在GitHubfreertos
/demos/device_shadow_for_aws/shadow_demo_main.c
以下屏幕截图显示演示成功时的预期输出。

Connect 到Amazon IoTMQTT 经纪商
连接到Amazon IoTMQTT 经纪商,我们使用的方法与MQTT_Connect()
中的CoreMQTT 双向身份验证演示.
删除影子文档
要删除影子文档,请致电xPublishToTopic
带有空消息,使用由Amazon IoTDevice Shadow 库。这使用使用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 );
订阅影子主题
订阅 Device Shadow 主题以接收来自Amazon IoT关于影子变化的经纪人。Device Shadow 主题是由 Device Shadow 库中定义的宏组合的。以下代码部分显示了如何执行此操作:prvShadowDemoTask
function.
/* 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 ) ); }
发送影子更新
要发送影子更新,演示会调用xPublishToTopic
使用 JSON 格式的消息,使用 Device Shadow 库定义的宏。这使用使用MQTT_Publish
发布到/delete
主题。以下代码部分显示了如何执行此操作:prvShadowDemoTask
function.
#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 ) );
处理影子 Delta 消息和影子更新消息
注册到的用户回调函数CoreMQTT 客户端库MQTT_Init
函数,将通知我们传入的数据包事件。查看回调函数prvEventCallback
回调函数确认传入的数据包是类型MQTT_PACKET_TYPE_PUBLISH
,并使用 Device Shadow 库 APIShadow_MatchTopic
以确认传入的消息是影子消息。
如果传入的消息是带有类型的影子消息ShadowMessageTypeUpdateDelta
,然后我们打电话给prvupdatedDeltaHandlerprvUpdateDeltaHandler
使用 coreJSON 库来解析消息以获取powerOn
状态并将其与本地维护的当前设备状态进行比较。如果不同,本地设备状态将更新以反映powerOn
来自影子文档的状态。
如果传入的消息是带有类型的影子消息ShadowMessageTypeUpdateAccepted
,然后我们打电话给prvupdate 接受处理程序prvUpdateAcceptedHandler
使用 coreJSON 库解析消息以获取clientToken
来自消息。此处理函数检查 JSON 消息中的客户端令牌是否与应用程序使用的客户端令牌匹配。如果不匹配,函数会记录警告消息。