Events and Alarms

Event Notification

Event notification services per ASHRAE 135-2020 Clause 13.5/13.8/13.9/13.13.

class bac_py.services.event_notification.EventNotificationRequest(process_identifier, initiating_device_identifier, event_object_identifier, time_stamp, notification_class, priority, event_type, notify_type, to_state, message_text=None, ack_required=None, from_state=None, event_values=None)[source]

Bases: object

Confirmed/Unconfirmed EventNotification-Request (Clause 13.8.1/13.9.1).

EventNotification-Request ::= SEQUENCE {
    processIdentifier            [0] Unsigned32,
    initiatingDeviceIdentifier   [1] BACnetObjectIdentifier,
    eventObjectIdentifier        [2] BACnetObjectIdentifier,
    timeStamp                    [3] BACnetTimeStamp,
    notificationClass            [4] Unsigned,
    priority                     [5] Unsigned (0..255),
    eventType                    [6] BACnetEventType,
    messageText                  [7] CharacterString OPTIONAL,
    notifyType                   [8] BACnetNotifyType,
    ackRequired                  [9] BOOLEAN           -- conditional,
    fromState                    [10] BACnetEventState  -- conditional,
    toState                      [11] BACnetEventState,
    eventValues                  [12] BACnetNotificationParameters -- conditional
}

Conditional fields (tags 9, 10, 12) are present only when notify_type is ALARM or EVENT.

The event_values field is decoded as a typed NotificationParameters variant.

Parameters:
process_identifier: int
initiating_device_identifier: ObjectIdentifier
event_object_identifier: ObjectIdentifier
time_stamp: BACnetTimeStamp
notification_class: int
priority: int
event_type: EventType
notify_type: NotifyType
to_state: EventState
message_text: str | None
ack_required: bool | None
from_state: EventState | None
event_values: ChangeOfBitstring | ChangeOfState | ChangeOfValue | CommandFailure | FloatingLimit | OutOfRange | ChangeOfLifeSafety | Extended | BufferReady | UnsignedRange | AccessEvent | DoubleOutOfRange | SignedOutOfRange | UnsignedOutOfRange | ChangeOfCharacterstring | ChangeOfStatusFlags | ChangeOfReliability | NoneParams | ChangeOfDiscreteValue | ChangeOfTimer | RawNotificationParameters | None
encode()[source]

Encode EventNotification-Request service parameters.

Return type:

bytes

Returns:

Encoded service request bytes.

classmethod decode(data)[source]

Decode EventNotification-Request from service request bytes.

Parameters:

data (memoryview | bytes) – Raw service request bytes.

Return type:

EventNotificationRequest

Returns:

Decoded EventNotificationRequest.

class bac_py.services.event_notification.AcknowledgeAlarmRequest(acknowledging_process_identifier, event_object_identifier, event_state_acknowledged, time_stamp, acknowledgment_source, time_of_acknowledgment)[source]

Bases: object

AcknowledgeAlarm-Request per Clause 13.5.1.

AcknowledgeAlarm-Request ::= SEQUENCE {
    acknowledgingProcessIdentifier [0] Unsigned32,
    eventObjectIdentifier          [1] BACnetObjectIdentifier,
    eventStateAcknowledged         [2] BACnetEventState,
    timeStamp                      [3] BACnetTimeStamp,
    acknowledgmentSource           [4] CharacterString,
    timeOfAcknowledgment           [5] BACnetTimeStamp
}
Parameters:
acknowledging_process_identifier: int
event_object_identifier: ObjectIdentifier
event_state_acknowledged: EventState
time_stamp: BACnetTimeStamp
acknowledgment_source: str
time_of_acknowledgment: BACnetTimeStamp
encode()[source]

Encode AcknowledgeAlarm-Request service parameters.

Return type:

bytes

Returns:

Encoded service request bytes.

classmethod decode(data)[source]

Decode AcknowledgeAlarm-Request from service request bytes.

Parameters:

data (memoryview | bytes) – Raw service request bytes.

Return type:

AcknowledgeAlarmRequest

Returns:

Decoded AcknowledgeAlarmRequest.

class bac_py.services.event_notification.LifeSafetyOperationRequest(requesting_process_identifier, requesting_source, request, object_identifier=None)[source]

Bases: object

LifeSafetyOperation-Request per Clause 13.13.1.

LifeSafetyOperation-Request ::= SEQUENCE {
    requestingProcessIdentifier [0] Unsigned32,
    requestingSource            [1] CharacterString,
    request                     [2] BACnetLifeSafetyOperation,
    objectIdentifier            [3] BACnetObjectIdentifier OPTIONAL
}
Parameters:
requesting_process_identifier: int
requesting_source: str
request: LifeSafetyOperation
object_identifier: ObjectIdentifier | None
encode()[source]

