Add new IP to BACRouter

We are often faced with third-party devices in the field whose IP cannot be modified and whose IP is not in the same subnet as the BACRouter or other BIP devices.
The solution already in place is to add an IP router, which will result in increased cost and complexity.
Usually we only need the BACRouter to communicate with this third party device using Modbus TCP or BACnet IP protocol, so the easiest way is to add an IP to the BACRouter dedicated to communicate with this device

For example, local IP subnet is 192.168.100.0/24,  BACRouter’s IP is 192.168.100.1;  Third-party device has a IP of 172.16.1.20, its netmask is 255.255.255.0

We will add IP of 172.16.1.1 to BACRouter
Original /etc/rc.local:

root@OpenWrt:~# cat /etc/rc.local
# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.

cd /root
./webui&
exit 0

Modify /etc/rc.local: (vi is available too)

root@OpenWrt:~# cat>/etc/rc.local
# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.

ifconfig br-lan:1 172.16.1.1 netmask 255.255.255.0
cd /root
./webui&
exit 0
CTRL+D

The ifconfig command will create a br-lan:1 interface with IP 172.16.1.1; if we connect to the third-party device by BIP protocol, we have to add new interface to BACRouter configuration.

Original /root/resource.conf:

~#cat /root/resource.conf
{ “eth0”: { “type”: “ETH”, “ifname”: “br-lan” }, “RS485-1”: { “type”: “USB”, “ifname”: “0:0” }, “RS485-2”: { “type”: “USB”, “ifname”: “0:1” } }

Modify /root/resource.conf: (vi is available too)

~#cat >/root/resource.conf
{ “eth0”: { “type”: “ETH”, “ifname”: “br-lan” }, “eth1”:{“type”:”ETH”, “ifname”:”br-lan:1″}, “RS485-1”: { “type”: “USB”, “ifname”: “0:0” }, “RS485-2”: { “type”: “USB”, “ifname”: “0:1” } }
CTRL+D

now restart BACRouter!

Modbus Devices Config & Lua Scripts & Conversion

Modbus Device Config

Siemens_RDF302.jsonSiemens RD302 Thermostat
Schneider_TC500.jsonSchneider TC500 Thermostat
JCI_T8600.jsonJCI T8600 Thermostat
JCI_T7000.jsonJCI T7000 Series Thermostat
ABB_ACS510.jsonABB ACS510 VFD

Lua Script

bcd.luaEach byte is 0-9, for example: 0x05090702 = 5972
Endian is defined by “big integer”
compat_bcd.luaEach half byte is 0-9, for example: 0x78695231 = 78695231
Endian is defined by “big integer”
m10k.luaEach register is -9999~9999, for example: 0x1f740a69 = 0x1f74*10000 + 0x0a69 = 80522665
Endian is defined by “big integer”
low10th.luaOnly 1 register, low byte is one tenth, the range is 0.0 to 255.9 for example: 0x0503 = 5.3
Endian is defined by “single integer”.
This is found in York TMS2100 FCU thermostat.

Conversion

Convert BASgatewayLX CSV Configuration

BACRouter&VPN

Based on OpenWRT platform, BACRouter could support various VPN, including OpenVPN, wireguard, IPSec, and so on.  To reserve maximum storage space for application program, the VPN support is not enabled by default.

Our OpenWRT code is hosted in https://github.com/hvacrcontrol/openwrt, the branch “bacrouter_new” is code for currently production.

The vpn.config in the repository is the configuration with OpenVPN and wireguard enabled.

Precompiled OpenWRT firmware file is: vpn_bacrouter_19.07_8fe8c902.tar.gz

Refer to upgrade-underlayer-firmware-of-bacrouter for how to upgrade the OpenWRT firmware.

Sometime, we need to enable BIP port on the VPN side, the BACRouter firmware from v4.23 intergrated that functionality. Below is a example of how to config it:

Upgrade Openwrt VPN firmware and BACRouter firmware to v4.23

Configure VPN, here is a example of wireguard:

~#uci show network.vpn
network.vpn.proto=’wireguard’
network.vpn.private_key=’####################################’
network.vpn.addresses=’192.168.231.3/24′

~#uci show network.wg0
network.wg0=wireguard_vpn
network.wg0.public_key=’#####################################’
network.wg0.endpoint_host=’###.###.###.###’
network.wg0.endpoint_port=’####’
network.wg0.route_allowed_ips=’1′
network.wg0.persistent_keepalive=’25’
network.wg0.allowed_ips=’192.168.231.0/24′

