You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用AdafruitIO时单台蓝牙设备MQTT数据无法发布的问题排查

树莓派Python脚本无法向AdafruitIO发布特定蓝牙设备数据

背景

修改了同事的树莓派Python代码,新增向AdafruitIO实时发布蓝牙传感器数据的功能。原代码仅每日采集数据发邮箱,现在逻辑是连接指定蓝牙设备,采集7个传感器数据,写入本地后推送到MQTT broker,推送主题为user_name/groups/macaddress/json,JSON格式示例如下:

client.publish("user_name/groups/macaddress/json", j)
# 用于创建或发布到broker上名为设备MAC地址的分组
# macaddress是设备的MAC地址
# j为如下格式的JSON
# {
#     "feeds": {
#         "ETH": 1,
#         "Hum": 54,
#         "temp-1": 18,
#         "temp-2": 85
#     }
# }

问题

无论扫描顺序如何,总有一台特定MAC地址的设备数据无法发布。新增其他设备数据能正常推送,移除故障设备后其余设备也正常。MQTT相关代码如下:

def uploadMQTT(macs, mqttList):
    # Imports
    import paho.mqtt.client as mqtt
    import ssl
    import random
    import sys
    import time
    import json

    mac = macs
    feedValues = mqttList
    username = "user_name"
    key = "password"
    feeds = ["temp-2-vs", "temp-2-vm", "temp-1-vs", "temp-1-vm", "hum-vs", "hum-vm", "eth-vm"]
    broker = "io.adafruit.com"
    port = 8883

    # 创建feed名称字典
    feedDict = dict((feed,0) for feed in feeds)

    # 创建客户端对象
    client = mqtt.Client()
    # 设置用户名密码
    client.username_pw_set(username, key)
    # 加密连接
    client.tls_set(certfile=None,
        keyfile=None,
        cert_reqs=ssl.CERT_REQUIRED)

    # 连接成功回调
    def connected(client, userdata, message, tmp=None):
        print("connected")

    # 断开连接回调
    def disconnected(client, userdata, message, tmp=None):
        print("disconnected")

    # 接收消息回调
    def message(client, userdata, message, tmp=None):
        print("Received message " + str(message.payload)
            + " on topic '" + message.topic
            + "' with QoS " + str(message.qos))

    # 设置回调函数
    client.on_connect = connected
    client.on_disconnect = disconnected
    client.on_message = message

    # 连接broker
    client.connect(broker,port)

    client.loop_start()

    # 遍历feedValues的计数器
    count = 0
    # 构造发布主题前缀
    currfeed = (username + "/groups/" + mac)
    for y in feeds:
        # 将feedValues赋值给feedDict
        value = str(feedValues[count])
        # 给feed值加上MAC地址(AdafruitIO下载文件名不会包含分组名)
        feedDict[y] = value + "," + macs
        count += 1
    # 构造JSON结构
    jsonDict = {'feeds':feedDict}
    j = json.dumps(jsonDict, indent = 4)
    # 发布消息
    client.publish(currfeed + "/json",j)

已确认故障设备的feedValues、MAC地址、JSON格式均与正常设备一致,且使用AdafruitIO高级版,不会触发数据点限制(单设备采集发布耗时约45秒)。

已尝试操作

添加大量打印语句,验证推送的JSON数据、目标分组主题均无错误,未发现值或MAC地址存在异常字符。正常设备与故障设备的JSON数据对比:

{
    "feeds": {
        "temp-1-vm": "22792,CB:B1:03:56:69:C1",
        "temp-2-vs": "40950,CB:B1:03:56:69:C1",
        "hum-vm": "4470,CB:B1:03:56:69:C1",
        "eth-vm": "409486,CB:B1:03:56:69:C1",
        "hum-vs": "40950,CB:B1:03:56:69:C1",
        "temp-2-vm": "831,CB:B1:03:56:69:C1",
        "temp-1-vs": "40950,CB:B1:03:56:69:C1"
    }
}
{
    "feeds": {
        "temp-1-vm": "16667,EB:10:08:5E:22:91",
        "temp-2-vs": "38336,EB:10:08:5E:22:91",
        "hum-vm": "17069,EB:10:08:5E:22:91",
        "eth-vm": "385375,EB:10:08:5E:22:91",
        "hum-vs": "38803,EB:10:08:5E:22:91",
        "temp-2-vm": "32165,EB:10:08:5E:22:91",
        "temp-1-vs": "37314,EB:10:08:5E:22:91"
    }
}

排查方向及解决建议

  1. 修复回调函数参数错误:你目前的回调函数参数不符合paho-mqtt的规范,会导致回调无法正常执行,无法确认连接状态。修正后的回调应该是:

    def connected(client, userdata, flags, rc):
        print(f"Connected with result code {rc}")  # rc=0表示连接成功
    
    def disconnected(client, userdata, rc):
        print(f"Disconnected with result code {rc}")
    
    def message(client, userdata, msg):
        print(f"Received message {str(msg.payload)} on topic '{msg.topic}' with QoS {msg.qos}")
    

    这样能直观看到连接是否成功,避免因连接失败导致消息发布失败。

  2. 等待消息发送完成:client.publish是异步操作,函数执行完毕后客户端可能被销毁,导致消息还没发送就中断。在client.publish后添加等待时间,或者确保消息发送完成再停止loop:

    client.publish(currfeed + "/json", j, qos=1)  # 用QoS=1确保消息送达
    time.sleep(2)  # 等待消息发送完成
    client.loop_stop()
    client.disconnect()
    
  3. 检查AdafruitIO后台状态:登录AdafruitIO后台,确认故障设备MAC对应的分组是否存在,所有Feed是否都已创建,有没有被禁用或权限异常。可以尝试删除该分组重新创建,再推送数据测试。

  4. 测试MAC地址主题兼容性:虽然AdafruitIO支持带冒号的主题,但可以临时把MAC地址的冒号换成下划线(比如EB_10_08_5E_22_91),创建新分组并修改代码中的主题,测试是否能正常发布,排除字符兼容性问题。

  5. 启用MQTT日志:在代码中添加日志输出,查看paho-mqtt的内部状态,比如:

    import logging
    logging.basicConfig(level=logging.INFO)
    

    这样能看到更多连接和发布过程中的细节,定位问题。

内容的提问来源于stack exchange,提问作者Matthew Jennison

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 13:03:32