OPC UA · BACnet/IP · Modbus TCP · Kepware · UaExpert · Azure IoT · 11 min read

OPC UA to BACnet and Modbus Gateway: Protocol Translation for BMS Integration

The vast majority of installed BMS devices — BACnet/IP controllers, Modbus TCP energy meters, and Modbus RTU field devices — do not implement an OPC UA server. A protocol gateway bridges this gap: it connects to legacy devices using their native protocols and exposes all discovered data points as OPC UA nodes in a single browsable address space. Kepware KEPServerEX is the industry-standard choice for this role, supported by Siemens, Schneider, and Rockwell Automation for multi-protocol BMS gateway deployments.

Why a gateway is needed

BACnet/IP and BACnet MS/TP devices expose data via BACnet object services (ReadProperty, SubscribeCOV) — not OPC UA services. Modbus TCP and RTU devices expose data as numbered registers with no built-in naming, type information, or security. An OPC UA client cannot communicate with either protocol natively.

The gateway acts as a translation layer. On the south side it polls or subscribes to devices using their native protocols. On the north side it runs a full OPC UA server, mapping each device data point to a named, typed OPC UA Variable node. The result: a SCADA system, cloud connector, or energy management platform sees a single OPC UA endpoint containing all building data, regardless of whether the underlying devices speak BACnet, Modbus, KNX, or SNMP.

COV vs polling in the gateway: For BACnet devices that support Change of Value (COV) subscriptions, configure Kepware to use SubscribeCOV rather than periodic ReadProperty polling. COV reduces BACnet network traffic and ensures the gateway reflects state changes immediately rather than waiting for the next poll cycle. Modbus devices always require polling — set the scan rate to match your data freshness requirement (typically 1–10 seconds for HVAC, 100–500 ms for power quality).

Gateway options comparison

GatewayOPC UA serverBACnet supportModbus supportPlatform
Kepware KEPServerEX 6Full UA server (all security modes)BACnet/IP + MS/TP; BBMD; COVModbus RTU/TCP/ASCII; 65535 regsWindows Server/PC
matrikon OPC UA TunnellerOPC UA server + DA/HDA bridgeVia OPC DA bridging onlyVia OPC DA bridging onlyWindows
Cogent DataHub OPC UAFull UA serverBACnet/IP; limited COVModbus TCPWindows
softing edgeConnector ModbusOPC UA serverNo — Modbus onlyModbus TCP + RTUDocker / Linux / Windows
softing edgeConnector BACnetOPC UA serverBACnet/IP + MS/TPNoDocker / Linux / Windows
Ignition (Inductive Automation)OPC UA server (built-in)BACnet/IP via driver moduleModbus TCP/RTU driverWindows / Linux (JVM)

Kepware KEPServerEX: BACnet/IP driver setup

Kepware’s BACnet/IP Ethernet driver (licensed separately from the base KEPServerEX package) connects to BACnet/IP devices on the local subnet or across routers using a BACnet Broadcast Management Device (BBMD). After adding the driver channel, Kepware auto-discovers all visible BACnet devices and imports their object lists.

Kepware BACnet/IP driver configuration

Channel settings (Connectivity > BACnet/IP Ethernet):
  Network adapter: 192.168.10.5 (Kepware server OT NIC)
  UDP port: 47808 (BAC0 — standard BACnet/IP port)
  BACnet device instance: 1001 (Kepware gateway identity on BACnet network)
  BBMD address: 192.168.10.1 (router acting as BBMD for cross-subnet discovery)
  BBMD UDP port: 47808
  Foreign device registration: enabled (for devices on other subnets)

Auto-discovery:
  Tools > Device Discovery > BACnet/IP
  Scan range: all subnets registered on BBMD
  Result: discovered 47 BACnet devices with object counts
  Import: select all → creates Kepware device entries with all objects

COV subscription (preferred over polling):
  Device property > Subscriptions > Use COV: Enabled
  Lifetime: 3600 seconds (re-subscribe hourly)
  COV increment for Analog Values: 0.5 (only report if change > 0.5 units)
  Fallback poll rate (if COV not supported): 5000 ms

Each imported BACnet object becomes a Kepware tag. Kepware automatically maps the BACnet Present_Value property to the tag’s primary value. The tag name follows the pattern DeviceName.ObjectType_Instance.Property, for example: PXC_01.AnalogInput_1.Present_Value. These tags are immediately exposed as OPC UA Variable nodes on the KEPServerEX built-in OPC UA endpoint.

