BACnet Properties

BACnet Properties

BACnet Properties

In the sections below, we’ll cover how a user can read from and write to BACnet properties such as reliability, outOfService, statusFlags, proprietary, and other object level properties, as well as how to incorporate these properties into actions and graphics.

Reliability, outOfService, statusFlags

These properties can be found by opening the Point Debug Info window for the point and scrolling to the bottom of the details pane.

image-20260123-202426.png

Useful functions

A couple useful functions can help you look up BACnet object types and property identifiers, including their names, short names, and corresponding integer values. These are especially helpful for the functions discussed in the following sections. Run these in Folio > Launch to get the results.

bacnetObjectTypeList() - Returns a list of all standard BACnet object types.
bacnetPropertyIdentifierList() - Returns a list of all standard BACnet property identifiers.

Read and Write functions

The platform provides several functions that allow users to directly read or write BACnet objects and their properties from the source device.

Available Functions
bacnetReadObject() - Reads a BACnet object, returning some common supported properties.
bacnetReadObjectProperty() - Reads a specific BACnet property from a given object.
bacnetWriteObjectProperty() - Writes a value to a specific BACnet property on a given object.

Below, we’ll explain each function in more detail, including arguments, and examples.

BACnet read object

Users can call bacnetReadObject() to view a list of common standard BACnet properties for an object, such as OBJECT_IDENTIFIER, OBJECT_NAME, PRESENT_VALUE, and others.

bacnetReadObject(conn,obj)

Parameters:
conn - The BACnet connector reference of the object used to query the device for its properties.
obj - The BACnet object to read. This can be one of the following:

  • A BACnet point record

  • A point Ref

  • A string formatted as "objectType:objectInstance" (e.g., "2:1", "AV1"). This can be copied from the bacnetCur found on the point.

Examples: Retrieve the properties of the Analog Input (AI) object instance 252.

bacnetReadObject(@p:test:r:31056c36-246e3f24, "AI252")
bacnetReadObject(@p:test:r:31056c36-246e3f24, "0:252")
bacnetReadObject(@p:test:r:31056c36-246e3f24, @p:test:r:31056c6a-88a14562)

image-20260123-211210.png

BACnet read object property

Users can call bacnetReadObjectProperty() to view a specific property of a BACnet object.

bacnetReadObjectProperty(conn,obj,prop,index)

Parameters:
conn - The BACnet connector reference of the object used to query the device for its properties.
obj - The BACnet object to read. This can be one of the following:

  • A BACnet point record

  • A point Ref

  • A string in "objectType:objectInstance" format (e.g., "2:1", "AV1"). This can be copied from the bacnetCur found on the point.

  • The special 'bacnetCur' form (see bacnetCur for details)

  • A @connRef when querying properties on the device object itself

prop - The property identifier. This may be provided as either:

  • An integer property ID (e.g., 85 for present_value)

  • A string property name (e.g., "object_name")

index (optional) - The array index for properties that contain array values. Important notes:

  • BACnet arrays are 1‑indexed.

  • Index 0 returns the length of the array.

Examples: Retrieve the present_value property (property ID 85) from the Analog Input (AI) object instance 252.

bacnetReadObjectProperty(@p:test:r:31056c36-246e3f24, "0:252", "present_value")
bacnetReadObjectProperty(@p:test:r:31056c36-246e3f24, "AI252", 85)

image-20260123-213818.png

Retrieve the relinquish_default property (property ID 104) from the Analog Output (AO) object instance 93.
bacnetReadObjectProperty(@p:test:r:31056c36-246e3f24, "AO93", "relinquish_default")

image-20260123-225137.png

BACnet write object property

The bacnetWriteObjectProperty() function allows users to write to a specific BACnet property using either a property ID or property name, with support for priority levels and optional array indexing.

bacnetWriteObjectProperty(conn,obj,prop,value,priority,index)

Parameters:
conn - The BACnet connector used to send the write request.
obj - The target BACnet object. This may be provided as:

  • A BACnet point record

  • A point Ref

  • A string in "objectType:objectInstance" format (e.g., "2:1", "AV1"). This can be copied from the bacnetCur found on the point.

  • The 'bacnetCur' form (see the bacnetCur documentation for details)

prop - The property to write. This may be provided as either:

  • Integer property ID (e.g., 85 for present_value)

  • String property name (e.g., "object_name", "present_value")

value - The value to write to the property. Supports standard BACnet data types, including complex encodings created with xstr().
priority (optional) - The BACnet write priority level.

  • Defaults to 16 (lowest priority).

  • Valid range: 1–16.

index (optional) - Array index for properties whose value is an array.

  • Defaults to null (write full property).

  • Remember:

    • BACnet arrays are 1‑indexed

    • Index 0 returns/affects the array length

