use bacnet_types::enums::AccessZoneOccupancyState;
use bacnet_types::error::Error;
use crate::common;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) struct Occupancy {
pub(super) enabled: bool,
pub(super) adjust_value: i32,
pub(super) lower_limit: u64,
pub(super) upper_limit: u64,
}
impl Occupancy {
pub(super) const NEW: Self = Self {
enabled: true,
adjust_value: 0,
lower_limit: 0,
upper_limit: 0,
};
pub(super) fn state(&self, count: u64) -> AccessZoneOccupancyState {
let lower = self.lower_limit;
let upper = self.upper_limit;
if !self.enabled {
AccessZoneOccupancyState::DISABLED
} else if lower != 0 && count < lower {
AccessZoneOccupancyState::BELOW_LOWER_LIMIT
} else if lower != 0 && count == lower {
AccessZoneOccupancyState::AT_LOWER_LIMIT
} else if upper != 0 && count > upper {
AccessZoneOccupancyState::ABOVE_UPPER_LIMIT
} else if upper != 0 && count == upper {
AccessZoneOccupancyState::AT_UPPER_LIMIT
} else {
AccessZoneOccupancyState::NORMAL
}
}
pub(super) fn set_limits(&mut self, lower: u64, upper: u64) -> Result<(), Error> {
if upper != 0 && upper <= lower {
return Err(common::value_out_of_range_error());
}
self.lower_limit = lower;
self.upper_limit = upper;
Ok(())
}
}
pub(super) fn adjusted(count: u64, adjust: i32) -> u64 {
match adjust {
0 => 0,
up if up > 0 => count.saturating_add(up.unsigned_abs().into()),
down => count.saturating_sub(down.unsigned_abs().into()),
}
}