More info please refer to https://openwrt.org/docs/guide-user/services/vpn/wireguard/start

~#ifconfig vpn
vpn Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:192.168.231.3 P-t-P:192.168.231.3 Mask:255.255.255.0
UP POINTOPOINT RUNNING NOARP MTU:1420 Metric:1
RX packets:557 errors:0 dropped:0 overruns:0 frame:0
TX packets:3593 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:50348 (49.1 KiB) TX bytes:176736 (172.5 KiB)

Add vpn interface to BACRouter:
Original /root/resource.conf:

~#cat /root/resource.conf
{ “eth0”: { “type”: “ETH”, “ifname”: “br-lan” }, “RS485-1”: { “type”: “USB”, “ifname”: “0:0” }, “RS485-2”: { “type”: “USB”, “ifname”: “0:1” } }

Modify /root/resource.conf: (vi is available too)

~#cat >/root/resource.conf
{ “vpn0”: { “type”: “PPP”, “ifname”: “vpn”}, “eth0”: { “type”: “ETH”, “ifname”: “br-lan” }, “RS485-1”: { “type”: “USB”, “ifname”: “0:0” }, “RS485-2”: { “type”: “USB”, “ifname”: “0:1” } }
CTRL+D

Because wireguard works on layer 3 (tun mode), so the type for vpn0 is defined as “PPP”. For VPN works on tap mode, “ETH” should be used.

Restart WebUI, the “System Settings” should show as:

Create another BIP port on vpn0. Because it’s a PPP interface, only “Foreign Device” and “BBMD” mode is allowed.

ATTN:When the WebUI and router daemon startup, it will read IP from every interface defined. so only static configured interface works here.  For wireguard, no further setting is needed because the ip is statically configured.

For OpenVPN tun mode, please Refer to: assign-static-ip-addresses-for-openvpn-clients  When OpenVPN client startups, it may need time to establish connection and get ip from the server. Below startup script will statically pre-configures ip of tun0 to prevent webui’s failing.

~#cat /etc/rc.local
ip tuntap add dev tun0 mode tun
ip link set tun0 up
ip addr add 192.168.231.3/24 dev tun0
/etc/init.d/openvpn start
cd /root
./webui&
exit 0

However, if OpenVPN tap mode is available, tap with bridge is most simple, no adjustment is needed for application level.

Great blog about VPN&BMS: Scott’s Technical Writeups

Upgrade underlayer firmware of BACRouter

BACRouter’s software is based on OpenWRT. The version of OpenWRT we used has never been upgraded since 2016. Security auditors complain the dropbear server’s vulnerabilities, though those vulnerabilities can not be utilized based on our evaluation.

However, we decided to switch to OpenWRT v19.07.10, which released on Apr 20, 2022. For existing users who want to upgrade, please follow those steps:

1.  Download OpenWRT upgrade file

2.  Upgrade BACRouter from WebUI’s “Upgrade Firmware”.  It will take 2~3 minutes. Be careful, all settings will be lost, including IP

3.  Open “http://192.168.100.1” by Web browser, the page will likes:

4. Select whatever version BACRouter firmware file, then click “upgrade”, the page will show:

5. Refresh page after one minute, the WebUI will come back, then restore settings from backup.

 

Old version firmware’s compatibility

From July, 2021, new BACRouter had a hardware revision for improving EMI, but that cause incompatibility with old firmware.

Some users keep using version 2.18, so we provide version 2.19 firmware which is compatible with old hardware and has same features with version 2.18.

Download Firmware version 2.19

From version 4.09,  the firmware is compatible with old hardware, but user can not downgrade to prior firmware on new hardware.

 

 

 

Convert BASgatewayLX CSV Configuration To BACRouter JSON

BASgatewayLX (Hereinafter referred to as LX) supports CSV configuration file. There are decent documents about the format and dozens of configuration samples for vary devices on their website. The convert tool we provided could convert the CSV file to JSON file which could be imported in BACRounter’s WebUI to create a Modbus slave station.

Convert on our website

Download and extract it to disk, open index.html by your web browser

Matters need attention:

Though LX claims the object name should be unique, but the accessory “Profile Checker” does not check duplicated object name. We found a lots duplicated object names in the samples. So we decided to disable object with duplicated name in converting.

