migration from CODESYS BACnet (protocol revision 14/15) to CODESYS BACnet2 (protocol revision 25)

Significant effort had been spend to make migration from CODESYS BACnet (protocol revision 14/15) to CODESYS BACnet2 (protocol revision >=25) as easy as possible and to avoid unneccessary changes in application code. The goal was to allow a simple migration of a good part of existing CODESYS BACnet applications with a very small amount of code changes - or even without code changes.

On the other hand - releasing a new major version of a product is a good chance and also a commitment to cleanup API issues of older versions.

Migration from CODESYS BACnet (protocol revision 14/15) to CODESYS BACnet2 (protocol revision >=25) may require some application code changes described hereafter - depending on the API aspects used by the application.

Please also note: changing the BACnet protocol revision of an already certified BACnet device is not for free regarding the BACnet certificate - there is a need to BTL conformance testing and certification again, so in fact it turns out to be kind of a brand new BACnet device.

prerequisites for migration from CODESYS BACnet (protocol revision 14/15) to CODESYS BACnet2 (protocol revision 25)

As described in the “parts and pieces” section there is a need for the runtime component CmpBACnet to run CODESYS BACnet. CODESYS BACnet2 requires the runtime component CmpBACnet2 to be existent on the PLC and and to be configured appropriately. For details about CmpBACnet2 configuration please refer to the CODESYS BACnet2 online dcoumentation section “BACnet Configuration in the Runtime”.

modifications of application code required by type changes of “event STRUCTs”

CODESYS BACnet works with extensively with “hooks” and “callbacks” implemented using events and “event STRUCTs” EVT_BACNET_*. In CODESYS BACnet up to version 1.7.*.* (respectively in CmpBACnet used in conjuction with this older versions of CODESYS BACnet) those “event STRUCTs” had been manually created matching their BACnet-Stack counterparts in a binary-compatible way. This approach was rated to cumbersome and error prone, and had been replaced by generating them (CmpBACnet2.EVT_BACNET_*) from the BACnet-Stack information. Within the BACnet-Stack “protocol revision 25” some member names of “hook” / “callback” arguments had been changed for consistency (compared as with BACnet-Stack “protocol revision 14/15”). This leads to name changes on “event STRUCT” members thus forcing the need of changes in application code migrating from CODESYS BACnet 1.7.*.* to “CODESYS BACnet2”.

modifications of application code required by API change regarding problematic simultaneous property access

CODESYS BACnet up to version 1.7.*.* did a bit too much for convenience in some place, not taking all implications into account.

For the following object types exceptional “two properties simultaneous access” had been put in place, to write two properties simultaneously. The initial thought about this was to ensure consistency of the number of elements in both properties - which is required by the BACnet standard. This exceptional “two properties simultaneous access” had been implemented for:

  • “Command” (Object Type) properties Action and Action_Text

  • “Global Group” properties Group_Members and Group_Member_Names

  • “Structured View” (Object Type) properties Subordinate_List and Subordinate_Annotations

not taking into account:

  • the second property is stated “optional” in the BACnet standard, so can be configured “not existent” if needed rendering the API broken

  • clients might write those properties using simple write-property-requests (instead write-property-multiple-requests) so for sure breaking the consistency of number of elements at least for a certain slot in time. Getting a value with “two properties simultaneous access” API will fail on that.

In fact this “two properties simultaneous access” had been meant to be a convenience, but turned out to be a hazzle. So it had been replaced by standard “property access” API thus forcing the need of changes in application code migrating from CODESYS BACnet 1.7.*.* to “CODESYS BACnet2”.

modifications of application code required by API changes done for consistency cleanup

