BACnet 一次读多属性只错一个,怎样保留成功值和属性错误
ReadPropertyMultiple的一个对象结果中,可以同时存在成功属性值和某个属性的访问错误。解析时应按嵌套上下文区分property-value与property-access-error,保留每一项,不能一个错误就把整组成功值抹成无数据。
适用版本与输入范围
依据维护者 bacnet-stack 固定标签 bacnet-stack-1.4.0 的下列源码解释公开实现子集。该参考不是 ASHRAE 标准全文;涉及具体楼控设备时仍需记录型号、固件和对象支持范围。 本文所有输入均为原创合成数据,未接真实设备。
从对象结果进入属性列表
附件已经剥离完整APDU头,输入只包含一个ReadAccessResult:上下文0给AnalogInput12,opening标签1开始结果列表。列表内每项上下文2给属性号,随后进入上下文4的值分支或上下文5的错误分支。合成例包含PresentValue属性85的REAL25、Units属性117的枚举62,以及ObjectName属性77的错误类别2与错误码32;不同结果类型特意放在同一对象内观察。
值和错误分支不能共享解释
opening4中的44表示REAL,91表示Enumerated;opening5中则有两个Enumerated分别表示错误类与错误码。若只扫描91和后继字节而不看当前分支,错误码可能被当成普通属性值写入点表。程序记录每个属性的id,成功项包含value_type和value,失败项只包含error_class和error_code,不伪造value=0。这样下游可以保留可用读数,同时准确显示哪个属性读取失败。
开闭标签必须和分支对应
值分支应由closing4结束,错误分支应由closing5结束,整个列表由closing1结束。显式负例将成功值后面的4F改成5F,字节数量没有变化,仍因关闭标签错误被拒绝。游标函数在每次读取前检查剩余长度,防止截短记录被切片容错掩盖。本程序明示只支持单对象、短属性号、REAL和单字节Enumerated值的演示子集,不是完整RPM实现。
局部属性错误不等于服务失败
如果完整服务层返回Error、Reject或Abort,那是另一种APDU结构,应在进入此结果解析器前分流。本例专门处理已收到RPM成功ACK内容中的局部访问错误,所以保留两个成功项是正确行为。错误类和码的具体解释仍需结合设备对象与访问策略;程序仅保留数字,不自动指责权限或网络。附件不发批量读取,也不保证真实设备支持这些属性或响应形状,适合先验证网关如何保存部分成功数据。
下载与复跑
将输入 fixture.json与独立程序 verify.py放在同一目录,用 Python 3.12 执行 python verify.py,无需安装第三方包。程序从自身目录读取输入并写入 report.json,不要求当前终端恰好位于下载目录。也可查看本次实跑报告和复跑说明。
本次实际运行通过 2 条输入断言,包括标有“显式负例”的记录;负例以JSON字段承载,不会把下载文件本身做成损坏编码。properties逐项保留value或error,错误项不生成假的零值;输入不含完整服务APDU头。 修改输入后应同时审查期望结果,不能只改断言数字让测试变绿。
对象或字段的基础关系可回到BACnet 对象与服务入门核对,更多接口入口在设备协议库。若需要把已确认的数据点接入展项编排,可了解SoftControl 展厅中控;具体接入能力以项目确认和实际测试为准。
一级依据
来源核对日期:2026-10-24。离线结果只证明给定输入的解析或计算行为;现场兼容性、响应时间、硬件准确度和具体产品支持均未测量。
相关阅读
留言讨论
评论发布后会被人工复核,违规内容将被删除。
如果发表没有反应,可以前往联系我们告诉我们。