CCN Gateway Changelog

Download&Extract the zip file, there are 2 firmware files inside it, one is for BACnet version, another is for Modbus version.

For CCN Gateway with firmware version prior to v3.00, please go to the bottom of page.

3.05  2025.02.26  Download

Fixs bug that may crash the daemon when there is collision on the CCN bus.

Updates BACnet ms/tp driver from BACRouter 6.09

2.26  Download

Most Versatile Modbus Gateway

BACRouter has a powerful Modbus master module, but there are still some scenarios that it can not handle well, for examples:

  1. Point’s value is read from register 3×00001, but has to write to register 4×00001.
  2. Value 1 read from Modbus mapping to BACnet 1.0, but writing BACnet value 1.0 to Modbus has to write 10. (Lua script for Modbus master module can do asymmetrical conversion for customized Analog object)
  3. Analog/Multistate object mapping to several Modbus coils or discrete inputs.
  4. Write only Modbus data address, read from it will report timeout or exception.

Fortunately,  we have free client module which can implement a most versatile Modbus gateway by Lua script.  We host the modbus.lua scripts on github.com

For modbus.lua, all devices under a bus share same baudrate/parity/timeout property. For Modbus master module, each device under a bus has independent timing property.

User should try Modbus master module at first, because of the test feature of Modbus master module, user can rapidly verify the mapping setting.

After all normal points have been setup, there may leave some weird points,  you should test read for those points.

Then the “Read Group” will verify the grouping.

Then you should export the device’s setting.

There is a fcmbconv.py python program on github repository, install python and run it, it will promote you to choose modbus.lua, then the device config file you had exported, then it will create a free client bus config file for the device.

Then import the created config into BACRouter under “Free Client Module”.

At last you have to modify the special settings for those weird points.

Example:

We assume there is a device, has several normal points, and

1. Analog output objects “lamp1” and “lamp2” get on/off status from bit 0 and bit 1 of Register 4×00032,  value 1 on the corresponding bit means on, value 0 means off.  To turn on/off of lamps, register 4×00031 should be written, but the value 1 on the corresponding bit means turning off, value 0 means turning on.

2. 8 bits from 1×00008 map to analog input object “temperature3”.

3. Write-only register 4×00100(Read will report timeout), low byte maps analog output object “load1”, high byte maps to analog output object “load2”.

Setup a Modbus device: ExampleModbusDevice,  verify the grouping by “Read Group”
Using fcmbconv.py to convert it to:  FCModbus

Import it into free client module:

Modify setting for weird points.

For lamp1:

For temperature3:

For load1 and load2:

Finally, verify its behavior by Yabe. If the script fails, please check the log.

The final config file for the free client bus is:  FCModbusFinal

BACRouter Changlog v6.00+

BACRouter switched to ARM soc from v6.00.  Now the firmware file format is xxxx_xxxx_6.00_arm_xxxx.tar.gz

For firmware version prior to v6.00, please visit: old firmware

6.09  2025.02.26  Download

MSTP bug to manipulate hardware will cause certain NPDU body discarded.

6.08  2025.01.23  Download

WebUI bug on Modbus Master Module:

When “Write Test” analog object mapping to single register, the byte order should respect to “Byte order for single register”, not “Byte order for big integer”.

When “Write Test” multi-state object mapping to 2 registers, the byte order should respect to “Byte order for big integer”, not “Byte order for single register”

The real value of binary object of free client device in “Runtime Info” page should respect to polarity setting.

6.07  2025.01.10  Download

Because BACRouter highly rely on high resolution timer, If there is electromagnetic disturbance, the crystal on the board may be disturbed, so timer will drift, lead to program malfunction.  We add correct function in this version.

6.06  2025.01.07  Download

Bugfix for free client module’s binary output object. It was introduced by v6.01 Polarity feature.

Modbus master module: when writing to read only data address, some devices respond timeout instead of report a exception, which will cause BACRouter keeps trying and fails with offline. For this version, BACRouter will only try 3 times then gives up.

6.05  2025.01.04

Refactor low level arc156 and ms/tp drivers to simplify code.

ARC156 driver add logic to drop packet send to node responding excess NAK to Free Buffer Enquiry

