BACnet Stack on Ubuntu: Metadata, Read & Write API Details

This page is a technical companion to the case study: BACnet Stack on Ubuntu to provide a Self-Configuring BACnet Server . It explains how a REST API can be mapped into a BACnet/IP device using the CAS BACnet Stack.


Tool Spotlight: CAS BACnet Explorer

When commissioning or troubleshooting a BACnet server, a reliable BACnet client tool makes validation fast. CAS BACnet Explorer is commonly used to:

  • Discover BACnet devices and browse objects/properties
  • Read key properties like Present Value and Reliability
  • Perform controlled tests using WriteProperty (setpoints, relays, overrides)

If you have questions about commissioning or mapping strategy, please CONTACT US.

How the Integration Works

The self-configuring BACnet server uses three core endpoints to build and maintain a BACnet device model: Metadata defines the device and objects, Read provides live values and reliability, and Write sends commands back to the REST system.

  1. GET /metadata – Builds the BACnet device and objects (types, instances, units, names). This also initializes an internal memory database for current values and properties.
  2. GET /read – Updates live values (e.g., Present Value) and Reliability. Values are stored in memory and served to BACnet clients.
  3. BACnet WriteProperty → POST /write – When a BACnet client writes to an AO/BO, the server forwards that command to the REST API. Success updates the memory database; failures are returned as BACnet errors.

Endpoint 1: Metadata (GET /metadata)

The metadata endpoint is used to initially set up the BACnet interface. Device properties, object definitions, and object properties are described in JSON. The server uses this data to:

  • Create/register the BACnet device and its objects
  • Build an internal memory database for properties and values
  • Optionally re-poll metadata to discover newly added sensors/devices

Minimal Example

{
  "result": "OK",
  "value": {
    "bacnetNetwork": 0,
    "udpPort": 47808,
    "device": {
      "instance": 1,
      "name": "DeviceName",
      "location": "",
      "description": "",
      "objectList": [
        { "instance": 2, "objectType": "analogInput", "name": "E00C - Temperature", "units": "degreesCelsius" },
        { "instance": 3, "objectType": "analogInput", "name": "E00C - Humidity", "units": "percentRelativeHumidity" }
      ]
    },
    "metadataPollInterval": 900000,
    "sensorPollInterval": 300000
  }
}

Field Reference

Field Meaning
bacnetNetwork BACnet network number used by the BACnet server for object/device registration.
udpPort UDP port for BACnet/IP communication (commonly 47808).
device.instance BACnet Device Object instance number.
device.objectList[] Defines BACnet objects to create (type, instance, name, units, etc.).
metadataPollInterval   How often to re-fetch metadata to detect added sensors/devices (milliseconds).
sensorPollInterval How often to poll the read endpoint for live values (milliseconds).

Endpoint 2: Read (GET /read)

The read endpoint contains the current values for mapped BACnet objects. It typically includes both the value (mapped to Present Value) and a status indicator (mapped to Reliability). If sensors go offline, the server can reflect this by updating reliability (and optionally other status properties depending on your model).

If the REST platform later optimizes read responses to return only deltas, the request can include a last-seen timestamp so the server receives only changes.

Minimal Example

{
  "result": "OK",
  "timestamp": "123456789",
  "values": [
    { "instance": 2, "presentValue": 25.3, "reliability": "no-fault-detected" },
    { "instance": 3, "presentValue": 45.0, "reliability": "no-fault-detected" }
  ]
}

Field Reference

Field Meaning
timestamp Monotonic or server-provided version marker used for delta polling (implementation-specific).
values[].instance Object instance number; must match the object instances created from metadata.
values[].presentValue   Mapped into BACnet Present Value for the corresponding object.
values[].reliability Mapped into BACnet Reliability property (e.g., no-fault-detected, unreliable-other, etc.).

Endpoint 3: Write (BACnet WriteProperty → POST /write)

The write functionality allows a BACnet client (BMS, workstation, or commissioning tool) to send commands that are forwarded to the REST API. In typical mappings:

  • Analog Output objects map to setpoints (numeric commands)
  • Binary Output objects map to relays or enable/disable commands (boolean commands)

When the BACnet server receives a WriteProperty request, it attempts the REST write. If the REST call succeeds, the server updates its internal memory database and reflects the new Present Value. If it fails, the server converts the failure into an appropriate BACnet error response.

Example Write Request/Response

// Request (example shape)
{
  "instance": 8,
  "value": 22.0
}

// Response (example shape)
{
  "result": "OK"
}

If the write fails, return a clear error message in JSON (e.g., permission denied, invalid value, device offline). The BACnet layer should translate that into a BACnet error so clients can display a meaningful failure.

Settings Summary

BACnet Settings

  • BACnetNetwork – Network number used for the BACnet server’s internal registration
  • udpPort – BACnet/IP UDP port (commonly 47808)

Polling Settings

  • metadataPollInterval – How often to refresh metadata to detect new sensors/devices (ms)
  • sensorPollInterval – How often to refresh values from the read endpoint (ms)

BBMD / Foreign Device Registration (Optional Enhancement)

If the BACnet server must communicate across IP subnets where broadcast discovery is limited, a common approach is BBMD support and/or Foreign Device Registration. This typically requires additional settings such as:

  • bbmdIPAddress – IP address of the BBMD
  • bbmdPort – BBMD UDP port (often 47808)
  • foreignDeviceTimeToLive – Registration TTL interval for RegisterForeignDevice

FAQ (AI Searchability)

What does “self-configuring” mean in this BACnet server?
The server learns the BACnet device model from /metadata and automatically creates objects and properties, rather than relying on a fixed static database.

How are BACnet objects created?
Objects are created using the device.objectList[] definitions in metadata. Each entry specifies object type (AI/AO/BI/BO), instance number, name, and (when applicable) units.

How does the server handle unreliable sensors?
The read endpoint provides a reliability indicator per object. The server maps that value to BACnet’s Reliability property so BACnet clients can clearly identify bad or missing data.

What happens if the REST platform returns only changed values?
The read request can include a last-seen timestamp. The REST platform can then return only deltas, and the server updates only those object instances.

How are BACnet WriteProperty commands mapped to REST writes?
Writes to mapped AO/BO objects are forwarded to /write. A successful REST response updates the server’s internal value. Failures are translated into BACnet errors for clear diagnostics.

View the full case study   |   CONTACT US if you’d like help implementing a similar BACnet/IP integration.

Contact Us

Contact us via phone (+1 866-383-1657) or leave a detailed message below for sales, support, or any other needs

*Required Field
*Required Field
I'd like to receive the newsletter. *Check email for confirmation.
*Required Field
8:00am - 12:00pm 12:00pm - 5:00pm
Message Sent Successfully