BACnet

连接 BACnet/IP 楼宇自动化设备:设备实例号、按对象类型和实例号寻址、Who-Is 设备发现,以及 presentValue。

以 Markdown 查看

BACnet 驱动通过 BACnet/IP 和楼宇自动化设备对话。每个点位读的是某一个 BACnet 对象的当前值:一个模拟输入的实时读数、一个二进制输出的状态、一个多状态值的位置。在 Connector 里的 BACnet 驱动下面添加一台设备;面板只显示这个协议用得到的那些字段。

连接

字段 含义 默认值
主机 BACnet 设备(或者替它应答的那个路由器)的 IP 地址或主机名。设备连接时,名称会被解析成它的 IPv4 地址;这台计算机解析不了的名称会让设备连不上,原因里会写明这一点。 空
端口 设备的 UDP 端口,1 到 65535。框留空时 47808(也就是 BACnet/IP 的标准端口)以灰色显示,设备就通过这个端口连上;以 0 保存的设备也是这样显示的。 47808
设备 Id 这台设备的实例号,也就是它 Device 对象的编号,在整个 BACnet 网络上唯一。 0

设备标题栏显示拼好的 endpoint,例如 bacnet://192.168.0.30:47808/1234。连接时会发一个请求去问这台设备对象列表的大小,用来确认仪器确实在应答;对象列表本身并不会被走一遍。那个回答就是连接:不回话的设备保持离线,而不是显示成已连接,原因(UDP 端口已被别人占着、一个不是地址的地址)会写进事件页面和当天的日志文件。这个驱动没有轮询间隔字段:它的点位每秒读一次。

寻址

BACnet 的点位靠点位“信号源”卡片里的两个定型字段寻址,没有自由文本地址:

字段 含义 接受的取值 默认值
对象类型 要读哪一种 BACnet 对象。 下面那九种类型 AnalogInput
实例号 这个对象在它那一类里的实例编号。 0 及以上 0

提供的对象类型和它们标准的 BACnet 类型码:

对象类型 类型码 当前值里装着
AnalogInput 0 一个测得的数
AnalogOutput 1 一个下达的数
AnalogValue 2 一个存着的数
BinaryInput 3 inactive/active
BinaryOutput 4 inactive/active
BinaryValue 5 inactive/active
MultiStateInput 13 一个从 1 起的状态号
MultiStateOutput 14 一个从 1 起的状态号
MultiStateValue 19 一个从 1 起的状态号

设备 1234 上的 AnalogInput 5,意思就是“那台设备第 5 号模拟输入的当前值”。每一次读取都去要这个对象的 presentValue 属性;别的属性寻不了址。“信号源”卡片里那行只读的源地址(总线)会随着你编辑显示拼好的 type,instance 这一对。

数据类型

数据类型选择器提供四种类型。挑和那个对象对得上的那一种:

数据类型 适合 说明
Float 模拟类对象 Real 型的当前值;double 会被收窄成 Float
Boolean 二进制类对象 Boolean 型的当前值,或者二进制对象用来应答的枚举值 0 和 1
Int32 多状态类以及别的整数值 有符号、无符号和枚举的回答都落在这里
String 字符串类的值 设备发来什么文本就是什么文本

挑的类型必须和这个对象装着的东西对上。设备答的是别的东西时,那个点位这一次读取就失败:点位转为质量不可用,原因点名到来的是什么(“设备为一个声明为整数的点答了一个 Single 值。”),而不是让一个换算过的数字进到趋势、历史和报警里去。把模拟对象读成布尔,或者把 Real 读成 Int32,正是这种情形。这台设备其余部分照读不误;也不会为一个类型填错的点位重新连接什么。

点位指向的对象设备里没有时,这次读取会带着设备自己的回答失败:原因说明设备在那个地址上没有对象,并点名它发来的错误(ERROR_CODE_UNKNOWN_OBJECT),这样地址填错和设备不再应答就能分得开。设备保持连接。

写入

访问为读写或只写的点位可以被写。一次写入会去设这个对象的 presentValue,用的是 BACnet 标准给这类对象规定的类型,不管点位的数据类型是什么:

对象 写成 接受
二进制输入、输出或值 Enumerated inactive (0) 或 active (1),来自 Boolean 点位,或等于 0 或 1 的 Int32
多状态输入、输出或值 Unsigned 一个从 1 起的状态号
模拟输入、输出或值 Real 来自 Float 或 Int32 点位的一个数
其他任何对象类型 点位的数据类型 Float 写 Real,Boolean 写 Boolean,Int32 写有符号整数,String 写字符串

写入时不带任何命令优先级。对象装不下的值,比如给多状态对象写 0,或给二进制对象写 2,在发出任何东西之前就被拒绝,拒绝会说明原因。设备用一个错误来回答这次写入时,点位报告设备发来的错误类别和错误码,而不是假装成功,设备也保持连接。新点位一开始是只读。

设备发现

Connector 的“发现设备”按钮会广播一个 BACnet Who-Is,并监听 I-Am 回答 10 秒。每一台回答的设备都成为一个候选项,带着它的地址、端口和设备实例号,连接字段都已经填好,可以直接添加;而且它是一答话就出现在列表里,不是等到十秒结束才出现:中途取消的扫描会保留所有已经答过话的东西。扫描不去浏览对象,所以候选项到来时点位数为零;对象类型和实例号那一对,请你自己填。

Who-Is 从 扫描范围 卡片指定的网络发出。它的输入框接受该网络上的一个 IPv4 地址,即某台设备的地址,或这台计算机自己在该网络上的地址(例如 192.168.1.20),扫描随后只在该网络上广播。留空时,Who-Is 从这台计算机的所有网络发出,因此装有两块网卡、VPN 或 Docker 的计算机也能找到每个网络上的设备。不是完整写出的 IPv4 地址会在输入框下方被拒绝,改正之前“发现设备”按钮保持灰色。

通过 BACnet 路由器应答的设备也是同样添加的。它的候选项带着路由器的地址,并在旁边带着这台设备自己所在的网络号和它在那个网络上的地址;你添加它时两者都保留下来,之后每一次读取都发给路由器,并在里面点名那台设备。因此,这样找到的设备读起来和别的没有两样,它的 endpoint 读作“device via router”。手工添加的设备没有路由,直接在它的主机上够到。

需要知道的事

  • 只支持 BACnet/IP:MS/TP 或 BACnet/SC 的仪器只有通过一个把它们呈现在 BACnet/IP 上的路由器才够得着,而找到它们的正是扫描:设备应答时所走的那条路由会从扫描里保留下来,所以请从发现出来的列表里添加它,而不是手工去打那些字段。
  • 在有多个网络接口的计算机上(两块网卡、VPN、Docker),每台设备都通过这台计算机路由其地址所用的接口到达,也就是这里任何其他程序都会用的那个接口;无需选择。
  • 本工作站上只有监听设备消息的那个套接字占用 BACnet 标准 UDP 端口 47808,所以同一台计算机上另一个独占该端口的 BACnet 应用会和它冲突。发给设备的请求从系统为每个客户端挑选的端口发出。
  • 这个驱动上每一个点位的轮询都固定为一秒;平常那些轮询间隔字段不显示。