Examples: Write to the present_value property (property ID 85) of the Binary Output (BO) object instance 134, Analog Output (AO) object instance 93, and Multistate Value (MSV) object instance 241.

Boolean/Binary point type:
bacnetWriteObjectProperty(@p:test:r:31056c36-246e3f24, "BO134", "present_value", true) //write true (default priority 16)
bacnetWriteObjectProperty(@p:test:r:31056c36-246e3f24, "4:134", 85, false) //write false (default priority 16)
bacnetWriteObjectProperty(@p:test:r:31056c36-246e3f24, @p:test:r:31056c71-b20a696e, "present_value", null) //release/null (default priority 16)
bacnetWriteObjectProperty(@p:test:r:31056c36-246e3f24, "BO134", 85, true, 14) //write true at priority 14

Number/Analog point type:
bacnetWriteObjectProperty(@p:test:r:31056c36-246e3f24, "1:93", "present_value", 100) //write 100 (default priority 16)
bacnetWriteObjectProperty(@p:test:r:31056c36-246e3f24, "AO93", 85, 1, 14) // write 1 at priority 14
bacnetWriteObjectProperty(@p:test:r:31056c36-246e3f24, @p:test:r:31056c6b-368e4323, "present_value", null, 14) //release/null at priority 14

Enum/Multistate point type:
bacnetWriteObjectProperty(@p:test:r:31056c36-246e3f24, "MSV241", "present_value", 1) //write 1 (numerical state) (default priority 16)

image-20260123-224917.png

This behavior applies to all BACnet properties. The examples below illustrate additional standard and proprietary properties.

  • Relinquish_Default: property ID 104, or 3113 on Johnson compatible devices.
    bacnetWriteObjectProperty(@p:test:r:31056c36-246e3f24, "AO93", "relinquish_default", 10)
    bacnetWriteObjectProperty(@p:test:r:31056c36-246e3f24, "AO93", 104, 100)

image-20260123-225513.png
  • COV_Increment: property ID 22.
    bacnetWriteObjectProperty(@p:test:r:31056c36-246e3f24, "AO93", "cov_increment", 1)
    bacnetWriteObjectProperty(@p:test:r:31056c36-246e3f24, "AO93", 22, 1)

image-20260123-230104.png

Cur and Write properties

Another method for reading or writing a specific BACnet property is to create a point that represents that property and use the BACnet Cur and BACnet Write paths.
Note: Each point created for this purpose consumes license capacity.

To use this approach, the user can either:

  • Navigate to an existing point that contains the desired BACnet property and duplicate it, or

  • Create a new point and manually assign the required tags.

The required tags are:

  • bacnetConnRef (Ref) - The ID of the BACnet connector the point belongs to.

  • bacnetCur (String) - “Cur Path” - Defines which BACnet property to read. It includes the objectTypeIdentifier, objectInstance, and propertyIdentifier in the following format: objectTypeIdentifier:objectInstance:propertyIdentifier

  • bacnetWrite (String - if applicable) - “Write Path” - Defines which BACnet property to write to (if writable). In most cases, this value is the same as bacnetCur.

If you copy an existing point, update the point type, unit, marker tags, and any other properties relevant to the new point.

Then a value change, or disable and re‑enable the BACnet connector to ensure the point syncs with the new configuration.

Examples:
Read and Write to the cov_increment property (property ID 22) of the Analog Output (AO) object instance 93.
BACnet Cur Path: 1:93:22
BACnet Write Path: 1:93:22

Read and Write to the relinquish_default property (property ID 104) of the Analog Output (AO) object instance 93.
BACnet Cur Path: 1:93:104
BACnet Cur Path: 1:93:104

Point actions

Based on the information above, users can incorporate bacnetWriteObjectProperty() into a point’s Actions to write to specific properties, priority levels, and more. You may add new Actions or modify existing ones as needed. If you require direct one‑to‑one writes, please refer to the 1‑for‑1 Writes documentation.

Keep in mind that Logic Builder, Schedules, and other applications that issue their own writes do not use Actions; instead, they perform their own internal point writes.

If the user wishes to customize their Actions, the following examples demonstrate common usage patterns.

Users can navigate to a point and click the dropdown icon next to the Actions property to edit it. From there, they can add new Actions or modify the existing ones.

image-20260123-234145.png

