本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
Amazon IoT Device Shadow 演示应用程序
此演示托管在 Amazon-FreeRTOS 存储库中,该存储库已过时。建议您在创建新项目时从这里开始。如果您已经有一个基于现已弃用的 Amazon-FreeRTOS 存储库的现有 FreeRTOS 项目,请参阅亚马逊 FreeRTOS Github 存储库迁移指南。
介绍
此演示说明如何使用Device Shadow 库连接到Device Shadow 服务。Amazon IoTAmazon它使用 TLS(双CoreMQTLARARARAR向身份验证)建立与 MQTT 代理的Amazon IoT MQTT 连接,并使用 CoreJSON 库解析器来解析从影子服务收到的Amazon影子文档。该演示显示了基本的影子操作,例如如何更新影子文档和如何删除影子文档。该演示还展示了如何在 CoreMQTT 库中注册回调函数,以处理诸如影子之类的/update/delta
消息/update
以及从 Device Shadow 服务发送的Amazon IoT消息。
此演示仅用于学习练习,因为更新影子文档(状态)的请求和更新响应是由同一个应用程序完成的。在实际生产场景中,即使设备当前未连接,外部应用程序也会远程请求更新设备的状态。设备连接后将确认更新请求。
要设置和运行 FreeRTOS 演示,请按照中的步骤操作FreeRTOS 入门。
功能
该演示创建了一个单一的应用程序任务,该任务循环浏览了一组示例,这些示例演示了暗影/update
和/update/delta
回调,以模拟切换远程设备的状态。它发送带有新desired
状态的影子更新,并等待设备根据新reported
状态更改其desired
状态。此外,阴影/update
回调用于打印不断变化的阴影状态。此演示还使用了与 MQTT Broker 的安全Amazon IoT MQTT 连接,并假设设备影子中存在powerOn
状态。
该演示执行以下操作:
-
使用中的帮助函数建立 MQTT 连接
shadow_demo_helpers.c
。 -
使用Device Shadow 库定义的宏汇编用于设备影子操作的 MQTT 主题字符串。Amazon IoT
-
发布到用于删除设备影子的 MQTT 主题以删除任何现有的设备影子。
-
订阅有关的 MQTT 主题
/update/delta
,/update/accepted
并在中/update/rejected
使用辅助函数shadow_demo_helpers.c
。 -
在中发布
powerOn
使用辅助函数的所需状态shadow_demo_helpers.c
。这将导致向设备发送/update/delta
消息。 -
处理传入的 MQTT 消息
prvEventCallback
,并使用Device Shadow 库 (Shadow_MatchTopic
) 定义的函数确定该消息是否与Amazon IoT设备影子有关。如果消息是设备影子/update/delta
消息,则主演示功能将发布第二条消息,将报告的状态更新为powerOn
。如果收到/update/accepted
消息,请验证该消息是否与先前在更新消息中发布的消息clientToken
相同。这将标志着演示的结束。

演示可以在文件中找到,
也可以在上面找到 GitHubfreertos
/demos/device_shadow_for_aws/shadow_demo_main.c
以下屏幕截图显示 Demo 成功执行时的预期输出。

Connect 到Amazon IoT MQTT 经纪人
要连接到Amazon IoT MQTT 代理,我们使用与MQTT_Connect()
中相同的方法CoreMQTT 双向身份验证演示。
删除影子文档
要删除影子文档,请xPublishToTopic
使用 Device Shadow 库定义的宏调Amazon IoT用一条空消息。这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
函数中执行此操作。
/* 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 ) ); }
发送影子更新
要发送影子更新,演示使用Device Shadow 库定义的宏调xPublishToTopic
用 JSON 格式的消息。这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 ) );
处理影子增量消息和影子更新消息
使用该函数注册到 CoreMQTT 客户端库MQTT_Init
函数将通知我们传入的数据包事件。请参阅 prvEventCallback
回调函数确认传入的数据包是类型的MQTT_PACKET_TYPE_PUBLISH
,并使用Device Shadow 库 APIShadow_MatchTopic
来确认传入的消息是影子消息。
如果传入的消息是类型为的影子消息ShadowMessageTypeUpdateDelta
,则我们调用 prvUpdateDeltaHandlerprvUpdateDeltaHandler
使用 CoreJSON 库解析消息以获取powerOn
状态的增量值,并将其与本地维护的当前设备状态进行比较。如果两者不同,则会更新本地设备状态以反映影子文档中powerOn
状态的新值。
如果传入的消息是类型为的影子消息ShadowMessageTypeUpdateAccepted
,则我们调用 prvUpdateAcceptedHandlerprvUpdateAcceptedHandler
解析消息,以clientToken
从消息中获取。此处理函数检查 JSON 消息中的客户端令牌是否与应用程序使用的客户端令牌相匹配。如果不匹配,该函数会记录警告消息。