Encode LifeSafetyOperation-Request service parameters.

Return type:

bytes

Returns:

Encoded service request bytes.

classmethod decode(data)[source]

Decode LifeSafetyOperation-Request from service request bytes.

Parameters:

data (memoryview | bytes) – Raw service request bytes.

Return type:

LifeSafetyOperationRequest

Returns:

Decoded LifeSafetyOperationRequest.

Alarm Summary

Alarm and enrollment query services per ASHRAE 135-2020 Clause 13.6/13.7/13.12.

class bac_py.services.alarm_summary.AlarmSummary(object_identifier, alarm_state, acknowledged_transitions)[source]

Bases: object

Single entry in a GetAlarmSummary-ACK (Clause 13.6.1.3).

Encoded as three consecutive application-tagged values within the SEQUENCE OF.

Parameters:
object_identifier: ObjectIdentifier
alarm_state: EventState
acknowledged_transitions: BitString
class bac_py.services.alarm_summary.GetAlarmSummaryRequest[source]

Bases: object

GetAlarmSummary-Request (Clause 13.6.1.1).

This service has no parameters.

encode()[source]

Encode GetAlarmSummary-Request (empty payload).

Return type:

bytes

Returns:

Empty bytes.

classmethod decode(data)[source]

Decode GetAlarmSummary-Request.

Parameters:

data (memoryview | bytes) – Raw service request bytes (expected empty).

Return type:

GetAlarmSummaryRequest

Returns:

Decoded GetAlarmSummaryRequest.

class bac_py.services.alarm_summary.GetAlarmSummaryACK(list_of_alarm_summaries)[source]

Bases: object

GetAlarmSummary-ACK (Clause 13.6.1.3).

GetAlarmSummary-ACK ::= SEQUENCE OF SEQUENCE {
    objectIdentifier         BACnetObjectIdentifier,
    alarmState               BACnetEventState,
    acknowledgedTransitions  BACnetEventTransitionBits
}

Inner SEQUENCE uses application-tagged encoding (no context tags).

Parameters:

list_of_alarm_summaries (list[AlarmSummary])

list_of_alarm_summaries: list[AlarmSummary]
encode()[source]

Encode GetAlarmSummary-ACK.

Return type:

bytes

Returns:

Encoded ACK bytes.

classmethod decode(data)[source]

Decode GetAlarmSummary-ACK.

Parameters:

data (memoryview | bytes) – Raw ACK bytes.

Return type:

GetAlarmSummaryACK

Returns:

Decoded GetAlarmSummaryACK.

class bac_py.services.alarm_summary.EnrollmentSummary(object_identifier, event_type, event_state, priority, notification_class)[source]

Bases: object

Single entry in a GetEnrollmentSummary-ACK (Clause 13.7.1.3).

Encoded as five consecutive application-tagged values.

Parameters:
object_identifier: ObjectIdentifier
event_type: EventType
event_state: EventState
priority: int
notification_class: int
class bac_py.services.alarm_summary.GetEnrollmentSummaryRequest(acknowledgment_filter, event_state_filter=None, event_type_filter=None, priority_min=None, priority_max=None, notification_class_filter=None)[source]

Bases: object

GetEnrollmentSummary-Request (Clause 13.7.1.1).

GetEnrollmentSummary-Request ::= SEQUENCE {
    acknowledgmentFilter      [0] ENUMERATED,
    enrollmentFilter          [1] BACnetRecipientProcess OPTIONAL,
    eventStateFilter          [2] ENUMERATED OPTIONAL,
    eventTypeFilter           [3] BACnetEventType OPTIONAL,
    priority                  [4] SEQUENCE {
        minPriority Unsigned(0..255),
        maxPriority Unsigned(0..255)
    } OPTIONAL,
    notificationClassFilter   [5] Unsigned OPTIONAL
}

The enrollment_filter field (tag 1) is not currently supported for encoding. Decoding will skip it if present.

Parameters:
acknowledgment_filter: AcknowledgmentFilter
event_state_filter: EventState | None
event_type_filter: EventType | None
priority_min: int | None
priority_max: int | None
notification_class_filter: int | None
encode()[source]

Encode GetEnrollmentSummary-Request.

Return type:

bytes

Returns:

Encoded service request bytes.

classmethod decode(data)[source]

Decode GetEnrollmentSummary-Request.

Parameters:

data (memoryview | bytes) – Raw service request bytes.

