使用Python读取CSV在网关发布遥测数据,ThingsBoard未接收数据求助
排查ThingsBoard未接收到遥测数据的问题
看起来你在通过Python网关向ThingsBoard发送CSV里的遥测数据时遇到了接收空的问题,咱们从代码和配置两个维度一步步排查:
一、先看代码里的几个明显问题
1. CSV读取逻辑完全不对
你直接把整个CSV文件读成字符串然后用;分割,这会把所有内容(包括换行符、表头)拆成一个混乱的列表,完全不是CSV的正确处理方式。更要命的是,你把这个字符串列表直接和bytes类型的data_from_device相加——这一步肯定会触发类型错误,只是可能你没注意到日志里的报错。
2. 冗余代码干扰逻辑
你定义了received_character = bytes('41\r2430947530\n','utf-8')但完全没用到,这部分测试代码可以删掉,避免混淆。
3. 数据格式不匹配转换器要求
converter.convert()需要的是设备原始数据(一般是bytes或结构化字符串),但你传的是字符串列表,转换器根本没法解析成ThingsBoard需要的遥测格式。
二、分步修复与验证
步骤1:正确读取CSV文件
改用Python内置的csv模块处理,假设你的CSV是分号分隔的,示例代码:
import csv def get_template(self): telemetry_rows = [] try: with open("/home/mohsen/bitbucket/iotgatewayv2/test.csv", "r", encoding="utf-8") as f: # 指定分号为分隔符,匹配你的CSV格式 reader = csv.reader(f, delimiter=";") # 如果有表头的话,跳过第一行 next(reader, None) for row in reader: telemetry_rows.append(row) return telemetry_rows except Exception as e: log.error(f"读CSV文件出错: {str(e)}") return []
步骤2:修复数据类型问题
把CSV读取到的每行数据转换成转换器需要的格式(比如bytes):
template = self.get_template() # 遍历每行数据处理 for row in template: # 把行数据转回分号分隔的字符串,再转成bytes data_from_device = ";".join(row).encode('utf-8') # 再调用转换器 converted_data = self.__devices[device]['converter'].convert( self.__devices[device]['device_config'], data_from_device )
步骤3:验证转换器输出格式
转换器必须返回ThingsBoard能识别的遥测结构,比如:
# 正确的遥测格式示例 { "deviceName": "你的设备名称", "telemetry": { "temperature": 26.2, "humidity": 58 } }
你可以在调用send_to_storage之前打印converted_data,看看格式对不对。
步骤4:验证网关发送逻辑
- 检查网关配置里的ThingsBoard服务器地址、访问令牌是否正确
- 查看网关的日志,有没有发送失败的提示(比如网络不通、认证失败)
- 可以直接用ThingsBoard的REST API发一条测试数据,确认平台端能正常接收
步骤5:完善日志排查
在代码里加更多打印,方便定位问题:
try: converted_data = converter.convert(device_config, data_from_device) print(f"转换后的数据: {converted_data}") self.__gateway.send_to_storage(self.get_name(), converted_data) print("数据已提交给网关") except Exception as e: print(f"处理设备[{device}]数据时出错: {str(e)}") log.exception(e)
三、修正后的核心代码参考
import csv import time import logging log = logging.getLogger(__name__) # ... 你的类其他代码 ... def get_template(self): telemetry_rows = [] try: with open("/home/mohsen/bitbucket/iotgatewayv2/test.csv", "r", encoding="utf-8") as f: reader = csv.reader(f, delimiter=";") next(reader, None) # 跳过表头(如果不需要可以删掉) for row in reader: telemetry_rows.append(row) return telemetry_rows except Exception as e: log.error(f"读取CSV失败: {str(e)}") return [] def run(self): try: while True: for device in self.__devices: template = self.get_template() if not template: log.warning("CSV无数据或读取失败,1秒后重试") time.sleep(1) continue device_config = self.__devices[device]['device_config'] converter = self.__devices[device]['converter'] for row in template: data_from_device = ";".join(row).encode('utf-8') try: converted_data = converter.convert(device_config, data_from_device) log.info(f"转换后的遥测: {converted_data}") self.__gateway.send_to_storage(self.get_name(), converted_data) time.sleep(0.1) except Exception as e: log.exception(f"处理设备[{device}]数据出错") time.sleep(5) # 控制循环频率,按需调整 except Exception as e: log.exception("网关运行异常") self.close() raise e
四、额外要检查的点
- 确认ThingsBoard里的设备名称/令牌和网关配置的完全一致
- 检查网关服务器是否能ping通ThingsBoard地址,有没有防火墙拦截
- 查看ThingsBoard的事件日志(平台左侧菜单的Events),有没有接收失败的记录
- 如果遥测数据带了时间戳,确认时间戳是合法的(不要是过去太久的时间,不然默认视图可能不显示)
内容的提问来源于stack exchange,提问作者mohsen difallah
相关产品推荐
相关产品推荐

