Skip to content

BACnet Device Service Component

The BACnet Device Service components integrate the BACnet protocol with XRT. There are two BACnet Device Services:

  • BACnet/IP
  • BACnet/MSTP

For further information on the protocol, refer to the official ASHRAE SSPC 135 website.

The BACnet Device Service components support the following features:

  • Device discovery and profile generation
  • Change of Value subscription
  • Reading and writing properties of BACnet devices
  • Multiple property read/writes
    • Data Sharing - ReadPropertyMultiple - B
    • Data Sharing - WritePropertyMultiple - B

BACnet Device Service Configuration

BACnet/IP Configuration

Note

The core components required for running BACnet/IP (and all other device services) are contained in Device Service Component Configuration. Please refer to this page to ensure the appropriate core components are assigned before continuing.

With those components assigned, there are also the following optional BACnet/IP Driver options that can be used to configure the device service:

BACnet/IP Driver Options

Parameter Type Description Default Value
NetworkID String BACnet instance ID of the Device Service on the network 0
NetworkInterface String Network interface name used to communicate to BACnet devices Primary interface determined by the device service if not set
Port UInt16 Port the BACnet communication will occur over 47808
APDUTimeout UInt32 The timeout on a confirmed request in milliseconds 3000
APDURetries UInt8 The maximum number of retries of a confirmed request 3
MultiBatchSize UInt8 Maximum number of properties in a multi read/write. If the request contains more properties than this limit, then another batch of multi read/writes will be performed 20
DisableMultiRead Bool Disable multiple property reads false
DisableMultiWrite Bool Disable multiple property writes false
CancelStaleCOV Bool Any COV notifications received that are not expected will be responded to with a cancellation request true
BBMDAddress String IP Address of the BBMD that the device service will register to as a foreign device If not set, then the device service assumes it is not acting as a foreign device
BBMDPort UInt16 Port number of the foreign device registration to the BBMD 47808, but will only be used if BBMDAddress is set
BBMDTimeToLive UInt16 How long the foreign device registration is set to last in seconds. The device service will automatically re-establish registration before this time elapses 65535, but will only be used if BBMDAddress is set
DefaultDiscoveryMode String What range of properties will be discovered on a device when generating a profile:

The three options are:
  • All - Will attempt PROP_ALL requests which receive all properties of an object. Upon failure of that call, it will try to read the property list of each object instance and query each property. Upon failure of that it will just try to read the standard and optional properties of each object instance on the device according to the BACnet specification of that particular object
  • Mandatory - Will only query the mandatory properties of each object instance on the device according to the BACnet specification of that particular object
  • PresentValue - Will only query present value
All

A template of the BACnet/IP device service configuration file is provided where all the driver options have been set to demonstrate their usage:

{
  "Library": "libxrt-bacnet-ip-device-service.so",
  "Factory": "xrt_bacnet_ip_device_service_factory",
  "Name": "bacnet_ip_device_service",
  "Topic": "xrt/device/bacnet_ip_device_service/data",
  "RequestTopic": "xrt/device/bacnet_ip_device_service/request",
  "ReplyTopic": "xrt/device/bacnet_ip_device_service/reply",
  "DiscoveryRequestTopic": "xrt/discovery/bacnet_ip_device_service/request",
  "DiscoveryReplyTopic": "xrt/discovery/bacnet_ip_device_service/reply",
  "DiscoveryTopic": "xrt/discovery/bacnet_ip_device_service/devices",
  "ProfileRequestTopic": "xrt/profile/bacnet_ip_device_service/request",
  "ProfileReplyTopic": "xrt/profile/bacnet_ip_device_service/reply",
  "ScheduleRequestTopic": "xrt/schedule/bacnet_ip_device_service/request",
  "ScheduleReplyTopic": "xrt/schedule/bacnet_ip_device_service/reply",
  "StateDir":"./config/state",
  "ProfileDir": "./config/profiles",
  "Scheduler": "sched",
  "Logger": "logger",
  "ThreadPool": "pool",
  "Bus": "bus",
  "Driver": {
    "NetworkID": 0,
    "NetworkInterface": "eno1",
    "Port": 47808,
    "APDUTimeout": 4000,
    "APDURetries": 2,
    "MultiBatchSize" : 25,
    "DisableMultiRead" : false,
    "DisableMultiWrite" : false,
    "CancelStaleCOV": true,
    "BBMDAddress": "172.17.0.2",
    "BBMDPort": 47808,
    "BBMDTimeToLive": 60000,
    "DefaultDiscoveryMode": "All"
  }
}

