1use chrono::{DateTime, Local, TimeZone, Utc};
2use futures::{SinkExt, StreamExt};
3use std::collections::HashMap;
4use std::{pin::Pin, time::Duration};
5use tokio_serial::SerialPortBuilderExt;
6use tokio_util::codec::Decoder;
7
8use super::measurement::{Memory, SavedPeakMeasurement};
9use super::proto::{
10 codec::ProtocolCodec,
11 command::Command,
12 response::{Ident, Response, ResponsePayload},
13 ProtoError,
14};
15use super::rawmea::{
16 RawMeasurement, RawSavedMeasurement, RawSavedMinMaxMeasurement, RawSavedPeakMeasurement,
17 RawSavedRecordingSessionInfo, RawSessionRecordReadings,
18};
19use crate::measurement::{SavedMeasurement, SavedMinMaxMeasurement, SavedRecordingSessionInfo};
20use crate::proto::command::{
21 ClearMemory, DateFormat, DezibelReference, DigitCount, Language, NumericFormat, TimeFormat,
22};
23use crate::proto::response::MemoryStat;
24use crate::proto::Result;
25
26trait AsyncReadWrite<S>: futures::Sink<S> + futures::Stream {}
27
28impl<T, S> AsyncReadWrite<S> for T where T: futures::Sink<S> + futures::Stream {}
29
30pub type ValueMap = HashMap<u16, String>;
31pub type ValueMaps = HashMap<String, ValueMap>;
32
33#[allow(clippy::type_complexity)]
34pub struct Device {
35 stream: Pin<
36 Box<
37 dyn AsyncReadWrite<
38 Command,
39 Error = std::io::Error,
40 Item = std::result::Result<Response, std::io::Error>,
41 >,
42 >,
43 >,
44}
45
46impl Device {
47 pub fn new(com: impl AsRef<str>, baudrate: u32) -> Result<Self> {
48 let mut port = tokio_serial::new(com.as_ref(), baudrate).open_native_async()?;
49
50 #[cfg(unix)]
51 port.set_exclusive(false)
52 .expect("Unable to set serial port exclusive to false");
53
54 let stream = ProtocolCodec::default().framed(port);
55
56 Ok(Self {
57 stream: Box::pin(stream),
58 })
59 }
60
61 #[cfg(test)]
62 pub fn new_faked(response_buf: Vec<char>) -> Self {
63 let converted = response_buf.iter().map(|x| *x as u8).collect();
64 let stream =
65 ProtocolCodec::default().framed(super::proto::fake::FakeBuffer::new(converted));
66
67 Self {
68 stream: Box::pin(stream),
69 }
70 }
71
72 pub async fn ident(&mut self) -> Result<Ident> {
73 self.stream.send(Command::Id).await?;
74 match self.stream.next().await {
75 Some(Ok(Response::Success(Some(ResponsePayload::Id(id))))) => Ok(id),
76 Some(Ok(response)) => Err(response.into()),
77 Some(Err(ioerr)) => Err(ioerr.into()),
78 None => Err(ProtoError::Abort),
79 }
80 }
81
82 pub async fn value_maps(&mut self) -> Result<ValueMaps> {
83 let map_keys = [
84 "primfunction",
85 "secfunction",
86 "autorange",
87 "unit",
88 "bolt",
89 "mode",
90 "state",
91 "attribute",
92 "recordtype",
93 "isstableflag",
94 "transientstate",
95 ];
96
97 let mut maps = ValueMaps::new();
98
99 for k in &map_keys {
100 self.stream
101 .send(Command::QueryMap(String::from(*k)))
102 .await?;
103 match self.stream.next().await {
104 Some(Ok(Response::Success(Some(ResponsePayload::Map(map))))) => {
105 maps.insert(k.to_string(), map);
106 }
107 Some(Ok(response)) => return Err(response.into()),
108 Some(Err(ioerr)) => return Err(ioerr.into()),
109 None => return Err(ProtoError::Abort),
110 }
111 }
112 Ok(maps)
113 }
114
115 pub async fn all_memory(&mut self, maps: &ValueMaps) -> Result<Vec<Memory>> {
116 let mea: Vec<SavedMeasurement> = self
117 .saved_measurements_all()
118 .await?
119 .into_iter()
120 .map(|raw| (raw, maps).into())
121 .collect();
122
123 let mea_minmax: Vec<SavedMinMaxMeasurement> = self
124 .saved_minmax_all()
125 .await?
126 .into_iter()
127 .map(|raw| (raw, maps).into())
128 .collect();
129
130 let mea_peak: Vec<SavedPeakMeasurement> = self
131 .saved_peak_all()
132 .await?
133 .into_iter()
134 .map(|raw| (raw, maps).into())
135 .collect();
136
137 let recordings: Vec<SavedRecordingSessionInfo> = self
138 .saved_recordings_all()
139 .await?
140 .into_iter()
141 .map(|raw| (raw, maps).into())
142 .collect();
143
144 Ok(mea
145 .into_iter()
146 .map(Memory::Measurement)
147 .chain(mea_minmax.into_iter().map(Memory::MinMaxMeasurement))
148 .chain(mea_peak.into_iter().map(Memory::PeakMeasurement))
149 .chain(recordings.into_iter().map(Memory::Recording))
150 .collect())
151 }
152
153 pub async fn backlight(&mut self) -> Result<Duration> {
154 self.stream.send(Command::GetBacklightTimeout).await?;
155 match self.stream.next().await {
156 Some(Ok(Response::Success(Some(ResponsePayload::BacklightTimeout(duration))))) => {
157 Ok(duration)
158 }
159 Some(Ok(response)) => Err(response.into()),
160 Some(Err(ioerr)) => Err(ioerr.into()),
161 None => Err(ProtoError::Abort),
162 }
163 }
164
165 pub async fn set_backlight(&mut self, duration: Duration) -> Result<()> {
166 self.stream
167 .send(Command::SetBacklightTimeout(duration))
168 .await?;
169 match self.stream.next().await {
170 Some(Ok(Response::Success(None))) => Ok(()),
171 Some(Ok(response)) => Err(response.into()),
172 Some(Err(ioerr)) => Err(ioerr.into()),
173 None => Err(ProtoError::Abort),
174 }
175 }
176
177 pub async fn poweroff(&mut self) -> Result<Duration> {
178 self.stream.send(Command::GetDevicePowerOff).await?;
179 match self.stream.next().await {
180 Some(Ok(Response::Success(Some(ResponsePayload::DevicePowerOff(duration))))) => {
181 Ok(duration)
182 }
183 Some(Ok(response)) => Err(response.into()),
184 Some(Err(ioerr)) => Err(ioerr.into()),
185 None => Err(ProtoError::Abort),
186 }
187 }
188
189 pub async fn set_poweroff(&mut self, duration: Duration) -> Result<()> {
190 self.stream
191 .send(Command::SetDevicePowerOff(duration))
192 .await?;
193 match self.stream.next().await {
194 Some(Ok(Response::Success(None))) => Ok(()),
195 Some(Ok(response)) => Err(response.into()),
196 Some(Err(ioerr)) => Err(ioerr.into()),
197 None => Err(ProtoError::Abort),
198 }
199 }
200
201 pub async fn operator(&mut self) -> Result<String> {
202 self.stream.send(Command::GetOperator).await?;
203 match self.stream.next().await {
204 Some(Ok(Response::Success(Some(ResponsePayload::Operator(operator))))) => Ok(operator),
205 Some(Ok(response)) => Err(response.into()),
206 Some(Err(ioerr)) => Err(ioerr.into()),
207 None => Err(ProtoError::Abort),
208 }
209 }
210
211 pub async fn set_operator(&mut self, operator: impl AsRef<str>) -> Result<()> {
212 self.stream
213 .send(Command::SetOperator(operator.as_ref().to_string()))
214 .await?;
215 match self.stream.next().await {
216 Some(Ok(Response::Success(None))) => Ok(()),
217 Some(Ok(response)) => Err(response.into()),
218 Some(Err(ioerr)) => Err(ioerr.into()),
219 None => Err(ProtoError::Abort),
220 }
221 }
222
223 pub async fn company(&mut self) -> Result<String> {
224 self.stream.send(Command::GetCompany).await?;
225 match self.stream.next().await {
226 Some(Ok(Response::Success(Some(ResponsePayload::Company(company))))) => Ok(company),
227 Some(Ok(response)) => Err(response.into()),
228 Some(Err(ioerr)) => Err(ioerr.into()),
229 None => Err(ProtoError::Abort),
230 }
231 }
232
233 pub async fn set_company(&mut self, company: impl AsRef<str>) -> Result<()> {
234 self.stream
235 .send(Command::SetCompany(company.as_ref().to_string()))
236 .await?;
237 match self.stream.next().await {
238 Some(Ok(Response::Success(None))) => Ok(()),
239 Some(Ok(response)) => Err(response.into()),
240 Some(Err(ioerr)) => Err(ioerr.into()),
241 None => Err(ProtoError::Abort),
242 }
243 }
244
245 pub async fn site(&mut self) -> Result<String> {
246 self.stream.send(Command::GetSite).await?;
247 match self.stream.next().await {
248 Some(Ok(Response::Success(Some(ResponsePayload::Site(site))))) => Ok(site),
249 Some(Ok(response)) => Err(response.into()),
250 Some(Err(ioerr)) => Err(ioerr.into()),
251 None => Err(ProtoError::Abort),
252 }
253 }
254
255 pub async fn set_site(&mut self, site: impl AsRef<str>) -> Result<()> {
256 self.stream
257 .send(Command::SetSite(site.as_ref().to_string()))
258 .await?;
259 match self.stream.next().await {
260 Some(Ok(Response::Success(None))) => Ok(()),
261 Some(Ok(response)) => Err(response.into()),
262 Some(Err(ioerr)) => Err(ioerr.into()),
263 None => Err(ProtoError::Abort),
264 }
265 }
266
267 pub async fn contact(&mut self) -> Result<String> {
268 self.stream.send(Command::GetContact).await?;
269 match self.stream.next().await {
270 Some(Ok(Response::Success(Some(ResponsePayload::Contact(contact))))) => Ok(contact),
271 Some(Ok(response)) => Err(response.into()),
272 Some(Err(ioerr)) => Err(ioerr.into()),
273 None => Err(ProtoError::Abort),
274 }
275 }
276
277 pub async fn set_contact(&mut self, contact: impl AsRef<str>) -> Result<()> {
278 self.stream
279 .send(Command::SetContact(contact.as_ref().to_string()))
280 .await?;
281 match self.stream.next().await {
282 Some(Ok(Response::Success(None))) => Ok(()),
283 Some(Ok(response)) => Err(response.into()),
284 Some(Err(ioerr)) => Err(ioerr.into()),
285 None => Err(ProtoError::Abort),
286 }
287 }
288
289 pub async fn beeper(&mut self) -> Result<bool> {
290 self.stream.send(Command::GetBeeper).await?;
291 match self.stream.next().await {
292 Some(Ok(Response::Success(Some(ResponsePayload::Beeper(state))))) => Ok(state),
293 Some(Ok(response)) => Err(response.into()),
294 Some(Err(ioerr)) => Err(ioerr.into()),
295 None => Err(ProtoError::Abort),
296 }
297 }
298
299 pub async fn set_beeper(&mut self, state: bool) -> Result<()> {
300 self.stream.send(Command::SetBeeper(state)).await?;
301 match self.stream.next().await {
302 Some(Ok(Response::Success(None))) => Ok(()),
303 Some(Ok(response)) => Err(response.into()),
304 Some(Err(ioerr)) => Err(ioerr.into()),
305 None => Err(ProtoError::Abort),
306 }
307 }
308
309 pub async fn smoothing(&mut self) -> Result<bool> {
310 self.stream.send(Command::GetSmoothing).await?;
311 match self.stream.next().await {
312 Some(Ok(Response::Success(Some(ResponsePayload::Smoothing(state))))) => Ok(state),
313 Some(Ok(response)) => Err(response.into()),
314 Some(Err(ioerr)) => Err(ioerr.into()),
315 None => Err(ProtoError::Abort),
316 }
317 }
318
319 pub async fn set_smoothing(&mut self, state: bool) -> Result<()> {
320 self.stream.send(Command::SetSmoothing(state)).await?;
321 match self.stream.next().await {
322 Some(Ok(Response::Success(None))) => Ok(()),
323 Some(Ok(response)) => Err(response.into()),
324 Some(Err(ioerr)) => Err(ioerr.into()),
325 None => Err(ProtoError::Abort),
326 }
327 }
328
329 pub async fn clock(&mut self) -> Result<u64> {
330 self.stream.send(Command::GetClock).await?;
331 match self.stream.next().await {
332 Some(Ok(Response::Success(Some(ResponsePayload::Clock(clock))))) => Ok(clock),
333 Some(Ok(response)) => Err(response.into()),
334 Some(Err(ioerr)) => Err(ioerr.into()),
335 None => Err(ProtoError::Abort),
336 }
337 }
338
339 pub async fn set_clock(&mut self, clock: DateTime<Local>) -> Result<()> {
340 let naive = clock.naive_local();
341 let utc: DateTime<Utc> = Utc.from_utc_datetime(&naive);
342 let secs = utc.timestamp() as u64;
343
344 self.stream.send(Command::SetClock(secs)).await?;
352 match self.stream.next().await {
353 Some(Ok(Response::Success(None))) => Ok(()),
354 Some(Ok(response)) => Err(response.into()),
355 Some(Err(ioerr)) => Err(ioerr.into()),
356 None => Err(ProtoError::Abort),
357 }
358 }
359
360 pub async fn clear(&mut self, mem: ClearMemory) -> Result<()> {
361 self.stream.send(Command::Clear(mem)).await?;
362 match self.stream.next().await {
363 Some(Ok(Response::Success(None))) => Ok(()),
364 Some(Ok(response)) => Err(response.into()),
365 Some(Err(ioerr)) => Err(ioerr.into()),
366 None => Err(ProtoError::Abort),
367 }
368 }
369
370 pub async fn reset(&mut self) -> Result<()> {
371 self.stream.send(Command::ResetDevice).await?;
372 match self.stream.next().await {
373 Some(Ok(Response::Success(None))) => Ok(()),
374 Some(Ok(response)) => Err(response.into()),
375 Some(Err(ioerr)) => Err(ioerr.into()),
376 None => Err(ProtoError::Abort),
377 }
378 }
379
380 pub async fn custom_dbm(&mut self) -> Result<u16> {
381 self.stream.send(Command::GetCustomDbm).await?;
382 match self.stream.next().await {
383 Some(Ok(Response::Success(Some(ResponsePayload::CustomDbm(dbm))))) => Ok(dbm),
384 Some(Ok(response)) => Err(response.into()),
385 Some(Err(ioerr)) => Err(ioerr.into()),
386 None => Err(ProtoError::Abort),
387 }
388 }
389
390 pub async fn set_custom_dbm(&mut self, dbm: u16) -> Result<()> {
391 self.stream.send(Command::SetCustomDbm(dbm)).await?;
392 match self.stream.next().await {
393 Some(Ok(Response::Success(None))) => Ok(()),
394 Some(Ok(response)) => Err(response.into()),
395 Some(Err(ioerr)) => Err(ioerr.into()),
396 None => Err(ProtoError::Abort),
397 }
398 }
399
400 pub async fn dbm_ref(&mut self) -> Result<DezibelReference> {
401 self.stream.send(Command::GetDbmRef).await?;
402 match self.stream.next().await {
403 Some(Ok(Response::Success(Some(ResponsePayload::DbmRef(dbm))))) => Ok(dbm),
404 Some(Ok(response)) => Err(response.into()),
405 Some(Err(ioerr)) => Err(ioerr.into()),
406 None => Err(ProtoError::Abort),
407 }
408 }
409
410 pub async fn set_dbm_ref(&mut self, dbm: DezibelReference) -> Result<()> {
411 self.stream.send(Command::SetDbmRef(dbm)).await?;
412 match self.stream.next().await {
413 Some(Ok(Response::Success(None))) => Ok(()),
414 Some(Ok(response)) => Err(response.into()),
415 Some(Err(ioerr)) => Err(ioerr.into()),
416 None => Err(ProtoError::Abort),
417 }
418 }
419
420 pub async fn temp_offset(&mut self) -> Result<i16> {
421 self.stream.send(Command::GetTempOffset).await?;
422 match self.stream.next().await {
423 Some(Ok(Response::Success(Some(ResponsePayload::TempOffset(offset))))) => Ok(offset),
424 Some(Ok(response)) => Err(response.into()),
425 Some(Err(ioerr)) => Err(ioerr.into()),
426 None => Err(ProtoError::Abort),
427 }
428 }
429
430 pub async fn set_temp_offset(&mut self, offset: i16) -> Result<()> {
431 self.stream.send(Command::SetTempOffset(offset)).await?;
432 match self.stream.next().await {
433 Some(Ok(Response::Success(None))) => Ok(()),
434 Some(Ok(response)) => Err(response.into()),
435 Some(Err(ioerr)) => Err(ioerr.into()),
436 None => Err(ProtoError::Abort),
437 }
438 }
439
440 pub async fn digit_count(&mut self) -> Result<DigitCount> {
441 self.stream.send(Command::GetDigitCount).await?;
442 match self.stream.next().await {
443 Some(Ok(Response::Success(Some(ResponsePayload::DigitCount(dc))))) => Ok(dc),
444 Some(Ok(response)) => Err(response.into()),
445 Some(Err(ioerr)) => Err(ioerr.into()),
446 None => Err(ProtoError::Abort),
447 }
448 }
449
450 pub async fn set_digit_count(&mut self, dc: DigitCount) -> Result<()> {
451 self.stream.send(Command::SetDigitCount(dc)).await?;
452 match self.stream.next().await {
453 Some(Ok(Response::Success(None))) => Ok(()),
454 Some(Ok(response)) => Err(response.into()),
455 Some(Err(ioerr)) => Err(ioerr.into()),
456 None => Err(ProtoError::Abort),
457 }
458 }
459
460 pub async fn autohold_event_threshold(&mut self) -> Result<u8> {
461 self.stream.send(Command::GetAutoHoldEventThreshold).await?;
462 match self.stream.next().await {
463 Some(Ok(Response::Success(Some(ResponsePayload::AutoHoldEventThreshold(thd))))) => {
464 Ok(thd)
465 }
466 Some(Ok(response)) => Err(response.into()),
467 Some(Err(ioerr)) => Err(ioerr.into()),
468 None => Err(ProtoError::Abort),
469 }
470 }
471
472 pub async fn set_autohold_event_threshold(&mut self, thd: u8) -> Result<()> {
473 self.stream
474 .send(Command::SetAutoHoldEventThreshold(thd))
475 .await?;
476 match self.stream.next().await {
477 Some(Ok(Response::Success(None))) => Ok(()),
478 Some(Ok(response)) => Err(response.into()),
479 Some(Err(ioerr)) => Err(ioerr.into()),
480 None => Err(ProtoError::Abort),
481 }
482 }
483
484 pub async fn recording_event_threshold(&mut self) -> Result<u8> {
485 self.stream
486 .send(Command::GetRecordingEventThreshold)
487 .await?;
488 match self.stream.next().await {
489 Some(Ok(Response::Success(Some(ResponsePayload::RecordingEventThreshold(thd))))) => {
490 Ok(thd)
491 }
492 Some(Ok(response)) => Err(response.into()),
493 Some(Err(ioerr)) => Err(ioerr.into()),
494 None => Err(ProtoError::Abort),
495 }
496 }
497
498 pub async fn set_recording_event_threshold(&mut self, thd: u8) -> Result<()> {
499 self.stream
500 .send(Command::SetRecordingEventThreshold(thd))
501 .await?;
502 match self.stream.next().await {
503 Some(Ok(Response::Success(None))) => Ok(()),
504 Some(Ok(response)) => Err(response.into()),
505 Some(Err(ioerr)) => Err(ioerr.into()),
506 None => Err(ProtoError::Abort),
507 }
508 }
509
510 pub async fn language(&mut self) -> Result<Language> {
511 self.stream.send(Command::GetLanguage).await?;
512 match self.stream.next().await {
513 Some(Ok(Response::Success(Some(ResponsePayload::Language(lang))))) => Ok(lang),
514 Some(Ok(response)) => Err(response.into()),
515 Some(Err(ioerr)) => Err(ioerr.into()),
516 None => Err(ProtoError::Abort),
517 }
518 }
519
520 pub async fn set_language(&mut self, lang: Language) -> Result<()> {
521 self.stream.send(Command::SetLanguage(lang)).await?;
522 match self.stream.next().await {
523 Some(Ok(Response::Success(None))) => Ok(()),
524 Some(Ok(response)) => Err(response.into()),
525 Some(Err(ioerr)) => Err(ioerr.into()),
526 None => Err(ProtoError::Abort),
527 }
528 }
529
530 pub async fn date_format(&mut self) -> Result<DateFormat> {
531 self.stream.send(Command::GetDateFormat).await?;
532 match self.stream.next().await {
533 Some(Ok(Response::Success(Some(ResponsePayload::DateFormat(fmt))))) => Ok(fmt),
534 Some(Ok(response)) => Err(response.into()),
535 Some(Err(ioerr)) => Err(ioerr.into()),
536 None => Err(ProtoError::Abort),
537 }
538 }
539
540 pub async fn set_date_format(&mut self, fmt: DateFormat) -> Result<()> {
541 self.stream.send(Command::SetDateFormat(fmt)).await?;
542 match self.stream.next().await {
543 Some(Ok(Response::Success(None))) => Ok(()),
544 Some(Ok(response)) => Err(response.into()),
545 Some(Err(ioerr)) => Err(ioerr.into()),
546 None => Err(ProtoError::Abort),
547 }
548 }
549
550 pub async fn time_format(&mut self) -> Result<TimeFormat> {
551 self.stream.send(Command::GetTimeFormat).await?;
552 match self.stream.next().await {
553 Some(Ok(Response::Success(Some(ResponsePayload::TimeFormat(fmt))))) => Ok(fmt),
554 Some(Ok(response)) => Err(response.into()),
555 Some(Err(ioerr)) => Err(ioerr.into()),
556 None => Err(ProtoError::Abort),
557 }
558 }
559
560 pub async fn set_time_format(&mut self, fmt: TimeFormat) -> Result<()> {
561 self.stream.send(Command::SetTimeFormat(fmt)).await?;
562 match self.stream.next().await {
563 Some(Ok(Response::Success(None))) => Ok(()),
564 Some(Ok(response)) => Err(response.into()),
565 Some(Err(ioerr)) => Err(ioerr.into()),
566 None => Err(ProtoError::Abort),
567 }
568 }
569
570 pub async fn numeric_format(&mut self) -> Result<NumericFormat> {
571 self.stream.send(Command::GetNumFormat).await?;
572 match self.stream.next().await {
573 Some(Ok(Response::Success(Some(ResponsePayload::NumericFormat(fmt))))) => Ok(fmt),
574 Some(Ok(response)) => Err(response.into()),
575 Some(Err(ioerr)) => Err(ioerr.into()),
576 None => Err(ProtoError::Abort),
577 }
578 }
579
580 pub async fn set_numeric_format(&mut self, fmt: NumericFormat) -> Result<()> {
581 self.stream.send(Command::SetNumFormat(fmt)).await?;
582 match self.stream.next().await {
583 Some(Ok(Response::Success(None))) => Ok(()),
584 Some(Ok(response)) => Err(response.into()),
585 Some(Err(ioerr)) => Err(ioerr.into()),
586 None => Err(ProtoError::Abort),
587 }
588 }
589
590 pub async fn save_name(&mut self, slot: u16) -> Result<String> {
591 self.stream.send(Command::GetSaveName(slot)).await?;
592 match self.stream.next().await {
593 Some(Ok(Response::Success(Some(ResponsePayload::SaveName(name))))) => Ok(name),
594 Some(Ok(response)) => Err(response.into()),
595 Some(Err(ioerr)) => Err(ioerr.into()),
596 None => Err(ProtoError::Abort),
597 }
598 }
599
600 pub async fn set_save_name(&mut self, slot: u16, name: impl AsRef<str>) -> Result<()> {
601 self.stream
602 .send(Command::SetSaveName(slot, name.as_ref().to_string()))
603 .await?;
604 match self.stream.next().await {
605 Some(Ok(Response::Success(None))) => Ok(()),
606 Some(Ok(response)) => Err(response.into()),
607 Some(Err(ioerr)) => Err(ioerr.into()),
608 None => Err(ProtoError::Abort),
609 }
610 }
611
612 pub async fn live_measurement(&mut self) -> Result<Option<RawMeasurement>> {
613 self.stream.send(Command::GetMeasurementBinary).await?;
614 match self.stream.next().await {
615 Some(Ok(Response::Success(Some(ResponsePayload::MeasurementBinary(m))))) => Ok(Some(m)),
616 Some(Ok(Response::NoData)) => Ok(None),
617 Some(Ok(response)) => Err(response.into()),
618 Some(Err(ioerr)) => Err(ioerr.into()),
619 None => Err(ProtoError::Abort),
620 }
621 }
622
623 pub async fn memory_statistics(&mut self) -> Result<MemoryStat> {
624 self.stream.send(Command::GetMemoryStat).await?;
625 match self.stream.next().await {
626 Some(Ok(Response::Success(Some(ResponsePayload::MemoryStat(m))))) => Ok(m),
627 Some(Ok(response)) => Err(response.into()),
628 Some(Err(ioerr)) => Err(ioerr.into()),
629 None => Err(ProtoError::Abort),
630 }
631 }
632
633 pub async fn saved_measurement(&mut self, idx: usize) -> Result<RawSavedMeasurement> {
634 self.stream
635 .send(Command::QuerySavedMeasurement(idx))
636 .await?;
637 match self.stream.next().await {
638 Some(Ok(Response::Success(Some(ResponsePayload::SavedMeasurement(m))))) => Ok(m),
639 Some(Ok(response)) => Err(response.into()),
640 Some(Err(ioerr)) => Err(ioerr.into()),
641 None => Err(ProtoError::Abort),
642 }
643 }
644
645 pub async fn saved_measurements_all(&mut self) -> Result<Vec<RawSavedMeasurement>> {
646 let stats = self.memory_statistics().await?;
647 let mut v = Vec::with_capacity(stats.measurement);
648 for i in 0..stats.measurement {
649 let m = self.saved_measurement(i).await?;
650 v.push(m);
651 }
652 Ok(v)
653 }
654
655 pub async fn saved_minmax(&mut self, idx: usize) -> Result<RawSavedMinMaxMeasurement> {
656 self.stream
657 .send(Command::QueryMinMaxSessionInfo(idx))
658 .await?;
659 match self.stream.next().await {
660 Some(Ok(Response::Success(Some(ResponsePayload::MinMaxSessionInfo(m))))) => Ok(m),
661 Some(Ok(response)) => Err(response.into()),
662 Some(Err(ioerr)) => Err(ioerr.into()),
663 None => Err(ProtoError::Abort),
664 }
665 }
666
667 pub async fn saved_minmax_all(&mut self) -> Result<Vec<RawSavedMinMaxMeasurement>> {
668 let stats = self.memory_statistics().await?;
669 let mut v = Vec::with_capacity(stats.min_max);
670 for i in 0..stats.min_max {
671 let m = self.saved_minmax(i).await?;
672 v.push(m);
673 }
674 Ok(v)
675 }
676
677 pub async fn saved_peak(&mut self, idx: usize) -> Result<RawSavedPeakMeasurement> {
678 self.stream.send(Command::QueryPeakSessionInfo(idx)).await?;
679 match self.stream.next().await {
680 Some(Ok(Response::Success(Some(ResponsePayload::PeakSessionInfo(m))))) => Ok(m),
681 Some(Ok(response)) => Err(response.into()),
682 Some(Err(ioerr)) => Err(ioerr.into()),
683 None => Err(ProtoError::Abort),
684 }
685 }
686
687 pub async fn saved_peak_all(&mut self) -> Result<Vec<RawSavedPeakMeasurement>> {
688 let stats = self.memory_statistics().await?;
689 let mut v = Vec::with_capacity(stats.peak);
690 for i in 0..stats.peak {
691 let m = self.saved_peak(i).await?;
692 v.push(m);
693 }
694 Ok(v)
695 }
696
697 pub async fn saved_recording(&mut self, idx: usize) -> Result<RawSavedRecordingSessionInfo> {
698 self.stream
699 .send(Command::QueryRecordedSessionInfo(idx))
700 .await?;
701 match self.stream.next().await {
702 Some(Ok(Response::Success(Some(ResponsePayload::RecordedSessionInfo(m))))) => Ok(m),
703 Some(Ok(response)) => Err(response.into()),
704 Some(Err(ioerr)) => Err(ioerr.into()),
705 None => Err(ProtoError::Abort),
706 }
707 }
708
709 pub async fn saved_recordings_all(&mut self) -> Result<Vec<RawSavedRecordingSessionInfo>> {
710 let stats = self.memory_statistics().await?;
711 let mut v = Vec::with_capacity(stats.recordings);
712 for i in 0..stats.recordings {
713 let m = self.saved_recording(i).await?;
714 v.push(m);
715 }
716 Ok(v)
717 }
718
719 pub async fn session_record_reading(
720 &mut self,
721 reading_idx: usize,
722 sample_idx: usize,
723 ) -> Result<RawSessionRecordReadings> {
724 self.stream
725 .send(Command::QuerySessionRecordReadings(reading_idx, sample_idx))
726 .await?;
727 match self.stream.next().await {
728 Some(Ok(Response::Success(Some(ResponsePayload::SessionRecordReading(m))))) => Ok(m),
729 Some(Ok(response)) => Err(response.into()),
730 Some(Err(ioerr)) => Err(ioerr.into()),
731 None => Err(ProtoError::Abort),
732 }
733 }
734
735 pub async fn session_record_reading_all_cb(
736 &mut self,
737 reading_index: usize,
738 num_samples: usize,
739 callback: impl FnOnce(usize, usize) + Copy + 'static,
740 ) -> Result<Vec<RawSessionRecordReadings>> {
741 let mut v = Vec::with_capacity(num_samples);
742 for i in 0..num_samples {
743 let m = self.session_record_reading(reading_index, i).await?;
744 callback(i, num_samples);
745
746 v.push(m);
747 }
748 Ok(v)
749 }
750
751 pub async fn session_record_reading_all(
752 &mut self,
753 reading_index: usize,
754 num_samples: usize,
755 ) -> Result<Vec<RawSessionRecordReadings>> {
756 self.session_record_reading_all_cb(reading_index, num_samples, |_, _| {})
757 .await
758 }
759}
760
761#[cfg(test)]
762mod tests {
763
764 use crate::measurement::{Measurement, Reading};
765
766 use super::*;
767
768 const GETEMAP: [u8; 1452] = [
769 0x30, 0x0d, 0x34, 0x39, 0x2c, 0x30, 0x2c, 0x4c, 0x49, 0x4d, 0x42, 0x4f, 0x2c, 0x31, 0x2c,
770 0x56, 0x5f, 0x41, 0x43, 0x2c, 0x32, 0x2c, 0x4d, 0x56, 0x5f, 0x41, 0x43, 0x2c, 0x33, 0x2c, 0x56,
772 0x5f, 0x44, 0x43, 0x2c, 0x34, 0x2c, 0x4d, 0x56, 0x5f, 0x44, 0x43, 0x2c, 0x35, 0x2c, 0x56, 0x5f,
774 0x41, 0x43, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x44, 0x43, 0x2c, 0x36, 0x2c, 0x56, 0x5f, 0x44,
776 0x43, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x41, 0x43, 0x2c, 0x37, 0x2c, 0x56, 0x5f, 0x41, 0x43,
778 0x5f, 0x50, 0x4c, 0x55, 0x53, 0x5f, 0x44, 0x43, 0x2c, 0x38, 0x2c, 0x4d, 0x56, 0x5f, 0x41, 0x43,
780 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x44, 0x43, 0x2c, 0x39, 0x2c, 0x4d, 0x56, 0x5f, 0x44, 0x43,
782 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x41, 0x43, 0x2c, 0x31, 0x30, 0x2c, 0x4d, 0x56, 0x5f, 0x41,
784 0x43, 0x5f, 0x50, 0x4c, 0x55, 0x53, 0x5f, 0x44, 0x43, 0x2c, 0x31, 0x31, 0x2c, 0x41, 0x5f, 0x41,
786 0x43, 0x2c, 0x31, 0x32, 0x2c, 0x4d, 0x41, 0x5f, 0x41, 0x43, 0x2c, 0x31, 0x33, 0x2c, 0x55, 0x41,
788 0x5f, 0x41, 0x43, 0x2c, 0x31, 0x34, 0x2c, 0x41, 0x5f, 0x44, 0x43, 0x2c, 0x31, 0x35, 0x2c, 0x4d,
790 0x41, 0x5f, 0x44, 0x43, 0x2c, 0x31, 0x36, 0x2c, 0x55, 0x41, 0x5f, 0x44, 0x43, 0x2c, 0x31, 0x37,
792 0x2c, 0x41, 0x5f, 0x41, 0x43, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x44, 0x43, 0x2c, 0x31, 0x38,
794 0x2c, 0x41, 0x5f, 0x44, 0x43, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x41, 0x43, 0x2c, 0x31, 0x39,
796 0x2c, 0x41, 0x5f, 0x41, 0x43, 0x5f, 0x50, 0x4c, 0x55, 0x53, 0x5f, 0x44, 0x43, 0x2c, 0x32, 0x30,
798 0x2c, 0x4d, 0x41, 0x5f, 0x41, 0x43, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x44, 0x43, 0x2c, 0x32,
800 0x31, 0x2c, 0x4d, 0x41, 0x5f, 0x44, 0x43, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x41, 0x43, 0x2c,
802 0x32, 0x32, 0x2c, 0x4d, 0x41, 0x5f, 0x41, 0x43, 0x5f, 0x50, 0x4c, 0x55, 0x53, 0x5f, 0x44, 0x43,
804 0x2c, 0x32, 0x33, 0x2c, 0x55, 0x41, 0x5f, 0x41, 0x43, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x44,
806 0x43, 0x2c, 0x32, 0x34, 0x2c, 0x55, 0x41, 0x5f, 0x44, 0x43, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f,
808 0x41, 0x43, 0x2c, 0x32, 0x35, 0x2c, 0x55, 0x41, 0x5f, 0x41, 0x43, 0x5f, 0x50, 0x4c, 0x55, 0x53,
810 0x5f, 0x44, 0x43, 0x2c, 0x32, 0x36, 0x2c, 0x54, 0x45, 0x4d, 0x50, 0x45, 0x52, 0x41, 0x54, 0x55,
812 0x52, 0x45, 0x2c, 0x32, 0x37, 0x2c, 0x4f, 0x48, 0x4d, 0x53, 0x2c, 0x32, 0x38, 0x2c, 0x43, 0x4f,
814 0x4e, 0x44, 0x55, 0x43, 0x54, 0x41, 0x4e, 0x43, 0x45, 0x2c, 0x32, 0x39, 0x2c, 0x43, 0x4f, 0x4e,
816 0x54, 0x49, 0x4e, 0x55, 0x49, 0x54, 0x59, 0x2c, 0x33, 0x30, 0x2c, 0x43, 0x41, 0x50, 0x41, 0x43,
818 0x49, 0x54, 0x41, 0x4e, 0x43, 0x45, 0x2c, 0x33, 0x31, 0x2c, 0x44, 0x49, 0x4f, 0x44, 0x45, 0x5f,
820 0x54, 0x45, 0x53, 0x54, 0x2c, 0x33, 0x32, 0x2c, 0x56, 0x5f, 0x41, 0x43, 0x5f, 0x4c, 0x4f, 0x5a,
822 0x2c, 0x33, 0x33, 0x2c, 0x4f, 0x48, 0x4d, 0x53, 0x5f, 0x4c, 0x4f, 0x57, 0x2c, 0x33, 0x34, 0x2c,
824 0x43, 0x41, 0x4c, 0x5f, 0x56, 0x5f, 0x44, 0x43, 0x5f, 0x4c, 0x4f, 0x5a, 0x2c, 0x33, 0x35, 0x2c,
826 0x43, 0x41, 0x4c, 0x5f, 0x41, 0x44, 0x5f, 0x47, 0x41, 0x49, 0x4e, 0x5f, 0x58, 0x32, 0x2c, 0x33,
828 0x36, 0x2c, 0x43, 0x41, 0x4c, 0x5f, 0x41, 0x44, 0x5f, 0x47, 0x41, 0x49, 0x4e, 0x5f, 0x58, 0x31,
830 0x2c, 0x33, 0x37, 0x2c, 0x43, 0x41, 0x4c, 0x5f, 0x52, 0x4d, 0x53, 0x2c, 0x33, 0x38, 0x2c, 0x43,
832 0x41, 0x4c, 0x5f, 0x46, 0x49, 0x4c, 0x54, 0x5f, 0x41, 0x4d, 0x50, 0x2c, 0x33, 0x39, 0x2c, 0x43,
834 0x41, 0x4c, 0x5f, 0x44, 0x43, 0x5f, 0x41, 0x4d, 0x50, 0x5f, 0x58, 0x35, 0x2c, 0x34, 0x30, 0x2c,
836 0x43, 0x41, 0x4c, 0x5f, 0x44, 0x43, 0x5f, 0x41, 0x4d, 0x50, 0x5f, 0x58, 0x31, 0x30, 0x2c, 0x34,
838 0x31, 0x2c, 0x43, 0x41, 0x4c, 0x5f, 0x4e, 0x49, 0x4e, 0x56, 0x5f, 0x41, 0x43, 0x5f, 0x41, 0x4d,
840 0x50, 0x2c, 0x34, 0x32, 0x2c, 0x43, 0x41, 0x4c, 0x5f, 0x49, 0x53, 0x52, 0x43, 0x5f, 0x35, 0x30,
842 0x30, 0x4e, 0x41, 0x2c, 0x34, 0x33, 0x2c, 0x43, 0x41, 0x4c, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x5f,
844 0x54, 0x52, 0x49, 0x4d, 0x5f, 0x4d, 0x56, 0x5f, 0x44, 0x43, 0x2c, 0x34, 0x34, 0x2c, 0x43, 0x41,
846 0x4c, 0x5f, 0x41, 0x43, 0x44, 0x43, 0x5f, 0x41, 0x43, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x2c, 0x34,
848 0x35, 0x2c, 0x43, 0x41, 0x4c, 0x5f, 0x56, 0x5f, 0x41, 0x43, 0x5f, 0x4c, 0x4f, 0x5a, 0x2c, 0x34,
850 0x36, 0x2c, 0x43, 0x41, 0x4c, 0x5f, 0x56, 0x5f, 0x41, 0x43, 0x5f, 0x50, 0x45, 0x41, 0x4b, 0x2c,
852 0x34, 0x37, 0x2c, 0x43, 0x41, 0x4c, 0x5f, 0x4d, 0x56, 0x5f, 0x41, 0x43, 0x5f, 0x50, 0x45, 0x41,
854 0x4b, 0x2c, 0x34, 0x38, 0x2c, 0x43, 0x41, 0x4c, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x45, 0x52, 0x41,
856 0x54, 0x55, 0x52, 0x45, 0x0d, 0x30, 0x0d, 0x31, 0x30, 0x2c, 0x30, 0x2c, 0x4e, 0x4f, 0x4e, 0x45, 0x2c, 0x31, 0x2c, 0x48,
860 0x45, 0x52, 0x54, 0x5a, 0x2c, 0x32, 0x2c, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c,
862 0x45, 0x2c, 0x33, 0x2c, 0x50, 0x55, 0x4c, 0x53, 0x45, 0x5f, 0x57, 0x49, 0x44, 0x54, 0x48, 0x2c,
864 0x34, 0x2c, 0x44, 0x42, 0x4d, 0x2c, 0x35, 0x2c, 0x44, 0x42, 0x56, 0x2c, 0x36, 0x2c, 0x44, 0x42,
866 0x4d, 0x5f, 0x48, 0x45, 0x52, 0x54, 0x5a, 0x2c, 0x37, 0x2c, 0x44, 0x42, 0x56, 0x5f, 0x48, 0x45,
868 0x52, 0x54, 0x5a, 0x2c, 0x38, 0x2c, 0x43, 0x52, 0x45, 0x53, 0x54, 0x5f, 0x46, 0x41, 0x43, 0x54,
870 0x4f, 0x52, 0x2c, 0x39, 0x2c, 0x50, 0x45, 0x41, 0x4b, 0x5f, 0x4d, 0x49, 0x4e, 0x5f, 0x4d, 0x41,
872 0x58, 0x0d, 0x30, 0x0d, 0x32, 0x2c, 0x31, 0x2c, 0x41, 0x55, 0x54, 0x4f, 0x2c, 0x30, 0x2c, 0x4d, 0x41,
875 0x4e, 0x55, 0x41, 0x4c, 0x0d, 0x30, 0x0d, 0x32, 0x31, 0x2c, 0x30, 0x2c, 0x4e, 0x4f, 0x4e, 0x45, 0x2c, 0x31, 0x2c, 0x56,
878 0x44, 0x43, 0x2c, 0x32, 0x2c, 0x56, 0x41, 0x43, 0x2c, 0x33, 0x2c, 0x56, 0x41, 0x43, 0x5f, 0x50,
880 0x4c, 0x55, 0x53, 0x5f, 0x44, 0x43, 0x2c, 0x34, 0x2c, 0x56, 0x2c, 0x35, 0x2c, 0x41, 0x44, 0x43,
882 0x2c, 0x36, 0x2c, 0x41, 0x41, 0x43, 0x2c, 0x37, 0x2c, 0x41, 0x41, 0x43, 0x5f, 0x50, 0x4c, 0x55,
884 0x53, 0x5f, 0x44, 0x43, 0x2c, 0x38, 0x2c, 0x41, 0x2c, 0x39, 0x2c, 0x4f, 0x48, 0x4d, 0x2c, 0x31,
886 0x30, 0x2c, 0x53, 0x49, 0x45, 0x2c, 0x31, 0x31, 0x2c, 0x48, 0x7a, 0x2c, 0x31, 0x32, 0x2c, 0x53,
888 0x2c, 0x31, 0x33, 0x2c, 0x46, 0x2c, 0x31, 0x34, 0x2c, 0x43, 0x45, 0x4c, 0x2c, 0x31, 0x35, 0x2c,
890 0x46, 0x41, 0x52, 0x2c, 0x31, 0x36, 0x2c, 0x50, 0x43, 0x54, 0x2c, 0x31, 0x37, 0x2c, 0x64, 0x42,
892 0x2c, 0x31, 0x38, 0x2c, 0x64, 0x42, 0x56, 0x2c, 0x31, 0x39, 0x2c, 0x64, 0x42, 0x6d, 0x2c, 0x32,
894 0x30, 0x2c, 0x43, 0x52, 0x45, 0x53, 0x54, 0x5f, 0x46, 0x41, 0x43, 0x54, 0x4f, 0x52,
896 0x0d, 0x30, 0x0d, 0x32, 0x2c, 0x30, 0x2c, 0x4f, 0x46, 0x46, 0x2c, 0x31, 0x2c, 0x4f, 0x4e,
898 0x0d, 0x30, 0x0d, 0x31, 0x30, 0x2c, 0x30, 0x2c, 0x4e, 0x4f, 0x4e, 0x45, 0x2c, 0x31, 0x2c, 0x41,
900 0x55, 0x54, 0x4f, 0x5f, 0x48, 0x4f, 0x4c, 0x44, 0x2c, 0x32, 0x2c, 0x41, 0x55, 0x54, 0x4f, 0x5f,
902 0x53, 0x41, 0x56, 0x45, 0x2c, 0x34, 0x2c, 0x48, 0x4f, 0x4c, 0x44, 0x2c, 0x38, 0x2c, 0x4c, 0x4f,
904 0x57, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x5f, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x2c, 0x31, 0x36,
906 0x2c, 0x4d, 0x49, 0x4e, 0x5f, 0x4d, 0x41, 0x58, 0x5f, 0x41, 0x56, 0x47, 0x2c, 0x33, 0x32, 0x2c,
908 0x52, 0x45, 0x43, 0x4f, 0x52, 0x44, 0x2c, 0x36, 0x34, 0x2c, 0x52, 0x45, 0x4c, 0x2c, 0x31, 0x32,
910 0x38, 0x2c, 0x52, 0x45, 0x4c, 0x5f, 0x50, 0x45, 0x52, 0x43, 0x45, 0x4e, 0x54, 0x2c, 0x32, 0x35,
912 0x36, 0x2c, 0x43, 0x41, 0x4c, 0x49, 0x42, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e,
914 0x0d, 0x30, 0x0d, 0x38, 0x2c, 0x30, 0x2c, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x2c,
916 0x31, 0x2c, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x2c, 0x32, 0x2c, 0x4e, 0x4f, 0x52, 0x4d,
918 0x41, 0x4c, 0x2c, 0x33, 0x2c, 0x42, 0x4c, 0x41, 0x4e, 0x4b, 0x2c, 0x34, 0x2c, 0x44, 0x49, 0x53,
920 0x43, 0x48, 0x41, 0x52, 0x47, 0x45, 0x2c, 0x35, 0x2c, 0x4f, 0x4c, 0x2c, 0x36, 0x2c, 0x4f, 0x4c,
922 0x5f, 0x4d, 0x49, 0x4e, 0x55, 0x53, 0x2c, 0x37, 0x2c, 0x4f, 0x50, 0x45, 0x4e, 0x5f, 0x54, 0x43,
924 0x0d, 0x30, 0x0d, 0x39, 0x2c, 0x30, 0x2c, 0x4e, 0x4f, 0x4e, 0x45, 0x2c, 0x31, 0x2c, 0x4f, 0x50,
926 0x45, 0x4e, 0x5f, 0x43, 0x49, 0x52, 0x43, 0x55, 0x49, 0x54, 0x2c, 0x32, 0x2c, 0x53, 0x48, 0x4f,
928 0x52, 0x54, 0x5f, 0x43, 0x49, 0x52, 0x43, 0x55, 0x49, 0x54, 0x2c, 0x33, 0x2c, 0x47, 0x4c, 0x49,
930 0x54, 0x43, 0x48, 0x5f, 0x43, 0x49, 0x52, 0x43, 0x55, 0x49, 0x54, 0x2c, 0x34, 0x2c, 0x47, 0x4f,
932 0x4f, 0x44, 0x5f, 0x44, 0x49, 0x4f, 0x44, 0x45, 0x2c, 0x35, 0x2c, 0x4c, 0x4f, 0x5f, 0x4f, 0x48,
934 0x4d, 0x53, 0x2c, 0x36, 0x2c, 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x45, 0x44,
936 0x47, 0x45, 0x2c, 0x37, 0x2c, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x45, 0x44,
938 0x47, 0x45, 0x2c, 0x38, 0x2c, 0x48, 0x49, 0x47, 0x48, 0x5f, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e,
940 0x54, 0x0d, 0x30, 0x0d, 0x32, 0x2c, 0x30, 0x2c, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x2c, 0x31, 0x2c, 0x49,
943 0x4e, 0x54, 0x45, 0x52, 0x56, 0x41, 0x4c, 0x0d, 0x30, 0x0d, 0x32, 0x2c, 0x30, 0x2c, 0x55, 0x4e, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x2c,
946 0x31, 0x2c, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x0d, 0x30, 0x0d, 0x35, 0x2c, 0x30, 0x2c, 0x4e, 0x4f, 0x4e, 0x5f, 0x54, 0x2c, 0x31, 0x2c, 0x52,
949 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x55, 0x50, 0x2c, 0x32, 0x2c, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x5f,
951 0x44, 0x4f, 0x57, 0x4e, 0x2c, 0x33, 0x2c, 0x4f, 0x56, 0x45, 0x52, 0x4c, 0x4f, 0x41, 0x44, 0x2c,
953 0x34, 0x2c, 0x4f, 0x50, 0x45, 0x4e, 0x5f, 0x54, 0x43, 0x0d, ];
956
957 #[tokio::test]
958 async fn test_get_id() {
959 let mut device = Device::new_faked(vec![
960 '0', '\r', 'F', 'l', 'u', 'k', 'e', ',', 'x', ',', 'x', '\r',
961 ]);
962 assert!(device.ident().await.is_ok());
963 }
964
965 #[tokio::test]
966 async fn test_set_backlight() {
967 let mut device = Device::new_faked(vec!['0', '\r']);
968 assert!(device
969 .set_backlight(Duration::from_secs(60 * 15))
970 .await
971 .is_ok());
972 }
973
974 #[tokio::test]
975 async fn test_set_backlight_in_settings_mode() {
976 let mut device = Device::new_faked(vec!['2', '\r']);
977 assert!(device
978 .set_backlight(Duration::from_secs(60 * 15))
979 .await
980 .is_err());
981 }
982
983 #[tokio::test]
984 async fn qddb_parse() {
985 let fake: Vec<u8> = vec![
986 0x30, 0x0d, 0x23, 0x30, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x40,
987 0x7f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
989 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0xc2, 0xf5, 0x11, 0x40, 0xf6, 0x28,
991 0x5c, 0x8f, 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0xbf, 0xf3,
993 0xd8, 0x41, 0x00, 0x40, 0x9d, 0xeb, 0x02, 0x00, 0xc2, 0xf5, 0x11, 0x40, 0xf6, 0x28, 0x5c, 0x8f,
995 0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0xbf, 0xf3, 0xd8, 0x41,
997 0x00, 0x40, 0x9d, 0xeb, 0x0d, ];
1000
1001 let mut device = Device::new_faked(
1002 GETEMAP
1003 .iter()
1004 .chain(fake.iter())
1005 .map(|x| *x as char)
1006 .collect(),
1007 );
1008
1009 let maps = device.value_maps().await.expect("Value Maps");
1010
1011 let raw_mea = device
1012 .live_measurement()
1013 .await
1014 .expect("Raw measurement")
1015 .expect("No data returned");
1016 println!("Raw measurement: {:?}", raw_mea);
1017 assert_eq!(raw_mea.pri_function, 27);
1018 assert_eq!(raw_mea.sec_function, 0);
1019 assert_eq!(raw_mea.auto_range, 1);
1020 assert_eq!(raw_mea.unit, 9);
1021 assert_eq!(raw_mea.unit_multiplier, 0);
1022 assert_eq!(raw_mea.bolt, 0);
1023
1024 assert_eq!(raw_mea.bolt, 0);
1025 assert_eq!(raw_mea.modes, 0);
1026 assert_eq!(raw_mea.readings.len(), 2);
1027
1028 println!("{:?}", Measurement::from((raw_mea.clone(), &maps)));
1029
1030 for rr in &raw_mea.readings {
1031 let r: Reading = (rr.clone(), &maps).into();
1032 println!("{}", r);
1033 }
1034
1035 }
1037}