
使用 paho-mqtt 将夜灯接入 MQTTRaspberry Pi 与虚拟 IoT 设备实战指南【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners导读本文基于 Microsoft「IoT for Beginners」课程第 4 课1-getting-started/lessons/4-connect-internet的「连接互联网」部分聚焦于为夜灯nightlight项目打通 MQTT 通信链路。你将学习在 Raspberry Pi 或虚拟 IoT 设备上安装paho-mqtt客户端库、配置唯一客户端 ID并与公共测试代理test.mosquitto.org建立连接。读完本文后你将掌握 MQTT 客户端连接、消息循环与主题topic命名的基本原理并能在本地运行代码验证「MQTT connected!」的连接结果为后续遥测上报与命令控制打下基础。背景为什么夜灯需要 MQTT「IoT」中的I代表 Internet。在本课的前几部分夜灯依靠设备本地代码直接读取光敏传感器并控制 LED而本部分的目标是把控制逻辑「上移」到服务器端设备只负责通过 MQTT 上报光照度遥测数据服务器代码在收到数据后决策再通过 MQTT 下发命令控制 LED 开关。这对应的正是物联网最常见的发布/订阅publish/subscribe通信模型设备连接到一个 MQTT 代理broker向其发布遥测、订阅命令云服务同样连接该代理订阅所有遥测、向指定设备发布命令。整体流程见课程总览文档 4-connect-internet/README.md 中的 pub-sub.png 示意图。由于搭建私有 MQTT 代理较为复杂本课选用由 Eclipse 基金会维护的开源代理 Mosquitto 提供的公共测试服务test.mosquitto.org——无需注册账号即可用于测试 MQTT 客户端与服务器代码。⚠️ 安全提示该测试代理是公开且不安全的任何人都有可能监听到你发布的消息因此绝不能用它传输需要保密的数据。安装 MQTT 客户端库前置条件已按课程前几部分完成夜灯项目并在 VS Code 中打开。虚拟 IoT 设备终端必须处于 Python 虚拟环境.venv中Raspberry Pi直接在系统 Python 环境操作不额外使用虚拟环境。安装 paho-mqtt在终端中执行pip3 install paho-mqttpaho-mqtt 是 Eclipse Paho 项目提供的 Python MQTT 客户端库也是本课程设备端与服务器端统一使用的通信库。虚拟环境方案可参考课程总览中的「配置 Python 虚拟环境」一节python3 -m venv .venv创建、source ./.venv/bin/activate激活确保依赖只安装到当前项目目录避免与系统其他 Python 包发生版本冲突。编写设备端连接代码设备端代码文件为 app.py完整源码如下虚拟设备版Pi 版与之几乎一致仅将counterfit_*导入替换为grove.*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)步骤一引入 MQTT 库在app.py顶部添加import paho.mqtt.client as mqttpaho.mqtt.client提供了Client、connect、publish、subscribe、loop_start等一系列 API是应用与 MQTT 代理通信的核心入口。步骤二定义唯一客户端 ID 与客户端名在光敏传感器与 LED 定义之后添加id ID client_name id nightlight_client务必将ID替换为唯一标识符原因如下test.mosquitto.org是公共代理全球许多用户包括其他正在做本作业的学生共用它唯一的 MQTT 客户端名client_name能避免不同客户端的连接互相冲突该 ID 之后还会拼接到遥测主题与命令主题中如id /telemetry、id /commands唯一性保证你发布/订阅的主题不与他人代码互相干扰在后续编写服务器代码时还需要使用完全相同的 ID 才能订阅到同一主题课程特别警告服务器端 ID 必须与设备端一致否则无法收到遥测消息。 提示可以使用 GUID 生成网站如 GUIDGen生成一个随机唯一 ID。步骤三创建客户端并连接代理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)与公共 MQTT 代理建立 TCP 连接MQTT 默认使用 1883 端口mqtt_client.loop_start()启动一个后台线程运行消息处理循环持续监听所有已订阅主题上的消息——这正是后续遥测发送与命令接收能够「随时触发」的机制基础。步骤四运行验证以与课程前几部分相同的方式运行代码虚拟设备需先确保 CounterFit 应用已启动并在正确引脚上创建了光敏传感器与 LED(.venv) ➜ nightlight python app.py MQTT connected! Light level: 0 Light level: 0看到MQTT connected!即表示设备已成功连上 MQTT 代理。此时主循环仍沿用本地控制逻辑光照值小于 300 时点亮 LED否则熄灭阈值 300 是本课本地夜灯逻辑的判定标准。 完整可运行代码位于仓库 code-mqtt/virtual-device虚拟设备与 code-mqtt/piRaspberry Pi目录。深入理解 MQTT 的核心机制结合课程总览文档 4-connect-internet/README.md 中的说明理解以下几点能帮助你正确使用上面的连接代码主题Topics与通配符MQTT 消息通过命名主题路由而非直接发送给某个客户端。客户端可以向主题发布消息订阅了该主题的所有客户端都会收到。主题支持层级结构可用通配符订阅多个层级例如把温度发到/telemetry/temperature、湿度发到/telemetry/humidity云端只需订阅/telemetry/*即可同时接收两类遥测。服务质量QoS消息可以指定服务质量级别至多一次At most once消息只发送一次收发双方不做任何确认fire and forget至少一次At least once发送方反复重试直到收到确认acknowledged delivery恰好一次Exactly once收发双方通过两级握手确保只收到一份拷贝assured delivery。保留消息、心跳与安全尽管名字里有「Message Queueing」MQTT并不真正支持消息队列客户端断线重连后收不到断线期间的消息但可给消息设置retained保留标志代理会保存某个主题上最后一条带该标志的消息并在新客户端订阅时立刻下发保证客户端总能拿到最新值MQTT 还支持keep alive心跳机制在消息间隔较长时检测连接是否仍然存活MQTT 基于 TCP/IP 通信默认端口 1883与 HTTP 不同也可以通过 WebSocket 与浏览器中的应用通信或绕过防火墙限制连接既可以是公开开放的也可以通过用户名/密码或证书进行加密与认证。为什么本课使用loop_start()而非loop_forever()从源码结构看设备端后续code-telemetry 与 code-commands 版本会同时进行「主循环读取传感器并发布遥测」与「后台监听命令」两条并行任务主线程负责传感器采样与发布loop_start()启动的后台线程负责分发收到的订阅消息给回调函数。这正是连接阶段就调用loop_start()的用意——它为后续章节的「遥测上报 命令响应」并发模型提前搭好了运行框架。面向单片机的对照实现虽然本文聚焦于 Raspberry Pi / 虚拟设备Python 版但课程在 wio-terminal-mqtt.md 中为 Wio Terminal 提供了基于 PlatformIO 的 C 对照实现位于 code-mqtt/wio-terminal/nightlight/src/main.cpp核心逻辑可以印证上述 MQTT 连接流程#include PubSubClient.h #include rpcWiFi.h #include SPI.h #include config.h void createMQTTClient() { client.setServer(BROKER.c_str(), 1883); reconnectMQTTClient(); }使用PubSubClient库setServer(BROKER.c_str(), 1883)显式指定代理地址与1883 端口Python 版connect(test.mosquitto.org)内部同样使用该默认端口reconnectMQTTClient()循环尝试client.connect(CLIENT_NAME.c_str())并打印client.state()返回值以输出连接失败原因失败后每 5 秒重试setup()中先connectWiFi()再createMQTTClient()说明网络连通是 MQTT 连接的前提loop()中每次都调用reconnectMQTTClient()与client.loop()来维持连接与处理消息。这份 C 实现可作为理解「连接建立—断线重连—消息循环」三要素的补充示例也与 Python 版connect()loop_start()形成了良好的概念对照。连接之后的下一步完成 MQTT 连接只是本课的第一步后续课程步骤会在此代码基础上逐步叠加发布遥测single-board-computer-telemetry.md定义client_telemetry_topic id /telemetry将光照值打包为 JSON如{light: 0}通过mqtt_client.publish()发送并以time.sleep(5)控制发送频率接收命令single-board-computer-commands.md定义server_command_topic id /commands通过mqtt_client.subscribe()订阅命令主题并实现handle_command回调根据消息中led_on字段的值调用led.on()/led.off()服务器端编写独立的 Python 服务器应用见 code-server/server/app.py以id nightlight_server作为客户端名连接同一代理订阅遥测主题收到遥测后计算{led_on: payload[light] 300}并通过client.publish(server_command_topic, json.dumps(command))回发命令。这三个阶段的完整演进代码分别位于仓库 code-telemetry、code-commands 与 code-server 目录可供对照学习。常见问题与注意事项虚拟环境未激活在虚拟设备环境下如果直接运行python app.py找不到paho模块请确认终端提示符前有(.venv)前缀Raspberry Pi 场景则无需虚拟环境ID未替换忘记替换占位符会导致客户端名与他人雷同出现连接冲突或收到他人消息服务器端与设备端的 ID 必须完全一致CounterFit 未运行虚拟设备模式依赖 CounterFit 应用提供传感器模拟需先启动它并在正确引脚创建光敏传感器引脚 0与 LED引脚 5对应代码中的GroveLightSensor(0)与GroveLed(5)安全边界test.mosquitto.org仅用于学习与测试不要在上面传输任何敏感数据。总结至此你的 Raspberry Pi 或虚拟 IoT 设备已经具备与 MQTT 代理通信的能力安装了paho-mqtt客户端库配置了唯一客户端名并通过connect()loop_start()建立了连接、启动了后台消息循环。这一步是整个「联网夜灯」项目的地基——后续只需在此基础上添加发布遥测与订阅命令的代码就能实现「设备上报光照度、服务器决策、LED 远程受控」的完整物联网应用闭环。【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考