Some CSV files have characters out of UTF8 code page, we guess they are ISO-8859-1 encoding. So if we fail to decode CSV by UTF8, we fall back to ISO-8859-1.

LX supports maximum 64 bytes of object name and description (With ISO-8859-1 encoding?). BACRouter supports 64 bytes too, but with UTF8 encoding. There has possibility that 64 bytes in ISO-8859-1 is larger than 64 bytes when encoding as UTF8. We will tail-cut too long name and description and promote to user.

BACRouter doesn’t allow 2 output objects mapped to overlapped Modbus address, but LX seems to allow it. We will disable the conflicted object in converting.

LX defines register order for every 32 bits data, but BACRouter has to set unitary byte order for all objects. If the consistent byte order definitions are found when converting, the previous definition will be accepted, the conflict will be promoted to user.

BACRouter has object instance range of 0~999 for every slave, but LX seems no limitation. If instance larger than 999 is found, the object will be auto assigned a new instance.

Offline configuration and import/export

From firmware v4.x,Offline configuration had been introduced. Now user could configure a BACRouter without device on hand, then export configuration to a file. When commissioning on the field, user just need to import previously exported file, “Save&Reboot” to take effect the configuration.

From v4.04,The object definitions for Modbus gateway could be import/export as CSV format. User could effectively setup object to Modbus address mapping In batches with Excel/WPS/Libreoffice, then import it to WebUI for detailed modify.

Offline configure on our website  (IE will not work now)