In Actions Example 1 below, bacnetWriteObjectProperty() is executed within a point’s Actions grid. The first two parameters dynamically reference the point’s own tags—bacnetConnRef and bacnetWrite—ensuring the function targets the correct BACnet object. The breakdown is as follows:

  • \$self->bacnetConnRef - The point’s own bacnetConnRef ID.

  • \$self->bacnetWrite - The point’s own bacnetWrite tag value (i.e., the BACnet object identifier such as "AV1").

  • toStr(present_value) or 85 - Either the BACnet property name as a string (e.g., "present_value"), or the BACnet property ID as an integer (e.g., 85 for present_value).

  • \$val - The value provided by the user when the Set action is executed.

These ensure that the write operation is dynamic and automatically applies to whichever point is executing the Action.

Actions Example 1

ver:"2.0" expr,dis "bacnetWriteObjectProperty(\$self->bacnetConnRef, \$self->bacnetWrite, toStr(`present_value`), \$val)", "Set"

Actions Example 2 - Numeric (string value for present value property)

ver:"3.0" dis,expr,hvac_finCat "Emergency Set","bacnetWriteObjectProperty((\$self)->bacnetConnRef, (\$self)->bacnetWrite, toStr(`present_value`), \$val, 1)",9 "Emergency Auto","bacnetWriteObjectProperty((\$self)->bacnetConnRef, (\$self)->bacnetWrite, toStr(`present_value`), null, 1)",9 "Manual Set","bacnetWriteObjectProperty((\$self)->bacnetConnRef, (\$self)->bacnetWrite, toStr(`present_value`), \$val, 8)",6 "Manual Auto","bacnetWriteObjectProperty((\$self)->bacnetConnRef, (\$self)->bacnetWrite, toStr(`present_value`), null, 8)",6 "Set Default","bacnetWriteObjectProperty((\$self)->bacnetConnRef, (\$self)->bacnetWrite, toStr(`present_value`), \$val, 16)",3 "Set Null","bacnetWriteObjectProperty((\$self)->bacnetConnRef, (\$self)->bacnetWrite, toStr(`present_value`), null, 16)",3

Actions Example 3 - Boolean (numerical value for present value property)

ver:"3.0" dis,expr,hvac_finCat "Emergency Active","bacnetWriteObjectProperty((\$self)->bacnetConnRef, (\$self)->bacnetWrite, 85, true, 1)",9 "Emergency Inactive","bacnetWriteObjectProperty((\$self)->bacnetConnRef, (\$self)->bacnetWrite, 85, false, 1)",9 "Emergency Auto","bacnetWriteObjectProperty((\$self)->bacnetConnRef, (\$self)->bacnetWrite, 85, null, 1)",9 "Manual On","bacnetWriteObjectProperty((\$self)->bacnetConnRef, (\$self)->bacnetWrite, 85, true, 8)",6 "Manual Off","bacnetWriteObjectProperty((\$self)->bacnetConnRef, (\$self)->bacnetWrite, 85, false, 8)",6 "Manual Auto","bacnetWriteObjectProperty((\$self)->bacnetConnRef, (\$self)->bacnetWrite, 85, null, 8)",6 "Set Default","bacnetWriteObjectProperty((\$self)->bacnetConnRef, (\$self)->bacnetWrite, 85, $val, 16)",3

Example: A custom action was added to command the cov_increment property of an existing point.

The original actions of a point:

ver:"3.0" dis,expr,hvac_finCat "Emergency Set","pointEmergencyOverride(\$self, \$val)",9 "Emergency Auto","pointEmergencyAuto(\$self)",9 "Manual Set","pointOverride(\$self, \$val, \$duration)",6 "Manual Auto","pointAuto(\$self)",6 "Set Default","pointSetDef(\$self, \$val)",3 "Set Null","pointSetDef(\$self, null)",3
image-20260126-200825.png

The new configuration:

ver:"3.0" dis,expr,hvac_finCat "Emergency Set","pointEmergencyOverride(\$self, \$val)",9 "Emergency Auto","pointEmergencyAuto(\$self)",9 "Manual Set","pointOverride(\$self, \$val, \$duration)",6 "Manual Auto","pointAuto(\$self)",6 "Set Default","pointSetDef(\$self, \$val)",3 "Set Null","pointSetDef(\$self, null)",3 "COV Increment Action","bacnetWriteObjectProperty(\$self->bacnetConnRef, \$self->bacnetWrite, toStr(`cov_increment`), \$val)",6
image-20260126-201119.png

The action name (e.g., “COV Increment Action”) is fully configurable and may be set to any user-defined value. The “cov_increment” field identifies the specific BACnet property to be commanded. Once configured, the action is available globally within the application wherever actions are supported.

Graphics

Sometimes a customer wants to display a BACnet property on a graphic and, if it’s writable, allow users to command it.

Read property

Below is an example showing how to read a BACnet property using the functions described earlier.
In this example, we’ll demonstrate reading the out_of_service property.