Modbus TCP to OPC UA: register map import

Modbus TCP devices require explicit register map configuration — unlike BACnet, there is no self-describing object discovery. Kepware’s Modbus TCP/IP Ethernet driver accepts a CSV tag import file or manual tag configuration specifying register address, data type, and engineering conversion.

Kepware Modbus TCP tag configuration

Channel: Modbus TCP/IP Ethernet
  Network adapter: 192.168.10.5
  Port: 502 (standard Modbus TCP port)
  Request timeout: 1000 ms
  Failure count before error: 3

Device: Schneider_PM5100
  IP address: 192.168.10.21
  Unit ID (slave address): 1
  Scan rate: 1000 ms (1 second)

Tags (imported from Schneider PM5100 register map):
  Tag name            | Address        | Data type | Scaling
  ActivePower_Total   | 400593 (HR593) | Float (4B) | ×1 → kW
  ActiveEnergy_Import | 400001 (HR001) | DWord (4B) | ×0.1 → kWh
  Voltage_L1_N        | 400003 (HR003) | Float (4B) | ×1 → V
  Current_L1          | 400013 (HR013) | Float (4B) | ×1 → A
  PowerFactor_Total   | 400085 (HR085) | Float (4B) | ×1 (dimensionless)
  Frequency           | 400073 (HR073) | Float (4B) | ×1 → Hz

# Tag addressing format for Kepware Modbus driver:
# Holding Register 40001 → address "400001" or "4:1"
# Input Register 30001   → address "300001" or "3:1"
# Coil 1                 → address "000001" or "0:1"
# Discrete Input 10001   → address "100001" or "1:1"

BACnet object to OPC UA node mapping

Kepware maps each BACnet object type to an OPC UA Variable node with the appropriate OPC UA data type. The Present_Value property of the BACnet object becomes the OPC UA node value. Status_Flags and Reliability properties are mapped to the OPC UA StatusCode of the Variable.

BACnet object typePresent_Value typeOPC UA data typeTypical use
Analog Input (AI)REAL (Float)FloatTemperature sensor, pressure, flow
Analog Output (AO)REAL (Float)Float (writable)Valve position setpoint, fan speed
Analog Value (AV)REAL (Float)Float (writable)Setpoint, calculated value
Binary Input (BI)ENUMERATED (Active/Inactive)BooleanOn/Off status, alarm state
Binary Output (BO)ENUMERATED (Active/Inactive)Boolean (writable)On/Off command, relay control
Binary Value (BV)ENUMERATED (Active/Inactive)Boolean (writable)Mode flag, override state
Multi-state Input (MI)UNSIGNED INTInt32Operating mode readback (Off=0, Heat=1, Cool=2)
Multi-state Output (MO)UNSIGNED INTInt32 (writable)Mode command, speed step
Multi-state Value (MV)UNSIGNED INTInt32 (writable)Configurable enum value
AccumulatorUNSIGNED INT (32-bit)UInt32Pulse counter: kWh, m³, litres

Security for OPC UA gateways

An OPC UA gateway is an IT/OT boundary device. If compromised, an attacker can write to writable BACnet outputs (valves, relays) or Modbus coils through the OPC UA write service. Apply defence-in-depth: network segmentation, certificate-based auth, and minimal write permissions.

Security controlImplementation
Dedicated OT VLANPlace Kepware server on isolated VLAN; BACnet and Modbus devices on same VLAN; no direct IT LAN routing
Firewall rulesAllow TCP 4840 inbound only from known OPC UA client IPs; block all other inbound; allow Kepware outbound to BACnet UDP 47808 and Modbus TCP 502
Certificate authenticationDisable Anonymous; require X.509 client certificates; import trusted client certs to Kepware trust store
Kepware user access controlCreate read-only UA role for monitoring clients; read-write UA role for BMS integration only; MFA on Kepware admin console
Tag-level write protectionSet Modbus tags to Read-Only in Kepware where writes are not required; BACnet AO/BO/MO tags write-enabled only for SCADA role
Audit loggingEnable Kepware event log; forward to Windows Event Log → SIEM; alert on unauthorised write attempts

Default port 4840: Kepware KEPServerEX listens on TCP port 4840 by default — the IANA-registered OPC UA port. This port must be opened on the Windows Firewall on the Kepware host for OPC UA clients to connect. Do not expose port 4840 to untrusted networks. If the Kepware server requires internet-accessible OPC UA (for cloud connectors), use a reverse proxy with mutual TLS rather than direct port forwarding.

