无法连接同局域网Thingsboard服务器,Python上报数据失败求助
问题描述
尝试向同一局域网内另一台电脑上的Thingsboard服务器发送数据,服务器可通过地址xxx.xxx.x.xx1:pppp访问,已创建设备并获取device_access_token。
编写的Python代码
# -*- coding: utf-8 -*- import nidaqmx from datetime import datetime import time from tb_device_mqtt import TBDeviceMqttClient, TBPublishInfo t_0=time.time_ns() client = TBDeviceMqttClient("xxx.xxx.x.xx1", ppp, "device_access_token") now = datetime.now() dt_name = now.strftime("%Y%m%d%H%M%S") filename = dt_name + ".txt" def envia(valor_0, valor_1): telemetry = {"T0": float(valor_0) } if not client.is_connected() : client.connect() #line 19 client.send_telemetry(telemetry) result = client.send_telemetry(telemetry) success = result.get() == TBPublishInfo.TB_ERR_SUCCESS telemetry = {"T1": float(valor_1) } if not client.is_connected() : client.connect() #line 26 client.send_telemetry(telemetry) result = client.send_telemetry(telemetry) success = result.get() == TBPublishInfo.TB_ERR_SUCCESS #linha 29 p, t = [1,2] with nidaqmx.Task() as task: print("running") task.ai_channels.add_ai_voltage_chan("6008/ai0:1") task.timing.cfg_samp_clk_timing(1000) t_0=time.perf_counter_ns() while (1): f = open(filename, "a") for i in range (1000): p, t = task.read() t_a = time.perf_counter_ns()-t_0 p = 2000*p/-9.418 t = 20*t f.write(str(t_a)+','+str(t)+','+str(p)+'\n') envia(p, t) #line 45 f.close() print("dados salvos")
运行报错信息
C:\Users\ange_\AppData\Local\Programs\Python\Python39\lib\site-packages\paho\mqtt\client.py:1779: ResourceWarning: unclosed <socket.socket fd=1796, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('xxx.xxx.x.xx2', 49172), raddr=('xxx.xxx.x.xx1', pppp) `self.reconnect()` ResourceWarning: Enable tracemalloc to get the object allocation traceback C:\Users\ange_\AppData\Local\Programs\Python\Python39\lib\site-packages\paho\mqtt\client.py:1083: ResourceWarning: unclosed <socket.socket fd=2264, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('xxx.xxx.x.xx2', 49276), raddr=('xxx.xxx.x.xx1', pppp)> `self._sock = sock` ResourceWarning: Enable tracemalloc to get the object allocation traceback Traceback (most recent call last): File "e:\Documents\Facul\Rota 2030\Codigos\Codigos_2023\Thingsboard_NI\teste.py", line 45, in <module> envia(p, t) #line 45 File "e:\Documents\Facul\Rota 2030\Codigos\Codigos_2023\Thingsboard_NI\teste.py", line 29, in envia success = result.get() == TBPublishInfo.TB_ERR_SUCCESS #linha 29 File "C:\Users\ange_\AppData\Local\Programs\Python\Python39\lib\site-packages\tb_device_mqtt.py", line 143, in get self.message_info.wait_for_publish(timeout=1) File "C:\Users\ange_\AppData\Local\Programs\Python\Python39\lib\site-packages\paho\mqtt\client.py", line 362, in wait_for_publish raise RuntimeError ('Message publish failed: %s' % (error_string(self.rc))) RuntimeError: `Message publish failed: The client is not currently connected.`
参考官方示例编写代码,多数示例使用127.0.0.1作为IP,尝试过但仅适用于服务器本地场景。
解决方案
1. 修复核心逻辑问题
你的代码存在重复发送、连接管理混乱的问题,以下是优化后的代码:
# -*- coding: utf-8 -*- import nidaqmx from datetime import datetime import time from tb_device_mqtt import TBDeviceMqttClient, TBPublishInfo t_0=time.time_ns() # 初始化客户端并提前建立连接 client = TBDeviceMqttClient("xxx.xxx.x.xx1", ppp, "device_access_token") try: client.connect() print("成功连接到Thingsboard服务器") except Exception as e: print(f"连接失败: {e}") exit(1) now = datetime.now() dt_name = now.strftime("%Y%m%d%H%M%S") filename = dt_name + ".txt" def envia(valor_0, valor_1): # 检查连接状态,断开则尝试重连 if not client.is_connected(): try: client.connect() print("重新连接到服务器成功") except Exception as e: print(f"重连失败: {e}") return # 一次性发送多个遥测数据,减少MQTT交互 telemetry = { "T0": float(valor_0), "T1": float(valor_1) } result = client.send_telemetry(telemetry) try: success = result.get() == TBPublishInfo.TB_ERR_SUCCESS if not success: print("遥测数据发送失败") except Exception as e: print(f"发送数据时出错: {e}") p, t = [1,2] with nidaqmx.Task() as task: print("running") task.ai_channels.add_ai_voltage_chan("6008/ai0:1") task.timing.cfg_samp_clk_timing(1000) t_0=time.perf_counter_ns() while (1): # 用with语句管理文件,自动处理关闭 with open(filename, "a") as f: for i in range (1000): p, t = task.read() t_a = time.perf_counter_ns()-t_0 p = 2000*p/-9.418 t = 20*t f.write(f"{t_a},{t},{p}\n") envia(p, t) print("dados salvos")
2. 额外检查项
- 确认服务器MQTT端口正确性:Thingsboard默认MQTT端口为1883,SSL端口为8883,需与服务器配置一致
- 检查防火墙设置:确保客户端设备能访问服务器的目标端口,无拦截
- 验证
device_access_token:确认token无拼写错误、无多余空格 - 先通过MQTT测试工具验证连接:以设备token作为用户名,连接服务器IP和端口,确认连接正常后再调试代码
内容的提问来源于stack exchange,提问作者Angeline Melchiors
相关产品推荐
相关产品推荐