Follow the steps below to read any BACnet property in a graphic:

  1. Drag a Label component onto the graphic.

  2. Drag and drop the desired point containing the BACnet property you want to read from onto the label to create a binding.

  3. Delete the automatically added basicBinding tag on the label so it doesn’t conflict with the program logic.

  4. Add a tag to the label (e.g. bacReadProp) that will be used to trigger the program.

  5. Add an additional string tag, for example:

    • Tag name: bacProp

    • Tag value: the name of the BACnet property you want to read (e.g., out_of_service, cov_increment, present_value etc.)

  6. Create a program that listens to the custom tag. Use the bacReadProp tag as the program trigger.

  7. Click the (⋮) menu in the top right corner and open the Variables panel.

  8. Create a variable named POINT with the following configuration:

    • Filter: id == $virtualPointRef

    • Invoke on: Tag Change = *

  9. Paste the example code into your program.

    finstack.eval(`bacnetReadObjectProperty(${POINT.bacnetConnRef}, "${POINT.bacnetCur}", "${this.bacProp}")`) .then(data => { this.value = data.result.toObj()[0].value; }) .catch(error => { console.error("Error reading BACnet property:", error); });
  10. Save the program, then check the graphic to verify the value is being read correctly.

image-20260127-193856.png
image-20260127-193825.png

Write property

Below is an example showing how to write to a BACnet property using the functions described earlier.
In this example, we’ll demonstrate writing to the cov_increment property.

Follow the steps below to configure a graphic component (such as a button) that writes to a BACnet property.

In this example, the write value will be collected using the browser’s built‑in prompt window, which accepts:

  • Numbers

  • true / false

  • yes / no

  • 1 / 0

All of these will be converted appropriately for the BACnet write function.

  1. Drag a Button (or any component) onto the graphic to use as the write trigger.

  2. Drag and drop the point containing the BACnet property you want to write to onto the button to create a binding.

  3. Delete the automatically added basicBinding tag on the button so that it doesn’t conflict with the program logic.

  4. Add a tag to the button (e.g. bacWriteProp) that will be used to trigger the program.

  5. Add an additional string tag, for example:

    • Tag name: bacProp

    • Tag value: the name of the BACnet property you want to write to (e.g., out_of_service, cov_increment, present_value etc.)

  6. (Optional) If the target property supports command priorities, add:

    • Tag name: bacPriority

    • Tag value: Priority level (1–16)

  7. Create a program that listens to the custom tag. Use the bacWriteProp tag as the program trigger.

  8. Click the (⋮) menu in the top right corner and open the Variables panel.

  9. For the this variable, set it to invoke the program on:

    • Mouse Events → Click

  10. Create a variable named POINT with the following configuration:

    • Filter: id == $virtualPointRef

  11. Paste the example code into your program.

    const propertyName = this.bacProp || "BACnet property"; const userInput = prompt(`Enter value for property "${propertyName}":\n(Numbers, true/false, yes/no, 1/0)`); if (userInput !== null) { let axonValue; let parsedValue; const trimmedInput = userInput.trim().toLowerCase(); // Check for boolean values first (including 1/0) if (['true', 't', 'yes', 'y', 'on', '1'].includes(trimmedInput)) { parsedValue = true; axonValue = 'true'; } else if (['false', 'f', 'no', 'n', 'off', '0'].includes(trimmedInput)) { parsedValue = false; axonValue = 'false'; } // Then check for other numbers (not 1 or 0) else if (!isNaN(userInput) && userInput.trim() !== '' && !['1', '0'].includes(trimmedInput)) { parsedValue = parseFloat(userInput); axonValue = `n:${parsedValue}`; } else { alert("Invalid input. Please enter a number or boolean value (true/false, yes/no, 1/0)."); return; } // Build function call let functionCall; if (this.bacPriority !== undefined && this.bacPriority !== null) { functionCall = `bacnetWriteObjectProperty(${POINT.bacnetConnRef}, "${POINT.bacnetCur}", "${this.bacProp}", ${axonValue}, ${this.bacPriority})`; } else { functionCall = `bacnetWriteObjectProperty(${POINT.bacnetConnRef}, "${POINT.bacnetCur}", "${this.bacProp}", ${axonValue})`; } finstack.eval(functionCall) .then(data => { alert(`✅ Successfully wrote: ${parsedValue}`); console.log("Write successful:", data); }) .catch(error => { alert(`❌ Error: ${error.message}`); console.error("Error writing BACnet property:", error); }); }
  12. Save the program, then click the button in the graphic. A prompt window will appear, enter a value, and the write should execute successfully.

image-20260127-215020.png
image-20260127-215410.png
image-20260127-220022.png