
IoT-For-Beginners 实战用 MQTT 从 Raspberry Pi 与虚拟设备发布光照遥测数据【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners本篇技术指南以 Microsoft 开源课程IoT-For-Beginners第 4 课Connect your Device to the Internet的 Raspberry Pi / 虚拟 IoT 设备章节single-board-computer-telemetry.md为核心骨架完整讲解如何把夜灯nightlight项目中的光敏传感器读数封装为 JSON 遥测消息通过 MQTT 发布到公共 Brokertest.mosquitto.org。读完本文你将掌握 MQTT 发布/订阅模型、telemetry遥测topic 的命名与设计、paho-mqtt客户端库的使用以及如何与仓库内的服务器端监听代码配合为后续服务器根据光照下发 LED 命令的完整闭环打下基础。遥测Telemetry与 MQTT 的基本概念在动手写代码之前先厘清两个贯穿本课的核心概念。遥测telemetry一词源于希腊语意为远程测量指从传感器采集数据并发送到云端的行为。在本项目中夜灯设备把 Grove 光敏传感器读取到的光照强度值作为遥测数据发送出去。课程 README 中给出了一个智能恒温器的遥测数据示例说明典型的遥测 JSON 往往携带多个带名称、带描述的字段例如NameValueDescriptionthermostat_temperature18°C恒温器内置温度传感器的读数livingroom_temperature19°C名为livingroom的远端温度传感器读数bedroom_temperature21°C名为bedroom的远端温度传感器读数MQTTMessage Queueing Telemetry Transport是本课采用的通信协议它是 1999 年为石油管道监控而设计的轻量级开放标准后由 IBM 在 15 年后发布为开放标准。MQTT 采用一个 Broker、多个客户端的架构——所有客户端都连接到 BrokerBroker 按主题topic路由消息客户端可以向某个 topic 发布publish消息订阅subscribe了该 topic 的客户端都会收到消息。 尽管名字里带 QueueingMQTT 实际上并不支持消息队列客户端断线重连后不会收到断线期间发送的消息。Broker 会保留设置了 retained 标志的最后一条消息并在新客户端订阅时将其下发。MQTT 还内置 keep alive 机制在消息间隔较长时探测连接是否存活。本课使用的 Broker 是test.mosquitto.org它运行开源 Broker Eclipse Mosquitto无需注册账号即可连接适合测试。但该公共 Broker 不安全——任何在网络上的人都能监听到你发布的内容因此绝不能用于需要保密的业务数据。前置准备连接 MQTT 与安装 paho-mqtt发布遥测的前提是设备已经成功连接 MQTT Broker。这一步在上一节 single-board-computer-mqtt.md 中完成核心要点如下在 VS Code 中打开 nightlight 项目虚拟设备需先激活 Python 虚拟环境.venv树莓派上则直接使用系统 Python。安装 MQTT 客户端库pip3 install paho-mqttpaho-mqtt是 Python 生态中流行的 MQTT 客户端库。注意如果使用虚拟设备该库只安装在虚拟环境内部不会污染系统全局 Python。在app.py中引入库并建立连接import paho.mqtt.client as mqtt 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!)关于ID的唯一性要求test.mosquitto.org 是公共 Broker全世界包括同课程的许多同学都在使用。必须用唯一 ID 作为 MQTT client 名称和后续 topic 名称的一部分避免与他人代码互相干扰。这个 ID 在后续编写服务器端代码时还要复用必须完全一致否则服务器订阅/发布不到正确的 topic。课程建议用 GUIDGen 之类的工具生成 GUID 作为 ID。mqtt_client.loop_start()会在后台线程启动消息处理循环持续监听已订阅主题上到达的消息。运行上述代码终端应输出MQTT connected!。发布遥测构造 JSON 消息并发送到 MQTT现在进入本文主题对应 single-board-computer-telemetry.md 的全部内容。目标是把光敏传感器读数打包成 JSON发布到 MQTT Broker 的 telemetry topic 上。第一步导入 json 库在app.py顶部加入import jsonjson是 Python 标准库用于把遥测数据编码为 JSON 文档。数据以 JSON 传输是 MQTT IoT 场景的通行做法——JSONJavaScript Object Notation是用键值对在文本中编码数据的标准格式。第二步声明 telemetry topic在client_name声明之后添加client_telemetry_topic id /telemetryclient_telemetry_topic是设备发布光照强度的 MQTT 主题。由于主题中带入了唯一id你的遥测消息与其他人发布的遥测消息相互隔离。仓库中同一阶段的其他实现与此保持一致Wio Terminal 版本在 config.h 中定义CLIENT_TELEMETRY_TOPIC ID /telemetry服务器端则在 code-server/server/app.py 中以同样方式拼接client_telemetry_topic——设备与服务器正是靠这一约定在同一个 topic 上碰头。第三步改造主循环发布遥测把文件末尾的while True:循环整体替换为while True: light light_sensor.light telemetry json.dumps({light : light}) print(Sending telemetry , telemetry) mqtt_client.publish(client_telemetry_topic, telemetry) time.sleep(5)这段代码的逻辑非常清晰从 Grove 光敏传感器读取当前光照值light light_sensor.light用json.dumps把它包装成{light: 0}形式的 JSON 文档通过mqtt_client.publish()发布到client_telemetry_topictime.sleep(5)控制发送频率避免消息过密。第四步运行并验证以与上一节相同的方式运行代码。虚拟设备用户需确认 CounterFit 应用正在运行且光敏传感器与 LED 已创建在正确的引脚上默认传感器在引脚 0、LED 在引脚 5。(.venv) ➜ nightlight python app.py MQTT connected! Sending telemetry {light: 0} Sending telemetry {light: 0}当终端持续输出Sending telemetry {light: ...}时说明遥测已经成功发布到 MQTT Broker。完整代码对照你可以直接对照仓库中的成品实现虚拟设备版本code-telemetry/virtual-device/nightlight/app.pyRaspberry Pi 版本code-telemetry/pi/nightlight/app.py两者逻辑完全一致仅导入来源不同虚拟设备通过counterfit_shims_grove与 CounterFit 模拟硬件通信初始化时连接127.0.0.1:5000树莓派则直接使用grove物理硬件库。这也解释了为什么虚拟设备需要先在 VS Code 终端里激活.venv虚拟环境其中已安装 counterfit 相关 shim 包而树莓派直接运行即可。遥测发布频率与断连策略何时发、发多少遥测发多少是 IoT 设计绕不开的问题。课程 README4-connect-internet/README.md给出了权衡框架与本课的time.sleep(5)直接相关测得太频繁更快响应变化但消耗更多电量、带宽产生更多数据云端处理与存储成本更高。对电池供电的远端传感器尤其致命。测得太稀疏可能错过关键状态变化。比如恒温器每天只测一次就可能在大晴天为夜间温度而持续供暖。课程给出的经验判断是it depends视场景而定恒温器每几分钟测一次足矣而工厂关键设备一旦故障可能造成灾难与巨额损失可能需要每秒多次采样——此时宁可浪费带宽也不能漏掉预示故障的异常数据必要时还可以先用边缘设备预处理遥测。断连loss of connectivity同样需要权衡恒温器的新读数会立刻覆盖旧值断连期间的数据可以丢弃而用于趋势分析与预测性维护的机器遥测则应当保留待网络恢复后补齐重发。此外设计者还要考虑设备在断网期间能否继续本地工作——例如智能恒温器应当能在无法上云时独立做出有限的加热决策。MQTT 本身不保证断连期间的消息送达若业务需要可靠投递设备与服务器需自行实现确认与补发机制例如要求所有消息在回复 topic 上应答未应答的进入手动队列重放。服务器端监听遥测的另一端遥测发布到 Broker 后必须有另一端订阅才能发挥价值。在完整课程序列中这一步对应服务器代码——在本地或 Pi 上运行一个 Python 应用订阅 telemetry topic 并处理光照数据。仓库中的服务器实现见 code-server/server/app.pyimport json import time import paho.mqtt.client as mqtt id ID client_telemetry_topic id /telemetry client_name id _nightlight_server mqtt_client mqtt.Client(client_name) mqtt_client.connect(test.mosquitto.org) mqtt_client.loop_start() def handle_telemetry(client, userdata, message): payload json.loads(message.payload.decode()) print(Message received:, payload) mqtt_client.subscribe(client_telemetry_topic) mqtt_client.on_message handle_telemetry while True: time.sleep(2)要点服务器的id必须与设备端完全一致否则订阅不到设备的遥测 topicmqtt_client.subscribe(client_telemetry_topic)订阅遥测主题每收到一条消息handle_telemetry被回调解码 JSON 后打印Message received: {light: 0}主线程用无限循环while True: time.sleep(2)保持进程存活消息处理在loop_start()启动的后台线程中进行。 设备端app.py必须保持运行服务器端app.py才能持续收到消息——两者分别运行在各自的虚拟环境中。在更完整的闭环中服务器收到遥测后会据此下发 LED 命令command { led_on : payload[light] 300 }并发布到id /commandstopic见 code-commands/server/app.py设备端则通过订阅server_command_topic与on_message handle_command回调来点亮/熄灭 LED见 code-commands/virtual-device/nightlight/app.py。遥测与命令分别使用单条 topic 意味着多个设备的遥测会出现在同一条 telemetry topic 上若要精确控制某台设备可改用带设备 ID 的独立命令 topic如/commands/device1、/commands/device2。MQTT 进阶知识QoS、通配符与加密课程 README 还补充了理解本课代码所必需的 MQTT 底层机制主题层次与通配符topic 有层级结构客户端可用通配符订阅多个层级。例如温度遥测发到/telemetry/temperature、湿度发到/telemetry/humidity云端应用订阅/telemetry/*即可同时收到两类消息。服务质量QoS决定消息投递保障分三档至多一次At most once只发送一次不进行任何确认即发后即忘fire and forget至少一次At least once发送方不断重试直到收到确认acknowledged delivery恰好一次Exactly once发送方与接收方进行两级握手保证只收到一份副本assured delivery。连接安全MQTT 连接可以是公开开放的也可以用用户名/密码或证书加密。注意 MQTT 基于 TCP/IP与 HTTP 相同的底层网络协议但端口不同还可以通过 MQTT over WebSockets 与浏览器中的 Web 应用通信或穿透阻止标准 MQTT 连接的防火墙。自建 Broker 的补充实验课程建议在学有余力时用 Mosquitto 自建 Broker 做实验。默认情况下 Mosquitto 不允许匿名连接也不允许来自本机之外的连接如需放开可在mosquitto.conf中配置listener 1883 0.0.0.0 allow_anonymous true小结本文以 single-board-computer-telemetry.md 为主线完成了从概念到可运行代码的完整闭环理解 telemetry 的定义以及 MQTT 的 topic、Broker、发布/订阅模型安装paho-mqtt用唯一 ID 连接公共 Brokertest.mosquitto.org用json.dumps把光敏传感器读数封装为{light: ...}每 5 秒发布到id /telemetrytopic对照仓库中的服务器实现理解遥测如何被另一端订阅与消费掌握 QoS、通配符、消息保留、keep alive 与加密等进阶机制并能权衡遥测频率与断连策略。设备侧完整代码虚拟设备版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 import json CounterFitConnection.init(127.0.0.1, 5000) light_sensor GroveLightSensor(0) led GroveLed(5) id ID client_telemetry_topic id /telemetry 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 telemetry json.dumps({light : light}) print(Sending telemetry , telemetry) mqtt_client.publish(client_telemetry_topic, telemetry) time.sleep(5)把这套代码跑起来并在后续课程中把它与服务器端命令下发代码组合你就能实现一个真正通过互联网远程控制的 IoT 夜灯。仓库中的成品代码位于 code-telemetry、code-mqtt 与 code-commands 目录可随时对照与复用。【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考