基于树莓派使用Bacpypes将JSON字符串转为Bacnet Analog Value Object问题求助
BACpypes JSON数据传输问题解决思路
需求1:拆分JSON为独立Bacnet Analog Value对象发送
- 第一步:先做JSON扁平化处理,把嵌套结构的键展开为一级键,方便后续和Bacnet对象做一一映射,示例代码如下:
def flatten_json(nested_json, parent_key='', sep='_'): items = [] for k, v in nested_json.items(): new_key = f"{parent_key}{sep}{k}" if parent_key else k if isinstance(v, dict): items.extend(flatten_json(v, new_key, sep=sep).items()) else: items.append((new_key, v)) return dict(items) # 测试示例JSON raw_json = {'sn':1, 'sampletime':123, 'device_1':{'p1':100,'p2':200}, 'device_2':{'p1':100,'p2':200}, 'temp': 50, 'hum': 23} flat_data = flatten_json(raw_json) # 输出结果:{'sn':1, 'sampletime':123, 'device_1_p1':100, 'device_1_p2':200, 'device_2_p1':100, 'device_2_p2':200, 'temp':50, 'hum':23}
- 第二步:提前配置固定的对象映射表,给每个扁平化后的键分配唯一的Bacnet Analog Value实例ID,避免动态分配ID导致上层Bacnet系统识别异常。
- 第三步:遍历扁平化后的键值对,逐个匹配映射表更新对应对象的
presentValue,不要复用同一个值批量更新所有对象,示例代码如下:
# 预定义映射表:key为扁平化后的JSON键,value为对应Bacnet Analog Value对象实例 obj_map = { "sn": analog_value_obj_1, "sampletime": analog_value_obj_2, "device_1_p1": analog_value_obj_3, # 其余参数依次配置即可 } for data_key, value in flat_data.items(): if data_key in obj_map: # 注意转换数据类型和Bacnet对象要求匹配 obj_map[data_key].presentValue = float(value)
需求2:完整JSON作为单个对象传输
该方案实现更简单,无需拆分JSON,不需要使用Analog Value对象,改用CharacterString Value类型对象即可:
- 第一步:在你的Bacpypes设备对象中新增1个CharacterString Value类型的对象,分配固定的实例ID。
- 第二步:每次收到JSON后直接序列化为字符串,赋值给该对象的
presentValue即可,示例代码如下:
import json # 假设已创建CharacterString Value实例:json_trans_obj raw_json = {'sn':1, 'sampletime':123, 'device_1':{'p1':100,'p2':200}, 'device_2':{'p1':100,'p2':200}, 'temp': 50, 'hum': 23} json_str = json.dumps(raw_json) json_trans_obj.presentValue = json_str
注意:选择该方案时,上层Bacnet系统需要支持读取CharacterString类型的对象值,自行解析字符串获取对应数据点即可。
内容的提问来源于stack exchange,提问作者Derek Allabaugh
相关产品推荐
相关产品推荐

