tinkerforge_async/bindings/
rotary_encoder_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//! 360° rotary encoder with push-button.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/RotaryEncoder_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 RotaryEncoderBrickletFunction {
24    GetCount,
25    SetCountCallbackPeriod,
26    GetCountCallbackPeriod,
27    SetCountCallbackThreshold,
28    GetCountCallbackThreshold,
29    SetDebouncePeriod,
30    GetDebouncePeriod,
31    IsPressed,
32    GetIdentity,
33    CallbackCount,
34    CallbackCountReached,
35    CallbackPressed,
36    CallbackReleased,
37}
38impl From<RotaryEncoderBrickletFunction> for u8 {
39    fn from(fun: RotaryEncoderBrickletFunction) -> Self {
40        match fun {
41            RotaryEncoderBrickletFunction::GetCount => 1,
42            RotaryEncoderBrickletFunction::SetCountCallbackPeriod => 2,
43            RotaryEncoderBrickletFunction::GetCountCallbackPeriod => 3,
44            RotaryEncoderBrickletFunction::SetCountCallbackThreshold => 4,
45            RotaryEncoderBrickletFunction::GetCountCallbackThreshold => 5,
46            RotaryEncoderBrickletFunction::SetDebouncePeriod => 6,
47            RotaryEncoderBrickletFunction::GetDebouncePeriod => 7,
48            RotaryEncoderBrickletFunction::IsPressed => 10,
49            RotaryEncoderBrickletFunction::GetIdentity => 255,
50            RotaryEncoderBrickletFunction::CallbackCount => 8,
51            RotaryEncoderBrickletFunction::CallbackCountReached => 9,
52            RotaryEncoderBrickletFunction::CallbackPressed => 11,
53            RotaryEncoderBrickletFunction::CallbackReleased => 12,
54        }
55    }
56}
57pub const ROTARY_ENCODER_BRICKLET_THRESHOLD_OPTION_OFF: char = 'x';
58pub const ROTARY_ENCODER_BRICKLET_THRESHOLD_OPTION_OUTSIDE: char = 'o';
59pub const ROTARY_ENCODER_BRICKLET_THRESHOLD_OPTION_INSIDE: char = 'i';
60pub const ROTARY_ENCODER_BRICKLET_THRESHOLD_OPTION_SMALLER: char = '<';
61pub const ROTARY_ENCODER_BRICKLET_THRESHOLD_OPTION_GREATER: char = '>';
62
63#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
64pub struct CountCallbackThreshold {
65    pub option: char,
66    pub min: i32,
67    pub max: i32,
68}
69impl FromByteSlice for CountCallbackThreshold {
70    fn bytes_expected() -> usize {
71        9
72    }
73    fn from_le_byte_slice(bytes: &[u8]) -> CountCallbackThreshold {
74        CountCallbackThreshold {
75            option: <char>::from_le_byte_slice(&bytes[0..1]),
76            min: <i32>::from_le_byte_slice(&bytes[1..5]),
77            max: <i32>::from_le_byte_slice(&bytes[5..9]),
78        }
79    }
80}
81
82#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
83pub struct Identity {
84    pub uid: String,
85    pub connected_uid: String,
86    pub position: char,
87    pub hardware_version: [u8; 3],
88    pub firmware_version: [u8; 3],
89    pub device_identifier: u16,
90}
91impl FromByteSlice for Identity {
92    fn bytes_expected() -> usize {
93        25
94    }
95    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
96        Identity {
97            uid: <String>::from_le_byte_slice(&bytes[0..8]),
98            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
99            position: <char>::from_le_byte_slice(&bytes[16..17]),
100            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
101            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
102            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
103        }
104    }
105}
106
107/// 360° rotary encoder with push-button
108#[derive(Clone)]
109pub struct RotaryEncoderBricklet {
110    device: Device,
111}
112impl RotaryEncoderBricklet {
113    pub const DEVICE_IDENTIFIER: u16 = 236;
114    pub const DEVICE_DISPLAY_NAME: &'static str = "Rotary Encoder Bricklet";
115    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
116    pub fn new(uid: Uid, connection: AsyncIpConnection) -> RotaryEncoderBricklet {
117        let mut result = RotaryEncoderBricklet { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
118        result.device.response_expected[u8::from(RotaryEncoderBrickletFunction::GetCount) as usize] = ResponseExpectedFlag::AlwaysTrue;
119        result.device.response_expected[u8::from(RotaryEncoderBrickletFunction::SetCountCallbackPeriod) as usize] =
120            ResponseExpectedFlag::True;
121        result.device.response_expected[u8::from(RotaryEncoderBrickletFunction::GetCountCallbackPeriod) as usize] =
122            ResponseExpectedFlag::AlwaysTrue;
123        result.device.response_expected[u8::from(RotaryEncoderBrickletFunction::SetCountCallbackThreshold) as usize] =
124            ResponseExpectedFlag::True;
125        result.device.response_expected[u8::from(RotaryEncoderBrickletFunction::GetCountCallbackThreshold) as usize] =
126            ResponseExpectedFlag::AlwaysTrue;
127        result.device.response_expected[u8::from(RotaryEncoderBrickletFunction::SetDebouncePeriod) as usize] = ResponseExpectedFlag::True;
128        result.device.response_expected[u8::from(RotaryEncoderBrickletFunction::GetDebouncePeriod) as usize] =
129            ResponseExpectedFlag::AlwaysTrue;
130        result.device.response_expected[u8::from(RotaryEncoderBrickletFunction::IsPressed) as usize] = ResponseExpectedFlag::AlwaysTrue;
131        result.device.response_expected[u8::from(RotaryEncoderBrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
132        result
133    }
134
135    /// Returns the response expected flag for the function specified by the function ID parameter.
136    /// It is true if the function is expected to send a response, false otherwise.
137    ///
138    /// For getter functions this is enabled by default and cannot be disabled, because those
139    /// functions will always send a response. For callback configuration functions it is enabled
140    /// by default too, but can be disabled by [`set_response_expected`](crate::rotary_encoder_bricklet::RotaryEncoderBricklet::set_response_expected).
141    /// For setter functions it is disabled by default and can be enabled.
142    ///
143    /// Enabling the response expected flag for a setter function allows to detect timeouts
144    /// and other error conditions calls of this setter as well. The device will then send a response
145    /// for this purpose. If this flag is disabled for a setter function then no response is sent
146    /// and errors are silently ignored, because they cannot be detected.
147    ///
148    /// See [`set_response_expected`](crate::rotary_encoder_bricklet::RotaryEncoderBricklet::set_response_expected) for the list of function ID constants available for this function.
149    pub fn get_response_expected(&mut self, fun: RotaryEncoderBrickletFunction) -> Result<bool, GetResponseExpectedError> {
150        self.device.get_response_expected(u8::from(fun))
151    }
152
153    /// Changes the response expected flag of the function specified by the function ID parameter.
154    /// This flag can only be changed for setter (default value: false) and callback configuration
155    /// functions (default value: true). For getter functions it is always enabled.
156    ///
157    /// Enabling the response expected flag for a setter function allows to detect timeouts and
158    /// other error conditions calls of this setter as well. The device will then send a response
159    /// for this purpose. If this flag is disabled for a setter function then no response is sent
160    /// and errors are silently ignored, because they cannot be detected.
161    pub fn set_response_expected(
162        &mut self,
163        fun: RotaryEncoderBrickletFunction,
164        response_expected: bool,
165    ) -> Result<(), SetResponseExpectedError> {
166        self.device.set_response_expected(u8::from(fun), response_expected)
167    }
168
169    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
170    pub fn set_response_expected_all(&mut self, response_expected: bool) {
171        self.device.set_response_expected_all(response_expected)
172    }
173
174    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
175    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
176    pub fn get_api_version(&self) -> [u8; 3] {
177        self.device.api_version
178    }
179
180    /// This receiver is triggered periodically with the period that is set by
181    /// [`set_count_callback_period`]. The parameter is the count of
182    /// the encoder.
183    ///
184    /// The [`get_count_callback_receiver`] receiver is only triggered if the count has changed since the
185    /// last triggering.
186    ///
187    /// [`set_count_callback_period`]: #method.set_count_callback_period
188    /// [`get_count_callback_receiver`]: #method.get_count_callback_receiver
189    pub async fn get_count_callback_receiver(&mut self) -> impl Stream<Item = i32> {
190        self.device
191            .get_callback_receiver(u8::from(RotaryEncoderBrickletFunction::CallbackCount))
192            .await
193            .map(|p| i32::from_le_byte_slice(p.body()))
194    }
195
196    /// This receiver is triggered when the threshold as set by
197    /// [`set_count_callback_threshold`] is reached.
198    /// The parameter is the count of the encoder.
199    ///
200    /// If the threshold keeps being reached, the receiver is triggered periodically
201    /// with the period as set by [`set_debounce_period`].
202    pub async fn get_count_reached_callback_receiver(&mut self) -> impl Stream<Item = i32> {
203        self.device
204            .get_callback_receiver(u8::from(RotaryEncoderBrickletFunction::CallbackCountReached))
205            .await
206            .map(|p| i32::from_le_byte_slice(p.body()))
207    }
208
209    /// This receiver is triggered when the button is pressed.
210    pub async fn get_pressed_callback_receiver(&mut self) -> impl Stream<Item = ()> {
211        self.device.get_callback_receiver(u8::from(RotaryEncoderBrickletFunction::CallbackPressed)).await.map(|_p| ())
212    }
213
214    /// This receiver is triggered when the button is released.
215    pub async fn get_released_callback_receiver(&mut self) -> impl Stream<Item = ()> {
216        self.device.get_callback_receiver(u8::from(RotaryEncoderBrickletFunction::CallbackReleased)).await.map(|_p| ())
217    }
218
219    /// Returns the current count of the encoder. If you set reset
220    /// to true, the count is set back to 0 directly after the
221    /// current count is read.
222    ///
223    /// The encoder has 24 steps per rotation
224    ///
225    /// Turning the encoder to the left decrements the counter,
226    /// so a negative count is possible.
227    pub async fn get_count(&mut self, reset: bool) -> Result<i32, TinkerforgeError> {
228        let mut payload = [0; 1];
229        reset.write_to_slice(&mut payload[0..1]);
230
231        #[allow(unused_variables)]
232        let result = self.device.get(u8::from(RotaryEncoderBrickletFunction::GetCount), &payload).await?;
233        Ok(i32::from_le_byte_slice(result.body()))
234    }
235
236    /// Sets the period with which the [`get_count_callback_receiver`] receiver is triggered
237    /// periodically. A value of 0 turns the receiver off.
238    ///
239    /// The [`get_count_callback_receiver`] receiver is only triggered if the count has changed since the
240    /// last triggering.
241    pub async fn set_count_callback_period(&mut self, period: u32) -> Result<(), TinkerforgeError> {
242        let mut payload = [0; 4];
243        period.write_to_slice(&mut payload[0..4]);
244
245        #[allow(unused_variables)]
246        let result = self.device.set(u8::from(RotaryEncoderBrickletFunction::SetCountCallbackPeriod), &payload).await?;
247        Ok(())
248    }
249
250    /// Returns the period as set by [`set_count_callback_period`].
251    pub async fn get_count_callback_period(&mut self) -> Result<u32, TinkerforgeError> {
252        let payload = [0; 0];
253
254        #[allow(unused_variables)]
255        let result = self.device.get(u8::from(RotaryEncoderBrickletFunction::GetCountCallbackPeriod), &payload).await?;
256        Ok(u32::from_le_byte_slice(result.body()))
257    }
258
259    /// Sets the thresholds for the [`get_count_reached_callback_receiver`] receiver.
260    ///
261    /// The following options are possible:
262    ///
263    ///  Option| Description
264    ///  --- | ---
265    ///  'x'|    Receiver is turned off
266    ///  'o'|    Receiver is triggered when the count is *outside* the min and max values
267    ///  'i'|    Receiver is triggered when the count is *inside* the min and max values
268    ///  '<'|    Receiver is triggered when the count is smaller than the min value (max is ignored)
269    ///  '>'|    Receiver is triggered when the count is greater than the min value (max is ignored)
270    ///
271    /// Associated constants:
272    /// * ROTARY_ENCODER_BRICKLET_THRESHOLD_OPTION_OFF
273    ///	* ROTARY_ENCODER_BRICKLET_THRESHOLD_OPTION_OUTSIDE
274    ///	* ROTARY_ENCODER_BRICKLET_THRESHOLD_OPTION_INSIDE
275    ///	* ROTARY_ENCODER_BRICKLET_THRESHOLD_OPTION_SMALLER
276    ///	* ROTARY_ENCODER_BRICKLET_THRESHOLD_OPTION_GREATER
277    pub async fn set_count_callback_threshold(&mut self, option: char, min: i32, max: i32) -> Result<(), TinkerforgeError> {
278        let mut payload = [0; 9];
279        option.write_to_slice(&mut payload[0..1]);
280        min.write_to_slice(&mut payload[1..5]);
281        max.write_to_slice(&mut payload[5..9]);
282
283        #[allow(unused_variables)]
284        let result = self.device.set(u8::from(RotaryEncoderBrickletFunction::SetCountCallbackThreshold), &payload).await?;
285        Ok(())
286    }
287
288    /// Returns the threshold as set by [`set_count_callback_threshold`].
289    ///
290    /// Associated constants:
291    /// * ROTARY_ENCODER_BRICKLET_THRESHOLD_OPTION_OFF
292    ///	* ROTARY_ENCODER_BRICKLET_THRESHOLD_OPTION_OUTSIDE
293    ///	* ROTARY_ENCODER_BRICKLET_THRESHOLD_OPTION_INSIDE
294    ///	* ROTARY_ENCODER_BRICKLET_THRESHOLD_OPTION_SMALLER
295    ///	* ROTARY_ENCODER_BRICKLET_THRESHOLD_OPTION_GREATER
296    pub async fn get_count_callback_threshold(&mut self) -> Result<CountCallbackThreshold, TinkerforgeError> {
297        let payload = [0; 0];
298
299        #[allow(unused_variables)]
300        let result = self.device.get(u8::from(RotaryEncoderBrickletFunction::GetCountCallbackThreshold), &payload).await?;
301        Ok(CountCallbackThreshold::from_le_byte_slice(result.body()))
302    }
303
304    /// Sets the period with which the threshold receiver
305    ///
306    /// * [`get_count_reached_callback_receiver`]
307    ///
308    /// is triggered, if the thresholds
309    ///
310    /// * [`set_count_callback_threshold`]
311    ///
312    /// keeps being reached.
313    pub async fn set_debounce_period(&mut self, debounce: u32) -> Result<(), TinkerforgeError> {
314        let mut payload = [0; 4];
315        debounce.write_to_slice(&mut payload[0..4]);
316
317        #[allow(unused_variables)]
318        let result = self.device.set(u8::from(RotaryEncoderBrickletFunction::SetDebouncePeriod), &payload).await?;
319        Ok(())
320    }
321
322    /// Returns the debounce period as set by [`set_debounce_period`].
323    pub async fn get_debounce_period(&mut self) -> Result<u32, TinkerforgeError> {
324        let payload = [0; 0];
325
326        #[allow(unused_variables)]
327        let result = self.device.get(u8::from(RotaryEncoderBrickletFunction::GetDebouncePeriod), &payload).await?;
328        Ok(u32::from_le_byte_slice(result.body()))
329    }
330
331    /// Returns *true* if the button is pressed and *false* otherwise.
332    ///
333    /// It is recommended to use the [`get_pressed_callback_receiver`] and [`get_released_callback_receiver`] receivers
334    /// to handle the button.
335    pub async fn is_pressed(&mut self) -> Result<bool, TinkerforgeError> {
336        let payload = [0; 0];
337
338        #[allow(unused_variables)]
339        let result = self.device.get(u8::from(RotaryEncoderBrickletFunction::IsPressed), &payload).await?;
340        Ok(bool::from_le_byte_slice(result.body()))
341    }
342
343    /// Returns the UID, the UID where the Bricklet is connected to,
344    /// the position, the hardware and firmware version as well as the
345    /// device identifier.
346    ///
347    /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
348    /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
349    /// position 'z'.
350    ///
351    /// The device identifier numbers can be found [here](device_identifier).
352    /// |device_identifier_constant|
353    pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
354        let payload = [0; 0];
355
356        #[allow(unused_variables)]
357        let result = self.device.get(u8::from(RotaryEncoderBrickletFunction::GetIdentity), &payload).await?;
358        Ok(Identity::from_le_byte_slice(result.body()))
359    }
360}