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}