使用 Paho-MQTT 为夜灯接入互联网Raspberry Pi 与虚拟 IoT 设备连接 MQTT 代理实战【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners在 IoT-For-Beginners 课程的第 4 课《Connect your device to the Internet》中夜灯项目的核心目标是让设备具备远程控制能力设备通过 MQTT 协议与公共代理test.mosquitto.org通信向上发布光敏传感器采集的遥测数据向下订阅控制 LED 开关的命令。本文以官方文档为骨架结合仓库内完整可运行的源码详细讲解在 Raspberry Pi 与虚拟 IoT 设备CounterFit两种环境下如何安装 MQTT 客户端库、编写连接代码并完成与代理的连通性验证为后续遥测发布与命令订阅打好基础。背景夜灯的互联网化需要什么夜灯项目在此之前已经在设备本地实现了光传感器读取 LED 开关的闭环逻辑光照低于 300 时开灯否则关灯。本课要做的是把这条控制链路搬到网络上设备端将光强读数作为遥测telemetry通过 MQTT 发布到公共代理服务端后续编写订阅遥测、判断光照并回发命令消息设备端订阅命令主题收到led_on指令后驱动 LED。对应任务流程图为降低学习门槛本课不要求自建代理而是使用 Eclipse Mosquitto 开源 MQTT 代理提供的公共测试服务器test.mosquitto.org。它无需注册账号即可连接非常适合调试 MQTT 客户端与服务端代码。⚠️ 注意该测试代理是公开且不安全的。任何连接者都可能监听到你发布的消息因此绝不能用于传输需要保密的数据。这一前提约束同样适用于整个课程的所有 MQTT 练习。安装 MQTT 客户端库 paho-mqtt要与 MQTT 代理通信设备端需要安装一个 MQTT 客户端库。本课选用 Python 生态中流行的 Paho-MQTT 库通过 pip 安装。操作步骤在 VS Code 中打开夜灯项目nightlight若使用虚拟 IoT 设备确保 VS Code 终端已激活虚拟环境若使用Raspberry Pi则直接使用系统 Python不涉及虚拟环境执行以下命令安装 MQTT 包pip3 install paho-mqtt仓库中对应代码位于 code-mqtt/virtual-device/nightlight/app.py虚拟设备版与 code-mqtt/pi/nightlight/app.py树莓派版两份代码的核心 MQTT 逻辑完全一致差异仅在于传感器与 LED 的导入来源CounterFit 模拟库 vs Grove 真实硬件库。编写设备代码从导入到建立连接设备端app.py的 MQTT 连接逻辑可分为四步下面逐一说明并给出可复制的完整代码。第一步导入 paho-mqtt 客户端模块在app.py文件顶部添加导入import paho.mqtt.client as mqttpaho.mqtt.client模块提供了 MQTT 客户端对象、连接管理与消息收发能力是整个设备联网的基础。第二步定义唯一客户端 ID 与客户端名在光传感器与 LED 定义之后添加id ID client_name id nightlight_clientID需要替换为你自己的唯一标识符。它的作用有两个用作该 MQTT 客户端在代理上的客户端名稍后用作该设备发布主题与订阅主题的名称前缀。由于test.mosquitto.org是公共代理全球各地的学生都在使用它完成同一作业没有唯一 ID 会导致你的客户端名、主题名与他人冲突、消息互相串扰。因此请务必使用随机生成的唯一字符串例如通过 GUID 生成网站生成并保存好这个 ID——在编写服务端代码时还需要使用同一个 ID否则服务端无法订阅到你设备的主题。client_name即id nightlight_client是代理上标识这个客户端的唯一名字。第三步创建客户端对象并连接代理在第二步代码下方添加mqtt_client mqtt.Client(client_name) mqtt_client.connect(test.mosquitto.org) mqtt_client.loop_start() print(MQTT connected!)这段代码做了三件事mqtt.Client(client_name)创建 MQTT 客户端对象携带唯一的客户端名mqtt_client.connect(test.mosquitto.org)向公共代理发起 TCP 连接MQTT 默认端口 1883此处使用默认值无需显式指定mqtt_client.loop_start()启动一个后台线程运行网络处理循环持续监听所有已订阅主题上的消息。结合仓库源码 code-mqtt/virtual-device/nightlight/app.py 可以看到这三步在真实代码中的位置与写法与文档完全一致说明文档示例是可运行的完整实现而非伪代码。第四步运行并验证连接按照上一部分运行程序的方式执行代码。若使用虚拟 IoT 设备请确保 CounterFit 应用正在运行且光传感器与 LED 已创建在正确的引脚光传感器 pin 0、LED pin 5上(.venv) ➜ nightlight python app.py MQTT connected! Light level: 0 Light level: 0看到MQTT connected!即表示设备已成功连上 MQTT 代理。此时代理端注册了名为IDnightlight_client的客户端设备主循环仍按本地逻辑运行读取光照、控制 LED、每秒循环一次联网能力已就绪。 上述完整代码可在 code-mqtt/virtual-device 或 code-mqtt/pi 目录中找到。MQTT 原理深入读懂你刚写的代码为了让这 6 行连接代码真正跑明白有必要理解其背后的 MQTT 协议机制。以下内容来自第 4 课主文档 README.md 的理论讲解与本节代码直接对应。代理-客户端模型与主题路由MQTT 采用**一个代理broker 多个客户端client的星型架构所有客户端都连接到同一个代理由代理负责把消息路由给相关客户端。消息不是直接发给某个客户端而是通过命名主题named topics**路由——客户端向主题发布publish消息所有订阅subscribe了该主题的客户端都会收到消息。这正是你刚创建的这个mqtt_client所扮演的角色它既是未来遥测的发布者也是命令的订阅者。主题层级与通配符主题支持层级结构客户端可以用通配符订阅不同层级。例如把温度发布到/telemetry/temperature、湿度发布到/telemetry/humidity云端应用订阅/telemetry/*即可同时收到两类消息。在夜灯项目中后续步骤将使用ID/telemetry与ID/commands两个主题分别承载遥测上行与命令下行。QoS 服务质量级别消息可以携带 QoS服务质量级别决定投递保证程度级别名称语义0至多一次消息只发送一次收发双方不做任何确认即发后即忘fire and forget1至少一次发送方重复发送直到收到确认acknowledged delivery2恰好一次发送方与接收方通过两阶段握手确保只收到一份消息副本assured delivery从源码看夜灯示例中的publish与subscribe均未显式指定 QoS使用 Paho 客户端的默认值 QoS 0。对于光照遥测这类丢了可以等下一条的数据是合理的但若后续传输关键指令则应根据可靠性需求选择更高 QoS。保留消息与 Keep Alive尽管 MQTT 名字里有Message Queueing但它实际上不支持消息队列——客户端断开期间发送的消息在重连后不会补发已在 QoS 流程中开始处理的消息除外。不过消息可以设置保留标志retained flag代理会保存某主题上最后一条带此标志的消息并在新客户端订阅该主题时立即推送保证订阅方总能拿到最新状态。此外 MQTT 还内置Keep Alive心跳机制在消息间隔较长时探测连接是否仍然存活。这些机制共同决定了设备在弱网环境下的行为。安全性MQTT 连接可以是完全公开开放的也可以使用用户名/密码或证书进行加密保护。公共测试代理test.mosquitto.org属于前一种仅用于学习验证。MQTT 运行在 TCP/IP 之上与 HTTP 底层协议相同但端口不同也可通过 WebSocket 承载以支持浏览器应用或在防火墙限制场景下通信。代码全貌虚拟设备版完整清单把连接逻辑与原有传感器/执行器逻辑合并后虚拟设备版的完整app.py如下与仓库 code-mqtt/virtual-device/nightlight/app.py 一致import time from counterfit_connection import CounterFitConnection from counterfit_shims_grove.grove_light_sensor_v1_2 import GroveLightSensor from counterfit_shims_grove.grove_led import GroveLed import paho.mqtt.client as mqtt CounterFitConnection.init(127.0.0.1, 5000) light_sensor GroveLightSensor(0) led GroveLed(5) id ID client_name id nightlight_client mqtt_client mqtt.Client(client_name) mqtt_client.connect(test.mosquitto.org) mqtt_client.loop_start() print(MQTT connected!) while True: light light_sensor.light print(Light level:, light) if light 300: led.on() else: led.off() time.sleep(1)Raspberry Pi 版本code-mqtt/pi/nightlight/app.py的差异仅在前两行从grove.grove_light_sensor_v1_2和grove.grove_led导入真实硬件驱动且无需CounterFitConnection.init(...)。其余 MQTT 连接代码与主循环完全相同体现出两套硬件平台在课程中的统一抽象。下一步从连接到通信闭环连接成功只是本课的第一块拼图。在 single-board-computer-telemetry.md 中设备会进一步把光照封装为 JSON{light: 0}发布到ID/telemetry主题每 5 秒发送一次见仓库 code-telemetry/virtual-device/nightlight/app.py在 single-board-computer-commands.md 中设备则订阅ID/commands主题通过handle_command回调解析led_on字段驱动 LED。服务端代码则对应仓库 code-server/server/app.py 与 code-commands/server/app.py。关于遥测与命令的设计主文档也给出了值得思考的工程问题发送频率遥测并非越快越好——高频测量能更快响应变化但消耗更多电量、带宽与云端处理资源。恒温器每隔几分钟采样即可而监测关键机械的设备可能需要每秒多次采样断连处理互联网连接不可靠。恒温器可以丢弃旧数据新数据会覆盖旧值但用于趋势分析/异常检测的机器遥测则必须缓存并在恢复连接后补发命令时序若最新命令会覆盖旧命令可忽略旧命令若命令必须按顺序执行如机械臂先上移、再合拢夹爪则需在恢复连接后按序补发。小结至此夜灯设备已经完成了与 MQTT 代理test.mosquitto.org的连接安装了paho-mqtt库、定义了唯一客户端 ID、创建并连接了客户端对象、启动了后台消息循环并通过运行输出验证了MQTT connected!。这条连接是后续遥测发布device → cloud与命令订阅cloud → device双向通信的物理基础也完整覆盖了 MQTT 协议中代理-客户端主题路由QoS保留消息等核心概念。接下来只需按课程顺序完成遥测发送与服务端命令回传夜灯即具备完整的互联网远程控制能力。【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考