#[cfg(not(feature = "std"))]
use alloc::{vec, vec::Vec};
use crate::error::Error;
use crate::primitives::{Date, ObjectIdentifier, Time};
use crate::MacAddr;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BACnetDateRange {
pub start_date: Date,
pub end_date: Date,
}
impl BACnetDateRange {
pub fn encode(&self) -> [u8; 8] {
let mut out = [0u8; 8];
out[..4].copy_from_slice(&self.start_date.encode());
out[4..].copy_from_slice(&self.end_date.encode());
out
}
pub fn decode(data: &[u8]) -> Result<Self, Error> {
if data.len() < 8 {
return Err(Error::buffer_too_short(8, data.len()));
}
Ok(Self {
start_date: Date::decode(&data[0..4])?,
end_date: Date::decode(&data[4..8])?,
})
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BACnetWeekNDay {
pub month: u8,
pub week_of_month: u8,
pub day_of_week: u8,
}
impl BACnetWeekNDay {
pub const ANY: u8 = 0xFF;
pub fn encode(&self) -> [u8; 3] {
[self.month, self.week_of_month, self.day_of_week]
}
pub fn decode(data: &[u8]) -> Result<Self, Error> {
if data.len() < 3 {
return Err(Error::buffer_too_short(3, data.len()));
}
Ok(Self {
month: data[0],
week_of_month: data[1],
day_of_week: data[2],
})
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum BACnetCalendarEntry {
Date(Date),
DateRange(BACnetDateRange),
WeekNDay(BACnetWeekNDay),
}
#[derive(Debug, Clone, PartialEq)]
pub struct BACnetTimeValue {
pub time: Time,
pub value: Vec<u8>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SpecialEventPeriod {
CalendarEntry(BACnetCalendarEntry),
CalendarReference(ObjectIdentifier),
}
#[derive(Debug, Clone, PartialEq)]
pub struct BACnetSpecialEvent {
pub period: SpecialEventPeriod,
pub list_of_time_values: Vec<BACnetTimeValue>,
pub event_priority: u8,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BACnetObjectPropertyReference {
pub object_identifier: ObjectIdentifier,
pub property_identifier: u32,
pub property_array_index: Option<u32>,
}
impl BACnetObjectPropertyReference {
pub fn new(object_identifier: ObjectIdentifier, property_identifier: u32) -> Self {
Self {
object_identifier,
property_identifier,
property_array_index: None,
}
}
pub fn new_indexed(
object_identifier: ObjectIdentifier,
property_identifier: u32,
array_index: u32,
) -> Self {
Self {
object_identifier,
property_identifier,
property_array_index: Some(array_index),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BACnetDeviceObjectPropertyReference {
pub object_identifier: ObjectIdentifier,
pub property_identifier: u32,
pub property_array_index: Option<u32>,
pub device_identifier: Option<ObjectIdentifier>,
}
impl BACnetDeviceObjectPropertyReference {
pub fn new_local(object_identifier: ObjectIdentifier, property_identifier: u32) -> Self {
Self {
object_identifier,
property_identifier,
property_array_index: None,
device_identifier: None,
}
}
pub fn new_remote(
object_identifier: ObjectIdentifier,
property_identifier: u32,
device_identifier: ObjectIdentifier,
) -> Self {
Self {
object_identifier,
property_identifier,
property_array_index: None,
device_identifier: Some(device_identifier),
}
}
pub fn with_index(mut self, array_index: u32) -> Self {
self.property_array_index = Some(array_index);
self
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BACnetAddress {
pub network_number: u16,
pub mac_address: MacAddr,
}
impl BACnetAddress {
pub fn local_broadcast() -> Self {
Self {
network_number: 0,
mac_address: MacAddr::new(),
}
}
pub fn from_ip(ip_port_bytes: [u8; 6]) -> Self {
Self {
network_number: 0,
mac_address: MacAddr::from_slice(&ip_port_bytes),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum BACnetRecipient {
Device(ObjectIdentifier),
Address(BACnetAddress),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BACnetDestination {
pub valid_days: u8,
pub from_time: Time,
pub to_time: Time,
pub recipient: BACnetRecipient,
pub process_identifier: u32,
pub issue_confirmed_notifications: bool,
pub transitions: u8,
}
#[derive(Debug, Clone, PartialEq)]
pub enum LogDatum {
LogStatus(u8),
BooleanValue(bool),
RealValue(f32),
EnumValue(u32),
UnsignedValue(u64),
SignedValue(i64),
BitstringValue {
unused_bits: u8,
data: Vec<u8>,
},
NullValue,
Failure {
error_class: u32,
error_code: u32,
},
TimeChange(f32),
AnyValue(Vec<u8>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct BACnetLogRecord {
pub date: Date,
pub time: Time,
pub log_datum: LogDatum,
pub status_flags: Option<u8>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum BACnetScale {
FloatScale(f32),
IntegerScale(i32),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BACnetPrescale {
pub multiplier: u32,
pub modulo_divide: u32,
}
#[derive(Debug, Clone, PartialEq)]
pub enum BACnetPropertyStates {
BooleanValue(bool), BinaryValue(u32), EventType(u32), Polarity(u32), ProgramChange(u32), ProgramState(u32), ReasonForHalt(u32), Reliability(u32), State(u32), SystemStatus(u32), Units(u32), UnsignedValue(u32), LifeSafetyMode(u32), LifeSafetyState(u32), DoorAlarmState(u32), Action(u32), DoorSecuredStatus(u32), DoorStatus(u32), DoorValue(u32), LiftCarDirection(u32), LiftCarDoorCommand(u32), TimerState(u32), TimerTransition(u32), Other {
tag: u8,
data: Vec<u8>,
},
}
#[derive(Debug, Clone, PartialEq)]
pub enum BACnetShedLevel {
Percent(u32),
Level(u32),
Amount(f32),
}
#[derive(Debug, Clone, PartialEq)]
pub struct BACnetLightingCommand {
pub operation: u32,
pub target_level: Option<f32>,
pub ramp_rate: Option<f32>,
pub step_increment: Option<f32>,
pub fade_time: Option<u32>,
pub priority: Option<u32>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BACnetDeviceObjectReference {
pub device_identifier: Option<ObjectIdentifier>,
pub object_identifier: ObjectIdentifier,
}
#[derive(Debug, Clone, PartialEq)]
pub struct BACnetAccessRule {
pub time_range_specifier: u32,
pub time_range: Option<(Date, Time, Date, Time)>,
pub location_specifier: u32,
pub location: Option<BACnetDeviceObjectReference>,
pub enable: bool,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BACnetAssignedAccessRights {
pub assigned_access_rights: ObjectIdentifier,
pub enable: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub struct BACnetAssignedLandingCalls {
pub floor_number: u8,
pub direction: u32,
}
#[derive(Debug, Clone, PartialEq)]
pub enum FaultParameters {
FaultNone,
FaultCharacterString { fault_values: Vec<String> },
FaultExtended {
vendor_id: u16,
extended_fault_type: u32,
parameters: Vec<u8>,
},
FaultLifeSafety {
fault_values: Vec<u32>,
mode_for_reference: BACnetDeviceObjectPropertyReference,
},
FaultState {
fault_values: Vec<BACnetPropertyStates>,
},
FaultStatusFlags {
reference: BACnetDeviceObjectPropertyReference,
},
FaultOutOfRange { min_normal: f64, max_normal: f64 },
FaultListed {
reference: BACnetDeviceObjectPropertyReference,
},
}
#[derive(Debug, Clone, PartialEq)]
pub struct BACnetRecipientProcess {
pub recipient: BACnetRecipient,
pub process_identifier: u32,
}
#[derive(Debug, Clone, PartialEq)]
pub struct BACnetCOVSubscription {
pub recipient: BACnetRecipientProcess,
pub monitored_property_reference: BACnetObjectPropertyReference,
pub issue_confirmed_notifications: bool,
pub time_remaining: u32,
pub cov_increment: Option<f32>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum BACnetValueSource {
None,
Object(ObjectIdentifier),
Address(BACnetAddress),
}
#[cfg(test)]
mod tests;