tinkerforge/bindings/
particulate_matter_bricklet.rs

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