
上周蹲在机房调温湿度采集节点,对着敲了半屏的paho-mqtt初始化代码突然反应过来,很多人做Python端IoT上报上来就套MQTT,其实根本没必要,不同的硬件、网络、上报频率适配的方案完全不一样。
直接复用现有Web服务的HTTP上报
这是最省事的方案,如果你已经有现成的后端Web服务,连额外的中间件都不用搭,几行代码就能跑。优点是调试成本极低,用Postman就能模拟上报,几乎所有能跑Python的硬件都支持;缺点是每次请求都要走TCP握手,频繁上报的话额外开销不小,也做不到服务端实时下发控制指令。
- 安装依赖库,普通Python环境直接装requests,MicroPython环境用自带的urequests不用额外装:
pip install requests - 写最小上报逻辑,注意超时时间别设太长,避免传感器读取线程被卡住:
import requests import dht11 import time sensor = dht11.DHT11(pin=4) REPORT_URL = "http://你的服务地址/api/iot/report" while True: data = sensor.read() if data.is_valid(): payload = { "device_id": "node_001", "temp": data.temperature, "hum": data.humidity, "ts": int(time.time()) } try: resp = requests.post(REPORT_URL, json=payload, timeout=2) except Exception as e: print(f"上报失败: {e}") time.sleep(300) # 按需求调整上报间隔
如果是ESP8266这类内存极小的MicroPython板子,上报的payload尽量精简,别塞冗余字段,不然容易触发内存溢出重启。
支持双向通信的MQTT长连接上报
这是目前做双向IoT通信最常用的方案,长连接建连之后后续报文的开销很小,服务端可以实时给设备下发控制指令,适合上报频率高、需要远程控制的场景。缺点是需要额外部署维护MQTT broker(比如Mosquitto、EMQX),弱网环境下要自己处理重连、消息去重的逻辑,对设备的稳定性要求更高。
- 安装paho-mqtt库,MicroPython环境用umqtt.simple:
pip install paho-mqtt - 基础初始化代码,记得配置遗嘱消息,方便服务端感知设备离线状态:
import paho.mqtt.client as mqtt import dht11 import time BROKER_ADDR = "你的MQTT服务地址" BROKER_PORT = 1883 TOPIC = "device/node_001/report" client = mqtt.Client(client_id="node_001") client.will_set("device/node_001/status", "offline", qos=1) client.username_pw_set("账号", "密码") client.connect(BROKER_ADDR, BROKER_PORT, keepalive=60) client.loop_start() client.publish("device/node_001/status", "online", qos=1) sensor = dht11.DHT11(pin=4) while True: data = sensor.read() if data.is_valid(): payload = f'{{"temp":{data.temperature},"hum":{data.humidity},"ts":{int(time.time())}}}' client.publish(TOPIC, payload, qos=1) time.sleep(5)
公网部署的话一定要开TLS加密,把服务端口换成8883,不要把1883裸端口暴露在公网;qos级别非必要别开2,弱网下消息堆积容易占满设备内存。
低功耗窄带场景的CoAP上报
这个方案的应用场景比较窄,是跑在UDP上的轻量协议,报文头比HTTP小很多,不需要维持长连接,功耗极低,适合电池供电、靠NB-IoT这类窄带网络传输、上报间隔在分钟级以上的野外节点。缺点是UDP本身不保证消息可靠到达,要自己补重传逻辑,周边调试工具少,生态不如前两个成熟。
给个MicroPython下的最简示例:
import ucoap
import network
import time
from machine import lightsleep
wlan = network.WLAN(network.STA_IF)
wlan.connect("你的WiFi/NB-IoT网络", "密码")
while not wlan.isconnected():
time.sleep(0.5)
client = ucoap.Client(udp=True)
server = ("你的CoAP服务地址", 5683)
while True:
temp = read_sensor() # 替换成自己的传感器读取逻辑
client.put(server, "/report", payload=f'{{"t":{temp}}}')
lightsleep(60000) # 上报完进轻睡眠,降低功耗
说白了选的时候根本不用追什么“行业主流”,如果就是个室内放着、几分钟甚至几小时报一次数据的监测点,直接用HTTP就够,折腾MQTT纯纯给自己加运维工作量;如果要做秒级数据上报、还需要远程控制继电器、蜂鸣器这类执行器,那就老老实实搭MQTT服务,把重连逻辑写稳比啥都强;要是做野外靠电池供电、几年才维护一次的监测节点,带宽有限功耗卡得严,再去琢磨CoAP的适配也不迟。
对了,不管用哪种方案,上报的payload里记得带设备时间戳,别靠服务端收包时间记数据,不然网络延迟大的时候数据时序全乱。
评论一下?