跨网络使用BAC0读取Bacnet设备失败问题求助
背景信息
远端局域网内有一台Eclypse ECY-TU203-96B019设备(IP:192.168.1.215),计划通过端口转发路由器(IP:10.x.y.z)访问该设备,并借助它读取局域网内其他设备。已用nmap验证端口转发正常,扫描命令及结果如下:
sudo nmap --script bacnet-info --script-args full=yes -sU -n -sV -p 47808 10.x.y.z Starting Nmap 7.95 ( https://nmap.org ) at 2024-08-09 09:34 CEST Nmap scan report for 10.x.y.z Host is up (0.25s latency). PORT STATE SERVICE VERSION 47808/udp open bacnet | bacnet-info: | Vendor ID: Distech Controls Inc. (364) | Vendor Name: Distech Controls, Inc. | Object-identifier: 1215 | Firmware: 1.14.17191.1 | Application Software: 1.13.19189.607 | Object Name: ECY-TU203-96B019 | Model Name: ECY-TU203 Rev 1.0A | Description: |_ Location:
运行的BAC0脚本
import BAC0 print(BAC0.version) bbmdIP = '10.x.y.z:47808' bbmdTTL = 900 bacnet = BAC0.lite(bbmdAddress=bbmdIP, bbmdTTL=bbmdTTL) #Connect print(bacnet.vendorName.strValue) print(bacnet.modelName.strValue) whois_results = bacnet.whois() print("WhoIs results:", whois_results) print(bacnet.devices) bacnet.discover(networks='known')
脚本运行结果
23.07.03 2024-08-09 10:36:14,549 - INFO | Starting BAC0 version 23.07.03 (Lite) 2024-08-09 10:36:14,549 - INFO | Use BAC0.log_level to adjust verbosity of the app. 2024-08-09 10:36:14,549 - INFO | Ex. BAC0.log_level('silence') or BAC0.log_level('error') 2024-08-09 10:36:14,549 - INFO | Starting TaskManager 2024-08-09 10:36:14,551 - INFO | Using ip : 192.168.1.33 on port 47808 | broadcast : 192.168.1.255 2024-08-09 10:36:14,560 - INFO | Starting app... 2024-08-09 10:36:14,561 - INFO | BAC0 started 2024-08-09 10:36:14,561 - INFO | Registered as Foreign Device 2024-08-09 10:36:14,561 - INFO | Device instance (id) : 3056745 2024-08-09 10:36:14,562 - INFO | Update Local COV Task started (required to support COV) b'SERVISYS inc.' b'BAC0 Scripting Tool' WhoIs results: [] [] 2024-08-09 10:36:18,670 - INFO | Found those networks : set() 2024-08-09 10:36:18,670 - INFO | No BACnet network found, attempting a simple whois using provided device instances limits (0 - 4194303)
本地机器IP为192.168.1.33,目前无法发现远端设备,需排查解决。
问题核心
从结果看,bacnet.vendorName和bacnet.modelName返回的是本地BAC0工具自身信息,而非远端Eclypse设备的,说明BAC0实例未正确关联远端设备,只是在本地创建了虚拟设备;同时WhoIs返回空,表明无法接收远端设备的响应。
具体修正步骤
启用远端Eclypse的BBMD功能
BACnet跨网段通信依赖BBMD(BACnet Broadcast Management Device)转发广播包。当前仅将BAC0注册为Foreign Device到路由器端口,但远端Eclypse未启用BBMD,无法处理跨网段的BACnet广播。需登录Eclypse的Web管理界面,开启BBMD功能,添加本地IP(192.168.1.33)为允许的Foreign Device,或配置自动接收外部Foreign Device注册。直接指定远端设备实例通信
已知远端Eclypse的设备实例ID为1215(来自nmap结果的Object-identifier:1215),可跳过WhoIs广播,直接建立连接:import BAC0 print(BAC0.version) # 路由器转发地址和端口 remote_router = '10.x.y.z' remote_port = 47808 # 远端Eclypse设备实例ID device_instance = 1215 # 初始化BAC0,指定本地端口避免冲突(可选,若本地47808被占用) bacnet = BAC0.lite(port=47809) # 直接连接远端设备 eclypse = bacnet.add_device(device_instance, remote_router, port=remote_port) # 验证设备连接 print("Vendor Name:", eclypse.vendorName) print("Model Name:", eclypse.modelName) # 若Eclypse已配置为BBMD,可指定远端网络号发现其他设备 # bacnet.discover(networks=[远端局域网的BACnet网络号])调整路由器UDP转发超时
UDP为无连接协议,路由器端口转发的会话超时需大于BBMD的TTL(你设置的900秒),避免会话提前断开导致通信中断。避免本地端口冲突
日志显示本地机器使用了47808端口,与远端设备端口一致,可能存在本地广播干扰。初始化BAC0时可指定不同的本地端口,如BAC0.lite(port=47809)。
内容的提问来源于stack exchange,提问作者FrancMo

