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