tinkerforge_async/bindings/
industrial_quad_relay_v2_bricklet.rs

1/* ***********************************************************
2 * This file was automatically generated on 2024-02-16.      *
3 *                                                           *
4 * Rust Bindings Version 2.0.20                              *
5 *                                                           *
6 * If you have a bugfix for this file and want to commit it, *
7 * please fix the bug in the generator. You can find a link  *
8 * to the generators git repository on tinkerforge.com       *
9 *************************************************************/
10
11//! 4 galvanically isolated solid state relays.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/IndustrialQuadRelayV2_Bricklet_Rust.html).
14#[allow(unused_imports)]
15use crate::{
16    base58::Uid, byte_converter::*, device::*, error::TinkerforgeError, ip_connection::async_io::AsyncIpConnection,
17    low_level_traits::LowLevelRead,
18};
19#[allow(unused_imports)]
20use futures_core::Stream;
21#[allow(unused_imports)]
22use tokio_stream::StreamExt;
23pub enum IndustrialQuadRelayV2BrickletFunction {
24    SetValue,
25    GetValue,
26    SetMonoflop,
27    GetMonoflop,
28    SetSelectedValue,
29    SetChannelLedConfig,
30    GetChannelLedConfig,
31    GetSpitfpErrorCount,
32    SetBootloaderMode,
33    GetBootloaderMode,
34    SetWriteFirmwarePointer,
35    WriteFirmware,
36    SetStatusLedConfig,
37    GetStatusLedConfig,
38    GetChipTemperature,
39    Reset,
40    WriteUid,
41    ReadUid,
42    GetIdentity,
43    CallbackMonoflopDone,
44}
45impl From<IndustrialQuadRelayV2BrickletFunction> for u8 {
46    fn from(fun: IndustrialQuadRelayV2BrickletFunction) -> Self {
47        match fun {
48            IndustrialQuadRelayV2BrickletFunction::SetValue => 1,
49            IndustrialQuadRelayV2BrickletFunction::GetValue => 2,
50            IndustrialQuadRelayV2BrickletFunction::SetMonoflop => 3,
51            IndustrialQuadRelayV2BrickletFunction::GetMonoflop => 4,
52            IndustrialQuadRelayV2BrickletFunction::SetSelectedValue => 5,
53            IndustrialQuadRelayV2BrickletFunction::SetChannelLedConfig => 6,
54            IndustrialQuadRelayV2BrickletFunction::GetChannelLedConfig => 7,
55            IndustrialQuadRelayV2BrickletFunction::GetSpitfpErrorCount => 234,
56            IndustrialQuadRelayV2BrickletFunction::SetBootloaderMode => 235,
57            IndustrialQuadRelayV2BrickletFunction::GetBootloaderMode => 236,
58            IndustrialQuadRelayV2BrickletFunction::SetWriteFirmwarePointer => 237,
59            IndustrialQuadRelayV2BrickletFunction::WriteFirmware => 238,
60            IndustrialQuadRelayV2BrickletFunction::SetStatusLedConfig => 239,
61            IndustrialQuadRelayV2BrickletFunction::GetStatusLedConfig => 240,
62            IndustrialQuadRelayV2BrickletFunction::GetChipTemperature => 242,
63            IndustrialQuadRelayV2BrickletFunction::Reset => 243,
64            IndustrialQuadRelayV2BrickletFunction::WriteUid => 248,
65            IndustrialQuadRelayV2BrickletFunction::ReadUid => 249,
66            IndustrialQuadRelayV2BrickletFunction::GetIdentity => 255,
67            IndustrialQuadRelayV2BrickletFunction::CallbackMonoflopDone => 8,
68        }
69    }
70}
71pub const INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_CHANNEL_LED_CONFIG_OFF: u8 = 0;
72pub const INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_CHANNEL_LED_CONFIG_ON: u8 = 1;
73pub const INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_CHANNEL_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
74pub const INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_CHANNEL_LED_CONFIG_SHOW_CHANNEL_STATUS: u8 = 3;
75pub const INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER: u8 = 0;
76pub const INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE: u8 = 1;
77pub const INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT: u8 = 2;
78pub const INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT: u8 = 3;
79pub const INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT: u8 = 4;
80pub const INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_STATUS_OK: u8 = 0;
81pub const INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE: u8 = 1;
82pub const INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE: u8 = 2;
83pub const INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT: u8 = 3;
84pub const INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT: u8 = 4;
85pub const INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH: u8 = 5;
86pub const INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_STATUS_LED_CONFIG_OFF: u8 = 0;
87pub const INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_STATUS_LED_CONFIG_ON: u8 = 1;
88pub const INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
89pub const INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS: u8 = 3;
90
91#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
92pub struct Monoflop {
93    pub value: bool,
94    pub time: u32,
95    pub time_remaining: u32,
96}
97impl FromByteSlice for Monoflop {
98    fn bytes_expected() -> usize {
99        9
100    }
101    fn from_le_byte_slice(bytes: &[u8]) -> Monoflop {
102        Monoflop {
103            value: <bool>::from_le_byte_slice(&bytes[0..1]),
104            time: <u32>::from_le_byte_slice(&bytes[1..5]),
105            time_remaining: <u32>::from_le_byte_slice(&bytes[5..9]),
106        }
107    }
108}
109
110#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
111pub struct MonoflopDoneEvent {
112    pub channel: u8,
113    pub value: bool,
114}
115impl FromByteSlice for MonoflopDoneEvent {
116    fn bytes_expected() -> usize {
117        2
118    }
119    fn from_le_byte_slice(bytes: &[u8]) -> MonoflopDoneEvent {
120        MonoflopDoneEvent { channel: <u8>::from_le_byte_slice(&bytes[0..1]), value: <bool>::from_le_byte_slice(&bytes[1..2]) }
121    }
122}
123
124#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
125pub struct SpitfpErrorCount {
126    pub error_count_ack_checksum: u32,
127    pub error_count_message_checksum: u32,
128    pub error_count_frame: u32,
129    pub error_count_overflow: u32,
130}
131impl FromByteSlice for SpitfpErrorCount {
132    fn bytes_expected() -> usize {
133        16
134    }
135    fn from_le_byte_slice(bytes: &[u8]) -> SpitfpErrorCount {
136        SpitfpErrorCount {
137            error_count_ack_checksum: <u32>::from_le_byte_slice(&bytes[0..4]),
138            error_count_message_checksum: <u32>::from_le_byte_slice(&bytes[4..8]),
139            error_count_frame: <u32>::from_le_byte_slice(&bytes[8..12]),
140            error_count_overflow: <u32>::from_le_byte_slice(&bytes[12..16]),
141        }
142    }
143}
144
145#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
146pub struct Identity {
147    pub uid: String,
148    pub connected_uid: String,
149    pub position: char,
150    pub hardware_version: [u8; 3],
151    pub firmware_version: [u8; 3],
152    pub device_identifier: u16,
153}
154impl FromByteSlice for Identity {
155    fn bytes_expected() -> usize {
156        25
157    }
158    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
159        Identity {
160            uid: <String>::from_le_byte_slice(&bytes[0..8]),
161            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
162            position: <char>::from_le_byte_slice(&bytes[16..17]),
163            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
164            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
165            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
166        }
167    }
168}
169
170/// 4 galvanically isolated solid state relays
171#[derive(Clone)]
172pub struct IndustrialQuadRelayV2Bricklet {
173    device: Device,
174}
175impl IndustrialQuadRelayV2Bricklet {
176    pub const DEVICE_IDENTIFIER: u16 = 2102;
177    pub const DEVICE_DISPLAY_NAME: &'static str = "Industrial Quad Relay Bricklet 2.0";
178    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
179    pub fn new(uid: Uid, connection: AsyncIpConnection) -> IndustrialQuadRelayV2Bricklet {
180        let mut result = IndustrialQuadRelayV2Bricklet { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
181        result.device.response_expected[u8::from(IndustrialQuadRelayV2BrickletFunction::SetValue) as usize] = ResponseExpectedFlag::False;
182        result.device.response_expected[u8::from(IndustrialQuadRelayV2BrickletFunction::GetValue) as usize] =
183            ResponseExpectedFlag::AlwaysTrue;
184        result.device.response_expected[u8::from(IndustrialQuadRelayV2BrickletFunction::SetMonoflop) as usize] =
185            ResponseExpectedFlag::False;
186        result.device.response_expected[u8::from(IndustrialQuadRelayV2BrickletFunction::GetMonoflop) as usize] =
187            ResponseExpectedFlag::AlwaysTrue;
188        result.device.response_expected[u8::from(IndustrialQuadRelayV2BrickletFunction::SetSelectedValue) as usize] =
189            ResponseExpectedFlag::False;
190        result.device.response_expected[u8::from(IndustrialQuadRelayV2BrickletFunction::SetChannelLedConfig) as usize] =
191            ResponseExpectedFlag::False;
192        result.device.response_expected[u8::from(IndustrialQuadRelayV2BrickletFunction::GetChannelLedConfig) as usize] =
193            ResponseExpectedFlag::AlwaysTrue;
194        result.device.response_expected[u8::from(IndustrialQuadRelayV2BrickletFunction::GetSpitfpErrorCount) as usize] =
195            ResponseExpectedFlag::AlwaysTrue;
196        result.device.response_expected[u8::from(IndustrialQuadRelayV2BrickletFunction::SetBootloaderMode) as usize] =
197            ResponseExpectedFlag::AlwaysTrue;
198        result.device.response_expected[u8::from(IndustrialQuadRelayV2BrickletFunction::GetBootloaderMode) as usize] =
199            ResponseExpectedFlag::AlwaysTrue;
200        result.device.response_expected[u8::from(IndustrialQuadRelayV2BrickletFunction::SetWriteFirmwarePointer) as usize] =
201            ResponseExpectedFlag::False;
202        result.device.response_expected[u8::from(IndustrialQuadRelayV2BrickletFunction::WriteFirmware) as usize] =
203            ResponseExpectedFlag::AlwaysTrue;
204        result.device.response_expected[u8::from(IndustrialQuadRelayV2BrickletFunction::SetStatusLedConfig) as usize] =
205            ResponseExpectedFlag::False;
206        result.device.response_expected[u8::from(IndustrialQuadRelayV2BrickletFunction::GetStatusLedConfig) as usize] =
207            ResponseExpectedFlag::AlwaysTrue;
208        result.device.response_expected[u8::from(IndustrialQuadRelayV2BrickletFunction::GetChipTemperature) as usize] =
209            ResponseExpectedFlag::AlwaysTrue;
210        result.device.response_expected[u8::from(IndustrialQuadRelayV2BrickletFunction::Reset) as usize] = ResponseExpectedFlag::False;
211        result.device.response_expected[u8::from(IndustrialQuadRelayV2BrickletFunction::WriteUid) as usize] = ResponseExpectedFlag::False;
212        result.device.response_expected[u8::from(IndustrialQuadRelayV2BrickletFunction::ReadUid) as usize] =
213            ResponseExpectedFlag::AlwaysTrue;
214        result.device.response_expected[u8::from(IndustrialQuadRelayV2BrickletFunction::GetIdentity) as usize] =
215            ResponseExpectedFlag::AlwaysTrue;
216        result
217    }
218
219    /// Returns the response expected flag for the function specified by the function ID parameter.
220    /// It is true if the function is expected to send a response, false otherwise.
221    ///
222    /// For getter functions this is enabled by default and cannot be disabled, because those
223    /// functions will always send a response. For callback configuration functions it is enabled
224    /// by default too, but can be disabled by [`set_response_expected`](crate::industrial_quad_relay_v2_bricklet::IndustrialQuadRelayV2Bricklet::set_response_expected).
225    /// For setter functions it is disabled by default and can be enabled.
226    ///
227    /// Enabling the response expected flag for a setter function allows to detect timeouts
228    /// and other error conditions calls of this setter as well. The device will then send a response
229    /// for this purpose. If this flag is disabled for a setter function then no response is sent
230    /// and errors are silently ignored, because they cannot be detected.
231    ///
232    /// See [`set_response_expected`](crate::industrial_quad_relay_v2_bricklet::IndustrialQuadRelayV2Bricklet::set_response_expected) for the list of function ID constants available for this function.
233    pub fn get_response_expected(&mut self, fun: IndustrialQuadRelayV2BrickletFunction) -> Result<bool, GetResponseExpectedError> {
234        self.device.get_response_expected(u8::from(fun))
235    }
236
237    /// Changes the response expected flag of the function specified by the function ID parameter.
238    /// This flag can only be changed for setter (default value: false) and callback configuration
239    /// functions (default value: true). For getter functions it is always enabled.
240    ///
241    /// Enabling the response expected flag for a setter function allows to detect timeouts and
242    /// other error conditions calls of this setter as well. The device will then send a response
243    /// for this purpose. If this flag is disabled for a setter function then no response is sent
244    /// and errors are silently ignored, because they cannot be detected.
245    pub fn set_response_expected(
246        &mut self,
247        fun: IndustrialQuadRelayV2BrickletFunction,
248        response_expected: bool,
249    ) -> Result<(), SetResponseExpectedError> {
250        self.device.set_response_expected(u8::from(fun), response_expected)
251    }
252
253    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
254    pub fn set_response_expected_all(&mut self, response_expected: bool) {
255        self.device.set_response_expected_all(response_expected)
256    }
257
258    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
259    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
260    pub fn get_api_version(&self) -> [u8; 3] {
261        self.device.api_version
262    }
263
264    /// This receiver is triggered whenever a monoflop timer reaches 0. The
265    /// parameters contain the channel and the current value of the channel
266    /// (the value after the monoflop).
267    pub async fn get_monoflop_done_callback_receiver(&mut self) -> impl Stream<Item = MonoflopDoneEvent> {
268        self.device
269            .get_callback_receiver(u8::from(IndustrialQuadRelayV2BrickletFunction::CallbackMonoflopDone))
270            .await
271            .map(|p| MonoflopDoneEvent::from_le_byte_slice(p.body()))
272    }
273
274    /// Sets the value of all four relays. A value of *true* closes the
275    /// relay and a value of *false* opens the relay.
276    ///
277    /// Use [`set_selected_value`] to only change one relay.
278    ///
279    /// All running monoflop timers will be aborted if this function is called.
280    pub async fn set_value(&mut self, value: &[bool; 4]) -> Result<(), TinkerforgeError> {
281        let mut payload = [0; 1];
282        value.write_to_slice(&mut payload[0..1]);
283
284        #[allow(unused_variables)]
285        let result = self.device.set(u8::from(IndustrialQuadRelayV2BrickletFunction::SetValue), &payload).await?;
286        Ok(())
287    }
288
289    /// Returns the values as set by [`set_value`].
290    pub async fn get_value(&mut self) -> Result<Box<[bool; 4]>, TinkerforgeError> {
291        let payload = [0; 0];
292
293        #[allow(unused_variables)]
294        let result = self.device.get(u8::from(IndustrialQuadRelayV2BrickletFunction::GetValue), &payload).await?;
295        Ok(Box::<[bool; 4]>::from_le_byte_slice(result.body()))
296    }
297
298    /// Configures a monoflop of the specified channel.
299    ///
300    /// The second parameter is the desired value of the specified
301    /// channel. A *true* means relay closed and a *false* means relay open.
302    ///
303    /// The third parameter indicates the time that the channels should hold
304    /// the value.
305    ///
306    /// If this function is called with the parameters (0, 1, 1500) channel 0 will
307    /// close and in 1.5s channel 0 will open again
308    ///
309    /// A monoflop can be used as a fail-safe mechanism. For example: Lets assume you
310    /// have a RS485 bus and a Industrial Quad Relay Bricklet 2.0 connected to one of
311    /// the slave stacks. You can now call this function every second, with a time
312    /// parameter of two seconds and channel 0 closed. Channel 0 will be closed all the
313    /// time. If now the RS485 connection is lost, then channel 0 will be opened in at
314    /// most two seconds.
315    pub async fn set_monoflop(&mut self, channel: u8, value: bool, time: u32) -> Result<(), TinkerforgeError> {
316        let mut payload = [0; 6];
317        channel.write_to_slice(&mut payload[0..1]);
318        value.write_to_slice(&mut payload[1..2]);
319        time.write_to_slice(&mut payload[2..6]);
320
321        #[allow(unused_variables)]
322        let result = self.device.set(u8::from(IndustrialQuadRelayV2BrickletFunction::SetMonoflop), &payload).await?;
323        Ok(())
324    }
325
326    /// Returns (for the given channel) the current value and the time as set by
327    /// [`set_monoflop`] as well as the remaining time until the value flips.
328    ///
329    /// If the timer is not running currently, the remaining time will be returned
330    /// as 0.
331    pub async fn get_monoflop(&mut self, channel: u8) -> Result<Monoflop, TinkerforgeError> {
332        let mut payload = [0; 1];
333        channel.write_to_slice(&mut payload[0..1]);
334
335        #[allow(unused_variables)]
336        let result = self.device.get(u8::from(IndustrialQuadRelayV2BrickletFunction::GetMonoflop), &payload).await?;
337        Ok(Monoflop::from_le_byte_slice(result.body()))
338    }
339
340    /// Sets the output value of the specified channel without affecting the other
341    /// channels.
342    ///
343    /// A running monoflop timer for the specified channel will be aborted if this
344    /// function is called.
345    pub async fn set_selected_value(&mut self, channel: u8, value: bool) -> Result<(), TinkerforgeError> {
346        let mut payload = [0; 2];
347        channel.write_to_slice(&mut payload[0..1]);
348        value.write_to_slice(&mut payload[1..2]);
349
350        #[allow(unused_variables)]
351        let result = self.device.set(u8::from(IndustrialQuadRelayV2BrickletFunction::SetSelectedValue), &payload).await?;
352        Ok(())
353    }
354
355    /// Each channel has a corresponding LED. You can turn the LED off, on or show a
356    /// heartbeat. You can also set the LED to Channel Status. In this mode the
357    /// LED is on if the channel is high and off otherwise.
358    ///
359    /// Associated constants:
360    /// * INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_CHANNEL_LED_CONFIG_OFF
361    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_CHANNEL_LED_CONFIG_ON
362    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_CHANNEL_LED_CONFIG_SHOW_HEARTBEAT
363    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_CHANNEL_LED_CONFIG_SHOW_CHANNEL_STATUS
364    pub async fn set_channel_led_config(&mut self, channel: u8, config: u8) -> Result<(), TinkerforgeError> {
365        let mut payload = [0; 2];
366        channel.write_to_slice(&mut payload[0..1]);
367        config.write_to_slice(&mut payload[1..2]);
368
369        #[allow(unused_variables)]
370        let result = self.device.set(u8::from(IndustrialQuadRelayV2BrickletFunction::SetChannelLedConfig), &payload).await?;
371        Ok(())
372    }
373
374    /// Returns the channel LED configuration as set by [`set_channel_led_config`]
375    ///
376    /// Associated constants:
377    /// * INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_CHANNEL_LED_CONFIG_OFF
378    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_CHANNEL_LED_CONFIG_ON
379    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_CHANNEL_LED_CONFIG_SHOW_HEARTBEAT
380    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_CHANNEL_LED_CONFIG_SHOW_CHANNEL_STATUS
381    pub async fn get_channel_led_config(&mut self, channel: u8) -> Result<u8, TinkerforgeError> {
382        let mut payload = [0; 1];
383        channel.write_to_slice(&mut payload[0..1]);
384
385        #[allow(unused_variables)]
386        let result = self.device.get(u8::from(IndustrialQuadRelayV2BrickletFunction::GetChannelLedConfig), &payload).await?;
387        Ok(u8::from_le_byte_slice(result.body()))
388    }
389
390    /// Returns the error count for the communication between Brick and Bricklet.
391    ///
392    /// The errors are divided into
393    ///
394    /// * ACK checksum errors,
395    /// * message checksum errors,
396    /// * framing errors and
397    /// * overflow errors.
398    ///
399    /// The errors counts are for errors that occur on the Bricklet side. All
400    /// Bricks have a similar function that returns the errors on the Brick side.
401    pub async fn get_spitfp_error_count(&mut self) -> Result<SpitfpErrorCount, TinkerforgeError> {
402        let payload = [0; 0];
403
404        #[allow(unused_variables)]
405        let result = self.device.get(u8::from(IndustrialQuadRelayV2BrickletFunction::GetSpitfpErrorCount), &payload).await?;
406        Ok(SpitfpErrorCount::from_le_byte_slice(result.body()))
407    }
408
409    /// Sets the bootloader mode and returns the status after the requested
410    /// mode change was instigated.
411    ///
412    /// You can change from bootloader mode to firmware mode and vice versa. A change
413    /// from bootloader mode to firmware mode will only take place if the entry function,
414    /// device identifier and CRC are present and correct.
415    ///
416    /// This function is used by Brick Viewer during flashing. It should not be
417    /// necessary to call it in a normal user program.
418    ///
419    /// Associated constants:
420    /// * INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
421    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE
422    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
423    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
424    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
425    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_STATUS_OK
426    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE
427    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE
428    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT
429    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT
430    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH
431    pub async fn set_bootloader_mode(&mut self, mode: u8) -> Result<u8, TinkerforgeError> {
432        let mut payload = [0; 1];
433        mode.write_to_slice(&mut payload[0..1]);
434
435        #[allow(unused_variables)]
436        let result = self.device.get(u8::from(IndustrialQuadRelayV2BrickletFunction::SetBootloaderMode), &payload).await?;
437        Ok(u8::from_le_byte_slice(result.body()))
438    }
439
440    /// Returns the current bootloader mode, see [`set_bootloader_mode`].
441    ///
442    /// Associated constants:
443    /// * INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
444    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE
445    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
446    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
447    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
448    pub async fn get_bootloader_mode(&mut self) -> Result<u8, TinkerforgeError> {
449        let payload = [0; 0];
450
451        #[allow(unused_variables)]
452        let result = self.device.get(u8::from(IndustrialQuadRelayV2BrickletFunction::GetBootloaderMode), &payload).await?;
453        Ok(u8::from_le_byte_slice(result.body()))
454    }
455
456    /// Sets the firmware pointer for [`write_firmware`]. The pointer has
457    /// to be increased by chunks of size 64. The data is written to flash
458    /// every 4 chunks (which equals to one page of size 256).
459    ///
460    /// This function is used by Brick Viewer during flashing. It should not be
461    /// necessary to call it in a normal user program.
462    pub async fn set_write_firmware_pointer(&mut self, pointer: u32) -> Result<(), TinkerforgeError> {
463        let mut payload = [0; 4];
464        pointer.write_to_slice(&mut payload[0..4]);
465
466        #[allow(unused_variables)]
467        let result = self.device.set(u8::from(IndustrialQuadRelayV2BrickletFunction::SetWriteFirmwarePointer), &payload).await?;
468        Ok(())
469    }
470
471    /// Writes 64 Bytes of firmware at the position as written by
472    /// [`set_write_firmware_pointer`] before. The firmware is written
473    /// to flash every 4 chunks.
474    ///
475    /// You can only write firmware in bootloader mode.
476    ///
477    /// This function is used by Brick Viewer during flashing. It should not be
478    /// necessary to call it in a normal user program.
479    pub async fn write_firmware(&mut self, data: &[u8; 64]) -> Result<u8, TinkerforgeError> {
480        let mut payload = [0; 64];
481        data.write_to_slice(&mut payload[0..64]);
482
483        #[allow(unused_variables)]
484        let result = self.device.get(u8::from(IndustrialQuadRelayV2BrickletFunction::WriteFirmware), &payload).await?;
485        Ok(u8::from_le_byte_slice(result.body()))
486    }
487
488    /// Sets the status LED configuration. By default the LED shows
489    /// communication traffic between Brick and Bricklet, it flickers once
490    /// for every 10 received data packets.
491    ///
492    /// You can also turn the LED permanently on/off or show a heartbeat.
493    ///
494    /// If the Bricklet is in bootloader mode, the LED is will show heartbeat by default.
495    ///
496    /// Associated constants:
497    /// * INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_STATUS_LED_CONFIG_OFF
498    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_STATUS_LED_CONFIG_ON
499    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
500    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
501    pub async fn set_status_led_config(&mut self, config: u8) -> Result<(), TinkerforgeError> {
502        let mut payload = [0; 1];
503        config.write_to_slice(&mut payload[0..1]);
504
505        #[allow(unused_variables)]
506        let result = self.device.set(u8::from(IndustrialQuadRelayV2BrickletFunction::SetStatusLedConfig), &payload).await?;
507        Ok(())
508    }
509
510    /// Returns the configuration as set by [`set_status_led_config`]
511    ///
512    /// Associated constants:
513    /// * INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_STATUS_LED_CONFIG_OFF
514    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_STATUS_LED_CONFIG_ON
515    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
516    ///	* INDUSTRIAL_QUAD_RELAY_V2_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
517    pub async fn get_status_led_config(&mut self) -> Result<u8, TinkerforgeError> {
518        let payload = [0; 0];
519
520        #[allow(unused_variables)]
521        let result = self.device.get(u8::from(IndustrialQuadRelayV2BrickletFunction::GetStatusLedConfig), &payload).await?;
522        Ok(u8::from_le_byte_slice(result.body()))
523    }
524
525    /// Returns the temperature as measured inside the microcontroller. The
526    /// value returned is not the ambient temperature!
527    ///
528    /// The temperature is only proportional to the real temperature and it has bad
529    /// accuracy. Practically it is only useful as an indicator for
530    /// temperature changes.
531    pub async fn get_chip_temperature(&mut self) -> Result<i16, TinkerforgeError> {
532        let payload = [0; 0];
533
534        #[allow(unused_variables)]
535        let result = self.device.get(u8::from(IndustrialQuadRelayV2BrickletFunction::GetChipTemperature), &payload).await?;
536        Ok(i16::from_le_byte_slice(result.body()))
537    }
538
539    /// Calling this function will reset the Bricklet. All configurations
540    /// will be lost.
541    ///
542    /// After a reset you have to create new device objects,
543    /// calling functions on the existing ones will result in
544    /// undefined behavior!
545    pub async fn reset(&mut self) -> Result<(), TinkerforgeError> {
546        let payload = [0; 0];
547
548        #[allow(unused_variables)]
549        let result = self.device.set(u8::from(IndustrialQuadRelayV2BrickletFunction::Reset), &payload).await?;
550        Ok(())
551    }
552
553    /// Writes a new UID into flash. If you want to set a new UID
554    /// you have to decode the Base58 encoded UID string into an
555    /// integer first.
556    ///
557    /// We recommend that you use Brick Viewer to change the UID.
558    pub async fn write_uid(&mut self, uid: u32) -> Result<(), TinkerforgeError> {
559        let mut payload = [0; 4];
560        uid.write_to_slice(&mut payload[0..4]);
561
562        #[allow(unused_variables)]
563        let result = self.device.set(u8::from(IndustrialQuadRelayV2BrickletFunction::WriteUid), &payload).await?;
564        Ok(())
565    }
566
567    /// Returns the current UID as an integer. Encode as
568    /// Base58 to get the usual string version.
569    pub async fn read_uid(&mut self) -> Result<u32, TinkerforgeError> {
570        let payload = [0; 0];
571
572        #[allow(unused_variables)]
573        let result = self.device.get(u8::from(IndustrialQuadRelayV2BrickletFunction::ReadUid), &payload).await?;
574        Ok(u32::from_le_byte_slice(result.body()))
575    }
576
577    /// Returns the UID, the UID where the Bricklet is connected to,
578    /// the position, the hardware and firmware version as well as the
579    /// device identifier.
580    ///
581    /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
582    /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
583    /// position 'z'.
584    ///
585    /// The device identifier numbers can be found [here](device_identifier).
586    /// |device_identifier_constant|
587    pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
588        let payload = [0; 0];
589
590        #[allow(unused_variables)]
591        let result = self.device.get(u8::from(IndustrialQuadRelayV2BrickletFunction::GetIdentity), &payload).await?;
592        Ok(Identity::from_le_byte_slice(result.body()))
593    }
594}