Return type:

GetEnrollmentSummaryRequest

Returns:

Decoded GetEnrollmentSummaryRequest.

class bac_py.services.alarm_summary.GetEnrollmentSummaryACK(list_of_enrollment_summaries)[source]

Bases: object

GetEnrollmentSummary-ACK (Clause 13.7.1.3).

GetEnrollmentSummary-ACK ::= SEQUENCE OF SEQUENCE {
    objectIdentifier   BACnetObjectIdentifier,
    eventType          BACnetEventType,
    eventState         BACnetEventState,
    priority           Unsigned(0..255),
    notificationClass  Unsigned
}

Inner SEQUENCE uses application-tagged encoding.

Parameters:

list_of_enrollment_summaries (list[EnrollmentSummary])

list_of_enrollment_summaries: list[EnrollmentSummary]
encode()[source]

Encode GetEnrollmentSummary-ACK.

Return type:

bytes

Returns:

Encoded ACK bytes.

classmethod decode(data)[source]

Decode GetEnrollmentSummary-ACK.

Parameters:

data (memoryview | bytes) – Raw ACK bytes.

Return type:

GetEnrollmentSummaryACK

Returns:

Decoded GetEnrollmentSummaryACK.

class bac_py.services.alarm_summary.EventSummary(object_identifier, event_state, acknowledged_transitions, event_time_stamps, notify_type, event_enable, event_priorities)[source]

Bases: object

Single entry in a GetEventInformation-ACK (Clause 13.12.1.3).

Uses context-tagged encoding within the outer SEQUENCE OF.

Parameters:
object_identifier: ObjectIdentifier
event_state: EventState
acknowledged_transitions: BitString
event_time_stamps: tuple[BACnetTimeStamp, BACnetTimeStamp, BACnetTimeStamp]
notify_type: NotifyType
event_enable: BitString
event_priorities: tuple[int, int, int]
class bac_py.services.alarm_summary.GetEventInformationRequest(last_received_object_identifier=None)[source]

Bases: object

GetEventInformation-Request (Clause 13.12.1.1).

GetEventInformation-Request ::= SEQUENCE {
    lastReceivedObjectIdentifier [0] BACnetObjectIdentifier OPTIONAL
}
Parameters:

last_received_object_identifier (ObjectIdentifier | None)

last_received_object_identifier: ObjectIdentifier | None
encode()[source]

Encode GetEventInformation-Request.

Return type:

bytes

Returns:

Encoded service request bytes.

classmethod decode(data)[source]

Decode GetEventInformation-Request.

Parameters:

data (memoryview | bytes) – Raw service request bytes.

Return type:

GetEventInformationRequest

Returns:

Decoded GetEventInformationRequest.

class bac_py.services.alarm_summary.GetEventInformationACK(list_of_event_summaries, more_events)[source]

Bases: object

GetEventInformation-ACK (Clause 13.12.1.3).

GetEventInformation-ACK ::= SEQUENCE {
    listOfEventSummaries [0] SEQUENCE OF SEQUENCE {
        objectIdentifier        [0] BACnetObjectIdentifier,
        eventState              [1] BACnetEventState,
        acknowledgedTransitions [2] BACnetEventTransitionBits,
        eventTimeStamps         [3] SEQUENCE OF BACnetTimeStamp SIZE(3),
        notifyType              [4] BACnetNotifyType,
        eventEnable             [5] BACnetEventTransitionBits,
        eventPriorities         [6] SEQUENCE SIZE(3) OF Unsigned
    },
    moreEvents [1] BOOLEAN
}
Parameters:
list_of_event_summaries: list[EventSummary]
more_events: bool
encode()[source]

Encode GetEventInformation-ACK.

Return type:

bytes

Returns:

Encoded ACK bytes.

classmethod decode(data)[source]

Decode GetEventInformation-ACK.

Parameters:

data (memoryview | bytes) – Raw ACK bytes.

Return type:

GetEventInformationACK

Returns:

Decoded GetEventInformationACK.

Text Message

Text message services per ASHRAE 135-2020 Clause 16.5-16.6.

ConfirmedTextMessage (Clause 16.5), UnconfirmedTextMessage (Clause 16.6).

class bac_py.services.text_message.ConfirmedTextMessageRequest(text_message_source_device, message_priority, message, message_class_numeric=None, message_class_character=None)[source]

Bases: object

ConfirmedTextMessage-Request (Clause 16.5.1).

