f289ctrl/
device.rs

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        /*
345        let secs = clock
346            .duration_since(SystemTime::UNIX_EPOCH)
347            .map_err(|_e| ProtoError::Abort)?
348            .as_secs();
349             */
350
351        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, // 0.49,0,LIMBO,1,V
771        0x5f, 0x41, 0x43, 0x2c, 0x32, 0x2c, 0x4d, 0x56, 0x5f, 0x41, 0x43, 0x2c, 0x33, 0x2c, 0x56,
772        0x5f, // _AC,2,MV_AC,3,V_
773        0x44, 0x43, 0x2c, 0x34, 0x2c, 0x4d, 0x56, 0x5f, 0x44, 0x43, 0x2c, 0x35, 0x2c, 0x56, 0x5f,
774        0x41, //0xDC,,4,MV_DC,5,V_A
775        0x43, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x44, 0x43, 0x2c, 0x36, 0x2c, 0x56, 0x5f, 0x44,
776        0x43, // C_OVER_DC,6,V_DC
777        0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x41, 0x43, 0x2c, 0x37, 0x2c, 0x56, 0x5f, 0x41, 0x43,
778        0x5f, // _OVER_AC,7,V_AC_
779        0x50, 0x4c, 0x55, 0x53, 0x5f, 0x44, 0x43, 0x2c, 0x38, 0x2c, 0x4d, 0x56, 0x5f, 0x41, 0x43,
780        0x5f, // PLUS_DC,8,MV_AC_
781        0x4f, 0x56, 0x45, 0x52, 0x5f, 0x44, 0x43, 0x2c, 0x39, 0x2c, 0x4d, 0x56, 0x5f, 0x44, 0x43,
782        0x5f, // OVER_DC,9,MV_DC_
783        0x4f, 0x56, 0x45, 0x52, 0x5f, 0x41, 0x43, 0x2c, 0x31, 0x30, 0x2c, 0x4d, 0x56, 0x5f, 0x41,
784        0x43, // OVER_AC,10,MV_AC
785        0x5f, 0x50, 0x4c, 0x55, 0x53, 0x5f, 0x44, 0x43, 0x2c, 0x31, 0x31, 0x2c, 0x41, 0x5f, 0x41,
786        0x43, // _PLUS_DC,11,A_AC
787        0x2c, 0x31, 0x32, 0x2c, 0x4d, 0x41, 0x5f, 0x41, 0x43, 0x2c, 0x31, 0x33, 0x2c, 0x55, 0x41,
788        0x5f, // ,12,MA_AC,13,UA_
789        0x41, 0x43, 0x2c, 0x31, 0x34, 0x2c, 0x41, 0x5f, 0x44, 0x43, 0x2c, 0x31, 0x35, 0x2c, 0x4d,
790        0x41, //0xAC,,14,A_DC,15,MA
791        0x5f, 0x44, 0x43, 0x2c, 0x31, 0x36, 0x2c, 0x55, 0x41, 0x5f, 0x44, 0x43, 0x2c, 0x31, 0x37,
792        0x2c, // _DC,16,UA_DC,17,
793        0x41, 0x5f, 0x41, 0x43, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x44, 0x43, 0x2c, 0x31, 0x38,
794        0x2c, // A_AC_OVER_DC,18,
795        0x41, 0x5f, 0x44, 0x43, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x41, 0x43, 0x2c, 0x31, 0x39,
796        0x2c, // A_DC_OVER_AC,19,
797        0x41, 0x5f, 0x41, 0x43, 0x5f, 0x50, 0x4c, 0x55, 0x53, 0x5f, 0x44, 0x43, 0x2c, 0x32, 0x30,
798        0x2c, // A_AC_PLUS_DC,20,
799        0x4d, 0x41, 0x5f, 0x41, 0x43, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x44, 0x43, 0x2c, 0x32,
800        0x31, // MA_AC_OVER_DC,21
801        0x2c, 0x4d, 0x41, 0x5f, 0x44, 0x43, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x41, 0x43, 0x2c,
802        0x32, // ,MA_DC_OVER_AC,2
803        0x32, 0x2c, 0x4d, 0x41, 0x5f, 0x41, 0x43, 0x5f, 0x50, 0x4c, 0x55, 0x53, 0x5f, 0x44, 0x43,
804        0x2c, // 2,MA_AC_PLUS_DC,
805        0x32, 0x33, 0x2c, 0x55, 0x41, 0x5f, 0x41, 0x43, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x44,
806        0x43, //0x23,,UA_AC_OVER_DC
807        0x2c, 0x32, 0x34, 0x2c, 0x55, 0x41, 0x5f, 0x44, 0x43, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x5f,
808        0x41, // ,24,UA_DC_OVER_A
809        0x43, 0x2c, 0x32, 0x35, 0x2c, 0x55, 0x41, 0x5f, 0x41, 0x43, 0x5f, 0x50, 0x4c, 0x55, 0x53,
810        0x5f, // C,25,UA_AC_PLUS_
811        0x44, 0x43, 0x2c, 0x32, 0x36, 0x2c, 0x54, 0x45, 0x4d, 0x50, 0x45, 0x52, 0x41, 0x54, 0x55,
812        0x52, //0xDC,,26,TEMPERATUR
813        0x45, 0x2c, 0x32, 0x37, 0x2c, 0x4f, 0x48, 0x4d, 0x53, 0x2c, 0x32, 0x38, 0x2c, 0x43, 0x4f,
814        0x4e, // E,27,OHMS,28,CON
815        0x44, 0x55, 0x43, 0x54, 0x41, 0x4e, 0x43, 0x45, 0x2c, 0x32, 0x39, 0x2c, 0x43, 0x4f, 0x4e,
816        0x54, // DUCTANCE,29,CONT
817        0x49, 0x4e, 0x55, 0x49, 0x54, 0x59, 0x2c, 0x33, 0x30, 0x2c, 0x43, 0x41, 0x50, 0x41, 0x43,
818        0x49, // INUITY,30,CAPACI
819        0x54, 0x41, 0x4e, 0x43, 0x45, 0x2c, 0x33, 0x31, 0x2c, 0x44, 0x49, 0x4f, 0x44, 0x45, 0x5f,
820        0x54, // TANCE,31,DIODE_T
821        0x45, 0x53, 0x54, 0x2c, 0x33, 0x32, 0x2c, 0x56, 0x5f, 0x41, 0x43, 0x5f, 0x4c, 0x4f, 0x5a,
822        0x2c, // EST,32,V_AC_LOZ,
823        0x33, 0x33, 0x2c, 0x4f, 0x48, 0x4d, 0x53, 0x5f, 0x4c, 0x4f, 0x57, 0x2c, 0x33, 0x34, 0x2c,
824        0x43, //0x33,,OHMS_LOW,34,C
825        0x41, 0x4c, 0x5f, 0x56, 0x5f, 0x44, 0x43, 0x5f, 0x4c, 0x4f, 0x5a, 0x2c, 0x33, 0x35, 0x2c,
826        0x43, // AL_V_DC_LOZ,35,C
827        0x41, 0x4c, 0x5f, 0x41, 0x44, 0x5f, 0x47, 0x41, 0x49, 0x4e, 0x5f, 0x58, 0x32, 0x2c, 0x33,
828        0x36, // AL_AD_GAIN_X2,36
829        0x2c, 0x43, 0x41, 0x4c, 0x5f, 0x41, 0x44, 0x5f, 0x47, 0x41, 0x49, 0x4e, 0x5f, 0x58, 0x31,
830        0x2c, // ,CAL_AD_GAIN_X1,
831        0x33, 0x37, 0x2c, 0x43, 0x41, 0x4c, 0x5f, 0x52, 0x4d, 0x53, 0x2c, 0x33, 0x38, 0x2c, 0x43,
832        0x41, //0x37,,CAL_RMS,38,CA
833        0x4c, 0x5f, 0x46, 0x49, 0x4c, 0x54, 0x5f, 0x41, 0x4d, 0x50, 0x2c, 0x33, 0x39, 0x2c, 0x43,
834        0x41, // L_FILT_AMP,39,CA
835        0x4c, 0x5f, 0x44, 0x43, 0x5f, 0x41, 0x4d, 0x50, 0x5f, 0x58, 0x35, 0x2c, 0x34, 0x30, 0x2c,
836        0x43, // L_DC_AMP_X5,40,C
837        0x41, 0x4c, 0x5f, 0x44, 0x43, 0x5f, 0x41, 0x4d, 0x50, 0x5f, 0x58, 0x31, 0x30, 0x2c, 0x34,
838        0x31, // AL_DC_AMP_X10,41
839        0x2c, 0x43, 0x41, 0x4c, 0x5f, 0x4e, 0x49, 0x4e, 0x56, 0x5f, 0x41, 0x43, 0x5f, 0x41, 0x4d,
840        0x50, // ,CAL_NINV_AC_AMP
841        0x2c, 0x34, 0x32, 0x2c, 0x43, 0x41, 0x4c, 0x5f, 0x49, 0x53, 0x52, 0x43, 0x5f, 0x35, 0x30,
842        0x30, // ,42,CAL_ISRC_500
843        0x4e, 0x41, 0x2c, 0x34, 0x33, 0x2c, 0x43, 0x41, 0x4c, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x5f,
844        0x54, // NA,43,CAL_COMP_T
845        0x52, 0x49, 0x4d, 0x5f, 0x4d, 0x56, 0x5f, 0x44, 0x43, 0x2c, 0x34, 0x34, 0x2c, 0x43, 0x41,
846        0x4c, // RIM_MV_DC,44,CAL
847        0x5f, 0x41, 0x43, 0x44, 0x43, 0x5f, 0x41, 0x43, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x2c, 0x34,
848        0x35, // _ACDC_AC_COMP,45
849        0x2c, 0x43, 0x41, 0x4c, 0x5f, 0x56, 0x5f, 0x41, 0x43, 0x5f, 0x4c, 0x4f, 0x5a, 0x2c, 0x34,
850        0x36, // ,CAL_V_AC_LOZ,46
851        0x2c, 0x43, 0x41, 0x4c, 0x5f, 0x56, 0x5f, 0x41, 0x43, 0x5f, 0x50, 0x45, 0x41, 0x4b, 0x2c,
852        0x34, // ,CAL_V_AC_PEAK,4
853        0x37, 0x2c, 0x43, 0x41, 0x4c, 0x5f, 0x4d, 0x56, 0x5f, 0x41, 0x43, 0x5f, 0x50, 0x45, 0x41,
854        0x4b, // 7,CAL_MV_AC_PEAK
855        0x2c, 0x34, 0x38, 0x2c, 0x43, 0x41, 0x4c, 0x5f, 0x54, 0x45, 0x4d, 0x50, 0x45, 0x52, 0x41,
856        0x54, // ,48,CAL_TEMPERAT
857        0x55, 0x52, 0x45, 0x0d, //             URE.
858        //
859        0x30, 0x0d, 0x31, 0x30, 0x2c, 0x30, 0x2c, 0x4e, 0x4f, 0x4e, 0x45, 0x2c, 0x31, 0x2c, 0x48,
860        0x45, // 0.10,0,NONE,1,HE
861        0x52, 0x54, 0x5a, 0x2c, 0x32, 0x2c, 0x44, 0x55, 0x54, 0x59, 0x5f, 0x43, 0x59, 0x43, 0x4c,
862        0x45, // RTZ,2,DUTY_CYCLE
863        0x2c, 0x33, 0x2c, 0x50, 0x55, 0x4c, 0x53, 0x45, 0x5f, 0x57, 0x49, 0x44, 0x54, 0x48, 0x2c,
864        0x34, // ,3,PULSE_WIDTH,4
865        0x2c, 0x44, 0x42, 0x4d, 0x2c, 0x35, 0x2c, 0x44, 0x42, 0x56, 0x2c, 0x36, 0x2c, 0x44, 0x42,
866        0x4d, // ,DBM,5,DBV,6,DBM
867        0x5f, 0x48, 0x45, 0x52, 0x54, 0x5a, 0x2c, 0x37, 0x2c, 0x44, 0x42, 0x56, 0x5f, 0x48, 0x45,
868        0x52, // _HERTZ,7,DBV_HER
869        0x54, 0x5a, 0x2c, 0x38, 0x2c, 0x43, 0x52, 0x45, 0x53, 0x54, 0x5f, 0x46, 0x41, 0x43, 0x54,
870        0x4f, // TZ,8,CREST_FACTO
871        0x52, 0x2c, 0x39, 0x2c, 0x50, 0x45, 0x41, 0x4b, 0x5f, 0x4d, 0x49, 0x4e, 0x5f, 0x4d, 0x41,
872        0x58, // R,9,PEAK_MIN_MAX
873        0x0d, //                .
874        0x30, 0x0d, 0x32, 0x2c, 0x31, 0x2c, 0x41, 0x55, 0x54, 0x4f, 0x2c, 0x30, 0x2c, 0x4d, 0x41,
875        0x4e, // 0.2,1,AUTO,0,MAN
876        0x55, 0x41, 0x4c, 0x0d, //             UAL.
877        0x30, 0x0d, 0x32, 0x31, 0x2c, 0x30, 0x2c, 0x4e, 0x4f, 0x4e, 0x45, 0x2c, 0x31, 0x2c, 0x56,
878        0x44, // 0.21,0,NONE,1,VD
879        0x43, 0x2c, 0x32, 0x2c, 0x56, 0x41, 0x43, 0x2c, 0x33, 0x2c, 0x56, 0x41, 0x43, 0x5f, 0x50,
880        0x4c, // C,2,VAC,3,VAC_PL
881        0x55, 0x53, 0x5f, 0x44, 0x43, 0x2c, 0x34, 0x2c, 0x56, 0x2c, 0x35, 0x2c, 0x41, 0x44, 0x43,
882        0x2c, // US_DC,4,V,5,ADC,
883        0x36, 0x2c, 0x41, 0x41, 0x43, 0x2c, 0x37, 0x2c, 0x41, 0x41, 0x43, 0x5f, 0x50, 0x4c, 0x55,
884        0x53, // 6,AAC,7,AAC_PLUS
885        0x5f, 0x44, 0x43, 0x2c, 0x38, 0x2c, 0x41, 0x2c, 0x39, 0x2c, 0x4f, 0x48, 0x4d, 0x2c, 0x31,
886        0x30, // _DC,8,A,9,OHM,10
887        0x2c, 0x53, 0x49, 0x45, 0x2c, 0x31, 0x31, 0x2c, 0x48, 0x7a, 0x2c, 0x31, 0x32, 0x2c, 0x53,
888        0x2c, // ,SIE,11,Hz,12,S,
889        0x31, 0x33, 0x2c, 0x46, 0x2c, 0x31, 0x34, 0x2c, 0x43, 0x45, 0x4c, 0x2c, 0x31, 0x35, 0x2c,
890        0x46, //0x13,,F,14,CEL,15,F
891        0x41, 0x52, 0x2c, 0x31, 0x36, 0x2c, 0x50, 0x43, 0x54, 0x2c, 0x31, 0x37, 0x2c, 0x64, 0x42,
892        0x2c, // AR,16,PCT,17,dB,
893        0x31, 0x38, 0x2c, 0x64, 0x42, 0x56, 0x2c, 0x31, 0x39, 0x2c, 0x64, 0x42, 0x6d, 0x2c, 0x32,
894        0x30, //0x18,,dBV,19,dBm,20
895        0x2c, 0x43, 0x52, 0x45, 0x53, 0x54, 0x5f, 0x46, 0x41, 0x43, 0x54, 0x4f, 0x52,
896        0x0d, //   ,CREST_FACTOR.
897        0x30, 0x0d, 0x32, 0x2c, 0x30, 0x2c, 0x4f, 0x46, 0x46, 0x2c, 0x31, 0x2c, 0x4f, 0x4e,
898        0x0d, //  0.2,0,OFF,1,ON.
899        0x30, 0x0d, 0x31, 0x30, 0x2c, 0x30, 0x2c, 0x4e, 0x4f, 0x4e, 0x45, 0x2c, 0x31, 0x2c, 0x41,
900        0x55, // 0.10,0,NONE,1,AU
901        0x54, 0x4f, 0x5f, 0x48, 0x4f, 0x4c, 0x44, 0x2c, 0x32, 0x2c, 0x41, 0x55, 0x54, 0x4f, 0x5f,
902        0x53, // TO_HOLD,2,AUTO_S
903        0x41, 0x56, 0x45, 0x2c, 0x34, 0x2c, 0x48, 0x4f, 0x4c, 0x44, 0x2c, 0x38, 0x2c, 0x4c, 0x4f,
904        0x57, // AVE,4,HOLD,8,LOW
905        0x5f, 0x50, 0x41, 0x53, 0x53, 0x5f, 0x46, 0x49, 0x4c, 0x54, 0x45, 0x52, 0x2c, 0x31, 0x36,
906        0x2c, // _PASS_FILTER,16,
907        0x4d, 0x49, 0x4e, 0x5f, 0x4d, 0x41, 0x58, 0x5f, 0x41, 0x56, 0x47, 0x2c, 0x33, 0x32, 0x2c,
908        0x52, // MIN_MAX_AVG,32,R
909        0x45, 0x43, 0x4f, 0x52, 0x44, 0x2c, 0x36, 0x34, 0x2c, 0x52, 0x45, 0x4c, 0x2c, 0x31, 0x32,
910        0x38, //0xEC,ORD,64,REL,128
911        0x2c, 0x52, 0x45, 0x4c, 0x5f, 0x50, 0x45, 0x52, 0x43, 0x45, 0x4e, 0x54, 0x2c, 0x32, 0x35,
912        0x36, // ,REL_PERCENT,256
913        0x2c, 0x43, 0x41, 0x4c, 0x49, 0x42, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e,
914        0x0d, //    ,CALIBRATION.
915        0x30, 0x0d, 0x38, 0x2c, 0x30, 0x2c, 0x49, 0x4e, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x2c,
916        0x31, // 0.8,0,INACTIVE,1
917        0x2c, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x2c, 0x32, 0x2c, 0x4e, 0x4f, 0x52, 0x4d,
918        0x41, // ,INVALID,2,NORMA
919        0x4c, 0x2c, 0x33, 0x2c, 0x42, 0x4c, 0x41, 0x4e, 0x4b, 0x2c, 0x34, 0x2c, 0x44, 0x49, 0x53,
920        0x43, // L,3,BLANK,4,DISC
921        0x48, 0x41, 0x52, 0x47, 0x45, 0x2c, 0x35, 0x2c, 0x4f, 0x4c, 0x2c, 0x36, 0x2c, 0x4f, 0x4c,
922        0x5f, // HARGE,5,OL,6,OL_
923        0x4d, 0x49, 0x4e, 0x55, 0x53, 0x2c, 0x37, 0x2c, 0x4f, 0x50, 0x45, 0x4e, 0x5f, 0x54, 0x43,
924        0x0d, // MINUS,7,OPEN_TC.
925        0x30, 0x0d, 0x39, 0x2c, 0x30, 0x2c, 0x4e, 0x4f, 0x4e, 0x45, 0x2c, 0x31, 0x2c, 0x4f, 0x50,
926        0x45, // 0.9,0,NONE,1,OPE
927        0x4e, 0x5f, 0x43, 0x49, 0x52, 0x43, 0x55, 0x49, 0x54, 0x2c, 0x32, 0x2c, 0x53, 0x48, 0x4f,
928        0x52, // N_CIRCUIT,2,SHOR
929        0x54, 0x5f, 0x43, 0x49, 0x52, 0x43, 0x55, 0x49, 0x54, 0x2c, 0x33, 0x2c, 0x47, 0x4c, 0x49,
930        0x54, // T_CIRCUIT,3,GLIT
931        0x43, 0x48, 0x5f, 0x43, 0x49, 0x52, 0x43, 0x55, 0x49, 0x54, 0x2c, 0x34, 0x2c, 0x47, 0x4f,
932        0x4f, // CH_CIRCUIT,4,GOO
933        0x44, 0x5f, 0x44, 0x49, 0x4f, 0x44, 0x45, 0x2c, 0x35, 0x2c, 0x4c, 0x4f, 0x5f, 0x4f, 0x48,
934        0x4d, // D_DIODE,5,LO_OHM
935        0x53, 0x2c, 0x36, 0x2c, 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x45, 0x44,
936        0x47, // S,6,NEGATIVE_EDG
937        0x45, 0x2c, 0x37, 0x2c, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x45, 0x44,
938        0x47, // E,7,POSITIVE_EDG
939        0x45, 0x2c, 0x38, 0x2c, 0x48, 0x49, 0x47, 0x48, 0x5f, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e,
940        0x54, // E,8,HIGH_CURRENT
941        0x0d, //                .
942        0x30, 0x0d, 0x32, 0x2c, 0x30, 0x2c, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x2c, 0x31, 0x2c, 0x49,
943        0x4e, // 0.2,0,INPUT,1,IN
944        0x54, 0x45, 0x52, 0x56, 0x41, 0x4c, 0x0d, //          TERVAL.
945        0x30, 0x0d, 0x32, 0x2c, 0x30, 0x2c, 0x55, 0x4e, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x2c,
946        0x31, // 0.2,0,UNSTABLE,1
947        0x2c, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x0d, //         ,STABLE.
948        0x30, 0x0d, 0x35, 0x2c, 0x30, 0x2c, 0x4e, 0x4f, 0x4e, 0x5f, 0x54, 0x2c, 0x31, 0x2c, 0x52,
949        0x41, // 0.5,0,NON_T,1,RA
950        0x4e, 0x47, 0x45, 0x5f, 0x55, 0x50, 0x2c, 0x32, 0x2c, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x5f,
951        0x44, // NGE_UP,2,RANGE_D
952        0x4f, 0x57, 0x4e, 0x2c, 0x33, 0x2c, 0x4f, 0x56, 0x45, 0x52, 0x4c, 0x4f, 0x41, 0x44, 0x2c,
953        0x34, // OWN,3,OVERLOAD,4
954        0x2c, 0x4f, 0x50, 0x45, 0x4e, 0x5f, 0x54, 0x43, 0x0d, //        ,OPEN_TC.
955    ];
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, // l1
988            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
989            0x00, 0x00, // l2
990            0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0xc2, 0xf5, 0x11, 0x40, 0xf6, 0x28,
991            0x5c, 0x8f, // l3
992            0x09, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0xbf, 0xf3,
993            0xd8, 0x41, // l4
994            0x00, 0x40, 0x9d, 0xeb, 0x02, 0x00, 0xc2, 0xf5, 0x11, 0x40, 0xf6, 0x28, 0x5c, 0x8f,
995            0x09, 0x00, // l5
996            0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0xbf, 0xf3, 0xd8, 0x41,
997            0x00, 0x40, // l6
998            0x9d, 0xeb, 0x0d, // l7
999        ];
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        // TODO: check readings
1036    }
1037}