All devices on a BACNet network are effectively peers. This means that any device (we take device here to mean any Bacnet capable entity – device or software application) can write to the writable properties of another device’s objects. This can result in conflicting commands.
BACnet has a mechanism to resolve the conflict. It differentiates between writable and commandable properties and the conflict resolution only applies to commandable properties. For writable ( and non-commandable properties) the last write wins and overwrites any previous writes – there is no conflict resolution.
Which properties are commandable and how does the command resolution work ?
• The Present Value of AO, BO, MO objects are always commandable.
• The Present Value of AV, BV, MV objects are commandable if the vendor implemented them that way. It’s a vendor choice. You can tell what choice they made by looking for the Priority_Array and Relinquish_Default properties on the object. That’s a clue but not a guarantee (we have found). Last resort is their documentation. (good luck).
• A vendor may choose to make any vendor (proprietary) property commandable. If a property is commandable then it is required to have appropriately named Priority_Array and Relinquish_Default properties.
If an object has a Present Value that is commandable then it also has two additional properties ; Priority Array and Relinquish Default. These two properties are used to resolve command conflicts.
When a write is sent to a commandable point it always contains a priority. If the priority is not specified then the priority is assumed to be the lowest. There are 16 priorities. 16 is the lowest. On restart each slot in the array is set to a Null (unused) state. When the command is received the BACnet device updates the slot in the Priority Array that corresponds to the commanded priority with the new value.
The device continuously looks thru the priority array of each commandable property and looks for the highest priority slot that is non Null. It uses that value to update the Present Value. Now its easy to understand why the command you sent to an objects Present Value has no effect. You may have commanded with a priority lower than the one currently in use.
How to you empty a priority slot ? You send a command to the point to relinquish (give up control). This is like a normal command – its specifies a value ( a special value – Null ) and a priority. The device frees the Priority Array slot that corresponds to the relinquished priority. There are 3 possible outcomes to a relinquish – 1) There is no change to the Present Value because the relinquished priority is lower than the one in use 2) The Present Value changes because the relinquished command was at a higher priority than another commanded value. 3) All the Priority Array slots are now Null (unused). In this case the device uses the value of the Relinquish Default property to set the value of the present value.
What happens if two remotes device command at the same priority ? The last command wins, overwriting the value in the Priority Array for the given priority ? The same applies to relinquishing – the first relinquisher wins. How do you avoid this ? Assign different devices, application or functions different priorities. These choices are site specific. BACnet does names the priorities to suggest a use but how they are used is up to you – the implementor.
Some Objects that have commandable Present Values also have properties that define a minimum on and/or off time. When either of these are present it could affect the outcome of the write you send to the Present Value. A full description of this behavior will be provided in a subsequent article.
The Relinquish Default Value is set by the device. The Vendor may choose to make it a writable property in which case in can be changed remotely. Even though the present value is commanded the device stores the commanded value in the priority array and uses the highest priority array slot to set the Present Value.
In our example, the device boots, the Priority array slots are all Null (Unused) and this vendor has set the Relinquish Default to 50. Since all the slots are null the device sets the Present Value to the Relinquish Default Value. The Present Value changes to 50.
Now a command is sent to set this objects Present Value to 45 at Priority 5. The device sets slot 5 in the Priority Array to 45. It then starts at the highest priority (1) and looks for the 1st non Null slot. It finds slot 5 filled with 45 and sets the Present Value to 45.
Now a new command is sent to set this objects Present Value to 70 at Priority 8. The device sets slot 8 in the Priority Array to 70 . It then starts at the highest priority (1) and looks for the 1st non Null slot. It finds slot 5 filled with 45. Thus there is no change to the Present Value to 45.
Now a command is sent to Relinquish the command at Priority 5. One would hope that the device that sent the original command sent the relinquish command but that is up to you and how you configured you system. When the relinquish command is received, the device sets the corresponding slot in the Priority Array to Null. The device then starts at the highest priority (1) and looks for the 1st non Null slot. The device finds slot 8 filled with 70. It changes the Present Value to 70.
The most recent command at a specific priority wins. Here a command is sent to set the Present Value to 80 at priority 8. The device overrides slot 8 in the array with the new value. In this case it is also the highest priority slot that is used so the device updates the Present Value to 80.
Finally, a command is sent to relinquish the command at priority 8. Slot 8 is set to Null and when the device looks through the priorty array it finds it all empty and it thus uses the Relinquish Default value to set the Present Value to 50.
This mechanism can be complicated if the object has minimum on/off times.