bacnet_objects/elevator/
escalator.rs1use crate::prelude::*;
4use alloc::borrow::Cow;
5use bacnet_types::constructed::BACnetDeviceObjectReference;
6use bacnet_types::enums::{
7 EscalatorFault, EscalatorMode, EscalatorOperationDirection, ObjectType, PropertyIdentifier,
8 Reliability,
9};
10use bacnet_types::error::Error;
11use bacnet_types::primitives::{ObjectIdentifier, PropertyValue, StatusFlags};
12
13use super::energy_meter::{EnergyMeter, energy_meter_accessors};
14use super::membership::{GroupMembership, group_membership_accessors};
15use super::{decode_fault_signals, metadata, named_or_proprietary};
16use crate::common::{self, read_common_properties};
17use crate::traits::BACnetObject;
18
19pub struct EscalatorObject {
24 oid: ObjectIdentifier,
25 name: String,
26 description: String,
27 membership: GroupMembership,
29 pub(super) escalator_mode: EscalatorMode,
32 pub(super) fault_signals: Vec<EscalatorFault>,
34 energy_meter: EnergyMeter,
36 power_mode: bool,
38 pub(super) operation_direction: EscalatorOperationDirection,
41 passenger_alarm: bool,
43 status_flags: StatusFlags,
44 out_of_service: bool,
45 reliability: Reliability,
46}
47
48impl EscalatorObject {
49 pub fn new(instance: u32, name: impl Into<String>) -> Result<Self, Error> {
51 let oid = ObjectIdentifier::new(ObjectType::ESCALATOR, instance)?;
52 Ok(Self {
53 oid,
54 name: name.into(),
55 description: String::new(),
56 membership: GroupMembership::new()?,
57 escalator_mode: EscalatorMode::UNKNOWN,
58 fault_signals: Vec::new(),
59 energy_meter: EnergyMeter::new()?,
60 power_mode: false,
61 operation_direction: EscalatorOperationDirection::UNKNOWN,
62 passenger_alarm: false,
63 status_flags: StatusFlags::empty(),
64 out_of_service: false,
65 reliability: Reliability::NO_FAULT_DETECTED,
66 })
67 }
68
69 group_membership_accessors!("escalator");
70 energy_meter_accessors!("escalator");
71}
72
73impl BACnetObject for EscalatorObject {
74 fn object_identifier(&self) -> ObjectIdentifier {
75 self.oid
76 }
77
78 fn object_name(&self) -> &str {
79 &self.name
80 }
81
82 fn read_property(
83 &self,
84 property: PropertyIdentifier,
85 array_index: Option<u32>,
86 ) -> Result<PropertyValue, Error> {
87 if let Some(result) = read_common_properties!(self, property, array_index) {
88 return result;
89 }
90 if let Some(value) = self.membership.read(property) {
91 return Ok(value);
92 }
93 if let Some(value) = self.energy_meter.read(property) {
94 return Ok(value);
95 }
96 match property {
97 p if p == PropertyIdentifier::OBJECT_TYPE => {
98 Ok(PropertyValue::Enumerated(ObjectType::ESCALATOR.to_raw()))
99 }
100 p if p == PropertyIdentifier::ESCALATOR_MODE => {
101 Ok(PropertyValue::Enumerated(self.escalator_mode.to_raw()))
102 }
103 p if p == PropertyIdentifier::FAULT_SIGNALS => {
104 let items: Vec<PropertyValue> = self
105 .fault_signals
106 .iter()
107 .map(|v| PropertyValue::Enumerated(v.to_raw()))
108 .collect();
109 Ok(PropertyValue::List(items))
110 }
111 p if p == PropertyIdentifier::POWER_MODE => Ok(PropertyValue::Boolean(self.power_mode)),
112 p if p == PropertyIdentifier::OPERATION_DIRECTION => {
113 Ok(PropertyValue::Enumerated(self.operation_direction.to_raw()))
114 }
115 p if p == PropertyIdentifier::PASSENGER_ALARM => {
116 Ok(PropertyValue::Boolean(self.passenger_alarm))
117 }
118 _ => Err(common::unknown_property_error()),
119 }
120 }
121
122 fn write_property(
123 &mut self,
124 property: PropertyIdentifier,
125 _array_index: Option<u32>,
126 value: PropertyValue,
127 _priority: Option<u8>,
128 ) -> Result<(), Error> {
129 if let Some(result) =
130 common::write_out_of_service(&mut self.out_of_service, property, &value)
131 {
132 return result;
133 }
134 if let Some(result) = common::write_description(&mut self.description, property, &value) {
135 return result;
136 }
137 if let Some(result) = self.energy_meter.write(property, &value) {
138 return result;
139 }
140 match property {
141 p if p == PropertyIdentifier::POWER_MODE => {
142 if let PropertyValue::Boolean(v) = value {
143 self.power_mode = v;
144 Ok(())
145 } else {
146 Err(common::invalid_data_type_error())
147 }
148 }
149 p if p == PropertyIdentifier::ESCALATOR_MODE => {
150 if let PropertyValue::Enumerated(v) = value {
151 let mode = EscalatorMode::from_raw(v);
152 if !named_or_proprietary(EscalatorMode::ALL_NAMED, mode, v) {
153 return Err(common::value_out_of_range_error());
154 }
155 self.escalator_mode = mode;
156 Ok(())
157 } else {
158 Err(common::invalid_data_type_error())
159 }
160 }
161 p if p == PropertyIdentifier::OPERATION_DIRECTION => {
162 if let PropertyValue::Enumerated(v) = value {
163 let direction = EscalatorOperationDirection::from_raw(v);
166 if !named_or_proprietary(EscalatorOperationDirection::ALL_NAMED, direction, v) {
167 return Err(common::value_out_of_range_error());
168 }
169 self.operation_direction = direction;
170 Ok(())
171 } else {
172 Err(common::invalid_data_type_error())
173 }
174 }
175 p if p == PropertyIdentifier::FAULT_SIGNALS => {
176 self.fault_signals = decode_fault_signals(
177 value,
178 EscalatorFault::ALL_NAMED,
179 EscalatorFault::from_raw,
180 )?;
181 Ok(())
182 }
183 p if p == PropertyIdentifier::PASSENGER_ALARM => {
184 if let PropertyValue::Boolean(v) = value {
185 self.passenger_alarm = v;
186 Ok(())
187 } else {
188 Err(common::invalid_data_type_error())
189 }
190 }
191 _ => Err(crate::common::unhandled_write_error(
192 self.property_metadata().as_ref(),
193 property,
194 _array_index,
195 )),
196 }
197 }
198
199 fn property_metadata(&self) -> Cow<'_, [crate::property_metadata::PropertyMetadata]> {
200 metadata::for_escalator_object(self)
201 }
202
203 fn property_list(&self) -> Cow<'static, [PropertyIdentifier]> {
204 crate::property_metadata::property_list_from_metadata(self.property_metadata().as_ref())
205 }
206}