BACnet

BACnet is a data communication protocol for Building Automation and Control networks. A data communication protocol is a set of rules governing the exchange of data over a computer network. The rules take the form of a written specification that spells out what is required to conform to the protocol.

BACnet glossary (advanced reading)

Device

The device represents a server that is managing one or more BACnet objects. A device has a unique device instance number (which is sufficient for addressing if using the same network interface) and a unique UDP port as device address (in the format <ip-address>:<port-number>) which can be used for addressing throughout the entire LAN. Technically, the device is an object with the name device. The device instance in fact is its object instance with the additional requirement to be unique.

Object

An object reflects a physical hardware actor or sensor (i.e. an I/O device). BACnet defines a list of standardized object types (such as analog-input, analog-output, binary-input, binary-output, etc.). Object types are identified by a fixed number or by a fixed ASCII string identifier (s.a.). Depending on the installation, a device may serve an arbitrary number of object instances of arbitrary type. A device may for example run 3 analog-inputs, 1 analog-value and two binary-outputs. An object is addressed using its type and numeric instance ID which must only be unique within the device.

Property

Every object contains a type-dependent set of properties. The most important property that exists in every object is the present-value property. This is conceptually very similar to the process-variable (PV) of other industry protocols. Like object types, the properties are identified by a fixed number or by a fixed ASCII string (e.g. present-value). Examples of other properties are version or object-name. The property is the final data-endpoint where values can be read from or written to. The value type can be any scalar value, arrays of scalars or specific complex types (this depends on the object type).

For unambiguously addressing any data endpoint (in BACnet: property) the following information must be provided:

  • At the Cybus::Connection:

    1. deviceAddress (e.g. 192.168.2.160:43712)

    2. deviceInstance (e.g. 27335)

  • At the Cybus::Endpoint:

    1. objectType (e.g. analog-input)

    2. objectInstance (e.g. 2)

    3. property (e.g. present-value)

Note

If only one device is running on a given host (with fixed IP), the port can be omitted from the deviceAddress field.

Connection Properties

localInterface (string)

Local interface used to receive data

Default: "eth0"

Examples: "lo", "eth0"

localPort (integer)

Local port used to receive data

Default: 47808

Example: 47808

deviceInstance (integer, required)

Integer number describing the device instance

Example: 27335

deviceAddress (string, required)

Device address as UDP network address in the form ip-address:port-number. The port can be skipped if only one device is available under the given IP address

Example: "192.168.2.114:40426"

connectionStrategy (object)

If a connection attempt fails, retries will be performed with increasing delay (waiting time) in between. The following parameters control how these delays behave.

Properties of the connectionStrategy object:

initialDelay (integer)

Delay (waiting time) of the first connection retry (in milliseconds). For subsequent retries, the delay will be increased according to the parameter incrementFactor which has a default value of 2.

Default: 1000

Additional restrictions:

  • Minimum: 1000

maxDelay (integer)

Maximum delay (waiting time) to wait until the next retry (in milliseconds). The delay (waiting time) for any subsequent connection retry will not be larger than this value. Must be strictly greater than initialDelay.

Default: 30000

incrementFactor (integer)

The factor used to increment initialDelay up to maxDelay. For example if initialDelay is set to 1000 and maxDelay to 5000 the values for the delay would be 1000, 2000, 4000, 5000.

Default: 2

Additional restrictions:

  • Minimum: 2

Endpoint Properties

objectType (string, enum, required)

Identifier of the BACnet object type of this endpoint

This element must be one of the following enum values:

  • analog-input

  • analog-output

  • analog-value

  • binary-input

  • binary-output

  • binary-value

  • calendar

  • command

  • device

  • event-enrollment

  • file

  • group

  • loop

  • multi-state-input

  • multi-state-output

  • notification-class

  • program

  • schedule

Example: "analog-input"

objectInstance (integer, required)

Integer number to describe the concrete object instance that should be accessed

Example: 1

property (string, required)

The name of this property. The most common property has the name present-value. Other typically available property names are: object-name, description, status-flags, units. On the device object the properties location, object-list and system_status are typically available

Example: "present-value"

interval (integer)

The poll interval in milliseconds

Default: 1000

Example: 1000

cronExpression (string)

