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}