tinkerforge_async/bindings/
particulate_matter_bricklet.rs

1/* ***********************************************************
2 * This file was automatically generated on 2024-02-16.      *
3 *                                                           *
4 * Rust Bindings Version 2.0.20                              *
5 *                                                           *
6 * If you have a bugfix for this file and want to commit it, *
7 * please fix the bug in the generator. You can find a link  *
8 * to the generators git repository on tinkerforge.com       *
9 *************************************************************/
10
11//! Measures Particulate Matter concentration (PM1.0, PM2.5 and PM10).
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/ParticulateMatter_Bricklet_Rust.html).
14#[allow(unused_imports)]
15use crate::{
16    base58::Uid, byte_converter::*, device::*, error::TinkerforgeError, ip_connection::async_io::AsyncIpConnection,
17    low_level_traits::LowLevelRead,
18};
19#[allow(unused_imports)]
20use futures_core::Stream;
21#[allow(unused_imports)]
22use tokio_stream::StreamExt;
23pub enum ParticulateMatterBrickletFunction {
24    GetPmConcentration,
25    GetPmCount,
26    SetEnable,
27    GetEnable,
28    GetSensorInfo,
29    SetPmConcentrationCallbackConfiguration,
30    GetPmConcentrationCallbackConfiguration,
31    SetPmCountCallbackConfiguration,
32    GetPmCountCallbackConfiguration,
33    GetSpitfpErrorCount,
34    SetBootloaderMode,
35    GetBootloaderMode,
36    SetWriteFirmwarePointer,
37    WriteFirmware,
38    SetStatusLedConfig,
39    GetStatusLedConfig,
40    GetChipTemperature,
41    Reset,
42    WriteUid,
43    ReadUid,
44    GetIdentity,
45    CallbackPmConcentration,
46    CallbackPmCount,
47}
48impl From<ParticulateMatterBrickletFunction> for u8 {
49    fn from(fun: ParticulateMatterBrickletFunction) -> Self {
50        match fun {
51            ParticulateMatterBrickletFunction::GetPmConcentration => 1,
52            ParticulateMatterBrickletFunction::GetPmCount => 2,
53            ParticulateMatterBrickletFunction::SetEnable => 3,
54            ParticulateMatterBrickletFunction::GetEnable => 4,
55            ParticulateMatterBrickletFunction::GetSensorInfo => 5,
56            ParticulateMatterBrickletFunction::SetPmConcentrationCallbackConfiguration => 6,
57            ParticulateMatterBrickletFunction::GetPmConcentrationCallbackConfiguration => 7,
58            ParticulateMatterBrickletFunction::SetPmCountCallbackConfiguration => 8,
59            ParticulateMatterBrickletFunction::GetPmCountCallbackConfiguration => 9,
60            ParticulateMatterBrickletFunction::GetSpitfpErrorCount => 234,
61            ParticulateMatterBrickletFunction::SetBootloaderMode => 235,
62            ParticulateMatterBrickletFunction::GetBootloaderMode => 236,
63            ParticulateMatterBrickletFunction::SetWriteFirmwarePointer => 237,
64            ParticulateMatterBrickletFunction::WriteFirmware => 238,
65            ParticulateMatterBrickletFunction::SetStatusLedConfig => 239,
66            ParticulateMatterBrickletFunction::GetStatusLedConfig => 240,
67            ParticulateMatterBrickletFunction::GetChipTemperature => 242,
68            ParticulateMatterBrickletFunction::Reset => 243,
69            ParticulateMatterBrickletFunction::WriteUid => 248,
70            ParticulateMatterBrickletFunction::ReadUid => 249,
71            ParticulateMatterBrickletFunction::GetIdentity => 255,
72            ParticulateMatterBrickletFunction::CallbackPmConcentration => 10,
73            ParticulateMatterBrickletFunction::CallbackPmCount => 11,
74        }
75    }
76}
77pub const PARTICULATE_MATTER_BRICKLET_BOOTLOADER_MODE_BOOTLOADER: u8 = 0;
78pub const PARTICULATE_MATTER_BRICKLET_BOOTLOADER_MODE_FIRMWARE: u8 = 1;
79pub const PARTICULATE_MATTER_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT: u8 = 2;
80pub const PARTICULATE_MATTER_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT: u8 = 3;
81pub const PARTICULATE_MATTER_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT: u8 = 4;
82pub const PARTICULATE_MATTER_BRICKLET_BOOTLOADER_STATUS_OK: u8 = 0;
83pub const PARTICULATE_MATTER_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE: u8 = 1;
84pub const PARTICULATE_MATTER_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE: u8 = 2;
85pub const PARTICULATE_MATTER_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT: u8 = 3;
86pub const PARTICULATE_MATTER_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT: u8 = 4;
87pub const PARTICULATE_MATTER_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH: u8 = 5;
88pub const PARTICULATE_MATTER_BRICKLET_STATUS_LED_CONFIG_OFF: u8 = 0;
89pub const PARTICULATE_MATTER_BRICKLET_STATUS_LED_CONFIG_ON: u8 = 1;
90pub const PARTICULATE_MATTER_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
91pub const PARTICULATE_MATTER_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS: u8 = 3;
92
93#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
94pub struct PmConcentration {
95    pub pm10: u16,
96    pub pm25: u16,
97    pub pm100: u16,
98}
99impl FromByteSlice for PmConcentration {
100    fn bytes_expected() -> usize {
101        6
102    }
103    fn from_le_byte_slice(bytes: &[u8]) -> PmConcentration {
104        PmConcentration {
105            pm10: <u16>::from_le_byte_slice(&bytes[0..2]),
106            pm25: <u16>::from_le_byte_slice(&bytes[2..4]),
107            pm100: <u16>::from_le_byte_slice(&bytes[4..6]),
108        }
109    }
110}
111
112#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
113pub struct PmCount {
114    pub greater03um: u16,
115    pub greater05um: u16,
116    pub greater10um: u16,
117    pub greater25um: u16,
118    pub greater50um: u16,
119    pub greater100um: u16,
120}
121impl FromByteSlice for PmCount {
122    fn bytes_expected() -> usize {
123        12
124    }
125    fn from_le_byte_slice(bytes: &[u8]) -> PmCount {
126        PmCount {
127            greater03um: <u16>::from_le_byte_slice(&bytes[0..2]),
128            greater05um: <u16>::from_le_byte_slice(&bytes[2..4]),
129            greater10um: <u16>::from_le_byte_slice(&bytes[4..6]),
130            greater25um: <u16>::from_le_byte_slice(&bytes[6..8]),
131            greater50um: <u16>::from_le_byte_slice(&bytes[8..10]),
132            greater100um: <u16>::from_le_byte_slice(&bytes[10..12]),
133        }
134    }
135}
136
137#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
138pub struct SensorInfo {
139    pub sensor_version: u8,
140    pub last_error_code: u8,
141    pub framing_error_count: u8,
142    pub checksum_error_count: u8,
143}
144impl FromByteSlice for SensorInfo {
145    fn bytes_expected() -> usize {
146        4
147    }
148    fn from_le_byte_slice(bytes: &[u8]) -> SensorInfo {
149        SensorInfo {
150            sensor_version: <u8>::from_le_byte_slice(&bytes[0..1]),
151            last_error_code: <u8>::from_le_byte_slice(&bytes[1..2]),
152            framing_error_count: <u8>::from_le_byte_slice(&bytes[2..3]),
153            checksum_error_count: <u8>::from_le_byte_slice(&bytes[3..4]),
154        }
155    }
156}
157
158#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
159pub struct PmConcentrationCallbackConfiguration {
160    pub period: u32,
161    pub value_has_to_change: bool,
162}
163impl FromByteSlice for PmConcentrationCallbackConfiguration {
164    fn bytes_expected() -> usize {
165        5
166    }
167    fn from_le_byte_slice(bytes: &[u8]) -> PmConcentrationCallbackConfiguration {
168        PmConcentrationCallbackConfiguration {
169            period: <u32>::from_le_byte_slice(&bytes[0..4]),
170            value_has_to_change: <bool>::from_le_byte_slice(&bytes[4..5]),
171        }
172    }
173}
174
175#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
176pub struct PmCountCallbackConfiguration {
177    pub period: u32,
178    pub value_has_to_change: bool,
179}
180impl FromByteSlice for PmCountCallbackConfiguration {
181    fn bytes_expected() -> usize {
182        5
183    }
184    fn from_le_byte_slice(bytes: &[u8]) -> PmCountCallbackConfiguration {
185        PmCountCallbackConfiguration {
186            period: <u32>::from_le_byte_slice(&bytes[0..4]),
187            value_has_to_change: <bool>::from_le_byte_slice(&bytes[4..5]),
188        }
189    }
190}
191
192#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
193pub struct PmConcentrationEvent {
194    pub pm10: u16,
195    pub pm25: u16,
196    pub pm100: u16,
197}
198impl FromByteSlice for PmConcentrationEvent {
199    fn bytes_expected() -> usize {
200        6
201    }
202    fn from_le_byte_slice(bytes: &[u8]) -> PmConcentrationEvent {
203        PmConcentrationEvent {
204            pm10: <u16>::from_le_byte_slice(&bytes[0..2]),
205            pm25: <u16>::from_le_byte_slice(&bytes[2..4]),
206            pm100: <u16>::from_le_byte_slice(&bytes[4..6]),
207        }
208    }
209}
210
211#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
212pub struct PmCountEvent {
213    pub greater03um: u16,
214    pub greater05um: u16,
215    pub greater10um: u16,
216    pub greater25um: u16,
217    pub greater50um: u16,
218    pub greater100um: u16,
219}
220impl FromByteSlice for PmCountEvent {
221    fn bytes_expected() -> usize {
222        12
223    }
224    fn from_le_byte_slice(bytes: &[u8]) -> PmCountEvent {
225        PmCountEvent {
226            greater03um: <u16>::from_le_byte_slice(&bytes[0..2]),
227            greater05um: <u16>::from_le_byte_slice(&bytes[2..4]),
228            greater10um: <u16>::from_le_byte_slice(&bytes[4..6]),
229            greater25um: <u16>::from_le_byte_slice(&bytes[6..8]),
230            greater50um: <u16>::from_le_byte_slice(&bytes[8..10]),
231            greater100um: <u16>::from_le_byte_slice(&bytes[10..12]),
232        }
233    }
234}
235
236#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
237pub struct SpitfpErrorCount {
238    pub error_count_ack_checksum: u32,
239    pub error_count_message_checksum: u32,
240    pub error_count_frame: u32,
241    pub error_count_overflow: u32,
242}
243impl FromByteSlice for SpitfpErrorCount {
244    fn bytes_expected() -> usize {
245        16
246    }
247    fn from_le_byte_slice(bytes: &[u8]) -> SpitfpErrorCount {
248        SpitfpErrorCount {
249            error_count_ack_checksum: <u32>::from_le_byte_slice(&bytes[0..4]),
250            error_count_message_checksum: <u32>::from_le_byte_slice(&bytes[4..8]),
251            error_count_frame: <u32>::from_le_byte_slice(&bytes[8..12]),
252            error_count_overflow: <u32>::from_le_byte_slice(&bytes[12..16]),
253        }
254    }
255}
256
257#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
258pub struct Identity {
259    pub uid: String,
260    pub connected_uid: String,
261    pub position: char,
262    pub hardware_version: [u8; 3],
263    pub firmware_version: [u8; 3],
264    pub device_identifier: u16,
265}
266impl FromByteSlice for Identity {
267    fn bytes_expected() -> usize {
268        25
269    }
270    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
271        Identity {
272            uid: <String>::from_le_byte_slice(&bytes[0..8]),
273            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
274            position: <char>::from_le_byte_slice(&bytes[16..17]),
275            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
276            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
277            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
278        }
279    }
280}
281
282/// Measures Particulate Matter concentration (PM1.0, PM2.5 and PM10)
283#[derive(Clone)]
284pub struct ParticulateMatterBricklet {
285    device: Device,
286}
287impl ParticulateMatterBricklet {
288    pub const DEVICE_IDENTIFIER: u16 = 2110;
289    pub const DEVICE_DISPLAY_NAME: &'static str = "Particulate Matter Bricklet";
290    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
291    pub fn new(uid: Uid, connection: AsyncIpConnection) -> ParticulateMatterBricklet {
292        let mut result = ParticulateMatterBricklet { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
293        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::GetPmConcentration) as usize] =
294            ResponseExpectedFlag::AlwaysTrue;
295        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::GetPmCount) as usize] =
296            ResponseExpectedFlag::AlwaysTrue;
297        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::SetEnable) as usize] = ResponseExpectedFlag::False;
298        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::GetEnable) as usize] = ResponseExpectedFlag::AlwaysTrue;
299        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::GetSensorInfo) as usize] =
300            ResponseExpectedFlag::AlwaysTrue;
301        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::SetPmConcentrationCallbackConfiguration) as usize] =
302            ResponseExpectedFlag::True;
303        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::GetPmConcentrationCallbackConfiguration) as usize] =
304            ResponseExpectedFlag::AlwaysTrue;
305        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::SetPmCountCallbackConfiguration) as usize] =
306            ResponseExpectedFlag::True;
307        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::GetPmCountCallbackConfiguration) as usize] =
308            ResponseExpectedFlag::AlwaysTrue;
309        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::GetSpitfpErrorCount) as usize] =
310            ResponseExpectedFlag::AlwaysTrue;
311        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::SetBootloaderMode) as usize] =
312            ResponseExpectedFlag::AlwaysTrue;
313        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::GetBootloaderMode) as usize] =
314            ResponseExpectedFlag::AlwaysTrue;
315        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::SetWriteFirmwarePointer) as usize] =
316            ResponseExpectedFlag::False;
317        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::WriteFirmware) as usize] =
318            ResponseExpectedFlag::AlwaysTrue;
319        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::SetStatusLedConfig) as usize] =
320            ResponseExpectedFlag::False;
321        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::GetStatusLedConfig) as usize] =
322            ResponseExpectedFlag::AlwaysTrue;
323        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::GetChipTemperature) as usize] =
324            ResponseExpectedFlag::AlwaysTrue;
325        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::Reset) as usize] = ResponseExpectedFlag::False;
326        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::WriteUid) as usize] = ResponseExpectedFlag::False;
327        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::ReadUid) as usize] = ResponseExpectedFlag::AlwaysTrue;
328        result.device.response_expected[u8::from(ParticulateMatterBrickletFunction::GetIdentity) as usize] =
329            ResponseExpectedFlag::AlwaysTrue;
330        result
331    }
332
333    /// Returns the response expected flag for the function specified by the function ID parameter.
334    /// It is true if the function is expected to send a response, false otherwise.
335    ///
336    /// For getter functions this is enabled by default and cannot be disabled, because those
337    /// functions will always send a response. For callback configuration functions it is enabled
338    /// by default too, but can be disabled by [`set_response_expected`](crate::particulate_matter_bricklet::ParticulateMatterBricklet::set_response_expected).
339    /// For setter functions it is disabled by default and can be enabled.
340    ///
341    /// Enabling the response expected flag for a setter function allows to detect timeouts
342    /// and other error conditions calls of this setter as well. The device will then send a response
343    /// for this purpose. If this flag is disabled for a setter function then no response is sent
344    /// and errors are silently ignored, because they cannot be detected.
345    ///
346    /// See [`set_response_expected`](crate::particulate_matter_bricklet::ParticulateMatterBricklet::set_response_expected) for the list of function ID constants available for this function.
347    pub fn get_response_expected(&mut self, fun: ParticulateMatterBrickletFunction) -> Result<bool, GetResponseExpectedError> {
348        self.device.get_response_expected(u8::from(fun))
349    }
350
351    /// Changes the response expected flag of the function specified by the function ID parameter.
352    /// This flag can only be changed for setter (default value: false) and callback configuration
353    /// functions (default value: true). For getter functions it is always enabled.
354    ///
355    /// Enabling the response expected flag for a setter function allows to detect timeouts and
356    /// other error conditions calls of this setter as well. The device will then send a response
357    /// for this purpose. If this flag is disabled for a setter function then no response is sent
358    /// and errors are silently ignored, because they cannot be detected.
359    pub fn set_response_expected(
360        &mut self,
361        fun: ParticulateMatterBrickletFunction,
362        response_expected: bool,
363    ) -> Result<(), SetResponseExpectedError> {
364        self.device.set_response_expected(u8::from(fun), response_expected)
365    }
366
367    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
368    pub fn set_response_expected_all(&mut self, response_expected: bool) {
369        self.device.set_response_expected_all(response_expected)
370    }
371
372    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
373    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
374    pub fn get_api_version(&self) -> [u8; 3] {
375        self.device.api_version
376    }
377
378    /// This receiver is triggered periodically according to the configuration set by
379    /// [`set_pm_concentration_callback_configuration`].
380    ///
381    /// The parameters are the same as [`get_pm_concentration`].
382    ///
383    /// [`get_pm_concentration`]: #method.get_pm_concentration
384    /// [`set_pm_concentration_callback_configuration`]: #method.set_pm_concentration_callback_configuration
385    pub async fn get_pm_concentration_callback_receiver(&mut self) -> impl Stream<Item = PmConcentrationEvent> {
386        self.device
387            .get_callback_receiver(u8::from(ParticulateMatterBrickletFunction::CallbackPmConcentration))
388            .await
389            .map(|p| PmConcentrationEvent::from_le_byte_slice(p.body()))
390    }
391
392    /// This receiver is triggered periodically according to the configuration set by
393    /// [`set_pm_count_callback_configuration`].
394    ///
395    /// The parameters are the same as [`get_pm_count`].
396    pub async fn get_pm_count_callback_receiver(&mut self) -> impl Stream<Item = PmCountEvent> {
397        self.device
398            .get_callback_receiver(u8::from(ParticulateMatterBrickletFunction::CallbackPmCount))
399            .await
400            .map(|p| PmCountEvent::from_le_byte_slice(p.body()))
401    }
402
403    /// Returns the particulate matter concentration, broken down as:
404    ///
405    /// * PM\ :sub:`1.0`\ ,
406    /// * PM\ :sub:`2.5`\  and
407    /// * PM\ :sub:`10.0`\ .
408    ///
409    /// If the sensor is disabled (see [`set_enable`]) then the last known good
410    /// values from the sensor are returned.
411    ///
412    /// If you want to get the values periodically, it is recommended to use the
413    /// [`get_pm_concentration_callback_receiver`] receiver. You can set the receiver configuration
414    /// with [`set_pm_concentration_callback_configuration`].
415    pub async fn get_pm_concentration(&mut self) -> Result<PmConcentration, TinkerforgeError> {
416        let payload = [0; 0];
417
418        #[allow(unused_variables)]
419        let result = self.device.get(u8::from(ParticulateMatterBrickletFunction::GetPmConcentration), &payload).await?;
420        Ok(PmConcentration::from_le_byte_slice(result.body()))
421    }
422
423    /// Returns the number of particulates in 100 ml of air, broken down by their
424    /// diameter:
425    ///
426    /// * greater 0.3µm,
427    /// * greater 0.5µm,
428    /// * greater 1.0µm,
429    /// * greater 2.5µm,
430    /// * greater 5.0µm and
431    /// * greater 10.0µm.
432    ///
433    /// If the sensor is disabled (see [`set_enable`]) then the last known good
434    /// value from the sensor is returned.
435    ///
436    /// If you want to get the values periodically, it is recommended to use the
437    /// [`get_pm_count_callback_receiver`] receiver. You can set the receiver configuration
438    /// with [`set_pm_count_callback_configuration`].
439    pub async fn get_pm_count(&mut self) -> Result<PmCount, TinkerforgeError> {
440        let payload = [0; 0];
441
442        #[allow(unused_variables)]
443        let result = self.device.get(u8::from(ParticulateMatterBrickletFunction::GetPmCount), &payload).await?;
444        Ok(PmCount::from_le_byte_slice(result.body()))
445    }
446
447    /// Enables/Disables the fan and the laser diode of the sensors.
448    ///
449    /// The sensor takes about 30 seconds after it is enabled to settle and produce stable
450    /// values.
451    ///
452    /// The laser diode has a lifetime of about 8000 hours. If you want to measure in
453    /// an interval with a long idle time (e.g. hourly) you should turn the
454    /// laser diode off between the measurements.
455    pub async fn set_enable(&mut self, enable: bool) -> Result<(), TinkerforgeError> {
456        let mut payload = [0; 1];
457        enable.write_to_slice(&mut payload[0..1]);
458
459        #[allow(unused_variables)]
460        let result = self.device.set(u8::from(ParticulateMatterBrickletFunction::SetEnable), &payload).await?;
461        Ok(())
462    }
463
464    /// Returns the state of the sensor as set by [`set_enable`].
465    pub async fn get_enable(&mut self) -> Result<bool, TinkerforgeError> {
466        let payload = [0; 0];
467
468        #[allow(unused_variables)]
469        let result = self.device.get(u8::from(ParticulateMatterBrickletFunction::GetEnable), &payload).await?;
470        Ok(bool::from_le_byte_slice(result.body()))
471    }
472
473    /// Returns information about the sensor:
474    ///
475    /// * the sensor version number,
476    /// * the last error code reported by the sensor (0 means no error) and
477    /// * the number of framing and checksum errors that occurred in the communication
478    ///   with the sensor.
479    pub async fn get_sensor_info(&mut self) -> Result<SensorInfo, TinkerforgeError> {
480        let payload = [0; 0];
481
482        #[allow(unused_variables)]
483        let result = self.device.get(u8::from(ParticulateMatterBrickletFunction::GetSensorInfo), &payload).await?;
484        Ok(SensorInfo::from_le_byte_slice(result.body()))
485    }
486
487    /// The period is the period with which the [`get_pm_concentration_callback_receiver`]
488    /// receiver is triggered periodically. A value of 0 turns the receiver off.
489    ///
490    /// If the `value has to change`-parameter is set to true, the receiver is only
491    /// triggered after the value has changed. If the value didn't change within the
492    /// period, the receiver is triggered immediately on change.
493    ///
494    /// If it is set to false, the receiver is continuously triggered with the period,
495    /// independent of the value.
496    pub async fn set_pm_concentration_callback_configuration(
497        &mut self,
498        period: u32,
499        value_has_to_change: bool,
500    ) -> Result<(), TinkerforgeError> {
501        let mut payload = [0; 5];
502        period.write_to_slice(&mut payload[0..4]);
503        value_has_to_change.write_to_slice(&mut payload[4..5]);
504
505        #[allow(unused_variables)]
506        let result =
507            self.device.set(u8::from(ParticulateMatterBrickletFunction::SetPmConcentrationCallbackConfiguration), &payload).await?;
508        Ok(())
509    }
510
511    /// Returns the receiver configuration as set by
512    /// [`set_pm_concentration_callback_configuration`].
513    pub async fn get_pm_concentration_callback_configuration(&mut self) -> Result<PmConcentrationCallbackConfiguration, TinkerforgeError> {
514        let payload = [0; 0];
515
516        #[allow(unused_variables)]
517        let result =
518            self.device.get(u8::from(ParticulateMatterBrickletFunction::GetPmConcentrationCallbackConfiguration), &payload).await?;
519        Ok(PmConcentrationCallbackConfiguration::from_le_byte_slice(result.body()))
520    }
521
522    /// The period is the period with which the [`get_pm_count_callback_receiver`] receiver
523    /// is triggered periodically. A value of 0 turns the receiver off.
524    ///
525    /// If the `value has to change`-parameter is set to true, the receiver is only
526    /// triggered after the value has changed. If the value didn't change within the
527    /// period, the receiver is triggered immediately on change.
528    ///
529    /// If it is set to false, the receiver is continuously triggered with the period,
530    /// independent of the value.
531    pub async fn set_pm_count_callback_configuration(&mut self, period: u32, value_has_to_change: bool) -> Result<(), TinkerforgeError> {
532        let mut payload = [0; 5];
533        period.write_to_slice(&mut payload[0..4]);
534        value_has_to_change.write_to_slice(&mut payload[4..5]);
535
536        #[allow(unused_variables)]
537        let result = self.device.set(u8::from(ParticulateMatterBrickletFunction::SetPmCountCallbackConfiguration), &payload).await?;
538        Ok(())
539    }
540
541    /// Returns the receiver configuration as set by
542    /// [`set_pm_count_callback_configuration`].
543    pub async fn get_pm_count_callback_configuration(&mut self) -> Result<PmCountCallbackConfiguration, TinkerforgeError> {
544        let payload = [0; 0];
545
546        #[allow(unused_variables)]
547        let result = self.device.get(u8::from(ParticulateMatterBrickletFunction::GetPmCountCallbackConfiguration), &payload).await?;
548        Ok(PmCountCallbackConfiguration::from_le_byte_slice(result.body()))
549    }
550
551    /// Returns the error count for the communication between Brick and Bricklet.
552    ///
553    /// The errors are divided into
554    ///
555    /// * ACK checksum errors,
556    /// * message checksum errors,
557    /// * framing errors and
558    /// * overflow errors.
559    ///
560    /// The errors counts are for errors that occur on the Bricklet side. All
561    /// Bricks have a similar function that returns the errors on the Brick side.
562    pub async fn get_spitfp_error_count(&mut self) -> Result<SpitfpErrorCount, TinkerforgeError> {
563        let payload = [0; 0];
564
565        #[allow(unused_variables)]
566        let result = self.device.get(u8::from(ParticulateMatterBrickletFunction::GetSpitfpErrorCount), &payload).await?;
567        Ok(SpitfpErrorCount::from_le_byte_slice(result.body()))
568    }
569
570    /// Sets the bootloader mode and returns the status after the requested
571    /// mode change was instigated.
572    ///
573    /// You can change from bootloader mode to firmware mode and vice versa. A change
574    /// from bootloader mode to firmware mode will only take place if the entry function,
575    /// device identifier and CRC are present and correct.
576    ///
577    /// This function is used by Brick Viewer during flashing. It should not be
578    /// necessary to call it in a normal user program.
579    ///
580    /// Associated constants:
581    /// * PARTICULATE_MATTER_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
582    ///	* PARTICULATE_MATTER_BRICKLET_BOOTLOADER_MODE_FIRMWARE
583    ///	* PARTICULATE_MATTER_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
584    ///	* PARTICULATE_MATTER_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
585    ///	* PARTICULATE_MATTER_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
586    ///	* PARTICULATE_MATTER_BRICKLET_BOOTLOADER_STATUS_OK
587    ///	* PARTICULATE_MATTER_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE
588    ///	* PARTICULATE_MATTER_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE
589    ///	* PARTICULATE_MATTER_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT
590    ///	* PARTICULATE_MATTER_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT
591    ///	* PARTICULATE_MATTER_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH
592    pub async fn set_bootloader_mode(&mut self, mode: u8) -> Result<u8, TinkerforgeError> {
593        let mut payload = [0; 1];
594        mode.write_to_slice(&mut payload[0..1]);
595
596        #[allow(unused_variables)]
597        let result = self.device.get(u8::from(ParticulateMatterBrickletFunction::SetBootloaderMode), &payload).await?;
598        Ok(u8::from_le_byte_slice(result.body()))
599    }
600
601    /// Returns the current bootloader mode, see [`set_bootloader_mode`].
602    ///
603    /// Associated constants:
604    /// * PARTICULATE_MATTER_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
605    ///	* PARTICULATE_MATTER_BRICKLET_BOOTLOADER_MODE_FIRMWARE
606    ///	* PARTICULATE_MATTER_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
607    ///	* PARTICULATE_MATTER_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
608    ///	* PARTICULATE_MATTER_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
609    pub async fn get_bootloader_mode(&mut self) -> Result<u8, TinkerforgeError> {
610        let payload = [0; 0];
611
612        #[allow(unused_variables)]
613        let result = self.device.get(u8::from(ParticulateMatterBrickletFunction::GetBootloaderMode), &payload).await?;
614        Ok(u8::from_le_byte_slice(result.body()))
615    }
616
617    /// Sets the firmware pointer for [`write_firmware`]. The pointer has
618    /// to be increased by chunks of size 64. The data is written to flash
619    /// every 4 chunks (which equals to one page of size 256).
620    ///
621    /// This function is used by Brick Viewer during flashing. It should not be
622    /// necessary to call it in a normal user program.
623    pub async fn set_write_firmware_pointer(&mut self, pointer: u32) -> Result<(), TinkerforgeError> {
624        let mut payload = [0; 4];
625        pointer.write_to_slice(&mut payload[0..4]);
626
627        #[allow(unused_variables)]
628        let result = self.device.set(u8::from(ParticulateMatterBrickletFunction::SetWriteFirmwarePointer), &payload).await?;
629        Ok(())
630    }
631
632    /// Writes 64 Bytes of firmware at the position as written by
633    /// [`set_write_firmware_pointer`] before. The firmware is written
634    /// to flash every 4 chunks.
635    ///
636    /// You can only write firmware in bootloader mode.
637    ///
638    /// This function is used by Brick Viewer during flashing. It should not be
639    /// necessary to call it in a normal user program.
640    pub async fn write_firmware(&mut self, data: &[u8; 64]) -> Result<u8, TinkerforgeError> {
641        let mut payload = [0; 64];
642        data.write_to_slice(&mut payload[0..64]);
643
644        #[allow(unused_variables)]
645        let result = self.device.get(u8::from(ParticulateMatterBrickletFunction::WriteFirmware), &payload).await?;
646        Ok(u8::from_le_byte_slice(result.body()))
647    }
648
649    /// Sets the status LED configuration. By default the LED shows
650    /// communication traffic between Brick and Bricklet, it flickers once
651    /// for every 10 received data packets.
652    ///
653    /// You can also turn the LED permanently on/off or show a heartbeat.
654    ///
655    /// If the Bricklet is in bootloader mode, the LED is will show heartbeat by default.
656    ///
657    /// Associated constants:
658    /// * PARTICULATE_MATTER_BRICKLET_STATUS_LED_CONFIG_OFF
659    ///	* PARTICULATE_MATTER_BRICKLET_STATUS_LED_CONFIG_ON
660    ///	* PARTICULATE_MATTER_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
661    ///	* PARTICULATE_MATTER_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
662    pub async fn set_status_led_config(&mut self, config: u8) -> Result<(), TinkerforgeError> {
663        let mut payload = [0; 1];
664        config.write_to_slice(&mut payload[0..1]);
665
666        #[allow(unused_variables)]
667        let result = self.device.set(u8::from(ParticulateMatterBrickletFunction::SetStatusLedConfig), &payload).await?;
668        Ok(())
669    }
670
671    /// Returns the configuration as set by [`set_status_led_config`]
672    ///
673    /// Associated constants:
674    /// * PARTICULATE_MATTER_BRICKLET_STATUS_LED_CONFIG_OFF
675    ///	* PARTICULATE_MATTER_BRICKLET_STATUS_LED_CONFIG_ON
676    ///	* PARTICULATE_MATTER_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
677    ///	* PARTICULATE_MATTER_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
678    pub async fn get_status_led_config(&mut self) -> Result<u8, TinkerforgeError> {
679        let payload = [0; 0];
680
681        #[allow(unused_variables)]
682        let result = self.device.get(u8::from(ParticulateMatterBrickletFunction::GetStatusLedConfig), &payload).await?;
683        Ok(u8::from_le_byte_slice(result.body()))
684    }
685
686    /// Returns the temperature as measured inside the microcontroller. The
687    /// value returned is not the ambient temperature!
688    ///
689    /// The temperature is only proportional to the real temperature and it has bad
690    /// accuracy. Practically it is only useful as an indicator for
691    /// temperature changes.
692    pub async fn get_chip_temperature(&mut self) -> Result<i16, TinkerforgeError> {
693        let payload = [0; 0];
694
695        #[allow(unused_variables)]
696        let result = self.device.get(u8::from(ParticulateMatterBrickletFunction::GetChipTemperature), &payload).await?;
697        Ok(i16::from_le_byte_slice(result.body()))
698    }
699
700    /// Calling this function will reset the Bricklet. All configurations
701    /// will be lost.
702    ///
703    /// After a reset you have to create new device objects,
704    /// calling functions on the existing ones will result in
705    /// undefined behavior!
706    pub async fn reset(&mut self) -> Result<(), TinkerforgeError> {
707        let payload = [0; 0];
708
709        #[allow(unused_variables)]
710        let result = self.device.set(u8::from(ParticulateMatterBrickletFunction::Reset), &payload).await?;
711        Ok(())
712    }
713
714    /// Writes a new UID into flash. If you want to set a new UID
715    /// you have to decode the Base58 encoded UID string into an
716    /// integer first.
717    ///
718    /// We recommend that you use Brick Viewer to change the UID.
719    pub async fn write_uid(&mut self, uid: u32) -> Result<(), TinkerforgeError> {
720        let mut payload = [0; 4];
721        uid.write_to_slice(&mut payload[0..4]);
722
723        #[allow(unused_variables)]
724        let result = self.device.set(u8::from(ParticulateMatterBrickletFunction::WriteUid), &payload).await?;
725        Ok(())
726    }
727
728    /// Returns the current UID as an integer. Encode as
729    /// Base58 to get the usual string version.
730    pub async fn read_uid(&mut self) -> Result<u32, TinkerforgeError> {
731        let payload = [0; 0];
732
733        #[allow(unused_variables)]
734        let result = self.device.get(u8::from(ParticulateMatterBrickletFunction::ReadUid), &payload).await?;
735        Ok(u32::from_le_byte_slice(result.body()))
736    }
737
738    /// Returns the UID, the UID where the Bricklet is connected to,
739    /// the position, the hardware and firmware version as well as the
740    /// device identifier.
741    ///
742    /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
743    /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
744    /// position 'z'.
745    ///
746    /// The device identifier numbers can be found [here](device_identifier).
747    /// |device_identifier_constant|
748    pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
749        let payload = [0; 0];
750
751        #[allow(unused_variables)]
752        let result = self.device.get(u8::from(ParticulateMatterBrickletFunction::GetIdentity), &payload).await?;
753        Ok(Identity::from_le_byte_slice(result.body()))
754    }
755}