ConfirmedTextMessage-Request ::= SEQUENCE {
    textMessageSourceDevice  [0] BACnetObjectIdentifier,
    messageClass             [1] CHOICE {
        numeric    [0] Unsigned,
        character  [1] CharacterString
    } OPTIONAL,
    messagePriority          [2] ENUMERATED { normal(0), urgent(1) },
    message                  [3] CharacterString
}
Parameters:
text_message_source_device: ObjectIdentifier
message_priority: MessagePriority
message: str
message_class_numeric: int | None
message_class_character: str | None
encode()[source]

Encode ConfirmedTextMessage-Request service parameters.

Return type:

bytes

classmethod decode(data)[source]

Decode ConfirmedTextMessage-Request from service request bytes.

Return type:

Self

Parameters:

data (memoryview | bytes)

class bac_py.services.text_message.UnconfirmedTextMessageRequest(text_message_source_device, message_priority, message, message_class_numeric=None, message_class_character=None)[source]

Bases: ConfirmedTextMessageRequest

UnconfirmedTextMessage-Request (Clause 16.6.1).

Same structure as ConfirmedTextMessage-Request.

Parameters:

Fault Algorithms

Fault algorithm evaluators per ASHRAE 135-2020 Clause 13.4.

Each public function evaluates one fault algorithm variant. They are pure functions – no I/O, no async, no side effects – making them straightforward to unit-test.

Contract with the caller: The reliability_evaluation_inhibit property (PropertyIdentifier 357) is checked by the caller before invoking any evaluator. When that flag is True the caller must skip evaluation and keep the current Reliability value unchanged.

bac_py.services.fault_algorithms.evaluate_fault_characterstring(current_value, params)[source]

Evaluate FAULT_CHARACTERSTRING (Clause 13.4.1).

If current_value matches any string in params.fault_values, return MULTI_STATE_FAULT; otherwise return NO_FAULT_DETECTED.

Parameters:
  • current_value (str) – The current character-string property value.

  • params (FaultCharacterString) – Fault parameter configuration carrying the list of fault-triggering strings.

Return type:

Reliability

Returns:

Computed Reliability value.

bac_py.services.fault_algorithms.evaluate_fault_extended(current_value, params, *, vendor_callback=None)[source]

Evaluate FAULT_EXTENDED (Clause 13.4.2).

Vendor-specific algorithm. If vendor_callback is provided the evaluation is delegated to it; otherwise NO_FAULT_DETECTED is returned because the algorithm cannot be evaluated without vendor-supplied logic.

Parameters:
  • current_value (Any) – The current property value (type varies by vendor).

  • params (FaultExtended) – Fault parameter configuration with vendor-id, extended-fault-type, and raw parameter bytes.

  • vendor_callback (Callable[[Any, FaultExtended], Reliability] | None (default: None)) – Optional callable implementing the vendor-specific evaluation logic.

Return type:

Reliability

Returns:

Computed Reliability value.

bac_py.services.fault_algorithms.evaluate_fault_life_safety(current_value, params)[source]

Evaluate FAULT_LIFE_SAFETY (Clause 13.4.3).

If current_value appears in params.fault_values, return MULTI_STATE_FAULT. Mode filtering (params.mode_values) is the responsibility of the caller – it determines whether this evaluator should be invoked at all.

Parameters:
  • current_value (LifeSafetyState) – The current life-safety state.

  • params (FaultLifeSafety) – Fault parameter configuration carrying fault values and mode values.

Return type:

Reliability

Returns:

Computed Reliability value.

bac_py.services.fault_algorithms.evaluate_fault_state(current_value, params, *, fault_enum_values=())[source]

Evaluate FAULT_STATE (Clause 13.4.4).

Because BACnetPropertyStates is a large CHOICE type whose params.fault_values are stored as raw bytes, the caller pre-parses them into fault_enum_values – a tuple of integer enumeration values to match against.

Parameters:
  • current_value (int) – The current enumerated property value (as an integer).

  • params (FaultState) – Fault parameter configuration (used for reference; the actual match set is fault_enum_values).

  • fault_enum_values (tuple[int, ...] (default: ())) – Pre-parsed integer enumeration values derived from params.fault_values.

Return type:

Reliability

Returns:

Computed Reliability value.

bac_py.services.fault_algorithms.evaluate_fault_status_flags(current_flags, params)[source]

Evaluate FAULT_STATUS_FLAGS (Clause 13.4.5).

If the fault bit in current_flags is set, return MEMBER_FAULT. The params.status_flags_ref tells the caller where to read the flags from; the actual flag values are supplied as current_flags.

Parameters:
  • current_flags (StatusFlags) – The resolved status-flags value.

  • params (FaultStatusFlags) – Fault parameter configuration carrying the property reference (used by the caller, not by this evaluator).

