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

Posted

技术标签:

【中文标题】MQTT 订阅 / OTA 更新深度睡眠 / ESP32 / FreeRTOS【英文标题】:MQTT Subscribe / OTA Update Deep Sleep / ESP32 / FreeRTOS 【发布时间】:2021-04-22 09:11:06 【问题描述】:

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


进展

它运行

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

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


    "state":
        "desired":
            "output":true
        
    

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


物联网工作

为了解决这个问题,我在控制台中创建了一个自定义 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

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


【问题讨论】:

将消息留在队列中是正确的解决方案,但您似乎需要修复与 AWS 的 MQTT 连接。睡觉前你会关机吗? 您从客户端订阅的 QOS 是什么? 订阅 qos=1。会话设置为持久。任何想法需要如何配置 mqtt 连接以使队列工作? 【参考方案1】:

是时候分享我通过拼凑大量帖子并联系非常有帮助的 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 作业来管理您的 OTA 推出,这是最初的意图。

【讨论】:

【参考方案2】:

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

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

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

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

【讨论】:

该问题与保留消息无关。 截至 2022 年 1 月 1 日(不确定有多远)IotCore 支持保留消息:--- 引用:docs.aws.amazon.com/iot/latest/developerguide/mqtt.html AWS IoT Core 支持 MQTT v3.1.1 中描述的 RETAIN 标志。当客户端在其发布的 MQTT 消息上设置 RETAIN 标志时,AWS IoT Core 会保存该消息。然后可以将其发送给新订阅者,通过调用 GetRetainedMessage 操作进行检索,并在 AWS IoT 控制台中查看。 AWS IoT Core 将消息在最后一次更新或访问后保留三年。

以上是关于MQTT 订阅 / OTA 更新深度睡眠 / ESP32 / FreeRTOS的主要内容,如果未能解决你的问题,请参考以下文章

(超简单)ESP8266深度睡眠模式下远程采集温湿度信息

Jmeter测试MQTT,发布和订阅消息查看不到响应数据,需要配置啥吗

Android使用MQTT订阅及发布消息(初步了解Mqtt以及实现Android操作mqtt服务)

MQTT--mosquitto实现发布与订阅

Linux编程MQTT实现主题发布订阅

MQTT协议-----订阅