Device Management¶
Service Base¶
Service handler registration and dispatch per ASHRAE 135-2016.
- type bac_py.services.base.ConfirmedHandler = Callable[[int, bytes, BACnetAddress], Awaitable[bytes | None]]¶
- type bac_py.services.base.UnconfirmedHandler = Callable[[int, bytes, BACnetAddress], Awaitable[None]]¶
- class bac_py.services.base.ServiceRegistry[source]¶
Bases:
objectRegistry for BACnet service request handlers.
Maps service choice numbers to handler coroutines for both confirmed and unconfirmed services.
- register_unconfirmed(service_choice, handler)[source]¶
Register a handler for an unconfirmed service.
- async dispatch_confirmed(service_choice, request_data, source)[source]¶
Dispatch an incoming confirmed request to its handler.
- Parameters:
service_choice (
int) – Confirmed service choice number.request_data (
bytes) – Raw service request bytes.source (
BACnetAddress) – Source address of the request.
- Return type:
- Returns:
Service ACK data for ComplexACK, or
Nonefor SimpleACK.- Raises:
BACnetRejectError – If no handler is registered for the service.
- async dispatch_unconfirmed(service_choice, request_data, source)[source]¶
Dispatch an incoming unconfirmed request to its handler.
If no handler is registered for service_choice, the request is silently ignored (per Clause 5.4.2 – no reject/abort is sent for unconfirmed services).
- Parameters:
service_choice (
int) – Unconfirmed service choice number.request_data (
bytes) – Raw service request bytes.source (
BACnetAddress) – Source address of the request.
- Return type:
Common Types¶
Shared BACnet service data types per ASHRAE 135-2016 Clause 21.
- class bac_py.services.common.BACnetPropertyValue(property_identifier, property_array_index=None, value=b'', priority=None)[source]¶
Bases:
objectBACnetPropertyValue per Clause 21.
BACnetPropertyValue ::= SEQUENCE { propertyIdentifier [0] BACnetPropertyIdentifier, propertyArrayIndex [1] Unsigned OPTIONAL, value [2] ABSTRACT-SYNTAX.&Type, priority [3] Unsigned (1..16) OPTIONAL }
The
valuefield contains raw application-tagged bytes.- Parameters:
property_identifier (PropertyIdentifier)
property_array_index (int | None)
value (bytes)
priority (int | None)
- property_identifier: PropertyIdentifier¶
- encode()[source]¶
Encode BACnetPropertyValue.
- Return type:
- Returns:
Encoded bytes for this property value sequence.
- classmethod decode_from(data, offset=0)[source]¶
Decode BACnetPropertyValue from data at a given offset.
- Parameters:
data (
memoryview|bytes) – Raw bytes containing encoded property value data.offset (
int(default:0)) – Byte offset to start decoding from.
- Return type:
- Returns:
Tuple of (decoded
BACnetPropertyValue, new offset).- Raises:
BACnetRejectError – If priority is outside the 1–16 range.
Errors¶
BACnet protocol error types per ASHRAE 135-2016 Clause 18.
- exception bac_py.services.errors.BACnetBaseError[source]¶
Bases:
ExceptionBase exception for BACnet protocol errors.
- exception bac_py.services.errors.BACnetError(error_class, error_code, error_data=b'')[source]¶
Bases:
BACnetBaseErrorBACnet Error-PDU received (Clause 18).
Contains error class and code per the specification.
- Parameters:
error_class (ErrorClass)
error_code (ErrorCode)
error_data (bytes)
- Return type:
None
- exception bac_py.services.errors.BACnetRejectError(reason)[source]¶
Bases:
BACnetBaseErrorBACnet Reject-PDU received (Clause 18.9).
Indicates a syntax or protocol error in the request.
- Parameters:
reason (RejectReason)
- Return type:
None
- exception bac_py.services.errors.BACnetAbortError(reason)[source]¶
Bases:
BACnetBaseErrorBACnet Abort-PDU received (Clause 18.10).
Indicates the transaction was aborted.
- Parameters:
reason (AbortReason)
- Return type:
None
- exception bac_py.services.errors.BACnetTimeoutError[source]¶
Bases:
BACnetBaseErrorRequest timed out after all retries exhausted.
Device Management¶
Device management services per ASHRAE 135-2016 Clause 16.
DeviceCommunicationControl (Clause 16.1), ReinitializeDevice (Clause 16.4), TimeSynchronization (Clause 16.7), and UTCTimeSynchronization (Clause 16.8).
- class bac_py.services.device_mgmt.DeviceCommunicationControlRequest(enable_disable, time_duration=None, password=None)[source]¶
Bases:
objectDeviceCommunicationControl-Request (Clause 16.1.1).
DeviceCommunicationControl-Request ::= SEQUENCE { timeDuration [0] Unsigned16 OPTIONAL, enable-disable [1] ENUMERATED, password [2] CharacterString (1..20) OPTIONAL }
- Parameters:
enable_disable (EnableDisable)
time_duration (int | None)
password (str | None)
- enable_disable: EnableDisable¶
- encode()[source]¶
Encode DeviceCommunicationControl-Request service parameters.
- Return type:
- Returns:
Encoded service request bytes.
- classmethod decode(data)[source]¶
Decode DeviceCommunicationControl-Request from service request bytes.
- Parameters:
data (
memoryview|bytes) – Raw service request bytes.- Return type:
- Returns:
Decoded
DeviceCommunicationControlRequest.- Raises:
BACnetRejectError – If a parameter is out of range.
- class bac_py.services.device_mgmt.ReinitializeDeviceRequest(reinitialized_state, password=None)[source]¶
Bases:
objectReinitializeDevice-Request (Clause 16.4.1).
ReinitializeDevice-Request ::= SEQUENCE { reinitializedStateOfDevice [0] ENUMERATED, password [1] CharacterString (1..20) OPTIONAL }
- Parameters:
reinitialized_state (ReinitializedState)
password (str | None)
- reinitialized_state: ReinitializedState¶
- encode()[source]¶
Encode ReinitializeDevice-Request service parameters.
- Return type:
- Returns:
Encoded service request bytes.
- classmethod decode(data)[source]¶
Decode ReinitializeDevice-Request from service request bytes.
- Parameters:
data (
memoryview|bytes) – Raw service request bytes.- Return type:
- Returns:
Decoded
ReinitializeDeviceRequest.- Raises:
BACnetRejectError – If the password is out of range.
- class bac_py.services.device_mgmt.TimeSynchronizationRequest(date, time)[source]¶
Bases:
objectTimeSynchronization-Request (Clause 16.7.1).
TimeSynchronization-Request ::= SEQUENCE { date Date, time Time }
Both fields are APPLICATION-tagged (not context).
- Parameters:
date (BACnetDate)
time (BACnetTime)
- date: BACnetDate¶
- time: BACnetTime¶
- encode()[source]¶
Encode TimeSynchronization-Request service parameters.
- Return type:
- Returns:
Encoded service request bytes.
- classmethod decode(data)[source]¶
Decode TimeSynchronization-Request from service request bytes.
- Parameters:
data (
memoryview|bytes) – Raw service request bytes.- Return type:
Self- Returns:
Decoded request instance.
- class bac_py.services.device_mgmt.UTCTimeSynchronizationRequest(date, time)[source]¶
Bases:
TimeSynchronizationRequestUTCTimeSynchronization-Request (Clause 16.8.1).
Same structure as TimeSynchronizationRequest but uses UnconfirmedServiceChoice.UTC_TIME_SYNCHRONIZATION (9).
- Parameters:
date (BACnetDate)
time (BACnetTime)
Object Management¶
Object management services per ASHRAE 135-2016 Clause 15.3-15.4.
CreateObject (Clause 15.3), DeleteObject (Clause 15.4).
- class bac_py.services.object_mgmt.CreateObjectRequest(object_type=None, object_identifier=None, list_of_initial_values=None)[source]¶
Bases:
objectCreateObject-Request (Clause 15.3.1.1).
CreateObject-Request ::= SEQUENCE { objectSpecifier [0] CHOICE { objectType [0] BACnetObjectType, objectIdentifier [1] BACnetObjectIdentifier }, listOfInitialValues [1] SEQUENCE OF BACnetPropertyValue OPTIONAL }
- Parameters:
object_type (ObjectType | None)
object_identifier (ObjectIdentifier | None)
list_of_initial_values (list[BACnetPropertyValue] | None)
- object_type: ObjectType | None¶
- object_identifier: ObjectIdentifier | None¶
- list_of_initial_values: list[BACnetPropertyValue] | None¶
- encode()[source]¶
Encode CreateObject-Request service parameters.
- Return type:
- Returns:
Encoded service request bytes.
- classmethod decode(data)[source]¶
Decode CreateObject-Request from service request bytes.
- Parameters:
data (
memoryview|bytes) – Raw service request bytes.- Return type:
- Returns:
Decoded
CreateObjectRequest.- Raises:
ValueError – If the objectSpecifier CHOICE tag is unrecognized.
- class bac_py.services.object_mgmt.DeleteObjectRequest(object_identifier)[source]¶
Bases:
objectDeleteObject-Request (Clause 15.4.1.1).
DeleteObject-Request ::= SEQUENCE { objectIdentifier BACnetObjectIdentifier }
The objectIdentifier is APPLICATION-tagged.
- Parameters:
object_identifier (ObjectIdentifier)
- object_identifier: ObjectIdentifier¶
- encode()[source]¶
Encode DeleteObject-Request service parameters.
- Return type:
- Returns:
Encoded service request bytes.
- classmethod decode(data)[source]¶
Decode DeleteObject-Request from service request bytes.
- Parameters:
data (
memoryview|bytes) – Raw service request bytes.- Return type:
- Returns:
Decoded
DeleteObjectRequest.
List Element¶
List element services per ASHRAE 135-2016 Clause 15.1-15.2.
AddListElement (Clause 15.1), RemoveListElement (Clause 15.2).
- class bac_py.services.list_element.AddListElementRequest(object_identifier, property_identifier, list_of_elements, property_array_index=None)[source]¶
Bases:
_ListElementRequestAddListElement-Request (Clause 15.1.1.1).
- Parameters:
object_identifier (ObjectIdentifier)
property_identifier (PropertyIdentifier)
list_of_elements (bytes)
property_array_index (int | None)
- class bac_py.services.list_element.RemoveListElementRequest(object_identifier, property_identifier, list_of_elements, property_array_index=None)[source]¶
Bases:
_ListElementRequestRemoveListElement-Request (Clause 15.2.1.1).
- Parameters:
object_identifier (ObjectIdentifier)
property_identifier (PropertyIdentifier)
list_of_elements (bytes)
property_array_index (int | None)
File Access¶
Atomic file access services per ASHRAE 135-2016 Clause 14.
AtomicReadFile (Clause 14.1), AtomicWriteFile (Clause 14.2).
- class bac_py.services.file_access.StreamReadAccess(file_start_position, requested_octet_count)[source]¶
Bases:
objectStream access parameters for AtomicReadFile-Request.
- class bac_py.services.file_access.RecordReadAccess(file_start_record, requested_record_count)[source]¶
Bases:
objectRecord access parameters for AtomicReadFile-Request.
- class bac_py.services.file_access.AtomicReadFileRequest(file_identifier, access_method)[source]¶
Bases:
objectAtomicReadFile-Request (Clause 14.1.1.1).
AtomicReadFile-Request ::= SEQUENCE { fileIdentifier BACnetObjectIdentifier, accessMethod CHOICE { streamAccess [0] SEQUENCE { fileStartPosition INTEGER, requestedOctetCount Unsigned }, recordAccess [1] SEQUENCE { fileStartRecord INTEGER, requestedRecordCount Unsigned } } }
- Parameters:
file_identifier (ObjectIdentifier)
access_method (StreamReadAccess | RecordReadAccess)
- file_identifier: ObjectIdentifier¶
- access_method: StreamReadAccess | RecordReadAccess¶
- encode()[source]¶
Encode AtomicReadFile-Request service parameters.
- Return type:
- Returns:
Encoded service request bytes.
- classmethod decode(data)[source]¶
Decode AtomicReadFile-Request from service request bytes.
- Parameters:
data (
memoryview|bytes) – Raw service request bytes.- Return type:
- Returns:
Decoded
AtomicReadFileRequest.- Raises:
ValueError – If the access method CHOICE tag is unrecognized.
- class bac_py.services.file_access.StreamReadACK(file_start_position, file_data)[source]¶
Bases:
objectStream access result for AtomicReadFile-ACK.
- class bac_py.services.file_access.RecordReadACK(file_start_record, returned_record_count, file_record_data)[source]¶
Bases:
objectRecord access result for AtomicReadFile-ACK.
- class bac_py.services.file_access.AtomicReadFileACK(end_of_file, access_method)[source]¶
Bases:
objectAtomicReadFile-ACK (Clause 14.1.1.2).
AtomicReadFile-ACK ::= SEQUENCE { endOfFile BOOLEAN, accessMethod CHOICE { streamAccess [0] SEQUENCE { fileStartPosition INTEGER, fileData OCTET STRING }, recordAccess [1] SEQUENCE { fileStartRecord INTEGER, returnedRecordCount Unsigned, fileRecordData SEQUENCE OF OCTET STRING } } }
- Parameters:
end_of_file (bool)
access_method (StreamReadACK | RecordReadACK)
- access_method: StreamReadACK | RecordReadACK¶
- encode()[source]¶
Encode AtomicReadFile-ACK service parameters.
- Return type:
- Returns:
Encoded service ACK bytes.
- classmethod decode(data)[source]¶
Decode AtomicReadFile-ACK from service ACK bytes.
- Parameters:
data (
memoryview|bytes) – Raw service ACK bytes.- Return type:
- Returns:
Decoded
AtomicReadFileACK.- Raises:
ValueError – If the access method CHOICE tag is unrecognized.
- class bac_py.services.file_access.StreamWriteAccess(file_start_position, file_data)[source]¶
Bases:
objectStream access parameters for AtomicWriteFile-Request.
- class bac_py.services.file_access.RecordWriteAccess(file_start_record, record_count, file_record_data)[source]¶
Bases:
objectRecord access parameters for AtomicWriteFile-Request.
- class bac_py.services.file_access.AtomicWriteFileRequest(file_identifier, access_method)[source]¶
Bases:
objectAtomicWriteFile-Request (Clause 14.2.1.1).
AtomicWriteFile-Request ::= SEQUENCE { fileIdentifier BACnetObjectIdentifier, accessMethod CHOICE { streamAccess [0] SEQUENCE { fileStartPosition INTEGER, fileData OCTET STRING }, recordAccess [1] SEQUENCE { fileStartRecord INTEGER, recordCount Unsigned, fileRecordData SEQUENCE OF OCTET STRING } } }
- Parameters:
file_identifier (ObjectIdentifier)
access_method (StreamWriteAccess | RecordWriteAccess)
- file_identifier: ObjectIdentifier¶
- access_method: StreamWriteAccess | RecordWriteAccess¶
- encode()[source]¶
Encode AtomicWriteFile-Request service parameters.
- Return type:
- Returns:
Encoded service request bytes.
- classmethod decode(data)[source]¶
Decode AtomicWriteFile-Request from service request bytes.
- Parameters:
data (
memoryview|bytes) – Raw service request bytes.- Return type:
- Returns:
Decoded
AtomicWriteFileRequest.- Raises:
ValueError – If the access method CHOICE tag is unrecognized.
- class bac_py.services.file_access.AtomicWriteFileACK(is_stream, file_start)[source]¶
Bases:
objectAtomicWriteFile-ACK (Clause 14.2.1.2).
AtomicWriteFile-ACK ::= CHOICE { fileStartPosition [0] INTEGER, fileStartRecord [1] INTEGER }
- encode()[source]¶
Encode AtomicWriteFile-ACK service parameters.
- Return type:
- Returns:
Encoded service ACK bytes.
- classmethod decode(data)[source]¶
Decode AtomicWriteFile-ACK from service ACK bytes.
- Parameters:
data (
memoryview|bytes) – Raw service ACK bytes.- Return type:
- Returns:
Decoded
AtomicWriteFileACK.
Private Transfer¶
Private transfer services per ASHRAE 135-2016 Clause 16.2-16.3.
ConfirmedPrivateTransfer (Clause 16.2), UnconfirmedPrivateTransfer (Clause 16.3).
- class bac_py.services.private_transfer.ConfirmedPrivateTransferRequest(vendor_id, service_number, service_parameters=None)[source]¶
Bases:
objectConfirmedPrivateTransfer-Request (Clause 16.2.1.1).
ConfirmedPrivateTransfer-Request ::= SEQUENCE { vendorID [0] Unsigned, serviceNumber [1] Unsigned, serviceParameters [2] ABSTRACT-SYNTAX.&TYPE OPTIONAL }
- encode()[source]¶
Encode ConfirmedPrivateTransfer-Request service parameters.
- Return type:
- Returns:
Encoded service request bytes.
- classmethod decode(data)[source]¶
Decode ConfirmedPrivateTransfer-Request from service request bytes.
- Parameters:
data (
memoryview|bytes) – Raw service request bytes.- Return type:
Self- Returns:
Decoded request instance.
- class bac_py.services.private_transfer.ConfirmedPrivateTransferACK(vendor_id, service_number, result_block=None)[source]¶
Bases:
objectConfirmedPrivateTransfer-ACK (Clause 16.2.1.2).
Uses the same wire format as the request, but the context-2 tagged block carries vendor-defined result data rather than request service-parameters.
- encode()[source]¶
Encode ConfirmedPrivateTransfer-ACK service parameters.
- Return type:
- Returns:
Encoded service ACK bytes.
- classmethod decode(data)[source]¶
Decode ConfirmedPrivateTransfer-ACK from service ACK bytes.
- Parameters:
data (
memoryview|bytes) – Raw service ACK bytes.- Return type:
- Returns:
Decoded
ConfirmedPrivateTransferACK.
- class bac_py.services.private_transfer.UnconfirmedPrivateTransferRequest(vendor_id, service_number, service_parameters=None)[source]¶
Bases:
ConfirmedPrivateTransferRequestUnconfirmedPrivateTransfer-Request (Clause 16.3.1.1).
Same structure as ConfirmedPrivateTransfer-Request.
Virtual Terminal¶
Virtual terminal services per ASHRAE 135-2020 Clause 17.
VT-Open (Clause 17.1), VT-Close (Clause 17.2), VT-Data (Clause 17.3).
- class bac_py.services.virtual_terminal.VTOpenRequest(vt_class, local_vt_session_identifier)[source]¶
Bases:
objectVT-Open-Request (Clause 17.1.1).
VT-Open-Request ::= SEQUENCE { vtClass BACnetVTClass, localVTSessionIdentifier Unsigned8 }
- classmethod decode(data)[source]¶
Decode VT-Open-Request from service request bytes.
- Return type:
- Parameters:
data (memoryview | bytes)
- class bac_py.services.virtual_terminal.VTOpenACK(remote_vt_session_identifier)[source]¶
Bases:
objectVT-Open-ACK (Clause 17.1.2).
VT-Open-ACK ::= SEQUENCE { remoteVTSessionIdentifier Unsigned8 }
- Parameters:
remote_vt_session_identifier (int)
- classmethod decode(data)[source]¶
Decode VT-Open-ACK from service request bytes.
- Return type:
- Parameters:
data (memoryview | bytes)
- class bac_py.services.virtual_terminal.VTCloseRequest(list_of_remote_vt_session_identifiers)[source]¶
Bases:
objectVT-Close-Request (Clause 17.2.1).
VT-Close-Request ::= SEQUENCE { listOfRemoteVTSessionIdentifiers SEQUENCE OF Unsigned8 }
- classmethod decode(data)[source]¶
Decode VT-Close-Request from service request bytes.
- Return type:
- Parameters:
data (memoryview | bytes)
- class bac_py.services.virtual_terminal.VTDataRequest(vt_session_identifier, vt_new_data, vt_data_flag)[source]¶
Bases:
objectVT-Data-Request (Clause 17.3.1).
VT-Data-Request ::= SEQUENCE { vtSessionIdentifier Unsigned8, vtNewData OCTET STRING, vtDataFlag BOOLEAN }
- classmethod decode(data)[source]¶
Decode VT-Data-Request from service request bytes.
- Return type:
- Parameters:
data (memoryview | bytes)
- class bac_py.services.virtual_terminal.VTDataACK(all_new_data_accepted, accepted_octet_count=None)[source]¶
Bases:
objectVT-Data-ACK (Clause 17.3.2).
VT-Data-ACK ::= SEQUENCE { allNewDataAccepted BOOLEAN, acceptedOctetCount Unsigned OPTIONAL }
accepted_octet_countis present only whenall_new_data_acceptedisFalse.- classmethod decode(data)[source]¶
Decode VT-Data-ACK from service request bytes.
- Return type:
- Parameters:
data (memoryview | bytes)
Write Group¶
WriteGroup service per ASHRAE 135-2020 Clause 15.11.
WriteGroup is an unconfirmed service for writing channel values via group addressing.
- class bac_py.services.write_group.GroupChannelValue(channel, value, overriding_priority=None)[source]¶
Bases:
objectA single channel value in a WriteGroup change list.
GroupChannelValue ::= SEQUENCE { channel [0] Unsigned16, overridingPriority [1] Unsigned (1..16) OPTIONAL, value ABSTRACT-SYNTAX.&TYPE }
- classmethod decode(data, offset)[source]¶
Decode a single GroupChannelValue starting at offset.
- Return type:
- Returns:
Tuple of (decoded value, new offset).
- Parameters:
data (memoryview)
offset (int)
- class bac_py.services.write_group.WriteGroupRequest(group_number, write_priority, change_list)[source]¶
Bases:
objectWriteGroup-Request (Clause 15.11.1).
WriteGroup-Request ::= SEQUENCE { groupNumber [0] Unsigned32, writePriority [1] Unsigned (1..16), changeList [2] SEQUENCE OF GroupChannelValue }
- Parameters:
group_number (int)
write_priority (int)
change_list (list[GroupChannelValue])
- change_list: list[GroupChannelValue]¶
- classmethod decode(data)[source]¶
Decode WriteGroup-Request from service request bytes.
- Return type:
Self- Parameters:
data (memoryview | bytes)