BACnet/MSTP Configuration

Note

The core components required for running BACnet/MSTP (and all other device services) are contained in Device Service Component Configuration. Please refer to this page to ensure the appropriate core components are assigned before continuing.

With those components assigned, there are also the following BACnet/MSTP Driver options that can be used to configure the device service. All of them are optional except SerialInterface which is mandatory.

BACnet/MSTP Driver Options

Parameter Type Description Default Value
NetworkID String BACnet instance ID of the Device Service on the network 0
SerialInterface String Path to the RS-485 connection on the host No default, this must be set by the user
APDUTimeout UInt32 The timeout on a confirmed request in milliseconds 60000
APDURetries UInt8 The maximum number of retries of a confirmed request 3
MultiBatchSize UInt8 Maximum number of properties in a multi read/write. If the request made contains more properties than this limit, then another batch of multi read/writes will be performed 20
DisableMultiRead Bool Disable multiple property reads false
DisableMultiWrite Bool Disable multiple property writes false
CancelStaleCOV Bool Any COV notifications received that are not expected will be responded to with a cancellation request true
DefaultDiscoveryMode String What range of properties will be discovered on a device when generating a profile:

The three options are:
  • All - Will attempt PROP_ALL requests which receive all properties of an object. Upon failure of that call, it will try to read the property list of each object instance and query each property. Upon failure of that it will just try to read the standard and optional properties of each object instance on the device according to the BACnet specification of that particular object
  • Mandatory - Will only query the mandatory properties of each object instance on the device according to the BACnet specification of that particular object.
  • PresentValue - Will only query present value
All

A template of the BACnet/MSTP device service configuration file is provided where all the driver options have been set to demonstrate their usage:

{
  "Library": "libxrt-bacnet-mstp-device-service.so",
  "Factory": "xrt_bacnet_mstp_device_service_factory",
  "Name": "bacnet_mstp_device_service",
  "Topic": "xrt/device/bacnet_mstp_device_service/data",
  "RequestTopic": "xrt/device/bacnet_mstp_device_service/request",
  "ReplyTopic": "xrt/device/bacnet_mstp_device_service/reply",
  "DiscoveryRequestTopic": "xrt/discovery/bacnet_mstp_device_service/request",
  "DiscoveryReplyTopic": "xrt/discovery/bacnet_mstp_device_service/reply",
  "DiscoveryTopic": "xrt/discovery/bacnet_mstp_device_service/devices",
  "ProfileRequestTopic": "xrt/profile/bacnet_mstp_device_service/request",
  "ProfileReplyTopic": "xrt/profile/bacnet_mstp_device_service/reply",
  "ScheduleRequestTopic": "xrt/schedule/bacnet_mstp_device_service/request",
  "ScheduleReplyTopic": "xrt/schedule/bacnet_mstp_device_service/reply",
  "StateDir":"./config/state",
  "ProfileDir": "./config/profiles",
  "Scheduler": "sched",
  "Logger": "logger",
  "ThreadPool": "pool",
  "Bus": "bus",
  "Driver": {
    "NetworkID": 0,
    "SerialInterface": "/dev/tty/USB0",
    "APDUTimeout": 10000,
    "APDURetries": 2,
    "MultiBatchSize": 10,
    "DisableMultiRead": false,
    "DisableMultiWrite": false,
    "CancelStaleCOV": true,
    "DefaultDiscoveryMode": "All"
  }
}

Determining Serial Interface Path

To find the path of the serial interface used there are a few options.

If the interface is not fixed to the host, for example via USB, remove it and connect again then run the following command:

dmesg -w

This command provides information on the last connected device, which will contain the device's path. This path is usually something like /dev/tty/USBx where x is the USB port number.

If you have a fixed interface, the following command could be used to find all the available serial connections:

dmesg | grep tty
This for example could return ttyS0 which would mean its full path is /dev/ttyS0

BACnet Device Profile

Details on general profile usage can be found on the Device Profiles page.

The following sections will cover how device resources are mapped to BACnet properties.

Attributes

The attributes used in a BACnet device resource are described in the following table:

Attribute Description Valid Values
type BACnet object type UInt32 value

Object type values are specified in an enumeration: bacenum.h file
instance BACnet object instance number UInt32 value
property BACnet property type UInt32 value

Property values are specified in an enumeration: bacenum.h file
index Index of array

Optional
UInt32 value

