Skip to main content

bacnet_types/constructed/
log.rs

1//! Log buffer records of three log objects: Trend Log (Clause 12.25.14),
2//! Event Log (Clause 12.27.13) and Trend Log Multiple (Clause 12.30.19). The
3//! record productions are in Clause 21; the encoding crate frames each one
4//! on the wire.
5
6#[cfg(not(feature = "std"))]
7use alloc::vec::Vec;
8
9use super::EventNotificationRequest;
10use crate::bitstring::LogStatus;
11use crate::primitives::{Date, StatusFlags, Time};
12
13// ---------------------------------------------------------------------------
14// LogDatum (Clause 12.25.14 -- Trend Log Log_Buffer)
15// ---------------------------------------------------------------------------
16
17/// What a Trend Log record carries: a sampled value, the error that stopped
18/// the sample, a status change of the log, or a clock change.
19///
20/// On the wire each alternative takes a context tag, 0 to 10 in declaration
21/// order; the encoding crate owns that numbering.
22#[derive(Debug, Clone, PartialEq)]
23pub enum LogDatum {
24    /// A status change of the log itself.
25    LogStatus(LogStatus),
26    /// A BOOLEAN value.
27    BooleanValue(bool),
28    /// A REAL value.
29    RealValue(f32),
30    /// An ENUMERATED value. A logging device may hold these to 32 bits but
31    /// need not, so a decoded record keeps up to 64.
32    EnumValue(u64),
33    /// An Unsigned value, up to 64 bits.
34    UnsignedValue(u64),
35    /// An INTEGER value, up to 64 bits.
36    SignedValue(i64),
37    /// A BIT STRING value.
38    BitstringValue {
39        /// Padding bits at the end of the final octet, 0 to 7.
40        unused_bits: u8,
41        /// The bit data.
42        data: Vec<u8>,
43    },
44    /// A NULL value.
45    NullValue,
46    /// The error that kept the value from being logged.
47    Failure {
48        /// Raw BACnet error class value.
49        error_class: u32,
50        /// Raw BACnet error code value.
51        error_code: u32,
52    },
53    /// The device clock moved by this many seconds; zero when unknown.
54    TimeChange(f32),
55    /// A value of any other datatype, as the tagged encoding a property read
56    /// carries for it: one or more complete values, context tags balanced.
57    AnyValue(Vec<u8>),
58}
59
60impl From<LogValue> for LogDatum {
61    /// The same sampled value as a Trend Log datum.
62    fn from(value: LogValue) -> Self {
63        match value {
64            LogValue::BooleanValue(value) => Self::BooleanValue(value),
65            LogValue::RealValue(value) => Self::RealValue(value),
66            LogValue::EnumValue(value) => Self::EnumValue(value),
67            LogValue::UnsignedValue(value) => Self::UnsignedValue(value),
68            LogValue::SignedValue(value) => Self::SignedValue(value),
69            LogValue::BitstringValue { unused_bits, data } => {
70                Self::BitstringValue { unused_bits, data }
71            }
72            LogValue::NullValue => Self::NullValue,
73            LogValue::Failure {
74                error_class,
75                error_code,
76            } => Self::Failure {
77                error_class,
78                error_code,
79            },
80            LogValue::AnyValue(bytes) => Self::AnyValue(bytes),
81        }
82    }
83}
84
85// ---------------------------------------------------------------------------
86// BACnetLogRecord (Clause 12.25.14 -- Trend Log Log_Buffer)
87// ---------------------------------------------------------------------------
88
89/// One record held in the log buffer of a Trend Log (Clause 12.25.14).
90///
91/// Contains a timestamp (date + time), the logged datum, and optional
92/// status flags that were in effect at logging time.
93#[derive(Debug, Clone, PartialEq)]
94pub struct BACnetLogRecord {
95    /// The date at which this record was logged.
96    pub date: Date,
97    /// The time at which this record was logged.
98    pub time: Time,
99    /// The logged datum.
100    pub log_datum: LogDatum,
101    /// The monitored object's Status_Flags when the value was acquired, if
102    /// recorded.
103    pub status_flags: Option<StatusFlags>,
104}
105
106// ---------------------------------------------------------------------------
107// BACnetEventLogRecord (Clause 12.27.13 -- Event Log Log_Buffer)
108// ---------------------------------------------------------------------------
109
110/// What an Event Log record carries.
111///
112/// On the wire the alternatives take context tags 0 to 2 in declaration
113/// order; the encoding crate owns that numbering.
114#[derive(Debug, Clone, PartialEq)]
115pub enum EventLogDatum {
116    /// A status change of the log itself.
117    LogStatus(LogStatus),
118    /// An event notification: the parameters of the ConfirmedEventNotification
119    /// request, from the process identifier through the optional event values.
120    ///
121    /// An ACK_NOTIFICATION is encoded without its ack-required, from-state and
122    /// event values, so the record ReadRange serves (and decodes back) has
123    /// them as `false`, NORMAL and `None`, whatever the stored request held.
124    Notification(EventNotificationRequest),
125    /// The device clock moved by this many seconds; zero when unknown.
126    TimeChange(f32),
127}
128
129/// One record held in the log buffer of an Event Log (Clause 12.27.13).
130#[derive(Debug, Clone, PartialEq)]
131pub struct BACnetEventLogRecord {
132    /// The local date at which the record was placed in the buffer.
133    pub date: Date,
134    /// The local time at which the record was placed in the buffer.
135    pub time: Time,
136    /// The record's contents.
137    pub log_datum: EventLogDatum,
138}
139
140// ---------------------------------------------------------------------------
141// BACnetLogMultipleRecord (Clause 12.30.19 -- Trend Log Multiple Log_Buffer)
142// ---------------------------------------------------------------------------
143
144/// One sampled value, or the error that stopped the sample, in a Trend Log
145/// Multiple record (Clause 12.30.19).
146///
147/// These are the per-member alternatives of Clause 21's BACnetLogData. On the
148/// wire they take context tags 0 to 8 in declaration order; the encoding crate
149/// owns that numbering, which differs from [`LogDatum`]'s.
150#[derive(Debug, Clone, PartialEq)]
151pub enum LogValue {
152    /// A BOOLEAN value.
153    BooleanValue(bool),
154    /// A REAL value.
155    RealValue(f32),
156    /// An ENUMERATED value. A logging device may hold these to 32 bits but
157    /// need not, so a decoded record keeps up to 64.
158    EnumValue(u64),
159    /// An Unsigned value, up to 64 bits.
160    UnsignedValue(u64),
161    /// An INTEGER value, up to 64 bits.
162    SignedValue(i64),
163    /// A BIT STRING value.
164    BitstringValue {
165        /// Padding bits at the end of the final octet, 0 to 7.
166        unused_bits: u8,
167        /// The bit data.
168        data: Vec<u8>,
169    },
170    /// A NULL value.
171    NullValue,
172    /// The error that kept this member from being logged.
173    Failure {
174        /// Raw BACnet error class value.
175        error_class: u32,
176        /// Raw BACnet error code value.
177        error_code: u32,
178    },
179    /// A value of any other datatype, as the tagged encoding a property read
180    /// carries for it: one or more complete values, context tags balanced.
181    AnyValue(Vec<u8>),
182}
183
184/// What a Trend Log Multiple record carries (Clause 21's BACnetLogData).
185#[derive(Debug, Clone, PartialEq)]
186pub enum LogData {
187    /// A status change of the log itself.
188    LogStatus(LogStatus),
189    /// One entry per Log_DeviceObjectProperty member, in member order.
190    Values(Vec<LogValue>),
191    /// The device clock moved by this many seconds; zero when unknown.
192    TimeChange(f32),
193}
194
195/// One record held in the log buffer of a Trend Log Multiple
196/// (Clause 12.30.19).
197#[derive(Debug, Clone, PartialEq)]
198pub struct BACnetLogMultipleRecord {
199    /// The local date at which the record was acquired.
200    pub date: Date,
201    /// The local time at which the record was acquired.
202    pub time: Time,
203    /// The record's contents.
204    pub log_data: LogData,
205}