bacnet_objects/traits.rs
1//! BACnetObject trait — the interface all BACnet objects implement.
2
3use std::borrow::Cow;
4
5use bacnet_types::constructed::BACnetLogRecord;
6use bacnet_types::enums::PropertyIdentifier;
7use bacnet_types::error::Error;
8use bacnet_types::primitives::{ObjectIdentifier, PropertyValue};
9
10use crate::event::EventStateChange;
11
12/// The core trait for all BACnet objects.
13///
14/// Implementors represent a single BACnet object (Device, AnalogInput, etc.)
15/// and provide read/write access to their properties.
16pub trait BACnetObject: Send + Sync {
17 /// The object's identifier (type + instance).
18 fn object_identifier(&self) -> ObjectIdentifier;
19
20 /// The object's name.
21 fn object_name(&self) -> &str;
22
23 /// Read a property value.
24 fn read_property(
25 &self,
26 property: PropertyIdentifier,
27 array_index: Option<u32>,
28 ) -> Result<PropertyValue, Error>;
29
30 /// Write a property value.
31 fn write_property(
32 &mut self,
33 property: PropertyIdentifier,
34 array_index: Option<u32>,
35 value: PropertyValue,
36 priority: Option<u8>,
37 ) -> Result<(), Error>;
38
39 /// List all properties this object supports.
40 fn property_list(&self) -> Cow<'static, [PropertyIdentifier]>;
41
42 /// List the REQUIRED properties for this object type.
43 ///
44 /// Default returns the four universal required properties per Clause 12.11.
45 /// Object implementations may override to include type-specific required properties.
46 fn required_properties(&self) -> Cow<'static, [PropertyIdentifier]> {
47 static UNIVERSAL: [PropertyIdentifier; 4] = [
48 PropertyIdentifier::OBJECT_IDENTIFIER,
49 PropertyIdentifier::OBJECT_NAME,
50 PropertyIdentifier::OBJECT_TYPE,
51 PropertyIdentifier::PROPERTY_LIST,
52 ];
53 Cow::Borrowed(&UNIVERSAL)
54 }
55
56 /// COV increment for this object (analog objects only).
57 ///
58 /// Returns `Some(increment)` for objects that use COV_Increment filtering
59 /// (e.g., AnalogInput, AnalogOutput, AnalogValue). A notification fires only
60 /// when `|current_value - last_notified_value| >= increment`.
61 ///
62 /// Returns `None` for objects that notify on any state change (binary, multi-state).
63 fn cov_increment(&self) -> Option<f32> {
64 None
65 }
66
67 /// Evaluate intrinsic reporting after a present_value change.
68 ///
69 /// Returns `Some(EventStateChange)` if the event state transitioned,
70 /// or `None` if no change occurred (or the object doesn't support intrinsic reporting).
71 fn evaluate_intrinsic_reporting(&mut self) -> Option<EventStateChange> {
72 None
73 }
74
75 /// Evaluate this object's schedule for the given time (Clause 12.24).
76 ///
77 /// Returns `Some((new_value, refs))` if the present value changed, where `refs`
78 /// is the list of (object_identifier, property_identifier) pairs to write to.
79 /// Only meaningful for Schedule objects; default returns `None`.
80 fn tick_schedule(
81 &mut self,
82 _day_of_week: u8,
83 _hour: u8,
84 _minute: u8,
85 ) -> Option<(PropertyValue, Vec<(ObjectIdentifier, u32)>)> {
86 None
87 }
88
89 /// Acknowledge an alarm transition. Sets the corresponding bit in acked_transitions.
90 /// Returns Ok(()) if the object supports event detection, Err otherwise.
91 fn acknowledge_alarm(&mut self, _transition_bit: u8) -> Result<(), bacnet_types::error::Error> {
92 Err(bacnet_types::error::Error::Protocol {
93 class: bacnet_types::enums::ErrorClass::OBJECT.to_raw() as u32,
94 code: bacnet_types::enums::ErrorCode::OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED.to_raw()
95 as u32,
96 })
97 }
98
99 /// Add a trend log record (only meaningful for TrendLog / TrendLogMultiple).
100 ///
101 /// Default is a no-op. TrendLog objects override to append to their buffer.
102 fn add_trend_record(&mut self, _record: BACnetLogRecord) {}
103}