1#[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 GpsBrickletFunction {
24 GetCoordinates,
25 GetStatus,
26 GetAltitude,
27 GetMotion,
28 GetDateTime,
29 Restart,
30 SetCoordinatesCallbackPeriod,
31 GetCoordinatesCallbackPeriod,
32 SetStatusCallbackPeriod,
33 GetStatusCallbackPeriod,
34 SetAltitudeCallbackPeriod,
35 GetAltitudeCallbackPeriod,
36 SetMotionCallbackPeriod,
37 GetMotionCallbackPeriod,
38 SetDateTimeCallbackPeriod,
39 GetDateTimeCallbackPeriod,
40 GetIdentity,
41 CallbackCoordinates,
42 CallbackStatus,
43 CallbackAltitude,
44 CallbackMotion,
45 CallbackDateTime,
46}
47impl From<GpsBrickletFunction> for u8 {
48 fn from(fun: GpsBrickletFunction) -> Self {
49 match fun {
50 GpsBrickletFunction::GetCoordinates => 1,
51 GpsBrickletFunction::GetStatus => 2,
52 GpsBrickletFunction::GetAltitude => 3,
53 GpsBrickletFunction::GetMotion => 4,
54 GpsBrickletFunction::GetDateTime => 5,
55 GpsBrickletFunction::Restart => 6,
56 GpsBrickletFunction::SetCoordinatesCallbackPeriod => 7,
57 GpsBrickletFunction::GetCoordinatesCallbackPeriod => 8,
58 GpsBrickletFunction::SetStatusCallbackPeriod => 9,
59 GpsBrickletFunction::GetStatusCallbackPeriod => 10,
60 GpsBrickletFunction::SetAltitudeCallbackPeriod => 11,
61 GpsBrickletFunction::GetAltitudeCallbackPeriod => 12,
62 GpsBrickletFunction::SetMotionCallbackPeriod => 13,
63 GpsBrickletFunction::GetMotionCallbackPeriod => 14,
64 GpsBrickletFunction::SetDateTimeCallbackPeriod => 15,
65 GpsBrickletFunction::GetDateTimeCallbackPeriod => 16,
66 GpsBrickletFunction::GetIdentity => 255,
67 GpsBrickletFunction::CallbackCoordinates => 17,
68 GpsBrickletFunction::CallbackStatus => 18,
69 GpsBrickletFunction::CallbackAltitude => 19,
70 GpsBrickletFunction::CallbackMotion => 20,
71 GpsBrickletFunction::CallbackDateTime => 21,
72 }
73 }
74}
75pub const GPS_BRICKLET_FIX_NO_FIX: u8 = 1;
76pub const GPS_BRICKLET_FIX_2D_FIX: u8 = 2;
77pub const GPS_BRICKLET_FIX_3D_FIX: u8 = 3;
78pub const GPS_BRICKLET_RESTART_TYPE_HOT_START: u8 = 0;
79pub const GPS_BRICKLET_RESTART_TYPE_WARM_START: u8 = 1;
80pub const GPS_BRICKLET_RESTART_TYPE_COLD_START: u8 = 2;
81pub const GPS_BRICKLET_RESTART_TYPE_FACTORY_RESET: u8 = 3;
82
83#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
84pub struct Coordinates {
85 pub latitude: u32,
86 pub ns: char,
87 pub longitude: u32,
88 pub ew: char,
89 pub pdop: u16,
90 pub hdop: u16,
91 pub vdop: u16,
92 pub epe: u16,
93}
94impl FromByteSlice for Coordinates {
95 fn bytes_expected() -> usize {
96 18
97 }
98 fn from_le_byte_slice(bytes: &[u8]) -> Coordinates {
99 Coordinates {
100 latitude: <u32>::from_le_byte_slice(&bytes[0..4]),
101 ns: <char>::from_le_byte_slice(&bytes[4..5]),
102 longitude: <u32>::from_le_byte_slice(&bytes[5..9]),
103 ew: <char>::from_le_byte_slice(&bytes[9..10]),
104 pdop: <u16>::from_le_byte_slice(&bytes[10..12]),
105 hdop: <u16>::from_le_byte_slice(&bytes[12..14]),
106 vdop: <u16>::from_le_byte_slice(&bytes[14..16]),
107 epe: <u16>::from_le_byte_slice(&bytes[16..18]),
108 }
109 }
110}
111
112#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
113pub struct Status {
114 pub fix: u8,
115 pub satellites_view: u8,
116 pub satellites_used: u8,
117}
118impl FromByteSlice for Status {
119 fn bytes_expected() -> usize {
120 3
121 }
122 fn from_le_byte_slice(bytes: &[u8]) -> Status {
123 Status {
124 fix: <u8>::from_le_byte_slice(&bytes[0..1]),
125 satellites_view: <u8>::from_le_byte_slice(&bytes[1..2]),
126 satellites_used: <u8>::from_le_byte_slice(&bytes[2..3]),
127 }
128 }
129}
130
131#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
132pub struct Altitude {
133 pub altitude: i32,
134 pub geoidal_separation: i32,
135}
136impl FromByteSlice for Altitude {
137 fn bytes_expected() -> usize {
138 8
139 }
140 fn from_le_byte_slice(bytes: &[u8]) -> Altitude {
141 Altitude { altitude: <i32>::from_le_byte_slice(&bytes[0..4]), geoidal_separation: <i32>::from_le_byte_slice(&bytes[4..8]) }
142 }
143}
144
145#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
146pub struct Motion {
147 pub course: u32,
148 pub speed: u32,
149}
150impl FromByteSlice for Motion {
151 fn bytes_expected() -> usize {
152 8
153 }
154 fn from_le_byte_slice(bytes: &[u8]) -> Motion {
155 Motion { course: <u32>::from_le_byte_slice(&bytes[0..4]), speed: <u32>::from_le_byte_slice(&bytes[4..8]) }
156 }
157}
158
159#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
160pub struct DateTime {
161 pub date: u32,
162 pub time: u32,
163}
164impl FromByteSlice for DateTime {
165 fn bytes_expected() -> usize {
166 8
167 }
168 fn from_le_byte_slice(bytes: &[u8]) -> DateTime {
169 DateTime { date: <u32>::from_le_byte_slice(&bytes[0..4]), time: <u32>::from_le_byte_slice(&bytes[4..8]) }
170 }
171}
172
173#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
174pub struct CoordinatesEvent {
175 pub latitude: u32,
176 pub ns: char,
177 pub longitude: u32,
178 pub ew: char,
179 pub pdop: u16,
180 pub hdop: u16,
181 pub vdop: u16,
182 pub epe: u16,
183}
184impl FromByteSlice for CoordinatesEvent {
185 fn bytes_expected() -> usize {
186 18
187 }
188 fn from_le_byte_slice(bytes: &[u8]) -> CoordinatesEvent {
189 CoordinatesEvent {
190 latitude: <u32>::from_le_byte_slice(&bytes[0..4]),
191 ns: <char>::from_le_byte_slice(&bytes[4..5]),
192 longitude: <u32>::from_le_byte_slice(&bytes[5..9]),
193 ew: <char>::from_le_byte_slice(&bytes[9..10]),
194 pdop: <u16>::from_le_byte_slice(&bytes[10..12]),
195 hdop: <u16>::from_le_byte_slice(&bytes[12..14]),
196 vdop: <u16>::from_le_byte_slice(&bytes[14..16]),
197 epe: <u16>::from_le_byte_slice(&bytes[16..18]),
198 }
199 }
200}
201
202#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
203pub struct StatusEvent {
204 pub fix: u8,
205 pub satellites_view: u8,
206 pub satellites_used: u8,
207}
208impl FromByteSlice for StatusEvent {
209 fn bytes_expected() -> usize {
210 3
211 }
212 fn from_le_byte_slice(bytes: &[u8]) -> StatusEvent {
213 StatusEvent {
214 fix: <u8>::from_le_byte_slice(&bytes[0..1]),
215 satellites_view: <u8>::from_le_byte_slice(&bytes[1..2]),
216 satellites_used: <u8>::from_le_byte_slice(&bytes[2..3]),
217 }
218 }
219}
220
221#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
222pub struct AltitudeEvent {
223 pub altitude: i32,
224 pub geoidal_separation: i32,
225}
226impl FromByteSlice for AltitudeEvent {
227 fn bytes_expected() -> usize {
228 8
229 }
230 fn from_le_byte_slice(bytes: &[u8]) -> AltitudeEvent {
231 AltitudeEvent { altitude: <i32>::from_le_byte_slice(&bytes[0..4]), geoidal_separation: <i32>::from_le_byte_slice(&bytes[4..8]) }
232 }
233}
234
235#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
236pub struct MotionEvent {
237 pub course: u32,
238 pub speed: u32,
239}
240impl FromByteSlice for MotionEvent {
241 fn bytes_expected() -> usize {
242 8
243 }
244 fn from_le_byte_slice(bytes: &[u8]) -> MotionEvent {
245 MotionEvent { course: <u32>::from_le_byte_slice(&bytes[0..4]), speed: <u32>::from_le_byte_slice(&bytes[4..8]) }
246 }
247}
248
249#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
250pub struct DateTimeEvent {
251 pub date: u32,
252 pub time: u32,
253}
254impl FromByteSlice for DateTimeEvent {
255 fn bytes_expected() -> usize {
256 8
257 }
258 fn from_le_byte_slice(bytes: &[u8]) -> DateTimeEvent {
259 DateTimeEvent { date: <u32>::from_le_byte_slice(&bytes[0..4]), time: <u32>::from_le_byte_slice(&bytes[4..8]) }
260 }
261}
262
263#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
264pub struct Identity {
265 pub uid: String,
266 pub connected_uid: String,
267 pub position: char,
268 pub hardware_version: [u8; 3],
269 pub firmware_version: [u8; 3],
270 pub device_identifier: u16,
271}
272impl FromByteSlice for Identity {
273 fn bytes_expected() -> usize {
274 25
275 }
276 fn from_le_byte_slice(bytes: &[u8]) -> Identity {
277 Identity {
278 uid: <String>::from_le_byte_slice(&bytes[0..8]),
279 connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
280 position: <char>::from_le_byte_slice(&bytes[16..17]),
281 hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
282 firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
283 device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
284 }
285 }
286}
287
288#[derive(Clone)]
290pub struct GpsBricklet {
291 device: Device,
292}
293impl GpsBricklet {
294 pub const DEVICE_IDENTIFIER: u16 = 222;
295 pub const DEVICE_DISPLAY_NAME: &'static str = "GPS Bricklet";
296 pub fn new(uid: Uid, connection: AsyncIpConnection) -> GpsBricklet {
298 let mut result = GpsBricklet { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
299 result.device.response_expected[u8::from(GpsBrickletFunction::GetCoordinates) as usize] = ResponseExpectedFlag::AlwaysTrue;
300 result.device.response_expected[u8::from(GpsBrickletFunction::GetStatus) as usize] = ResponseExpectedFlag::AlwaysTrue;
301 result.device.response_expected[u8::from(GpsBrickletFunction::GetAltitude) as usize] = ResponseExpectedFlag::AlwaysTrue;
302 result.device.response_expected[u8::from(GpsBrickletFunction::GetMotion) as usize] = ResponseExpectedFlag::AlwaysTrue;
303 result.device.response_expected[u8::from(GpsBrickletFunction::GetDateTime) as usize] = ResponseExpectedFlag::AlwaysTrue;
304 result.device.response_expected[u8::from(GpsBrickletFunction::Restart) as usize] = ResponseExpectedFlag::False;
305 result.device.response_expected[u8::from(GpsBrickletFunction::SetCoordinatesCallbackPeriod) as usize] = ResponseExpectedFlag::True;
306 result.device.response_expected[u8::from(GpsBrickletFunction::GetCoordinatesCallbackPeriod) as usize] =
307 ResponseExpectedFlag::AlwaysTrue;
308 result.device.response_expected[u8::from(GpsBrickletFunction::SetStatusCallbackPeriod) as usize] = ResponseExpectedFlag::True;
309 result.device.response_expected[u8::from(GpsBrickletFunction::GetStatusCallbackPeriod) as usize] = ResponseExpectedFlag::AlwaysTrue;
310 result.device.response_expected[u8::from(GpsBrickletFunction::SetAltitudeCallbackPeriod) as usize] = ResponseExpectedFlag::True;
311 result.device.response_expected[u8::from(GpsBrickletFunction::GetAltitudeCallbackPeriod) as usize] =
312 ResponseExpectedFlag::AlwaysTrue;
313 result.device.response_expected[u8::from(GpsBrickletFunction::SetMotionCallbackPeriod) as usize] = ResponseExpectedFlag::True;
314 result.device.response_expected[u8::from(GpsBrickletFunction::GetMotionCallbackPeriod) as usize] = ResponseExpectedFlag::AlwaysTrue;
315 result.device.response_expected[u8::from(GpsBrickletFunction::SetDateTimeCallbackPeriod) as usize] = ResponseExpectedFlag::True;
316 result.device.response_expected[u8::from(GpsBrickletFunction::GetDateTimeCallbackPeriod) as usize] =
317 ResponseExpectedFlag::AlwaysTrue;
318 result.device.response_expected[u8::from(GpsBrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
319 result
320 }
321
322 pub fn get_response_expected(&mut self, fun: GpsBrickletFunction) -> Result<bool, GetResponseExpectedError> {
337 self.device.get_response_expected(u8::from(fun))
338 }
339
340 pub fn set_response_expected(&mut self, fun: GpsBrickletFunction, response_expected: bool) -> Result<(), SetResponseExpectedError> {
349 self.device.set_response_expected(u8::from(fun), response_expected)
350 }
351
352 pub fn set_response_expected_all(&mut self, response_expected: bool) {
354 self.device.set_response_expected_all(response_expected)
355 }
356
357 pub fn get_api_version(&self) -> [u8; 3] {
360 self.device.api_version
361 }
362
363 pub async fn get_coordinates_callback_receiver(&mut self) -> impl Stream<Item = CoordinatesEvent> {
376 self.device
377 .get_callback_receiver(u8::from(GpsBrickletFunction::CallbackCoordinates))
378 .await
379 .map(|p| CoordinatesEvent::from_le_byte_slice(p.body()))
380 }
381
382 pub async fn get_status_callback_receiver(&mut self) -> impl Stream<Item = StatusEvent> {
389 self.device
390 .get_callback_receiver(u8::from(GpsBrickletFunction::CallbackStatus))
391 .await
392 .map(|p| StatusEvent::from_le_byte_slice(p.body()))
393 }
394
395 pub async fn get_altitude_callback_receiver(&mut self) -> impl Stream<Item = AltitudeEvent> {
403 self.device
404 .get_callback_receiver(u8::from(GpsBrickletFunction::CallbackAltitude))
405 .await
406 .map(|p| AltitudeEvent::from_le_byte_slice(p.body()))
407 }
408
409 pub async fn get_motion_callback_receiver(&mut self) -> impl Stream<Item = MotionEvent> {
417 self.device
418 .get_callback_receiver(u8::from(GpsBrickletFunction::CallbackMotion))
419 .await
420 .map(|p| MotionEvent::from_le_byte_slice(p.body()))
421 }
422
423 pub async fn get_date_time_callback_receiver(&mut self) -> impl Stream<Item = DateTimeEvent> {
430 self.device
431 .get_callback_receiver(u8::from(GpsBrickletFunction::CallbackDateTime))
432 .await
433 .map(|p| DateTimeEvent::from_le_byte_slice(p.body()))
434 }
435
436 pub async fn get_coordinates(&mut self) -> Result<Coordinates, TinkerforgeError> {
455 let payload = [0; 0];
456
457 #[allow(unused_variables)]
458 let result = self.device.get(u8::from(GpsBrickletFunction::GetCoordinates), &payload).await?;
459 Ok(Coordinates::from_le_byte_slice(result.body()))
460 }
461
462 pub async fn get_status(&mut self) -> Result<Status, TinkerforgeError> {
481 let payload = [0; 0];
482
483 #[allow(unused_variables)]
484 let result = self.device.get(u8::from(GpsBrickletFunction::GetStatus), &payload).await?;
485 Ok(Status::from_le_byte_slice(result.body()))
486 }
487
488 pub async fn get_altitude(&mut self) -> Result<Altitude, TinkerforgeError> {
493 let payload = [0; 0];
494
495 #[allow(unused_variables)]
496 let result = self.device.get(u8::from(GpsBrickletFunction::GetAltitude), &payload).await?;
497 Ok(Altitude::from_le_byte_slice(result.body()))
498 }
499
500 pub async fn get_motion(&mut self) -> Result<Motion, TinkerforgeError> {
509 let payload = [0; 0];
510
511 #[allow(unused_variables)]
512 let result = self.device.get(u8::from(GpsBrickletFunction::GetMotion), &payload).await?;
513 Ok(Motion::from_le_byte_slice(result.body()))
514 }
515
516 pub async fn get_date_time(&mut self) -> Result<DateTime, TinkerforgeError> {
521 let payload = [0; 0];
522
523 #[allow(unused_variables)]
524 let result = self.device.get(u8::from(GpsBrickletFunction::GetDateTime), &payload).await?;
525 Ok(DateTime::from_le_byte_slice(result.body()))
526 }
527
528 pub async fn restart(&mut self, restart_type: u8) -> Result<(), TinkerforgeError> {
543 let mut payload = [0; 1];
544 restart_type.write_to_slice(&mut payload[0..1]);
545
546 #[allow(unused_variables)]
547 let result = self.device.set(u8::from(GpsBrickletFunction::Restart), &payload).await?;
548 Ok(())
549 }
550
551 pub async fn set_coordinates_callback_period(&mut self, period: u32) -> Result<(), TinkerforgeError> {
557 let mut payload = [0; 4];
558 period.write_to_slice(&mut payload[0..4]);
559
560 #[allow(unused_variables)]
561 let result = self.device.set(u8::from(GpsBrickletFunction::SetCoordinatesCallbackPeriod), &payload).await?;
562 Ok(())
563 }
564
565 pub async fn get_coordinates_callback_period(&mut self) -> Result<u32, TinkerforgeError> {
567 let payload = [0; 0];
568
569 #[allow(unused_variables)]
570 let result = self.device.get(u8::from(GpsBrickletFunction::GetCoordinatesCallbackPeriod), &payload).await?;
571 Ok(u32::from_le_byte_slice(result.body()))
572 }
573
574 pub async fn set_status_callback_period(&mut self, period: u32) -> Result<(), TinkerforgeError> {
580 let mut payload = [0; 4];
581 period.write_to_slice(&mut payload[0..4]);
582
583 #[allow(unused_variables)]
584 let result = self.device.set(u8::from(GpsBrickletFunction::SetStatusCallbackPeriod), &payload).await?;
585 Ok(())
586 }
587
588 pub async fn get_status_callback_period(&mut self) -> Result<u32, TinkerforgeError> {
590 let payload = [0; 0];
591
592 #[allow(unused_variables)]
593 let result = self.device.get(u8::from(GpsBrickletFunction::GetStatusCallbackPeriod), &payload).await?;
594 Ok(u32::from_le_byte_slice(result.body()))
595 }
596
597 pub async fn set_altitude_callback_period(&mut self, period: u32) -> Result<(), TinkerforgeError> {
603 let mut payload = [0; 4];
604 period.write_to_slice(&mut payload[0..4]);
605
606 #[allow(unused_variables)]
607 let result = self.device.set(u8::from(GpsBrickletFunction::SetAltitudeCallbackPeriod), &payload).await?;
608 Ok(())
609 }
610
611 pub async fn get_altitude_callback_period(&mut self) -> Result<u32, TinkerforgeError> {
613 let payload = [0; 0];
614
615 #[allow(unused_variables)]
616 let result = self.device.get(u8::from(GpsBrickletFunction::GetAltitudeCallbackPeriod), &payload).await?;
617 Ok(u32::from_le_byte_slice(result.body()))
618 }
619
620 pub async fn set_motion_callback_period(&mut self, period: u32) -> Result<(), TinkerforgeError> {
626 let mut payload = [0; 4];
627 period.write_to_slice(&mut payload[0..4]);
628
629 #[allow(unused_variables)]
630 let result = self.device.set(u8::from(GpsBrickletFunction::SetMotionCallbackPeriod), &payload).await?;
631 Ok(())
632 }
633
634 pub async fn get_motion_callback_period(&mut self) -> Result<u32, TinkerforgeError> {
636 let payload = [0; 0];
637
638 #[allow(unused_variables)]
639 let result = self.device.get(u8::from(GpsBrickletFunction::GetMotionCallbackPeriod), &payload).await?;
640 Ok(u32::from_le_byte_slice(result.body()))
641 }
642
643 pub async fn set_date_time_callback_period(&mut self, period: u32) -> Result<(), TinkerforgeError> {
649 let mut payload = [0; 4];
650 period.write_to_slice(&mut payload[0..4]);
651
652 #[allow(unused_variables)]
653 let result = self.device.set(u8::from(GpsBrickletFunction::SetDateTimeCallbackPeriod), &payload).await?;
654 Ok(())
655 }
656
657 pub async fn get_date_time_callback_period(&mut self) -> Result<u32, TinkerforgeError> {
659 let payload = [0; 0];
660
661 #[allow(unused_variables)]
662 let result = self.device.get(u8::from(GpsBrickletFunction::GetDateTimeCallbackPeriod), &payload).await?;
663 Ok(u32::from_le_byte_slice(result.body()))
664 }
665
666 pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
677 let payload = [0; 0];
678
679 #[allow(unused_variables)]
680 let result = self.device.get(u8::from(GpsBrickletFunction::GetIdentity), &payload).await?;
681 Ok(Identity::from_le_byte_slice(result.body()))
682 }
683}