#[cfg(not(feature = "std"))]
use alloc::{string::String, vec::Vec};
use crate::bitstring::{DaysOfWeek, EventTransitionBits};
use crate::enums::LifeSafetyState;
use crate::error::Error;
use crate::primitives::{Date, ObjectIdentifier, PropertyValue, Time};
use crate::MacAddr;
mod action;
pub use action::{BACnetActionCommand, BACnetActionList};
mod access;
pub use access::{
BACnetAccessRule, BACnetAssignedAccessRights, BACnetAuthenticationFactor,
BACnetAuthenticationFactorFormat, BACnetAuthenticationPolicy, BACnetAuthenticationPolicyEntry,
BACnetCredentialAuthenticationFactor,
};
mod audit;
pub use audit::{
AuditPropertyReference, BACnetAuditLogDatum, BACnetAuditLogQueryParameters,
BACnetAuditLogRecord, BACnetAuditLogRecordResult, BACnetAuditNotification,
BACnetObjectSelector,
};
mod color;
pub use color::{BACnetColorCommand, BACnetXyColor};
mod event_notification;
pub use event_notification::{
ChangeOfValueChoice, EventNotificationRequest, NotificationParameters,
};
mod lift;
pub use lift::{
AssignedLandingCall, BACnetAssignedLandingCalls, BACnetLandingCallStatus,
BACnetLandingDoorStatus, BACnetLiftCarCallList, LandingCallCommand, LandingDoor,
};
mod lighting;
pub use lighting::BACnetLightingCommand;
mod log;
pub use log::{
BACnetEventLogRecord, BACnetLogMultipleRecord, BACnetLogRecord, EventLogDatum, LogData,
LogDatum, LogValue,
};
mod name_value;
pub use name_value::BACnetNameValue;
mod network_port;
pub use network_port::{BACnetBDTEntry, BACnetFDTEntry, BACnetHostAddress, BACnetHostNPort};
mod property_access;
pub use property_access::{AccessResult, BACnetPropertyAccessResult};
mod property_value;
pub use property_value::BACnetPropertyValue;
mod read_access;
pub use read_access::{PropertyReference, ReadAccessSpecification};
mod staging;
pub use staging::BACnetStageLimitValue;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BACnetDateRange {
pub start_date: Date,
pub end_date: Date,
}
#[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: PropertyValue,
}
#[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: u64,
}
#[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),
}
}
pub fn is_unset(&self) -> bool {
self.object_identifier.instance_number() == ObjectIdentifier::WILDCARD_INSTANCE
}
}
#[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
}
pub fn device_identifier_is_device(&self) -> bool {
device_identifier_is_device(self.device_identifier)
}
pub fn is_unset(&self) -> bool {
let reserved =
|oid: ObjectIdentifier| oid.instance_number() == ObjectIdentifier::WILDCARD_INSTANCE;
reserved(self.object_identifier) || self.device_identifier.is_some_and(reserved)
}
}
pub fn device_identifier_is_device(device: Option<ObjectIdentifier>) -> bool {
device.is_none_or(|device| device.object_type() == crate::enums::ObjectType::DEVICE)
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BACnetAddress {
pub network_number: u16,
pub mac_address: MacAddr,
}
impl BACnetAddress {
pub const MAX_MAC_LEN: usize = 18;
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: DaysOfWeek,
pub from_time: Time,
pub to_time: Time,
pub recipient: BACnetRecipient,
pub process_identifier: u32,
pub issue_confirmed_notifications: bool,
pub transitions: EventTransitionBits,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BACnetEventNotificationSubscription {
pub recipient: BACnetRecipient,
pub process_identifier: u32,
pub issue_confirmed_notifications: bool,
pub time_remaining: u32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BACnetPortPermission {
pub port_id: u8,
pub enabled: bool,
}
#[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 BACnetShedLevel {
Percent(u64),
Level(u64),
Amount(f32),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BACnetDeviceObjectReference {
pub device_identifier: Option<ObjectIdentifier>,
pub object_identifier: ObjectIdentifier,
}
impl BACnetDeviceObjectReference {
pub fn device_identifier_is_device(&self) -> bool {
device_identifier_is_device(self.device_identifier)
}
}
impl From<ObjectIdentifier> for BACnetDeviceObjectReference {
fn from(object_identifier: ObjectIdentifier) -> Self {
Self {
device_identifier: None,
object_identifier,
}
}
}
#[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<LifeSafetyState>,
mode_property_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 struct BACnetCOVMultipleSubscription {
pub recipient: BACnetRecipientProcess,
pub issue_confirmed_notifications: bool,
pub time_remaining: u32,
pub max_notification_delay: u32,
pub list_of_cov_subscription_specifications: Vec<BACnetCOVSubscriptionSpecification>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct BACnetCOVSubscriptionSpecification {
pub monitored_object_identifier: ObjectIdentifier,
pub list_of_cov_references: Vec<BACnetCOVReference>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct BACnetCOVReference {
pub property_identifier: crate::enums::PropertyIdentifier,
pub property_array_index: Option<u32>,
pub cov_increment: Option<f32>,
pub timestamped: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub enum BACnetValueSource {
None,
Object(BACnetDeviceObjectReference),
Address(BACnetAddress),
}
mod event_parameter;
pub use event_parameter::{event_parameter_tag, BACnetEventParameter, ChangeOfValueCriteria};
mod property_states;
pub use property_states::{
BACnetExtendedPropertyState, BACnetPropertyStates, BACnetProprietaryPropertyState,
};
#[cfg(test)]
mod tests;