Server and Application¶
BACnet Application¶
BACnet application layer orchestrator per ASHRAE 135-2016.
- class bac_py.app.application.DeviceInfo(max_apdu_length, segmentation_supported)[source]¶
Bases:
objectCached peer device capabilities from I-Am responses (Clause 19.4).
- class bac_py.app.application.BBMDConfig(bdt_entries=<factory>)[source]¶
Bases:
objectConfiguration for BBMD on a router port.
- class bac_py.app.application.RouterPortConfig(port_id, network_number, interface='0.0.0.0', port=47808, broadcast_address='255.255.255.255', bbmd_config=None, ipv6=False, multicast_address='', vmac=None, sc_config=None, ethernet_interface=None, ethernet_mac=None)[source]¶
Bases:
objectConfiguration for a single router port.
- Parameters:
- bbmd_config: BBMDConfig | None = None¶
- sc_config: SCTransportConfig | None = None¶
BACnet/SC transport for this router port. Mutually exclusive with
ipv6.
- class bac_py.app.application.RouterConfig(ports=<factory>, application_port_id=1)[source]¶
Bases:
objectConfiguration for a router device.
- Parameters:
ports (list[RouterPortConfig])
application_port_id (int)
- ports: list[RouterPortConfig]¶
- class bac_py.app.application.DeviceConfig(instance_number, name='bac-py', vendor_name='bac-py', vendor_id=0, model_name='bac-py', firmware_revision='', application_software_version='', interface='0.0.0.0', port=47808, apdu_timeout=6000, apdu_segment_timeout=2000, apdu_retries=3, max_apdu_length=1476, max_segments=None, router_config=None, broadcast_address='255.255.255.255', password=None, ipv6=False, multicast_address='', vmac=None, sc_config=None, ethernet_interface=None, ethernet_mac=None)[source]¶
Bases:
objectConfiguration for a BACnet device.
- Parameters:
instance_number (int)
name (str)
vendor_name (str)
vendor_id (int)
model_name (str)
firmware_revision (str)
application_software_version (str)
interface (str)
port (int)
apdu_timeout (int)
apdu_segment_timeout (int)
apdu_retries (int)
max_apdu_length (int)
max_segments (int | None)
router_config (RouterConfig | None)
broadcast_address (str)
password (str | None)
ipv6 (bool)
multicast_address (str)
vmac (bytes | None)
sc_config (SCTransportConfig | None)
ethernet_interface (str | None)
ethernet_mac (bytes | None)
- application_software_version: str = ''¶
Application software version string. Defaults to the bac-py package version.
- router_config: RouterConfig | None = None¶
Optional router configuration for multi-network mode.
- broadcast_address: str = '255.255.255.255'¶
Directed broadcast address for this subnet. Default global broadcast works on physical networks; set to the subnet broadcast (e.g.
"192.168.1.255") when running in Docker bridge networks where global broadcast is not routable.
- password: str | None = None¶
Optional password for DeviceCommunicationControl and ReinitializeDevice services (1-20 characters, per Clause 16.1.3.1 and 16.4.3.4). When set, incoming requests must include a matching password.
- multicast_address: str = ''¶
IPv6 multicast group address. Defaults to
ff02::bac0when ipv6 isTrue. Ignored for IPv4 mode.
- vmac: bytes | None = None¶
3-byte VMAC for IPv6 transport. Auto-generated if
None. Ignored for IPv4 mode.
- sc_config: SCTransportConfig | None = None¶
BACnet/SC transport configuration. When set, uses SC transport instead of BIP/BIP6. Mutually exclusive with
ipv6.
- class bac_py.app.application.ForeignDeviceStatus(bbmd_address, ttl, is_registered, last_result)[source]¶
Bases:
objectForeign device registration status.
Provides a snapshot of the current registration state when operating as a foreign device via a BBMD.
- class bac_py.app.application.BACnetApplication(config)[source]¶
Bases:
objectCentral orchestrator connecting all protocol layers.
Wires transport, network, TSMs, and service dispatch.
- Parameters:
config (DeviceConfig)
- property object_db: ObjectDatabase¶
The object database for this device.
- property service_registry: ServiceRegistry¶
The service handler registry.
- property config: DeviceConfig¶
The device configuration.
- property cov_manager: COVManager | None¶
The COV subscription manager, or None if not started.
- property event_engine: EventEngine | None¶
The event/alarm evaluation engine, or None if not started.
- property dcc_state: EnableDisable¶
The current DeviceCommunicationControl state.
- set_dcc_state(state, duration=None)[source]¶
Set the DeviceCommunicationControl state.
- Parameters:
state (
EnableDisable) – New DCC state (ENABLE, DISABLE, or DISABLE_INITIATION).duration (
int|None(default:None)) – Optional duration in minutes. When provided and state is not ENABLE, a timer is set to auto-re-enable after the specified number of minutes.
- Return type:
- property device_object_identifier: Any¶
The device object identifier for this application.
Returns the ObjectIdentifier of the device object from the object database. Used by the COV manager to populate the initiating device identifier in notifications.
- get_device_info(address)[source]¶
Look up cached peer device capabilities.
Returns cached
DeviceInfofrom I-Am responses, orNoneif no information is available for address.- Parameters:
address (
BACnetAddress) – The peer device address.- Return type:
- Returns:
Cached device info, or
None.
- async stop()[source]¶
Stop the application and clean up resources.
This method is idempotent – calling it multiple times is safe.
- Return type:
- async register_as_foreign_device(bbmd_address, ttl=60)[source]¶
Register as a foreign device with a BBMD.
Attaches a foreign device manager to the primary transport and begins periodic re-registration at TTL/2 intervals.
- Parameters:
- Raises:
RuntimeError – If already registered, application not started, or running in router mode.
- Return type:
- async deregister_foreign_device()[source]¶
Deregister from the BBMD and stop re-registration.
Sends a Delete-Foreign-Device-Table-Entry to the BBMD so the entry is removed immediately rather than waiting for TTL expiry.
- Raises:
RuntimeError – If not registered as a foreign device.
- Return type:
- property foreign_device_status: ForeignDeviceStatus | None¶
Current foreign device registration status.
Returns
Noneif foreign device mode is not active.
- async wait_for_registration(timeout=10.0)[source]¶
Wait for foreign device registration to complete.
Blocks until the BBMD confirms registration or the timeout elapses. Useful after
register_as_foreign_device()to ensure broadcasts will be distributed before performing discovery.
- send_network_message(message_type, data, destination=None)[source]¶
Send a network-layer message (non-APDU).
- Parameters:
message_type (
int) – Network message type code.data (
bytes) – Encoded message payload.destination (
BACnetAddress|None(default:None)) – Target address. IfNone, broadcasts locally.
- Raises:
RuntimeError – If the application is not started or is running in router mode (which has its own message API).
- Return type:
- add_route(network, router_address)[source]¶
Pre-populate the router cache for a remote network.
Allows sending to a remote network without broadcast-based router discovery. Useful in Docker or test environments where broadcast delivery is unreliable.
- Parameters:
- Raises:
RuntimeError – If the application is not started.
- Return type:
- register_network_message_handler(message_type, handler)[source]¶
Register a handler for incoming network-layer messages.
- unregister_network_message_handler(message_type, handler)[source]¶
Remove a network-layer message handler.
- async confirmed_request(destination, service_choice, service_data, timeout=None)[source]¶
Send a confirmed request and await response.
- Parameters:
destination (
BACnetAddress) – Target device address.service_choice (
int) – Confirmed service choice number.service_data (
bytes) – Encoded service request bytes.timeout (
float|None(default:None)) – Optional caller-level timeout in seconds. When provided, the request is cancelled if no response is received within this duration (raisesasyncio.TimeoutError). WhenNone, the TSM’s built-in retry/timeout logic is used exclusively.
- Return type:
- Returns:
ComplexACK service data, or empty bytes for SimpleACK.
- unconfirmed_request(destination, service_choice, service_data)[source]¶
Send an unconfirmed request.
- Parameters:
destination (
BACnetAddress) – Target device address.service_choice (
int) – Unconfirmed service choice number.service_data (
bytes) – Encoded service request bytes.
- Return type:
- send_confirmed_cov_notification(service_data, destination, service_choice)[source]¶
Send a confirmed COV notification (fire-and-forget).
Unlike
confirmed_request, this does not await a response. COV notifications are best-effort; failures are logged but do not propagate.- Parameters:
service_data (
bytes) – Encoded service request bytes.destination (
BACnetAddress) – Target device address.service_choice (
int) – Confirmed service choice number.
- Return type:
- register_cov_callback(process_id, callback)[source]¶
Register a callback for incoming COV notifications.
Server¶
Default BACnet server handlers per ASHRAE 135-2016.
Provides handlers for Who-Is, ReadProperty, WriteProperty, ReadPropertyMultiple, WritePropertyMultiple, and ReadRange that work with the local ObjectDatabase and DeviceObject.
- class bac_py.app.server.DefaultServerHandlers(app, object_db, device)[source]¶
Bases:
objectStandard BACnet service handlers for a server device.
Registers handlers for ReadProperty, WriteProperty, Who-Is, ReadPropertyMultiple, WritePropertyMultiple, and ReadRange with the application’s service registry.
- Parameters:
app (BACnetApplication)
object_db (ObjectDatabase)
device (DeviceObject)
- async handle_read_property(service_choice, data, source)[source]¶
Handle ReadProperty-Request per Clause 15.5.
Decodes the request, looks up the object and property in the database, and returns the encoded
ReadPropertyACK.- Parameters:
service_choice (
int) – Confirmed service choice code.data (
bytes) – Raw service request bytes.source (
BACnetAddress) – Address of the requesting device.
- Return type:
- Returns:
Encoded ReadProperty-ACK service data.
- Raises:
BACnetError – If the object or property is not found.
- async handle_write_property(service_choice, data, source)[source]¶
Handle WriteProperty-Request per Clause 15.9.
Decodes the request, looks up the object in the database, and writes the property value. Returns
Nonefor SimpleACK.- Parameters:
service_choice (
int) – Confirmed service choice code.data (
bytes) – Raw service request bytes.source (
BACnetAddress) – Address of the requesting device.
- Return type:
- Returns:
None(SimpleACK response).- Raises:
BACnetError – If the object or property is not found, or the write is not permitted.
- async handle_subscribe_cov(service_choice, data, source)[source]¶
Handle SubscribeCOV-Request per Clause 13.14.
Returns
None(SimpleACK) on success.- Parameters:
service_choice (
int) – Confirmed service choice code.data (
bytes) – Raw service request bytes.source (
BACnetAddress) – Address of the requesting device.
- Raises:
BACnetError – If the monitored object does not exist or COV is not supported.
- Return type:
- async handle_subscribe_cov_property(service_choice, data, source)[source]¶
Handle SubscribeCOVProperty-Request per Clause 13.15.
- Parameters:
service_choice (
int) – Confirmed service choice code.data (
bytes) – Raw service request bytes.source (
BACnetAddress) – Address of the requesting device.
- Return type:
- async handle_subscribe_cov_property_multiple(service_choice, data, source)[source]¶
Handle SubscribeCOVPropertyMultiple-Request per Clause 13.16.
- Parameters:
service_choice (
int) – Confirmed service choice code.data (
bytes) – Raw service request bytes.source (
BACnetAddress) – Address of the requesting device.
- Return type:
- async handle_confirmed_cov_notification_multiple(service_choice, data, source)[source]¶
Handle ConfirmedCOVNotification-Multiple per Clause 13.17.
- Parameters:
service_choice (
int) – Confirmed service choice code.data (
bytes) – Raw service request bytes.source (
BACnetAddress) – Address of the requesting device.
- Return type:
- async handle_unconfirmed_cov_notification_multiple(service_choice, data, source)[source]¶
Handle UnconfirmedCOVNotification-Multiple per Clause 13.18.
- Parameters:
service_choice (
int) – Unconfirmed service choice code.data (
bytes) – Raw service request bytes.source (
BACnetAddress) – Address of the sending device.
- Return type:
- async handle_who_is(service_choice, data, source)[source]¶
Handle Who-Is-Request per Clause 16.10.
Checks if the local device instance is within the requested range and responds with an I-Am if so.
- Parameters:
service_choice (
int) – Unconfirmed service choice code.data (
bytes) – Raw service request bytes.source (
BACnetAddress) – Address of the requesting device.
- Return type:
- async handle_read_property_multiple(service_choice, data, source)[source]¶
Handle ReadPropertyMultiple-Request per Clause 15.7.
Decodes the request, reads all requested properties from the database, and returns the encoded ReadPropertyMultiple-ACK. Per-property errors are embedded in the ACK (no top-level error). Supports ALL, REQUIRED, and OPTIONAL special property identifiers per Clause 15.7.3.2.
- Parameters:
service_choice (
int) – Confirmed service choice code.data (
bytes) – Raw service request bytes.source (
BACnetAddress) – Address of the requesting device.
- Return type:
- Returns:
Encoded ReadPropertyMultiple-ACK service data.
- async handle_write_property_multiple(service_choice, data, source)[source]¶
Handle WritePropertyMultiple-Request per Clause 15.10.
Uses a two-pass approach for atomicity: validates all writes first, then applies them. Either all writes succeed or none are applied.
- Parameters:
service_choice (
int) – Confirmed service choice code.data (
bytes) – Raw service request bytes.source (
BACnetAddress) – Address of the requesting device.
- Return type:
- Returns:
None(SimpleACK response) on full success.- Raises:
BACnetError – On first validation or write failure.
- async handle_read_range(service_choice, data, source)[source]¶
Handle ReadRange-Request per Clause 15.8.
Decodes the request, reads the list/array property, applies the range qualifier, and returns the encoded ReadRange-ACK.
- Return type:
- Returns:
Encoded ReadRange-ACK service data.
- Raises:
BACnetError – If the object or property is not found.
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_device_communication_control(service_choice, data, source)[source]¶
Handle DeviceCommunicationControl-Request per Clause 16.1.
Sets the application DCC state and optionally starts a timer to auto-re-enable after the specified duration.
- Return type:
- Returns:
None(SimpleACK response).- Raises:
BACnetError – If the password does not match (Clause 16.1.3.1).
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_reinitialize_device(service_choice, data, source)[source]¶
Handle ReinitializeDevice-Request per Clause 16.4 & 19.1.
Manages backup/restore state transitions on the Device object per Clause 19.1:
START_BACKUP→system_status=BACKUP_IN_PROGRESSEND_BACKUP→system_status=OPERATIONALSTART_RESTORE→system_status=DOWNLOAD_IN_PROGRESSEND_RESTORE→system_status=OPERATIONALABORT_RESTORE→system_status=OPERATIONAL
- Return type:
- Returns:
None(SimpleACK response).- Raises:
BACnetError – If the password does not match or the state transition is invalid.
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_time_synchronization(service_choice, data, source)[source]¶
Handle TimeSynchronization-Request per Clause 16.7.
Logs the received time. Does not update the local clock.
- Return type:
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_utc_time_synchronization(service_choice, data, source)[source]¶
Handle UTCTimeSynchronization-Request per Clause 16.8.
Logs the received UTC time. Does not update the local clock.
- Return type:
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_atomic_read_file(service_choice, data, source)[source]¶
Handle AtomicReadFile-Request per Clause 14.1.
- Return type:
- Returns:
Encoded AtomicReadFile-ACK service data.
- Raises:
BACnetError – If the object is not found or is not a
FileObject.- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_atomic_write_file(service_choice, data, source)[source]¶
Handle AtomicWriteFile-Request per Clause 14.2.
- Return type:
- Returns:
Encoded AtomicWriteFile-ACK service data.
- Raises:
BACnetError – If the object is not found or is not a
FileObject.- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_create_object(service_choice, data, source)[source]¶
Handle CreateObject-Request per Clause 15.3.
Creates a new object in the database and returns the encoded object identifier.
- Return type:
- Returns:
Encoded APPLICATION-tagged
ObjectIdentifier.- Raises:
BACnetError – If the object type is unsupported or the object identifier already exists.
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_delete_object(service_choice, data, source)[source]¶
Handle DeleteObject-Request per Clause 15.4.
Removes the object from the database.
- Return type:
- Returns:
None(SimpleACK response).- Raises:
BACnetError – If the object does not exist or is a Device object.
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_add_list_element(service_choice, data, source)[source]¶
Handle AddListElement-Request per Clause 15.1.
Decodes the elements from the request, validates that the target property is a list, checks write access, and extends the list.
- Return type:
- Returns:
None(SimpleACK response).- Raises:
BACnetError – If the object or property is not found, or the property is not a list or is read-only.
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_remove_list_element(service_choice, data, source)[source]¶
Handle RemoveListElement-Request per Clause 15.2.
Decodes the elements from the request, validates that the target property is a list, checks write access, and removes matching entries. Non-matching elements are silently ignored per the standard.
- Return type:
- Returns:
None(SimpleACK response).- Raises:
BACnetError – If the object or property is not found, or the property is not a list or is read-only.
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_acknowledge_alarm(service_choice, data, source)[source]¶
Handle AcknowledgeAlarm-Request per Clause 13.5.
Updates the acked_transitions property on the target object to mark the appropriate transition as acknowledged.
- Return type:
- Returns:
None(SimpleACK response).- Raises:
BACnetError – If the target object does not exist.
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_confirmed_event_notification(service_choice, data, source)[source]¶
Handle ConfirmedEventNotification-Request per Clause 13.8.
Logs the notification at debug level.
- Return type:
- Returns:
None(SimpleACK response).- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_unconfirmed_event_notification(service_choice, data, source)[source]¶
Handle UnconfirmedEventNotification-Request per Clause 13.9.
Logs the notification at debug level.
- Return type:
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_get_alarm_summary(service_choice, data, source)[source]¶
Handle GetAlarmSummary-Request per Clause 13.6.
Scans all objects in the database for those in an alarm (non-NORMAL) event state and returns their summaries.
- Return type:
- Returns:
Encoded GetAlarmSummary-ACK service data.
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_get_enrollment_summary(service_choice, data, source)[source]¶
Handle GetEnrollmentSummary-Request per Clause 13.7.
Iterates EventEnrollment objects, applies the request filters, and returns matching enrollment summaries.
- Return type:
- Returns:
Encoded GetEnrollmentSummary-ACK service data.
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_get_event_information(service_choice, data, source)[source]¶
Handle GetEventInformation-Request per Clause 13.12.
Iterates all objects in the database for those in an alarm (non-NORMAL) event state and returns event summaries with pagination support.
- Return type:
- Returns:
Encoded GetEventInformation-ACK service data.
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_who_has(service_choice, data, source)[source]¶
Handle Who-Has-Request per Clause 16.9.
Searches the local object database for a matching object and responds with I-Have if found.
- Return type:
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_confirmed_text_message(service_choice, data, source)[source]¶
Handle ConfirmedTextMessage-Request per Clause 16.5.
Logs the message and invokes the text message callback if set.
- Return type:
- Returns:
None(SimpleACK response).- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_unconfirmed_text_message(service_choice, data, source)[source]¶
Handle UnconfirmedTextMessage-Request per Clause 16.6.
Logs the message and invokes the text message callback if set.
- Return type:
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_write_group(service_choice, data, source)[source]¶
Handle WriteGroup-Request per Clause 15.11.
Looks up Channel objects by group number and writes values.
- Return type:
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_who_am_i(service_choice, data, source)[source]¶
Handle Who-Am-I-Request per Clause 16.11.
Logs the request. A supervisor application should register a callback to handle device identity assignment.
- Return type:
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_you_are(service_choice, data, source)[source]¶
Handle You-Are-Request per Clause 16.11.
Applies the assigned device identity if the device is unconfigured.
- Return type:
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_vt_open(service_choice, data, source)[source]¶
Handle VT-Open-Request per Clause 17.1.
- Return type:
- Returns:
Encoded VT-Open-ACK with remote session ID.
- Raises:
BACnetError – If no VT sessions are available or the VT class is not supported.
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_vt_close(service_choice, data, source)[source]¶
Handle VT-Close-Request per Clause 17.2.
- Return type:
- Returns:
None(SimpleACK response).- Raises:
BACnetError – If a session ID is unknown.
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_vt_data(service_choice, data, source)[source]¶
Handle VT-Data-Request per Clause 17.3.
- Return type:
- Returns:
Encoded VT-Data-ACK.
- Raises:
BACnetError – If the session is unknown.
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_audit_log_query(service_choice, data, source)[source]¶
Handle AuditLogQuery-Request per Clause 13.19.
Queries the specified Audit Log object’s buffer.
- Return type:
- Returns:
Encoded AuditLogQuery-ACK.
- Raises:
BACnetError – If the audit log object is not found.
- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
- async handle_confirmed_audit_notification(service_choice, data, source)[source]¶
Handle ConfirmedAuditNotification-Request per Clause 13.20.
Appends notifications to Audit Log objects.
- Return type:
- Returns:
None(SimpleACK response).- Parameters:
service_choice (int)
data (bytes)
source (BACnetAddress)
Transaction State Machine¶
Transaction State Machines per ASHRAE 135-2016 Clause 5.4.
- class bac_py.app.tsm.ClientTransactionState(*values)[source]¶
Bases:
IntEnumClient TSM states per Clause 5.4.4.
- IDLE = 0¶
- SEGMENTED_REQUEST = 1¶
- AWAIT_CONFIRMATION = 2¶
- SEGMENTED_CONFIRMATION = 3¶
- class bac_py.app.tsm.ClientTransaction(invoke_id, destination, service_choice, request_data, future, retry_count=0, timeout_handle=None, state=ClientTransactionState.IDLE, segment_sender=None, segment_receiver=None, seg_retry_count=0)[source]¶
Bases:
objectTracks an outstanding confirmed service request.
- Parameters:
invoke_id (int)
destination (BACnetAddress)
service_choice (int)
request_data (bytes)
future (Future[bytes])
retry_count (int)
timeout_handle (TimerHandle | None)
state (ClientTransactionState)
segment_sender (SegmentSender | None)
segment_receiver (SegmentReceiver | None)
seg_retry_count (int)
- destination: BACnetAddress¶
- state: ClientTransactionState = 0¶
- segment_sender: SegmentSender | None = None¶
- segment_receiver: SegmentReceiver | None = None¶
- class bac_py.app.tsm.ClientTSM(network, *, apdu_timeout=6.0, apdu_retries=3, max_apdu_length=1476, max_segments=None, segment_timeout=2.0, proposed_window_size=16)[source]¶
Bases:
objectClient Transaction State Machine (Clause 5.4.4).
Manages outstanding confirmed requests, correlating responses by (source_address, invoke_id).
- Parameters:
- async send_request(service_choice, request_data, destination, *, max_apdu_override=None)[source]¶
Send a confirmed request and await the response.
If the request data exceeds the max segment payload, the request is automatically segmented per Clause 5.2.
- Parameters:
service_choice (
int) – Confirmed service choice number.request_data (
bytes) – Encoded service request bytes.destination (
BACnetAddress) – Target device address.max_apdu_override (
int|None(default:None)) – When provided, constrains the effective max APDU length for segmentation decisions (Clause 19.4). Typically set tomin(local, remote)based on cached peer device info from I-Am responses.
- Return type:
- Returns:
The service-ack data from ComplexACK, or empty bytes for SimpleACK.
- Raises:
BACnetError – On Error-PDU response.
BACnetRejectError – On Reject-PDU response.
BACnetAbortError – On Abort-PDU response.
BACnetTimeoutError – On timeout after all retries.
- handle_simple_ack(source, invoke_id, service_choice)[source]¶
Handle a SimpleACK response.
- Return type:
- Parameters:
source (BACnetAddress)
invoke_id (int)
service_choice (int)
- handle_complex_ack(source, invoke_id, service_choice, data)[source]¶
Handle a ComplexACK response (non-segmented).
- Return type:
- Parameters:
source (BACnetAddress)
invoke_id (int)
service_choice (int)
data (bytes)
- handle_error(source, invoke_id, error_class, error_code, error_data=b'')[source]¶
Handle an Error-PDU response.
- Return type:
- Parameters:
source (BACnetAddress)
invoke_id (int)
error_class (ErrorClass)
error_code (ErrorCode)
error_data (bytes)
- handle_reject(source, invoke_id, reason)[source]¶
Handle a Reject-PDU response.
- Return type:
- Parameters:
source (BACnetAddress)
invoke_id (int)
reason (RejectReason)
- handle_abort(source, invoke_id, reason)[source]¶
Handle an Abort-PDU response.
- Return type:
- Parameters:
source (BACnetAddress)
invoke_id (int)
reason (AbortReason)
- handle_segment_ack(source, pdu)[source]¶
Handle SegmentACK during segmented request sending.
- Return type:
- Parameters:
source (BACnetAddress)
pdu (SegmentAckPDU)
- handle_segmented_complex_ack(source, pdu)[source]¶
Handle a segmented ComplexACK response.
- Return type:
- Parameters:
source (BACnetAddress)
pdu (ComplexAckPDU)
- class bac_py.app.tsm.ServerTransactionState(*values)[source]¶
Bases:
IntEnumServer TSM states per Clause 5.4.5.
- IDLE = 0¶
- SEGMENTED_REQUEST = 1¶
- AWAIT_RESPONSE = 2¶
- SEGMENTED_RESPONSE = 3¶
- class bac_py.app.tsm.ServerTransaction(invoke_id, source, service_choice, state=ServerTransactionState.IDLE, cached_response=None, timeout_handle=None, segment_receiver=None, segment_sender=None, seg_retry_count=0, client_max_apdu_length=1476, client_max_segments=None, segmented_response_accepted=False)[source]¶
Bases:
objectTracks an incoming confirmed request being processed.
- Parameters:
invoke_id (int)
source (BACnetAddress)
service_choice (int)
state (ServerTransactionState)
cached_response (bytes | None)
timeout_handle (TimerHandle | None)
segment_receiver (SegmentReceiver | None)
segment_sender (SegmentSender | None)
seg_retry_count (int)
client_max_apdu_length (int)
client_max_segments (int | None)
segmented_response_accepted (bool)
- source: BACnetAddress¶
- state: ServerTransactionState = 0¶
- segment_receiver: SegmentReceiver | None = None¶
- segment_sender: SegmentSender | None = None¶
- class bac_py.app.tsm.ServerTSM(network, *, request_timeout=6.0, apdu_retries=3, segment_timeout=2.0, max_apdu_length=1476, max_segments=None, proposed_window_size=16)[source]¶
Bases:
objectServer Transaction State Machine (Clause 5.4.5).
Prevents duplicate processing and caches responses for retransmission detection.
- Parameters:
- receive_confirmed_request(pdu, source)[source]¶
Register an incoming confirmed request.
Returns
(txn, service_data)for new requests.service_datais the complete request payload for non-segmented requests, orNonefor segmented requests that need more segments.Returns
Nonefor duplicates (cached response is resent).- Return type:
tuple[ServerTransaction,bytes|None] |None- Parameters:
pdu (ConfirmedRequestPDU)
source (BACnetAddress)
- handle_request_segment(pdu, source)[source]¶
Handle a subsequent segment of a segmented confirmed request.
Returns
(txn, complete_data)when all segments are received,(txn, None)when more segments expected, orNoneif no matching transaction.- Return type:
tuple[ServerTransaction,bytes|None] |None- Parameters:
pdu (ConfirmedRequestPDU)
source (BACnetAddress)
- start_segmented_response(txn, service_choice, response_data)[source]¶
Begin sending a segmented ComplexACK response.
- Parameters:
txn (
ServerTransaction) – The server transaction.service_choice (
int) – Service choice for the response.response_data (
bytes) – The complete service-ack data to segment.
- Return type:
- handle_segment_ack_for_response(source, pdu)[source]¶
Handle SegmentACK from client during segmented response sending.
- Return type:
- Parameters:
source (BACnetAddress)
pdu (SegmentAckPDU)
- complete_transaction(txn, response_apdu)[source]¶
Cache the response and schedule cleanup.
- Return type:
- Parameters:
txn (ServerTransaction)
response_apdu (bytes)