As explained in section “application programming interface” -> “BACnet objects” the “property access” is using data types defined in CmpBACnet2 in most cases, only some aspects of “property access” use IEC-61311 standard types for convenience. This rule had not been obeyed in CODESYS BACnet up to version 1.7.*.* in some places and had been cleaned up for consistency:

  • “Device object” properties Last_Restore_Time and Time_Of_Device_Restart used type BACnetTimeStamp (instead CmpBACnet.IEC_BACNET_TIME_STAMP)

    to provide some convenience, but breaking consistency with other properties of type CmpBACnet.IEC_BACNET_TIME_STAMP. So both properties had beed changed to CmpBACnet.IEC_BACNET_TIME_STAMP, please use conversion functions InitializeBACnetTimeStamp and FromBACnetTimeStamp if needed. Most likely your application should not contain code related to those properties, because BAcnetDefaultImpl.library provides the necessary functionality ready-to-use in BackupRestore, DeviceDateTime and ReinitDevice_SvcAppHook.

  • BACnetDeviceObjectPropertyReference vs. CmpBACnet.IEC_BACNET_DEV_OBJ_PROP_REFERENCE

    Some object / property combination used BACnetDeviceObjectPropertyReference instead CmpBACnet.IEC_BACNET_DEV_OBJ_PROP_REFERENCE for a little convenience, declaring BACnetDeviceObjectPropertyReference.fDevicePresent as BOOL instead IEC_BACNET_DEV_OBJ_PROP_REFERENCE.fDevicePresent as IEC_BACNET_BOOLEAN. BACnetDeviceObjectPropertyReference had been removed from the API and had been replace by CmpBACnet.IEC_BACNET_DEV_OBJ_PROP_REFERENCE in

    • “Averaging” Object_Property_Reference

    • “Global Group” Group_Members (modifications of application code needed also because of “problematic simultaneous property access” see above)

    • “Event Enrollment” Object_Property_Reference

    • “Schedule” List_Of_Object_Property_References

    • “Trend Log” Log_DeviceObjectProperty

    • “Trend Log Multiple” Log_DeviceObjectProperty

  • BACnetARRAY[] of and BACnetLIST of properties API cleanup

    In CODESYS BACnet up to version 1.7.*.* property access of BACnetARRAY[] of and BACnetLIST of properties had been inconsistent, confusing container type (array vs. list) access semantics and naming - this was to be cleaned up. The old property access had been kept for compatibility if possible and marked {attribute ‘obsolete’…} so you might notice warnings. Those “compatibility alias” parts of the API will be removed in future versions, so you better cleanup your application code early on.

    Also index-based operations had been confused within CODESYS BACnet up to version 1.7.*.*. The BACnet-Standard defines that BACnetARRAY[] of contains the number of elements in the array in element[0] as UNSIGNED, so element access is using index 1 .. number of elements at the wire. The BACnet-Standard doesnt define index-based operations for BACnetLIST of. CODESYS BACnet up to version 1.7.*.* tried to implement index-based operations for some BACnetLIST of properties at extreme costs. Those costs result from two apects:

    • to get an element from a BACnetLIST of property the whole content had to be retreived and the element had to be extracted

    • if the BACnetLIST of property is of complex type containing SEQUENCE’s the whole content data had to be stored away until application code did a |FreeStackAllocatedMemory| of the element data, because the element data refer to data contained in the whole content data

    As with CODESYS BACnet2 this approach had been changed to cleanup the API:

    • index-based operations do use index 0 .. number of elements - 1 consistently for BACnetARRAY[] of and BACnetLIST of properties

    • the number of elements can be obtained using GetCount()

    • BACnetLIST of properties doesnt provide GetElement() semantics

    • most API METHODs of CODESYS BACnet API up to version 1.7.*.* dealing with BACnetARRAY[] of and BACnetLIST of properties had been marked as {attribute ‘obsolete’…} - you should replace those calls with the mentioned replacement, they still compile and work properly for now, but will be removed in future versions.

    • API METHODs of CODESYS BACnet API up to version 1.7.*.* dealing with BACnetLIST of getElement semantics had been removed without any substitute. Use GetContent() to get the whole content data and process this appropriatly.

    Most parts of the API of CODESYS BACnet up to version 1.7.*.* plagued with this issues could be redirected to the new API. Those parts had been marked as {attribute ‘obsolete’…} - you should replace those calls with the mentioned replacement, they still compile and work properly for now, but will be removed in future versions.

    Unfortunatley one part of the parts of the API of CODESYS BACnet up to version 1.7.*.* plagued with this issues could not be saved this way, so Calendar.GetEntry was removed - use Calendar.GetContent and work this way.

