tinkerforge_async/bindings/
industrial_dual_ac_in_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//! 2 inputs that can detect AC voltages of up to 230V.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/IndustrialDualACIn_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 IndustrialDualAcInBrickletFunction {
24    GetValue,
25    SetValueCallbackConfiguration,
26    GetValueCallbackConfiguration,
27    SetAllValueCallbackConfiguration,
28    GetAllValueCallbackConfiguration,
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    CallbackValue,
44    CallbackAllValue,
45}
46impl From<IndustrialDualAcInBrickletFunction> for u8 {
47    fn from(fun: IndustrialDualAcInBrickletFunction) -> Self {
48        match fun {
49            IndustrialDualAcInBrickletFunction::GetValue => 1,
50            IndustrialDualAcInBrickletFunction::SetValueCallbackConfiguration => 2,
51            IndustrialDualAcInBrickletFunction::GetValueCallbackConfiguration => 3,
52            IndustrialDualAcInBrickletFunction::SetAllValueCallbackConfiguration => 4,
53            IndustrialDualAcInBrickletFunction::GetAllValueCallbackConfiguration => 5,
54            IndustrialDualAcInBrickletFunction::SetChannelLedConfig => 6,
55            IndustrialDualAcInBrickletFunction::GetChannelLedConfig => 7,
56            IndustrialDualAcInBrickletFunction::GetSpitfpErrorCount => 234,
57            IndustrialDualAcInBrickletFunction::SetBootloaderMode => 235,
58            IndustrialDualAcInBrickletFunction::GetBootloaderMode => 236,
59            IndustrialDualAcInBrickletFunction::SetWriteFirmwarePointer => 237,
60            IndustrialDualAcInBrickletFunction::WriteFirmware => 238,
61            IndustrialDualAcInBrickletFunction::SetStatusLedConfig => 239,
62            IndustrialDualAcInBrickletFunction::GetStatusLedConfig => 240,
63            IndustrialDualAcInBrickletFunction::GetChipTemperature => 242,
64            IndustrialDualAcInBrickletFunction::Reset => 243,
65            IndustrialDualAcInBrickletFunction::WriteUid => 248,
66            IndustrialDualAcInBrickletFunction::ReadUid => 249,
67            IndustrialDualAcInBrickletFunction::GetIdentity => 255,
68            IndustrialDualAcInBrickletFunction::CallbackValue => 8,
69            IndustrialDualAcInBrickletFunction::CallbackAllValue => 9,
70        }
71    }
72}
73pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_0: u8 = 0;
74pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_1: u8 = 1;
75pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_LED_CONFIG_OFF: u8 = 0;
76pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_LED_CONFIG_ON: u8 = 1;
77pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
78pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_LED_CONFIG_SHOW_CHANNEL_STATUS: u8 = 3;
79pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_MODE_BOOTLOADER: u8 = 0;
80pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_MODE_FIRMWARE: u8 = 1;
81pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT: u8 = 2;
82pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT: u8 = 3;
83pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT: u8 = 4;
84pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_STATUS_OK: u8 = 0;
85pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE: u8 = 1;
86pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE: u8 = 2;
87pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT: u8 = 3;
88pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT: u8 = 4;
89pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH: u8 = 5;
90pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_STATUS_LED_CONFIG_OFF: u8 = 0;
91pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_STATUS_LED_CONFIG_ON: u8 = 1;
92pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT: u8 = 2;
93pub const INDUSTRIAL_DUAL_AC_IN_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS: u8 = 3;
94
95#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
96pub struct ValueCallbackConfiguration {
97    pub period: u32,
98    pub value_has_to_change: bool,
99}
100impl FromByteSlice for ValueCallbackConfiguration {
101    fn bytes_expected() -> usize {
102        5
103    }
104    fn from_le_byte_slice(bytes: &[u8]) -> ValueCallbackConfiguration {
105        ValueCallbackConfiguration {
106            period: <u32>::from_le_byte_slice(&bytes[0..4]),
107            value_has_to_change: <bool>::from_le_byte_slice(&bytes[4..5]),
108        }
109    }
110}
111
112#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
113pub struct AllValueCallbackConfiguration {
114    pub period: u32,
115    pub value_has_to_change: bool,
116}
117impl FromByteSlice for AllValueCallbackConfiguration {
118    fn bytes_expected() -> usize {
119        5
120    }
121    fn from_le_byte_slice(bytes: &[u8]) -> AllValueCallbackConfiguration {
122        AllValueCallbackConfiguration {
123            period: <u32>::from_le_byte_slice(&bytes[0..4]),
124            value_has_to_change: <bool>::from_le_byte_slice(&bytes[4..5]),
125        }
126    }
127}
128
129#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
130pub struct ValueEvent {
131    pub channel: u8,
132    pub changed: bool,
133    pub value: bool,
134}
135impl FromByteSlice for ValueEvent {
136    fn bytes_expected() -> usize {
137        3
138    }
139    fn from_le_byte_slice(bytes: &[u8]) -> ValueEvent {
140        ValueEvent {
141            channel: <u8>::from_le_byte_slice(&bytes[0..1]),
142            changed: <bool>::from_le_byte_slice(&bytes[1..2]),
143            value: <bool>::from_le_byte_slice(&bytes[2..3]),
144        }
145    }
146}
147
148#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
149pub struct AllValueEvent {
150    pub changed: [bool; 2],
151    pub value: [bool; 2],
152}
153impl FromByteSlice for AllValueEvent {
154    fn bytes_expected() -> usize {
155        2
156    }
157    fn from_le_byte_slice(bytes: &[u8]) -> AllValueEvent {
158        AllValueEvent { changed: <[bool; 2]>::from_le_byte_slice(&bytes[0..1]), value: <[bool; 2]>::from_le_byte_slice(&bytes[1..2]) }
159    }
160}
161
162#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
163pub struct SpitfpErrorCount {
164    pub error_count_ack_checksum: u32,
165    pub error_count_message_checksum: u32,
166    pub error_count_frame: u32,
167    pub error_count_overflow: u32,
168}
169impl FromByteSlice for SpitfpErrorCount {
170    fn bytes_expected() -> usize {
171        16
172    }
173    fn from_le_byte_slice(bytes: &[u8]) -> SpitfpErrorCount {
174        SpitfpErrorCount {
175            error_count_ack_checksum: <u32>::from_le_byte_slice(&bytes[0..4]),
176            error_count_message_checksum: <u32>::from_le_byte_slice(&bytes[4..8]),
177            error_count_frame: <u32>::from_le_byte_slice(&bytes[8..12]),
178            error_count_overflow: <u32>::from_le_byte_slice(&bytes[12..16]),
179        }
180    }
181}
182
183#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
184pub struct Identity {
185    pub uid: String,
186    pub connected_uid: String,
187    pub position: char,
188    pub hardware_version: [u8; 3],
189    pub firmware_version: [u8; 3],
190    pub device_identifier: u16,
191}
192impl FromByteSlice for Identity {
193    fn bytes_expected() -> usize {
194        25
195    }
196    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
197        Identity {
198            uid: <String>::from_le_byte_slice(&bytes[0..8]),
199            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
200            position: <char>::from_le_byte_slice(&bytes[16..17]),
201            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
202            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
203            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
204        }
205    }
206}
207
208/// 2 inputs that can detect AC voltages of up to 230V
209#[derive(Clone)]
210pub struct IndustrialDualAcInBricklet {
211    device: Device,
212}
213impl IndustrialDualAcInBricklet {
214    pub const DEVICE_IDENTIFIER: u16 = 2174;
215    pub const DEVICE_DISPLAY_NAME: &'static str = "Industrial Dual AC In Bricklet";
216    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
217    pub fn new(uid: Uid, connection: AsyncIpConnection) -> IndustrialDualAcInBricklet {
218        let mut result = IndustrialDualAcInBricklet { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
219        result.device.response_expected[u8::from(IndustrialDualAcInBrickletFunction::GetValue) as usize] = ResponseExpectedFlag::AlwaysTrue;
220        result.device.response_expected[u8::from(IndustrialDualAcInBrickletFunction::SetValueCallbackConfiguration) as usize] =
221            ResponseExpectedFlag::True;
222        result.device.response_expected[u8::from(IndustrialDualAcInBrickletFunction::GetValueCallbackConfiguration) as usize] =
223            ResponseExpectedFlag::AlwaysTrue;
224        result.device.response_expected[u8::from(IndustrialDualAcInBrickletFunction::SetAllValueCallbackConfiguration) as usize] =
225            ResponseExpectedFlag::True;
226        result.device.response_expected[u8::from(IndustrialDualAcInBrickletFunction::GetAllValueCallbackConfiguration) as usize] =
227            ResponseExpectedFlag::AlwaysTrue;
228        result.device.response_expected[u8::from(IndustrialDualAcInBrickletFunction::SetChannelLedConfig) as usize] =
229            ResponseExpectedFlag::False;
230        result.device.response_expected[u8::from(IndustrialDualAcInBrickletFunction::GetChannelLedConfig) as usize] =
231            ResponseExpectedFlag::AlwaysTrue;
232        result.device.response_expected[u8::from(IndustrialDualAcInBrickletFunction::GetSpitfpErrorCount) as usize] =
233            ResponseExpectedFlag::AlwaysTrue;
234        result.device.response_expected[u8::from(IndustrialDualAcInBrickletFunction::SetBootloaderMode) as usize] =
235            ResponseExpectedFlag::AlwaysTrue;
236        result.device.response_expected[u8::from(IndustrialDualAcInBrickletFunction::GetBootloaderMode) as usize] =
237            ResponseExpectedFlag::AlwaysTrue;
238        result.device.response_expected[u8::from(IndustrialDualAcInBrickletFunction::SetWriteFirmwarePointer) as usize] =
239            ResponseExpectedFlag::False;
240        result.device.response_expected[u8::from(IndustrialDualAcInBrickletFunction::WriteFirmware) as usize] =
241            ResponseExpectedFlag::AlwaysTrue;
242        result.device.response_expected[u8::from(IndustrialDualAcInBrickletFunction::SetStatusLedConfig) as usize] =
243            ResponseExpectedFlag::False;
244        result.device.response_expected[u8::from(IndustrialDualAcInBrickletFunction::GetStatusLedConfig) as usize] =
245            ResponseExpectedFlag::AlwaysTrue;
246        result.device.response_expected[u8::from(IndustrialDualAcInBrickletFunction::GetChipTemperature) as usize] =
247            ResponseExpectedFlag::AlwaysTrue;
248        result.device.response_expected[u8::from(IndustrialDualAcInBrickletFunction::Reset) as usize] = ResponseExpectedFlag::False;
249        result.device.response_expected[u8::from(IndustrialDualAcInBrickletFunction::WriteUid) as usize] = ResponseExpectedFlag::False;
250        result.device.response_expected[u8::from(IndustrialDualAcInBrickletFunction::ReadUid) as usize] = ResponseExpectedFlag::AlwaysTrue;
251        result.device.response_expected[u8::from(IndustrialDualAcInBrickletFunction::GetIdentity) as usize] =
252            ResponseExpectedFlag::AlwaysTrue;
253        result
254    }
255
256    /// Returns the response expected flag for the function specified by the function ID parameter.
257    /// It is true if the function is expected to send a response, false otherwise.
258    ///
259    /// For getter functions this is enabled by default and cannot be disabled, because those
260    /// functions will always send a response. For callback configuration functions it is enabled
261    /// by default too, but can be disabled by [`set_response_expected`](crate::industrial_dual_ac_in_bricklet::IndustrialDualAcInBricklet::set_response_expected).
262    /// For setter functions it is disabled by default and can be enabled.
263    ///
264    /// Enabling the response expected flag for a setter function allows to detect timeouts
265    /// and other error conditions calls of this setter as well. The device will then send a response
266    /// for this purpose. If this flag is disabled for a setter function then no response is sent
267    /// and errors are silently ignored, because they cannot be detected.
268    ///
269    /// See [`set_response_expected`](crate::industrial_dual_ac_in_bricklet::IndustrialDualAcInBricklet::set_response_expected) for the list of function ID constants available for this function.
270    pub fn get_response_expected(&mut self, fun: IndustrialDualAcInBrickletFunction) -> Result<bool, GetResponseExpectedError> {
271        self.device.get_response_expected(u8::from(fun))
272    }
273
274    /// Changes the response expected flag of the function specified by the function ID parameter.
275    /// This flag can only be changed for setter (default value: false) and callback configuration
276    /// functions (default value: true). For getter functions it is always enabled.
277    ///
278    /// Enabling the response expected flag for a setter function allows to detect timeouts and
279    /// other error conditions calls of this setter as well. The device will then send a response
280    /// for this purpose. If this flag is disabled for a setter function then no response is sent
281    /// and errors are silently ignored, because they cannot be detected.
282    pub fn set_response_expected(
283        &mut self,
284        fun: IndustrialDualAcInBrickletFunction,
285        response_expected: bool,
286    ) -> Result<(), SetResponseExpectedError> {
287        self.device.set_response_expected(u8::from(fun), response_expected)
288    }
289
290    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
291    pub fn set_response_expected_all(&mut self, response_expected: bool) {
292        self.device.set_response_expected_all(response_expected)
293    }
294
295    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
296    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
297    pub fn get_api_version(&self) -> [u8; 3] {
298        self.device.api_version
299    }
300
301    /// This receiver is triggered periodically according to the configuration set by
302    /// [`set_value_callback_configuration`].
303    ///
304    /// The parameters are the channel, a value-changed indicator and the actual
305    /// value for the channel. The `changed` parameter is true if the value has changed
306    /// since the last receiver.
307    ///
308    /// [`set_value_callback_configuration`]: #method.set_value_callback_configuration
309    pub async fn get_value_callback_receiver(&mut self) -> impl Stream<Item = ValueEvent> {
310        self.device
311            .get_callback_receiver(u8::from(IndustrialDualAcInBrickletFunction::CallbackValue))
312            .await
313            .map(|p| ValueEvent::from_le_byte_slice(p.body()))
314    }
315
316    /// This receiver is triggered periodically according to the configuration set by
317    /// [`set_all_value_callback_configuration`].
318    ///
319    /// The parameters are the same as [`get_value`]. Additional the
320    /// `changed` parameter is true if the value has changed since
321    /// the last receiver.
322    pub async fn get_all_value_callback_receiver(&mut self) -> impl Stream<Item = AllValueEvent> {
323        self.device
324            .get_callback_receiver(u8::from(IndustrialDualAcInBrickletFunction::CallbackAllValue))
325            .await
326            .map(|p| AllValueEvent::from_le_byte_slice(p.body()))
327    }
328
329    /// Returns the input values as bools, *true* refers to AC voltage detected and *false* refers to no AC voltage detected.
330    pub async fn get_value(&mut self) -> Result<Box<[bool; 2]>, TinkerforgeError> {
331        let payload = [0; 0];
332
333        #[allow(unused_variables)]
334        let result = self.device.get(u8::from(IndustrialDualAcInBrickletFunction::GetValue), &payload).await?;
335        Ok(Box::<[bool; 2]>::from_le_byte_slice(result.body()))
336    }
337
338    /// This receiver can be configured per channel.
339    ///
340    /// The period is the period with which the [`get_value_callback_receiver`]
341    /// receiver is triggered periodically. A value of 0 turns the receiver off.
342    ///
343    /// If the `value has to change`-parameter is set to true, the receiver is only
344    /// triggered after the value has changed. If the value didn't change within the
345    /// period, the receiver is triggered immediately on change.
346    ///
347    /// If it is set to false, the receiver is continuously triggered with the period,
348    /// independent of the value.
349    ///
350    /// Associated constants:
351    /// * INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_0
352    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_1
353    pub async fn set_value_callback_configuration(
354        &mut self,
355        channel: u8,
356        period: u32,
357        value_has_to_change: bool,
358    ) -> Result<(), TinkerforgeError> {
359        let mut payload = [0; 6];
360        channel.write_to_slice(&mut payload[0..1]);
361        period.write_to_slice(&mut payload[1..5]);
362        value_has_to_change.write_to_slice(&mut payload[5..6]);
363
364        #[allow(unused_variables)]
365        let result = self.device.set(u8::from(IndustrialDualAcInBrickletFunction::SetValueCallbackConfiguration), &payload).await?;
366        Ok(())
367    }
368
369    /// Returns the receiver configuration for the given channel as set by
370    /// [`set_value_callback_configuration`].
371    ///
372    /// Associated constants:
373    /// * INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_0
374    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_1
375    pub async fn get_value_callback_configuration(&mut self, channel: u8) -> Result<ValueCallbackConfiguration, TinkerforgeError> {
376        let mut payload = [0; 1];
377        channel.write_to_slice(&mut payload[0..1]);
378
379        #[allow(unused_variables)]
380        let result = self.device.get(u8::from(IndustrialDualAcInBrickletFunction::GetValueCallbackConfiguration), &payload).await?;
381        Ok(ValueCallbackConfiguration::from_le_byte_slice(result.body()))
382    }
383
384    /// The period is the period with which the [`get_all_value_callback_receiver`]
385    /// receiver is triggered periodically. A value of 0 turns the receiver off.
386    ///
387    /// If the `value has to change`-parameter is set to true, the receiver is only
388    /// triggered after the value has changed. If the value didn't change within the
389    /// period, the receiver is triggered immediately on change.
390    ///
391    /// If it is set to false, the receiver is continuously triggered with the period,
392    /// independent of the value.
393    pub async fn set_all_value_callback_configuration(&mut self, period: u32, value_has_to_change: bool) -> Result<(), TinkerforgeError> {
394        let mut payload = [0; 5];
395        period.write_to_slice(&mut payload[0..4]);
396        value_has_to_change.write_to_slice(&mut payload[4..5]);
397
398        #[allow(unused_variables)]
399        let result = self.device.set(u8::from(IndustrialDualAcInBrickletFunction::SetAllValueCallbackConfiguration), &payload).await?;
400        Ok(())
401    }
402
403    /// Returns the receiver configuration as set by
404    /// [`set_all_value_callback_configuration`].
405    pub async fn get_all_value_callback_configuration(&mut self) -> Result<AllValueCallbackConfiguration, TinkerforgeError> {
406        let payload = [0; 0];
407
408        #[allow(unused_variables)]
409        let result = self.device.get(u8::from(IndustrialDualAcInBrickletFunction::GetAllValueCallbackConfiguration), &payload).await?;
410        Ok(AllValueCallbackConfiguration::from_le_byte_slice(result.body()))
411    }
412
413    /// Each channel has a corresponding LED. You can turn the LED off, on or show a
414    /// heartbeat. You can also set the LED to Channel Status. In this mode the
415    /// LED is on if the channel is high and off otherwise.
416    ///
417    /// By default all channel LEDs are configured as Channel Status.
418    ///
419    /// Associated constants:
420    /// * INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_0
421    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_1
422    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_LED_CONFIG_OFF
423    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_LED_CONFIG_ON
424    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_LED_CONFIG_SHOW_HEARTBEAT
425    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_LED_CONFIG_SHOW_CHANNEL_STATUS
426    pub async fn set_channel_led_config(&mut self, channel: u8, config: u8) -> Result<(), TinkerforgeError> {
427        let mut payload = [0; 2];
428        channel.write_to_slice(&mut payload[0..1]);
429        config.write_to_slice(&mut payload[1..2]);
430
431        #[allow(unused_variables)]
432        let result = self.device.set(u8::from(IndustrialDualAcInBrickletFunction::SetChannelLedConfig), &payload).await?;
433        Ok(())
434    }
435
436    /// Returns the channel LED configuration as set by [`set_channel_led_config`]
437    ///
438    /// Associated constants:
439    /// * INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_0
440    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_1
441    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_LED_CONFIG_OFF
442    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_LED_CONFIG_ON
443    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_LED_CONFIG_SHOW_HEARTBEAT
444    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_CHANNEL_LED_CONFIG_SHOW_CHANNEL_STATUS
445    pub async fn get_channel_led_config(&mut self, channel: u8) -> Result<u8, TinkerforgeError> {
446        let mut payload = [0; 1];
447        channel.write_to_slice(&mut payload[0..1]);
448
449        #[allow(unused_variables)]
450        let result = self.device.get(u8::from(IndustrialDualAcInBrickletFunction::GetChannelLedConfig), &payload).await?;
451        Ok(u8::from_le_byte_slice(result.body()))
452    }
453
454    /// Returns the error count for the communication between Brick and Bricklet.
455    ///
456    /// The errors are divided into
457    ///
458    /// * ACK checksum errors,
459    /// * message checksum errors,
460    /// * framing errors and
461    /// * overflow errors.
462    ///
463    /// The errors counts are for errors that occur on the Bricklet side. All
464    /// Bricks have a similar function that returns the errors on the Brick side.
465    pub async fn get_spitfp_error_count(&mut self) -> Result<SpitfpErrorCount, TinkerforgeError> {
466        let payload = [0; 0];
467
468        #[allow(unused_variables)]
469        let result = self.device.get(u8::from(IndustrialDualAcInBrickletFunction::GetSpitfpErrorCount), &payload).await?;
470        Ok(SpitfpErrorCount::from_le_byte_slice(result.body()))
471    }
472
473    /// Sets the bootloader mode and returns the status after the requested
474    /// mode change was instigated.
475    ///
476    /// You can change from bootloader mode to firmware mode and vice versa. A change
477    /// from bootloader mode to firmware mode will only take place if the entry function,
478    /// device identifier and CRC are present and correct.
479    ///
480    /// This function is used by Brick Viewer during flashing. It should not be
481    /// necessary to call it in a normal user program.
482    ///
483    /// Associated constants:
484    /// * INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
485    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_MODE_FIRMWARE
486    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
487    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
488    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
489    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_STATUS_OK
490    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_STATUS_INVALID_MODE
491    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_STATUS_NO_CHANGE
492    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT
493    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT
494    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_STATUS_CRC_MISMATCH
495    pub async fn set_bootloader_mode(&mut self, mode: u8) -> Result<u8, TinkerforgeError> {
496        let mut payload = [0; 1];
497        mode.write_to_slice(&mut payload[0..1]);
498
499        #[allow(unused_variables)]
500        let result = self.device.get(u8::from(IndustrialDualAcInBrickletFunction::SetBootloaderMode), &payload).await?;
501        Ok(u8::from_le_byte_slice(result.body()))
502    }
503
504    /// Returns the current bootloader mode, see [`set_bootloader_mode`].
505    ///
506    /// Associated constants:
507    /// * INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_MODE_BOOTLOADER
508    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_MODE_FIRMWARE
509    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT
510    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT
511    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT
512    pub async fn get_bootloader_mode(&mut self) -> Result<u8, TinkerforgeError> {
513        let payload = [0; 0];
514
515        #[allow(unused_variables)]
516        let result = self.device.get(u8::from(IndustrialDualAcInBrickletFunction::GetBootloaderMode), &payload).await?;
517        Ok(u8::from_le_byte_slice(result.body()))
518    }
519
520    /// Sets the firmware pointer for [`write_firmware`]. The pointer has
521    /// to be increased by chunks of size 64. The data is written to flash
522    /// every 4 chunks (which equals to one page of size 256).
523    ///
524    /// This function is used by Brick Viewer during flashing. It should not be
525    /// necessary to call it in a normal user program.
526    pub async fn set_write_firmware_pointer(&mut self, pointer: u32) -> Result<(), TinkerforgeError> {
527        let mut payload = [0; 4];
528        pointer.write_to_slice(&mut payload[0..4]);
529
530        #[allow(unused_variables)]
531        let result = self.device.set(u8::from(IndustrialDualAcInBrickletFunction::SetWriteFirmwarePointer), &payload).await?;
532        Ok(())
533    }
534
535    /// Writes 64 Bytes of firmware at the position as written by
536    /// [`set_write_firmware_pointer`] before. The firmware is written
537    /// to flash every 4 chunks.
538    ///
539    /// You can only write firmware in bootloader mode.
540    ///
541    /// This function is used by Brick Viewer during flashing. It should not be
542    /// necessary to call it in a normal user program.
543    pub async fn write_firmware(&mut self, data: &[u8; 64]) -> Result<u8, TinkerforgeError> {
544        let mut payload = [0; 64];
545        data.write_to_slice(&mut payload[0..64]);
546
547        #[allow(unused_variables)]
548        let result = self.device.get(u8::from(IndustrialDualAcInBrickletFunction::WriteFirmware), &payload).await?;
549        Ok(u8::from_le_byte_slice(result.body()))
550    }
551
552    /// Sets the status LED configuration. By default the LED shows
553    /// communication traffic between Brick and Bricklet, it flickers once
554    /// for every 10 received data packets.
555    ///
556    /// You can also turn the LED permanently on/off or show a heartbeat.
557    ///
558    /// If the Bricklet is in bootloader mode, the LED is will show heartbeat by default.
559    ///
560    /// Associated constants:
561    /// * INDUSTRIAL_DUAL_AC_IN_BRICKLET_STATUS_LED_CONFIG_OFF
562    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_STATUS_LED_CONFIG_ON
563    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
564    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
565    pub async fn set_status_led_config(&mut self, config: u8) -> Result<(), TinkerforgeError> {
566        let mut payload = [0; 1];
567        config.write_to_slice(&mut payload[0..1]);
568
569        #[allow(unused_variables)]
570        let result = self.device.set(u8::from(IndustrialDualAcInBrickletFunction::SetStatusLedConfig), &payload).await?;
571        Ok(())
572    }
573
574    /// Returns the configuration as set by [`set_status_led_config`]
575    ///
576    /// Associated constants:
577    /// * INDUSTRIAL_DUAL_AC_IN_BRICKLET_STATUS_LED_CONFIG_OFF
578    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_STATUS_LED_CONFIG_ON
579    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_STATUS_LED_CONFIG_SHOW_HEARTBEAT
580    ///	* INDUSTRIAL_DUAL_AC_IN_BRICKLET_STATUS_LED_CONFIG_SHOW_STATUS
581    pub async fn get_status_led_config(&mut self) -> Result<u8, TinkerforgeError> {
582        let payload = [0; 0];
583
584        #[allow(unused_variables)]
585        let result = self.device.get(u8::from(IndustrialDualAcInBrickletFunction::GetStatusLedConfig), &payload).await?;
586        Ok(u8::from_le_byte_slice(result.body()))
587    }
588
589    /// Returns the temperature as measured inside the microcontroller. The
590    /// value returned is not the ambient temperature!
591    ///
592    /// The temperature is only proportional to the real temperature and it has bad
593    /// accuracy. Practically it is only useful as an indicator for
594    /// temperature changes.
595    pub async fn get_chip_temperature(&mut self) -> Result<i16, TinkerforgeError> {
596        let payload = [0; 0];
597
598        #[allow(unused_variables)]
599        let result = self.device.get(u8::from(IndustrialDualAcInBrickletFunction::GetChipTemperature), &payload).await?;
600        Ok(i16::from_le_byte_slice(result.body()))
601    }
602
603    /// Calling this function will reset the Bricklet. All configurations
604    /// will be lost.
605    ///
606    /// After a reset you have to create new device objects,
607    /// calling functions on the existing ones will result in
608    /// undefined behavior!
609    pub async fn reset(&mut self) -> Result<(), TinkerforgeError> {
610        let payload = [0; 0];
611
612        #[allow(unused_variables)]
613        let result = self.device.set(u8::from(IndustrialDualAcInBrickletFunction::Reset), &payload).await?;
614        Ok(())
615    }
616
617    /// Writes a new UID into flash. If you want to set a new UID
618    /// you have to decode the Base58 encoded UID string into an
619    /// integer first.
620    ///
621    /// We recommend that you use Brick Viewer to change the UID.
622    pub async fn write_uid(&mut self, uid: u32) -> Result<(), TinkerforgeError> {
623        let mut payload = [0; 4];
624        uid.write_to_slice(&mut payload[0..4]);
625
626        #[allow(unused_variables)]
627        let result = self.device.set(u8::from(IndustrialDualAcInBrickletFunction::WriteUid), &payload).await?;
628        Ok(())
629    }
630
631    /// Returns the current UID as an integer. Encode as
632    /// Base58 to get the usual string version.
633    pub async fn read_uid(&mut self) -> Result<u32, TinkerforgeError> {
634        let payload = [0; 0];
635
636        #[allow(unused_variables)]
637        let result = self.device.get(u8::from(IndustrialDualAcInBrickletFunction::ReadUid), &payload).await?;
638        Ok(u32::from_le_byte_slice(result.body()))
639    }
640
641    /// Returns the UID, the UID where the Bricklet is connected to,
642    /// the position, the hardware and firmware version as well as the
643    /// device identifier.
644    ///
645    /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
646    /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
647    /// position 'z'.
648    ///
649    /// The device identifier numbers can be found [here](device_identifier).
650    /// |device_identifier_constant|
651    pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
652        let payload = [0; 0];
653
654        #[allow(unused_variables)]
655        let result = self.device.get(u8::from(IndustrialDualAcInBrickletFunction::GetIdentity), &payload).await?;
656        Ok(Identity::from_le_byte_slice(result.body()))
657    }
658}