The Cron expression used to poll the endpoint. (For examples, see: https://github.com/node-cron/node-cron)

Examples: "1,2,4,5 * * * *", "1-5 * * * *", "*/2 * * * *", "* * * January,September Sunday"

priority (integer)

Only effective during writing to BACnet: Defines the priority (highest: 1, lowest 16 = default)

Example: 16

Additional restrictions:

  • Maximum: 16

propertyTag (integer)

Only effective during writing to BACnet: Forces the data type of the provided value into the provided BACnet type (called propertyTag). The propertyTag is an integer value (enumeration), please see the documentation for the encoding

Example: 4

Example Configuration

The following example demonstrates how to configure a simple BACnet connection and endpoint that subscribes to an analog-input BACnet object.

Download: bacnet-example.yml

 1# ----------------------------------------------------------------------------#
 2# BACnet Commissioning File Example
 3# ----------------------------------------------------------------------------#
 4# Copyright: Cybus GmbH (2021)
 5# Contact: support@cybus.io
 6# ----------------------------------------------------------------------------#
 7# Source Interface Definition - BACnet
 8# ----------------------------------------------------------------------------#
 9
10description: |
11  Sample commissioning file for Bacnet protocol connectivity and data mapping
12
13metadata:
14
15  name: Bacnet Protocol Connectivity
16  icon: https://www.cybus.io/wp-content/uploads/2019/03/Cybus-logo-Claim-lang.svg
17  provider: cybus
18  homepage: https://www.cybus.io
19  version: 0.0.1
20
21parameters:
22  IP_Address:
23    type: string
24    default: 192.168.10.30
25
26  Port_Number:
27    type: number
28    default: 47808
29
30  Device_Instance:
31    type: number
32    default: 2000
33
34  initialReconnectDelay:
35    type: integer
36    default: 1000
37
38  maxReconnectDelay:
39    type: integer
40    default: 30000
41
42  factorReconnectDelay:
43    type: integer
44    default: 2
45
46resources:
47  # Lets define the connection to the device.
48  bacnetConnection:
49    type: Cybus::Connection
50    properties:
51      protocol: Bacnet
52      targetState: connected
53      connection:
54        deviceInstance: !ref Device_Instance
55        deviceAddress: !sub '${IP_Address}:${Port_Number}'
56        connectionStrategy:
57          initialDelay: !ref initialReconnectDelay
58          maxDelay: !ref maxReconnectDelay
59          incrementFactor: !ref factorReconnectDelay
60
61  # The Bacnet protocol supports endpoints of type read, write and subscribe.
62  # Below are example on how to configure such operations.
63  # Read endpoint
64  bacnetReadBinaryOutput:
65    type: Cybus::Endpoint
66    properties:
67      protocol: Bacnet
68      connection: !ref bacnetConnection
69      # Specifying the topic here instead of using a Mapping block allow us to remove an extra hop.
70      read:
71        objectType: binary-output
72        objectInstance: 303
73        property: present-value
74
75  # Write endpoint
76  bacnetWriteBinaryOutput:
77    type: Cybus::Endpoint
78    properties:
79      protocol: Bacnet
80      connection: !ref bacnetConnection
81      write:
82        objectType: binary-output
83        objectInstance: 303
84        property: present-value
85        priority: 8
86        propertyTag: 7
87
88  # Subscription endpoint
89  bacnetSubscribeBinaryOutput:
90    type: Cybus::Endpoint
91    properties:
92      protocol: Bacnet
93      connection: !ref bacnetConnection
94      subscribe:
95        objectType: binary-output
96        objectInstance: 303
97        property: present-value
98        interval: 1000

Input Format

To write data to BACnet a request must be sent to the MQTT endpoint of the service using a /set suffix providing a JSON object with the following format:

{ "value": "<value>" }

No response message is written to the /res topic of the Endpoint for this protocol.

Output Format on Read

For a read endpoint, additionally a correlation id (id) can be set in the payload of the message request, to ensure the correct identification of responses to specific requests.

When data is read results are published to the /res topic of the Endpoint. The output message is an object with the following format:

{
  "value": "<value>",
  "timestamp": "<msSinceEpoch>"
  "id": "<correlation id>"
}

Further reading: