Skip to main content

matter_clusters/gen/
fan_control.rs

1//! FanControl cluster (0x0202).
2//! @generated by `cargo xtask codegen` — do not edit.
3
4#![allow(
5    clippy::all,
6    clippy::pedantic,
7    dead_code,
8    unreachable_pub,
9    unused_imports
10)]
11
12use crate::datatypes::SemanticTagStruct;
13use crate::error::ClusterError;
14use crate::types::Nullable;
15use matter_codec::{ContainerKind, Element, Tag, TlvReader, TlvWriter, Value};
16
17/// Cluster ID.
18pub const CLUSTER_ID: u32 = 0x0202;
19/// Cluster revision.
20pub const CLUSTER_REVISION: u16 = 6;
21
22/// Command IDs (requests and responses).
23pub mod command_id {
24    /// `Step` (request).
25    pub const STEP: u32 = 0x00;
26}
27
28/// Attribute IDs (cluster-specific).
29pub mod attribute_id {
30    /// `FanMode`.
31    pub const FAN_MODE: u32 = 0x0000;
32    /// `FanModeSequence`.
33    pub const FAN_MODE_SEQUENCE: u32 = 0x0001;
34    /// `PercentSetting`.
35    pub const PERCENT_SETTING: u32 = 0x0002;
36    /// `PercentCurrent`.
37    pub const PERCENT_CURRENT: u32 = 0x0003;
38    /// `SpeedMax`.
39    pub const SPEED_MAX: u32 = 0x0004;
40    /// `SpeedSetting`.
41    pub const SPEED_SETTING: u32 = 0x0005;
42    /// `SpeedCurrent`.
43    pub const SPEED_CURRENT: u32 = 0x0006;
44    /// `RockSupport`.
45    pub const ROCK_SUPPORT: u32 = 0x0007;
46    /// `RockSetting`.
47    pub const ROCK_SETTING: u32 = 0x0008;
48    /// `WindSupport`.
49    pub const WIND_SUPPORT: u32 = 0x0009;
50    /// `WindSetting`.
51    pub const WIND_SETTING: u32 = 0x000A;
52    /// `AirflowDirection`.
53    pub const AIRFLOW_DIRECTION: u32 = 0x000B;
54}
55
56bitflags::bitflags! {
57    /// `FanControl` feature bits (FeatureMap).
58    #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
59    pub struct Feature: u32 {
60        /// MultiSpeed (SPD).
61        const SPD = 1 << 0;
62        /// Auto (AUT).
63        const AUT = 1 << 1;
64        /// Rocking (RCK).
65        const RCK = 1 << 2;
66        /// Wind (WND).
67        const WND = 1 << 3;
68        /// Step (STEP).
69        const STEP = 1 << 4;
70        /// AirflowDirection (DIR).
71        const DIR = 1 << 5;
72    }
73}
74
75/// `AirflowDirectionEnum` (enum8).
76#[derive(Copy, Clone, Debug, PartialEq, Eq)]
77pub enum AirflowDirectionEnum {
78    /// Forward = 0.
79    Forward,
80    /// Reverse = 1.
81    Reverse,
82    /// A value not known to this codegen revision.
83    Unknown(u8),
84}
85
86impl AirflowDirectionEnum {
87    /// Decode from its raw discriminant (unknown → `Unknown`).
88    #[must_use]
89    pub fn from_raw(v: u8) -> Self {
90        match v {
91            0 => Self::Forward,
92            1 => Self::Reverse,
93            other => Self::Unknown(other),
94        }
95    }
96    /// The raw discriminant.
97    #[must_use]
98    pub fn to_raw(self) -> u8 {
99        match self {
100            Self::Forward => 0,
101            Self::Reverse => 1,
102            Self::Unknown(v) => v,
103        }
104    }
105}
106
107/// `FanModeEnum` (enum8).
108#[derive(Copy, Clone, Debug, PartialEq, Eq)]
109pub enum FanModeEnum {
110    /// Off = 0.
111    Off,
112    /// Low = 1.
113    Low,
114    /// Medium = 2.
115    Medium,
116    /// High = 3.
117    High,
118    /// On = 4.
119    On,
120    /// Auto = 5.
121    Auto,
122    /// Smart = 6.
123    Smart,
124    /// A value not known to this codegen revision.
125    Unknown(u8),
126}
127
128impl FanModeEnum {
129    /// Decode from its raw discriminant (unknown → `Unknown`).
130    #[must_use]
131    pub fn from_raw(v: u8) -> Self {
132        match v {
133            0 => Self::Off,
134            1 => Self::Low,
135            2 => Self::Medium,
136            3 => Self::High,
137            4 => Self::On,
138            5 => Self::Auto,
139            6 => Self::Smart,
140            other => Self::Unknown(other),
141        }
142    }
143    /// The raw discriminant.
144    #[must_use]
145    pub fn to_raw(self) -> u8 {
146        match self {
147            Self::Off => 0,
148            Self::Low => 1,
149            Self::Medium => 2,
150            Self::High => 3,
151            Self::On => 4,
152            Self::Auto => 5,
153            Self::Smart => 6,
154            Self::Unknown(v) => v,
155        }
156    }
157}
158
159/// `FanModeSequenceEnum` (enum8).
160#[derive(Copy, Clone, Debug, PartialEq, Eq)]
161pub enum FanModeSequenceEnum {
162    /// OffLowMedHigh = 0.
163    OffLowMedHigh,
164    /// OffLowHigh = 1.
165    OffLowHigh,
166    /// OffLowMedHighAuto = 2.
167    OffLowMedHighAuto,
168    /// OffLowHighAuto = 3.
169    OffLowHighAuto,
170    /// OffHighAuto = 4.
171    OffHighAuto,
172    /// OffHigh = 5.
173    OffHigh,
174    /// A value not known to this codegen revision.
175    Unknown(u8),
176}
177
178impl FanModeSequenceEnum {
179    /// Decode from its raw discriminant (unknown → `Unknown`).
180    #[must_use]
181    pub fn from_raw(v: u8) -> Self {
182        match v {
183            0 => Self::OffLowMedHigh,
184            1 => Self::OffLowHigh,
185            2 => Self::OffLowMedHighAuto,
186            3 => Self::OffLowHighAuto,
187            4 => Self::OffHighAuto,
188            5 => Self::OffHigh,
189            other => Self::Unknown(other),
190        }
191    }
192    /// The raw discriminant.
193    #[must_use]
194    pub fn to_raw(self) -> u8 {
195        match self {
196            Self::OffLowMedHigh => 0,
197            Self::OffLowHigh => 1,
198            Self::OffLowMedHighAuto => 2,
199            Self::OffLowHighAuto => 3,
200            Self::OffHighAuto => 4,
201            Self::OffHigh => 5,
202            Self::Unknown(v) => v,
203        }
204    }
205}
206
207bitflags::bitflags! {
208    /// `RockBitmap` (map8).
209    #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
210    pub struct RockBitmap: u8 {
211        /// RockLeftRight.
212        const ROCK_LEFT_RIGHT = 1 << 0;
213        /// RockUpDown.
214        const ROCK_UP_DOWN = 1 << 1;
215        /// RockRound.
216        const ROCK_ROUND = 1 << 2;
217    }
218}
219
220/// `StepDirectionEnum` (enum8).
221#[derive(Copy, Clone, Debug, PartialEq, Eq)]
222pub enum StepDirectionEnum {
223    /// Increase = 0.
224    Increase,
225    /// Decrease = 1.
226    Decrease,
227    /// A value not known to this codegen revision.
228    Unknown(u8),
229}
230
231impl StepDirectionEnum {
232    /// Decode from its raw discriminant (unknown → `Unknown`).
233    #[must_use]
234    pub fn from_raw(v: u8) -> Self {
235        match v {
236            0 => Self::Increase,
237            1 => Self::Decrease,
238            other => Self::Unknown(other),
239        }
240    }
241    /// The raw discriminant.
242    #[must_use]
243    pub fn to_raw(self) -> u8 {
244        match self {
245            Self::Increase => 0,
246            Self::Decrease => 1,
247            Self::Unknown(v) => v,
248        }
249    }
250}
251
252bitflags::bitflags! {
253    /// `WindBitmap` (map8).
254    #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
255    pub struct WindBitmap: u8 {
256        /// SleepWind.
257        const SLEEP_WIND = 1 << 0;
258        /// NaturalWind.
259        const NATURAL_WIND = 1 << 1;
260    }
261}
262
263/// Decode the `FanMode` attribute value.
264///
265/// # Errors
266/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
267pub fn decode_fan_mode(tlv: &[u8]) -> Result<FanModeEnum, ClusterError> {
268    let mut r = TlvReader::new(tlv);
269    match r.next()? {
270        Some(Element::Scalar {
271            value: Value::Uint(v),
272            ..
273        }) => Ok(FanModeEnum::from_raw(
274            u8::try_from(v).map_err(|_| ClusterError::InvalidLength("FanMode"))?,
275        )),
276        _ => Err(ClusterError::UnexpectedType { context: "FanMode" }),
277    }
278}
279
280/// Encode the `FanMode` attribute value as a standalone TLV element.
281#[must_use]
282#[allow(clippy::expect_used, clippy::missing_panics_doc)] // Vec-backed TlvWriter is infallible.
283pub fn encode_fan_mode(value: FanModeEnum) -> Vec<u8> {
284    let mut buf = Vec::new();
285    let mut w = TlvWriter::new(&mut buf);
286    w.put_uint(Tag::Anonymous, u64::from(value.to_raw()))
287        .expect("infallible: vec writer");
288    buf
289}
290
291/// Decode the `FanModeSequence` attribute value.
292///
293/// # Errors
294/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
295pub fn decode_fan_mode_sequence(tlv: &[u8]) -> Result<FanModeSequenceEnum, ClusterError> {
296    let mut r = TlvReader::new(tlv);
297    match r.next()? {
298        Some(Element::Scalar {
299            value: Value::Uint(v),
300            ..
301        }) => Ok(FanModeSequenceEnum::from_raw(
302            u8::try_from(v).map_err(|_| ClusterError::InvalidLength("FanModeSequence"))?,
303        )),
304        _ => Err(ClusterError::UnexpectedType {
305            context: "FanModeSequence",
306        }),
307    }
308}
309
310/// Decode the `PercentSetting` attribute value.
311///
312/// # Errors
313/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
314pub fn decode_percent_setting(tlv: &[u8]) -> Result<Nullable<u8>, ClusterError> {
315    let mut r = TlvReader::new(tlv);
316    match r.next()? {
317        Some(Element::Scalar {
318            value: Value::Null, ..
319        }) => Ok(Nullable::Null),
320        Some(Element::Scalar {
321            value: Value::Uint(v),
322            ..
323        }) => {
324            Ok(Nullable::Value(u8::try_from(v).map_err(|_| {
325                ClusterError::InvalidLength("PercentSetting")
326            })?))
327        }
328        _ => Err(ClusterError::UnexpectedType {
329            context: "PercentSetting",
330        }),
331    }
332}
333
334/// Encode the `PercentSetting` attribute value as a standalone TLV element.
335#[must_use]
336#[allow(clippy::expect_used, clippy::missing_panics_doc)] // Vec-backed TlvWriter is infallible.
337pub fn encode_percent_setting(value: Nullable<u8>) -> Vec<u8> {
338    let mut buf = Vec::new();
339    let mut w = TlvWriter::new(&mut buf);
340    match value {
341        Nullable::Null => w.put_null(Tag::Anonymous).expect("infallible: vec writer"),
342        Nullable::Value(value) => {
343            w.put_uint(Tag::Anonymous, u64::from(value))
344                .expect("infallible: vec writer");
345        }
346    }
347    buf
348}
349
350/// Decode the `PercentCurrent` attribute value.
351///
352/// # Errors
353/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
354pub fn decode_percent_current(tlv: &[u8]) -> Result<u8, ClusterError> {
355    let mut r = TlvReader::new(tlv);
356    match r.next()? {
357        Some(Element::Scalar {
358            value: Value::Uint(v),
359            ..
360        }) => Ok(u8::try_from(v).map_err(|_| ClusterError::InvalidLength("PercentCurrent"))?),
361        _ => Err(ClusterError::UnexpectedType {
362            context: "PercentCurrent",
363        }),
364    }
365}
366
367/// Decode the `SpeedMax` attribute value.
368///
369/// # Errors
370/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
371pub fn decode_speed_max(tlv: &[u8]) -> Result<u8, ClusterError> {
372    let mut r = TlvReader::new(tlv);
373    match r.next()? {
374        Some(Element::Scalar {
375            value: Value::Uint(v),
376            ..
377        }) => Ok(u8::try_from(v).map_err(|_| ClusterError::InvalidLength("SpeedMax"))?),
378        _ => Err(ClusterError::UnexpectedType {
379            context: "SpeedMax",
380        }),
381    }
382}
383
384/// Decode the `SpeedSetting` attribute value.
385///
386/// # Errors
387/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
388pub fn decode_speed_setting(tlv: &[u8]) -> Result<Nullable<u8>, ClusterError> {
389    let mut r = TlvReader::new(tlv);
390    match r.next()? {
391        Some(Element::Scalar {
392            value: Value::Null, ..
393        }) => Ok(Nullable::Null),
394        Some(Element::Scalar {
395            value: Value::Uint(v),
396            ..
397        }) => {
398            Ok(Nullable::Value(u8::try_from(v).map_err(|_| {
399                ClusterError::InvalidLength("SpeedSetting")
400            })?))
401        }
402        _ => Err(ClusterError::UnexpectedType {
403            context: "SpeedSetting",
404        }),
405    }
406}
407
408/// Encode the `SpeedSetting` attribute value as a standalone TLV element.
409#[must_use]
410#[allow(clippy::expect_used, clippy::missing_panics_doc)] // Vec-backed TlvWriter is infallible.
411pub fn encode_speed_setting(value: Nullable<u8>) -> Vec<u8> {
412    let mut buf = Vec::new();
413    let mut w = TlvWriter::new(&mut buf);
414    match value {
415        Nullable::Null => w.put_null(Tag::Anonymous).expect("infallible: vec writer"),
416        Nullable::Value(value) => {
417            w.put_uint(Tag::Anonymous, u64::from(value))
418                .expect("infallible: vec writer");
419        }
420    }
421    buf
422}
423
424/// Decode the `SpeedCurrent` attribute value.
425///
426/// # Errors
427/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
428pub fn decode_speed_current(tlv: &[u8]) -> Result<u8, ClusterError> {
429    let mut r = TlvReader::new(tlv);
430    match r.next()? {
431        Some(Element::Scalar {
432            value: Value::Uint(v),
433            ..
434        }) => Ok(u8::try_from(v).map_err(|_| ClusterError::InvalidLength("SpeedCurrent"))?),
435        _ => Err(ClusterError::UnexpectedType {
436            context: "SpeedCurrent",
437        }),
438    }
439}
440
441/// Decode the `RockSupport` attribute value.
442///
443/// # Errors
444/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
445pub fn decode_rock_support(tlv: &[u8]) -> Result<RockBitmap, ClusterError> {
446    let mut r = TlvReader::new(tlv);
447    match r.next()? {
448        Some(Element::Scalar {
449            value: Value::Uint(v),
450            ..
451        }) => Ok(RockBitmap::from_bits_retain(
452            u8::try_from(v).map_err(|_| ClusterError::InvalidLength("RockSupport"))?,
453        )),
454        _ => Err(ClusterError::UnexpectedType {
455            context: "RockSupport",
456        }),
457    }
458}
459
460/// Decode the `RockSetting` attribute value.
461///
462/// # Errors
463/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
464pub fn decode_rock_setting(tlv: &[u8]) -> Result<RockBitmap, ClusterError> {
465    let mut r = TlvReader::new(tlv);
466    match r.next()? {
467        Some(Element::Scalar {
468            value: Value::Uint(v),
469            ..
470        }) => Ok(RockBitmap::from_bits_retain(
471            u8::try_from(v).map_err(|_| ClusterError::InvalidLength("RockSetting"))?,
472        )),
473        _ => Err(ClusterError::UnexpectedType {
474            context: "RockSetting",
475        }),
476    }
477}
478
479/// Encode the `RockSetting` attribute value as a standalone TLV element.
480#[must_use]
481#[allow(clippy::expect_used, clippy::missing_panics_doc)] // Vec-backed TlvWriter is infallible.
482pub fn encode_rock_setting(value: RockBitmap) -> Vec<u8> {
483    let mut buf = Vec::new();
484    let mut w = TlvWriter::new(&mut buf);
485    w.put_uint(Tag::Anonymous, u64::from(value.bits()))
486        .expect("infallible: vec writer");
487    buf
488}
489
490/// Decode the `WindSupport` attribute value.
491///
492/// # Errors
493/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
494pub fn decode_wind_support(tlv: &[u8]) -> Result<WindBitmap, ClusterError> {
495    let mut r = TlvReader::new(tlv);
496    match r.next()? {
497        Some(Element::Scalar {
498            value: Value::Uint(v),
499            ..
500        }) => Ok(WindBitmap::from_bits_retain(
501            u8::try_from(v).map_err(|_| ClusterError::InvalidLength("WindSupport"))?,
502        )),
503        _ => Err(ClusterError::UnexpectedType {
504            context: "WindSupport",
505        }),
506    }
507}
508
509/// Decode the `WindSetting` attribute value.
510///
511/// # Errors
512/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
513pub fn decode_wind_setting(tlv: &[u8]) -> Result<WindBitmap, ClusterError> {
514    let mut r = TlvReader::new(tlv);
515    match r.next()? {
516        Some(Element::Scalar {
517            value: Value::Uint(v),
518            ..
519        }) => Ok(WindBitmap::from_bits_retain(
520            u8::try_from(v).map_err(|_| ClusterError::InvalidLength("WindSetting"))?,
521        )),
522        _ => Err(ClusterError::UnexpectedType {
523            context: "WindSetting",
524        }),
525    }
526}
527
528/// Encode the `WindSetting` attribute value as a standalone TLV element.
529#[must_use]
530#[allow(clippy::expect_used, clippy::missing_panics_doc)] // Vec-backed TlvWriter is infallible.
531pub fn encode_wind_setting(value: WindBitmap) -> Vec<u8> {
532    let mut buf = Vec::new();
533    let mut w = TlvWriter::new(&mut buf);
534    w.put_uint(Tag::Anonymous, u64::from(value.bits()))
535        .expect("infallible: vec writer");
536    buf
537}
538
539/// Decode the `AirflowDirection` attribute value.
540///
541/// # Errors
542/// Returns [`ClusterError`] on a type mismatch or out-of-range value.
543pub fn decode_airflow_direction(tlv: &[u8]) -> Result<AirflowDirectionEnum, ClusterError> {
544    let mut r = TlvReader::new(tlv);
545    match r.next()? {
546        Some(Element::Scalar {
547            value: Value::Uint(v),
548            ..
549        }) => Ok(AirflowDirectionEnum::from_raw(
550            u8::try_from(v).map_err(|_| ClusterError::InvalidLength("AirflowDirection"))?,
551        )),
552        _ => Err(ClusterError::UnexpectedType {
553            context: "AirflowDirection",
554        }),
555    }
556}
557
558/// Encode the `AirflowDirection` attribute value as a standalone TLV element.
559#[must_use]
560#[allow(clippy::expect_used, clippy::missing_panics_doc)] // Vec-backed TlvWriter is infallible.
561pub fn encode_airflow_direction(value: AirflowDirectionEnum) -> Vec<u8> {
562    let mut buf = Vec::new();
563    let mut w = TlvWriter::new(&mut buf);
564    w.put_uint(Tag::Anonymous, u64::from(value.to_raw()))
565        .expect("infallible: vec writer");
566    buf
567}
568
569/// Encode the `Step` command request payload.
570#[must_use]
571#[allow(clippy::expect_used, clippy::missing_panics_doc)] // Vec-backed TlvWriter is infallible.
572pub fn encode_step(
573    direction: StepDirectionEnum,
574    wrap: Option<bool>,
575    lowest_off: Option<bool>,
576) -> Vec<u8> {
577    let mut buf = Vec::new();
578    let mut w = TlvWriter::new(&mut buf);
579    w.start_structure(Tag::Anonymous)
580        .expect("infallible: vec writer");
581    w.put_uint(Tag::Context(0), u64::from(direction.to_raw()))
582        .expect("infallible: vec writer");
583    if let Some(wrap) = wrap {
584        w.put_bool(Tag::Context(1), wrap)
585            .expect("infallible: vec writer");
586    }
587    if let Some(lowest_off) = lowest_off {
588        w.put_bool(Tag::Context(2), lowest_off)
589            .expect("infallible: vec writer");
590    }
591    w.end_container().expect("infallible: vec writer");
592    buf
593}