WebUI: Remind user when IP or netmask has been changed but DHCP server keeps enabled,

6.04  2024.12.26  Download

Fix bug on ms/tp:  Sending packet to ms/tp port with NPDU length near 1497 bytes may trigger the bug.

6.03  2024.12.25

ARC156 is usable now.

6.01  2024.12.06

Fixed bug on bus name collision detection for Modbus/Free Client module.

Free Client:  Bianry objects add “Polority” attribute. Multistate objects add state quantity limitation of 256.

Gateway For M-Bus

M-Bus or Meter-Bus is a European standard (EN 13757-2 physical and link layer, EN 13757-3 application layer) for the remote reading of water, gas or electricity meters.

The detail of M-Bus could be found here: https://m-bus.com/documentation

The implementation of M-Bus gateway in BACRouter refers to libmbus,  Currently we only support serial. TCP is not supoorted yet.

There is very few M-Bus devices in China, so we can not test our implementation well. If you find any bug, please share with us.

To communicate with M-Bus devices, you need a M-Bus/RS485 signal converter.

Scan Records In A Meter:

In libmbus, there are some very useful tools, we have cross-compiled some of them to Win32 platform:

mbus-serial-scan.exe: Scan M-Bus devices on the bus by primary address (0~250)
Usage:  mbus-serial-scan.exe -b 2400 COM3
2400 is baudrate. COM3 is the serial port.

mbus-serial-scan-secondary.exe: Scan M-Bus devices on the bus by secondary address
Usage:  mbus-serial-scan-secondary.exe -b 2400 COM3

mbus-serial-switch-baudrate.exe: Switch the baudrate of a M-Bus device
Usage:  mbus-serial-switch-baudrate.exe -b 2400 COM3 Address Newbaudrate
Address could be a primary address or a secondary address, which could be obtained from previous scan.

mbus-serial-set-address.exe: Set the primary address of a M-Bus device
Usage:  mbus-serial-set-address.exe -b 2400 COM3 Address NewPrimaryAddress

mbus-serial-request-data-multi-reply.exe: Pull all records from a M-Bus device
Usage:  mbus-serial-request-data-multi-reply.exe -b 2400 COM3 Address

Records pulled will be listed as:

<DataRecord id="1">
    <Function>Instantaneous value</Function>
    <StorageNumber>0</StorageNumber>
    <Unit>Energy (10 Wh)</Unit>
    <Value>288144</Value>
    <Timestamp>2024-04-07T12:01:21Z</Timestamp>
</DataRecord>

We can just focus on the record id and unit.

Setup Free Client In The BACRouter:

Upgrade the firmware in the BACRouter to version 5.04 or larger.

Connect the RS485 port to the M-Bus, If there is a MS/TP port running on the RS485 port,  you should disable the MS/TP port first.

Open WebUI by web browser, select “Free Client Module”, on the “Create bus” row, click “RS485”

After bus is created, edit the bus:

From firmware version 5.X, more than one bus can be defined on the same RS485 port. Most RS485 protocol is stateless, so it is safe to do so. But for M-Bus, the sequence of communication is critical, so Don’t define more than one M-Bus on a RS485 port.

The Lua script could be downloaded from here: mbus1.2.lua

On the “tag” field, update_interval=5000, means every 5000 milliseconds, BACRouter will refresh all values. If force_reset is set, before BACRouter try to communicate with a M-Bus device by primary address, BACRouter will send a “SND_NKE” to the address, which will initialize the device. There was report that some devices only worked under force_reset=true.

On the “Device create/delete” row, click “Create Empty” to create a new M-Bus device. select created device to edit:

On the “tag” field, input:  addr=1

That means the primary address of the M-Bus device is 1,  if you want to use secondary address,  it should look like:  addr=”f57072162440f102″

The create a new point to map record id 1, click to edit:

On the “tag” field, id=1 means the record id is 1,  scale=10 means the value read from device will be multiplied with 10.  Note: the unit of record id 1 is 10 Wh,  the BACnet unit we choosed here is Wh.

Example Of M-Bus Configuration

The config of the above M-Bus bus can be downloaded here: RS485-1_mbus.json

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.