Index 0 holds the size of an array in BACnet
raw Read / write the full APDU if true

XRT data type must also be set to Binary if true

Optional
true / false

Example Device Resources

The following section provides examples of some device resources mapped to BACnet properties.

  • The extract from a device profile shown below reads the Present Value property of instance 1 of the Binary Input object

    Location Description
    Object Type Binary Input

    Enumeration: 3
    Object Instance Number 1
    Property Present Value

    Enumeration: 85
    Indexing No array indexing
    BACnet Data Type Enumerated
    XRT Data Type UInt32

    {
      "name": "binary_input_1:present-value",
      "description": "Get the present value of binary input object 1",
      "attributes": {
        "type": "3",
        "instance": "1",
        "property": "85"
      },
      "properties": {
        "value": {
          "type": "Uint32",
          "readWrite": "RW"
        }
      }
    }
    
  • The device resource shown below reads / writes the Present Value property of instance 4 of the Analog Output object

    Location Description
    Object Type Analog Input

    Enumeration: 1
    Object Instance Number 4
    Property Present Value

    Enumeration: 85
    Indexing No array indexing
    BACnet Data Type Float
    XRT Data Type Float32

    {
      "name": "analog_output_4:present-value",
      "description": "The present value of analog output 4",
      "attributes": {
        "type": "1",
        "instance": "4",
        "property": "85"
      },
      "properties": {
        "value": {
          "type": "Float32",
          "readWrite": "RW"
        }
      }
    }
    
  • The device resource shown below reads the full Priority Array of instance 4 of the Analog Output object

    Location Description
    Object Type Analog Input

    Enumeration: 1
    Object Instance Number 4
    Property Priority Array

    Enumeration: 87
    Indexing No array indexing
    BACnet Data Type BACnet Array of floats or nulls
    XRT Data Type String

    {
      "name": "analog_output_4:priority-array",
      "description": "The priority array of analog output 4",
      "attributes": {
        "type": "1",
        "instance": "4",
        "property": "87"
      },
      "properties": {
        "value": {
          "type": "String",
          "readWrite": "R"
        }
      }
    }
    
  • The device resource shown below reads the third index of the Priority Array of instance 4 of the Analog Output Object

    Location Description
    Object Type Analog Input

    Enumeration: 1
    Object Instance Number 4
    Property Priority Array

    Enumeration: 87
    Indexing Element 3
    BACnet Data Type Float
    XRT Data Type Float32

    {
      "name": "analog_output_4:priority-array-index-3",
      "description": "The priority array of analog output 4, index 3",
      "attributes": {
        "type": "1",
        "instance": "4",
        "property": "87",
        "index": "3"
      },
      "properties": {
        "value": {
          "type": "Float32",
          "readWrite": "RW"
        }
      }
    }
    
  • The device resource shown below reads / writes the property Event Time Stamps of instance 2 of the Analog Value Object.

    • The BACnet data type that represents this property is BACnetARRAY3 of BACnetTimeStamp
    • As the device service does not support this it, this resource must be set to a raw type with the XRT data type as Binary

    Location Description
    Object Type Analog Value

    Enumeration: 2
    Object Instance Number 2
    Property Event Time Stamps

    Enumeration: 130
    Indexing No array indexing
    BACnet Data Type BACnetARRAY3 of BACnetTimeStamp
    XRT Data Type Binary (with raw attribute set to true)

    {
      "name": "analog_value_2:event-time-stamps",
      "description": "The event time stamps of analog value 2",
      "attributes": {
        "type": "2",
        "instance": "2",
        "property": "130",
        "raw": "true"
      },
      "properties": {
        "value": {
          "type": "Binary",
          "readWrite": "RW"
        }
      }
    }
    

Data Types

When the device receives a request, it returns a value with a BACnet type. The following table lists the supported BACnet data types, their equivalent XRT data types and the supported read / write abilities:

BACnet Data Type XRT Data Type Read/Write Ability
Boolean Bool RW
Unsigned Int UInt64 RW
Signed Int Int32 RW
Real Float32 RW
Double Float64 RW
Enumerated UInt32 RW
Character String String RW
Date String R
Bit String Binary R
Octect String Binary R
Time String R
BACnetObjectIdentifier String R

Unsupported BACnet Types

The BACnet device service does not support decoding all BACnet data types into readable formats. To read/write any BACnet types that are not supported in the table above, the XRT data type Binary must be used along with an attribute of raw set to true in the device resource.

