tinkerforge/bindings/
thermal_imaging_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//! 80x60 pixel thermal imaging camera.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/ThermalImaging_Bricklet_Rust.html).
14use crate::{
15    byte_converter::*,
16    converting_callback_receiver::ConvertingCallbackReceiver,
17    converting_high_level_callback_receiver::ConvertingHighLevelCallbackReceiver,
18    converting_receiver::{BrickletRecvTimeoutError, ConvertingReceiver},
19    device::*,
20    ip_connection::GetRequestSender,
21    low_level_traits::*,
22};
23pub enum ThermalImagingBrickletFunction {
24    GetHighContrastImageLowLevel,
25    GetTemperatureImageLowLevel,
26    GetStatistics,
27    SetResolution,
28    GetResolution,
29    SetSpotmeterConfig,
30    GetSpotmeterConfig,
31    SetHighContrastConfig,
32    GetHighContrastConfig,
33    SetImageTransferConfig,
34    GetImageTransferConfig,
35    SetFluxLinearParameters,
36    GetFluxLinearParameters,
37    SetFfcShutterMode,
38    GetFfcShutterMode,
39    RunFfcNormalization,
40    GetSpitfpErrorCount,
41    SetBootloaderMode,
42    GetBootloaderMode,
43    SetWriteFirmwarePointer,
44    WriteFirmware,
45    SetStatusLedConfig,
46    GetStatusLedConfig,
47    GetChipTemperature,
48    Reset,
49    WriteUid,
50    ReadUid,
51    GetIdentity,
52    CallbackHighContrastImageLowLevel,
53    CallbackTemperatureImageLowLevel,
54}
55impl From<ThermalImagingBrickletFunction> for u8 {
56    fn from(fun: ThermalImagingBrickletFunction) -> Self {
57        match fun {
58            ThermalImagingBrickletFunction::GetHighContrastImageLowLevel => 1,
59            ThermalImagingBrickletFunction::GetTemperatureImageLowLevel => 2,
60            ThermalImagingBrickletFunction::GetStatistics => 3,
61            ThermalImagingBrickletFunction::SetResolution => 4,
62            ThermalImagingBrickletFunction::GetResolution => 5,
63            ThermalImagingBrickletFunction::SetSpotmeterConfig => 6,
64            ThermalImagingBrickletFunction::GetSpotmeterConfig => 7,
65            ThermalImagingBrickletFunction::SetHighContrastConfig => 8,
66            ThermalImagingBrickletFunction::GetHighContrastConfig => 9,
67            ThermalImagingBrickletFunction::SetImageTransferConfig => 10,
68            ThermalImagingBrickletFunction::GetImageTransferConfig => 11,
69            ThermalImagingBrickletFunction::SetFluxLinearParameters => 14,
70            ThermalImagingBrickletFunction::GetFluxLinearParameters => 15,
71            ThermalImagingBrickletFunction::SetFfcShutterMode => 16,
72            ThermalImagingBrickletFunction::GetFfcShutterMode => 17,
73            ThermalImagingBrickletFunction::RunFfcNormalization => 18,
74            ThermalImagingBrickletFunction::GetSpitfpErrorCount => 234,
75            ThermalImagingBrickletFunction::SetBootloaderMode => 235,
76            ThermalImagingBrickletFunction::GetBootloaderMode => 236,
77            ThermalImagingBrickletFunction::SetWriteFirmwarePointer => 237,
78            ThermalImagingBrickletFunction::WriteFirmware => 238,
79            ThermalImagingBrickletFunction::SetStatusLedConfig => 239,
80            ThermalImagingBrickletFunction::GetStatusLedConfig => 240,
81            ThermalImagingBrickletFunction::GetChipTemperature => 242,
82            ThermalImagingBrickletFunction::Reset => 243,
83            ThermalImagingBrickletFunction::WriteUid => 248,
84            ThermalImagingBrickletFunction::ReadUid => 249,
85            ThermalImagingBrickletFunction::GetIdentity => 255,
86            ThermalImagingBrickletFunction::CallbackHighContrastImageLowLevel => 12,
87            ThermalImagingBrickletFunction::CallbackTemperatureImageLowLevel => 13,
88        }
89    }
90}
91pub const THERMAL_IMAGING_BRICKLET_RESOLUTION_0_TO_6553_KELVIN: u8 = 0;
92pub const THERMAL_IMAGING_BRICKLET_RESOLUTION_0_TO_655_KELVIN: u8 = 1;
93pub const THERMAL_IMAGING_BRICKLET_FFC_STATUS_NEVER_COMMANDED: u8 = 0;
94pub const THERMAL_IMAGING_BRICKLET_FFC_STATUS_IMMINENT: u8 = 1;
95pub const THERMAL_IMAGING_BRICKLET_FFC_STATUS_IN_PROGRESS: u8 = 2;
96pub const THERMAL_IMAGING_BRICKLET_FFC_STATUS_COMPLETE: u8 = 3;
97pub const THERMAL_IMAGING_BRICKLET_IMAGE_TRANSFER_MANUAL_HIGH_CONTRAST_IMAGE: u8 = 0;
98pub const THERMAL_IMAGING_BRICKLET_IMAGE_TRANSFER_MANUAL_TEMPERATURE_IMAGE: u8 = 1;
99pub const THERMAL_IMAGING_BRICKLET_IMAGE_TRANSFER_CALLBACK_HIGH_CONTRAST_IMAGE: u8 = 2;
100pub const THERMAL_IMAGING_BRICKLET_IMAGE_TRANSFER_CALLBACK_TEMPERATURE_IMAGE: u8 = 3;
101pub const THERMAL_IMAGING_BRICKLET_SHUTTER_MODE_MANUAL: u8 = 0;
102pub const THERMAL_IMAGING_BRICKLET_SHUTTER_MODE_AUTO: u8 = 1;
103pub const THERMAL_IMAGING_BRICKLET_SHUTTER_MODE_EXTERNAL: u8 = 2;
104pub const THERMAL_IMAGING_BRICKLET_SHUTTER_LOCKOUT_INACTIVE: u8 = 0;
105pub const THERMAL_IMAGING_BRICKLET_SHUTTER_LOCKOUT_HIGH: u8 = 1;
106pub const THERMAL_IMAGING_BRICKLET_SHUTTER_LOCKOUT_LOW: u8 = 2;
107pub const THERMAL_IMAGING_BRICKLET_BOOTLOADER_MODE_BOOTLOADER: u8 = 0;
108pub const THERMAL_IMAGING_BRICKLET_BOOTLOADER_MODE_FIRMWARE: u8 = 1;
109pub const THERMAL_IMAGING_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT: u8 = 2;
110pub const THERMAL_IMAGING_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT: u8 = 3;
111pub const THERMAL_IMAGING_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT: u8 = 4;
112pub const THERMAL_IMAGING_BRICKLET_BOOTLOADER_STATUS_OK: u8 = 0;
113pub const THERMAL_IMAGING_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE: u8 = 1;
114pub const THERMAL_IMAGING_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE: u8 = 2;
115pub const THERMAL_IMAGING_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT: u8 = 3;
116pub const THERMAL_IMAGING_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT: u8 = 4;
117pub const THERMAL_IMAGING_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH: u8 = 5;
118pub const THERMAL_IMAGING_BRICKLET_STATUS_LED_CONFIG_OFF: u8 = 0;
119pub const THERMAL_IMAGING_BRICKLET_STATUS_LED_CONFIG_ON: u8 = 1;
120pub const THERMAL_IMAGING_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
121pub const THERMAL_IMAGING_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS: u8 = 3;
122
123#[derive(Clone, Copy)]
124pub struct HighContrastImageLowLevel {
125    pub image_chunk_offset: u16,
126    pub image_chunk_data: [u8; 62],
127}
128impl FromByteSlice for HighContrastImageLowLevel {
129    fn bytes_expected() -> usize { 64 }
130    fn from_le_byte_slice(bytes: &[u8]) -> HighContrastImageLowLevel {
131        HighContrastImageLowLevel {
132            image_chunk_offset: <u16>::from_le_byte_slice(&bytes[0..2]),
133            image_chunk_data: <[u8; 62]>::from_le_byte_slice(&bytes[2..64]),
134        }
135    }
136}
137impl LowLevelRead<u8, HighContrastImageResult> for HighContrastImageLowLevel {
138    fn ll_message_length(&self) -> usize { 4800 }
139
140    fn ll_message_chunk_offset(&self) -> usize { self.image_chunk_offset as usize }
141
142    fn ll_message_chunk_data(&self) -> &[u8] { &self.image_chunk_data }
143
144    fn get_result(&self) -> HighContrastImageResult { HighContrastImageResult {} }
145}
146
147#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
148pub struct TemperatureImageLowLevel {
149    pub image_chunk_offset: u16,
150    pub image_chunk_data: [u16; 31],
151}
152impl FromByteSlice for TemperatureImageLowLevel {
153    fn bytes_expected() -> usize { 64 }
154    fn from_le_byte_slice(bytes: &[u8]) -> TemperatureImageLowLevel {
155        TemperatureImageLowLevel {
156            image_chunk_offset: <u16>::from_le_byte_slice(&bytes[0..2]),
157            image_chunk_data: <[u16; 31]>::from_le_byte_slice(&bytes[2..64]),
158        }
159    }
160}
161impl LowLevelRead<u16, TemperatureImageResult> for TemperatureImageLowLevel {
162    fn ll_message_length(&self) -> usize { 4800 }
163
164    fn ll_message_chunk_offset(&self) -> usize { self.image_chunk_offset as usize }
165
166    fn ll_message_chunk_data(&self) -> &[u16] { &self.image_chunk_data }
167
168    fn get_result(&self) -> TemperatureImageResult { TemperatureImageResult {} }
169}
170
171#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
172pub struct Statistics {
173    pub spotmeter_statistics: [u16; 4],
174    pub temperatures: [u16; 4],
175    pub resolution: u8,
176    pub ffc_status: u8,
177    pub temperature_warning: [bool; 2],
178}
179impl FromByteSlice for Statistics {
180    fn bytes_expected() -> usize { 19 }
181    fn from_le_byte_slice(bytes: &[u8]) -> Statistics {
182        Statistics {
183            spotmeter_statistics: <[u16; 4]>::from_le_byte_slice(&bytes[0..8]),
184            temperatures: <[u16; 4]>::from_le_byte_slice(&bytes[8..16]),
185            resolution: <u8>::from_le_byte_slice(&bytes[16..17]),
186            ffc_status: <u8>::from_le_byte_slice(&bytes[17..18]),
187            temperature_warning: <[bool; 2]>::from_le_byte_slice(&bytes[18..19]),
188        }
189    }
190}
191
192#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
193pub struct HighContrastConfig {
194    pub region_of_interest: [u8; 4],
195    pub dampening_factor: u16,
196    pub clip_limit: [u16; 2],
197    pub empty_counts: u16,
198}
199impl FromByteSlice for HighContrastConfig {
200    fn bytes_expected() -> usize { 12 }
201    fn from_le_byte_slice(bytes: &[u8]) -> HighContrastConfig {
202        HighContrastConfig {
203            region_of_interest: <[u8; 4]>::from_le_byte_slice(&bytes[0..4]),
204            dampening_factor: <u16>::from_le_byte_slice(&bytes[4..6]),
205            clip_limit: <[u16; 2]>::from_le_byte_slice(&bytes[6..10]),
206            empty_counts: <u16>::from_le_byte_slice(&bytes[10..12]),
207        }
208    }
209}
210
211#[derive(Clone, Copy)]
212pub struct HighContrastImageLowLevelEvent {
213    pub image_chunk_offset: u16,
214    pub image_chunk_data: [u8; 62],
215}
216impl FromByteSlice for HighContrastImageLowLevelEvent {
217    fn bytes_expected() -> usize { 64 }
218    fn from_le_byte_slice(bytes: &[u8]) -> HighContrastImageLowLevelEvent {
219        HighContrastImageLowLevelEvent {
220            image_chunk_offset: <u16>::from_le_byte_slice(&bytes[0..2]),
221            image_chunk_data: <[u8; 62]>::from_le_byte_slice(&bytes[2..64]),
222        }
223    }
224}
225impl LowLevelRead<u8, HighContrastImageResult> for HighContrastImageLowLevelEvent {
226    fn ll_message_length(&self) -> usize { 4800 }
227
228    fn ll_message_chunk_offset(&self) -> usize { self.image_chunk_offset as usize }
229
230    fn ll_message_chunk_data(&self) -> &[u8] { &self.image_chunk_data }
231
232    fn get_result(&self) -> HighContrastImageResult { HighContrastImageResult {} }
233}
234
235#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
236pub struct TemperatureImageLowLevelEvent {
237    pub image_chunk_offset: u16,
238    pub image_chunk_data: [u16; 31],
239}
240impl FromByteSlice for TemperatureImageLowLevelEvent {
241    fn bytes_expected() -> usize { 64 }
242    fn from_le_byte_slice(bytes: &[u8]) -> TemperatureImageLowLevelEvent {
243        TemperatureImageLowLevelEvent {
244            image_chunk_offset: <u16>::from_le_byte_slice(&bytes[0..2]),
245            image_chunk_data: <[u16; 31]>::from_le_byte_slice(&bytes[2..64]),
246        }
247    }
248}
249impl LowLevelRead<u16, TemperatureImageResult> for TemperatureImageLowLevelEvent {
250    fn ll_message_length(&self) -> usize { 4800 }
251
252    fn ll_message_chunk_offset(&self) -> usize { self.image_chunk_offset as usize }
253
254    fn ll_message_chunk_data(&self) -> &[u16] { &self.image_chunk_data }
255
256    fn get_result(&self) -> TemperatureImageResult { TemperatureImageResult {} }
257}
258
259#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
260pub struct FluxLinearParameters {
261    pub scene_emissivity: u16,
262    pub temperature_background: u16,
263    pub tau_window: u16,
264    pub temperatur_window: u16,
265    pub tau_atmosphere: u16,
266    pub temperature_atmosphere: u16,
267    pub reflection_window: u16,
268    pub temperature_reflection: u16,
269}
270impl FromByteSlice for FluxLinearParameters {
271    fn bytes_expected() -> usize { 16 }
272    fn from_le_byte_slice(bytes: &[u8]) -> FluxLinearParameters {
273        FluxLinearParameters {
274            scene_emissivity: <u16>::from_le_byte_slice(&bytes[0..2]),
275            temperature_background: <u16>::from_le_byte_slice(&bytes[2..4]),
276            tau_window: <u16>::from_le_byte_slice(&bytes[4..6]),
277            temperatur_window: <u16>::from_le_byte_slice(&bytes[6..8]),
278            tau_atmosphere: <u16>::from_le_byte_slice(&bytes[8..10]),
279            temperature_atmosphere: <u16>::from_le_byte_slice(&bytes[10..12]),
280            reflection_window: <u16>::from_le_byte_slice(&bytes[12..14]),
281            temperature_reflection: <u16>::from_le_byte_slice(&bytes[14..16]),
282        }
283    }
284}
285
286#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
287pub struct FfcShutterMode {
288    pub shutter_mode: u8,
289    pub temp_lockout_state: u8,
290    pub video_freeze_during_ffc: bool,
291    pub ffc_desired: bool,
292    pub elapsed_time_since_last_ffc: u32,
293    pub desired_ffc_period: u32,
294    pub explicit_cmd_to_open: bool,
295    pub desired_ffc_temp_delta: u16,
296    pub imminent_delay: u16,
297}
298impl FromByteSlice for FfcShutterMode {
299    fn bytes_expected() -> usize { 17 }
300    fn from_le_byte_slice(bytes: &[u8]) -> FfcShutterMode {
301        FfcShutterMode {
302            shutter_mode: <u8>::from_le_byte_slice(&bytes[0..1]),
303            temp_lockout_state: <u8>::from_le_byte_slice(&bytes[1..2]),
304            video_freeze_during_ffc: <bool>::from_le_byte_slice(&bytes[2..3]),
305            ffc_desired: <bool>::from_le_byte_slice(&bytes[3..4]),
306            elapsed_time_since_last_ffc: <u32>::from_le_byte_slice(&bytes[4..8]),
307            desired_ffc_period: <u32>::from_le_byte_slice(&bytes[8..12]),
308            explicit_cmd_to_open: <bool>::from_le_byte_slice(&bytes[12..13]),
309            desired_ffc_temp_delta: <u16>::from_le_byte_slice(&bytes[13..15]),
310            imminent_delay: <u16>::from_le_byte_slice(&bytes[15..17]),
311        }
312    }
313}
314
315#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
316pub struct SpitfpErrorCount {
317    pub error_count_ack_checksum: u32,
318    pub error_count_message_checksum: u32,
319    pub error_count_frame: u32,
320    pub error_count_overflow: u32,
321}
322impl FromByteSlice for SpitfpErrorCount {
323    fn bytes_expected() -> usize { 16 }
324    fn from_le_byte_slice(bytes: &[u8]) -> SpitfpErrorCount {
325        SpitfpErrorCount {
326            error_count_ack_checksum: <u32>::from_le_byte_slice(&bytes[0..4]),
327            error_count_message_checksum: <u32>::from_le_byte_slice(&bytes[4..8]),
328            error_count_frame: <u32>::from_le_byte_slice(&bytes[8..12]),
329            error_count_overflow: <u32>::from_le_byte_slice(&bytes[12..16]),
330        }
331    }
332}
333
334#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
335pub struct Identity {
336    pub uid: String,
337    pub connected_uid: String,
338    pub position: char,
339    pub hardware_version: [u8; 3],
340    pub firmware_version: [u8; 3],
341    pub device_identifier: u16,
342}
343impl FromByteSlice for Identity {
344    fn bytes_expected() -> usize { 25 }
345    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
346        Identity {
347            uid: <String>::from_le_byte_slice(&bytes[0..8]),
348            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
349            position: <char>::from_le_byte_slice(&bytes[16..17]),
350            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
351            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
352            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
353        }
354    }
355}
356
357#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
358pub struct HighContrastImageResult {}
359
360#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
361pub struct TemperatureImageResult {}
362
363/// 80x60 pixel thermal imaging camera
364#[derive(Clone)]
365pub struct ThermalImagingBricklet {
366    device: Device,
367}
368impl ThermalImagingBricklet {
369    pub const DEVICE_IDENTIFIER: u16 = 278;
370    pub const DEVICE_DISPLAY_NAME: &'static str = "Thermal Imaging Bricklet";
371    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
372    pub fn new<T: GetRequestSender>(uid: &str, req_sender: T) -> ThermalImagingBricklet {
373        let mut result = ThermalImagingBricklet { device: Device::new([2, 0, 2], uid, req_sender, 4) };
374        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::GetHighContrastImageLowLevel) as usize] =
375            ResponseExpectedFlag::AlwaysTrue;
376        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::GetTemperatureImageLowLevel) as usize] =
377            ResponseExpectedFlag::AlwaysTrue;
378        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::GetStatistics) as usize] =
379            ResponseExpectedFlag::AlwaysTrue;
380        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::SetResolution) as usize] = ResponseExpectedFlag::False;
381        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::GetResolution) as usize] =
382            ResponseExpectedFlag::AlwaysTrue;
383        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::SetSpotmeterConfig) as usize] =
384            ResponseExpectedFlag::False;
385        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::GetSpotmeterConfig) as usize] =
386            ResponseExpectedFlag::AlwaysTrue;
387        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::SetHighContrastConfig) as usize] =
388            ResponseExpectedFlag::False;
389        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::GetHighContrastConfig) as usize] =
390            ResponseExpectedFlag::AlwaysTrue;
391        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::SetImageTransferConfig) as usize] =
392            ResponseExpectedFlag::True;
393        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::GetImageTransferConfig) as usize] =
394            ResponseExpectedFlag::AlwaysTrue;
395        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::SetFluxLinearParameters) as usize] =
396            ResponseExpectedFlag::False;
397        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::GetFluxLinearParameters) as usize] =
398            ResponseExpectedFlag::AlwaysTrue;
399        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::SetFfcShutterMode) as usize] = ResponseExpectedFlag::False;
400        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::GetFfcShutterMode) as usize] =
401            ResponseExpectedFlag::AlwaysTrue;
402        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::RunFfcNormalization) as usize] =
403            ResponseExpectedFlag::False;
404        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::GetSpitfpErrorCount) as usize] =
405            ResponseExpectedFlag::AlwaysTrue;
406        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::SetBootloaderMode) as usize] =
407            ResponseExpectedFlag::AlwaysTrue;
408        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::GetBootloaderMode) as usize] =
409            ResponseExpectedFlag::AlwaysTrue;
410        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::SetWriteFirmwarePointer) as usize] =
411            ResponseExpectedFlag::False;
412        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::WriteFirmware) as usize] =
413            ResponseExpectedFlag::AlwaysTrue;
414        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::SetStatusLedConfig) as usize] =
415            ResponseExpectedFlag::False;
416        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::GetStatusLedConfig) as usize] =
417            ResponseExpectedFlag::AlwaysTrue;
418        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::GetChipTemperature) as usize] =
419            ResponseExpectedFlag::AlwaysTrue;
420        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::Reset) as usize] = ResponseExpectedFlag::False;
421        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::WriteUid) as usize] = ResponseExpectedFlag::False;
422        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::ReadUid) as usize] = ResponseExpectedFlag::AlwaysTrue;
423        result.device.response_expected[u8::from(ThermalImagingBrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
424        result
425    }
426
427    /// Returns the response expected flag for the function specified by the function ID parameter.
428    /// It is true if the function is expected to send a response, false otherwise.
429    ///
430    /// For getter functions this is enabled by default and cannot be disabled, because those
431    /// functions will always send a response. For callback configuration functions it is enabled
432    /// by default too, but can be disabled by [`set_response_expected`](crate::thermal_imaging_bricklet::ThermalImagingBricklet::set_response_expected).
433    /// For setter functions it is disabled by default and can be enabled.
434    ///
435    /// Enabling the response expected flag for a setter function allows to detect timeouts
436    /// and other error conditions calls of this setter as well. The device will then send a response
437    /// for this purpose. If this flag is disabled for a setter function then no response is sent
438    /// and errors are silently ignored, because they cannot be detected.
439    ///
440    /// See [`set_response_expected`](crate::thermal_imaging_bricklet::ThermalImagingBricklet::set_response_expected) for the list of function ID constants available for this function.
441    pub fn get_response_expected(&mut self, fun: ThermalImagingBrickletFunction) -> Result<bool, GetResponseExpectedError> {
442        self.device.get_response_expected(u8::from(fun))
443    }
444
445    /// Changes the response expected flag of the function specified by the function ID parameter.
446    /// This flag can only be changed for setter (default value: false) and callback configuration
447    /// functions (default value: true). For getter functions it is always enabled.
448    ///
449    /// Enabling the response expected flag for a setter function allows to detect timeouts and
450    /// other error conditions calls of this setter as well. The device will then send a response
451    /// for this purpose. If this flag is disabled for a setter function then no response is sent
452    /// and errors are silently ignored, because they cannot be detected.
453    pub fn set_response_expected(
454        &mut self,
455        fun: ThermalImagingBrickletFunction,
456        response_expected: bool,
457    ) -> Result<(), SetResponseExpectedError> {
458        self.device.set_response_expected(u8::from(fun), response_expected)
459    }
460
461    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
462    pub fn set_response_expected_all(&mut self, response_expected: bool) { self.device.set_response_expected_all(response_expected) }
463
464    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
465    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
466    pub fn get_api_version(&self) -> [u8; 3] { self.device.api_version }
467
468    /// See [`get_high_contrast_image_callback_receiver`](crate::thermal_imaging::ThermalImaging::get_high_contrast_image_callback_receiver)
469    pub fn get_high_contrast_image_low_level_callback_receiver(&self) -> ConvertingCallbackReceiver<HighContrastImageLowLevelEvent> {
470        self.device.get_callback_receiver(u8::from(ThermalImagingBrickletFunction::CallbackHighContrastImageLowLevel))
471    }
472
473    /// This receiver is triggered with every new high contrast image if the transfer image
474    /// config is configured for high contrast receiver (see [`set_image_transfer_config`]).
475    ///
476    /// The data is organized as a 8-bit value 80x60 pixel matrix linearized in
477    /// a one-dimensional array. The data is arranged line by line from top left to
478    /// bottom right.
479    ///
480    /// Each 8-bit value represents one gray-scale image pixel that can directly be
481    /// shown to a user on a display.
482    ///
483    /// [`set_image_transfer_config`]: #method.set_image_transfer_config
484    pub fn get_high_contrast_image_callback_receiver(
485        &self,
486    ) -> ConvertingHighLevelCallbackReceiver<u8, HighContrastImageResult, HighContrastImageLowLevelEvent> {
487        ConvertingHighLevelCallbackReceiver::new(
488            self.device.get_callback_receiver(u8::from(ThermalImagingBrickletFunction::CallbackHighContrastImageLowLevel)),
489        )
490    }
491
492    /// See [`get_temperature_image_callback_receiver`](crate::thermal_imaging::ThermalImaging::get_temperature_image_callback_receiver)
493    pub fn get_temperature_image_low_level_callback_receiver(&self) -> ConvertingCallbackReceiver<TemperatureImageLowLevelEvent> {
494        self.device.get_callback_receiver(u8::from(ThermalImagingBrickletFunction::CallbackTemperatureImageLowLevel))
495    }
496
497    /// This receiver is triggered with every new temperature image if the transfer image
498    /// config is configured for temperature receiver (see [`set_image_transfer_config`]).
499    ///
500    /// The data is organized as a 16-bit value 80x60 pixel matrix linearized in
501    /// a one-dimensional array. The data is arranged line by line from top left to
502    /// bottom right.
503    ///
504    /// Each 16-bit value represents one temperature measurement in either
505    /// Kelvin/10 or Kelvin/100 (depending on the resolution set with [`set_resolution`]).
506    pub fn get_temperature_image_callback_receiver(
507        &self,
508    ) -> ConvertingHighLevelCallbackReceiver<u16, TemperatureImageResult, TemperatureImageLowLevelEvent> {
509        ConvertingHighLevelCallbackReceiver::new(
510            self.device.get_callback_receiver(u8::from(ThermalImagingBrickletFunction::CallbackTemperatureImageLowLevel)),
511        )
512    }
513
514    /// Returns the current high contrast image. See [here](https://www.tinkerforge.com/en/doc/Hardware/Bricklets/Thermal_Imaging.html#high-contrast-image-vs-temperature-image)__
515    /// for the difference between
516    /// High Contrast and Temperature Image. If you don't know what to use
517    /// the High Contrast Image is probably right for you.
518    ///
519    /// The data is organized as a 8-bit value 80x60 pixel matrix linearized in
520    /// a one-dimensional array. The data is arranged line by line from top left to
521    /// bottom right.
522    ///
523    /// Each 8-bit value represents one gray-scale image pixel that can directly be
524    /// shown to a user on a display.
525    ///
526    /// Before you can use this function you have to enable it with
527    /// [`set_image_transfer_config`].
528    pub fn get_high_contrast_image_low_level(&self) -> ConvertingReceiver<HighContrastImageLowLevel> {
529        let payload = vec![0; 0];
530
531        self.device.get(u8::from(ThermalImagingBrickletFunction::GetHighContrastImageLowLevel), payload)
532    }
533
534    /// Returns the current high contrast image. See [here](https://www.tinkerforge.com/en/doc/Hardware/Bricklets/Thermal_Imaging.html#high-contrast-image-vs-temperature-image)__
535    /// for the difference between
536    /// High Contrast and Temperature Image. If you don't know what to use
537    /// the High Contrast Image is probably right for you.
538    ///
539    /// The data is organized as a 8-bit value 80x60 pixel matrix linearized in
540    /// a one-dimensional array. The data is arranged line by line from top left to
541    /// bottom right.
542    ///
543    /// Each 8-bit value represents one gray-scale image pixel that can directly be
544    /// shown to a user on a display.
545    ///
546    /// Before you can use this function you have to enable it with
547    /// [`set_image_transfer_config`].
548    pub fn get_high_contrast_image(&self) -> Result<Vec<u8>, BrickletRecvTimeoutError> {
549        let ll_result = self.device.get_high_level(0, &mut || self.get_high_contrast_image_low_level().recv())?;
550        Ok(ll_result.0)
551    }
552
553    /// Returns the current temperature image. See [here](https://www.tinkerforge.com/en/doc/Hardware/Bricklets/Thermal_Imaging.html#high-contrast-image-vs-temperature-image)__
554    /// for the difference between High Contrast and Temperature Image.
555    /// If you don't know what to use the High Contrast Image is probably right for you.
556    ///
557    /// The data is organized as a 16-bit value 80x60 pixel matrix linearized in
558    /// a one-dimensional array. The data is arranged line by line from top left to
559    /// bottom right.
560    ///
561    /// Each 16-bit value represents one temperature measurement in either
562    /// Kelvin/10 or Kelvin/100 (depending on the resolution set with [`set_resolution`]).
563    ///
564    /// Before you can use this function you have to enable it with
565    /// [`set_image_transfer_config`].
566    pub fn get_temperature_image_low_level(&self) -> ConvertingReceiver<TemperatureImageLowLevel> {
567        let payload = vec![0; 0];
568
569        self.device.get(u8::from(ThermalImagingBrickletFunction::GetTemperatureImageLowLevel), payload)
570    }
571
572    /// Returns the current temperature image. See [here](https://www.tinkerforge.com/en/doc/Hardware/Bricklets/Thermal_Imaging.html#high-contrast-image-vs-temperature-image)__
573    /// for the difference between High Contrast and Temperature Image.
574    /// If you don't know what to use the High Contrast Image is probably right for you.
575    ///
576    /// The data is organized as a 16-bit value 80x60 pixel matrix linearized in
577    /// a one-dimensional array. The data is arranged line by line from top left to
578    /// bottom right.
579    ///
580    /// Each 16-bit value represents one temperature measurement in either
581    /// Kelvin/10 or Kelvin/100 (depending on the resolution set with [`set_resolution`]).
582    ///
583    /// Before you can use this function you have to enable it with
584    /// [`set_image_transfer_config`].
585    pub fn get_temperature_image(&self) -> Result<Vec<u16>, BrickletRecvTimeoutError> {
586        let ll_result = self.device.get_high_level(1, &mut || self.get_temperature_image_low_level().recv())?;
587        Ok(ll_result.0)
588    }
589
590    /// Returns the spotmeter statistics, various temperatures, current resolution and status bits.
591    ///
592    /// The spotmeter statistics are:
593    ///
594    /// * Index 0: Mean Temperature.
595    /// * Index 1: Maximum Temperature.
596    /// * Index 2: Minimum Temperature.
597    /// * Index 3: Pixel Count of spotmeter region of interest.
598    ///
599    /// The temperatures are:
600    ///
601    /// * Index 0: Focal Plain Array temperature.
602    /// * Index 1: Focal Plain Array temperature at last FFC (Flat Field Correction).
603    /// * Index 2: Housing temperature.
604    /// * Index 3: Housing temperature at last FFC.
605    ///
606    /// The resolution is either `0 to 6553 Kelvin` or `0 to 655 Kelvin`. If the resolution is the former,
607    /// the temperatures are in Kelvin/10, if it is the latter the temperatures are in Kelvin/100.
608    ///
609    /// FFC (Flat Field Correction) Status:
610    ///
611    /// * FFC Never Commanded: Only seen on startup before first FFC.
612    /// * FFC Imminent: This state is entered 2 seconds prior to initiating FFC.
613    /// * FFC In Progress: Flat field correction is started (shutter moves in front of lens and back). Takes about 1 second.
614    /// * FFC Complete: Shutter is in waiting position again, FFC done.
615    ///
616    /// Temperature warning bits:
617    ///
618    /// * Index 0: Shutter lockout (if true shutter is locked out because temperature is outside -10°C to +65°C)
619    /// * Index 1: Overtemperature shut down imminent (goes true 10 seconds before shutdown)
620    ///
621    /// Associated constants:
622    /// * THERMAL_IMAGING_BRICKLET_RESOLUTION_0_TO_6553_KELVIN
623    ///	* THERMAL_IMAGING_BRICKLET_RESOLUTION_0_TO_655_KELVIN
624    ///	* THERMAL_IMAGING_BRICKLET_FFC_STATUS_NEVER_COMMANDED
625    ///	* THERMAL_IMAGING_BRICKLET_FFC_STATUS_IMMINENT
626    ///	* THERMAL_IMAGING_BRICKLET_FFC_STATUS_IN_PROGRESS
627    ///	* THERMAL_IMAGING_BRICKLET_FFC_STATUS_COMPLETE
628    pub fn get_statistics(&self) -> ConvertingReceiver<Statistics> {
629        let payload = vec![0; 0];
630
631        self.device.get(u8::from(ThermalImagingBrickletFunction::GetStatistics), payload)
632    }
633
634    /// Sets the resolution. The Thermal Imaging Bricklet can either measure
635    ///
636    /// * from 0 to 6553 Kelvin (-273.15°C to +6279.85°C) with 0.1°C resolution or
637    /// * from 0 to 655 Kelvin (-273.15°C to +381.85°C) with 0.01°C resolution.
638    ///
639    /// The accuracy is specified for -10°C to 450°C in the
640    /// first range and -10°C and 140°C in the second range.
641    ///
642    /// Associated constants:
643    /// * THERMAL_IMAGING_BRICKLET_RESOLUTION_0_TO_6553_KELVIN
644    ///	* THERMAL_IMAGING_BRICKLET_RESOLUTION_0_TO_655_KELVIN
645    pub fn set_resolution(&self, resolution: u8) -> ConvertingReceiver<()> {
646        let mut payload = vec![0; 1];
647        payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(resolution));
648
649        self.device.set(u8::from(ThermalImagingBrickletFunction::SetResolution), payload)
650    }
651
652    /// Returns the resolution as set by [`set_resolution`].
653    ///
654    /// Associated constants:
655    /// * THERMAL_IMAGING_BRICKLET_RESOLUTION_0_TO_6553_KELVIN
656    ///	* THERMAL_IMAGING_BRICKLET_RESOLUTION_0_TO_655_KELVIN
657    pub fn get_resolution(&self) -> ConvertingReceiver<u8> {
658        let payload = vec![0; 0];
659
660        self.device.get(u8::from(ThermalImagingBrickletFunction::GetResolution), payload)
661    }
662
663    /// Sets the spotmeter region of interest. The 4 values are
664    ///
665    /// * Index 0: Column start (has to be smaller then Column end).
666    /// * Index 1: Row start (has to be smaller then Row end).
667    /// * Index 2: Column end (has to be smaller then 80).
668    /// * Index 3: Row end (has to be smaller then 60).
669    ///
670    /// The spotmeter statistics can be read out with [`get_statistics`].
671    pub fn set_spotmeter_config(&self, region_of_interest: [u8; 4]) -> ConvertingReceiver<()> {
672        let mut payload = vec![0; 4];
673        payload[0..4].copy_from_slice(&<[u8; 4]>::to_le_byte_vec(region_of_interest));
674
675        self.device.set(u8::from(ThermalImagingBrickletFunction::SetSpotmeterConfig), payload)
676    }
677
678    /// Returns the spotmeter config as set by [`set_spotmeter_config`].
679    pub fn get_spotmeter_config(&self) -> ConvertingReceiver<[u8; 4]> {
680        let payload = vec![0; 0];
681
682        self.device.get(u8::from(ThermalImagingBrickletFunction::GetSpotmeterConfig), payload)
683    }
684
685    /// Sets the high contrast region of interest, dampening factor, clip limit and empty counts.
686    /// This config is only used in high contrast mode (see [`set_image_transfer_config`]).
687    ///
688    /// The high contrast region of interest consists of four values:
689    ///
690    /// * Index 0: Column start (has to be smaller or equal then Column end).
691    /// * Index 1: Row start (has to be smaller then Row end).
692    /// * Index 2: Column end (has to be smaller then 80).
693    /// * Index 3: Row end (has to be smaller then 60).
694    ///
695    /// The algorithm to generate the high contrast image is applied to this region.
696    ///
697    /// Dampening Factor: This parameter is the amount of temporal dampening applied to the HEQ
698    /// (history equalization) transformation function. An IIR filter of the form::
699    ///
700    ///  (N / 256) * previous + ((256 - N) / 256) * current
701    ///
702    /// is applied, and the HEQ dampening factor
703    /// represents the value N in the equation, i.e., a value that applies to the amount of
704    /// influence the previous HEQ transformation function has on the current function. The
705    /// lower the value of N the higher the influence of the current video frame whereas
706    /// the higher the value of N the more influence the previous damped transfer function has.
707    ///
708    /// Clip Limit Index 0 (AGC HEQ Clip Limit High): This parameter defines the maximum number of pixels allowed
709    /// to accumulate in any given histogram bin. Any additional pixels in a given bin are clipped.
710    /// The effect of this parameter is to limit the influence of highly-populated bins on the
711    /// resulting HEQ transformation function.
712    ///
713    /// Clip Limit Index 1 (AGC HEQ Clip Limit Low): This parameter defines an artificial population that is added to
714    /// every non-empty histogram bin. In other words, if the Clip Limit Low is set to L, a bin
715    /// with an actual population of X will have an effective population of L + X. Any empty bin
716    /// that is nearby a populated bin will be given an artificial population of L. The effect of
717    /// higher values is to provide a more linear transfer function; lower values provide a more
718    /// non-linear (equalized) transfer function.
719    ///
720    /// Empty Counts: This parameter specifies the maximum number of pixels in a bin that will be
721    /// interpreted as an empty bin. Histogram bins with this number of pixels or less will be
722    /// processed as an empty bin.
723    pub fn set_high_contrast_config(
724        &self,
725        region_of_interest: [u8; 4],
726        dampening_factor: u16,
727        clip_limit: [u16; 2],
728        empty_counts: u16,
729    ) -> ConvertingReceiver<()> {
730        let mut payload = vec![0; 12];
731        payload[0..4].copy_from_slice(&<[u8; 4]>::to_le_byte_vec(region_of_interest));
732        payload[4..6].copy_from_slice(&<u16>::to_le_byte_vec(dampening_factor));
733        payload[6..10].copy_from_slice(&<[u16; 2]>::to_le_byte_vec(clip_limit));
734        payload[10..12].copy_from_slice(&<u16>::to_le_byte_vec(empty_counts));
735
736        self.device.set(u8::from(ThermalImagingBrickletFunction::SetHighContrastConfig), payload)
737    }
738
739    /// Returns the high contrast config as set by [`set_high_contrast_config`].
740    pub fn get_high_contrast_config(&self) -> ConvertingReceiver<HighContrastConfig> {
741        let payload = vec![0; 0];
742
743        self.device.get(u8::from(ThermalImagingBrickletFunction::GetHighContrastConfig), payload)
744    }
745
746    /// The necessary bandwidth of this Bricklet is too high to use getter/receiver or
747    /// high contrast/temperature image at the same time. You have to configure the one
748    /// you want to use, the Bricklet will optimize the internal configuration accordingly.
749    ///
750    /// Corresponding functions:
751    ///
752    /// * Manual High Contrast Image: [`get_high_contrast_image`].
753    /// * Manual Temperature Image: [`get_temperature_image`].
754    /// * Receiver High Contrast Image: [`get_high_contrast_image_callback_receiver`] receiver.
755    /// * Receiver Temperature Image: [`get_temperature_image_callback_receiver`] receiver.
756    ///
757    /// Associated constants:
758    /// * THERMAL_IMAGING_BRICKLET_IMAGE_TRANSFER_MANUAL_HIGH_CONTRAST_IMAGE
759    ///	* THERMAL_IMAGING_BRICKLET_IMAGE_TRANSFER_MANUAL_TEMPERATURE_IMAGE
760    ///	* THERMAL_IMAGING_BRICKLET_IMAGE_TRANSFER_CALLBACK_HIGH_CONTRAST_IMAGE
761    ///	* THERMAL_IMAGING_BRICKLET_IMAGE_TRANSFER_CALLBACK_TEMPERATURE_IMAGE
762    pub fn set_image_transfer_config(&self, config: u8) -> ConvertingReceiver<()> {
763        let mut payload = vec![0; 1];
764        payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(config));
765
766        self.device.set(u8::from(ThermalImagingBrickletFunction::SetImageTransferConfig), payload)
767    }
768
769    /// Returns the image transfer config, as set by [`set_image_transfer_config`].
770    ///
771    /// Associated constants:
772    /// * THERMAL_IMAGING_BRICKLET_IMAGE_TRANSFER_MANUAL_HIGH_CONTRAST_IMAGE
773    ///	* THERMAL_IMAGING_BRICKLET_IMAGE_TRANSFER_MANUAL_TEMPERATURE_IMAGE
774    ///	* THERMAL_IMAGING_BRICKLET_IMAGE_TRANSFER_CALLBACK_HIGH_CONTRAST_IMAGE
775    ///	* THERMAL_IMAGING_BRICKLET_IMAGE_TRANSFER_CALLBACK_TEMPERATURE_IMAGE
776    pub fn get_image_transfer_config(&self) -> ConvertingReceiver<u8> {
777        let payload = vec![0; 0];
778
779        self.device.get(u8::from(ThermalImagingBrickletFunction::GetImageTransferConfig), payload)
780    }
781
782    /// Sets the flux linear parameters that can be used for radiometry calibration.
783    ///
784    /// See FLIR document 102-PS245-100-01 for more details.
785    ///
786    ///
787    /// .. versionadded:: 2.0.5$nbsp;(Plugin)
788    pub fn set_flux_linear_parameters(
789        &self,
790        scene_emissivity: u16,
791        temperature_background: u16,
792        tau_window: u16,
793        temperatur_window: u16,
794        tau_atmosphere: u16,
795        temperature_atmosphere: u16,
796        reflection_window: u16,
797        temperature_reflection: u16,
798    ) -> ConvertingReceiver<()> {
799        let mut payload = vec![0; 16];
800        payload[0..2].copy_from_slice(&<u16>::to_le_byte_vec(scene_emissivity));
801        payload[2..4].copy_from_slice(&<u16>::to_le_byte_vec(temperature_background));
802        payload[4..6].copy_from_slice(&<u16>::to_le_byte_vec(tau_window));
803        payload[6..8].copy_from_slice(&<u16>::to_le_byte_vec(temperatur_window));
804        payload[8..10].copy_from_slice(&<u16>::to_le_byte_vec(tau_atmosphere));
805        payload[10..12].copy_from_slice(&<u16>::to_le_byte_vec(temperature_atmosphere));
806        payload[12..14].copy_from_slice(&<u16>::to_le_byte_vec(reflection_window));
807        payload[14..16].copy_from_slice(&<u16>::to_le_byte_vec(temperature_reflection));
808
809        self.device.set(u8::from(ThermalImagingBrickletFunction::SetFluxLinearParameters), payload)
810    }
811
812    /// Returns the flux linear parameters, as set by [`set_flux_linear_parameters`].
813    ///
814    ///
815    /// .. versionadded:: 2.0.5$nbsp;(Plugin)
816    pub fn get_flux_linear_parameters(&self) -> ConvertingReceiver<FluxLinearParameters> {
817        let payload = vec![0; 0];
818
819        self.device.get(u8::from(ThermalImagingBrickletFunction::GetFluxLinearParameters), payload)
820    }
821
822    /// Sets the FFC shutter mode parameters.
823    ///
824    /// See FLIR document 110-0144-03 4.5.15 for more details.
825    ///
826    ///
827    /// .. versionadded:: 2.0.6$nbsp;(Plugin)
828    ///
829    /// Associated constants:
830    /// * THERMAL_IMAGING_BRICKLET_SHUTTER_MODE_MANUAL
831    ///	* THERMAL_IMAGING_BRICKLET_SHUTTER_MODE_AUTO
832    ///	* THERMAL_IMAGING_BRICKLET_SHUTTER_MODE_EXTERNAL
833    ///	* THERMAL_IMAGING_BRICKLET_SHUTTER_LOCKOUT_INACTIVE
834    ///	* THERMAL_IMAGING_BRICKLET_SHUTTER_LOCKOUT_HIGH
835    ///	* THERMAL_IMAGING_BRICKLET_SHUTTER_LOCKOUT_LOW
836    pub fn set_ffc_shutter_mode(
837        &self,
838        shutter_mode: u8,
839        temp_lockout_state: u8,
840        video_freeze_during_ffc: bool,
841        ffc_desired: bool,
842        elapsed_time_since_last_ffc: u32,
843        desired_ffc_period: u32,
844        explicit_cmd_to_open: bool,
845        desired_ffc_temp_delta: u16,
846        imminent_delay: u16,
847    ) -> ConvertingReceiver<()> {
848        let mut payload = vec![0; 17];
849        payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(shutter_mode));
850        payload[1..2].copy_from_slice(&<u8>::to_le_byte_vec(temp_lockout_state));
851        payload[2..3].copy_from_slice(&<bool>::to_le_byte_vec(video_freeze_during_ffc));
852        payload[3..4].copy_from_slice(&<bool>::to_le_byte_vec(ffc_desired));
853        payload[4..8].copy_from_slice(&<u32>::to_le_byte_vec(elapsed_time_since_last_ffc));
854        payload[8..12].copy_from_slice(&<u32>::to_le_byte_vec(desired_ffc_period));
855        payload[12..13].copy_from_slice(&<bool>::to_le_byte_vec(explicit_cmd_to_open));
856        payload[13..15].copy_from_slice(&<u16>::to_le_byte_vec(desired_ffc_temp_delta));
857        payload[15..17].copy_from_slice(&<u16>::to_le_byte_vec(imminent_delay));
858
859        self.device.set(u8::from(ThermalImagingBrickletFunction::SetFfcShutterMode), payload)
860    }
861
862    /// Sets the FFC shutter mode parameters.
863    ///
864    /// See FLIR document 110-0144-03 4.5.15 for more details.
865    ///
866    ///
867    /// .. versionadded:: 2.0.6$nbsp;(Plugin)
868    ///
869    /// Associated constants:
870    /// * THERMAL_IMAGING_BRICKLET_SHUTTER_MODE_MANUAL
871    ///	* THERMAL_IMAGING_BRICKLET_SHUTTER_MODE_AUTO
872    ///	* THERMAL_IMAGING_BRICKLET_SHUTTER_MODE_EXTERNAL
873    ///	* THERMAL_IMAGING_BRICKLET_SHUTTER_LOCKOUT_INACTIVE
874    ///	* THERMAL_IMAGING_BRICKLET_SHUTTER_LOCKOUT_HIGH
875    ///	* THERMAL_IMAGING_BRICKLET_SHUTTER_LOCKOUT_LOW
876    pub fn get_ffc_shutter_mode(&self) -> ConvertingReceiver<FfcShutterMode> {
877        let payload = vec![0; 0];
878
879        self.device.get(u8::from(ThermalImagingBrickletFunction::GetFfcShutterMode), payload)
880    }
881
882    /// Starts the Flat-Field Correction (FFC) normalization.
883    ///
884    /// See FLIR document 110-0144-03 4.5.16 for more details.
885    ///
886    ///
887    /// .. versionadded:: 2.0.6$nbsp;(Plugin)
888    pub fn run_ffc_normalization(&self) -> ConvertingReceiver<()> {
889        let payload = vec![0; 0];
890
891        self.device.set(u8::from(ThermalImagingBrickletFunction::RunFfcNormalization), payload)
892    }
893
894    /// Returns the error count for the communication between Brick and Bricklet.
895    ///
896    /// The errors are divided into
897    ///
898    /// * ACK checksum errors,
899    /// * message checksum errors,
900    /// * framing errors and
901    /// * overflow errors.
902    ///
903    /// The errors counts are for errors that occur on the Bricklet side. All
904    /// Bricks have a similar function that returns the errors on the Brick side.
905    pub fn get_spitfp_error_count(&self) -> ConvertingReceiver<SpitfpErrorCount> {
906        let payload = vec![0; 0];
907
908        self.device.get(u8::from(ThermalImagingBrickletFunction::GetSpitfpErrorCount), payload)
909    }
910
911    /// Sets the bootloader mode and returns the status after the requested
912    /// mode change was instigated.
913    ///
914    /// You can change from bootloader mode to firmware mode and vice versa. A change
915    /// from bootloader mode to firmware mode will only take place if the entry function,
916    /// device identifier and CRC are present and correct.
917    ///
918    /// This function is used by Brick Viewer during flashing. It should not be
919    /// necessary to call it in a normal user program.
920    ///
921    /// Associated constants:
922    /// * THERMAL_IMAGING_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
923    ///	* THERMAL_IMAGING_BRICKLET_BOOTLOADER_MODE_FIRMWARE
924    ///	* THERMAL_IMAGING_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
925    ///	* THERMAL_IMAGING_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
926    ///	* THERMAL_IMAGING_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
927    ///	* THERMAL_IMAGING_BRICKLET_BOOTLOADER_STATUS_OK
928    ///	* THERMAL_IMAGING_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE
929    ///	* THERMAL_IMAGING_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE
930    ///	* THERMAL_IMAGING_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT
931    ///	* THERMAL_IMAGING_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT
932    ///	* THERMAL_IMAGING_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH
933    pub fn set_bootloader_mode(&self, mode: u8) -> ConvertingReceiver<u8> {
934        let mut payload = vec![0; 1];
935        payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(mode));
936
937        self.device.get(u8::from(ThermalImagingBrickletFunction::SetBootloaderMode), payload)
938    }
939
940    /// Returns the current bootloader mode, see [`set_bootloader_mode`].
941    ///
942    /// Associated constants:
943    /// * THERMAL_IMAGING_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
944    ///	* THERMAL_IMAGING_BRICKLET_BOOTLOADER_MODE_FIRMWARE
945    ///	* THERMAL_IMAGING_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
946    ///	* THERMAL_IMAGING_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
947    ///	* THERMAL_IMAGING_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
948    pub fn get_bootloader_mode(&self) -> ConvertingReceiver<u8> {
949        let payload = vec![0; 0];
950
951        self.device.get(u8::from(ThermalImagingBrickletFunction::GetBootloaderMode), payload)
952    }
953
954    /// Sets the firmware pointer for [`write_firmware`]. The pointer has
955    /// to be increased by chunks of size 64. The data is written to flash
956    /// every 4 chunks (which equals to one page of size 256).
957    ///
958    /// This function is used by Brick Viewer during flashing. It should not be
959    /// necessary to call it in a normal user program.
960    pub fn set_write_firmware_pointer(&self, pointer: u32) -> ConvertingReceiver<()> {
961        let mut payload = vec![0; 4];
962        payload[0..4].copy_from_slice(&<u32>::to_le_byte_vec(pointer));
963
964        self.device.set(u8::from(ThermalImagingBrickletFunction::SetWriteFirmwarePointer), payload)
965    }
966
967    /// Writes 64 Bytes of firmware at the position as written by
968    /// [`set_write_firmware_pointer`] before. The firmware is written
969    /// to flash every 4 chunks.
970    ///
971    /// You can only write firmware in bootloader mode.
972    ///
973    /// This function is used by Brick Viewer during flashing. It should not be
974    /// necessary to call it in a normal user program.
975    pub fn write_firmware(&self, data: [u8; 64]) -> ConvertingReceiver<u8> {
976        let mut payload = vec![0; 64];
977        payload[0..64].copy_from_slice(&<[u8; 64]>::to_le_byte_vec(data));
978
979        self.device.get(u8::from(ThermalImagingBrickletFunction::WriteFirmware), payload)
980    }
981
982    /// Sets the status LED configuration. By default the LED shows
983    /// communication traffic between Brick and Bricklet, it flickers once
984    /// for every 10 received data packets.
985    ///
986    /// You can also turn the LED permanently on/off or show a heartbeat.
987    ///
988    /// If the Bricklet is in bootloader mode, the LED is will show heartbeat by default.
989    ///
990    /// Associated constants:
991    /// * THERMAL_IMAGING_BRICKLET_STATUS_LED_CONFIG_OFF
992    ///	* THERMAL_IMAGING_BRICKLET_STATUS_LED_CONFIG_ON
993    ///	* THERMAL_IMAGING_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
994    ///	* THERMAL_IMAGING_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
995    pub fn set_status_led_config(&self, config: u8) -> ConvertingReceiver<()> {
996        let mut payload = vec![0; 1];
997        payload[0..1].copy_from_slice(&<u8>::to_le_byte_vec(config));
998
999        self.device.set(u8::from(ThermalImagingBrickletFunction::SetStatusLedConfig), payload)
1000    }
1001
1002    /// Returns the configuration as set by [`set_status_led_config`]
1003    ///
1004    /// Associated constants:
1005    /// * THERMAL_IMAGING_BRICKLET_STATUS_LED_CONFIG_OFF
1006    ///	* THERMAL_IMAGING_BRICKLET_STATUS_LED_CONFIG_ON
1007    ///	* THERMAL_IMAGING_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
1008    ///	* THERMAL_IMAGING_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
1009    pub fn get_status_led_config(&self) -> ConvertingReceiver<u8> {
1010        let payload = vec![0; 0];
1011
1012        self.device.get(u8::from(ThermalImagingBrickletFunction::GetStatusLedConfig), payload)
1013    }
1014
1015    /// Returns the temperature as measured inside the microcontroller. The
1016    /// value returned is not the ambient temperature!
1017    ///
1018    /// The temperature is only proportional to the real temperature and it has bad
1019    /// accuracy. Practically it is only useful as an indicator for
1020    /// temperature changes.
1021    pub fn get_chip_temperature(&self) -> ConvertingReceiver<i16> {
1022        let payload = vec![0; 0];
1023
1024        self.device.get(u8::from(ThermalImagingBrickletFunction::GetChipTemperature), payload)
1025    }
1026
1027    /// Calling this function will reset the Bricklet. All configurations
1028    /// will be lost.
1029    ///
1030    /// After a reset you have to create new device objects,
1031    /// calling functions on the existing ones will result in
1032    /// undefined behavior!
1033    pub fn reset(&self) -> ConvertingReceiver<()> {
1034        let payload = vec![0; 0];
1035
1036        self.device.set(u8::from(ThermalImagingBrickletFunction::Reset), payload)
1037    }
1038
1039    /// Writes a new UID into flash. If you want to set a new UID
1040    /// you have to decode the Base58 encoded UID string into an
1041    /// integer first.
1042    ///
1043    /// We recommend that you use Brick Viewer to change the UID.
1044    pub fn write_uid(&self, uid: u32) -> ConvertingReceiver<()> {
1045        let mut payload = vec![0; 4];
1046        payload[0..4].copy_from_slice(&<u32>::to_le_byte_vec(uid));
1047
1048        self.device.set(u8::from(ThermalImagingBrickletFunction::WriteUid), payload)
1049    }
1050
1051    /// Returns the current UID as an integer. Encode as
1052    /// Base58 to get the usual string version.
1053    pub fn read_uid(&self) -> ConvertingReceiver<u32> {
1054        let payload = vec![0; 0];
1055
1056        self.device.get(u8::from(ThermalImagingBrickletFunction::ReadUid), payload)
1057    }
1058
1059    /// Returns the UID, the UID where the Bricklet is connected to,
1060    /// the position, the hardware and firmware version as well as the
1061    /// device identifier.
1062    ///
1063    /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
1064    /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
1065    /// position 'z'.
1066    ///
1067    /// The device identifier numbers can be found [here](device_identifier).
1068    /// |device_identifier_constant|
1069    pub fn get_identity(&self) -> ConvertingReceiver<Identity> {
1070        let payload = vec![0; 0];
1071
1072        self.device.get(u8::from(ThermalImagingBrickletFunction::GetIdentity), payload)
1073    }
1074}