# BACnet/IP 设备扫描

BACnet/IP 驱动需要预先知道设备地址。当现场设备清单不明确时，可以先用扫描驱动摸清网络：它广播 Who-Is 发现设备，再逐台读取设备的 Object_List，把每个对象的地址、名称、当前值等属性整理成点位清单。清单通过 HTTP 接口读取，也可以直接据此生成一个配置好的 BACnet/IP 采集节点。

扫描只负责「发现」，不负责「采集」。入口是 **数据采集 → BACnet/IP 设备扫描**，数据采集仍由 BACnet/IP 驱动完成。

典型用法是三步：

1. 开启扫描，按网络拓扑选好扫描方式
2. 查看扫描到的设备和设备点位
3. 选中一台设备和需要的点位，点击 `添加驱动和点位` 直接生成配置好的 BACnet/IP 驱动；若驱动已存在，用 `添加点位到组` 把点位加进已有的采集组

## 开启扫描功能

在 **数据采集 → BACnet/IP 设备扫描** 页开启扫描。

## 扫描配置

| 字段                 | 默认值            | 说明                                                                   |
| -------------------- | ----------------- | ---------------------------------------------------------------------- |
| **本地绑定地址**     | `0.0.0.0`         | 绑定的本地网卡地址，`0.0.0.0` 表示绑定所有网卡。多网卡主机建议指定网卡 |
| **本地绑定端口号**   | `47808`           | 收发 BACnet 报文的本地端口，通常必须是 47808，原因见下                 |
| **设备扫描周期**     | `600`             | 定时广播 Who-Is 发现设备的周期，单位秒，取值 30 - 86400                |
| **点位扫描周期**     | `1200`            | 定时枚举已发现设备点位的周期，单位秒，取值 60 - 86400                  |
| **本地子网广播扫描** | 启用              | 以 Original-Broadcast-NPDU 发送 Who-Is                                 |
| **全局广播扫描**     | 禁用              | 以 DNET 0xFFFF 发送 Who-Is，BACnet 路由器会向所有直连网络转发          |
| **广播地址**         | `255.255.255.255` | 两种广播模式的目标地址，建议改为子网定向广播地址，如 `192.168.1.255`   |
| **经 BBMD 扫描**     | 禁用              | 向 BBMD 注册为外部设备，以 Distribute-Broadcast-To-Network 发送 Who-Is |
| **BBMD IP 地址**     | 空                | 仅在启用"经 BBMD 扫描"时需要填写                                       |
| **BBMD 端口号**      | `47808`           | 仅在启用"经 BBMD 扫描"时需要填写                                       |

## 三种扫描方式怎么选

三种方式对应三种不同的网络位置，可以同时启用，发现结果会自动去重。

| 设备位置                                        | 需要启用的方式   | 说明                                                  |
| ----------------------------------------------- | ---------------- | ----------------------------------------------------- |
| 与 EMQX Neuron 在同一个 IP 子网                      | 本地子网广播扫描 | 最常见的情况，广播报文直接送达                        |
| 同一个 BACnet/IP 网络，但在别的 IP 子网         | 经 BBMD 扫描     | IP 广播不跨子网，需要子网里的 BBMD 代为转发           |
| 在 BACnet 路由器后面的 MS/TP 等其他 BACnet 网络 | 全局广播扫描     | 路由器收到 DNET 0xFFFF 的 Who-Is 后向它的所有网络转发 |

判断不了的话把三种都启用，扫一次看结果。跨 BACnet 网络发现到的设备，结果中 `routed` 为 `true` 并带有 `dnet` 和 `dadr`，可直接填入上文的目标设备网络和目标设备 MAC。

## 扫描到的属性

每个对象除地址和名称外，还会读取以下属性。它们大多是 BACnet 的可选属性，设备不支持时对应字段为空。

| 属性             | 适用对象类型 | 用途                                           |
| ---------------- | ------------ | ---------------------------------------------- |
| Object_Name      | 全部         | 点位名称                                       |
| Present_Value    | 全部         | 扫描时刻的值快照                               |
| Status_Flags     | 全部         | 报警、故障、被强制、脱离服务四个标志           |
| Description      | 全部         | 描述，设备的可读标签常放在这里而非 Object_Name |
| Units            | 模拟量类     | 工程单位，如 `degrees-celsius`                 |
| Number_Of_States | 多状态类     | 状态总数                                       |
| State_Text       | 多状态类     | 每个状态的名称，最多记录 16 个                 |
| Inactive_Text    | 二进制类     | 值为 0 时的含义，如"停止"                      |
| Active_Text      | 二进制类     | 值为 1 时的含义，如"运行"                      |
