tinkerforge_async/bindings/
led_strip_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//! Controls up to 320 RGB LEDs.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/LEDStrip_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 LedStripBrickletFunction {
24    SetRgbValues,
25    GetRgbValues,
26    SetFrameDuration,
27    GetFrameDuration,
28    GetSupplyVoltage,
29    SetClockFrequency,
30    GetClockFrequency,
31    SetChipType,
32    GetChipType,
33    SetRgbwValues,
34    GetRgbwValues,
35    SetChannelMapping,
36    GetChannelMapping,
37    EnableFrameRenderedCallback,
38    DisableFrameRenderedCallback,
39    IsFrameRenderedCallbackEnabled,
40    GetIdentity,
41    CallbackFrameRendered,
42}
43impl From<LedStripBrickletFunction> for u8 {
44    fn from(fun: LedStripBrickletFunction) -> Self {
45        match fun {
46            LedStripBrickletFunction::SetRgbValues => 1,
47            LedStripBrickletFunction::GetRgbValues => 2,
48            LedStripBrickletFunction::SetFrameDuration => 3,
49            LedStripBrickletFunction::GetFrameDuration => 4,
50            LedStripBrickletFunction::GetSupplyVoltage => 5,
51            LedStripBrickletFunction::SetClockFrequency => 7,
52            LedStripBrickletFunction::GetClockFrequency => 8,
53            LedStripBrickletFunction::SetChipType => 9,
54            LedStripBrickletFunction::GetChipType => 10,
55            LedStripBrickletFunction::SetRgbwValues => 11,
56            LedStripBrickletFunction::GetRgbwValues => 12,
57            LedStripBrickletFunction::SetChannelMapping => 13,
58            LedStripBrickletFunction::GetChannelMapping => 14,
59            LedStripBrickletFunction::EnableFrameRenderedCallback => 15,
60            LedStripBrickletFunction::DisableFrameRenderedCallback => 16,
61            LedStripBrickletFunction::IsFrameRenderedCallbackEnabled => 17,
62            LedStripBrickletFunction::GetIdentity => 255,
63            LedStripBrickletFunction::CallbackFrameRendered => 6,
64        }
65    }
66}
67pub const LED_STRIP_BRICKLET_CHIP_TYPE_WS2801: u16 = 2801;
68pub const LED_STRIP_BRICKLET_CHIP_TYPE_WS2811: u16 = 2811;
69pub const LED_STRIP_BRICKLET_CHIP_TYPE_WS2812: u16 = 2812;
70pub const LED_STRIP_BRICKLET_CHIP_TYPE_LPD8806: u16 = 8806;
71pub const LED_STRIP_BRICKLET_CHIP_TYPE_APA102: u16 = 102;
72pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_RGB: u8 = 6;
73pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_RBG: u8 = 9;
74pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_BRG: u8 = 33;
75pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_BGR: u8 = 36;
76pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_GRB: u8 = 18;
77pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_GBR: u8 = 24;
78pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_RGBW: u8 = 27;
79pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_RGWB: u8 = 30;
80pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_RBGW: u8 = 39;
81pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_RBWG: u8 = 45;
82pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_RWGB: u8 = 54;
83pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_RWBG: u8 = 57;
84pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_GRWB: u8 = 78;
85pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_GRBW: u8 = 75;
86pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_GBWR: u8 = 108;
87pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_GBRW: u8 = 99;
88pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_GWBR: u8 = 120;
89pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_GWRB: u8 = 114;
90pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_BRGW: u8 = 135;
91pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_BRWG: u8 = 141;
92pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_BGRW: u8 = 147;
93pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_BGWR: u8 = 156;
94pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_BWRG: u8 = 177;
95pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_BWGR: u8 = 180;
96pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_WRBG: u8 = 201;
97pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_WRGB: u8 = 198;
98pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_WGBR: u8 = 216;
99pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_WGRB: u8 = 210;
100pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_WBGR: u8 = 228;
101pub const LED_STRIP_BRICKLET_CHANNEL_MAPPING_WBRG: u8 = 225;
102
103#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
104pub struct RgbValues {
105    pub r: [u8; 16],
106    pub g: [u8; 16],
107    pub b: [u8; 16],
108}
109impl FromByteSlice for RgbValues {
110    fn bytes_expected() -> usize {
111        48
112    }
113    fn from_le_byte_slice(bytes: &[u8]) -> RgbValues {
114        RgbValues {
115            r: <[u8; 16]>::from_le_byte_slice(&bytes[0..16]),
116            g: <[u8; 16]>::from_le_byte_slice(&bytes[16..32]),
117            b: <[u8; 16]>::from_le_byte_slice(&bytes[32..48]),
118        }
119    }
120}
121
122#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
123pub struct RgbwValues {
124    pub r: [u8; 12],
125    pub g: [u8; 12],
126    pub b: [u8; 12],
127    pub w: [u8; 12],
128}
129impl FromByteSlice for RgbwValues {
130    fn bytes_expected() -> usize {
131        48
132    }
133    fn from_le_byte_slice(bytes: &[u8]) -> RgbwValues {
134        RgbwValues {
135            r: <[u8; 12]>::from_le_byte_slice(&bytes[0..12]),
136            g: <[u8; 12]>::from_le_byte_slice(&bytes[12..24]),
137            b: <[u8; 12]>::from_le_byte_slice(&bytes[24..36]),
138            w: <[u8; 12]>::from_le_byte_slice(&bytes[36..48]),
139        }
140    }
141}
142
143#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
144pub struct Identity {
145    pub uid: String,
146    pub connected_uid: String,
147    pub position: char,
148    pub hardware_version: [u8; 3],
149    pub firmware_version: [u8; 3],
150    pub device_identifier: u16,
151}
152impl FromByteSlice for Identity {
153    fn bytes_expected() -> usize {
154        25
155    }
156    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
157        Identity {
158            uid: <String>::from_le_byte_slice(&bytes[0..8]),
159            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
160            position: <char>::from_le_byte_slice(&bytes[16..17]),
161            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
162            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
163            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
164        }
165    }
166}
167
168/// Controls up to 320 RGB LEDs
169#[derive(Clone)]
170pub struct LedStripBricklet {
171    device: Device,
172}
173impl LedStripBricklet {
174    pub const DEVICE_IDENTIFIER: u16 = 231;
175    pub const DEVICE_DISPLAY_NAME: &'static str = "LED Strip Bricklet";
176    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
177    pub fn new(uid: Uid, connection: AsyncIpConnection) -> LedStripBricklet {
178        let mut result = LedStripBricklet { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
179        result.device.response_expected[u8::from(LedStripBrickletFunction::SetRgbValues) as usize] = ResponseExpectedFlag::False;
180        result.device.response_expected[u8::from(LedStripBrickletFunction::GetRgbValues) as usize] = ResponseExpectedFlag::AlwaysTrue;
181        result.device.response_expected[u8::from(LedStripBrickletFunction::SetFrameDuration) as usize] = ResponseExpectedFlag::False;
182        result.device.response_expected[u8::from(LedStripBrickletFunction::GetFrameDuration) as usize] = ResponseExpectedFlag::AlwaysTrue;
183        result.device.response_expected[u8::from(LedStripBrickletFunction::GetSupplyVoltage) as usize] = ResponseExpectedFlag::AlwaysTrue;
184        result.device.response_expected[u8::from(LedStripBrickletFunction::SetClockFrequency) as usize] = ResponseExpectedFlag::False;
185        result.device.response_expected[u8::from(LedStripBrickletFunction::GetClockFrequency) as usize] = ResponseExpectedFlag::AlwaysTrue;
186        result.device.response_expected[u8::from(LedStripBrickletFunction::SetChipType) as usize] = ResponseExpectedFlag::False;
187        result.device.response_expected[u8::from(LedStripBrickletFunction::GetChipType) as usize] = ResponseExpectedFlag::AlwaysTrue;
188        result.device.response_expected[u8::from(LedStripBrickletFunction::SetRgbwValues) as usize] = ResponseExpectedFlag::False;
189        result.device.response_expected[u8::from(LedStripBrickletFunction::GetRgbwValues) as usize] = ResponseExpectedFlag::AlwaysTrue;
190        result.device.response_expected[u8::from(LedStripBrickletFunction::SetChannelMapping) as usize] = ResponseExpectedFlag::False;
191        result.device.response_expected[u8::from(LedStripBrickletFunction::GetChannelMapping) as usize] = ResponseExpectedFlag::AlwaysTrue;
192        result.device.response_expected[u8::from(LedStripBrickletFunction::EnableFrameRenderedCallback) as usize] =
193            ResponseExpectedFlag::True;
194        result.device.response_expected[u8::from(LedStripBrickletFunction::DisableFrameRenderedCallback) as usize] =
195            ResponseExpectedFlag::True;
196        result.device.response_expected[u8::from(LedStripBrickletFunction::IsFrameRenderedCallbackEnabled) as usize] =
197            ResponseExpectedFlag::AlwaysTrue;
198        result.device.response_expected[u8::from(LedStripBrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
199        result
200    }
201
202    /// Returns the response expected flag for the function specified by the function ID parameter.
203    /// It is true if the function is expected to send a response, false otherwise.
204    ///
205    /// For getter functions this is enabled by default and cannot be disabled, because those
206    /// functions will always send a response. For callback configuration functions it is enabled
207    /// by default too, but can be disabled by [`set_response_expected`](crate::led_strip_bricklet::LedStripBricklet::set_response_expected).
208    /// For setter functions it is disabled by default and can be enabled.
209    ///
210    /// Enabling the response expected flag for a setter function allows to detect timeouts
211    /// and other error conditions calls of this setter as well. The device will then send a response
212    /// for this purpose. If this flag is disabled for a setter function then no response is sent
213    /// and errors are silently ignored, because they cannot be detected.
214    ///
215    /// See [`set_response_expected`](crate::led_strip_bricklet::LedStripBricklet::set_response_expected) for the list of function ID constants available for this function.
216    pub fn get_response_expected(&mut self, fun: LedStripBrickletFunction) -> Result<bool, GetResponseExpectedError> {
217        self.device.get_response_expected(u8::from(fun))
218    }
219
220    /// Changes the response expected flag of the function specified by the function ID parameter.
221    /// This flag can only be changed for setter (default value: false) and callback configuration
222    /// functions (default value: true). For getter functions it is always enabled.
223    ///
224    /// Enabling the response expected flag for a setter function allows to detect timeouts and
225    /// other error conditions calls of this setter as well. The device will then send a response
226    /// for this purpose. If this flag is disabled for a setter function then no response is sent
227    /// and errors are silently ignored, because they cannot be detected.
228    pub fn set_response_expected(
229        &mut self,
230        fun: LedStripBrickletFunction,
231        response_expected: bool,
232    ) -> Result<(), SetResponseExpectedError> {
233        self.device.set_response_expected(u8::from(fun), response_expected)
234    }
235
236    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
237    pub fn set_response_expected_all(&mut self, response_expected: bool) {
238        self.device.set_response_expected_all(response_expected)
239    }
240
241    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
242    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
243    pub fn get_api_version(&self) -> [u8; 3] {
244        self.device.api_version
245    }
246
247    /// This receiver is triggered directly after a new frame is rendered. The
248    /// parameter is the number of RGB or RGBW LEDs in that frame.
249    ///
250    /// You should send the data for the next frame directly after this receiver
251    /// was triggered.
252    ///
253    /// For an explanation of the general approach see [`set_rgb_values`].
254    ///
255    /// [`set_rgb_values`]: #method.set_rgb_values
256    pub async fn get_frame_rendered_callback_receiver(&mut self) -> impl Stream<Item = u16> {
257        self.device
258            .get_callback_receiver(u8::from(LedStripBrickletFunction::CallbackFrameRendered))
259            .await
260            .map(|p| u16::from_le_byte_slice(p.body()))
261    }
262
263    /// Sets *length* RGB values for the LEDs starting from *index*.
264    ///
265    /// To make the colors show correctly you need to configure the chip type
266    /// (:func:[Set Chip Type`) and a 3-channel channel mapping ([`set_channel_mapping`])
267    /// according to the connected LEDs.
268    ///
269    /// Example: If you set
270    ///
271    /// * index to 5,
272    /// * length to 3,
273    /// * r to [255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
274    /// * g to [0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] and
275    /// * b to [0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
276    ///
277    /// the LED with index 5 will be red, 6 will be green and 7 will be blue.
278    ///
279    /// # Note Depending on the LED circuitry colors can be permuted.
280    ///
281    /// The colors will be transfered to actual LEDs when the next
282    /// frame duration ends, see [`set_frame_duration`].
283    ///
284    /// Generic approach:
285    ///
286    /// * Set the frame duration to a value that represents
287    ///   the number of frames per second you want to achieve.
288    /// * Set all of the LED colors for one frame.
289    /// * Wait for the [`get_frame_rendered_callback_receiver`] receiver.
290    /// * Set all of the LED colors for next frame.
291    /// * Wait for the [`get_frame_rendered_callback_receiver`] receiver.
292    /// * and so on.
293    ///
294    /// This approach ensures that you can change the LED colors with
295    /// a fixed frame rate.
296    ///
297    /// The actual number of controllable LEDs depends on the number of free
298    /// Bricklet ports. See `here](led_strip_bricklet_ram_constraints) for more
299    /// information. A call of [`set_rgb_values`] with index + length above the
300    /// bounds is ignored completely.
301    pub async fn set_rgb_values(
302        &mut self,
303        index: u16,
304        length: u8,
305        r: &[u8; 16],
306        g: &[u8; 16],
307        b: &[u8; 16],
308    ) -> Result<(), TinkerforgeError> {
309        let mut payload = [0; 51];
310        index.write_to_slice(&mut payload[0..2]);
311        length.write_to_slice(&mut payload[2..3]);
312        r.write_to_slice(&mut payload[3..19]);
313        g.write_to_slice(&mut payload[19..35]);
314        b.write_to_slice(&mut payload[35..51]);
315
316        #[allow(unused_variables)]
317        let result = self.device.set(u8::from(LedStripBrickletFunction::SetRgbValues), &payload).await?;
318        Ok(())
319    }
320
321    /// Returns *length* R, G and B values starting from the
322    /// given LED *index*.
323    ///
324    /// The values are the last values that were set by [`set_rgb_values`].
325    pub async fn get_rgb_values(&mut self, index: u16, length: u8) -> Result<RgbValues, TinkerforgeError> {
326        let mut payload = [0; 3];
327        index.write_to_slice(&mut payload[0..2]);
328        length.write_to_slice(&mut payload[2..3]);
329
330        #[allow(unused_variables)]
331        let result = self.device.get(u8::from(LedStripBrickletFunction::GetRgbValues), &payload).await?;
332        Ok(RgbValues::from_le_byte_slice(result.body()))
333    }
334
335    /// Sets the frame duration.
336    ///
337    /// Example: If you want to achieve 20 frames per second, you should
338    /// set the frame duration to 50ms (50ms * 20 = 1 second).
339    ///
340    /// For an explanation of the general approach see [`set_rgb_values`].
341    pub async fn set_frame_duration(&mut self, duration: u16) -> Result<(), TinkerforgeError> {
342        let mut payload = [0; 2];
343        duration.write_to_slice(&mut payload[0..2]);
344
345        #[allow(unused_variables)]
346        let result = self.device.set(u8::from(LedStripBrickletFunction::SetFrameDuration), &payload).await?;
347        Ok(())
348    }
349
350    /// Returns the frame duration as set by [`set_frame_duration`].
351    pub async fn get_frame_duration(&mut self) -> Result<u16, TinkerforgeError> {
352        let payload = [0; 0];
353
354        #[allow(unused_variables)]
355        let result = self.device.get(u8::from(LedStripBrickletFunction::GetFrameDuration), &payload).await?;
356        Ok(u16::from_le_byte_slice(result.body()))
357    }
358
359    /// Returns the current supply voltage of the LEDs.
360    pub async fn get_supply_voltage(&mut self) -> Result<u16, TinkerforgeError> {
361        let payload = [0; 0];
362
363        #[allow(unused_variables)]
364        let result = self.device.get(u8::from(LedStripBrickletFunction::GetSupplyVoltage), &payload).await?;
365        Ok(u16::from_le_byte_slice(result.body()))
366    }
367
368    /// Sets the frequency of the clock.
369    ///
370    /// The Bricklet will choose the nearest achievable frequency, which may
371    /// be off by a few Hz. You can get the exact frequency that is used by
372    /// calling [`get_clock_frequency`].
373    ///
374    /// If you have problems with flickering LEDs, they may be bits flipping. You
375    /// can fix this by either making the connection between the LEDs and the
376    /// Bricklet shorter or by reducing the frequency.
377    ///
378    /// With a decreasing frequency your maximum frames per second will decrease
379    /// too.
380    ///
381    /// # Note
382    ///  The frequency in firmware version 2.0.0 is fixed at 2MHz.
383    ///
384    ///
385    /// .. versionadded:: 2.0.1$nbsp;(Plugin)
386    pub async fn set_clock_frequency(&mut self, frequency: u32) -> Result<(), TinkerforgeError> {
387        let mut payload = [0; 4];
388        frequency.write_to_slice(&mut payload[0..4]);
389
390        #[allow(unused_variables)]
391        let result = self.device.set(u8::from(LedStripBrickletFunction::SetClockFrequency), &payload).await?;
392        Ok(())
393    }
394
395    /// Returns the currently used clock frequency as set by [`set_clock_frequency`].
396    ///
397    ///
398    /// .. versionadded:: 2.0.1$nbsp;(Plugin)
399    pub async fn get_clock_frequency(&mut self) -> Result<u32, TinkerforgeError> {
400        let payload = [0; 0];
401
402        #[allow(unused_variables)]
403        let result = self.device.get(u8::from(LedStripBrickletFunction::GetClockFrequency), &payload).await?;
404        Ok(u32::from_le_byte_slice(result.body()))
405    }
406
407    /// Sets the type of the LED driver chip. We currently support the chips
408    ///
409    /// * WS2801,
410    /// * WS2811,
411    /// * WS2812 / SK6812 / NeoPixel RGB,
412    /// * SK6812RGBW / NeoPixel RGBW (Chip Type = WS2812),
413    /// * LPD8806 and
414    /// * APA102 / DotStar.
415    ///
416    ///
417    /// .. versionadded:: 2.0.2$nbsp;(Plugin)
418    ///
419    /// Associated constants:
420    /// * LED_STRIP_BRICKLET_CHIP_TYPE_WS2801
421    ///	* LED_STRIP_BRICKLET_CHIP_TYPE_WS2811
422    ///	* LED_STRIP_BRICKLET_CHIP_TYPE_WS2812
423    ///	* LED_STRIP_BRICKLET_CHIP_TYPE_LPD8806
424    ///	* LED_STRIP_BRICKLET_CHIP_TYPE_APA102
425    pub async fn set_chip_type(&mut self, chip: u16) -> Result<(), TinkerforgeError> {
426        let mut payload = [0; 2];
427        chip.write_to_slice(&mut payload[0..2]);
428
429        #[allow(unused_variables)]
430        let result = self.device.set(u8::from(LedStripBrickletFunction::SetChipType), &payload).await?;
431        Ok(())
432    }
433
434    /// Returns the currently used chip type as set by [`set_chip_type`].
435    ///
436    ///
437    /// .. versionadded:: 2.0.2$nbsp;(Plugin)
438    ///
439    /// Associated constants:
440    /// * LED_STRIP_BRICKLET_CHIP_TYPE_WS2801
441    ///	* LED_STRIP_BRICKLET_CHIP_TYPE_WS2811
442    ///	* LED_STRIP_BRICKLET_CHIP_TYPE_WS2812
443    ///	* LED_STRIP_BRICKLET_CHIP_TYPE_LPD8806
444    ///	* LED_STRIP_BRICKLET_CHIP_TYPE_APA102
445    pub async fn get_chip_type(&mut self) -> Result<u16, TinkerforgeError> {
446        let payload = [0; 0];
447
448        #[allow(unused_variables)]
449        let result = self.device.get(u8::from(LedStripBrickletFunction::GetChipType), &payload).await?;
450        Ok(u16::from_le_byte_slice(result.body()))
451    }
452
453    /// Sets *length* RGBW values for the LEDs starting from *index*.
454    ///
455    /// To make the colors show correctly you need to configure the chip type
456    /// (:func:[Set Chip Type`) and a 4-channel channel mapping ([`set_channel_mapping`])
457    /// according to the connected LEDs.
458    ///
459    /// The maximum length is 12, the index goes from 0 to 239 and the rgbw values
460    /// have 8 bits each.
461    ///
462    /// Example: If you set
463    ///
464    /// * index to 5,
465    /// * length to 4,
466    /// * r to [255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
467    /// * g to [0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
468    /// * b to [0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0] and
469    /// * w to [0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0]
470    ///
471    /// the LED with index 5 will be red, 6 will be green, 7 will be blue and 8 will be white.
472    ///
473    /// # Note Depending on the LED circuitry colors can be permuted.
474    ///
475    /// The colors will be transfered to actual LEDs when the next
476    /// frame duration ends, see [`set_frame_duration`].
477    ///
478    /// Generic approach:
479    ///
480    /// * Set the frame duration to a value that represents
481    ///   the number of frames per second you want to achieve.
482    /// * Set all of the LED colors for one frame.
483    /// * Wait for the [`get_frame_rendered_callback_receiver`] receiver.
484    /// * Set all of the LED colors for next frame.
485    /// * Wait for the [`get_frame_rendered_callback_receiver`] receiver.
486    /// * and so on.
487    ///
488    /// This approach ensures that you can change the LED colors with
489    /// a fixed frame rate.
490    ///
491    /// The actual number of controllable LEDs depends on the number of free
492    /// Bricklet ports. See `here](led_strip_bricklet_ram_constraints) for more
493    /// information. A call of [`set_rgbw_values`] with index + length above the
494    /// bounds is ignored completely.
495    ///
496    /// The LPD8806 LED driver chips have 7-bit channels for RGB. Internally the LED
497    /// Strip Bricklets divides the 8-bit values set using this function by 2 to make
498    /// them 7-bit. Therefore, you can just use the normal value range (0-255) for
499    /// LPD8806 LEDs.
500    ///
501    /// The brightness channel of the APA102 LED driver chips has 5-bit. Internally the
502    /// LED Strip Bricklets divides the 8-bit values set using this function by 8 to make
503    /// them 5-bit. Therefore, you can just use the normal value range (0-255) for
504    /// the brightness channel of APA102 LEDs.
505    ///
506    ///
507    /// .. versionadded:: 2.0.6$nbsp;(Plugin)
508    pub async fn set_rgbw_values(
509        &mut self,
510        index: u16,
511        length: u8,
512        r: &[u8; 12],
513        g: &[u8; 12],
514        b: &[u8; 12],
515        w: &[u8; 12],
516    ) -> Result<(), TinkerforgeError> {
517        let mut payload = [0; 51];
518        index.write_to_slice(&mut payload[0..2]);
519        length.write_to_slice(&mut payload[2..3]);
520        r.write_to_slice(&mut payload[3..15]);
521        g.write_to_slice(&mut payload[15..27]);
522        b.write_to_slice(&mut payload[27..39]);
523        w.write_to_slice(&mut payload[39..51]);
524
525        #[allow(unused_variables)]
526        let result = self.device.set(u8::from(LedStripBrickletFunction::SetRgbwValues), &payload).await?;
527        Ok(())
528    }
529
530    /// Returns *length* RGBW values starting from the given *index*.
531    ///
532    /// The values are the last values that were set by [`set_rgbw_values`].
533    ///
534    ///
535    /// .. versionadded:: 2.0.6$nbsp;(Plugin)
536    pub async fn get_rgbw_values(&mut self, index: u16, length: u8) -> Result<RgbwValues, TinkerforgeError> {
537        let mut payload = [0; 3];
538        index.write_to_slice(&mut payload[0..2]);
539        length.write_to_slice(&mut payload[2..3]);
540
541        #[allow(unused_variables)]
542        let result = self.device.get(u8::from(LedStripBrickletFunction::GetRgbwValues), &payload).await?;
543        Ok(RgbwValues::from_le_byte_slice(result.body()))
544    }
545
546    /// Sets the channel mapping for the connected LEDs.
547    ///
548    /// [`set_rgb_values`] and [`set_rgbw_values`] take the data in RGB(W) order.
549    /// But the connected LED driver chips might have their 3 or 4 channels in a
550    /// different order. For example, the WS2801 chips typically use BGR order, the
551    /// WS2812 chips typically use GRB order and the APA102 chips typically use WBGR
552    /// order.
553    ///
554    /// The APA102 chips are special. They have three 8-bit channels for RGB
555    /// and an additional 5-bit channel for the overall brightness of the RGB LED
556    /// making them 4-channel chips. Internally the brightness channel is the first
557    /// channel, therefore one of the Wxyz channel mappings should be used. Then
558    /// the W channel controls the brightness.
559    ///
560    /// If a 3-channel mapping is selected then [`set_rgb_values`] has to be used.
561    /// Calling [`set_rgbw_values`] with a 3-channel mapping will produce incorrect
562    /// results. Vice-versa if a 4-channel mapping is selected then
563    /// [`set_rgbw_values`] has to be used. Calling [`set_rgb_values`] with a
564    /// 4-channel mapping will produce incorrect results.
565    ///
566    ///
567    /// .. versionadded:: 2.0.6$nbsp;(Plugin)
568    ///
569    /// Associated constants:
570    /// * LED_STRIP_BRICKLET_CHANNEL_MAPPING_RGB
571    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_RBG
572    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_BRG
573    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_BGR
574    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_GRB
575    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_GBR
576    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_RGBW
577    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_RGWB
578    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_RBGW
579    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_RBWG
580    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_RWGB
581    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_RWBG
582    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_GRWB
583    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_GRBW
584    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_GBWR
585    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_GBRW
586    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_GWBR
587    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_GWRB
588    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_BRGW
589    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_BRWG
590    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_BGRW
591    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_BGWR
592    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_BWRG
593    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_BWGR
594    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_WRBG
595    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_WRGB
596    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_WGBR
597    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_WGRB
598    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_WBGR
599    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_WBRG
600    pub async fn set_channel_mapping(&mut self, mapping: u8) -> Result<(), TinkerforgeError> {
601        let mut payload = [0; 1];
602        mapping.write_to_slice(&mut payload[0..1]);
603
604        #[allow(unused_variables)]
605        let result = self.device.set(u8::from(LedStripBrickletFunction::SetChannelMapping), &payload).await?;
606        Ok(())
607    }
608
609    /// Returns the currently used channel mapping as set by [`set_channel_mapping`].
610    ///
611    ///
612    /// .. versionadded:: 2.0.6$nbsp;(Plugin)
613    ///
614    /// Associated constants:
615    /// * LED_STRIP_BRICKLET_CHANNEL_MAPPING_RGB
616    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_RBG
617    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_BRG
618    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_BGR
619    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_GRB
620    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_GBR
621    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_RGBW
622    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_RGWB
623    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_RBGW
624    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_RBWG
625    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_RWGB
626    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_RWBG
627    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_GRWB
628    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_GRBW
629    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_GBWR
630    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_GBRW
631    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_GWBR
632    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_GWRB
633    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_BRGW
634    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_BRWG
635    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_BGRW
636    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_BGWR
637    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_BWRG
638    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_BWGR
639    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_WRBG
640    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_WRGB
641    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_WGBR
642    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_WGRB
643    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_WBGR
644    ///	* LED_STRIP_BRICKLET_CHANNEL_MAPPING_WBRG
645    pub async fn get_channel_mapping(&mut self) -> Result<u8, TinkerforgeError> {
646        let payload = [0; 0];
647
648        #[allow(unused_variables)]
649        let result = self.device.get(u8::from(LedStripBrickletFunction::GetChannelMapping), &payload).await?;
650        Ok(u8::from_le_byte_slice(result.body()))
651    }
652
653    /// Enables the [`get_frame_rendered_callback_receiver`] receiver.
654    ///
655    /// By default the receiver is enabled.
656    ///
657    ///
658    /// .. versionadded:: 2.0.6$nbsp;(Plugin)
659    pub async fn enable_frame_rendered_callback(&mut self) -> Result<(), TinkerforgeError> {
660        let payload = [0; 0];
661
662        #[allow(unused_variables)]
663        let result = self.device.set(u8::from(LedStripBrickletFunction::EnableFrameRenderedCallback), &payload).await?;
664        Ok(())
665    }
666
667    /// Disables the [`get_frame_rendered_callback_receiver`] receiver.
668    ///
669    /// By default the receiver is enabled.
670    ///
671    ///
672    /// .. versionadded:: 2.0.6$nbsp;(Plugin)
673    pub async fn disable_frame_rendered_callback(&mut self) -> Result<(), TinkerforgeError> {
674        let payload = [0; 0];
675
676        #[allow(unused_variables)]
677        let result = self.device.set(u8::from(LedStripBrickletFunction::DisableFrameRenderedCallback), &payload).await?;
678        Ok(())
679    }
680
681    /// Returns *true* if the [`get_frame_rendered_callback_receiver`] receiver is enabled, *false* otherwise.
682    ///
683    ///
684    /// .. versionadded:: 2.0.6$nbsp;(Plugin)
685    pub async fn is_frame_rendered_callback_enabled(&mut self) -> Result<bool, TinkerforgeError> {
686        let payload = [0; 0];
687
688        #[allow(unused_variables)]
689        let result = self.device.get(u8::from(LedStripBrickletFunction::IsFrameRenderedCallbackEnabled), &payload).await?;
690        Ok(bool::from_le_byte_slice(result.body()))
691    }
692
693    /// Returns the UID, the UID where the Bricklet is connected to,
694    /// the position, the hardware and firmware version as well as the
695    /// device identifier.
696    ///
697    /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
698    /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
699    /// position 'z'.
700    ///
701    /// The device identifier numbers can be found [here](device_identifier).
702    /// |device_identifier_constant|
703    pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
704        let payload = [0; 0];
705
706        #[allow(unused_variables)]
707        let result = self.device.get(u8::from(LedStripBrickletFunction::GetIdentity), &payload).await?;
708        Ok(Identity::from_le_byte_slice(result.body()))
709    }
710}