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}