1use crate::{
15 byte_converter::*, converting_callback_receiver::ConvertingCallbackReceiver, converting_receiver::ConvertingReceiver, device::*,
16 ip_connection::GetRequestSender,
17};
18pub enum RealTimeClockBrickletFunction {
19 SetDateTime,
20 GetDateTime,
21 GetTimestamp,
22 SetOffset,
23 GetOffset,
24 SetDateTimeCallbackPeriod,
25 GetDateTimeCallbackPeriod,
26 SetAlarm,
27 GetAlarm,
28 GetIdentity,
29 CallbackDateTime,
30 CallbackAlarm,
31}
32impl From<RealTimeClockBrickletFunction> for u8 {
33 fn from(fun: RealTimeClockBrickletFunction) -> Self {
34 match fun {
35 RealTimeClockBrickletFunction::SetDateTime => 1,
36 RealTimeClockBrickletFunction::GetDateTime => 2,
37 RealTimeClockBrickletFunction::GetTimestamp => 3,
38 RealTimeClockBrickletFunction::SetOffset => 4,
39 RealTimeClockBrickletFunction::GetOffset => 5,
40 RealTimeClockBrickletFunction::SetDateTimeCallbackPeriod => 6,
41 RealTimeClockBrickletFunction::GetDateTimeCallbackPeriod => 7,
42 RealTimeClockBrickletFunction::SetAlarm => 8,
43 RealTimeClockBrickletFunction::GetAlarm => 9,
44 RealTimeClockBrickletFunction::GetIdentity => 255,
45 RealTimeClockBrickletFunction::CallbackDateTime => 10,
46 RealTimeClockBrickletFunction::CallbackAlarm => 11,
47 }
48 }
49}
50pub const REAL_TIME_CLOCK_BRICKLET_WEEKDAY_MONDAY: u8 = 1;
51pub const REAL_TIME_CLOCK_BRICKLET_WEEKDAY_TUESDAY: u8 = 2;
52pub const REAL_TIME_CLOCK_BRICKLET_WEEKDAY_WEDNESDAY: u8 = 3;
53pub const REAL_TIME_CLOCK_BRICKLET_WEEKDAY_THURSDAY: u8 = 4;
54pub const REAL_TIME_CLOCK_BRICKLET_WEEKDAY_FRIDAY: u8 = 5;
55pub const REAL_TIME_CLOCK_BRICKLET_WEEKDAY_SATURDAY: u8 = 6;
56pub const REAL_TIME_CLOCK_BRICKLET_WEEKDAY_SUNDAY: u8 = 7;
57pub const REAL_TIME_CLOCK_BRICKLET_ALARM_MATCH_DISABLED: i8 = -1;
58pub const REAL_TIME_CLOCK_BRICKLET_ALARM_INTERVAL_DISABLED: i32 = -1;
59
60#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
61pub struct DateTime {
62 pub year: u16,
63 pub month: u8,
64 pub day: u8,
65 pub hour: u8,
66 pub minute: u8,
67 pub second: u8,
68 pub centisecond: u8,
69 pub weekday: u8,
70}
71impl FromByteSlice for DateTime {
72 fn bytes_expected() -> usize { 9 }
73 fn from_le_byte_slice(bytes: &[u8]) -> DateTime {
74 DateTime {
75 year: <u16>::from_le_byte_slice(&bytes[0..2]),
76 month: <u8>::from_le_byte_slice(&bytes[2..3]),
77 day: <u8>::from_le_byte_slice(&bytes[3..4]),
78 hour: <u8>::from_le_byte_slice(&bytes[4..5]),
79 minute: <u8>::from_le_byte_slice(&bytes[5..6]),
80 second: <u8>::from_le_byte_slice(&bytes[6..7]),
81 centisecond: <u8>::from_le_byte_slice(&bytes[7..8]),
82 weekday: <u8>::from_le_byte_slice(&bytes[8..9]),
83 }
84 }
85}
86
87#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
88pub struct Alarm {
89 pub month: i8,
90 pub day: i8,
91 pub hour: i8,
92 pub minute: i8,
93 pub second: i8,
94 pub weekday: i8,
95 pub interval: i32,
96}
97impl FromByteSlice for Alarm {
98 fn bytes_expected() -> usize { 10 }
99 fn from_le_byte_slice(bytes: &[u8]) -> Alarm {
100 Alarm {
101 month: <i8>::from_le_byte_slice(&bytes[0..1]),
102 day: <i8>::from_le_byte_slice(&bytes[1..2]),
103 hour: <i8>::from_le_byte_slice(&bytes[2..3]),
104 minute: <i8>::from_le_byte_slice(&bytes[3..4]),
105 second: <i8>::from_le_byte_slice(&bytes[4..5]),
106 weekday: <i8>::from_le_byte_slice(&bytes[5..6]),
107 interval: <i32>::from_le_byte_slice(&bytes[6..10]),
108 }
109 }
110}
111
112#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
113pub struct DateTimeEvent {
114 pub year: u16,
115 pub month: u8,
116 pub day: u8,
117 pub hour: u8,
118 pub minute: u8,
119 pub second: u8,
120 pub centisecond: u8,
121 pub weekday: u8,
122 pub timestamp: i64,
123}
124impl FromByteSlice for DateTimeEvent {
125 fn bytes_expected() -> usize { 17 }
126 fn from_le_byte_slice(bytes: &[u8]) -> DateTimeEvent {
127 DateTimeEvent {
128 year: <u16>::from_le_byte_slice(&bytes[0..2]),
129 month: <u8>::from_le_byte_slice(&bytes[2..3]),
130 day: <u8>::from_le_byte_slice(&bytes[3..4]),
131 hour: <u8>::from_le_byte_slice(&bytes[4..5]),
132 minute: <u8>::from_le_byte_slice(&bytes[5..6]),
133 second: <u8>::from_le_byte_slice(&bytes[6..7]),
134 centisecond: <u8>::from_le_byte_slice(&bytes[7..8]),
135 weekday: <u8>::from_le_byte_slice(&bytes[8..9]),
136 timestamp: <i64>::from_le_byte_slice(&bytes[9..17]),
137 }
138 }
139}
140
141#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
142pub struct AlarmEvent {
143 pub year: u16,
144 pub month: u8,
145 pub day: u8,
146 pub hour: u8,
147 pub minute: u8,
148 pub second: u8,
149 pub centisecond: u8,
150 pub weekday: u8,
151 pub timestamp: i64,
152}
153impl FromByteSlice for AlarmEvent {
154 fn bytes_expected() -> usize { 17 }
155 fn from_le_byte_slice(bytes: &[u8]) -> AlarmEvent {
156 AlarmEvent {
157 year: <u16>::from_le_byte_slice(&bytes[0..2]),
158 month: <u8>::from_le_byte_slice(&bytes[2..3]),
159 day: <u8>::from_le_byte_slice(&bytes[3..4]),
160 hour: <u8>::from_le_byte_slice(&bytes[4..5]),
161 minute: <u8>::from_le_byte_slice(&bytes[5..6]),
162 second: <u8>::from_le_byte_slice(&bytes[6..7]),
163 centisecond: <u8>::from_le_byte_slice(&bytes[7..8]),
164 weekday: <u8>::from_le_byte_slice(&bytes[8..9]),
165 timestamp: <i64>::from_le_byte_slice(&bytes[9..17]),
166 }
167 }
168}
169
170#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
171pub struct Identity {
172 pub uid: String,
173 pub connected_uid: String,
174 pub position: char,
175 pub hardware_version: [u8; 3],
176 pub firmware_version: [u8; 3],
177 pub device_identifier: u16,
178}
179impl FromByteSlice for Identity {
180 fn bytes_expected() -> usize { 25 }
181 fn from_le_byte_slice(bytes: &[u8]) -> Identity {
182 Identity {
183 uid: <String>::from_le_byte_slice(&bytes[0..8]),
184 connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
185 position: <char>::from_le_byte_slice(&bytes[16..17]),
186 hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
187 firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
188 device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
189 }
190 }
191}
192
193#[derive(Clone)]
195pub struct RealTimeClockBricklet {
196 device: Device,
197}
198impl RealTimeClockBricklet {
199 pub const DEVICE_IDENTIFIER: u16 = 268;
200 pub const DEVICE_DISPLAY_NAME: &'static str = "Real-Time Clock Bricklet";
201 pub fn new<T: GetRequestSender>(uid: &str, req_sender: T) -> RealTimeClockBricklet {
203 let mut result = RealTimeClockBricklet { device: Device::new([2, 0, 1], uid, req_sender, 0) };
204 result.device.response_expected[u8::from(RealTimeClockBrickletFunction::SetDateTime) as usize] = ResponseExpectedFlag::False;
205 result.device.response_expected[u8::from(RealTimeClockBrickletFunction::GetDateTime) as usize] = ResponseExpectedFlag::AlwaysTrue;
206 result.device.response_expected[u8::from(RealTimeClockBrickletFunction::GetTimestamp) as usize] = ResponseExpectedFlag::AlwaysTrue;
207 result.device.response_expected[u8::from(RealTimeClockBrickletFunction::SetOffset) as usize] = ResponseExpectedFlag::False;
208 result.device.response_expected[u8::from(RealTimeClockBrickletFunction::GetOffset) as usize] = ResponseExpectedFlag::AlwaysTrue;
209 result.device.response_expected[u8::from(RealTimeClockBrickletFunction::SetDateTimeCallbackPeriod) as usize] =
210 ResponseExpectedFlag::True;
211 result.device.response_expected[u8::from(RealTimeClockBrickletFunction::GetDateTimeCallbackPeriod) as usize] =
212 ResponseExpectedFlag::AlwaysTrue;
213 result.device.response_expected[u8::from(RealTimeClockBrickletFunction::SetAlarm) as usize] = ResponseExpectedFlag::True;
214 result.device.response_expected[u8::from(RealTimeClockBrickletFunction::GetAlarm) as usize] = ResponseExpectedFlag::AlwaysTrue;
215 result.device.response_expected[u8::from(RealTimeClockBrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
216 result
217 }
218
219 pub fn get_response_expected(&mut self, fun: RealTimeClockBrickletFunction) -> Result<bool, GetResponseExpectedError> {
234 self.device.get_response_expected(u8::from(fun))
235 }
236
237 pub fn set_response_expected(
246 &mut self,
247 fun: RealTimeClockBrickletFunction,
248 response_expected: bool,
249 ) -> Result<(), SetResponseExpectedError> {
250 self.device.set_response_expected(u8::from(fun), response_expected)
251 }
252
253 pub fn set_response_expected_all(&mut self, response_expected: bool) { self.device.set_response_expected_all(response_expected) }
255
256 pub fn get_api_version(&self) -> [u8; 3] { self.device.api_version }
259
260 pub fn get_date_time_callback_receiver(&self) -> ConvertingCallbackReceiver<DateTimeEvent> {
273 self.device.get_callback_receiver(u8::from(RealTimeClockBrickletFunction::CallbackDateTime))
274 }
275
276 pub fn get_alarm_callback_receiver(&self) -> ConvertingCallbackReceiver<AlarmEvent> {
283 self.device.get_callback_receiver(u8::from(RealTimeClockBrickletFunction::CallbackAlarm))
284 }
285
286 pub fn set_date_time(
304 &self,
305 year: u16,
306 month: u8,
307 day: u8,
308 hour: u8,
309 minute: u8,
310 second: u8,
311 centisecond: u8,
312 weekday: u8,
313 ) -> ConvertingReceiver<()> {
314 let mut payload = vec![0; 9];
315 payload[0..2].copy_from_slice(&<u16>::to_le_byte_vec(year));
316 payload[2..3].copy_from_slice(&<u8>::to_le_byte_vec(month));
317 payload[3..4].copy_from_slice(&<u8>::to_le_byte_vec(day));
318 payload[4..5].copy_from_slice(&<u8>::to_le_byte_vec(hour));
319 payload[5..6].copy_from_slice(&<u8>::to_le_byte_vec(minute));
320 payload[6..7].copy_from_slice(&<u8>::to_le_byte_vec(second));
321 payload[7..8].copy_from_slice(&<u8>::to_le_byte_vec(centisecond));
322 payload[8..9].copy_from_slice(&<u8>::to_le_byte_vec(weekday));
323
324 self.device.set(u8::from(RealTimeClockBrickletFunction::SetDateTime), payload)
325 }
326
327 pub fn get_date_time(&self) -> ConvertingReceiver<DateTime> {
339 let payload = vec![0; 0];
340
341 self.device.get(u8::from(RealTimeClockBrickletFunction::GetDateTime), payload)
342 }
343
344 pub fn get_timestamp(&self) -> ConvertingReceiver<i64> {
348 let payload = vec![0; 0];
349
350 self.device.get(u8::from(RealTimeClockBrickletFunction::GetTimestamp), payload)
351 }
352
353 pub fn set_offset(&self, offset: i8) -> ConvertingReceiver<()> {
379 let mut payload = vec![0; 1];
380 payload[0..1].copy_from_slice(&<i8>::to_le_byte_vec(offset));
381
382 self.device.set(u8::from(RealTimeClockBrickletFunction::SetOffset), payload)
383 }
384
385 pub fn get_offset(&self) -> ConvertingReceiver<i8> {
387 let payload = vec![0; 0];
388
389 self.device.get(u8::from(RealTimeClockBrickletFunction::GetOffset), payload)
390 }
391
392 pub fn set_date_time_callback_period(&self, period: u32) -> ConvertingReceiver<()> {
401 let mut payload = vec![0; 4];
402 payload[0..4].copy_from_slice(&<u32>::to_le_byte_vec(period));
403
404 self.device.set(u8::from(RealTimeClockBrickletFunction::SetDateTimeCallbackPeriod), payload)
405 }
406
407 pub fn get_date_time_callback_period(&self) -> ConvertingReceiver<u32> {
412 let payload = vec![0; 0];
413
414 self.device.get(u8::from(RealTimeClockBrickletFunction::GetDateTimeCallbackPeriod), payload)
415 }
416
417 pub fn set_alarm(&self, month: i8, day: i8, hour: i8, minute: i8, second: i8, weekday: i8, interval: i32) -> ConvertingReceiver<()> {
449 let mut payload = vec![0; 10];
450 payload[0..1].copy_from_slice(&<i8>::to_le_byte_vec(month));
451 payload[1..2].copy_from_slice(&<i8>::to_le_byte_vec(day));
452 payload[2..3].copy_from_slice(&<i8>::to_le_byte_vec(hour));
453 payload[3..4].copy_from_slice(&<i8>::to_le_byte_vec(minute));
454 payload[4..5].copy_from_slice(&<i8>::to_le_byte_vec(second));
455 payload[5..6].copy_from_slice(&<i8>::to_le_byte_vec(weekday));
456 payload[6..10].copy_from_slice(&<i32>::to_le_byte_vec(interval));
457
458 self.device.set(u8::from(RealTimeClockBrickletFunction::SetAlarm), payload)
459 }
460
461 pub fn get_alarm(&self) -> ConvertingReceiver<Alarm> {
470 let payload = vec![0; 0];
471
472 self.device.get(u8::from(RealTimeClockBrickletFunction::GetAlarm), payload)
473 }
474
475 pub fn get_identity(&self) -> ConvertingReceiver<Identity> {
486 let payload = vec![0; 0];
487
488 self.device.get(u8::from(RealTimeClockBrickletFunction::GetIdentity), payload)
489 }
490}