tinkerforge_async/bindings/
real_time_clock_v2_bricklet.rs

1/* ***********************************************************
2 * This file was automatically generated on 2024-02-16.      *
3 *                                                           *
4 * Rust Bindings Version 2.0.20                              *
5 *                                                           *
6 * If you have a bugfix for this file and want to commit it, *
7 * please fix the bug in the generator. You can find a link  *
8 * to the generators git repository on tinkerforge.com       *
9 *************************************************************/
10
11//! Battery-backed real-time clock.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/RealTimeClockV2_Bricklet_Rust.html).
14#[allow(unused_imports)]
15use crate::{
16    base58::Uid, byte_converter::*, device::*, error::TinkerforgeError, ip_connection::async_io::AsyncIpConnection,
17    low_level_traits::LowLevelRead,
18};
19#[allow(unused_imports)]
20use futures_core::Stream;
21#[allow(unused_imports)]
22use tokio_stream::StreamExt;
23pub enum RealTimeClockV2BrickletFunction {
24    SetDateTime,
25    GetDateTime,
26    GetTimestamp,
27    SetOffset,
28    GetOffset,
29    SetDateTimeCallbackConfiguration,
30    GetDateTimeCallbackConfiguration,
31    SetAlarm,
32    GetAlarm,
33    GetSpitfpErrorCount,
34    SetBootloaderMode,
35    GetBootloaderMode,
36    SetWriteFirmwarePointer,
37    WriteFirmware,
38    SetStatusLedConfig,
39    GetStatusLedConfig,
40    GetChipTemperature,
41    Reset,
42    WriteUid,
43    ReadUid,
44    GetIdentity,
45    CallbackDateTime,
46    CallbackAlarm,
47}
48impl From<RealTimeClockV2BrickletFunction> for u8 {
49    fn from(fun: RealTimeClockV2BrickletFunction) -> Self {
50        match fun {
51            RealTimeClockV2BrickletFunction::SetDateTime => 1,
52            RealTimeClockV2BrickletFunction::GetDateTime => 2,
53            RealTimeClockV2BrickletFunction::GetTimestamp => 3,
54            RealTimeClockV2BrickletFunction::SetOffset => 4,
55            RealTimeClockV2BrickletFunction::GetOffset => 5,
56            RealTimeClockV2BrickletFunction::SetDateTimeCallbackConfiguration => 6,
57            RealTimeClockV2BrickletFunction::GetDateTimeCallbackConfiguration => 7,
58            RealTimeClockV2BrickletFunction::SetAlarm => 8,
59            RealTimeClockV2BrickletFunction::GetAlarm => 9,
60            RealTimeClockV2BrickletFunction::GetSpitfpErrorCount => 234,
61            RealTimeClockV2BrickletFunction::SetBootloaderMode => 235,
62            RealTimeClockV2BrickletFunction::GetBootloaderMode => 236,
63            RealTimeClockV2BrickletFunction::SetWriteFirmwarePointer => 237,
64            RealTimeClockV2BrickletFunction::WriteFirmware => 238,
65            RealTimeClockV2BrickletFunction::SetStatusLedConfig => 239,
66            RealTimeClockV2BrickletFunction::GetStatusLedConfig => 240,
67            RealTimeClockV2BrickletFunction::GetChipTemperature => 242,
68            RealTimeClockV2BrickletFunction::Reset => 243,
69            RealTimeClockV2BrickletFunction::WriteUid => 248,
70            RealTimeClockV2BrickletFunction::ReadUid => 249,
71            RealTimeClockV2BrickletFunction::GetIdentity => 255,
72            RealTimeClockV2BrickletFunction::CallbackDateTime => 10,
73            RealTimeClockV2BrickletFunction::CallbackAlarm => 11,
74        }
75    }
76}
77pub const REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_MONDAY: u8 = 1;
78pub const REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_TUESDAY: u8 = 2;
79pub const REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_WEDNESDAY: u8 = 3;
80pub const REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_THURSDAY: u8 = 4;
81pub const REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_FRIDAY: u8 = 5;
82pub const REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_SATURDAY: u8 = 6;
83pub const REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_SUNDAY: u8 = 7;
84pub const REAL_TIME_CLOCK_V2_BRICKLET_ALARM_MATCH_DISABLED: i8 = -1;
85pub const REAL_TIME_CLOCK_V2_BRICKLET_ALARM_INTERVAL_DISABLED: i32 = -1;
86pub const REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER: u8 = 0;
87pub const REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE: u8 = 1;
88pub const REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT: u8 = 2;
89pub const REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT: u8 = 3;
90pub const REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT: u8 = 4;
91pub const REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_STATUS_OK: u8 = 0;
92pub const REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE: u8 = 1;
93pub const REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE: u8 = 2;
94pub const REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT: u8 = 3;
95pub const REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT: u8 = 4;
96pub const REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH: u8 = 5;
97pub const REAL_TIME_CLOCK_V2_BRICKLET_STATUS_LED_CONFIG_OFF: u8 = 0;
98pub const REAL_TIME_CLOCK_V2_BRICKLET_STATUS_LED_CONFIG_ON: u8 = 1;
99pub const REAL_TIME_CLOCK_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
100pub const REAL_TIME_CLOCK_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS: u8 = 3;
101
102#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
103pub struct DateTime {
104    pub year: u16,
105    pub month: u8,
106    pub day: u8,
107    pub hour: u8,
108    pub minute: u8,
109    pub second: u8,
110    pub centisecond: u8,
111    pub weekday: u8,
112    pub timestamp: i64,
113}
114impl FromByteSlice for DateTime {
115    fn bytes_expected() -> usize {
116        17
117    }
118    fn from_le_byte_slice(bytes: &[u8]) -> DateTime {
119        DateTime {
120            year: <u16>::from_le_byte_slice(&bytes[0..2]),
121            month: <u8>::from_le_byte_slice(&bytes[2..3]),
122            day: <u8>::from_le_byte_slice(&bytes[3..4]),
123            hour: <u8>::from_le_byte_slice(&bytes[4..5]),
124            minute: <u8>::from_le_byte_slice(&bytes[5..6]),
125            second: <u8>::from_le_byte_slice(&bytes[6..7]),
126            centisecond: <u8>::from_le_byte_slice(&bytes[7..8]),
127            weekday: <u8>::from_le_byte_slice(&bytes[8..9]),
128            timestamp: <i64>::from_le_byte_slice(&bytes[9..17]),
129        }
130    }
131}
132
133#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
134pub struct Alarm {
135    pub month: i8,
136    pub day: i8,
137    pub hour: i8,
138    pub minute: i8,
139    pub second: i8,
140    pub weekday: i8,
141    pub interval: i32,
142}
143impl FromByteSlice for Alarm {
144    fn bytes_expected() -> usize {
145        10
146    }
147    fn from_le_byte_slice(bytes: &[u8]) -> Alarm {
148        Alarm {
149            month: <i8>::from_le_byte_slice(&bytes[0..1]),
150            day: <i8>::from_le_byte_slice(&bytes[1..2]),
151            hour: <i8>::from_le_byte_slice(&bytes[2..3]),
152            minute: <i8>::from_le_byte_slice(&bytes[3..4]),
153            second: <i8>::from_le_byte_slice(&bytes[4..5]),
154            weekday: <i8>::from_le_byte_slice(&bytes[5..6]),
155            interval: <i32>::from_le_byte_slice(&bytes[6..10]),
156        }
157    }
158}
159
160#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
161pub struct DateTimeEvent {
162    pub year: u16,
163    pub month: u8,
164    pub day: u8,
165    pub hour: u8,
166    pub minute: u8,
167    pub second: u8,
168    pub centisecond: u8,
169    pub weekday: u8,
170    pub timestamp: i64,
171}
172impl FromByteSlice for DateTimeEvent {
173    fn bytes_expected() -> usize {
174        17
175    }
176    fn from_le_byte_slice(bytes: &[u8]) -> DateTimeEvent {
177        DateTimeEvent {
178            year: <u16>::from_le_byte_slice(&bytes[0..2]),
179            month: <u8>::from_le_byte_slice(&bytes[2..3]),
180            day: <u8>::from_le_byte_slice(&bytes[3..4]),
181            hour: <u8>::from_le_byte_slice(&bytes[4..5]),
182            minute: <u8>::from_le_byte_slice(&bytes[5..6]),
183            second: <u8>::from_le_byte_slice(&bytes[6..7]),
184            centisecond: <u8>::from_le_byte_slice(&bytes[7..8]),
185            weekday: <u8>::from_le_byte_slice(&bytes[8..9]),
186            timestamp: <i64>::from_le_byte_slice(&bytes[9..17]),
187        }
188    }
189}
190
191#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
192pub struct AlarmEvent {
193    pub year: u16,
194    pub month: u8,
195    pub day: u8,
196    pub hour: u8,
197    pub minute: u8,
198    pub second: u8,
199    pub centisecond: u8,
200    pub weekday: u8,
201    pub timestamp: i64,
202}
203impl FromByteSlice for AlarmEvent {
204    fn bytes_expected() -> usize {
205        17
206    }
207    fn from_le_byte_slice(bytes: &[u8]) -> AlarmEvent {
208        AlarmEvent {
209            year: <u16>::from_le_byte_slice(&bytes[0..2]),
210            month: <u8>::from_le_byte_slice(&bytes[2..3]),
211            day: <u8>::from_le_byte_slice(&bytes[3..4]),
212            hour: <u8>::from_le_byte_slice(&bytes[4..5]),
213            minute: <u8>::from_le_byte_slice(&bytes[5..6]),
214            second: <u8>::from_le_byte_slice(&bytes[6..7]),
215            centisecond: <u8>::from_le_byte_slice(&bytes[7..8]),
216            weekday: <u8>::from_le_byte_slice(&bytes[8..9]),
217            timestamp: <i64>::from_le_byte_slice(&bytes[9..17]),
218        }
219    }
220}
221
222#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
223pub struct SpitfpErrorCount {
224    pub error_count_ack_checksum: u32,
225    pub error_count_message_checksum: u32,
226    pub error_count_frame: u32,
227    pub error_count_overflow: u32,
228}
229impl FromByteSlice for SpitfpErrorCount {
230    fn bytes_expected() -> usize {
231        16
232    }
233    fn from_le_byte_slice(bytes: &[u8]) -> SpitfpErrorCount {
234        SpitfpErrorCount {
235            error_count_ack_checksum: <u32>::from_le_byte_slice(&bytes[0..4]),
236            error_count_message_checksum: <u32>::from_le_byte_slice(&bytes[4..8]),
237            error_count_frame: <u32>::from_le_byte_slice(&bytes[8..12]),
238            error_count_overflow: <u32>::from_le_byte_slice(&bytes[12..16]),
239        }
240    }
241}
242
243#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
244pub struct Identity {
245    pub uid: String,
246    pub connected_uid: String,
247    pub position: char,
248    pub hardware_version: [u8; 3],
249    pub firmware_version: [u8; 3],
250    pub device_identifier: u16,
251}
252impl FromByteSlice for Identity {
253    fn bytes_expected() -> usize {
254        25
255    }
256    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
257        Identity {
258            uid: <String>::from_le_byte_slice(&bytes[0..8]),
259            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
260            position: <char>::from_le_byte_slice(&bytes[16..17]),
261            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
262            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
263            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
264        }
265    }
266}
267
268/// Battery-backed real-time clock
269#[derive(Clone)]
270pub struct RealTimeClockV2Bricklet {
271    device: Device,
272}
273impl RealTimeClockV2Bricklet {
274    pub const DEVICE_IDENTIFIER: u16 = 2106;
275    pub const DEVICE_DISPLAY_NAME: &'static str = "Real-Time Clock Bricklet 2.0";
276    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
277    pub fn new(uid: Uid, connection: AsyncIpConnection) -> RealTimeClockV2Bricklet {
278        let mut result = RealTimeClockV2Bricklet { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
279        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::SetDateTime) as usize] = ResponseExpectedFlag::False;
280        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::GetDateTime) as usize] = ResponseExpectedFlag::AlwaysTrue;
281        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::GetTimestamp) as usize] =
282            ResponseExpectedFlag::AlwaysTrue;
283        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::SetOffset) as usize] = ResponseExpectedFlag::False;
284        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::GetOffset) as usize] = ResponseExpectedFlag::AlwaysTrue;
285        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::SetDateTimeCallbackConfiguration) as usize] =
286            ResponseExpectedFlag::True;
287        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::GetDateTimeCallbackConfiguration) as usize] =
288            ResponseExpectedFlag::AlwaysTrue;
289        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::SetAlarm) as usize] = ResponseExpectedFlag::True;
290        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::GetAlarm) as usize] = ResponseExpectedFlag::AlwaysTrue;
291        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::GetSpitfpErrorCount) as usize] =
292            ResponseExpectedFlag::AlwaysTrue;
293        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::SetBootloaderMode) as usize] =
294            ResponseExpectedFlag::AlwaysTrue;
295        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::GetBootloaderMode) as usize] =
296            ResponseExpectedFlag::AlwaysTrue;
297        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::SetWriteFirmwarePointer) as usize] =
298            ResponseExpectedFlag::False;
299        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::WriteFirmware) as usize] =
300            ResponseExpectedFlag::AlwaysTrue;
301        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::SetStatusLedConfig) as usize] =
302            ResponseExpectedFlag::False;
303        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::GetStatusLedConfig) as usize] =
304            ResponseExpectedFlag::AlwaysTrue;
305        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::GetChipTemperature) as usize] =
306            ResponseExpectedFlag::AlwaysTrue;
307        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::Reset) as usize] = ResponseExpectedFlag::False;
308        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::WriteUid) as usize] = ResponseExpectedFlag::False;
309        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::ReadUid) as usize] = ResponseExpectedFlag::AlwaysTrue;
310        result.device.response_expected[u8::from(RealTimeClockV2BrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
311        result
312    }
313
314    /// Returns the response expected flag for the function specified by the function ID parameter.
315    /// It is true if the function is expected to send a response, false otherwise.
316    ///
317    /// For getter functions this is enabled by default and cannot be disabled, because those
318    /// functions will always send a response. For callback configuration functions it is enabled
319    /// by default too, but can be disabled by [`set_response_expected`](crate::real_time_clock_v2_bricklet::RealTimeClockV2Bricklet::set_response_expected).
320    /// For setter functions it is disabled by default and can be enabled.
321    ///
322    /// Enabling the response expected flag for a setter function allows to detect timeouts
323    /// and other error conditions calls of this setter as well. The device will then send a response
324    /// for this purpose. If this flag is disabled for a setter function then no response is sent
325    /// and errors are silently ignored, because they cannot be detected.
326    ///
327    /// See [`set_response_expected`](crate::real_time_clock_v2_bricklet::RealTimeClockV2Bricklet::set_response_expected) for the list of function ID constants available for this function.
328    pub fn get_response_expected(&mut self, fun: RealTimeClockV2BrickletFunction) -> Result<bool, GetResponseExpectedError> {
329        self.device.get_response_expected(u8::from(fun))
330    }
331
332    /// Changes the response expected flag of the function specified by the function ID parameter.
333    /// This flag can only be changed for setter (default value: false) and callback configuration
334    /// functions (default value: true). For getter functions it is always enabled.
335    ///
336    /// Enabling the response expected flag for a setter function allows to detect timeouts and
337    /// other error conditions calls of this setter as well. The device will then send a response
338    /// for this purpose. If this flag is disabled for a setter function then no response is sent
339    /// and errors are silently ignored, because they cannot be detected.
340    pub fn set_response_expected(
341        &mut self,
342        fun: RealTimeClockV2BrickletFunction,
343        response_expected: bool,
344    ) -> Result<(), SetResponseExpectedError> {
345        self.device.set_response_expected(u8::from(fun), response_expected)
346    }
347
348    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
349    pub fn set_response_expected_all(&mut self, response_expected: bool) {
350        self.device.set_response_expected_all(response_expected)
351    }
352
353    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
354    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
355    pub fn get_api_version(&self) -> [u8; 3] {
356        self.device.api_version
357    }
358
359    /// This receiver is triggered periodically with the period that is set by
360    /// [`set_date_time_callback_configuration`]. The parameters are the
361    /// same as for [`get_date_time`].
362    ///
363    /// [`get_date_time`]: #method.get_date_time
364    /// [`set_date_time_callback_configuration`]: #method.set_date_time_callback_configuration
365    pub async fn get_date_time_callback_receiver(&mut self) -> impl Stream<Item = DateTimeEvent> {
366        self.device
367            .get_callback_receiver(u8::from(RealTimeClockV2BrickletFunction::CallbackDateTime))
368            .await
369            .map(|p| DateTimeEvent::from_le_byte_slice(p.body()))
370    }
371
372    /// This receiver is triggered every time the current date and time matches the
373    /// configured alarm (see [`set_alarm`]). The parameters are the same
374    /// as for [`get_date_time`].
375    pub async fn get_alarm_callback_receiver(&mut self) -> impl Stream<Item = AlarmEvent> {
376        self.device
377            .get_callback_receiver(u8::from(RealTimeClockV2BrickletFunction::CallbackAlarm))
378            .await
379            .map(|p| AlarmEvent::from_le_byte_slice(p.body()))
380    }
381
382    /// Sets the current date (including weekday) and the current time.
383    ///
384    /// If the backup battery is installed then the real-time clock keeps date and
385    /// time even if the Bricklet is not powered by a Brick.
386    ///
387    /// The real-time clock handles leap year and inserts the 29th of February
388    /// accordingly. But leap seconds, time zones and daylight saving time are not
389    /// handled.
390    ///
391    /// Associated constants:
392    /// * REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_MONDAY
393    ///	* REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_TUESDAY
394    ///	* REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_WEDNESDAY
395    ///	* REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_THURSDAY
396    ///	* REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_FRIDAY
397    ///	* REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_SATURDAY
398    ///	* REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_SUNDAY
399    pub async fn set_date_time(
400        &mut self,
401        year: u16,
402        month: u8,
403        day: u8,
404        hour: u8,
405        minute: u8,
406        second: u8,
407        centisecond: u8,
408        weekday: u8,
409    ) -> Result<(), TinkerforgeError> {
410        let mut payload = [0; 9];
411        year.write_to_slice(&mut payload[0..2]);
412        month.write_to_slice(&mut payload[2..3]);
413        day.write_to_slice(&mut payload[3..4]);
414        hour.write_to_slice(&mut payload[4..5]);
415        minute.write_to_slice(&mut payload[5..6]);
416        second.write_to_slice(&mut payload[6..7]);
417        centisecond.write_to_slice(&mut payload[7..8]);
418        weekday.write_to_slice(&mut payload[8..9]);
419
420        #[allow(unused_variables)]
421        let result = self.device.set(u8::from(RealTimeClockV2BrickletFunction::SetDateTime), &payload).await?;
422        Ok(())
423    }
424
425    /// Returns the current date (including weekday) and the current time of the
426    /// real-time.
427    ///
428    /// The timestamp represents the current date and the the current time of the
429    /// real-time clock converted to milliseconds and is an offset to 2000-01-01 00:00:00.0000.
430    ///
431    /// Associated constants:
432    /// * REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_MONDAY
433    ///	* REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_TUESDAY
434    ///	* REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_WEDNESDAY
435    ///	* REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_THURSDAY
436    ///	* REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_FRIDAY
437    ///	* REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_SATURDAY
438    ///	* REAL_TIME_CLOCK_V2_BRICKLET_WEEKDAY_SUNDAY
439    pub async fn get_date_time(&mut self) -> Result<DateTime, TinkerforgeError> {
440        let payload = [0; 0];
441
442        #[allow(unused_variables)]
443        let result = self.device.get(u8::from(RealTimeClockV2BrickletFunction::GetDateTime), &payload).await?;
444        Ok(DateTime::from_le_byte_slice(result.body()))
445    }
446
447    /// Returns the current date and the time of the real-time clock converted to
448    /// milliseconds. The timestamp has an effective resolution of hundredths of a
449    /// second and is an offset to 2000-01-01 00:00:00.0000.
450    pub async fn get_timestamp(&mut self) -> Result<i64, TinkerforgeError> {
451        let payload = [0; 0];
452
453        #[allow(unused_variables)]
454        let result = self.device.get(u8::from(RealTimeClockV2BrickletFunction::GetTimestamp), &payload).await?;
455        Ok(i64::from_le_byte_slice(result.body()))
456    }
457
458    /// Sets the offset the real-time clock should compensate for in 2.17 ppm steps
459    /// between -277.76 ppm (-128) and +275.59 ppm (127).
460    ///
461    /// The real-time clock time can deviate from the actual time due to the frequency
462    /// deviation of its 32.768 kHz crystal. Even without compensation (factory
463    /// default) the resulting time deviation should be at most ±20 ppm (±52.6
464    /// seconds per month).
465    ///
466    /// This deviation can be calculated by comparing the same duration measured by the
467    /// real-time clock (``rtc_duration``) an accurate reference clock
468    /// (``ref_duration``).
469    ///
470    /// For best results the configured offset should be set to 0 ppm first and then a
471    /// duration of at least 6 hours should be measured.
472    ///
473    /// The new offset (``new_offset``) can be calculated from the currently configured
474    /// offset (``current_offset``) and the measured durations as follow::
475    ///
476    ///   new_offset = current_offset - round(1000000 * (rtc_duration - ref_duration) / rtc_duration / 2.17)
477    ///
478    /// If you want to calculate the offset, then we recommend using the calibration
479    /// dialog in Brick Viewer, instead of doing it manually.
480    ///
481    /// The offset is saved in the EEPROM of the Bricklet and only needs to be
482    /// configured once.
483    pub async fn set_offset(&mut self, offset: i8) -> Result<(), TinkerforgeError> {
484        let mut payload = [0; 1];
485        offset.write_to_slice(&mut payload[0..1]);
486
487        #[allow(unused_variables)]
488        let result = self.device.set(u8::from(RealTimeClockV2BrickletFunction::SetOffset), &payload).await?;
489        Ok(())
490    }
491
492    /// Returns the offset as set by [`set_offset`].
493    pub async fn get_offset(&mut self) -> Result<i8, TinkerforgeError> {
494        let payload = [0; 0];
495
496        #[allow(unused_variables)]
497        let result = self.device.get(u8::from(RealTimeClockV2BrickletFunction::GetOffset), &payload).await?;
498        Ok(i8::from_le_byte_slice(result.body()))
499    }
500
501    /// Sets the period with which the [`get_date_time_callback_receiver`] receiver is triggered
502    /// periodically. A value of 0 turns the receiver off.
503    pub async fn set_date_time_callback_configuration(&mut self, period: u32) -> Result<(), TinkerforgeError> {
504        let mut payload = [0; 4];
505        period.write_to_slice(&mut payload[0..4]);
506
507        #[allow(unused_variables)]
508        let result = self.device.set(u8::from(RealTimeClockV2BrickletFunction::SetDateTimeCallbackConfiguration), &payload).await?;
509        Ok(())
510    }
511
512    /// Returns the period as set by [`set_date_time_callback_configuration`].
513    pub async fn get_date_time_callback_configuration(&mut self) -> Result<u32, TinkerforgeError> {
514        let payload = [0; 0];
515
516        #[allow(unused_variables)]
517        let result = self.device.get(u8::from(RealTimeClockV2BrickletFunction::GetDateTimeCallbackConfiguration), &payload).await?;
518        Ok(u32::from_le_byte_slice(result.body()))
519    }
520
521    /// Configures a repeatable alarm. The [`get_alarm_callback_receiver`] receiver is triggered if the
522    /// current date and time matches the configured alarm.
523    ///
524    /// Setting a parameter to -1 means that it should be disabled and doesn't take part
525    /// in the match. Setting all parameters to -1 disables the alarm completely.
526    ///
527    /// For example, to make the alarm trigger every day at 7:30 AM it can be
528    /// configured as (-1, -1, 7, 30, -1, -1, -1). The hour is set to match 7 and the
529    /// minute is set to match 30. The alarm is triggered if all enabled parameters
530    /// match.
531    ///
532    /// The interval has a special role. It allows to make the alarm reconfigure itself.
533    /// This is useful if you need a repeated alarm that cannot be expressed by matching
534    /// the current date and time. For example, to make the alarm trigger every 23
535    /// seconds it can be configured as (-1, -1, -1, -1, -1, -1, 23). Internally the
536    /// Bricklet will take the current date and time, add 23 seconds to it and set the
537    /// result as its alarm. The first alarm will be triggered 23 seconds after the
538    /// call. Because the interval is not -1, the Bricklet will do the same again
539    /// internally, take the current date and time, add 23 seconds to it and set that
540    /// as its alarm. This results in a repeated alarm that triggers every 23 seconds.
541    ///
542    /// The interval can also be used in combination with the other parameters. For
543    /// example, configuring the alarm as (-1, -1, 7, 30, -1, -1, 300) results in an
544    /// alarm that triggers every day at 7:30 AM and is then repeated every 5 minutes.
545    ///
546    /// Associated constants:
547    /// * REAL_TIME_CLOCK_V2_BRICKLET_ALARM_MATCH_DISABLED
548    ///	* REAL_TIME_CLOCK_V2_BRICKLET_ALARM_INTERVAL_DISABLED
549    pub async fn set_alarm(
550        &mut self,
551        month: i8,
552        day: i8,
553        hour: i8,
554        minute: i8,
555        second: i8,
556        weekday: i8,
557        interval: i32,
558    ) -> Result<(), TinkerforgeError> {
559        let mut payload = [0; 10];
560        month.write_to_slice(&mut payload[0..1]);
561        day.write_to_slice(&mut payload[1..2]);
562        hour.write_to_slice(&mut payload[2..3]);
563        minute.write_to_slice(&mut payload[3..4]);
564        second.write_to_slice(&mut payload[4..5]);
565        weekday.write_to_slice(&mut payload[5..6]);
566        interval.write_to_slice(&mut payload[6..10]);
567
568        #[allow(unused_variables)]
569        let result = self.device.set(u8::from(RealTimeClockV2BrickletFunction::SetAlarm), &payload).await?;
570        Ok(())
571    }
572
573    /// Returns the alarm configuration as set by [`set_alarm`].
574    ///
575    /// Associated constants:
576    /// * REAL_TIME_CLOCK_V2_BRICKLET_ALARM_MATCH_DISABLED
577    ///	* REAL_TIME_CLOCK_V2_BRICKLET_ALARM_INTERVAL_DISABLED
578    pub async fn get_alarm(&mut self) -> Result<Alarm, TinkerforgeError> {
579        let payload = [0; 0];
580
581        #[allow(unused_variables)]
582        let result = self.device.get(u8::from(RealTimeClockV2BrickletFunction::GetAlarm), &payload).await?;
583        Ok(Alarm::from_le_byte_slice(result.body()))
584    }
585
586    /// Returns the error count for the communication between Brick and Bricklet.
587    ///
588    /// The errors are divided into
589    ///
590    /// * ACK checksum errors,
591    /// * message checksum errors,
592    /// * framing errors and
593    /// * overflow errors.
594    ///
595    /// The errors counts are for errors that occur on the Bricklet side. All
596    /// Bricks have a similar function that returns the errors on the Brick side.
597    pub async fn get_spitfp_error_count(&mut self) -> Result<SpitfpErrorCount, TinkerforgeError> {
598        let payload = [0; 0];
599
600        #[allow(unused_variables)]
601        let result = self.device.get(u8::from(RealTimeClockV2BrickletFunction::GetSpitfpErrorCount), &payload).await?;
602        Ok(SpitfpErrorCount::from_le_byte_slice(result.body()))
603    }
604
605    /// Sets the bootloader mode and returns the status after the requested
606    /// mode change was instigated.
607    ///
608    /// You can change from bootloader mode to firmware mode and vice versa. A change
609    /// from bootloader mode to firmware mode will only take place if the entry function,
610    /// device identifier and CRC are present and correct.
611    ///
612    /// This function is used by Brick Viewer during flashing. It should not be
613    /// necessary to call it in a normal user program.
614    ///
615    /// Associated constants:
616    /// * REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
617    ///	* REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE
618    ///	* REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
619    ///	* REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
620    ///	* REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
621    ///	* REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_STATUS_OK
622    ///	* REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE
623    ///	* REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE
624    ///	* REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT
625    ///	* REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT
626    ///	* REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH
627    pub async fn set_bootloader_mode(&mut self, mode: u8) -> Result<u8, TinkerforgeError> {
628        let mut payload = [0; 1];
629        mode.write_to_slice(&mut payload[0..1]);
630
631        #[allow(unused_variables)]
632        let result = self.device.get(u8::from(RealTimeClockV2BrickletFunction::SetBootloaderMode), &payload).await?;
633        Ok(u8::from_le_byte_slice(result.body()))
634    }
635
636    /// Returns the current bootloader mode, see [`set_bootloader_mode`].
637    ///
638    /// Associated constants:
639    /// * REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
640    ///	* REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE
641    ///	* REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
642    ///	* REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
643    ///	* REAL_TIME_CLOCK_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
644    pub async fn get_bootloader_mode(&mut self) -> Result<u8, TinkerforgeError> {
645        let payload = [0; 0];
646
647        #[allow(unused_variables)]
648        let result = self.device.get(u8::from(RealTimeClockV2BrickletFunction::GetBootloaderMode), &payload).await?;
649        Ok(u8::from_le_byte_slice(result.body()))
650    }
651
652    /// Sets the firmware pointer for [`write_firmware`]. The pointer has
653    /// to be increased by chunks of size 64. The data is written to flash
654    /// every 4 chunks (which equals to one page of size 256).
655    ///
656    /// This function is used by Brick Viewer during flashing. It should not be
657    /// necessary to call it in a normal user program.
658    pub async fn set_write_firmware_pointer(&mut self, pointer: u32) -> Result<(), TinkerforgeError> {
659        let mut payload = [0; 4];
660        pointer.write_to_slice(&mut payload[0..4]);
661
662        #[allow(unused_variables)]
663        let result = self.device.set(u8::from(RealTimeClockV2BrickletFunction::SetWriteFirmwarePointer), &payload).await?;
664        Ok(())
665    }
666
667    /// Writes 64 Bytes of firmware at the position as written by
668    /// [`set_write_firmware_pointer`] before. The firmware is written
669    /// to flash every 4 chunks.
670    ///
671    /// You can only write firmware in bootloader mode.
672    ///
673    /// This function is used by Brick Viewer during flashing. It should not be
674    /// necessary to call it in a normal user program.
675    pub async fn write_firmware(&mut self, data: &[u8; 64]) -> Result<u8, TinkerforgeError> {
676        let mut payload = [0; 64];
677        data.write_to_slice(&mut payload[0..64]);
678
679        #[allow(unused_variables)]
680        let result = self.device.get(u8::from(RealTimeClockV2BrickletFunction::WriteFirmware), &payload).await?;
681        Ok(u8::from_le_byte_slice(result.body()))
682    }
683
684    /// Sets the status LED configuration. By default the LED shows
685    /// communication traffic between Brick and Bricklet, it flickers once
686    /// for every 10 received data packets.
687    ///
688    /// You can also turn the LED permanently on/off or show a heartbeat.
689    ///
690    /// If the Bricklet is in bootloader mode, the LED is will show heartbeat by default.
691    ///
692    /// Associated constants:
693    /// * REAL_TIME_CLOCK_V2_BRICKLET_STATUS_LED_CONFIG_OFF
694    ///	* REAL_TIME_CLOCK_V2_BRICKLET_STATUS_LED_CONFIG_ON
695    ///	* REAL_TIME_CLOCK_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
696    ///	* REAL_TIME_CLOCK_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
697    pub async fn set_status_led_config(&mut self, config: u8) -> Result<(), TinkerforgeError> {
698        let mut payload = [0; 1];
699        config.write_to_slice(&mut payload[0..1]);
700
701        #[allow(unused_variables)]
702        let result = self.device.set(u8::from(RealTimeClockV2BrickletFunction::SetStatusLedConfig), &payload).await?;
703        Ok(())
704    }
705
706    /// Returns the configuration as set by [`set_status_led_config`]
707    ///
708    /// Associated constants:
709    /// * REAL_TIME_CLOCK_V2_BRICKLET_STATUS_LED_CONFIG_OFF
710    ///	* REAL_TIME_CLOCK_V2_BRICKLET_STATUS_LED_CONFIG_ON
711    ///	* REAL_TIME_CLOCK_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
712    ///	* REAL_TIME_CLOCK_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
713    pub async fn get_status_led_config(&mut self) -> Result<u8, TinkerforgeError> {
714        let payload = [0; 0];
715
716        #[allow(unused_variables)]
717        let result = self.device.get(u8::from(RealTimeClockV2BrickletFunction::GetStatusLedConfig), &payload).await?;
718        Ok(u8::from_le_byte_slice(result.body()))
719    }
720
721    /// Returns the temperature as measured inside the microcontroller. The
722    /// value returned is not the ambient temperature!
723    ///
724    /// The temperature is only proportional to the real temperature and it has bad
725    /// accuracy. Practically it is only useful as an indicator for
726    /// temperature changes.
727    pub async fn get_chip_temperature(&mut self) -> Result<i16, TinkerforgeError> {
728        let payload = [0; 0];
729
730        #[allow(unused_variables)]
731        let result = self.device.get(u8::from(RealTimeClockV2BrickletFunction::GetChipTemperature), &payload).await?;
732        Ok(i16::from_le_byte_slice(result.body()))
733    }
734
735    /// Calling this function will reset the Bricklet. All configurations
736    /// will be lost.
737    ///
738    /// After a reset you have to create new device objects,
739    /// calling functions on the existing ones will result in
740    /// undefined behavior!
741    pub async fn reset(&mut self) -> Result<(), TinkerforgeError> {
742        let payload = [0; 0];
743
744        #[allow(unused_variables)]
745        let result = self.device.set(u8::from(RealTimeClockV2BrickletFunction::Reset), &payload).await?;
746        Ok(())
747    }
748
749    /// Writes a new UID into flash. If you want to set a new UID
750    /// you have to decode the Base58 encoded UID string into an
751    /// integer first.
752    ///
753    /// We recommend that you use Brick Viewer to change the UID.
754    pub async fn write_uid(&mut self, uid: u32) -> Result<(), TinkerforgeError> {
755        let mut payload = [0; 4];
756        uid.write_to_slice(&mut payload[0..4]);
757
758        #[allow(unused_variables)]
759        let result = self.device.set(u8::from(RealTimeClockV2BrickletFunction::WriteUid), &payload).await?;
760        Ok(())
761    }
762
763    /// Returns the current UID as an integer. Encode as
764    /// Base58 to get the usual string version.
765    pub async fn read_uid(&mut self) -> Result<u32, TinkerforgeError> {
766        let payload = [0; 0];
767
768        #[allow(unused_variables)]
769        let result = self.device.get(u8::from(RealTimeClockV2BrickletFunction::ReadUid), &payload).await?;
770        Ok(u32::from_le_byte_slice(result.body()))
771    }
772
773    /// Returns the UID, the UID where the Bricklet is connected to,
774    /// the position, the hardware and firmware version as well as the
775    /// device identifier.
776    ///
777    /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
778    /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
779    /// position 'z'.
780    ///
781    /// The device identifier numbers can be found [here](device_identifier).
782    /// |device_identifier_constant|
783    pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
784        let payload = [0; 0];
785
786        #[allow(unused_variables)]
787        let result = self.device.get(u8::from(RealTimeClockV2BrickletFunction::GetIdentity), &payload).await?;
788        Ok(Identity::from_le_byte_slice(result.body()))
789    }
790}