Download and extract it to disk, open index.html by your web browser (Because IE/Edge doesn’t support Local Storage for file:// URL, the user library for binary text and most used engineering unit will not be kept after leaving the web page)

There are 3 types of configuration file:

BACRouter Configuration File

This type of configuration file keeps all settings in BACRouter. If the firmware version of exporting one is same to importing one, WebUI should not complain of the configuration file.

Modbus Master Configuration File

This type of configuration file keeps setting under the scope of Modbus master.  When importing it, collision detecting logic based on current mapping mode will check every enabled slave in this master, if collision is found, the slave will be disabled.

If the master is RTU/ASCII type, it may also be disabled if there are contention for RS485 port.

With these problem, WebUI will prompt user to re-check configuration.

Modbus Slave Configuration File

This type of configuration file keeps setting under the scope of Modbus slave.  When importing it, if collision detecting logic based on current mapping mode found problem, the slave will be disabled.

It is allowed to import TCP salve configuration file in RTU/ASCII master, and vice versa, but the slave may be disabled if Modbus parameter setting do not work.

With these problem, WebUI will prompt user to re-check configuration.

Interoperability between extended MS/TP frame capable devices and legacy devices

Original BACnet MS/TP data link specification only supports NPDU length up to 501 bytes, which is much shorter than 1497 bytes of Ethernet and IP data link. It limits transmission performance, increases complexity on application layer, especial when two IP/Ethernet networks are conjoined by a MS/TP network.

Extended frame was designed to solve this problem. The detail could be found here. Briefly, this addendum added two new frame types as:

  • 32: BACnet Extended Data Expecting Reply
  • 33: BACnet Extended Data Not Expecting Reply

Frame type 32 is extended from frame type 5 (BACnet Data Expecting Reply),  the special of it is that it is encoded by COBS and the NPDU length it carried is in range of 502 to 1497 bytes.

In the same way, frame type 33 is extended from frame type 6 (BACnet Data Not Expecting Reply)

Extended frame support was added into BACnet standard since revision 16. There are still lot of devices installed or on the market that do not support it. The interoperability between extended frame capable devices and legacy device is discussed below.

  • Non-router legacy device and extended frame capable device: Because all messages sent to legacy device are application layer message, the “Max APDU Length Accepted” from Device object property or confirmed service request primitive should be respected, the NPDU length will not exceed 501 bytes. So there are no problem with this configuration.
  • Legacy router and extended frame capable device: NPDU that should be relayed to other network through legacy router with length over 501 bytes will be discarded, no reject-message-to network with reason “Message Too Long” will be responded. Even more, the “Max APDU Length Accepted” of legacy router may be determined by other port that has a NPDU length larger than 501 bytes (It is allowed by standard), so NPDU for local application layer sent to legacy router will still possibly be carried by extended frame and discarded. So this configuration may cause problem in field.

BACRouter supports extended frame from very early version. From firmware version 3.18, we introduced “Extended frame” option on BACRouter’s MS/TP configuration, if there are legacy router that does not support extended frame on the bus, this option should be disabled to avoid Interoperability issues.

It’s worth noting that even “Extended frame” option is disabled, unlike legacy router, BACRouter will still be interoperable with extended frame capable devices.

(Screenshot has been updated on Aug 5, 2021. Because extended frame is mandatory from standard revision 16, from firmware 4.13, we move this option to extended configure mode.)

 

 

MSTP message delay guarantee

There are 2 types of BACnet service: unconfirmed and confirmed. The sender(client) of confirmed service request will wait for reply until timeout expires.

Usually there are no side effect of excess message delay for unconfirmed service. For confirmed service request or reply,  excess message delay will result in poor network performance, because the service reply will be dropped by client due to timeout.

Furthermore, too late reply for confirmed service will cause application logic wrong. Each confirmed service request has a invokeID, the reply message carries same invokeID. The value range of invokeID is 0~255. On a busy client, the invokeID will be exhausted and re-used soon. if the invokeID of a delayed confirmed service reply is re-used by another service, the reply will be regarded as replying to later one. For exmaple:

  • Client send WriteProperty service A to device X object Y property Z. The invokeID is 0.  The request or reply messages is delayed.
  • Client waits until timeout expires. Service A fails so invokeID 0 is reclaimed.
  • Client send WriteProperty service B to device X object U property V. The invokeID 0 is chosed.
  • Reply for service A is arrived, because its invokeID is same as service B, client believes that service B success.

For high speed data link type as Ethernet or IP, the message delay is neglect-able, but for MSTP, there are several possible reasons for excess message delay:

  1. Signal noise.
  2. Incorrect/improper device configuration(baudrate, max-master, max_info_frames)
  3. Excess traffic.
  4. Slow device

To avoid invokeID conflict and improve network performance, BACRouter with firmware version >=2.0 implements message delay guarantee of 10 seconds (It is changed to 6 seconds from v4.17 respecting BACnet default APDU_Timeout). Messages which could not be sent within the delay will be dropped by BACRouter.

Fixed/Auto/Forced baudrate for MSTP

Update on 2020-11-20 (Appended info. about JCI module)

MSTP baudrate is always painful for field technician. If the baudrate is wrong, device can’t join a MSTP bus.

Most devices have fixed baudrate. To modify the baudrate setting, technician have to physically access the device and change dip switches. Some devices support changing baudrate by BACnet service. but before that they should already have correctly baudrate setting for BACnet service to access it.

Some vendors implement auto baudrate, but introduce more problem than it solves. There are two types of auto baudrate mechanism:

  • Starting detection: The device detects and adopts baudrate on the bus when it starts. then never changes baudrate.
  • Dynamic detection: The device does same as starting detection type when it starts, but if it find there are error on bus for a predefined time, it considers that the baudrate is changed, it detects baudrate again.

For both types, it is difficult to change baudrate when devices is working. Simply changing baudrate on all fixed baudrate devices can not work, because auto baudrate devices are still working on old baudrate. The solution is to power off all auto baudrate devices, then power on all auto baudrate devices(Don’t power off/on auto baudrate devices one by one)

Our new firmware(>=2.0) introduces new baudrate management mechanism(Patent pending). There are 3 types of baudrate mode for BACRouter : Fixed/Auto/Force:

  • Fixed baudrate mode works as most traditional devices.
  • Auto baudrate mode is same as above-mentioned dynamic detection. The predefined time to re-initiate detection is 10 error frames, it usually take several seconds.
  • Forced baudrate mode is same as auto mode except that when the device get token, it changes baudrate to predefined value.

When there is a device with forced baudrate mode, the baudrate on the bus will be forced to predefined value. Devices with auto baudrate mode will automatically synchronize to predefined baudrate. Devices with fixed baudrate mode but baudrate setting different with predefined value will not be seen on bus (It’s easy to check out in “Recent active devices” field from BACRouter’s runtime info). Devices with starting detection type may run on wrong baudrate, they will not be seen on bus too, but powering off/on them one by one will synchronize them to forced value.

More than one device with forced baudrate mode could coexist on a bus, but the baudrate values on them should be same.

JCI FEC/IOM modules implements baudrate dynamic detection mechanism, the re-detect interval is about 150 sec on the test.

On a test bus , BACRouter cooperate perfectly with FEC2611, IOM3731,  the baudrate is dynamically controlled by BACRouter from 9.6k ~ 76.8k, FEC2611 and IOM3731 will catch up after 2.5 minutes.