tinkerforge_async/bindings/
io16_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//! 16-channel digital input/output.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/IO16_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 Io16BrickletFunction {
24    SetPort,
25    GetPort,
26    SetPortConfiguration,
27    GetPortConfiguration,
28    SetDebouncePeriod,
29    GetDebouncePeriod,
30    SetPortInterrupt,
31    GetPortInterrupt,
32    SetPortMonoflop,
33    GetPortMonoflop,
34    SetSelectedValues,
35    GetEdgeCount,
36    SetEdgeCountConfig,
37    GetEdgeCountConfig,
38    GetIdentity,
39    CallbackInterrupt,
40    CallbackMonoflopDone,
41}
42impl From<Io16BrickletFunction> for u8 {
43    fn from(fun: Io16BrickletFunction) -> Self {
44        match fun {
45            Io16BrickletFunction::SetPort => 1,
46            Io16BrickletFunction::GetPort => 2,
47            Io16BrickletFunction::SetPortConfiguration => 3,
48            Io16BrickletFunction::GetPortConfiguration => 4,
49            Io16BrickletFunction::SetDebouncePeriod => 5,
50            Io16BrickletFunction::GetDebouncePeriod => 6,
51            Io16BrickletFunction::SetPortInterrupt => 7,
52            Io16BrickletFunction::GetPortInterrupt => 8,
53            Io16BrickletFunction::SetPortMonoflop => 10,
54            Io16BrickletFunction::GetPortMonoflop => 11,
55            Io16BrickletFunction::SetSelectedValues => 13,
56            Io16BrickletFunction::GetEdgeCount => 14,
57            Io16BrickletFunction::SetEdgeCountConfig => 15,
58            Io16BrickletFunction::GetEdgeCountConfig => 16,
59            Io16BrickletFunction::GetIdentity => 255,
60            Io16BrickletFunction::CallbackInterrupt => 9,
61            Io16BrickletFunction::CallbackMonoflopDone => 12,
62        }
63    }
64}
65pub const IO16_BRICKLET_DIRECTION_IN: char = 'i';
66pub const IO16_BRICKLET_DIRECTION_OUT: char = 'o';
67pub const IO16_BRICKLET_EDGE_TYPE_RISING: u8 = 0;
68pub const IO16_BRICKLET_EDGE_TYPE_FALLING: u8 = 1;
69pub const IO16_BRICKLET_EDGE_TYPE_BOTH: u8 = 2;
70
71#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
72pub struct PortConfiguration {
73    pub direction_mask: u8,
74    pub value_mask: u8,
75}
76impl FromByteSlice for PortConfiguration {
77    fn bytes_expected() -> usize {
78        2
79    }
80    fn from_le_byte_slice(bytes: &[u8]) -> PortConfiguration {
81        PortConfiguration { direction_mask: <u8>::from_le_byte_slice(&bytes[0..1]), value_mask: <u8>::from_le_byte_slice(&bytes[1..2]) }
82    }
83}
84
85#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
86pub struct InterruptEvent {
87    pub port: char,
88    pub interrupt_mask: u8,
89    pub value_mask: u8,
90}
91impl FromByteSlice for InterruptEvent {
92    fn bytes_expected() -> usize {
93        3
94    }
95    fn from_le_byte_slice(bytes: &[u8]) -> InterruptEvent {
96        InterruptEvent {
97            port: <char>::from_le_byte_slice(&bytes[0..1]),
98            interrupt_mask: <u8>::from_le_byte_slice(&bytes[1..2]),
99            value_mask: <u8>::from_le_byte_slice(&bytes[2..3]),
100        }
101    }
102}
103
104#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
105pub struct PortMonoflop {
106    pub value: u8,
107    pub time: u32,
108    pub time_remaining: u32,
109}
110impl FromByteSlice for PortMonoflop {
111    fn bytes_expected() -> usize {
112        9
113    }
114    fn from_le_byte_slice(bytes: &[u8]) -> PortMonoflop {
115        PortMonoflop {
116            value: <u8>::from_le_byte_slice(&bytes[0..1]),
117            time: <u32>::from_le_byte_slice(&bytes[1..5]),
118            time_remaining: <u32>::from_le_byte_slice(&bytes[5..9]),
119        }
120    }
121}
122
123#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
124pub struct MonoflopDoneEvent {
125    pub port: char,
126    pub selection_mask: u8,
127    pub value_mask: u8,
128}
129impl FromByteSlice for MonoflopDoneEvent {
130    fn bytes_expected() -> usize {
131        3
132    }
133    fn from_le_byte_slice(bytes: &[u8]) -> MonoflopDoneEvent {
134        MonoflopDoneEvent {
135            port: <char>::from_le_byte_slice(&bytes[0..1]),
136            selection_mask: <u8>::from_le_byte_slice(&bytes[1..2]),
137            value_mask: <u8>::from_le_byte_slice(&bytes[2..3]),
138        }
139    }
140}
141
142#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
143pub struct EdgeCountConfig {
144    pub edge_type: u8,
145    pub debounce: u8,
146}
147impl FromByteSlice for EdgeCountConfig {
148    fn bytes_expected() -> usize {
149        2
150    }
151    fn from_le_byte_slice(bytes: &[u8]) -> EdgeCountConfig {
152        EdgeCountConfig { edge_type: <u8>::from_le_byte_slice(&bytes[0..1]), debounce: <u8>::from_le_byte_slice(&bytes[1..2]) }
153    }
154}
155
156#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
157pub struct Identity {
158    pub uid: String,
159    pub connected_uid: String,
160    pub position: char,
161    pub hardware_version: [u8; 3],
162    pub firmware_version: [u8; 3],
163    pub device_identifier: u16,
164}
165impl FromByteSlice for Identity {
166    fn bytes_expected() -> usize {
167        25
168    }
169    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
170        Identity {
171            uid: <String>::from_le_byte_slice(&bytes[0..8]),
172            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
173            position: <char>::from_le_byte_slice(&bytes[16..17]),
174            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
175            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
176            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
177        }
178    }
179}
180
181/// 16-channel digital input/output
182#[derive(Clone)]
183pub struct Io16Bricklet {
184    device: Device,
185}
186impl Io16Bricklet {
187    pub const DEVICE_IDENTIFIER: u16 = 28;
188    pub const DEVICE_DISPLAY_NAME: &'static str = "IO-16 Bricklet";
189    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
190    pub fn new(uid: Uid, connection: AsyncIpConnection) -> Io16Bricklet {
191        let mut result = Io16Bricklet { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
192        result.device.response_expected[u8::from(Io16BrickletFunction::SetPort) as usize] = ResponseExpectedFlag::False;
193        result.device.response_expected[u8::from(Io16BrickletFunction::GetPort) as usize] = ResponseExpectedFlag::AlwaysTrue;
194        result.device.response_expected[u8::from(Io16BrickletFunction::SetPortConfiguration) as usize] = ResponseExpectedFlag::False;
195        result.device.response_expected[u8::from(Io16BrickletFunction::GetPortConfiguration) as usize] = ResponseExpectedFlag::AlwaysTrue;
196        result.device.response_expected[u8::from(Io16BrickletFunction::SetDebouncePeriod) as usize] = ResponseExpectedFlag::True;
197        result.device.response_expected[u8::from(Io16BrickletFunction::GetDebouncePeriod) as usize] = ResponseExpectedFlag::AlwaysTrue;
198        result.device.response_expected[u8::from(Io16BrickletFunction::SetPortInterrupt) as usize] = ResponseExpectedFlag::True;
199        result.device.response_expected[u8::from(Io16BrickletFunction::GetPortInterrupt) as usize] = ResponseExpectedFlag::AlwaysTrue;
200        result.device.response_expected[u8::from(Io16BrickletFunction::SetPortMonoflop) as usize] = ResponseExpectedFlag::False;
201        result.device.response_expected[u8::from(Io16BrickletFunction::GetPortMonoflop) as usize] = ResponseExpectedFlag::AlwaysTrue;
202        result.device.response_expected[u8::from(Io16BrickletFunction::SetSelectedValues) as usize] = ResponseExpectedFlag::False;
203        result.device.response_expected[u8::from(Io16BrickletFunction::GetEdgeCount) as usize] = ResponseExpectedFlag::AlwaysTrue;
204        result.device.response_expected[u8::from(Io16BrickletFunction::SetEdgeCountConfig) as usize] = ResponseExpectedFlag::False;
205        result.device.response_expected[u8::from(Io16BrickletFunction::GetEdgeCountConfig) as usize] = ResponseExpectedFlag::AlwaysTrue;
206        result.device.response_expected[u8::from(Io16BrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
207        result
208    }
209
210    /// Returns the response expected flag for the function specified by the function ID parameter.
211    /// It is true if the function is expected to send a response, false otherwise.
212    ///
213    /// For getter functions this is enabled by default and cannot be disabled, because those
214    /// functions will always send a response. For callback configuration functions it is enabled
215    /// by default too, but can be disabled by [`set_response_expected`](crate::io16_bricklet::Io16Bricklet::set_response_expected).
216    /// For setter functions it is disabled by default and can be enabled.
217    ///
218    /// Enabling the response expected flag for a setter function allows to detect timeouts
219    /// and other error conditions calls of this setter as well. The device will then send a response
220    /// for this purpose. If this flag is disabled for a setter function then no response is sent
221    /// and errors are silently ignored, because they cannot be detected.
222    ///
223    /// See [`set_response_expected`](crate::io16_bricklet::Io16Bricklet::set_response_expected) for the list of function ID constants available for this function.
224    pub fn get_response_expected(&mut self, fun: Io16BrickletFunction) -> Result<bool, GetResponseExpectedError> {
225        self.device.get_response_expected(u8::from(fun))
226    }
227
228    /// Changes the response expected flag of the function specified by the function ID parameter.
229    /// This flag can only be changed for setter (default value: false) and callback configuration
230    /// functions (default value: true). For getter functions it is always enabled.
231    ///
232    /// Enabling the response expected flag for a setter function allows to detect timeouts and
233    /// other error conditions calls of this setter as well. The device will then send a response
234    /// for this purpose. If this flag is disabled for a setter function then no response is sent
235    /// and errors are silently ignored, because they cannot be detected.
236    pub fn set_response_expected(&mut self, fun: Io16BrickletFunction, response_expected: bool) -> Result<(), SetResponseExpectedError> {
237        self.device.set_response_expected(u8::from(fun), response_expected)
238    }
239
240    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
241    pub fn set_response_expected_all(&mut self, response_expected: bool) {
242        self.device.set_response_expected_all(response_expected)
243    }
244
245    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
246    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
247    pub fn get_api_version(&self) -> [u8; 3] {
248        self.device.api_version
249    }
250
251    /// This receiver is triggered whenever a change of the voltage level is detected
252    /// on pins where the interrupt was activated with [`set_port_interrupt`].
253    ///
254    /// The values are the port, a bitmask that specifies which interrupts occurred
255    /// and the current value bitmask of the port.
256    ///
257    /// For example:
258    ///
259    /// * ('a', 1, 1) or ('a', 0b00000001, 0b00000001) means that on port A an
260    ///   interrupt on pin 0 occurred and currently pin 0 is high and pins 1-7 are low.
261    /// * ('b', 129, 254) or ('b', 0b10000001, 0b11111110) means that on port B
262    ///   interrupts on pins 0 and 7 occurred and currently pin 0 is low and pins 1-7
263    ///   are high.
264    ///
265    /// [`set_port_interrupt`]: #method.set_port_interrupt
266    pub async fn get_interrupt_callback_receiver(&mut self) -> impl Stream<Item = InterruptEvent> {
267        self.device
268            .get_callback_receiver(u8::from(Io16BrickletFunction::CallbackInterrupt))
269            .await
270            .map(|p| InterruptEvent::from_le_byte_slice(p.body()))
271    }
272
273    /// This receiver is triggered whenever a monoflop timer reaches 0. The
274    /// parameters contain the port, the involved pins and the current value of
275    /// the pins (the value after the monoflop).
276    pub async fn get_monoflop_done_callback_receiver(&mut self) -> impl Stream<Item = MonoflopDoneEvent> {
277        self.device
278            .get_callback_receiver(u8::from(Io16BrickletFunction::CallbackMonoflopDone))
279            .await
280            .map(|p| MonoflopDoneEvent::from_le_byte_slice(p.body()))
281    }
282
283    /// Sets the output value (high or low) for a port (a or b) with a bitmask
284    /// (8bit). A 1 in the bitmask means high and a 0 in the bitmask means low.
285    ///
286    /// For example: The value 15 or 0b00001111 will turn the pins 0-3 high and the
287    /// pins 4-7 low for the specified port.
288    ///
289    /// All running monoflop timers of the given port will be aborted if this function
290    /// is called.
291    ///
292    /// # Note
293    ///  This function does nothing for pins that are configured as input.
294    ///  Pull-up resistors can be switched on with [`set_port_configuration`].
295    pub async fn set_port(&mut self, port: char, value_mask: u8) -> Result<(), TinkerforgeError> {
296        let mut payload = [0; 2];
297        port.write_to_slice(&mut payload[0..1]);
298        value_mask.write_to_slice(&mut payload[1..2]);
299
300        #[allow(unused_variables)]
301        let result = self.device.set(u8::from(Io16BrickletFunction::SetPort), &payload).await?;
302        Ok(())
303    }
304
305    /// Returns a bitmask of the values that are currently measured on the
306    /// specified port. This function works if the pin is configured to input
307    /// as well as if it is configured to output.
308    pub async fn get_port(&mut self, port: char) -> Result<u8, TinkerforgeError> {
309        let mut payload = [0; 1];
310        port.write_to_slice(&mut payload[0..1]);
311
312        #[allow(unused_variables)]
313        let result = self.device.get(u8::from(Io16BrickletFunction::GetPort), &payload).await?;
314        Ok(u8::from_le_byte_slice(result.body()))
315    }
316
317    /// Configures the value and direction of a specified port. Possible directions
318    /// are 'i' and 'o' for input and output.
319    ///
320    /// If the direction is configured as output, the value is either high or low
321    /// (set as *true* or *false*).
322    ///
323    /// If the direction is configured as input, the value is either pull-up or
324    /// default (set as *true* or *false*).
325    ///
326    /// For example:
327    ///
328    /// * ('a', 255, 'i', true) or ('a', 0b11111111, 'i', true) will set all pins of port A as input pull-up.
329    /// * ('a', 128, 'i', false) or ('a', 0b10000000, 'i', false) will set pin 7 of port A as input default (floating if nothing is connected).
330    /// * ('b', 3, 'o', false) or ('b', 0b00000011, 'o', false) will set pins 0 and 1 of port B as output low.
331    /// * ('b', 4, 'o', true) or ('b', 0b00000100, 'o', true) will set pin 2 of port B as output high.
332    ///
333    /// Running monoflop timers for the selected pins will be aborted if this
334    /// function is called.
335    ///
336    /// Associated constants:
337    /// * IO16_BRICKLET_DIRECTION_IN
338    ///	* IO16_BRICKLET_DIRECTION_OUT
339    pub async fn set_port_configuration(
340        &mut self,
341        port: char,
342        selection_mask: u8,
343        direction: char,
344        value: bool,
345    ) -> Result<(), TinkerforgeError> {
346        let mut payload = [0; 4];
347        port.write_to_slice(&mut payload[0..1]);
348        selection_mask.write_to_slice(&mut payload[1..2]);
349        direction.write_to_slice(&mut payload[2..3]);
350        value.write_to_slice(&mut payload[3..4]);
351
352        #[allow(unused_variables)]
353        let result = self.device.set(u8::from(Io16BrickletFunction::SetPortConfiguration), &payload).await?;
354        Ok(())
355    }
356
357    /// Returns a direction bitmask and a value bitmask for the specified port. A 1 in
358    /// the direction bitmask means input and a 0 in the bitmask means output.
359    ///
360    /// For example: A return value of (15, 51) or (0b00001111, 0b00110011) for
361    /// direction and value means that:
362    ///
363    /// * pins 0 and 1 are configured as input pull-up,
364    /// * pins 2 and 3 are configured as input default,
365    /// * pins 4 and 5 are configured as output high
366    /// * and pins 6 and 7 are configured as output low.
367    pub async fn get_port_configuration(&mut self, port: char) -> Result<PortConfiguration, TinkerforgeError> {
368        let mut payload = [0; 1];
369        port.write_to_slice(&mut payload[0..1]);
370
371        #[allow(unused_variables)]
372        let result = self.device.get(u8::from(Io16BrickletFunction::GetPortConfiguration), &payload).await?;
373        Ok(PortConfiguration::from_le_byte_slice(result.body()))
374    }
375
376    /// Sets the debounce period of the [`get_interrupt_callback_receiver`] receiver.
377    ///
378    /// For example: If you set this value to 100, you will get the interrupt
379    /// maximal every 100ms. This is necessary if something that bounces is
380    /// connected to the IO-16 Bricklet, such as a button.
381    pub async fn set_debounce_period(&mut self, debounce: u32) -> Result<(), TinkerforgeError> {
382        let mut payload = [0; 4];
383        debounce.write_to_slice(&mut payload[0..4]);
384
385        #[allow(unused_variables)]
386        let result = self.device.set(u8::from(Io16BrickletFunction::SetDebouncePeriod), &payload).await?;
387        Ok(())
388    }
389
390    /// Returns the debounce period as set by [`set_debounce_period`].
391    pub async fn get_debounce_period(&mut self) -> Result<u32, TinkerforgeError> {
392        let payload = [0; 0];
393
394        #[allow(unused_variables)]
395        let result = self.device.get(u8::from(Io16BrickletFunction::GetDebouncePeriod), &payload).await?;
396        Ok(u32::from_le_byte_slice(result.body()))
397    }
398
399    /// Sets the pins on which an interrupt is activated with a bitmask.
400    /// Interrupts are triggered on changes of the voltage level of the pin,
401    /// i.e. changes from high to low and low to high.
402    ///
403    /// For example: ('a', 129) or ('a', 0b10000001) will enable the interrupt for
404    /// pins 0 and 7 of port a.
405    ///
406    /// The interrupt is delivered with the [`get_interrupt_callback_receiver`] receiver.
407    pub async fn set_port_interrupt(&mut self, port: char, interrupt_mask: u8) -> Result<(), TinkerforgeError> {
408        let mut payload = [0; 2];
409        port.write_to_slice(&mut payload[0..1]);
410        interrupt_mask.write_to_slice(&mut payload[1..2]);
411
412        #[allow(unused_variables)]
413        let result = self.device.set(u8::from(Io16BrickletFunction::SetPortInterrupt), &payload).await?;
414        Ok(())
415    }
416
417    /// Returns the interrupt bitmask for the specified port as set by
418    /// [`set_port_interrupt`].
419    pub async fn get_port_interrupt(&mut self, port: char) -> Result<u8, TinkerforgeError> {
420        let mut payload = [0; 1];
421        port.write_to_slice(&mut payload[0..1]);
422
423        #[allow(unused_variables)]
424        let result = self.device.get(u8::from(Io16BrickletFunction::GetPortInterrupt), &payload).await?;
425        Ok(u8::from_le_byte_slice(result.body()))
426    }
427
428    /// Configures a monoflop of the pins specified by the second parameter as 8 bit
429    /// long bitmask. The specified pins must be configured for output. Non-output
430    /// pins will be ignored.
431    ///
432    /// The third parameter is a bitmask with the desired value of the specified
433    /// output pins. A 1 in the bitmask means high and a 0 in the bitmask means low.
434    ///
435    /// The forth parameter indicates the time that the pins should hold
436    /// the value.
437    ///
438    /// If this function is called with the parameters ('a', 9, 1, 1500) or
439    /// ('a', 0b00001001, 0b00000001, 1500): Pin 0 will get high and pin 3 will get
440    /// low on port 'a'. In 1.5s pin 0 will get low and pin 3 will get high again.
441    ///
442    /// A monoflop can be used as a fail-safe mechanism. For example: Lets assume you
443    /// have a RS485 bus and an IO-16 Bricklet connected to one of the slave
444    /// stacks. You can now call this function every second, with a time parameter
445    /// of two seconds and pin 0 set to high. Pin 0 will be high all the time. If now
446    /// the RS485 connection is lost, then pin 0 will get low in at most two seconds.
447    pub async fn set_port_monoflop(&mut self, port: char, selection_mask: u8, value_mask: u8, time: u32) -> Result<(), TinkerforgeError> {
448        let mut payload = [0; 7];
449        port.write_to_slice(&mut payload[0..1]);
450        selection_mask.write_to_slice(&mut payload[1..2]);
451        value_mask.write_to_slice(&mut payload[2..3]);
452        time.write_to_slice(&mut payload[3..7]);
453
454        #[allow(unused_variables)]
455        let result = self.device.set(u8::from(Io16BrickletFunction::SetPortMonoflop), &payload).await?;
456        Ok(())
457    }
458
459    /// Returns (for the given pin) the current value and the time as set by
460    /// [`set_port_monoflop`] as well as the remaining time until the value flips.
461    ///
462    /// If the timer is not running currently, the remaining time will be returned
463    /// as 0.
464    pub async fn get_port_monoflop(&mut self, port: char, pin: u8) -> Result<PortMonoflop, TinkerforgeError> {
465        let mut payload = [0; 2];
466        port.write_to_slice(&mut payload[0..1]);
467        pin.write_to_slice(&mut payload[1..2]);
468
469        #[allow(unused_variables)]
470        let result = self.device.get(u8::from(Io16BrickletFunction::GetPortMonoflop), &payload).await?;
471        Ok(PortMonoflop::from_le_byte_slice(result.body()))
472    }
473
474    /// Sets the output value (high or low) for a port (a or b with a bitmask,
475    /// according to the selection mask. The bitmask is 8 bit long and a 1 in the
476    /// bitmask means high and a 0 in the bitmask means low.
477    ///
478    /// For example: The parameters ('a', 192, 128) or ('a', 0b11000000, 0b10000000)
479    /// will turn pin 7 high and pin 6 low on port A, pins 0-6 will remain untouched.
480    ///
481    /// Running monoflop timers for the selected pins will be aborted if this
482    /// function is called.
483    ///
484    /// # Note
485    ///  This function does nothing for pins that are configured as input.
486    ///  Pull-up resistors can be switched on with [`set_port_configuration`].
487    pub async fn set_selected_values(&mut self, port: char, selection_mask: u8, value_mask: u8) -> Result<(), TinkerforgeError> {
488        let mut payload = [0; 3];
489        port.write_to_slice(&mut payload[0..1]);
490        selection_mask.write_to_slice(&mut payload[1..2]);
491        value_mask.write_to_slice(&mut payload[2..3]);
492
493        #[allow(unused_variables)]
494        let result = self.device.set(u8::from(Io16BrickletFunction::SetSelectedValues), &payload).await?;
495        Ok(())
496    }
497
498    /// Returns the current value of the edge counter for the selected pin on port A.
499    /// You can configure the edges that are counted with [`set_edge_count_config`].
500    ///
501    /// If you set the reset counter to *true*, the count is set back to 0
502    /// directly after it is read.
503    ///
504    ///
505    /// .. versionadded:: 2.0.3$nbsp;(Plugin)
506    pub async fn get_edge_count(&mut self, pin: u8, reset_counter: bool) -> Result<u32, TinkerforgeError> {
507        let mut payload = [0; 2];
508        pin.write_to_slice(&mut payload[0..1]);
509        reset_counter.write_to_slice(&mut payload[1..2]);
510
511        #[allow(unused_variables)]
512        let result = self.device.get(u8::from(Io16BrickletFunction::GetEdgeCount), &payload).await?;
513        Ok(u32::from_le_byte_slice(result.body()))
514    }
515
516    /// Configures the edge counter for the selected pin of port A. Pins 0 and 1
517    /// are available for edge counting.
518    ///
519    /// The edge type parameter configures if rising edges, falling edges or
520    /// both are counted if the pin is configured for input. Possible edge types are:
521    ///
522    /// * 0 = rising
523    /// * 1 = falling
524    /// * 2 = both
525    ///
526    /// Configuring an edge counter resets its value to 0.
527    ///
528    /// If you don't know what any of this means, just leave it at default. The
529    /// default configuration is very likely OK for you.
530    ///
531    ///
532    /// .. versionadded:: 2.0.3$nbsp;(Plugin)
533    ///
534    /// Associated constants:
535    /// * IO16_BRICKLET_EDGE_TYPE_RISING
536    ///	* IO16_BRICKLET_EDGE_TYPE_FALLING
537    ///	* IO16_BRICKLET_EDGE_TYPE_BOTH
538    pub async fn set_edge_count_config(&mut self, pin: u8, edge_type: u8, debounce: u8) -> Result<(), TinkerforgeError> {
539        let mut payload = [0; 3];
540        pin.write_to_slice(&mut payload[0..1]);
541        edge_type.write_to_slice(&mut payload[1..2]);
542        debounce.write_to_slice(&mut payload[2..3]);
543
544        #[allow(unused_variables)]
545        let result = self.device.set(u8::from(Io16BrickletFunction::SetEdgeCountConfig), &payload).await?;
546        Ok(())
547    }
548
549    /// Returns the edge type and debounce time for the selected pin of port A as set by
550    /// [`set_edge_count_config`].
551    ///
552    ///
553    /// .. versionadded:: 2.0.3$nbsp;(Plugin)
554    ///
555    /// Associated constants:
556    /// * IO16_BRICKLET_EDGE_TYPE_RISING
557    ///	* IO16_BRICKLET_EDGE_TYPE_FALLING
558    ///	* IO16_BRICKLET_EDGE_TYPE_BOTH
559    pub async fn get_edge_count_config(&mut self, pin: u8) -> Result<EdgeCountConfig, TinkerforgeError> {
560        let mut payload = [0; 1];
561        pin.write_to_slice(&mut payload[0..1]);
562
563        #[allow(unused_variables)]
564        let result = self.device.get(u8::from(Io16BrickletFunction::GetEdgeCountConfig), &payload).await?;
565        Ok(EdgeCountConfig::from_le_byte_slice(result.body()))
566    }
567
568    /// Returns the UID, the UID where the Bricklet is connected to,
569    /// the position, the hardware and firmware version as well as the
570    /// device identifier.
571    ///
572    /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
573    /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
574    /// position 'z'.
575    ///
576    /// The device identifier numbers can be found [here](device_identifier).
577    /// |device_identifier_constant|
578    pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
579        let payload = [0; 0];
580
581        #[allow(unused_variables)]
582        let result = self.device.get(u8::from(Io16BrickletFunction::GetIdentity), &payload).await?;
583        Ok(Identity::from_le_byte_slice(result.body()))
584    }
585}