API differences between CODESYS BACnet up to version 1.7.*.* and CODESYS BACnet2

Here the list of changes which require modifications of application code caused by API cleanup (sorted by function block / property / method):

  • Averaging.ObjectPropertyReference type changed from BACnetDevObjPropReference to CmpBACnet.IEC_BACNET_DEV_OBJ_PROP_REFERENCE

  • Calendar.GetEntry removed - use Calendar.GetContent and process property content accordingly

  • Device.LastRestoreTime type changed from BACnetTimeStamp to CmpBACnet.IEC_BACNET_TIME_STAMP

  • Device.SerialNumber type changed from STRING to WSTRING(255)

  • Device.TimeOfDeviceRestart type changed from BACnetTimeStamp to CmpBACnet.IEC_BACNET_TIME_STAMP

  • Device.GetAutoSlaveDiscovery removed because this property was removed from the BACnet-Standard

  • Device.GetManualSlaveAddressBinding removed because this property was removed from the BACnet-Standard

  • Device.GetSlaveAddressBinding removed because this property was removed from the BACnet-Standard

  • Device.GetSlaveProxyEnable removed because this property was removed from the BACnet-Standard

  • Device.SetAutoSlaveDiscovery removed because this property was removed from the BACnet-Standard

  • Device.SetManualSlaveAddressBinding removed because this property was removed from the BACnet-Standard

  • Device.SetSlaveAddressBinding removed because this property was removed from the BACnet-Standard

  • Device.SetSlaveProxyEnable removed because this property was removed from the BACnet-Standard

  • EventEnrollment.ObjectPropertyReference type changed from BACnetDevObjPropReference to CmpBACnet.IEC_BACNET_DEV_OBJ_PROP_REFERENCE

  • Schedule.GetPropertyReference removed - use ObjectPropertyReferences.GetContent and process property content accordingly

  • Schedule.AddWeeklyEntry removed - use WeeklySchedule accordingly

  • Schedule.GetWeeklyEntry removed - use WeeklySchedule accordingly

  • Schedule.GetWeeklyEntryCount removed - use WeeklySchedule accordingly

  • Schedule.GetWeeklySchedule removed - use WeeklySchedule accordingly

  • Schedule.RemoveWeeklyEntry removed - use WeeklySchedule accordingly

  • TrendLog.LogDeviceObjectProperty type changed from BACnetDevObjPropReference to CmpBACnet.IEC_BACNET_DEV_OBJ_PROP_REFERENCE

Please be aware, that additional parts of CODESYS BACnet API up to version 1.7.*.* had be marked as {attribute ‘obsolete’…}. You should replace calls to those methods or properties with the replacement mentioned - they still compile and work properly for now, but will be removed in future versions.

hint regarding BACnetARRAY[N] ordering

CODESYS BACnet up to version 1.7.*.* ignored the fact that the BACnet standard states, that a “BACnetARRAY” datatype is a structured datatype consisting of an ordered sequence of data elements, each having the same datatype. So the sematic Get??? / Get???Count / Add??? (to end of array) / Remove??? (at given position) chosen in older versions of CODESYS BACnet did not fullfill the BACnet standard completely. For most pratical use this was relevant, but had to cleaned up as with “CODESYS BACnet2” - so a method Insert??? had been added. Please consider using this method if array element ordering is of any relevance for your application.