Return type:

Reliability

Returns:

Computed Reliability value.

bac_py.services.fault_algorithms.evaluate_fault_out_of_range(current_value, params)[source]

Evaluate FAULT_OUT_OF_RANGE (Clause 13.4.6).

Returns UNDER_RANGE when current_value is strictly less than params.min_normal_value, OVER_RANGE when strictly greater than params.max_normal_value, and NO_FAULT_DETECTED otherwise. Values exactly at the boundary are not faulted.

Parameters:
  • current_value (float | int) – The current analog property value.

  • params (FaultOutOfRange) – Fault parameter configuration with min/max normal value boundaries.

Return type:

Reliability

Returns:

Computed Reliability value.

bac_py.services.fault_algorithms.evaluate_fault_listed(current_value, params, *, fault_list=())[source]

Evaluate FAULT_LISTED (Clause 13.4.7).

Iterates over fault_list – a sequence of (fault_params, evaluator_fn) pairs – and returns the first non-NO_FAULT_DETECTED result. If every evaluator returns NO_FAULT_DETECTED (or the list is empty), NO_FAULT_DETECTED is returned.

params.fault_list_ref tells the caller where to read the fault list; the resolved list content is supplied as fault_list.

Parameters:
  • current_value (Any) – The current property value forwarded to each sub-evaluator.

  • params (FaultListed) – Fault parameter configuration carrying the property reference (used by the caller, not directly by this evaluator).

  • fault_list (tuple[tuple[Any, Callable[..., Reliability]], ...] (default: ())) – Pre-resolved sequence of fault parameter / evaluator pairs.

Return type:

Reliability

Returns:

Computed Reliability value.

Audit Services

Audit services per ASHRAE 135-2020 Clauses 13.19-13.21.

AuditLogQuery (Clause 13.19), ConfirmedAuditNotification (Clause 13.20), UnconfirmedAuditNotification (Clause 13.21).

class bac_py.services.audit.AuditLogQueryRequest(audit_log, query_parameters, requested_count=100, start_at_sequence_number=None)[source]

Bases: object

AuditLogQuery-Request per Clause 13.19.

AuditLogQuery-Request ::= SEQUENCE {
    audit-log             [0] BACnetObjectIdentifier,
    query-parameters      CHOICE {
        by-target         [1] ...,
        by-source         [2] ...
    },
    start-at-seq-number   [3] Unsigned64 OPTIONAL,
    requested-count       [4] Unsigned16
}
Parameters:
audit_log: ObjectIdentifier
query_parameters: AuditQueryByTarget | AuditQueryBySource
requested_count: int
start_at_sequence_number: int | None
encode()[source]

Encode AuditLogQuery-Request.

Return type:

bytes

classmethod decode(data)[source]

Decode AuditLogQuery-Request.

Return type:

Self

Parameters:

data (memoryview | bytes)

class bac_py.services.audit.AuditLogQueryACK(audit_log, records, no_more_items)[source]

Bases: object

AuditLogQuery-ACK per Clause 13.19.

AuditLogQuery-ACK ::= SEQUENCE {
    audit-log         [0] BACnetObjectIdentifier,
    records           [1] SEQUENCE OF BACnetAuditLogRecord,
    no-more-items     [2] BOOLEAN
}
Parameters:
audit_log: ObjectIdentifier
records: list[BACnetAuditLogRecord]
no_more_items: bool
encode()[source]

Encode AuditLogQuery-ACK.

Return type:

bytes

classmethod decode(data)[source]

Decode AuditLogQuery-ACK.

Return type:

Self

Parameters:

data (memoryview | bytes)

class bac_py.services.audit.ConfirmedAuditNotificationRequest(notifications)[source]

Bases: object

ConfirmedAuditNotification-Request per Clause 13.20.

ConfirmedAuditNotification-Request ::= SEQUENCE {
    notifications [0] SEQUENCE OF BACnetAuditNotification
}
Parameters:

notifications (list[BACnetAuditNotification])

notifications: list[BACnetAuditNotification]
encode()[source]

Encode ConfirmedAuditNotification-Request.

Return type:

bytes

classmethod decode(data)[source]

Decode ConfirmedAuditNotification-Request.

Return type:

Self

Parameters:

data (memoryview | bytes)

class bac_py.services.audit.UnconfirmedAuditNotificationRequest(notifications)[source]

Bases: ConfirmedAuditNotificationRequest

UnconfirmedAuditNotification-Request per Clause 13.21.

Same structure as ConfirmedAuditNotification-Request.

Parameters:

notifications (list[BACnetAuditNotification])