
IoT-For-Beginners 实操使用 paho-mqtt 将夜灯设备接入 test.mosquitto.org 公共 MQTT Broker【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners本文是 IoT-For-Beginners 课程第 4 课《将设备连接到互联网》中「树莓派 / 虚拟 IoT 设备」分支的实战指南讲解如何用 Python 的paho-mqtt库让夜灯设备通过 MQTT 协议与公共 Brokertest.mosquitto.org建立连接。读完本文你将掌握 MQTT 客户端的三步核心流程——安装依赖、创建客户端并连接 Broker、启动后台消息循环并理解设备为后续遥测上报与远程命令控制所做的主题与命名准备。任务背景让夜灯从本地控制走向联网控制本课的前一阶段夜灯设备树莓派 Grove 传感器或基于 CounterFit 的虚拟 IoT 设备已经在本地实现了「光照传感器读数 → 阈值判断 → 点亮/熄灭 LED」的完整逻辑。本阶段的目标是引入互联网控制设备需要与test.mosquitto.org通信一方面发布携带光照读数的遥测数据telemetry另一方面准备订阅来自云端的 LED 控制命令。整节课的最终架构是设备发布遥测 → 服务端代码接收并判断光照阈值 → 服务端向命令主题发布led_on指令 → 设备订阅命令主题并驱动 LED。与其自建 MQTT Broker本课直接使用 Eclipse Mosquitto 开源 Broker 的公共测试实例test.mosquitto.org。它无需注册账号即可连接非常适合验证 MQTT 客户端与服务器代码。但要注意这是一个公开且不安全的 Broker任何人都可能监听你发布的消息切勿传输任何需要保密的数据。下图为本次作业的整体数据流光照读数被读取、判断后最终通过命令控制 LEDMQTT 快速认知Broker、主题与发布/订阅在动手编码前先建立 MQTT 的核心模型详细讲解见第 4 课 READMEBroker 与客户端MQTT 采用单一 Broker 多个客户端的星型结构。所有客户端都连接到 Broker由 Broker 负责把消息路由给相关客户端。主题路由消息通过命名主题topic路由而非直接发给某个客户端。客户端可以发布publish消息到主题任何订阅subscribe该主题的客户端都会收到它。主题层级与通配符主题可以分层例如温度发到/telemetry/temperature、湿度发到/telemetry/humidity云端应用订阅/telemetry/*即可同时收到两类遥测。QoS 服务质量至多一次At most once即发即弃、至少一次At least once发送方重试直到收到确认、恰好一次Exactly once通过两级握手确保只收一份。MQTT 名字里虽有队列但它并不真正支持消息队列客户端断线重连后不会收到断线期间的消息除非消息设置了 retained保留标志——Broker 会保存主题上最后一条带该标志的消息供后续订阅者获取。Keep AliveMQTT 还内置心跳保活机制在消息间隔较长时检查连接是否仍然存活。准备工作VS Code 与运行环境开始前请先打开夜灯项目nightlight project的 VS Code 工作区并根据设备形态确认运行环境虚拟 IoT 设备使用 CounterFit 模拟硬件需要确保终端处于 Python 虚拟环境中例如已激活的.venv并保证 CounterFit 应用正在运行、光照传感器与 LED 已创建在正确的引脚上。树莓派直接在板子上运行不使用虚拟环境。第一步安装 MQTT 客户端包paho-mqtt与 Broker 通信需要 MQTT 客户端库。在终端中执行pip3 install paho-mqtt虚拟 IoT 设备场景该包会安装到当前激活的虚拟环境内仅对当前项目生效树莓派场景直接安装到系统的 Python 环境中。paho-mqtt是 Python 生态中最流行的 MQTT 库之一本课程的服务端代码见 code-server/server/app.py同样依赖它。第二步编写设备连接代码在app.py顶部追加 MQTT 库的导入import paho.mqtt.client as mqttpaho.mqtt.client库让应用具备通过 MQTT 通信的能力。接着在光照传感器与 LED 的定义之后加入设备 ID 与客户端名id ID client_name id nightlight_client务必用唯一 ID 替换ID。test.mosquitto.org是公共 Broker许多学习者都在使用唯一的 MQTT 客户端名与后续的主题名可以保证你的代码不会与其他人的相互干扰。这个 ID 在后续编写服务端代码时还要再次使用服务端用id /telemetry订阅遥测、用id /commands发布命令必须保持一致。你可以通过在线 GUID 生成工具获取一个随机唯一 ID。client_name是当前客户端在 Broker 上的唯一标识符。随后创建客户端对象并连接 Brokermqtt_client mqtt.Client(client_name) mqtt_client.connect(test.mosquitto.org) mqtt_client.loop_start() print(MQTT connected!)这段代码做了三件事mqtt.Client(client_name)以唯一名称创建客户端对象connect(test.mosquitto.org)连接到公共 MQTT Broker默认 1883 端口loop_start()启动一个运行在后台线程中的处理循环持续监听所有已订阅主题上的消息——这是后续接收命令消息的基础。第三步运行并验证连接按上一阶段的运行方式执行代码。虚拟 IoT 设备需确保 CounterFit 应用与传感器/执行器就绪(.venv) ➜ nightlight python app.py MQTT connected! Light level: 0 Light level: 0看到MQTT connected!即表示设备已成功连接 Broker。当前while True:主循环仍保留着本地的阈值控制逻辑light 300时点亮 LED后续步骤会将它替换为「发布遥测」与「订阅命令」的实现。仓库源码对照完整的连接实现课程将本阶段完整代码放在仓库中可直接对照学习虚拟设备版code-mqtt/virtual-device/nightlight/app.py树莓派版code-mqtt/pi/nightlight/app.py两个版本除传感器/执行器的导入来源不同虚拟设备使用counterfit_shims_grove模拟库并通过CounterFitConnection.init(127.0.0.1, 5000)连接 CounterFit树莓派直接使用grove硬件库外MQTT 连接部分完全一致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 # 树莓派版 # from grove.grove_light_sensor_v1_2 import GroveLightSensor # from grove.grove_led import GroveLed import paho.mqtt.client as mqtt # 虚拟设备版需初始化 CounterFit 连接 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)可以观察到几个关键点光照传感器接在 Grove 端口 0LED 接在端口 5本地阈值逻辑以 300 为界与后续服务端判断阈值payload[light] 300保持一致主循环每 1 秒读取一次光照并驱动 LED同时loop_start()的后台线程已就绪等待后续订阅命令。其他硬件平台对照本课还提供了 Wio TerminalArduino分支MQTT 连接思路相同、但 API 不同它使用PubSubClient库通过 main.cpp 中的client.setServer(BROKER.c_str(), 1883)指定 Broker 与端口并在loop()中反复调用client.loop()维持消息处理。感兴趣可对比阅读 wio-terminal-mqtt.md。连接之后遥测主题与命令主题本阶段只完成了连接但它为接下来的两步做好了命名铺垫发布遥测见 single-board-computer-telemetry.md 与 code-telemetry/virtual-device/nightlight/app.pyclient_telemetry_topic id /telemetry # ... telemetry json.dumps({light : light}) mqtt_client.publish(client_telemetry_topic, telemetry) time.sleep(5)设备将光照读数编码为 JSON如{light: 0}发布到id /telemetry主题并让主循环休眠 5 秒以降低发送频率。服务端代码code-server/server/app.py用相同的id订阅该主题打印收到的遥测。处理命令见 single-board-computer-commands.mdserver_command_topic id /commands def handle_command(client, userdata, message): payload json.loads(message.payload.decode()) print(Message received:, payload) if payload[led_on]: led.on() else: led.off() mqtt_client.subscribe(server_command_topic) mqtt_client.on_message handle_command设备订阅id /commands主题服务端据此判断光照阈值并发布{led_on: true/false}指令on_message回调驱动 LED 亮灭。这正是本阶段loop_start()后台循环的意义所在——连接建立后Broker 推送的命令消息将由该循环分发到回调函数。关键注意事项与最佳实践唯一 ID 必须前后一致设备端、服务端的id必须完全相同否则服务端无法订阅到正确的主题。建议生成一个 GUID 后集中记录供设备代码与服务端代码共用。公共 Broker 的隐私边界test.mosquitto.org面向所有人开放任何人可订阅任意主题仅适合课程练习与开发测试严禁发布敏感数据。遥测频率要平衡频率越高响应越快但功耗、带宽、数据量与云端处理成本也随之上升。本课设备取 5 秒间隔、LED 本地循环取 1 秒属于教学场景的合理折中真实产品需结合场景权衡例如恒温器每分钟一次即可而工厂关键设备可能需要每秒多次采样。断线处理MQTT 本身不保证断线期间的消息送达。若业务要求不丢消息需要在设备与服务端自行实现确认/重发机制。延伸阅读第 4 课完整讲义含通信协议对比、QoS 详解、挑战与测验README.md本阶段的作业要求assignment.md中文译文对应的英文原文single-board-computer-mqtt.md课后延伸用 Mosquitto 自行搭建 Broker 并连接体验。默认配置不允许匿名连接与外网访问可在mosquitto.conf中加入listener 1883 0.0.0.0与allow_anonymous true放开限制仅限本地实验。【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考