pub trait BACnetObject: Send + Sync {
Show 37 methods
// Required methods
fn object_identifier(&self) -> ObjectIdentifier;
fn object_name(&self) -> &str;
fn read_property(
&self,
property: PropertyIdentifier,
array_index: Option<u32>,
) -> Result<PropertyValue, Error>;
fn write_property(
&mut self,
property: PropertyIdentifier,
array_index: Option<u32>,
value: PropertyValue,
priority: Option<u8>,
) -> Result<(), Error>;
fn property_list(&self) -> Cow<'static, [PropertyIdentifier]>;
// Provided methods
fn property_metadata(&self) -> Cow<'_, [PropertyMetadata]> { ... }
fn is_writable_property(&self, property: PropertyIdentifier) -> bool { ... }
fn is_array_property(&self, property: PropertyIdentifier) -> bool { ... }
fn is_createable(&self) -> bool { ... }
fn is_deleteable(&self) -> bool { ... }
fn required_properties(&self) -> Cow<'static, [PropertyIdentifier]> { ... }
fn supports_cov(&self) -> bool { ... }
fn supports_cov_property(&self, property: PropertyIdentifier) -> bool { ... }
fn cov_increment(&self) -> Option<f32> { ... }
fn set_overridden(&mut self, _overridden: bool) { ... }
fn evaluate_intrinsic_reporting(&mut self) -> Option<TransitionOutcome> { ... }
fn tick_intrinsic_reporting(&mut self) -> Option<TransitionOutcome> { ... }
fn tick_schedule(
&mut self,
_day_of_week: u8,
_hour: u8,
_minute: u8,
) -> Option<(PropertyValue, Vec<(ObjectIdentifier, u32)>)> { ... }
fn acknowledge_alarm(&mut self, _transition_bit: u8) -> Result<(), Error> { ... }
fn apply_life_safety_operation(
&mut self,
_operation: LifeSafetyOperation,
) -> Result<LifeSafetyOperationEffect, Error> { ... }
fn apply_life_safety_operation_detailed(
&mut self,
operation: LifeSafetyOperation,
) -> Result<LifeSafetyOperationOutcome, Error> { ... }
fn set_life_safety_operation_expected_internal(
&mut self,
_operation: LifeSafetyOperation,
) -> Result<(), Error> { ... }
fn set_event_state_internal(
&mut self,
_state: EventState,
) -> Result<(), Error> { ... }
fn enrollment_eval_state_internal(&self) -> Option<EventEnrollmentEvalState> { ... }
fn set_enrollment_eval_state_internal(
&mut self,
_state: EventEnrollmentEvalState,
) -> Result<(), Error> { ... }
fn enrollment_eval_source_internal(
&self,
) -> Option<Option<EventEnrollmentMonitoredSource>> { ... }
fn set_enrollment_eval_source_internal(
&mut self,
_source: Option<EventEnrollmentMonitoredSource>,
) -> Result<(), Error> { ... }
fn set_acked_transitions_internal(
&mut self,
_transition_bit: u8,
_acknowledged: bool,
) -> Result<(), Error> { ... }
fn evaluate_reliability_internal(
&mut self,
) -> Result<ReliabilityEvaluation, Error> { ... }
fn set_reliability_internal(
&mut self,
_reliability: u32,
) -> Result<(), Error> { ... }
fn set_present_value_internal(
&mut self,
_value: PropertyValue,
) -> Result<(), Error> { ... }
fn audit_log_storage_internal(&self) -> Option<&dyn AuditLogStorage> { ... }
fn audit_log_notification_sink_internal(
&mut self,
) -> Option<&mut dyn AuditLogNotificationSink> { ... }
fn file_storage_internal(&self) -> Option<&dyn FileStorage> { ... }
fn file_storage_internal_mut(&mut self) -> Option<&mut dyn FileStorage> { ... }
fn log_record_identities_internal(&self) -> Option<Vec<LogRecordIdentity>> { ... }
fn add_trend_record(&mut self, _record: BACnetLogRecord) { ... }
}Expand description
The core trait for all BACnet objects.
Implementors represent a single BACnet object (Device, AnalogInput, etc.) and provide read/write access to their properties.
Required Methods§
Sourcefn object_identifier(&self) -> ObjectIdentifier
fn object_identifier(&self) -> ObjectIdentifier
The object’s identifier (type + instance).
Sourcefn object_name(&self) -> &str
fn object_name(&self) -> &str
The object’s name.
Sourcefn read_property(
&self,
property: PropertyIdentifier,
array_index: Option<u32>,
) -> Result<PropertyValue, Error>
fn read_property( &self, property: PropertyIdentifier, array_index: Option<u32>, ) -> Result<PropertyValue, Error>
Read a property value.
Sourcefn write_property(
&mut self,
property: PropertyIdentifier,
array_index: Option<u32>,
value: PropertyValue,
priority: Option<u8>,
) -> Result<(), Error>
fn write_property( &mut self, property: PropertyIdentifier, array_index: Option<u32>, value: PropertyValue, priority: Option<u8>, ) -> Result<(), Error>
Write a property value.
Returning Err MUST leave the object unchanged. WritePropertyMultiple
retains earlier successful writes and cannot undo a mutation made by the
currently failing write, including for a write-only property.
Sourcefn property_list(&self) -> Cow<'static, [PropertyIdentifier]>
fn property_list(&self) -> Cow<'static, [PropertyIdentifier]>
List all properties this object supports in the legacy projection.
For migrated objects this includes Object_Identifier, Object_Name, and Object_Type but omits Property_List. Reading the BACnet Property_List property applies the additional wire-level universal-property filter.
Provided Methods§
Sourcefn property_metadata(&self) -> Cow<'_, [PropertyMetadata]>
fn property_metadata(&self) -> Cow<'_, [PropertyMetadata]>
Return canonical metadata for this object’s effective property rows.
Migrated implementations return every supported standard row for the
current instance, including PROPERTY_LIST. Borrowed rows cover static
or object-owned metadata; owned rows support dynamically assembled
per-instance sets. An empty borrowed default marks an object as unmigrated.
Sourcefn is_writable_property(&self, property: PropertyIdentifier) -> bool
fn is_writable_property(&self, property: PropertyIdentifier) -> bool
Whether write_property accepts property for this object.
PICS generation and runtime dispatch MUST consult this (or
write_property itself) rather than a separate heuristic, so the PICS
writable flags cannot drift from the actual write routes. The default
reproduces the historical PICS heuristic (see
[historical_writable_default]) so unmigrated object types keep their
current PICS output. Object implementations override to mirror their
real write_property arms exactly.
Universal read-only properties (OBJECT_IDENTIFIER, OBJECT_TYPE,
PROPERTY_LIST, STATUS_FLAGS) are always non-writable and are
excluded by the default; overrides should preserve that invariant.
Sourcefn is_array_property(&self, property: PropertyIdentifier) -> bool
fn is_array_property(&self, property: PropertyIdentifier) -> bool
Whether property accepts an array index on this object.
Per Clause 12.1.5.1, only BACnetARRAY (and BACnetARRAY of BACnetLIST) properties accept an array index; Clause 12.1.5.2 makes ReadRange the only positional access to a BACnetLIST. The RP/RPM/WP/WPM service handlers gate the request’s array index on this query and reject a supplied index on a non-array property with PROPERTY / PROPERTY_IS_NOT_AN_ARRAY (Clause 15.5.1.3, Clause 15.9.1.3).
The default reproduces the standard’s classification (see
[array_property_default]): identifier-stable arrays are admitted
without consulting the object type, the identifiers whose datatype
changes with the object type (ALARM_VALUES / FAULT_VALUES,
LIST_OF_OBJECT_PROPERTY_REFERENCES, PRESENT_VALUE) classify by
object_identifier().object_type(), and everything else — scalars and
BACnetLIST properties — rejects the index. Object implementations with
vendor or per-instance array properties override.
Sourcefn is_createable(&self) -> bool
fn is_createable(&self) -> bool
Whether this object type can be created at runtime via CreateObject.
Default false; override true only for types the network factory
(handle_create_object) actually constructs, so PICS createability
matches the runtime factory with no separate list to drift.
Sourcefn is_deleteable(&self) -> bool
fn is_deleteable(&self) -> bool
Whether this object type can be deleted at runtime via DeleteObject.
Default true; override false on object types that are not
deleteable (e.g. Device, NetworkPort).
Sourcefn required_properties(&self) -> Cow<'static, [PropertyIdentifier]>
fn required_properties(&self) -> Cow<'static, [PropertyIdentifier]>
List the REQUIRED properties for this object type.
Migrated objects derive this set from canonical R and W rows,
including Property_List. Unmigrated objects retain the historical four
universal properties. Service-specific consumers may exclude
Property_List where their protocol contract requires it.
Sourcefn supports_cov(&self) -> bool
fn supports_cov(&self) -> bool
Whether this object type supports COV notifications.
Override to return true for object types that can generate COV
notifications (analog, binary, multi-state I/O/V). Default is false.
Sourcefn supports_cov_property(&self, property: PropertyIdentifier) -> bool
fn supports_cov_property(&self, property: PropertyIdentifier) -> bool
Whether a readable property supports property-specific COV.
The default preserves the existing behavior of every other COV-capable object family while enforcing the bounded standardized Life Safety surface for source-compatible custom Point and Zone implementations.
Sourcefn cov_increment(&self) -> Option<f32>
fn cov_increment(&self) -> Option<f32>
COV increment for this object (analog objects only).
Returns Some(increment) for objects that use COV_Increment filtering
(e.g., AnalogInput, AnalogOutput, AnalogValue). A notification fires only
when |current_value - last_notified_value| >= increment.
Returns None for objects that notify on any state change (binary, multi-state).
Sourcefn set_overridden(&mut self, _overridden: bool)
fn set_overridden(&mut self, _overridden: bool)
Set the OVERRIDDEN bit in StatusFlags.
For software-only objects this is always FALSE per spec. Hardware integrations can override to set TRUE when present_value is overridden by physical means (e.g., a manual switch on an output).
Sourcefn evaluate_intrinsic_reporting(&mut self) -> Option<TransitionOutcome>
fn evaluate_intrinsic_reporting(&mut self) -> Option<TransitionOutcome>
Evaluate intrinsic reporting after a present_value change.
This is the per-write entry point: it seeds (or cancels) a pending
delayed transition and fires immediately only when Time_Delay == 0.
It never advances the Time_Delay countdown — repeated writes to the
same value do not shorten the delay (per ASHRAE 135-2020 §13.2.4 the
countdown advances once per elapsed second via
tick_intrinsic_reporting).
Returns Some(TransitionOutcome) whenever a transition is ready to be
committed, or
None when none did (no change, delay seeded, or the object does not
support intrinsic reporting). A cleared Event_Enable bit sets the
outcome’s distribute flag to false rather than withholding the
transition. Built-in object families leave Event_State,
Acked_Transitions, event history, and fire-ready detector state
unchanged until commit_event_transition_internal
succeeds. Clause 13.2.2.1.4’s transition actions run either way, and
Event_Enable disables only external distribution, downstream in the
notification-distribution process (Clause 13.2.5).
Sourcefn tick_intrinsic_reporting(&mut self) -> Option<TransitionOutcome>
fn tick_intrinsic_reporting(&mut self) -> Option<TransitionOutcome>
Advance the Time_Delay countdown for a pending transition.
Called by the server’s one-second intrinsic-reporting task. Fires the
pending transition when its delay elapses this tick, cancels it if the
triggering condition reverted, and returns Some(TransitionOutcome)
when a transition is ready. A fire-ready built-in proposal remains
retryable until the commit hook succeeds. As with
evaluate_intrinsic_reporting,
Event_Enable is reported via distribute, not by returning None.
Objects without a delayed transition return None.
Sourcefn tick_schedule(
&mut self,
_day_of_week: u8,
_hour: u8,
_minute: u8,
) -> Option<(PropertyValue, Vec<(ObjectIdentifier, u32)>)>
fn tick_schedule( &mut self, _day_of_week: u8, _hour: u8, _minute: u8, ) -> Option<(PropertyValue, Vec<(ObjectIdentifier, u32)>)>
Evaluate this object’s schedule for the given time.
Returns Some((new_value, refs)) if the present value changed, where refs
is the list of (object_identifier, property_identifier) pairs to write to.
Only meaningful for Schedule objects; default returns None.
Sourcefn acknowledge_alarm(&mut self, _transition_bit: u8) -> Result<(), Error>
fn acknowledge_alarm(&mut self, _transition_bit: u8) -> Result<(), Error>
Acknowledge an alarm transition. Sets the corresponding bit in acked_transitions. Returns Ok(()) if the object supports event detection, Err otherwise.
Sourcefn apply_life_safety_operation(
&mut self,
_operation: LifeSafetyOperation,
) -> Result<LifeSafetyOperationEffect, Error>
fn apply_life_safety_operation( &mut self, _operation: LifeSafetyOperation, ) -> Result<LifeSafetyOperationEffect, Error>
Apply a LifeSafetyOperation atomically to this object.
Implementations must leave the object unchanged when returning Err.
They run synchronously under the object-database write lock and must be
fast, nonblocking, and panic-free. External or irreversible actuation
also needs an application-owned idempotency/replay contract. The default
reports that the object does not support this service.
Sourcefn apply_life_safety_operation_detailed(
&mut self,
operation: LifeSafetyOperation,
) -> Result<LifeSafetyOperationOutcome, Error>
fn apply_life_safety_operation_detailed( &mut self, operation: LifeSafetyOperation, ) -> Result<LifeSafetyOperationOutcome, Error>
Apply a LifeSafetyOperation and report exact known property deltas.
The default delegates to the source-compatible coarse hook and reports no known properties rather than guessing about custom object state.
Sourcefn set_life_safety_operation_expected_internal(
&mut self,
_operation: LifeSafetyOperation,
) -> Result<(), Error>
fn set_life_safety_operation_expected_internal( &mut self, _operation: LifeSafetyOperation, ) -> Result<(), Error>
Set the next LifeSafetyOperation expected by trusted local logic.
This is an application-facing state channel, not a network property write. The default reports that the object does not support the state.
Sourcefn set_event_state_internal(&mut self, _state: EventState) -> Result<(), Error>
fn set_event_state_internal(&mut self, _state: EventState) -> Result<(), Error>
Apply an internally-detected Event_State transition.
This is the internal lifecycle path for the algorithmically-derived
Event_State on objects such as Event Enrollment (ASHRAE 135-2020
Clause 12.12). It is deliberately distinct from the network
write_property route: Event_State is
read-only over the network, so network writes are rejected while the
server’s evaluator reaches the field through this method. Objects
without an algorithmic Event_State return
OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED.
The default returns Err, so objects without an algorithmic
Event_State opt out. Objects that do model one (e.g.
EventEnrollmentObject) override this to store the value verbatim:
the only caller is a trusted internal evaluator that passes a modeled
EventState, mirroring the inherent set_event_state builder and
the existing read arm. Network-facing validation — rejecting all
Event_State writes — lives in write_property,
not here. Implementations must leave Event_State unchanged when they
return Err.
Sourcefn enrollment_eval_state_internal(&self) -> Option<EventEnrollmentEvalState>
fn enrollment_eval_state_internal(&self) -> Option<EventEnrollmentEvalState>
Snapshot this object’s Event Enrollment evaluation state, if it models one.
This is the read half of the internal channel the server’s Event
Enrollment evaluator uses to persist per-enrollment algorithm state
across evaluation cycles: the pending (delayed) transition countdown,
the CHANGE_OF_VALUE detection baseline (Clause 13.3.3: “the value of
the monitored value when a transition to NORMAL is indicated”), and
the value that caused the last transition to OFFNORMAL (Clause 13.3.2
condition (c)). Like set_event_state_internal
it deliberately bypasses the network property model: none of the three
slots is a BACnet property, and 135-2020 assigns their initialization
to local matters.
The default returns None — objects without algorithmic event
detection carry no such state, and the evaluator treats None as an
empty state it cannot write back (delay honoring and the COV baseline
then stay unavailable, matching this crate’s pre-delay behavior).
Sourcefn set_enrollment_eval_state_internal(
&mut self,
_state: EventEnrollmentEvalState,
) -> Result<(), Error>
fn set_enrollment_eval_state_internal( &mut self, _state: EventEnrollmentEvalState, ) -> Result<(), Error>
Store this object’s Event Enrollment evaluation state.
The write half of enrollment_eval_state_internal.
The only caller is the trusted server evaluator, passing a state it
derived from a prior snapshot plus the current cycle’s evaluation.
Implementations enforce the Clause 13.2.2.1 invariant by construction:
while Event_Detection_Enable is FALSE “no transitions shall occur”,
so a write arriving then is refused rather than queued (and the
detection-disable reset has already cleared the fields).
The default returns Err, so objects without enrollment evaluation
state opt out and the evaluator’s write-back is dropped, never stored
into an object that does not model it.
Sourcefn enrollment_eval_source_internal(
&self,
) -> Option<Option<EventEnrollmentMonitoredSource>>
fn enrollment_eval_source_internal( &self, ) -> Option<Option<EventEnrollmentMonitoredSource>>
Snapshot the monitored source that owns Event Enrollment private state.
The outer Option indicates whether the object supports this channel;
the inner Option is empty before a source has been established.
The server stores source ownership in its object database when an
object implements evaluation state but leaves this channel unsupported.
Sourcefn set_enrollment_eval_source_internal(
&mut self,
_source: Option<EventEnrollmentMonitoredSource>,
) -> Result<(), Error>
fn set_enrollment_eval_source_internal( &mut self, _source: Option<EventEnrollmentMonitoredSource>, ) -> Result<(), Error>
Store or clear the monitored source that owns Event Enrollment state.
Sourcefn set_acked_transitions_internal(
&mut self,
_transition_bit: u8,
_acknowledged: bool,
) -> Result<(), Error>
fn set_acked_transitions_internal( &mut self, _transition_bit: u8, _acknowledged: bool, ) -> Result<(), Error>
Set or clear one Acked_Transitions bit on a received event-state
transition.
Implements the alarm-acknowledgment half of Clause 13.2.2.1.4’s fourth
transition action (“indicate the transition to the Alarm-Acknowledgment
process”), per Clause 13.2.3: “When an event state transition is
received, the corresponding bit in Acked_Transitions is either set or
cleared. If the corresponding bit in Ack_Required is set, then the bit
in Acked_Transitions is cleared, otherwise it is set.” The caller (the
server evaluator) resolves Ack_Required from the referenced
Notification Class object and passes the outcome as acknowledged;
this method performs only the bit maintenance.
transition_bit is the transition direction’s bit mask in
Acked_Transitions’ internal bit0-first form (0x01 TO_OFFNORMAL,
0x02 TO_FAULT, 0x04 TO_NORMAL). The set half overlaps the
network-reachable acknowledge_alarm, which
also ORs the bit in per Clause 13.2.3’s acknowledgment-indication
paragraph; the clear half has no network route by design (a property
write could fabricate or erase acknowledgments — see the
write_generic_event_properties! denial comment).
The default returns Err, so objects without an algorithmic
Acked_Transitions opt out.
Sourcefn evaluate_reliability_internal(
&mut self,
) -> Result<ReliabilityEvaluation, Error>
fn evaluate_reliability_internal( &mut self, ) -> Result<ReliabilityEvaluation, Error>
Evaluate and, when necessary, mutate this object’s Reliability.
Reliability evaluation is object-owned: an implementation decides
whether and how its internal conditions affect Reliability, performs
the mutation itself, and returns ReliabilityEvaluation::Changed only
after that mutation succeeds. ReliabilityEvaluation::Unchanged means
the object made no mutation. Returning Err MUST leave all object state
unchanged.
The default opts out without changing state, preserving source compatibility for object implementations that do not own a reliability evaluation algorithm.
Sourcefn set_reliability_internal(&mut self, _reliability: u32) -> Result<(), Error>
fn set_reliability_internal(&mut self, _reliability: u32) -> Result<(), Error>
Apply an internally-derived Reliability value.
This is the internal reliability-evaluation path, distinct from the
network write_property route. Implementations
enforce symmetric ownership: clients may write while Out_Of_Service
is TRUE, and internal evaluation may write while it is FALSE. ASHRAE
135-2020 Clause 3.2 defines reliability evaluation as “the process by
which an object determines its reliability and thus the value to set
into its Reliability property.”
The default rejects the operation, so object types without an internal reliability-evaluation process remain unaffected.
Sourcefn set_present_value_internal(
&mut self,
_value: PropertyValue,
) -> Result<(), Error>
fn set_present_value_internal( &mut self, _value: PropertyValue, ) -> Result<(), Error>
Apply the logical Present_Value supplied by an Input’s application.
This narrow internal hook is distinct from the network
write_property route. Built-in Analog Input,
Binary Input, and Multi-state Input objects opt in. Their implementations
accept application updates only while in service; rejecting them while
Out_Of_Service is TRUE is a local ownership policy that protects the
client’s simulation value, not a requirement imposed by the Standard.
The default fails closed so commandable and other object families do not
acquire privileged Present_Value write authority through this hook.
Sourcefn audit_log_storage_internal(&self) -> Option<&dyn AuditLogStorage>
fn audit_log_storage_internal(&self) -> Option<&dyn AuditLogStorage>
Borrow this object’s Audit Log query storage, if it has any.
This read-only, type-erased channel lets the bundled server execute an
AuditLogQuery against an object’s already-loaded retained records. It
deliberately does not expose persistence, mutation, or object
downcasting. The default returns None; an Audit Log object that
does not opt in is reported as SERVICES /
OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED.
Sourcefn audit_log_notification_sink_internal(
&mut self,
) -> Option<&mut dyn AuditLogNotificationSink>
fn audit_log_notification_sink_internal( &mut self, ) -> Option<&mut dyn AuditLogNotificationSink>
Mutably borrow this object’s Audit notification receiver capability.
The default opts out. Implementations own their persistence transaction and must leave memory unchanged when the batch cannot be committed.
Sourcefn file_storage_internal(&self) -> Option<&dyn FileStorage>
fn file_storage_internal(&self) -> Option<&dyn FileStorage>
Borrow this object’s File storage, if it has any.
This is the read half of the internal channel the server’s
AtomicReadFile handler uses to reach file contents. Like
set_event_state_internal it
bypasses the property model on purpose: Table 12-16 (ASHRAE 135-2020
Clause 12.13) defines no File Data property, so file contents are
reachable only through the Clause 14 File Access Services.
The default returns None, so object types without a file opt
out; the server reports None on a File-typed object as SERVICES /
FILE_ACCESS_DENIED (Clause 18: “a file that is currently locked or
otherwise not accessible”) rather than reading it as empty.
Applications backing a File object with their own storage — a disk
file, a firmware partition — implement FileStorage and return
Some.
Sourcefn file_storage_internal_mut(&mut self) -> Option<&mut dyn FileStorage>
fn file_storage_internal_mut(&mut self) -> Option<&mut dyn FileStorage>
Mutably borrow this object’s File storage, if it has any.
The write half of
file_storage_internal, used by the
AtomicWriteFile handler after the read-only and access-method gates
have passed. The default returns None.
Sourcefn log_record_identities_internal(&self) -> Option<Vec<LogRecordIdentity>>
fn log_record_identities_internal(&self) -> Option<Vec<LogRecordIdentity>>
Return stable identities aligned with this object’s resident log records.
Implementing log objects return identities oldest-to-newest, in the
same order as their public resident-record view and LOG_BUFFER
projection. Sequence numbers are object-owned metadata and never part
of a projected BACnet record payload. Non-log objects return None.
Sourcefn add_trend_record(&mut self, _record: BACnetLogRecord)
fn add_trend_record(&mut self, _record: BACnetLogRecord)
Add a trend log record (only meaningful for TrendLog / TrendLogMultiple).
Default is a no-op. TrendLog objects override to append to their buffer.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".