When making a reading using a device resource of this type, the device service will return the entire APDU that is received. If writing to a device resource of this type the entire encoded APDU must be provided as the payload by the user.

An example device resource of this type is shown in the Example Device Resources section.

BACnet Arrays

BACnet Array types are supported to be read but will only be returned using the XRT String type. Each element is comma separated where the following BACnet types are supported for the array:

  • Null
  • Boolean
  • Enumerated
  • Unsigned Int
  • Signed Int
  • Real
  • Double
  • Character String

Device Commands

See the Device Commands page for details on how to define device commands for grouping device resources for fewer requests.

BACnet Device Provisioning

The following sections will explain how devices can be statically configured for both BACnet/IP and BACnet/MSTP device services.

Note

For information on dynamic device additions, removals and updates please see the MQTT API Guide.

BACnet/IP Device Provisioning

To provision a BACnet/IP device, the BACnet-IP protocol must be used along with the DeviceInstance protocol property which specifies the BACnet device instance network ID.

An example of a BACnet/IP device provision within the devices.json file is provided below:

{
  "BacnetSimulator": {
    "name": "BacnetSimulator",
    "profile": "bacnet-simulator",
    "protocols": {
      "BACnet-IP": {
        "DeviceInstance": "1234"
      }
    }
  }
}

BACnet/MSTP Device Provisioning

To provision a BACnet/IP device, the BACnet-MSTP protocol must be used along with the DeviceInstance protocol property which specifies the BACnet device instance network ID.

An example of a BACnet/MSTP device provision within the devices.json file is provided below:

{
  "BacnetSimulator": {
    "name": "BacnetSimulator",
    "profile": "bacnet-simulator",
    "protocols": {
      "BACnet-MSTP": {
        "DeviceInstance": "1234"
      }
    }
  }
}

BACnet Device Service Interaction

Any sections contained within the part of the guide are to describe protocol specific functionality of the device service.

For information on how to dynamically execute reads, writes, setting up schedules, triggering device discovery and much more, please refer to the MQTT API Guide.

BACnet Priority Levels

When performing a put request on a BACnet device resource, an additional option can be added to the payload, Priority, which indicates the priority level (1 to 16) that the value will be written as. Only a select few Object types and properties support these priority levels in BACnet.

An example user payload is provided which demonstrates its usage on the Present Value property of the Analog Output Object. In this example, priority level 2 will be set as the value 33.0.

{
  "client": "iotech",
  "request_id": "102",
  "op": "device:put",
  "device": "BacnetSimulator",
  "values": {
    "analog_output_0:present-value": 33.0
  },
  "options": {
    "Priority": 2
  }
}

These priority levels can also be set to null. In the following example, priority level 1 will be set to null. This will mean that when the Present Value property is read, the returned reading will skip priority level 1 as its null and return the value from level 2 which was set as 33.0.

{
  "client": "iotech",
  "request_id": "101",
  "op": "device:put",
  "device": "BacnetSimulator",
  "values": {
    "analog_output_0:present-value": null
  },
  "options": {
    "Priority": 1
  }
}

BACnet Change of Value

In addition to regular polling via schedules that are described in the Schedules page, the BACnet device service supports a protocol specific feature called Change of Value (COV). This allows the device service to subscribe for changes to a specific property on a device, which is usually the Present Value. When the value of this property changes, if the delta is larger than the COV Increment property value then the device will send the device service a notification which includes this new value.

To set up a COV subscription it is similar to how a schedule is configured for XRT. The main differences are the interval is just ignored so can be set to 1000000 and there is an extra field used called options. Within this options field there is a COV field that contains 2 settings, Confirmed and Lifetime. The usage of these options is explained in the table below.

COV Setting Description Valid Values
Confirmed Confirmed or unconfirmed COV notifications true / false
Lifetime Length of time the COV subscription will last in seconds

Once the time has elapsed, a cancel request will be sent to the device and the COV removed from the XRT configuration

Set to 0 for an infinite COV subscription
UInt16 value

An example of a COV subscription for two different properties is provided below as a static configuration in the schedules.json file.

{
  "cov0": {
    "name": "cov0",
    "device": "BacnetSimulator", 
    "interval": 1000000,
    "resource": ["analog_value_0:present-value", "analog_value_1:present-value"], 
    "options": {
      "COV": {
        "Confirmed": false, 
        "Lifetime": 600
      }
    }
  }
}

Run the BACnet Device Service

Find details on how to run the BACnet device service on the Run Device Services page.

Back to top