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.
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    /// Whether this object type supports COV notifications.
57    ///
58    /// Override to return `true` for object types that can generate COV
59    /// notifications (analog, binary, multi-state I/O/V). Default is `false`.
60    fn supports_cov(&self) -> bool {
61        false
62    }
63
64    /// COV increment for this object (analog objects only).
65    ///
66    /// Returns `Some(increment)` for objects that use COV_Increment filtering
67    /// (e.g., AnalogInput, AnalogOutput, AnalogValue). A notification fires only
68    /// when `|current_value - last_notified_value| >= increment`.
69    ///
70    /// Returns `None` for objects that notify on any state change (binary, multi-state).
71    fn cov_increment(&self) -> Option<f32> {
72        None
73    }
74
75    /// Set the OVERRIDDEN bit in StatusFlags.
76    ///
77    /// For software-only objects this is always FALSE per spec. Hardware
78    /// integrations can override to set TRUE when present_value is overridden
79    /// by physical means (e.g., a manual switch on an output).
80    fn set_overridden(&mut self, _overridden: bool) {}
81
82    /// Evaluate intrinsic reporting after a present_value change.
83    ///
84    /// Returns `Some(EventStateChange)` if the event state transitioned,
85    /// or `None` if no change occurred (or the object doesn't support intrinsic reporting).
86    fn evaluate_intrinsic_reporting(&mut self) -> Option<EventStateChange> {
87        None
88    }
89
90    /// Evaluate this object's schedule for the given time.
91    ///
92    /// Returns `Some((new_value, refs))` if the present value changed, where `refs`
93    /// is the list of (object_identifier, property_identifier) pairs to write to.
94    /// Only meaningful for Schedule objects; default returns `None`.
95    fn tick_schedule(
96        &mut self,
97        _day_of_week: u8,
98        _hour: u8,
99        _minute: u8,
100    ) -> Option<(PropertyValue, Vec<(ObjectIdentifier, u32)>)> {
101        None
102    }
103
104    /// Acknowledge an alarm transition. Sets the corresponding bit in acked_transitions.
105    /// Returns Ok(()) if the object supports event detection, Err otherwise.
106    fn acknowledge_alarm(&mut self, _transition_bit: u8) -> Result<(), bacnet_types::error::Error> {
107        Err(bacnet_types::error::Error::Protocol {
108            class: bacnet_types::enums::ErrorClass::OBJECT.to_raw() as u32,
109            code: bacnet_types::enums::ErrorCode::OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED.to_raw()
110                as u32,
111        })
112    }
113
114    /// Add a trend log record (only meaningful for TrendLog / TrendLogMultiple).
115    ///
116    /// Default is a no-op. TrendLog objects override to append to their buffer.
117    fn add_trend_record(&mut self, _record: BACnetLogRecord) {}
118}