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