MQTT 订阅 / OTA 更新深度睡眠 / ESP32 / FreeRTOS

时间:2021-01-18 03:01:32

标签: mqtt esp32 aws-iot freertos

目标是在定期退出深度睡眠的 IoT 设备中通过 MQTT 接收消息。 OTA 更新与任何其他参数更新存在完全相同的注意事项。就我而言,最终,我想将其用于两者。


进展

运行

设备唤醒大约 15 秒。如果在那段时间,我向相关主题发布了一堆消息,则消息成功到达。在 AWS 控制台内,我可以发布到:

$aws/things/<device-name>/shadow/update/delta

{
    "state":{
        "desired":{
            "output":true
        }
    }
}

delta 回调函数为“输出”运行。很棒,但对任何人都没有实际用途。


物联网工作

我在控制台中创建了一个自定义 AWS IoT 作业以解决该问题。我的想法是它可能会保留消息以确保交付。过去半个小时我一直在运行这项工作,但到目前为止还没有任何进展。它有 20 次超时,但仍然停留在排队状态,甚至还没有进行中......所以,这种方法显然存在缺陷。


AWS CLI 测试

为了完整起见,我尝试从控制台发出 MQTT 消息。它的好处是您可以指定 QOS,(理论上)确保它至少交付一次。

aws iot-data publish --topic "$aws/things/<device-name>/shadow/update/delta" --qos 1 --payload file://Downloads/outputTrue.json --cli-binary-format raw-in-base64-out

但奇怪的是,这似乎根本不起作用。我根本没有看到消息到达代理:在控制台测试中订阅。


2 个答案:

答案 0 :(得分:0)

AWS IoT Core 不支持保留消息,请参阅 here

<块引用>

MQTT 规范为发布者提供了一个规定,以请求代理保留发送到某个主题的最后一条消息,并将其发送给所有未来的主题订阅者。 AWS IoT 不支持保留消息。如果请求保留消息,连接将断开。

由于唤醒时间是周期性的,一种可能的方法是在后端正在侦听的单独主题中发布设备的下一个唤醒时段。一旦插槽打开,您的后端就会将所需信息发布到您的设备主题。

当然,这种方法在延迟和网络稳定性方面非常脆弱。

答案 1 :(得分:0)

是时候分享我从拼凑大量帖子并联系非常有帮助的 AWS 支持团队中找到的答案了。这个链接是真正涵盖它的链接:

https://docs.aws.amazon.com/iot/latest/developerguide/jobs-devices.html#jobs-workflow-device-online

我总结的伪代码是:

1. init() & connect() to mqtt as before.
2. Subscribe to the following topics & create callback function for each:

  a. Get pending.   
  b. Notify next.    
  c. Get next.
  d. Update rejected.   
  e. Update accepted.   

3.  Create Publish topics:

  a.    Get pending.
  b.    Get Next.

4. Pending topics = optional. But necessary to handle many tasks and select between them. 
5. Aws-iot-jobs-describe() to publish a request for the next job. It links up to the notify next callback (somehow). 
6. In the callback, grab job document, execute job & report Success / Failure. 
7. Done.

在 esp-aws-iot/samples/linux/jobs-samples/jobs_sample.c 中有一个有用的例子。您需要从示例 aws_iot_config.h 中复制一些常量。

完成所有这些后,您就可以使用 AWS Jobs 来管理您的 OTA 部署,这是最初的意图。