Skip to main content

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}