1#![allow(clippy::too_many_arguments)]
7
8use crate::tlv;
9use anyhow;
10use serde_json;
11
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
16#[repr(u8)]
17pub enum ColorLoopAction {
18 Deactivate = 0,
20 Activatefromcolorloopstartenhancedhue = 1,
22 Activatefromenhancedcurrenthue = 2,
24}
25
26impl ColorLoopAction {
27 pub fn from_u8(value: u8) -> Option<Self> {
29 match value {
30 0 => Some(ColorLoopAction::Deactivate),
31 1 => Some(ColorLoopAction::Activatefromcolorloopstartenhancedhue),
32 2 => Some(ColorLoopAction::Activatefromenhancedcurrenthue),
33 _ => None,
34 }
35 }
36
37 pub fn to_u8(self) -> u8 {
39 self as u8
40 }
41}
42
43impl From<ColorLoopAction> for u8 {
44 fn from(val: ColorLoopAction) -> Self {
45 val as u8
46 }
47}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
50#[repr(u8)]
51pub enum ColorLoopDirection {
52 Decrement = 0,
54 Increment = 1,
56}
57
58impl ColorLoopDirection {
59 pub fn from_u8(value: u8) -> Option<Self> {
61 match value {
62 0 => Some(ColorLoopDirection::Decrement),
63 1 => Some(ColorLoopDirection::Increment),
64 _ => None,
65 }
66 }
67
68 pub fn to_u8(self) -> u8 {
70 self as u8
71 }
72}
73
74impl From<ColorLoopDirection> for u8 {
75 fn from(val: ColorLoopDirection) -> Self {
76 val as u8
77 }
78}
79
80#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
81#[repr(u8)]
82pub enum ColorMode {
83 Currenthueandcurrentsaturation = 0,
85 Currentxandcurrenty = 1,
87 Colortemperaturemireds = 2,
89}
90
91impl ColorMode {
92 pub fn from_u8(value: u8) -> Option<Self> {
94 match value {
95 0 => Some(ColorMode::Currenthueandcurrentsaturation),
96 1 => Some(ColorMode::Currentxandcurrenty),
97 2 => Some(ColorMode::Colortemperaturemireds),
98 _ => None,
99 }
100 }
101
102 pub fn to_u8(self) -> u8 {
104 self as u8
105 }
106}
107
108impl From<ColorMode> for u8 {
109 fn from(val: ColorMode) -> Self {
110 val as u8
111 }
112}
113
114#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
115#[repr(u8)]
116pub enum Direction {
117 Shortest = 0,
119 Longest = 1,
121 Up = 2,
123 Down = 3,
125}
126
127impl Direction {
128 pub fn from_u8(value: u8) -> Option<Self> {
130 match value {
131 0 => Some(Direction::Shortest),
132 1 => Some(Direction::Longest),
133 2 => Some(Direction::Up),
134 3 => Some(Direction::Down),
135 _ => None,
136 }
137 }
138
139 pub fn to_u8(self) -> u8 {
141 self as u8
142 }
143}
144
145impl From<Direction> for u8 {
146 fn from(val: Direction) -> Self {
147 val as u8
148 }
149}
150
151#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
152#[repr(u8)]
153pub enum DriftCompensation {
154 None = 0,
156 Otherorunknown = 1,
158 Temperaturemonitoring = 2,
160 Opticalluminancemonitoringandfeedback = 3,
162 Opticalcolormonitoringandfeedback = 4,
164}
165
166impl DriftCompensation {
167 pub fn from_u8(value: u8) -> Option<Self> {
169 match value {
170 0 => Some(DriftCompensation::None),
171 1 => Some(DriftCompensation::Otherorunknown),
172 2 => Some(DriftCompensation::Temperaturemonitoring),
173 3 => Some(DriftCompensation::Opticalluminancemonitoringandfeedback),
174 4 => Some(DriftCompensation::Opticalcolormonitoringandfeedback),
175 _ => None,
176 }
177 }
178
179 pub fn to_u8(self) -> u8 {
181 self as u8
182 }
183}
184
185impl From<DriftCompensation> for u8 {
186 fn from(val: DriftCompensation) -> Self {
187 val as u8
188 }
189}
190
191#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
192#[repr(u8)]
193pub enum EnhancedColorMode {
194 Currenthueandcurrentsaturation = 0,
196 Currentxandcurrenty = 1,
198 Colortemperaturemireds = 2,
200 Enhancedcurrenthueandcurrentsaturation = 3,
202}
203
204impl EnhancedColorMode {
205 pub fn from_u8(value: u8) -> Option<Self> {
207 match value {
208 0 => Some(EnhancedColorMode::Currenthueandcurrentsaturation),
209 1 => Some(EnhancedColorMode::Currentxandcurrenty),
210 2 => Some(EnhancedColorMode::Colortemperaturemireds),
211 3 => Some(EnhancedColorMode::Enhancedcurrenthueandcurrentsaturation),
212 _ => None,
213 }
214 }
215
216 pub fn to_u8(self) -> u8 {
218 self as u8
219 }
220}
221
222impl From<EnhancedColorMode> for u8 {
223 fn from(val: EnhancedColorMode) -> Self {
224 val as u8
225 }
226}
227
228#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
229#[repr(u8)]
230pub enum MoveMode {
231 Stop = 0,
233 Up = 1,
235 Down = 3,
237}
238
239impl MoveMode {
240 pub fn from_u8(value: u8) -> Option<Self> {
242 match value {
243 0 => Some(MoveMode::Stop),
244 1 => Some(MoveMode::Up),
245 3 => Some(MoveMode::Down),
246 _ => None,
247 }
248 }
249
250 pub fn to_u8(self) -> u8 {
252 self as u8
253 }
254}
255
256impl From<MoveMode> for u8 {
257 fn from(val: MoveMode) -> Self {
258 val as u8
259 }
260}
261
262#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
263#[repr(u8)]
264pub enum StepMode {
265 Up = 1,
267 Down = 3,
269}
270
271impl StepMode {
272 pub fn from_u8(value: u8) -> Option<Self> {
274 match value {
275 1 => Some(StepMode::Up),
276 3 => Some(StepMode::Down),
277 _ => None,
278 }
279 }
280
281 pub fn to_u8(self) -> u8 {
283 self as u8
284 }
285}
286
287impl From<StepMode> for u8 {
288 fn from(val: StepMode) -> Self {
289 val as u8
290 }
291}
292
293pub type ColorCapabilities = u8;
297
298pub mod colorcapabilities {
300 pub const HUE_SATURATION: u8 = 0x01;
302 pub const ENHANCED_HUE: u8 = 0x02;
304 pub const COLOR_LOOP: u8 = 0x04;
306 pub const XY: u8 = 0x08;
308 pub const COLOR_TEMPERATURE: u8 = 0x10;
310}
311
312pub type Options = u8;
314
315pub mod options {
317 pub const EXECUTE_IF_OFF: u8 = 0x01;
319}
320
321pub type UpdateFlags = u8;
323
324pub mod updateflags {
326 pub const UPDATE_ACTION: u8 = 0x01;
328 pub const UPDATE_DIRECTION: u8 = 0x02;
330 pub const UPDATE_TIME: u8 = 0x04;
332 pub const UPDATE_START_HUE: u8 = 0x08;
334}
335
336pub fn encode_move_to_hue(hue: u8, direction: Direction, transition_time: u16, options_mask: Options, options_override: Options) -> anyhow::Result<Vec<u8>> {
340 let tlv = tlv::TlvItemEnc {
341 tag: 0,
342 value: tlv::TlvItemValueEnc::StructInvisible(vec![
343 (0, tlv::TlvItemValueEnc::UInt8(hue)).into(),
344 (1, tlv::TlvItemValueEnc::UInt8(direction.to_u8())).into(),
345 (2, tlv::TlvItemValueEnc::UInt16(transition_time)).into(),
346 (3, tlv::TlvItemValueEnc::UInt8(options_mask)).into(),
347 (4, tlv::TlvItemValueEnc::UInt8(options_override)).into(),
348 ]),
349 };
350 Ok(tlv.encode()?)
351}
352
353pub fn encode_move_hue(move_mode: MoveMode, rate: u8, options_mask: Options, options_override: Options) -> anyhow::Result<Vec<u8>> {
355 let tlv = tlv::TlvItemEnc {
356 tag: 0,
357 value: tlv::TlvItemValueEnc::StructInvisible(vec![
358 (0, tlv::TlvItemValueEnc::UInt8(move_mode.to_u8())).into(),
359 (1, tlv::TlvItemValueEnc::UInt8(rate)).into(),
360 (2, tlv::TlvItemValueEnc::UInt8(options_mask)).into(),
361 (3, tlv::TlvItemValueEnc::UInt8(options_override)).into(),
362 ]),
363 };
364 Ok(tlv.encode()?)
365}
366
367pub fn encode_step_hue(step_mode: StepMode, step_size: u8, transition_time: u8, options_mask: Options, options_override: Options) -> anyhow::Result<Vec<u8>> {
369 let tlv = tlv::TlvItemEnc {
370 tag: 0,
371 value: tlv::TlvItemValueEnc::StructInvisible(vec![
372 (0, tlv::TlvItemValueEnc::UInt8(step_mode.to_u8())).into(),
373 (1, tlv::TlvItemValueEnc::UInt8(step_size)).into(),
374 (2, tlv::TlvItemValueEnc::UInt8(transition_time)).into(),
375 (3, tlv::TlvItemValueEnc::UInt8(options_mask)).into(),
376 (4, tlv::TlvItemValueEnc::UInt8(options_override)).into(),
377 ]),
378 };
379 Ok(tlv.encode()?)
380}
381
382pub fn encode_move_to_saturation(saturation: u8, transition_time: u16, options_mask: Options, options_override: Options) -> anyhow::Result<Vec<u8>> {
384 let tlv = tlv::TlvItemEnc {
385 tag: 0,
386 value: tlv::TlvItemValueEnc::StructInvisible(vec![
387 (0, tlv::TlvItemValueEnc::UInt8(saturation)).into(),
388 (1, tlv::TlvItemValueEnc::UInt16(transition_time)).into(),
389 (2, tlv::TlvItemValueEnc::UInt8(options_mask)).into(),
390 (3, tlv::TlvItemValueEnc::UInt8(options_override)).into(),
391 ]),
392 };
393 Ok(tlv.encode()?)
394}
395
396pub fn encode_move_saturation(move_mode: MoveMode, rate: u8, options_mask: Options, options_override: Options) -> anyhow::Result<Vec<u8>> {
398 let tlv = tlv::TlvItemEnc {
399 tag: 0,
400 value: tlv::TlvItemValueEnc::StructInvisible(vec![
401 (0, tlv::TlvItemValueEnc::UInt8(move_mode.to_u8())).into(),
402 (1, tlv::TlvItemValueEnc::UInt8(rate)).into(),
403 (2, tlv::TlvItemValueEnc::UInt8(options_mask)).into(),
404 (3, tlv::TlvItemValueEnc::UInt8(options_override)).into(),
405 ]),
406 };
407 Ok(tlv.encode()?)
408}
409
410pub fn encode_step_saturation(step_mode: StepMode, step_size: u8, transition_time: u8, options_mask: Options, options_override: Options) -> anyhow::Result<Vec<u8>> {
412 let tlv = tlv::TlvItemEnc {
413 tag: 0,
414 value: tlv::TlvItemValueEnc::StructInvisible(vec![
415 (0, tlv::TlvItemValueEnc::UInt8(step_mode.to_u8())).into(),
416 (1, tlv::TlvItemValueEnc::UInt8(step_size)).into(),
417 (2, tlv::TlvItemValueEnc::UInt8(transition_time)).into(),
418 (3, tlv::TlvItemValueEnc::UInt8(options_mask)).into(),
419 (4, tlv::TlvItemValueEnc::UInt8(options_override)).into(),
420 ]),
421 };
422 Ok(tlv.encode()?)
423}
424
425pub fn encode_move_to_hue_and_saturation(hue: u8, saturation: u8, transition_time: u16, options_mask: Options, options_override: Options) -> anyhow::Result<Vec<u8>> {
427 let tlv = tlv::TlvItemEnc {
428 tag: 0,
429 value: tlv::TlvItemValueEnc::StructInvisible(vec![
430 (0, tlv::TlvItemValueEnc::UInt8(hue)).into(),
431 (1, tlv::TlvItemValueEnc::UInt8(saturation)).into(),
432 (2, tlv::TlvItemValueEnc::UInt16(transition_time)).into(),
433 (3, tlv::TlvItemValueEnc::UInt8(options_mask)).into(),
434 (4, tlv::TlvItemValueEnc::UInt8(options_override)).into(),
435 ]),
436 };
437 Ok(tlv.encode()?)
438}
439
440pub fn encode_move_to_color(color_x: u16, color_y: u16, transition_time: u16, options_mask: Options, options_override: Options) -> anyhow::Result<Vec<u8>> {
442 let tlv = tlv::TlvItemEnc {
443 tag: 0,
444 value: tlv::TlvItemValueEnc::StructInvisible(vec![
445 (0, tlv::TlvItemValueEnc::UInt16(color_x)).into(),
446 (1, tlv::TlvItemValueEnc::UInt16(color_y)).into(),
447 (2, tlv::TlvItemValueEnc::UInt16(transition_time)).into(),
448 (3, tlv::TlvItemValueEnc::UInt8(options_mask)).into(),
449 (4, tlv::TlvItemValueEnc::UInt8(options_override)).into(),
450 ]),
451 };
452 Ok(tlv.encode()?)
453}
454
455pub fn encode_move_color(rate_x: i16, rate_y: i16, options_mask: Options, options_override: Options) -> anyhow::Result<Vec<u8>> {
457 let tlv = tlv::TlvItemEnc {
458 tag: 0,
459 value: tlv::TlvItemValueEnc::StructInvisible(vec![
460 (0, tlv::TlvItemValueEnc::Int16(rate_x)).into(),
461 (1, tlv::TlvItemValueEnc::Int16(rate_y)).into(),
462 (2, tlv::TlvItemValueEnc::UInt8(options_mask)).into(),
463 (3, tlv::TlvItemValueEnc::UInt8(options_override)).into(),
464 ]),
465 };
466 Ok(tlv.encode()?)
467}
468
469pub fn encode_step_color(step_x: i16, step_y: i16, transition_time: u16, options_mask: Options, options_override: Options) -> anyhow::Result<Vec<u8>> {
471 let tlv = tlv::TlvItemEnc {
472 tag: 0,
473 value: tlv::TlvItemValueEnc::StructInvisible(vec![
474 (0, tlv::TlvItemValueEnc::Int16(step_x)).into(),
475 (1, tlv::TlvItemValueEnc::Int16(step_y)).into(),
476 (2, tlv::TlvItemValueEnc::UInt16(transition_time)).into(),
477 (3, tlv::TlvItemValueEnc::UInt8(options_mask)).into(),
478 (4, tlv::TlvItemValueEnc::UInt8(options_override)).into(),
479 ]),
480 };
481 Ok(tlv.encode()?)
482}
483
484pub fn encode_move_to_color_temperature(color_temperature_mireds: u16, transition_time: u16, options_mask: Options, options_override: Options) -> anyhow::Result<Vec<u8>> {
486 let tlv = tlv::TlvItemEnc {
487 tag: 0,
488 value: tlv::TlvItemValueEnc::StructInvisible(vec![
489 (0, tlv::TlvItemValueEnc::UInt16(color_temperature_mireds)).into(),
490 (1, tlv::TlvItemValueEnc::UInt16(transition_time)).into(),
491 (2, tlv::TlvItemValueEnc::UInt8(options_mask)).into(),
492 (3, tlv::TlvItemValueEnc::UInt8(options_override)).into(),
493 ]),
494 };
495 Ok(tlv.encode()?)
496}
497
498pub fn encode_enhanced_move_to_hue(enhanced_hue: u16, direction: Direction, transition_time: u16, options_mask: Options, options_override: Options) -> anyhow::Result<Vec<u8>> {
500 let tlv = tlv::TlvItemEnc {
501 tag: 0,
502 value: tlv::TlvItemValueEnc::StructInvisible(vec![
503 (0, tlv::TlvItemValueEnc::UInt16(enhanced_hue)).into(),
504 (1, tlv::TlvItemValueEnc::UInt8(direction.to_u8())).into(),
505 (2, tlv::TlvItemValueEnc::UInt16(transition_time)).into(),
506 (3, tlv::TlvItemValueEnc::UInt8(options_mask)).into(),
507 (4, tlv::TlvItemValueEnc::UInt8(options_override)).into(),
508 ]),
509 };
510 Ok(tlv.encode()?)
511}
512
513pub fn encode_enhanced_move_hue(move_mode: MoveMode, rate: u16, options_mask: Options, options_override: Options) -> anyhow::Result<Vec<u8>> {
515 let tlv = tlv::TlvItemEnc {
516 tag: 0,
517 value: tlv::TlvItemValueEnc::StructInvisible(vec![
518 (0, tlv::TlvItemValueEnc::UInt8(move_mode.to_u8())).into(),
519 (1, tlv::TlvItemValueEnc::UInt16(rate)).into(),
520 (2, tlv::TlvItemValueEnc::UInt8(options_mask)).into(),
521 (3, tlv::TlvItemValueEnc::UInt8(options_override)).into(),
522 ]),
523 };
524 Ok(tlv.encode()?)
525}
526
527pub fn encode_enhanced_step_hue(step_mode: StepMode, step_size: u16, transition_time: u16, options_mask: Options, options_override: Options) -> anyhow::Result<Vec<u8>> {
529 let tlv = tlv::TlvItemEnc {
530 tag: 0,
531 value: tlv::TlvItemValueEnc::StructInvisible(vec![
532 (0, tlv::TlvItemValueEnc::UInt8(step_mode.to_u8())).into(),
533 (1, tlv::TlvItemValueEnc::UInt16(step_size)).into(),
534 (2, tlv::TlvItemValueEnc::UInt16(transition_time)).into(),
535 (3, tlv::TlvItemValueEnc::UInt8(options_mask)).into(),
536 (4, tlv::TlvItemValueEnc::UInt8(options_override)).into(),
537 ]),
538 };
539 Ok(tlv.encode()?)
540}
541
542pub fn encode_enhanced_move_to_hue_and_saturation(enhanced_hue: u16, saturation: u8, transition_time: u16, options_mask: Options, options_override: Options) -> anyhow::Result<Vec<u8>> {
544 let tlv = tlv::TlvItemEnc {
545 tag: 0,
546 value: tlv::TlvItemValueEnc::StructInvisible(vec![
547 (0, tlv::TlvItemValueEnc::UInt16(enhanced_hue)).into(),
548 (1, tlv::TlvItemValueEnc::UInt8(saturation)).into(),
549 (2, tlv::TlvItemValueEnc::UInt16(transition_time)).into(),
550 (3, tlv::TlvItemValueEnc::UInt8(options_mask)).into(),
551 (4, tlv::TlvItemValueEnc::UInt8(options_override)).into(),
552 ]),
553 };
554 Ok(tlv.encode()?)
555}
556
557pub fn encode_color_loop_set(update_flags: UpdateFlags, action: ColorLoopAction, direction: ColorLoopDirection, time: u16, start_hue: u16, options_mask: Options, options_override: Options) -> anyhow::Result<Vec<u8>> {
559 let tlv = tlv::TlvItemEnc {
560 tag: 0,
561 value: tlv::TlvItemValueEnc::StructInvisible(vec![
562 (0, tlv::TlvItemValueEnc::UInt8(update_flags)).into(),
563 (1, tlv::TlvItemValueEnc::UInt8(action.to_u8())).into(),
564 (2, tlv::TlvItemValueEnc::UInt8(direction.to_u8())).into(),
565 (3, tlv::TlvItemValueEnc::UInt16(time)).into(),
566 (4, tlv::TlvItemValueEnc::UInt16(start_hue)).into(),
567 (5, tlv::TlvItemValueEnc::UInt8(options_mask)).into(),
568 (6, tlv::TlvItemValueEnc::UInt8(options_override)).into(),
569 ]),
570 };
571 Ok(tlv.encode()?)
572}
573
574pub fn encode_stop_move_step(options_mask: Options, options_override: Options) -> anyhow::Result<Vec<u8>> {
576 let tlv = tlv::TlvItemEnc {
577 tag: 0,
578 value: tlv::TlvItemValueEnc::StructInvisible(vec![
579 (0, tlv::TlvItemValueEnc::UInt8(options_mask)).into(),
580 (1, tlv::TlvItemValueEnc::UInt8(options_override)).into(),
581 ]),
582 };
583 Ok(tlv.encode()?)
584}
585
586pub fn encode_move_color_temperature(move_mode: MoveMode, rate: u16, color_temperature_minimum_mireds: u16, color_temperature_maximum_mireds: u16, options_mask: Options, options_override: Options) -> anyhow::Result<Vec<u8>> {
588 let tlv = tlv::TlvItemEnc {
589 tag: 0,
590 value: tlv::TlvItemValueEnc::StructInvisible(vec![
591 (0, tlv::TlvItemValueEnc::UInt8(move_mode.to_u8())).into(),
592 (1, tlv::TlvItemValueEnc::UInt16(rate)).into(),
593 (2, tlv::TlvItemValueEnc::UInt16(color_temperature_minimum_mireds)).into(),
594 (3, tlv::TlvItemValueEnc::UInt16(color_temperature_maximum_mireds)).into(),
595 (4, tlv::TlvItemValueEnc::UInt8(options_mask)).into(),
596 (5, tlv::TlvItemValueEnc::UInt8(options_override)).into(),
597 ]),
598 };
599 Ok(tlv.encode()?)
600}
601
602pub fn encode_step_color_temperature(step_mode: StepMode, step_size: u16, transition_time: u16, color_temperature_minimum_mireds: u16, color_temperature_maximum_mireds: u16, options_mask: Options, options_override: Options) -> anyhow::Result<Vec<u8>> {
604 let tlv = tlv::TlvItemEnc {
605 tag: 0,
606 value: tlv::TlvItemValueEnc::StructInvisible(vec![
607 (0, tlv::TlvItemValueEnc::UInt8(step_mode.to_u8())).into(),
608 (1, tlv::TlvItemValueEnc::UInt16(step_size)).into(),
609 (2, tlv::TlvItemValueEnc::UInt16(transition_time)).into(),
610 (3, tlv::TlvItemValueEnc::UInt16(color_temperature_minimum_mireds)).into(),
611 (4, tlv::TlvItemValueEnc::UInt16(color_temperature_maximum_mireds)).into(),
612 (5, tlv::TlvItemValueEnc::UInt8(options_mask)).into(),
613 (6, tlv::TlvItemValueEnc::UInt8(options_override)).into(),
614 ]),
615 };
616 Ok(tlv.encode()?)
617}
618
619pub fn decode_current_hue(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
623 if let tlv::TlvItemValue::Int(v) = inp {
624 Ok(*v as u8)
625 } else {
626 Err(anyhow::anyhow!("Expected UInt8"))
627 }
628}
629
630pub fn decode_current_saturation(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
632 if let tlv::TlvItemValue::Int(v) = inp {
633 Ok(*v as u8)
634 } else {
635 Err(anyhow::anyhow!("Expected UInt8"))
636 }
637}
638
639pub fn decode_remaining_time(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
641 if let tlv::TlvItemValue::Int(v) = inp {
642 Ok(*v as u16)
643 } else {
644 Err(anyhow::anyhow!("Expected UInt16"))
645 }
646}
647
648pub fn decode_current_x(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
650 if let tlv::TlvItemValue::Int(v) = inp {
651 Ok(*v as u16)
652 } else {
653 Err(anyhow::anyhow!("Expected UInt16"))
654 }
655}
656
657pub fn decode_current_y(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
659 if let tlv::TlvItemValue::Int(v) = inp {
660 Ok(*v as u16)
661 } else {
662 Err(anyhow::anyhow!("Expected UInt16"))
663 }
664}
665
666pub fn decode_drift_compensation(inp: &tlv::TlvItemValue) -> anyhow::Result<DriftCompensation> {
668 if let tlv::TlvItemValue::Int(v) = inp {
669 DriftCompensation::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
670 } else {
671 Err(anyhow::anyhow!("Expected Integer"))
672 }
673}
674
675pub fn decode_compensation_text(inp: &tlv::TlvItemValue) -> anyhow::Result<String> {
677 if let tlv::TlvItemValue::String(v) = inp {
678 Ok(v.clone())
679 } else {
680 Err(anyhow::anyhow!("Expected String"))
681 }
682}
683
684pub fn decode_color_temperature_mireds(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
686 if let tlv::TlvItemValue::Int(v) = inp {
687 Ok(*v as u16)
688 } else {
689 Err(anyhow::anyhow!("Expected UInt16"))
690 }
691}
692
693pub fn decode_color_mode(inp: &tlv::TlvItemValue) -> anyhow::Result<ColorMode> {
695 if let tlv::TlvItemValue::Int(v) = inp {
696 ColorMode::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
697 } else {
698 Err(anyhow::anyhow!("Expected Integer"))
699 }
700}
701
702pub fn decode_options(inp: &tlv::TlvItemValue) -> anyhow::Result<Options> {
704 if let tlv::TlvItemValue::Int(v) = inp {
705 Ok(*v as u8)
706 } else {
707 Err(anyhow::anyhow!("Expected Integer"))
708 }
709}
710
711pub fn decode_number_of_primaries(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
713 if let tlv::TlvItemValue::Int(v) = inp {
714 Ok(Some(*v as u8))
715 } else {
716 Ok(None)
717 }
718}
719
720pub fn decode_primary1_x(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
722 if let tlv::TlvItemValue::Int(v) = inp {
723 Ok(*v as u16)
724 } else {
725 Err(anyhow::anyhow!("Expected UInt16"))
726 }
727}
728
729pub fn decode_primary1_y(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
731 if let tlv::TlvItemValue::Int(v) = inp {
732 Ok(*v as u16)
733 } else {
734 Err(anyhow::anyhow!("Expected UInt16"))
735 }
736}
737
738pub fn decode_primary1_intensity(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
740 if let tlv::TlvItemValue::Int(v) = inp {
741 Ok(Some(*v as u8))
742 } else {
743 Ok(None)
744 }
745}
746
747pub fn decode_primary2_x(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
749 if let tlv::TlvItemValue::Int(v) = inp {
750 Ok(*v as u16)
751 } else {
752 Err(anyhow::anyhow!("Expected UInt16"))
753 }
754}
755
756pub fn decode_primary2_y(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
758 if let tlv::TlvItemValue::Int(v) = inp {
759 Ok(*v as u16)
760 } else {
761 Err(anyhow::anyhow!("Expected UInt16"))
762 }
763}
764
765pub fn decode_primary2_intensity(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
767 if let tlv::TlvItemValue::Int(v) = inp {
768 Ok(Some(*v as u8))
769 } else {
770 Ok(None)
771 }
772}
773
774pub fn decode_primary3_x(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
776 if let tlv::TlvItemValue::Int(v) = inp {
777 Ok(*v as u16)
778 } else {
779 Err(anyhow::anyhow!("Expected UInt16"))
780 }
781}
782
783pub fn decode_primary3_y(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
785 if let tlv::TlvItemValue::Int(v) = inp {
786 Ok(*v as u16)
787 } else {
788 Err(anyhow::anyhow!("Expected UInt16"))
789 }
790}
791
792pub fn decode_primary3_intensity(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
794 if let tlv::TlvItemValue::Int(v) = inp {
795 Ok(Some(*v as u8))
796 } else {
797 Ok(None)
798 }
799}
800
801pub fn decode_primary4_x(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
803 if let tlv::TlvItemValue::Int(v) = inp {
804 Ok(*v as u16)
805 } else {
806 Err(anyhow::anyhow!("Expected UInt16"))
807 }
808}
809
810pub fn decode_primary4_y(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
812 if let tlv::TlvItemValue::Int(v) = inp {
813 Ok(*v as u16)
814 } else {
815 Err(anyhow::anyhow!("Expected UInt16"))
816 }
817}
818
819pub fn decode_primary4_intensity(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
821 if let tlv::TlvItemValue::Int(v) = inp {
822 Ok(Some(*v as u8))
823 } else {
824 Ok(None)
825 }
826}
827
828pub fn decode_primary5_x(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
830 if let tlv::TlvItemValue::Int(v) = inp {
831 Ok(*v as u16)
832 } else {
833 Err(anyhow::anyhow!("Expected UInt16"))
834 }
835}
836
837pub fn decode_primary5_y(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
839 if let tlv::TlvItemValue::Int(v) = inp {
840 Ok(*v as u16)
841 } else {
842 Err(anyhow::anyhow!("Expected UInt16"))
843 }
844}
845
846pub fn decode_primary5_intensity(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
848 if let tlv::TlvItemValue::Int(v) = inp {
849 Ok(Some(*v as u8))
850 } else {
851 Ok(None)
852 }
853}
854
855pub fn decode_primary6_x(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
857 if let tlv::TlvItemValue::Int(v) = inp {
858 Ok(*v as u16)
859 } else {
860 Err(anyhow::anyhow!("Expected UInt16"))
861 }
862}
863
864pub fn decode_primary6_y(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
866 if let tlv::TlvItemValue::Int(v) = inp {
867 Ok(*v as u16)
868 } else {
869 Err(anyhow::anyhow!("Expected UInt16"))
870 }
871}
872
873pub fn decode_primary6_intensity(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
875 if let tlv::TlvItemValue::Int(v) = inp {
876 Ok(Some(*v as u8))
877 } else {
878 Ok(None)
879 }
880}
881
882pub fn decode_white_point_x(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
884 if let tlv::TlvItemValue::Int(v) = inp {
885 Ok(*v as u16)
886 } else {
887 Err(anyhow::anyhow!("Expected UInt16"))
888 }
889}
890
891pub fn decode_white_point_y(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
893 if let tlv::TlvItemValue::Int(v) = inp {
894 Ok(*v as u16)
895 } else {
896 Err(anyhow::anyhow!("Expected UInt16"))
897 }
898}
899
900pub fn decode_color_point_rx(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
902 if let tlv::TlvItemValue::Int(v) = inp {
903 Ok(*v as u16)
904 } else {
905 Err(anyhow::anyhow!("Expected UInt16"))
906 }
907}
908
909pub fn decode_color_point_ry(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
911 if let tlv::TlvItemValue::Int(v) = inp {
912 Ok(*v as u16)
913 } else {
914 Err(anyhow::anyhow!("Expected UInt16"))
915 }
916}
917
918pub fn decode_color_point_r_intensity(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
920 if let tlv::TlvItemValue::Int(v) = inp {
921 Ok(Some(*v as u8))
922 } else {
923 Ok(None)
924 }
925}
926
927pub fn decode_color_point_gx(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
929 if let tlv::TlvItemValue::Int(v) = inp {
930 Ok(*v as u16)
931 } else {
932 Err(anyhow::anyhow!("Expected UInt16"))
933 }
934}
935
936pub fn decode_color_point_gy(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
938 if let tlv::TlvItemValue::Int(v) = inp {
939 Ok(*v as u16)
940 } else {
941 Err(anyhow::anyhow!("Expected UInt16"))
942 }
943}
944
945pub fn decode_color_point_g_intensity(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
947 if let tlv::TlvItemValue::Int(v) = inp {
948 Ok(Some(*v as u8))
949 } else {
950 Ok(None)
951 }
952}
953
954pub fn decode_color_point_bx(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
956 if let tlv::TlvItemValue::Int(v) = inp {
957 Ok(*v as u16)
958 } else {
959 Err(anyhow::anyhow!("Expected UInt16"))
960 }
961}
962
963pub fn decode_color_point_by(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
965 if let tlv::TlvItemValue::Int(v) = inp {
966 Ok(*v as u16)
967 } else {
968 Err(anyhow::anyhow!("Expected UInt16"))
969 }
970}
971
972pub fn decode_color_point_b_intensity(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u8>> {
974 if let tlv::TlvItemValue::Int(v) = inp {
975 Ok(Some(*v as u8))
976 } else {
977 Ok(None)
978 }
979}
980
981pub fn decode_enhanced_current_hue(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
983 if let tlv::TlvItemValue::Int(v) = inp {
984 Ok(*v as u16)
985 } else {
986 Err(anyhow::anyhow!("Expected UInt16"))
987 }
988}
989
990pub fn decode_enhanced_color_mode(inp: &tlv::TlvItemValue) -> anyhow::Result<EnhancedColorMode> {
992 if let tlv::TlvItemValue::Int(v) = inp {
993 EnhancedColorMode::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
994 } else {
995 Err(anyhow::anyhow!("Expected Integer"))
996 }
997}
998
999pub fn decode_color_loop_active(inp: &tlv::TlvItemValue) -> anyhow::Result<u8> {
1001 if let tlv::TlvItemValue::Int(v) = inp {
1002 Ok(*v as u8)
1003 } else {
1004 Err(anyhow::anyhow!("Expected UInt8"))
1005 }
1006}
1007
1008pub fn decode_color_loop_direction(inp: &tlv::TlvItemValue) -> anyhow::Result<ColorLoopDirection> {
1010 if let tlv::TlvItemValue::Int(v) = inp {
1011 ColorLoopDirection::from_u8(*v as u8).ok_or_else(|| anyhow::anyhow!("Invalid enum value"))
1012 } else {
1013 Err(anyhow::anyhow!("Expected Integer"))
1014 }
1015}
1016
1017pub fn decode_color_loop_time(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
1019 if let tlv::TlvItemValue::Int(v) = inp {
1020 Ok(*v as u16)
1021 } else {
1022 Err(anyhow::anyhow!("Expected UInt16"))
1023 }
1024}
1025
1026pub fn decode_color_loop_start_enhanced_hue(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
1028 if let tlv::TlvItemValue::Int(v) = inp {
1029 Ok(*v as u16)
1030 } else {
1031 Err(anyhow::anyhow!("Expected UInt16"))
1032 }
1033}
1034
1035pub fn decode_color_loop_stored_enhanced_hue(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
1037 if let tlv::TlvItemValue::Int(v) = inp {
1038 Ok(*v as u16)
1039 } else {
1040 Err(anyhow::anyhow!("Expected UInt16"))
1041 }
1042}
1043
1044pub fn decode_color_capabilities(inp: &tlv::TlvItemValue) -> anyhow::Result<ColorCapabilities> {
1046 if let tlv::TlvItemValue::Int(v) = inp {
1047 Ok(*v as u8)
1048 } else {
1049 Err(anyhow::anyhow!("Expected Integer"))
1050 }
1051}
1052
1053pub fn decode_color_temp_physical_min_mireds(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
1055 if let tlv::TlvItemValue::Int(v) = inp {
1056 Ok(*v as u16)
1057 } else {
1058 Err(anyhow::anyhow!("Expected UInt16"))
1059 }
1060}
1061
1062pub fn decode_color_temp_physical_max_mireds(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
1064 if let tlv::TlvItemValue::Int(v) = inp {
1065 Ok(*v as u16)
1066 } else {
1067 Err(anyhow::anyhow!("Expected UInt16"))
1068 }
1069}
1070
1071pub fn decode_couple_color_temp_to_level_min_mireds(inp: &tlv::TlvItemValue) -> anyhow::Result<u16> {
1073 if let tlv::TlvItemValue::Int(v) = inp {
1074 Ok(*v as u16)
1075 } else {
1076 Err(anyhow::anyhow!("Expected UInt16"))
1077 }
1078}
1079
1080pub fn decode_start_up_color_temperature_mireds(inp: &tlv::TlvItemValue) -> anyhow::Result<Option<u16>> {
1082 if let tlv::TlvItemValue::Int(v) = inp {
1083 Ok(Some(*v as u16))
1084 } else {
1085 Ok(None)
1086 }
1087}
1088
1089
1090pub fn decode_attribute_json(cluster_id: u32, attribute_id: u32, tlv_value: &crate::tlv::TlvItemValue) -> String {
1102 if cluster_id != 0x0300 {
1104 return format!("{{\"error\": \"Invalid cluster ID. Expected 0x0300, got {}\"}}", cluster_id);
1105 }
1106
1107 match attribute_id {
1108 0x0000 => {
1109 match decode_current_hue(tlv_value) {
1110 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1111 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1112 }
1113 }
1114 0x0001 => {
1115 match decode_current_saturation(tlv_value) {
1116 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1117 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1118 }
1119 }
1120 0x0002 => {
1121 match decode_remaining_time(tlv_value) {
1122 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1123 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1124 }
1125 }
1126 0x0003 => {
1127 match decode_current_x(tlv_value) {
1128 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1129 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1130 }
1131 }
1132 0x0004 => {
1133 match decode_current_y(tlv_value) {
1134 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1135 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1136 }
1137 }
1138 0x0005 => {
1139 match decode_drift_compensation(tlv_value) {
1140 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1141 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1142 }
1143 }
1144 0x0006 => {
1145 match decode_compensation_text(tlv_value) {
1146 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1147 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1148 }
1149 }
1150 0x0007 => {
1151 match decode_color_temperature_mireds(tlv_value) {
1152 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1153 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1154 }
1155 }
1156 0x0008 => {
1157 match decode_color_mode(tlv_value) {
1158 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1159 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1160 }
1161 }
1162 0x000F => {
1163 match decode_options(tlv_value) {
1164 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1165 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1166 }
1167 }
1168 0x0010 => {
1169 match decode_number_of_primaries(tlv_value) {
1170 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1171 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1172 }
1173 }
1174 0x0011 => {
1175 match decode_primary1_x(tlv_value) {
1176 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1177 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1178 }
1179 }
1180 0x0012 => {
1181 match decode_primary1_y(tlv_value) {
1182 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1183 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1184 }
1185 }
1186 0x0013 => {
1187 match decode_primary1_intensity(tlv_value) {
1188 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1189 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1190 }
1191 }
1192 0x0015 => {
1193 match decode_primary2_x(tlv_value) {
1194 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1195 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1196 }
1197 }
1198 0x0016 => {
1199 match decode_primary2_y(tlv_value) {
1200 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1201 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1202 }
1203 }
1204 0x0017 => {
1205 match decode_primary2_intensity(tlv_value) {
1206 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1207 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1208 }
1209 }
1210 0x0019 => {
1211 match decode_primary3_x(tlv_value) {
1212 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1213 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1214 }
1215 }
1216 0x001A => {
1217 match decode_primary3_y(tlv_value) {
1218 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1219 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1220 }
1221 }
1222 0x001B => {
1223 match decode_primary3_intensity(tlv_value) {
1224 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1225 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1226 }
1227 }
1228 0x0020 => {
1229 match decode_primary4_x(tlv_value) {
1230 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1231 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1232 }
1233 }
1234 0x0021 => {
1235 match decode_primary4_y(tlv_value) {
1236 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1237 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1238 }
1239 }
1240 0x0022 => {
1241 match decode_primary4_intensity(tlv_value) {
1242 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1243 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1244 }
1245 }
1246 0x0024 => {
1247 match decode_primary5_x(tlv_value) {
1248 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1249 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1250 }
1251 }
1252 0x0025 => {
1253 match decode_primary5_y(tlv_value) {
1254 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1255 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1256 }
1257 }
1258 0x0026 => {
1259 match decode_primary5_intensity(tlv_value) {
1260 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1261 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1262 }
1263 }
1264 0x0028 => {
1265 match decode_primary6_x(tlv_value) {
1266 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1267 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1268 }
1269 }
1270 0x0029 => {
1271 match decode_primary6_y(tlv_value) {
1272 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1273 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1274 }
1275 }
1276 0x002A => {
1277 match decode_primary6_intensity(tlv_value) {
1278 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1279 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1280 }
1281 }
1282 0x0030 => {
1283 match decode_white_point_x(tlv_value) {
1284 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1285 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1286 }
1287 }
1288 0x0031 => {
1289 match decode_white_point_y(tlv_value) {
1290 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1291 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1292 }
1293 }
1294 0x0032 => {
1295 match decode_color_point_rx(tlv_value) {
1296 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1297 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1298 }
1299 }
1300 0x0033 => {
1301 match decode_color_point_ry(tlv_value) {
1302 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1303 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1304 }
1305 }
1306 0x0034 => {
1307 match decode_color_point_r_intensity(tlv_value) {
1308 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1309 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1310 }
1311 }
1312 0x0036 => {
1313 match decode_color_point_gx(tlv_value) {
1314 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1315 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1316 }
1317 }
1318 0x0037 => {
1319 match decode_color_point_gy(tlv_value) {
1320 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1321 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1322 }
1323 }
1324 0x0038 => {
1325 match decode_color_point_g_intensity(tlv_value) {
1326 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1327 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1328 }
1329 }
1330 0x003A => {
1331 match decode_color_point_bx(tlv_value) {
1332 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1333 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1334 }
1335 }
1336 0x003B => {
1337 match decode_color_point_by(tlv_value) {
1338 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1339 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1340 }
1341 }
1342 0x003C => {
1343 match decode_color_point_b_intensity(tlv_value) {
1344 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1345 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1346 }
1347 }
1348 0x4000 => {
1349 match decode_enhanced_current_hue(tlv_value) {
1350 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1351 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1352 }
1353 }
1354 0x4001 => {
1355 match decode_enhanced_color_mode(tlv_value) {
1356 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1357 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1358 }
1359 }
1360 0x4002 => {
1361 match decode_color_loop_active(tlv_value) {
1362 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1363 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1364 }
1365 }
1366 0x4003 => {
1367 match decode_color_loop_direction(tlv_value) {
1368 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1369 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1370 }
1371 }
1372 0x4004 => {
1373 match decode_color_loop_time(tlv_value) {
1374 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1375 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1376 }
1377 }
1378 0x4005 => {
1379 match decode_color_loop_start_enhanced_hue(tlv_value) {
1380 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1381 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1382 }
1383 }
1384 0x4006 => {
1385 match decode_color_loop_stored_enhanced_hue(tlv_value) {
1386 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1387 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1388 }
1389 }
1390 0x400A => {
1391 match decode_color_capabilities(tlv_value) {
1392 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1393 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1394 }
1395 }
1396 0x400B => {
1397 match decode_color_temp_physical_min_mireds(tlv_value) {
1398 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1399 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1400 }
1401 }
1402 0x400C => {
1403 match decode_color_temp_physical_max_mireds(tlv_value) {
1404 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1405 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1406 }
1407 }
1408 0x400D => {
1409 match decode_couple_color_temp_to_level_min_mireds(tlv_value) {
1410 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1411 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1412 }
1413 }
1414 0x4010 => {
1415 match decode_start_up_color_temperature_mireds(tlv_value) {
1416 Ok(value) => serde_json::to_string(&value).unwrap_or_else(|_| "null".to_string()),
1417 Err(e) => format!("{{\"error\": \"{}\"}}", e),
1418 }
1419 }
1420 _ => format!("{{\"error\": \"Unknown attribute ID: {}\"}}", attribute_id),
1421 }
1422}
1423
1424pub fn get_attribute_list() -> Vec<(u32, &'static str)> {
1429 vec![
1430 (0x0000, "CurrentHue"),
1431 (0x0001, "CurrentSaturation"),
1432 (0x0002, "RemainingTime"),
1433 (0x0003, "CurrentX"),
1434 (0x0004, "CurrentY"),
1435 (0x0005, "DriftCompensation"),
1436 (0x0006, "CompensationText"),
1437 (0x0007, "ColorTemperatureMireds"),
1438 (0x0008, "ColorMode"),
1439 (0x000F, "Options"),
1440 (0x0010, "NumberOfPrimaries"),
1441 (0x0011, "Primary1X"),
1442 (0x0012, "Primary1Y"),
1443 (0x0013, "Primary1Intensity"),
1444 (0x0015, "Primary2X"),
1445 (0x0016, "Primary2Y"),
1446 (0x0017, "Primary2Intensity"),
1447 (0x0019, "Primary3X"),
1448 (0x001A, "Primary3Y"),
1449 (0x001B, "Primary3Intensity"),
1450 (0x0020, "Primary4X"),
1451 (0x0021, "Primary4Y"),
1452 (0x0022, "Primary4Intensity"),
1453 (0x0024, "Primary5X"),
1454 (0x0025, "Primary5Y"),
1455 (0x0026, "Primary5Intensity"),
1456 (0x0028, "Primary6X"),
1457 (0x0029, "Primary6Y"),
1458 (0x002A, "Primary6Intensity"),
1459 (0x0030, "WhitePointX"),
1460 (0x0031, "WhitePointY"),
1461 (0x0032, "ColorPointRX"),
1462 (0x0033, "ColorPointRY"),
1463 (0x0034, "ColorPointRIntensity"),
1464 (0x0036, "ColorPointGX"),
1465 (0x0037, "ColorPointGY"),
1466 (0x0038, "ColorPointGIntensity"),
1467 (0x003A, "ColorPointBX"),
1468 (0x003B, "ColorPointBY"),
1469 (0x003C, "ColorPointBIntensity"),
1470 (0x4000, "EnhancedCurrentHue"),
1471 (0x4001, "EnhancedColorMode"),
1472 (0x4002, "ColorLoopActive"),
1473 (0x4003, "ColorLoopDirection"),
1474 (0x4004, "ColorLoopTime"),
1475 (0x4005, "ColorLoopStartEnhancedHue"),
1476 (0x4006, "ColorLoopStoredEnhancedHue"),
1477 (0x400A, "ColorCapabilities"),
1478 (0x400B, "ColorTempPhysicalMinMireds"),
1479 (0x400C, "ColorTempPhysicalMaxMireds"),
1480 (0x400D, "CoupleColorTempToLevelMinMireds"),
1481 (0x4010, "StartUpColorTemperatureMireds"),
1482 ]
1483}
1484
1485pub fn get_command_list() -> Vec<(u32, &'static str)> {
1488 vec![
1489 (0x00, "MoveToHue"),
1490 (0x01, "MoveHue"),
1491 (0x02, "StepHue"),
1492 (0x03, "MoveToSaturation"),
1493 (0x04, "MoveSaturation"),
1494 (0x05, "StepSaturation"),
1495 (0x06, "MoveToHueAndSaturation"),
1496 (0x07, "MoveToColor"),
1497 (0x08, "MoveColor"),
1498 (0x09, "StepColor"),
1499 (0x0A, "MoveToColorTemperature"),
1500 (0x40, "EnhancedMoveToHue"),
1501 (0x41, "EnhancedMoveHue"),
1502 (0x42, "EnhancedStepHue"),
1503 (0x43, "EnhancedMoveToHueAndSaturation"),
1504 (0x44, "ColorLoopSet"),
1505 (0x47, "StopMoveStep"),
1506 (0x4B, "MoveColorTemperature"),
1507 (0x4C, "StepColorTemperature"),
1508 ]
1509}
1510
1511pub fn get_command_name(cmd_id: u32) -> Option<&'static str> {
1512 match cmd_id {
1513 0x00 => Some("MoveToHue"),
1514 0x01 => Some("MoveHue"),
1515 0x02 => Some("StepHue"),
1516 0x03 => Some("MoveToSaturation"),
1517 0x04 => Some("MoveSaturation"),
1518 0x05 => Some("StepSaturation"),
1519 0x06 => Some("MoveToHueAndSaturation"),
1520 0x07 => Some("MoveToColor"),
1521 0x08 => Some("MoveColor"),
1522 0x09 => Some("StepColor"),
1523 0x0A => Some("MoveToColorTemperature"),
1524 0x40 => Some("EnhancedMoveToHue"),
1525 0x41 => Some("EnhancedMoveHue"),
1526 0x42 => Some("EnhancedStepHue"),
1527 0x43 => Some("EnhancedMoveToHueAndSaturation"),
1528 0x44 => Some("ColorLoopSet"),
1529 0x47 => Some("StopMoveStep"),
1530 0x4B => Some("MoveColorTemperature"),
1531 0x4C => Some("StepColorTemperature"),
1532 _ => None,
1533 }
1534}
1535
1536pub fn get_command_schema(cmd_id: u32) -> Option<Vec<crate::clusters::codec::CommandField>> {
1537 match cmd_id {
1538 0x00 => Some(vec![
1539 crate::clusters::codec::CommandField { tag: 0, name: "hue", kind: crate::clusters::codec::FieldKind::U8, optional: false, nullable: false },
1540 crate::clusters::codec::CommandField { tag: 1, name: "direction", kind: crate::clusters::codec::FieldKind::Enum { name: "Direction", variants: &[(0, "Shortest"), (1, "Longest"), (2, "Up"), (3, "Down")] }, optional: false, nullable: false },
1541 crate::clusters::codec::CommandField { tag: 2, name: "transition_time", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1542 crate::clusters::codec::CommandField { tag: 3, name: "options_mask", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1543 crate::clusters::codec::CommandField { tag: 4, name: "options_override", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1544 ]),
1545 0x01 => Some(vec![
1546 crate::clusters::codec::CommandField { tag: 0, name: "move_mode", kind: crate::clusters::codec::FieldKind::Enum { name: "MoveMode", variants: &[(0, "Stop"), (1, "Up"), (3, "Down")] }, optional: false, nullable: false },
1547 crate::clusters::codec::CommandField { tag: 1, name: "rate", kind: crate::clusters::codec::FieldKind::U8, optional: false, nullable: false },
1548 crate::clusters::codec::CommandField { tag: 2, name: "options_mask", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1549 crate::clusters::codec::CommandField { tag: 3, name: "options_override", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1550 ]),
1551 0x02 => Some(vec![
1552 crate::clusters::codec::CommandField { tag: 0, name: "step_mode", kind: crate::clusters::codec::FieldKind::Enum { name: "StepMode", variants: &[(1, "Up"), (3, "Down")] }, optional: false, nullable: false },
1553 crate::clusters::codec::CommandField { tag: 1, name: "step_size", kind: crate::clusters::codec::FieldKind::U8, optional: false, nullable: false },
1554 crate::clusters::codec::CommandField { tag: 2, name: "transition_time", kind: crate::clusters::codec::FieldKind::U8, optional: false, nullable: false },
1555 crate::clusters::codec::CommandField { tag: 3, name: "options_mask", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1556 crate::clusters::codec::CommandField { tag: 4, name: "options_override", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1557 ]),
1558 0x03 => Some(vec![
1559 crate::clusters::codec::CommandField { tag: 0, name: "saturation", kind: crate::clusters::codec::FieldKind::U8, optional: false, nullable: false },
1560 crate::clusters::codec::CommandField { tag: 1, name: "transition_time", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1561 crate::clusters::codec::CommandField { tag: 2, name: "options_mask", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1562 crate::clusters::codec::CommandField { tag: 3, name: "options_override", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1563 ]),
1564 0x04 => Some(vec![
1565 crate::clusters::codec::CommandField { tag: 0, name: "move_mode", kind: crate::clusters::codec::FieldKind::Enum { name: "MoveMode", variants: &[(0, "Stop"), (1, "Up"), (3, "Down")] }, optional: false, nullable: false },
1566 crate::clusters::codec::CommandField { tag: 1, name: "rate", kind: crate::clusters::codec::FieldKind::U8, optional: false, nullable: false },
1567 crate::clusters::codec::CommandField { tag: 2, name: "options_mask", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1568 crate::clusters::codec::CommandField { tag: 3, name: "options_override", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1569 ]),
1570 0x05 => Some(vec![
1571 crate::clusters::codec::CommandField { tag: 0, name: "step_mode", kind: crate::clusters::codec::FieldKind::Enum { name: "StepMode", variants: &[(1, "Up"), (3, "Down")] }, optional: false, nullable: false },
1572 crate::clusters::codec::CommandField { tag: 1, name: "step_size", kind: crate::clusters::codec::FieldKind::U8, optional: false, nullable: false },
1573 crate::clusters::codec::CommandField { tag: 2, name: "transition_time", kind: crate::clusters::codec::FieldKind::U8, optional: false, nullable: false },
1574 crate::clusters::codec::CommandField { tag: 3, name: "options_mask", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1575 crate::clusters::codec::CommandField { tag: 4, name: "options_override", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1576 ]),
1577 0x06 => Some(vec![
1578 crate::clusters::codec::CommandField { tag: 0, name: "hue", kind: crate::clusters::codec::FieldKind::U8, optional: false, nullable: false },
1579 crate::clusters::codec::CommandField { tag: 1, name: "saturation", kind: crate::clusters::codec::FieldKind::U8, optional: false, nullable: false },
1580 crate::clusters::codec::CommandField { tag: 2, name: "transition_time", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1581 crate::clusters::codec::CommandField { tag: 3, name: "options_mask", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1582 crate::clusters::codec::CommandField { tag: 4, name: "options_override", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1583 ]),
1584 0x07 => Some(vec![
1585 crate::clusters::codec::CommandField { tag: 0, name: "color_x", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1586 crate::clusters::codec::CommandField { tag: 1, name: "color_y", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1587 crate::clusters::codec::CommandField { tag: 2, name: "transition_time", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1588 crate::clusters::codec::CommandField { tag: 3, name: "options_mask", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1589 crate::clusters::codec::CommandField { tag: 4, name: "options_override", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1590 ]),
1591 0x08 => Some(vec![
1592 crate::clusters::codec::CommandField { tag: 0, name: "rate_x", kind: crate::clusters::codec::FieldKind::I16, optional: false, nullable: false },
1593 crate::clusters::codec::CommandField { tag: 1, name: "rate_y", kind: crate::clusters::codec::FieldKind::I16, optional: false, nullable: false },
1594 crate::clusters::codec::CommandField { tag: 2, name: "options_mask", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1595 crate::clusters::codec::CommandField { tag: 3, name: "options_override", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1596 ]),
1597 0x09 => Some(vec![
1598 crate::clusters::codec::CommandField { tag: 0, name: "step_x", kind: crate::clusters::codec::FieldKind::I16, optional: false, nullable: false },
1599 crate::clusters::codec::CommandField { tag: 1, name: "step_y", kind: crate::clusters::codec::FieldKind::I16, optional: false, nullable: false },
1600 crate::clusters::codec::CommandField { tag: 2, name: "transition_time", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1601 crate::clusters::codec::CommandField { tag: 3, name: "options_mask", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1602 crate::clusters::codec::CommandField { tag: 4, name: "options_override", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1603 ]),
1604 0x0A => Some(vec![
1605 crate::clusters::codec::CommandField { tag: 0, name: "color_temperature_mireds", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1606 crate::clusters::codec::CommandField { tag: 1, name: "transition_time", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1607 crate::clusters::codec::CommandField { tag: 2, name: "options_mask", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1608 crate::clusters::codec::CommandField { tag: 3, name: "options_override", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1609 ]),
1610 0x40 => Some(vec![
1611 crate::clusters::codec::CommandField { tag: 0, name: "enhanced_hue", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1612 crate::clusters::codec::CommandField { tag: 1, name: "direction", kind: crate::clusters::codec::FieldKind::Enum { name: "Direction", variants: &[(0, "Shortest"), (1, "Longest"), (2, "Up"), (3, "Down")] }, optional: false, nullable: false },
1613 crate::clusters::codec::CommandField { tag: 2, name: "transition_time", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1614 crate::clusters::codec::CommandField { tag: 3, name: "options_mask", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1615 crate::clusters::codec::CommandField { tag: 4, name: "options_override", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1616 ]),
1617 0x41 => Some(vec![
1618 crate::clusters::codec::CommandField { tag: 0, name: "move_mode", kind: crate::clusters::codec::FieldKind::Enum { name: "MoveMode", variants: &[(0, "Stop"), (1, "Up"), (3, "Down")] }, optional: false, nullable: false },
1619 crate::clusters::codec::CommandField { tag: 1, name: "rate", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1620 crate::clusters::codec::CommandField { tag: 2, name: "options_mask", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1621 crate::clusters::codec::CommandField { tag: 3, name: "options_override", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1622 ]),
1623 0x42 => Some(vec![
1624 crate::clusters::codec::CommandField { tag: 0, name: "step_mode", kind: crate::clusters::codec::FieldKind::Enum { name: "StepMode", variants: &[(1, "Up"), (3, "Down")] }, optional: false, nullable: false },
1625 crate::clusters::codec::CommandField { tag: 1, name: "step_size", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1626 crate::clusters::codec::CommandField { tag: 2, name: "transition_time", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1627 crate::clusters::codec::CommandField { tag: 3, name: "options_mask", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1628 crate::clusters::codec::CommandField { tag: 4, name: "options_override", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1629 ]),
1630 0x43 => Some(vec![
1631 crate::clusters::codec::CommandField { tag: 0, name: "enhanced_hue", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1632 crate::clusters::codec::CommandField { tag: 1, name: "saturation", kind: crate::clusters::codec::FieldKind::U8, optional: false, nullable: false },
1633 crate::clusters::codec::CommandField { tag: 2, name: "transition_time", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1634 crate::clusters::codec::CommandField { tag: 3, name: "options_mask", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1635 crate::clusters::codec::CommandField { tag: 4, name: "options_override", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1636 ]),
1637 0x44 => Some(vec![
1638 crate::clusters::codec::CommandField { tag: 0, name: "update_flags", kind: crate::clusters::codec::FieldKind::Bitmap { name: "UpdateFlags", bits: &[(1, "UPDATE_ACTION"), (2, "UPDATE_DIRECTION"), (4, "UPDATE_TIME"), (8, "UPDATE_START_HUE")] }, optional: false, nullable: false },
1639 crate::clusters::codec::CommandField { tag: 1, name: "action", kind: crate::clusters::codec::FieldKind::Enum { name: "ColorLoopAction", variants: &[(0, "Deactivate"), (1, "Activatefromcolorloopstartenhancedhue"), (2, "Activatefromenhancedcurrenthue")] }, optional: false, nullable: false },
1640 crate::clusters::codec::CommandField { tag: 2, name: "direction", kind: crate::clusters::codec::FieldKind::Enum { name: "ColorLoopDirection", variants: &[(0, "Decrement"), (1, "Increment")] }, optional: false, nullable: false },
1641 crate::clusters::codec::CommandField { tag: 3, name: "time", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1642 crate::clusters::codec::CommandField { tag: 4, name: "start_hue", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1643 crate::clusters::codec::CommandField { tag: 5, name: "options_mask", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1644 crate::clusters::codec::CommandField { tag: 6, name: "options_override", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1645 ]),
1646 0x47 => Some(vec![
1647 crate::clusters::codec::CommandField { tag: 0, name: "options_mask", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1648 crate::clusters::codec::CommandField { tag: 1, name: "options_override", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1649 ]),
1650 0x4B => Some(vec![
1651 crate::clusters::codec::CommandField { tag: 0, name: "move_mode", kind: crate::clusters::codec::FieldKind::Enum { name: "MoveMode", variants: &[(0, "Stop"), (1, "Up"), (3, "Down")] }, optional: false, nullable: false },
1652 crate::clusters::codec::CommandField { tag: 1, name: "rate", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1653 crate::clusters::codec::CommandField { tag: 2, name: "color_temperature_minimum_mireds", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1654 crate::clusters::codec::CommandField { tag: 3, name: "color_temperature_maximum_mireds", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1655 crate::clusters::codec::CommandField { tag: 4, name: "options_mask", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1656 crate::clusters::codec::CommandField { tag: 5, name: "options_override", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1657 ]),
1658 0x4C => Some(vec![
1659 crate::clusters::codec::CommandField { tag: 0, name: "step_mode", kind: crate::clusters::codec::FieldKind::Enum { name: "StepMode", variants: &[(1, "Up"), (3, "Down")] }, optional: false, nullable: false },
1660 crate::clusters::codec::CommandField { tag: 1, name: "step_size", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1661 crate::clusters::codec::CommandField { tag: 2, name: "transition_time", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1662 crate::clusters::codec::CommandField { tag: 3, name: "color_temperature_minimum_mireds", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1663 crate::clusters::codec::CommandField { tag: 4, name: "color_temperature_maximum_mireds", kind: crate::clusters::codec::FieldKind::U16, optional: false, nullable: false },
1664 crate::clusters::codec::CommandField { tag: 5, name: "options_mask", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1665 crate::clusters::codec::CommandField { tag: 6, name: "options_override", kind: crate::clusters::codec::FieldKind::Bitmap { name: "Options", bits: &[(1, "EXECUTE_IF_OFF")] }, optional: false, nullable: false },
1666 ]),
1667 _ => None,
1668 }
1669}
1670
1671pub fn encode_command_json(cmd_id: u32, args: &serde_json::Value) -> anyhow::Result<Vec<u8>> {
1672 match cmd_id {
1673 0x00 => {
1674 let hue = crate::clusters::codec::json_util::get_u8(args, "hue")?;
1675 let direction = {
1676 let n = crate::clusters::codec::json_util::get_u64(args, "direction")?;
1677 Direction::from_u8(n as u8).ok_or_else(|| anyhow::anyhow!("invalid Direction: {}", n))?
1678 };
1679 let transition_time = crate::clusters::codec::json_util::get_u16(args, "transition_time")?;
1680 let options_mask = crate::clusters::codec::json_util::get_u8(args, "options_mask")?;
1681 let options_override = crate::clusters::codec::json_util::get_u8(args, "options_override")?;
1682 encode_move_to_hue(hue, direction, transition_time, options_mask, options_override)
1683 }
1684 0x01 => {
1685 let move_mode = {
1686 let n = crate::clusters::codec::json_util::get_u64(args, "move_mode")?;
1687 MoveMode::from_u8(n as u8).ok_or_else(|| anyhow::anyhow!("invalid MoveMode: {}", n))?
1688 };
1689 let rate = crate::clusters::codec::json_util::get_u8(args, "rate")?;
1690 let options_mask = crate::clusters::codec::json_util::get_u8(args, "options_mask")?;
1691 let options_override = crate::clusters::codec::json_util::get_u8(args, "options_override")?;
1692 encode_move_hue(move_mode, rate, options_mask, options_override)
1693 }
1694 0x02 => {
1695 let step_mode = {
1696 let n = crate::clusters::codec::json_util::get_u64(args, "step_mode")?;
1697 StepMode::from_u8(n as u8).ok_or_else(|| anyhow::anyhow!("invalid StepMode: {}", n))?
1698 };
1699 let step_size = crate::clusters::codec::json_util::get_u8(args, "step_size")?;
1700 let transition_time = crate::clusters::codec::json_util::get_u8(args, "transition_time")?;
1701 let options_mask = crate::clusters::codec::json_util::get_u8(args, "options_mask")?;
1702 let options_override = crate::clusters::codec::json_util::get_u8(args, "options_override")?;
1703 encode_step_hue(step_mode, step_size, transition_time, options_mask, options_override)
1704 }
1705 0x03 => {
1706 let saturation = crate::clusters::codec::json_util::get_u8(args, "saturation")?;
1707 let transition_time = crate::clusters::codec::json_util::get_u16(args, "transition_time")?;
1708 let options_mask = crate::clusters::codec::json_util::get_u8(args, "options_mask")?;
1709 let options_override = crate::clusters::codec::json_util::get_u8(args, "options_override")?;
1710 encode_move_to_saturation(saturation, transition_time, options_mask, options_override)
1711 }
1712 0x04 => {
1713 let move_mode = {
1714 let n = crate::clusters::codec::json_util::get_u64(args, "move_mode")?;
1715 MoveMode::from_u8(n as u8).ok_or_else(|| anyhow::anyhow!("invalid MoveMode: {}", n))?
1716 };
1717 let rate = crate::clusters::codec::json_util::get_u8(args, "rate")?;
1718 let options_mask = crate::clusters::codec::json_util::get_u8(args, "options_mask")?;
1719 let options_override = crate::clusters::codec::json_util::get_u8(args, "options_override")?;
1720 encode_move_saturation(move_mode, rate, options_mask, options_override)
1721 }
1722 0x05 => {
1723 let step_mode = {
1724 let n = crate::clusters::codec::json_util::get_u64(args, "step_mode")?;
1725 StepMode::from_u8(n as u8).ok_or_else(|| anyhow::anyhow!("invalid StepMode: {}", n))?
1726 };
1727 let step_size = crate::clusters::codec::json_util::get_u8(args, "step_size")?;
1728 let transition_time = crate::clusters::codec::json_util::get_u8(args, "transition_time")?;
1729 let options_mask = crate::clusters::codec::json_util::get_u8(args, "options_mask")?;
1730 let options_override = crate::clusters::codec::json_util::get_u8(args, "options_override")?;
1731 encode_step_saturation(step_mode, step_size, transition_time, options_mask, options_override)
1732 }
1733 0x06 => {
1734 let hue = crate::clusters::codec::json_util::get_u8(args, "hue")?;
1735 let saturation = crate::clusters::codec::json_util::get_u8(args, "saturation")?;
1736 let transition_time = crate::clusters::codec::json_util::get_u16(args, "transition_time")?;
1737 let options_mask = crate::clusters::codec::json_util::get_u8(args, "options_mask")?;
1738 let options_override = crate::clusters::codec::json_util::get_u8(args, "options_override")?;
1739 encode_move_to_hue_and_saturation(hue, saturation, transition_time, options_mask, options_override)
1740 }
1741 0x07 => {
1742 let color_x = crate::clusters::codec::json_util::get_u16(args, "color_x")?;
1743 let color_y = crate::clusters::codec::json_util::get_u16(args, "color_y")?;
1744 let transition_time = crate::clusters::codec::json_util::get_u16(args, "transition_time")?;
1745 let options_mask = crate::clusters::codec::json_util::get_u8(args, "options_mask")?;
1746 let options_override = crate::clusters::codec::json_util::get_u8(args, "options_override")?;
1747 encode_move_to_color(color_x, color_y, transition_time, options_mask, options_override)
1748 }
1749 0x08 => {
1750 let rate_x = crate::clusters::codec::json_util::get_i16(args, "rate_x")?;
1751 let rate_y = crate::clusters::codec::json_util::get_i16(args, "rate_y")?;
1752 let options_mask = crate::clusters::codec::json_util::get_u8(args, "options_mask")?;
1753 let options_override = crate::clusters::codec::json_util::get_u8(args, "options_override")?;
1754 encode_move_color(rate_x, rate_y, options_mask, options_override)
1755 }
1756 0x09 => {
1757 let step_x = crate::clusters::codec::json_util::get_i16(args, "step_x")?;
1758 let step_y = crate::clusters::codec::json_util::get_i16(args, "step_y")?;
1759 let transition_time = crate::clusters::codec::json_util::get_u16(args, "transition_time")?;
1760 let options_mask = crate::clusters::codec::json_util::get_u8(args, "options_mask")?;
1761 let options_override = crate::clusters::codec::json_util::get_u8(args, "options_override")?;
1762 encode_step_color(step_x, step_y, transition_time, options_mask, options_override)
1763 }
1764 0x0A => {
1765 let color_temperature_mireds = crate::clusters::codec::json_util::get_u16(args, "color_temperature_mireds")?;
1766 let transition_time = crate::clusters::codec::json_util::get_u16(args, "transition_time")?;
1767 let options_mask = crate::clusters::codec::json_util::get_u8(args, "options_mask")?;
1768 let options_override = crate::clusters::codec::json_util::get_u8(args, "options_override")?;
1769 encode_move_to_color_temperature(color_temperature_mireds, transition_time, options_mask, options_override)
1770 }
1771 0x40 => {
1772 let enhanced_hue = crate::clusters::codec::json_util::get_u16(args, "enhanced_hue")?;
1773 let direction = {
1774 let n = crate::clusters::codec::json_util::get_u64(args, "direction")?;
1775 Direction::from_u8(n as u8).ok_or_else(|| anyhow::anyhow!("invalid Direction: {}", n))?
1776 };
1777 let transition_time = crate::clusters::codec::json_util::get_u16(args, "transition_time")?;
1778 let options_mask = crate::clusters::codec::json_util::get_u8(args, "options_mask")?;
1779 let options_override = crate::clusters::codec::json_util::get_u8(args, "options_override")?;
1780 encode_enhanced_move_to_hue(enhanced_hue, direction, transition_time, options_mask, options_override)
1781 }
1782 0x41 => {
1783 let move_mode = {
1784 let n = crate::clusters::codec::json_util::get_u64(args, "move_mode")?;
1785 MoveMode::from_u8(n as u8).ok_or_else(|| anyhow::anyhow!("invalid MoveMode: {}", n))?
1786 };
1787 let rate = crate::clusters::codec::json_util::get_u16(args, "rate")?;
1788 let options_mask = crate::clusters::codec::json_util::get_u8(args, "options_mask")?;
1789 let options_override = crate::clusters::codec::json_util::get_u8(args, "options_override")?;
1790 encode_enhanced_move_hue(move_mode, rate, options_mask, options_override)
1791 }
1792 0x42 => {
1793 let step_mode = {
1794 let n = crate::clusters::codec::json_util::get_u64(args, "step_mode")?;
1795 StepMode::from_u8(n as u8).ok_or_else(|| anyhow::anyhow!("invalid StepMode: {}", n))?
1796 };
1797 let step_size = crate::clusters::codec::json_util::get_u16(args, "step_size")?;
1798 let transition_time = crate::clusters::codec::json_util::get_u16(args, "transition_time")?;
1799 let options_mask = crate::clusters::codec::json_util::get_u8(args, "options_mask")?;
1800 let options_override = crate::clusters::codec::json_util::get_u8(args, "options_override")?;
1801 encode_enhanced_step_hue(step_mode, step_size, transition_time, options_mask, options_override)
1802 }
1803 0x43 => {
1804 let enhanced_hue = crate::clusters::codec::json_util::get_u16(args, "enhanced_hue")?;
1805 let saturation = crate::clusters::codec::json_util::get_u8(args, "saturation")?;
1806 let transition_time = crate::clusters::codec::json_util::get_u16(args, "transition_time")?;
1807 let options_mask = crate::clusters::codec::json_util::get_u8(args, "options_mask")?;
1808 let options_override = crate::clusters::codec::json_util::get_u8(args, "options_override")?;
1809 encode_enhanced_move_to_hue_and_saturation(enhanced_hue, saturation, transition_time, options_mask, options_override)
1810 }
1811 0x44 => {
1812 let update_flags = crate::clusters::codec::json_util::get_u8(args, "update_flags")?;
1813 let action = {
1814 let n = crate::clusters::codec::json_util::get_u64(args, "action")?;
1815 ColorLoopAction::from_u8(n as u8).ok_or_else(|| anyhow::anyhow!("invalid ColorLoopAction: {}", n))?
1816 };
1817 let direction = {
1818 let n = crate::clusters::codec::json_util::get_u64(args, "direction")?;
1819 ColorLoopDirection::from_u8(n as u8).ok_or_else(|| anyhow::anyhow!("invalid ColorLoopDirection: {}", n))?
1820 };
1821 let time = crate::clusters::codec::json_util::get_u16(args, "time")?;
1822 let start_hue = crate::clusters::codec::json_util::get_u16(args, "start_hue")?;
1823 let options_mask = crate::clusters::codec::json_util::get_u8(args, "options_mask")?;
1824 let options_override = crate::clusters::codec::json_util::get_u8(args, "options_override")?;
1825 encode_color_loop_set(update_flags, action, direction, time, start_hue, options_mask, options_override)
1826 }
1827 0x47 => {
1828 let options_mask = crate::clusters::codec::json_util::get_u8(args, "options_mask")?;
1829 let options_override = crate::clusters::codec::json_util::get_u8(args, "options_override")?;
1830 encode_stop_move_step(options_mask, options_override)
1831 }
1832 0x4B => {
1833 let move_mode = {
1834 let n = crate::clusters::codec::json_util::get_u64(args, "move_mode")?;
1835 MoveMode::from_u8(n as u8).ok_or_else(|| anyhow::anyhow!("invalid MoveMode: {}", n))?
1836 };
1837 let rate = crate::clusters::codec::json_util::get_u16(args, "rate")?;
1838 let color_temperature_minimum_mireds = crate::clusters::codec::json_util::get_u16(args, "color_temperature_minimum_mireds")?;
1839 let color_temperature_maximum_mireds = crate::clusters::codec::json_util::get_u16(args, "color_temperature_maximum_mireds")?;
1840 let options_mask = crate::clusters::codec::json_util::get_u8(args, "options_mask")?;
1841 let options_override = crate::clusters::codec::json_util::get_u8(args, "options_override")?;
1842 encode_move_color_temperature(move_mode, rate, color_temperature_minimum_mireds, color_temperature_maximum_mireds, options_mask, options_override)
1843 }
1844 0x4C => {
1845 let step_mode = {
1846 let n = crate::clusters::codec::json_util::get_u64(args, "step_mode")?;
1847 StepMode::from_u8(n as u8).ok_or_else(|| anyhow::anyhow!("invalid StepMode: {}", n))?
1848 };
1849 let step_size = crate::clusters::codec::json_util::get_u16(args, "step_size")?;
1850 let transition_time = crate::clusters::codec::json_util::get_u16(args, "transition_time")?;
1851 let color_temperature_minimum_mireds = crate::clusters::codec::json_util::get_u16(args, "color_temperature_minimum_mireds")?;
1852 let color_temperature_maximum_mireds = crate::clusters::codec::json_util::get_u16(args, "color_temperature_maximum_mireds")?;
1853 let options_mask = crate::clusters::codec::json_util::get_u8(args, "options_mask")?;
1854 let options_override = crate::clusters::codec::json_util::get_u8(args, "options_override")?;
1855 encode_step_color_temperature(step_mode, step_size, transition_time, color_temperature_minimum_mireds, color_temperature_maximum_mireds, options_mask, options_override)
1856 }
1857 _ => Err(anyhow::anyhow!("unknown command ID: 0x{:02X}", cmd_id)),
1858 }
1859}
1860
1861pub async fn move_to_hue(conn: &crate::controller::Connection, endpoint: u16, hue: u8, direction: Direction, transition_time: u16, options_mask: Options, options_override: Options) -> anyhow::Result<()> {
1865 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_CMD_ID_MOVETOHUE, &encode_move_to_hue(hue, direction, transition_time, options_mask, options_override)?).await?;
1866 Ok(())
1867}
1868
1869pub async fn move_hue(conn: &crate::controller::Connection, endpoint: u16, move_mode: MoveMode, rate: u8, options_mask: Options, options_override: Options) -> anyhow::Result<()> {
1871 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_CMD_ID_MOVEHUE, &encode_move_hue(move_mode, rate, options_mask, options_override)?).await?;
1872 Ok(())
1873}
1874
1875pub async fn step_hue(conn: &crate::controller::Connection, endpoint: u16, step_mode: StepMode, step_size: u8, transition_time: u8, options_mask: Options, options_override: Options) -> anyhow::Result<()> {
1877 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_CMD_ID_STEPHUE, &encode_step_hue(step_mode, step_size, transition_time, options_mask, options_override)?).await?;
1878 Ok(())
1879}
1880
1881pub async fn move_to_saturation(conn: &crate::controller::Connection, endpoint: u16, saturation: u8, transition_time: u16, options_mask: Options, options_override: Options) -> anyhow::Result<()> {
1883 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_CMD_ID_MOVETOSATURATION, &encode_move_to_saturation(saturation, transition_time, options_mask, options_override)?).await?;
1884 Ok(())
1885}
1886
1887pub async fn move_saturation(conn: &crate::controller::Connection, endpoint: u16, move_mode: MoveMode, rate: u8, options_mask: Options, options_override: Options) -> anyhow::Result<()> {
1889 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_CMD_ID_MOVESATURATION, &encode_move_saturation(move_mode, rate, options_mask, options_override)?).await?;
1890 Ok(())
1891}
1892
1893pub async fn step_saturation(conn: &crate::controller::Connection, endpoint: u16, step_mode: StepMode, step_size: u8, transition_time: u8, options_mask: Options, options_override: Options) -> anyhow::Result<()> {
1895 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_CMD_ID_STEPSATURATION, &encode_step_saturation(step_mode, step_size, transition_time, options_mask, options_override)?).await?;
1896 Ok(())
1897}
1898
1899pub async fn move_to_hue_and_saturation(conn: &crate::controller::Connection, endpoint: u16, hue: u8, saturation: u8, transition_time: u16, options_mask: Options, options_override: Options) -> anyhow::Result<()> {
1901 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_CMD_ID_MOVETOHUEANDSATURATION, &encode_move_to_hue_and_saturation(hue, saturation, transition_time, options_mask, options_override)?).await?;
1902 Ok(())
1903}
1904
1905pub async fn move_to_color(conn: &crate::controller::Connection, endpoint: u16, color_x: u16, color_y: u16, transition_time: u16, options_mask: Options, options_override: Options) -> anyhow::Result<()> {
1907 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_CMD_ID_MOVETOCOLOR, &encode_move_to_color(color_x, color_y, transition_time, options_mask, options_override)?).await?;
1908 Ok(())
1909}
1910
1911pub async fn move_color(conn: &crate::controller::Connection, endpoint: u16, rate_x: i16, rate_y: i16, options_mask: Options, options_override: Options) -> anyhow::Result<()> {
1913 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_CMD_ID_MOVECOLOR, &encode_move_color(rate_x, rate_y, options_mask, options_override)?).await?;
1914 Ok(())
1915}
1916
1917pub async fn step_color(conn: &crate::controller::Connection, endpoint: u16, step_x: i16, step_y: i16, transition_time: u16, options_mask: Options, options_override: Options) -> anyhow::Result<()> {
1919 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_CMD_ID_STEPCOLOR, &encode_step_color(step_x, step_y, transition_time, options_mask, options_override)?).await?;
1920 Ok(())
1921}
1922
1923pub async fn move_to_color_temperature(conn: &crate::controller::Connection, endpoint: u16, color_temperature_mireds: u16, transition_time: u16, options_mask: Options, options_override: Options) -> anyhow::Result<()> {
1925 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_CMD_ID_MOVETOCOLORTEMPERATURE, &encode_move_to_color_temperature(color_temperature_mireds, transition_time, options_mask, options_override)?).await?;
1926 Ok(())
1927}
1928
1929pub async fn enhanced_move_to_hue(conn: &crate::controller::Connection, endpoint: u16, enhanced_hue: u16, direction: Direction, transition_time: u16, options_mask: Options, options_override: Options) -> anyhow::Result<()> {
1931 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_CMD_ID_ENHANCEDMOVETOHUE, &encode_enhanced_move_to_hue(enhanced_hue, direction, transition_time, options_mask, options_override)?).await?;
1932 Ok(())
1933}
1934
1935pub async fn enhanced_move_hue(conn: &crate::controller::Connection, endpoint: u16, move_mode: MoveMode, rate: u16, options_mask: Options, options_override: Options) -> anyhow::Result<()> {
1937 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_CMD_ID_ENHANCEDMOVEHUE, &encode_enhanced_move_hue(move_mode, rate, options_mask, options_override)?).await?;
1938 Ok(())
1939}
1940
1941pub async fn enhanced_step_hue(conn: &crate::controller::Connection, endpoint: u16, step_mode: StepMode, step_size: u16, transition_time: u16, options_mask: Options, options_override: Options) -> anyhow::Result<()> {
1943 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_CMD_ID_ENHANCEDSTEPHUE, &encode_enhanced_step_hue(step_mode, step_size, transition_time, options_mask, options_override)?).await?;
1944 Ok(())
1945}
1946
1947pub async fn enhanced_move_to_hue_and_saturation(conn: &crate::controller::Connection, endpoint: u16, enhanced_hue: u16, saturation: u8, transition_time: u16, options_mask: Options, options_override: Options) -> anyhow::Result<()> {
1949 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_CMD_ID_ENHANCEDMOVETOHUEANDSATURATION, &encode_enhanced_move_to_hue_and_saturation(enhanced_hue, saturation, transition_time, options_mask, options_override)?).await?;
1950 Ok(())
1951}
1952
1953pub async fn color_loop_set(conn: &crate::controller::Connection, endpoint: u16, update_flags: UpdateFlags, action: ColorLoopAction, direction: ColorLoopDirection, time: u16, start_hue: u16, options_mask: Options, options_override: Options) -> anyhow::Result<()> {
1955 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_CMD_ID_COLORLOOPSET, &encode_color_loop_set(update_flags, action, direction, time, start_hue, options_mask, options_override)?).await?;
1956 Ok(())
1957}
1958
1959pub async fn stop_move_step(conn: &crate::controller::Connection, endpoint: u16, options_mask: Options, options_override: Options) -> anyhow::Result<()> {
1961 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_CMD_ID_STOPMOVESTEP, &encode_stop_move_step(options_mask, options_override)?).await?;
1962 Ok(())
1963}
1964
1965pub async fn move_color_temperature(conn: &crate::controller::Connection, endpoint: u16, move_mode: MoveMode, rate: u16, color_temperature_minimum_mireds: u16, color_temperature_maximum_mireds: u16, options_mask: Options, options_override: Options) -> anyhow::Result<()> {
1967 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_CMD_ID_MOVECOLORTEMPERATURE, &encode_move_color_temperature(move_mode, rate, color_temperature_minimum_mireds, color_temperature_maximum_mireds, options_mask, options_override)?).await?;
1968 Ok(())
1969}
1970
1971pub async fn step_color_temperature(conn: &crate::controller::Connection, endpoint: u16, step_mode: StepMode, step_size: u16, transition_time: u16, color_temperature_minimum_mireds: u16, color_temperature_maximum_mireds: u16, options_mask: Options, options_override: Options) -> anyhow::Result<()> {
1973 conn.invoke_request(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_CMD_ID_STEPCOLORTEMPERATURE, &encode_step_color_temperature(step_mode, step_size, transition_time, color_temperature_minimum_mireds, color_temperature_maximum_mireds, options_mask, options_override)?).await?;
1974 Ok(())
1975}
1976
1977pub async fn read_current_hue(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u8> {
1979 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_CURRENTHUE).await?;
1980 decode_current_hue(&tlv)
1981}
1982
1983pub async fn read_current_saturation(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u8> {
1985 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_CURRENTSATURATION).await?;
1986 decode_current_saturation(&tlv)
1987}
1988
1989pub async fn read_remaining_time(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
1991 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_REMAININGTIME).await?;
1992 decode_remaining_time(&tlv)
1993}
1994
1995pub async fn read_current_x(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
1997 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_CURRENTX).await?;
1998 decode_current_x(&tlv)
1999}
2000
2001pub async fn read_current_y(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2003 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_CURRENTY).await?;
2004 decode_current_y(&tlv)
2005}
2006
2007pub async fn read_drift_compensation(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<DriftCompensation> {
2009 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_DRIFTCOMPENSATION).await?;
2010 decode_drift_compensation(&tlv)
2011}
2012
2013pub async fn read_compensation_text(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<String> {
2015 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COMPENSATIONTEXT).await?;
2016 decode_compensation_text(&tlv)
2017}
2018
2019pub async fn read_color_temperature_mireds(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2021 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COLORTEMPERATUREMIREDS).await?;
2022 decode_color_temperature_mireds(&tlv)
2023}
2024
2025pub async fn read_color_mode(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<ColorMode> {
2027 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COLORMODE).await?;
2028 decode_color_mode(&tlv)
2029}
2030
2031pub async fn read_options(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Options> {
2033 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_OPTIONS).await?;
2034 decode_options(&tlv)
2035}
2036
2037pub async fn read_number_of_primaries(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u8>> {
2039 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_NUMBEROFPRIMARIES).await?;
2040 decode_number_of_primaries(&tlv)
2041}
2042
2043pub async fn read_primary1_x(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2045 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_PRIMARY1X).await?;
2046 decode_primary1_x(&tlv)
2047}
2048
2049pub async fn read_primary1_y(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2051 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_PRIMARY1Y).await?;
2052 decode_primary1_y(&tlv)
2053}
2054
2055pub async fn read_primary1_intensity(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u8>> {
2057 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_PRIMARY1INTENSITY).await?;
2058 decode_primary1_intensity(&tlv)
2059}
2060
2061pub async fn read_primary2_x(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2063 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_PRIMARY2X).await?;
2064 decode_primary2_x(&tlv)
2065}
2066
2067pub async fn read_primary2_y(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2069 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_PRIMARY2Y).await?;
2070 decode_primary2_y(&tlv)
2071}
2072
2073pub async fn read_primary2_intensity(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u8>> {
2075 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_PRIMARY2INTENSITY).await?;
2076 decode_primary2_intensity(&tlv)
2077}
2078
2079pub async fn read_primary3_x(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2081 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_PRIMARY3X).await?;
2082 decode_primary3_x(&tlv)
2083}
2084
2085pub async fn read_primary3_y(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2087 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_PRIMARY3Y).await?;
2088 decode_primary3_y(&tlv)
2089}
2090
2091pub async fn read_primary3_intensity(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u8>> {
2093 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_PRIMARY3INTENSITY).await?;
2094 decode_primary3_intensity(&tlv)
2095}
2096
2097pub async fn read_primary4_x(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2099 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_PRIMARY4X).await?;
2100 decode_primary4_x(&tlv)
2101}
2102
2103pub async fn read_primary4_y(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2105 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_PRIMARY4Y).await?;
2106 decode_primary4_y(&tlv)
2107}
2108
2109pub async fn read_primary4_intensity(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u8>> {
2111 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_PRIMARY4INTENSITY).await?;
2112 decode_primary4_intensity(&tlv)
2113}
2114
2115pub async fn read_primary5_x(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2117 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_PRIMARY5X).await?;
2118 decode_primary5_x(&tlv)
2119}
2120
2121pub async fn read_primary5_y(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2123 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_PRIMARY5Y).await?;
2124 decode_primary5_y(&tlv)
2125}
2126
2127pub async fn read_primary5_intensity(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u8>> {
2129 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_PRIMARY5INTENSITY).await?;
2130 decode_primary5_intensity(&tlv)
2131}
2132
2133pub async fn read_primary6_x(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2135 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_PRIMARY6X).await?;
2136 decode_primary6_x(&tlv)
2137}
2138
2139pub async fn read_primary6_y(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2141 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_PRIMARY6Y).await?;
2142 decode_primary6_y(&tlv)
2143}
2144
2145pub async fn read_primary6_intensity(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u8>> {
2147 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_PRIMARY6INTENSITY).await?;
2148 decode_primary6_intensity(&tlv)
2149}
2150
2151pub async fn read_white_point_x(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2153 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_WHITEPOINTX).await?;
2154 decode_white_point_x(&tlv)
2155}
2156
2157pub async fn read_white_point_y(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2159 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_WHITEPOINTY).await?;
2160 decode_white_point_y(&tlv)
2161}
2162
2163pub async fn read_color_point_rx(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2165 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COLORPOINTRX).await?;
2166 decode_color_point_rx(&tlv)
2167}
2168
2169pub async fn read_color_point_ry(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2171 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COLORPOINTRY).await?;
2172 decode_color_point_ry(&tlv)
2173}
2174
2175pub async fn read_color_point_r_intensity(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u8>> {
2177 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COLORPOINTRINTENSITY).await?;
2178 decode_color_point_r_intensity(&tlv)
2179}
2180
2181pub async fn read_color_point_gx(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2183 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COLORPOINTGX).await?;
2184 decode_color_point_gx(&tlv)
2185}
2186
2187pub async fn read_color_point_gy(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2189 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COLORPOINTGY).await?;
2190 decode_color_point_gy(&tlv)
2191}
2192
2193pub async fn read_color_point_g_intensity(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u8>> {
2195 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COLORPOINTGINTENSITY).await?;
2196 decode_color_point_g_intensity(&tlv)
2197}
2198
2199pub async fn read_color_point_bx(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2201 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COLORPOINTBX).await?;
2202 decode_color_point_bx(&tlv)
2203}
2204
2205pub async fn read_color_point_by(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2207 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COLORPOINTBY).await?;
2208 decode_color_point_by(&tlv)
2209}
2210
2211pub async fn read_color_point_b_intensity(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u8>> {
2213 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COLORPOINTBINTENSITY).await?;
2214 decode_color_point_b_intensity(&tlv)
2215}
2216
2217pub async fn read_enhanced_current_hue(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2219 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_ENHANCEDCURRENTHUE).await?;
2220 decode_enhanced_current_hue(&tlv)
2221}
2222
2223pub async fn read_enhanced_color_mode(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<EnhancedColorMode> {
2225 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_ENHANCEDCOLORMODE).await?;
2226 decode_enhanced_color_mode(&tlv)
2227}
2228
2229pub async fn read_color_loop_active(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u8> {
2231 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COLORLOOPACTIVE).await?;
2232 decode_color_loop_active(&tlv)
2233}
2234
2235pub async fn read_color_loop_direction(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<ColorLoopDirection> {
2237 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COLORLOOPDIRECTION).await?;
2238 decode_color_loop_direction(&tlv)
2239}
2240
2241pub async fn read_color_loop_time(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2243 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COLORLOOPTIME).await?;
2244 decode_color_loop_time(&tlv)
2245}
2246
2247pub async fn read_color_loop_start_enhanced_hue(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2249 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COLORLOOPSTARTENHANCEDHUE).await?;
2250 decode_color_loop_start_enhanced_hue(&tlv)
2251}
2252
2253pub async fn read_color_loop_stored_enhanced_hue(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2255 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COLORLOOPSTOREDENHANCEDHUE).await?;
2256 decode_color_loop_stored_enhanced_hue(&tlv)
2257}
2258
2259pub async fn read_color_capabilities(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<ColorCapabilities> {
2261 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COLORCAPABILITIES).await?;
2262 decode_color_capabilities(&tlv)
2263}
2264
2265pub async fn read_color_temp_physical_min_mireds(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2267 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COLORTEMPPHYSICALMINMIREDS).await?;
2268 decode_color_temp_physical_min_mireds(&tlv)
2269}
2270
2271pub async fn read_color_temp_physical_max_mireds(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2273 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COLORTEMPPHYSICALMAXMIREDS).await?;
2274 decode_color_temp_physical_max_mireds(&tlv)
2275}
2276
2277pub async fn read_couple_color_temp_to_level_min_mireds(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<u16> {
2279 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_COUPLECOLORTEMPTOLEVELMINMIREDS).await?;
2280 decode_couple_color_temp_to_level_min_mireds(&tlv)
2281}
2282
2283pub async fn read_start_up_color_temperature_mireds(conn: &crate::controller::Connection, endpoint: u16) -> anyhow::Result<Option<u16>> {
2285 let tlv = conn.read_request2(endpoint, crate::clusters::defs::CLUSTER_ID_COLOR_CONTROL, crate::clusters::defs::CLUSTER_COLOR_CONTROL_ATTR_ID_STARTUPCOLORTEMPERATUREMIREDS).await?;
2286 decode_start_up_color_temperature_mireds(&tlv)
2287}
2288