Testing OPC UA connections with UaExpert

UaExpert (by Unified Automation) is the standard free OPC UA client for commissioning and diagnostics. It provides a full address space browser, real-time data monitoring, subscription testing, and security certificate management. Download from unified-automation.com (free registration required).

UaExpert — connection and verification steps

1. Add server:
   Server menu > Add > Advanced > Enter URL:
   opc.tcp://192.168.10.50:4840
   Security policy: Basic256Sha256
   Message security mode: SignAndEncrypt
   Authentication: Certificate (browse to client_cert.pem + client_key.pem)

2. First connection — certificate exchange:
   UaExpert generates a self-signed client cert on first run
   Server will show certificate as "untrusted" initially
   On Kepware: OPC UA Configuration > Trusted Clients > Move cert to Trusted
   On UaExpert: OPC UA > Manage Certificates > Trust the server cert

3. Browse address space:
   Expand Root > Objects > (your channel name) > (device name)
   Locate BACnet tags: PXC_01 > AnalogInput_1 > Present_Value
   Locate Modbus tags: Schneider_PM5100 > ActivePower_Total

4. Read values:
   Double-click any Variable node to open Data Monitor
   Verify values match expected engineering units and range
   Check StatusCode column — should show "Good (0x00000000)"
   StatusCode "Bad_NoCommunication" → check BACnet/Modbus connectivity from Kepware

5. Create subscription:
   Data Access View panel (bottom): drag Variable nodes from address space
   Set PublishingInterval 1000 ms
   Watch values update in real time — confirms subscription pipeline is working

6. Test write (writable tags only):
   Right-click Variable node > Write Value
   Enter test value within EU range
   Verify change reflected on BACnet device Present_Value
   Note: writes on Kepware require the connecting client to have write permission in UA role

Cloud integration via Azure IoT Hub OPC Publisher

Azure IoT Hub OPC Publisher is Microsoft’s open-source OPC UA client that connects to OPC UA servers (including Kepware) and forwards telemetry to Azure IoT Hub. It runs as an Azure IoT Edge module on a Linux container host in the building, bridging the OT OPC UA layer to Azure cloud services.

OPC Publisher — publishednodes.json for Kepware

// publishednodes.json — defines which OPC UA nodes to publish to Azure IoT Hub
[
  {
    "EndpointUrl": "opc.tcp://192.168.10.50:4840",
    "UseSecurity": true,
    "OpcAuthenticationMode": "UsernamePassword",
    "OpcAuthenticationUsername": "azure-publisher",
    "OpcAuthenticationPassword": "<from keyvault>",
    "OpcNodes": [
      {
        "Id": "ns=2;s=Channel1.PXC_01.AnalogInput_1.Present_Value",
        "DisplayName": "AHU01_SupplyAirTemp",
        "OpcPublishingInterval": 10000,
        "OpcSamplingInterval": 5000,
        "HeartbeatInterval": 60
      },
      {
        "Id": "ns=2;s=Channel1.Schneider_PM5100.ActivePower_Total",
        "DisplayName": "MainMeter_ActivePower_kW",
        "OpcPublishingInterval": 5000,
        "OpcSamplingInterval": 2000
      },
      {
        "Id": "ns=2;s=Channel1.Schneider_PM5100.ActiveEnergy_Import",
        "DisplayName": "MainMeter_Energy_kWh",
        "OpcPublishingInterval": 60000,
        "OpcSamplingInterval": 30000,
        "SkipFirst": true
      }
    ]
  }
]

// Azure IoT Hub receives JSON telemetry:
// {
//   "NodeId": "ns=2;s=Channel1.Schneider_PM5100.ActivePower_Total",
//   "DisplayName": "MainMeter_ActivePower_kW",
//   "Value": { "Value": 47.3, "StatusCode": "Good", "SourceTimestamp": "2025-03-14T10:30:00Z" }
// }

From Azure IoT Hub, telemetry routes to Azure Time Series Insights, Azure Data Explorer, or a custom Azure Stream Analytics job for real-time energy KPI dashboards in Power BI. The OPC Publisher container handles reconnection, buffering during connectivity loss (configurable store-and-forward), and certificate management for the OPC UA connection to Kepware.

Need a BACnet or Modbus to OPC UA gateway for your project?

We configure and commission Kepware KEPServerEX gateways connecting BACnet/IP, Modbus TCP, and KNX building devices to OPC UA clients, SCADA platforms, and Azure IoT Hub — with full security hardening and certificate management.

Request a quote →
Loading...
Back to top