1use 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#[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 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 pub fn get_response_expected(&mut self, fun: ParticulateMatterBrickletFunction) -> Result<bool, GetResponseExpectedError> {
325 self.device.get_response_expected(u8::from(fun))
326 }
327
328 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 pub fn set_response_expected_all(&mut self, response_expected: bool) { self.device.set_response_expected_all(response_expected) }
346
347 pub fn get_api_version(&self) -> [u8; 3] { self.device.api_version }
350
351 pub fn get_pm_concentration_callback_receiver(&self) -> ConvertingCallbackReceiver<PmConcentrationEvent> {
359 self.device.get_callback_receiver(u8::from(ParticulateMatterBrickletFunction::CallbackPmConcentration))
360 }
361
362 pub fn get_pm_count_callback_receiver(&self) -> ConvertingCallbackReceiver<PmCountEvent> {
367 self.device.get_callback_receiver(u8::from(ParticulateMatterBrickletFunction::CallbackPmCount))
368 }
369
370 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 pub fn reset(&self) -> ConvertingReceiver<()> {
634 let payload = vec![0; 0];
635
636 self.device.set(u8::from(ParticulateMatterBrickletFunction::Reset), payload)
637 }
638
639 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 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 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}