#![allow(
clippy::all,
clippy::pedantic,
dead_code,
unreachable_pub,
unused_imports
)]
use crate::datatypes::SemanticTagStruct;
use crate::error::ClusterError;
use crate::types::Nullable;
use matter_codec::{ContainerKind, Element, Tag, TlvReader, TlvWriter, Value};
pub const CLUSTER_ID: u32 = 0x0102;
pub const CLUSTER_REVISION: u16 = 8;
pub mod command_id {
pub const UP_OR_OPEN: u32 = 0x00;
pub const DOWN_OR_CLOSE: u32 = 0x01;
pub const STOP_MOTION: u32 = 0x02;
pub const GO_TO_LIFT_PERCENTAGE: u32 = 0x05;
pub const GO_TO_TILT_PERCENTAGE: u32 = 0x08;
}
pub mod attribute_id {
pub const TYPE: u32 = 0x0000;
pub const NUMBER_OF_ACTUATIONS_LIFT: u32 = 0x0005;
pub const NUMBER_OF_ACTUATIONS_TILT: u32 = 0x0006;
pub const CONFIG_STATUS: u32 = 0x0007;
pub const CURRENT_POSITION_LIFT_PERCENTAGE: u32 = 0x0008;
pub const CURRENT_POSITION_TILT_PERCENTAGE: u32 = 0x0009;
pub const OPERATIONAL_STATUS: u32 = 0x000A;
pub const TARGET_POSITION_LIFT_PERCENT100THS: u32 = 0x000B;
pub const TARGET_POSITION_TILT_PERCENT100THS: u32 = 0x000C;
pub const END_PRODUCT_TYPE: u32 = 0x000D;
pub const CURRENT_POSITION_LIFT_PERCENT100THS: u32 = 0x000E;
pub const CURRENT_POSITION_TILT_PERCENT100THS: u32 = 0x000F;
pub const MODE: u32 = 0x0017;
pub const SAFETY_STATUS: u32 = 0x001A;
}
bitflags::bitflags! {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct Feature: u32 {
const LF = 1 << 0;
const TL = 1 << 1;
const PA_LF = 1 << 2;
const PA_TL = 1 << 4;
}
}
bitflags::bitflags! {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct ConfigStatusBitmap: u8 {
const OPERATIONAL = 1 << 0;
const ONLINE_RESERVED = 1 << 1;
const LIFT_MOVEMENT_REVERSED = 1 << 2;
const LIFT_POSITION_AWARE = 1 << 3;
const TILT_POSITION_AWARE = 1 << 4;
const LIFT_ENCODER_CONTROLLED = 1 << 5;
const TILT_ENCODER_CONTROLLED = 1 << 6;
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum EndProductTypeEnum {
RollerShade,
RomanShade,
BalloonShade,
WovenWood,
PleatedShade,
CellularShade,
LayeredShade,
LayeredShade2D,
SheerShade,
TiltOnlyInteriorBlind,
InteriorBlind,
VerticalBlindStripCurtain,
InteriorVenetianBlind,
ExteriorVenetianBlind,
LateralLeftCurtain,
LateralRightCurtain,
CentralCurtain,
RollerShutter,
ExteriorVerticalScreen,
AwningTerracePatio,
AwningVerticalScreen,
TiltOnlyPergola,
SwingingShutter,
SlidingShutter,
Unknown,
Unrecognized(u8),
}
impl EndProductTypeEnum {
#[must_use]
pub fn from_raw(v: u8) -> Self {
match v {
0 => Self::RollerShade,
1 => Self::RomanShade,
2 => Self::BalloonShade,
3 => Self::WovenWood,
4 => Self::PleatedShade,
5 => Self::CellularShade,
6 => Self::LayeredShade,
7 => Self::LayeredShade2D,
8 => Self::SheerShade,
9 => Self::TiltOnlyInteriorBlind,
10 => Self::InteriorBlind,
11 => Self::VerticalBlindStripCurtain,
12 => Self::InteriorVenetianBlind,
13 => Self::ExteriorVenetianBlind,
14 => Self::LateralLeftCurtain,
15 => Self::LateralRightCurtain,
16 => Self::CentralCurtain,
17 => Self::RollerShutter,
18 => Self::ExteriorVerticalScreen,
19 => Self::AwningTerracePatio,
20 => Self::AwningVerticalScreen,
21 => Self::TiltOnlyPergola,
22 => Self::SwingingShutter,
23 => Self::SlidingShutter,
255 => Self::Unknown,
other => Self::Unrecognized(other),
}
}
#[must_use]
pub fn to_raw(self) -> u8 {
match self {
Self::RollerShade => 0,
Self::RomanShade => 1,
Self::BalloonShade => 2,
Self::WovenWood => 3,
Self::PleatedShade => 4,
Self::CellularShade => 5,
Self::LayeredShade => 6,
Self::LayeredShade2D => 7,
Self::SheerShade => 8,
Self::TiltOnlyInteriorBlind => 9,
Self::InteriorBlind => 10,
Self::VerticalBlindStripCurtain => 11,
Self::InteriorVenetianBlind => 12,
Self::ExteriorVenetianBlind => 13,
Self::LateralLeftCurtain => 14,
Self::LateralRightCurtain => 15,
Self::CentralCurtain => 16,
Self::RollerShutter => 17,
Self::ExteriorVerticalScreen => 18,
Self::AwningTerracePatio => 19,
Self::AwningVerticalScreen => 20,
Self::TiltOnlyPergola => 21,
Self::SwingingShutter => 22,
Self::SlidingShutter => 23,
Self::Unknown => 255,
Self::Unrecognized(v) => v,
}
}
}
bitflags::bitflags! {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct ModeBitmap: u8 {
const MOTOR_DIRECTION_REVERSED = 1 << 0;
const CALIBRATION_MODE = 1 << 1;
const MAINTENANCE_MODE = 1 << 2;
const LED_FEEDBACK = 1 << 3;
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum MovementStatus {
Stopped,
Opening,
Closing,
Unknown(u8),
}
impl MovementStatus {
#[must_use]
pub fn from_raw(v: u8) -> Self {
match v {
0 => Self::Stopped,
1 => Self::Opening,
2 => Self::Closing,
other => Self::Unknown(other),
}
}
#[must_use]
pub fn to_raw(self) -> u8 {
match self {
Self::Stopped => 0,
Self::Opening => 1,
Self::Closing => 2,
Self::Unknown(v) => v,
}
}
}
bitflags::bitflags! {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct OperationalStatusBitmap: u8 {
}
}
bitflags::bitflags! {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct SafetyStatusBitmap: u16 {
const REMOTE_LOCKOUT = 1 << 0;
const TAMPER_DETECTION = 1 << 1;
const FAILED_COMMUNICATION = 1 << 2;
const POSITION_FAILURE = 1 << 3;
const THERMAL_PROTECTION = 1 << 4;
const OBSTACLE_DETECTED = 1 << 5;
const POWER = 1 << 6;
const STOP_INPUT = 1 << 7;
const MOTOR_JAMMED = 1 << 8;
const HARDWARE_FAILURE = 1 << 9;
const MANUAL_OPERATION = 1 << 10;
const PROTECTION = 1 << 11;
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum TypeEnum {
Rollershade,
Rollershade2Motor,
RollershadeExterior,
RollershadeExterior2Motor,
Drapery,
Awning,
Shutter,
TiltBlindTiltOnly,
TiltBlindLift,
ProjectorScreen,
Unknown,
Unrecognized(u8),
}
impl TypeEnum {
#[must_use]
pub fn from_raw(v: u8) -> Self {
match v {
0 => Self::Rollershade,
1 => Self::Rollershade2Motor,
2 => Self::RollershadeExterior,
3 => Self::RollershadeExterior2Motor,
4 => Self::Drapery,
5 => Self::Awning,
6 => Self::Shutter,
7 => Self::TiltBlindTiltOnly,
8 => Self::TiltBlindLift,
9 => Self::ProjectorScreen,
255 => Self::Unknown,
other => Self::Unrecognized(other),
}
}
#[must_use]
pub fn to_raw(self) -> u8 {
match self {
Self::Rollershade => 0,
Self::Rollershade2Motor => 1,
Self::RollershadeExterior => 2,
Self::RollershadeExterior2Motor => 3,
Self::Drapery => 4,
Self::Awning => 5,
Self::Shutter => 6,
Self::TiltBlindTiltOnly => 7,
Self::TiltBlindLift => 8,
Self::ProjectorScreen => 9,
Self::Unknown => 255,
Self::Unrecognized(v) => v,
}
}
}
pub fn decode_type(tlv: &[u8]) -> Result<TypeEnum, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(TypeEnum::from_raw(
u8::try_from(v).map_err(|_| ClusterError::InvalidLength("Type"))?,
)),
_ => Err(ClusterError::UnexpectedType { context: "Type" }),
}
}
pub fn decode_number_of_actuations_lift(tlv: &[u8]) -> Result<u16, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => {
Ok(u16::try_from(v)
.map_err(|_| ClusterError::InvalidLength("NumberOfActuationsLift"))?)
}
_ => Err(ClusterError::UnexpectedType {
context: "NumberOfActuationsLift",
}),
}
}
pub fn decode_number_of_actuations_tilt(tlv: &[u8]) -> Result<u16, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => {
Ok(u16::try_from(v)
.map_err(|_| ClusterError::InvalidLength("NumberOfActuationsTilt"))?)
}
_ => Err(ClusterError::UnexpectedType {
context: "NumberOfActuationsTilt",
}),
}
}
pub fn decode_config_status(tlv: &[u8]) -> Result<ConfigStatusBitmap, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(ConfigStatusBitmap::from_bits_retain(
u8::try_from(v).map_err(|_| ClusterError::InvalidLength("ConfigStatus"))?,
)),
_ => Err(ClusterError::UnexpectedType {
context: "ConfigStatus",
}),
}
}
pub fn decode_current_position_lift_percentage(tlv: &[u8]) -> Result<Nullable<u8>, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Null, ..
}) => Ok(Nullable::Null),
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(Nullable::Value(u8::try_from(v).map_err(|_| {
ClusterError::InvalidLength("CurrentPositionLiftPercentage")
})?)),
_ => Err(ClusterError::UnexpectedType {
context: "CurrentPositionLiftPercentage",
}),
}
}
pub fn decode_current_position_tilt_percentage(tlv: &[u8]) -> Result<Nullable<u8>, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Null, ..
}) => Ok(Nullable::Null),
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(Nullable::Value(u8::try_from(v).map_err(|_| {
ClusterError::InvalidLength("CurrentPositionTiltPercentage")
})?)),
_ => Err(ClusterError::UnexpectedType {
context: "CurrentPositionTiltPercentage",
}),
}
}
pub fn decode_operational_status(tlv: &[u8]) -> Result<OperationalStatusBitmap, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(OperationalStatusBitmap::from_bits_retain(
u8::try_from(v).map_err(|_| ClusterError::InvalidLength("OperationalStatus"))?,
)),
_ => Err(ClusterError::UnexpectedType {
context: "OperationalStatus",
}),
}
}
pub fn decode_target_position_lift_percent100ths(
tlv: &[u8],
) -> Result<Nullable<u16>, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Null, ..
}) => Ok(Nullable::Null),
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(Nullable::Value(u16::try_from(v).map_err(|_| {
ClusterError::InvalidLength("TargetPositionLiftPercent100ths")
})?)),
_ => Err(ClusterError::UnexpectedType {
context: "TargetPositionLiftPercent100ths",
}),
}
}
pub fn decode_target_position_tilt_percent100ths(
tlv: &[u8],
) -> Result<Nullable<u16>, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Null, ..
}) => Ok(Nullable::Null),
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(Nullable::Value(u16::try_from(v).map_err(|_| {
ClusterError::InvalidLength("TargetPositionTiltPercent100ths")
})?)),
_ => Err(ClusterError::UnexpectedType {
context: "TargetPositionTiltPercent100ths",
}),
}
}
pub fn decode_end_product_type(tlv: &[u8]) -> Result<EndProductTypeEnum, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(EndProductTypeEnum::from_raw(
u8::try_from(v).map_err(|_| ClusterError::InvalidLength("EndProductType"))?,
)),
_ => Err(ClusterError::UnexpectedType {
context: "EndProductType",
}),
}
}
pub fn decode_current_position_lift_percent100ths(
tlv: &[u8],
) -> Result<Nullable<u16>, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Null, ..
}) => Ok(Nullable::Null),
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(Nullable::Value(u16::try_from(v).map_err(|_| {
ClusterError::InvalidLength("CurrentPositionLiftPercent100ths")
})?)),
_ => Err(ClusterError::UnexpectedType {
context: "CurrentPositionLiftPercent100ths",
}),
}
}
pub fn decode_current_position_tilt_percent100ths(
tlv: &[u8],
) -> Result<Nullable<u16>, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Null, ..
}) => Ok(Nullable::Null),
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(Nullable::Value(u16::try_from(v).map_err(|_| {
ClusterError::InvalidLength("CurrentPositionTiltPercent100ths")
})?)),
_ => Err(ClusterError::UnexpectedType {
context: "CurrentPositionTiltPercent100ths",
}),
}
}
pub fn decode_mode(tlv: &[u8]) -> Result<ModeBitmap, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(ModeBitmap::from_bits_retain(
u8::try_from(v).map_err(|_| ClusterError::InvalidLength("Mode"))?,
)),
_ => Err(ClusterError::UnexpectedType { context: "Mode" }),
}
}
#[must_use]
#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_mode(value: ModeBitmap) -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.put_uint(Tag::Anonymous, u64::from(value.bits()))
.expect("infallible: vec writer");
buf
}
pub fn decode_safety_status(tlv: &[u8]) -> Result<SafetyStatusBitmap, ClusterError> {
let mut r = TlvReader::new(tlv);
match r.next()? {
Some(Element::Scalar {
value: Value::Uint(v),
..
}) => Ok(SafetyStatusBitmap::from_bits_retain(
u16::try_from(v).map_err(|_| ClusterError::InvalidLength("SafetyStatus"))?,
)),
_ => Err(ClusterError::UnexpectedType {
context: "SafetyStatus",
}),
}
}
#[must_use]
#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_up_or_open() -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.start_structure(Tag::Anonymous)
.expect("infallible: vec writer");
w.end_container().expect("infallible: vec writer");
buf
}
#[must_use]
#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_down_or_close() -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.start_structure(Tag::Anonymous)
.expect("infallible: vec writer");
w.end_container().expect("infallible: vec writer");
buf
}
#[must_use]
#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_stop_motion() -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.start_structure(Tag::Anonymous)
.expect("infallible: vec writer");
w.end_container().expect("infallible: vec writer");
buf
}
#[must_use]
#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_go_to_lift_percentage(lift_percent100ths_value: u16) -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.start_structure(Tag::Anonymous)
.expect("infallible: vec writer");
w.put_uint(Tag::Context(0), u64::from(lift_percent100ths_value))
.expect("infallible: vec writer");
w.end_container().expect("infallible: vec writer");
buf
}
#[must_use]
#[allow(clippy::expect_used, clippy::missing_panics_doc)] pub fn encode_go_to_tilt_percentage(tilt_percent100ths_value: u16) -> Vec<u8> {
let mut buf = Vec::new();
let mut w = TlvWriter::new(&mut buf);
w.start_structure(Tag::Anonymous)
.expect("infallible: vec writer");
w.put_uint(Tag::Context(0), u64::from(tilt_percent100ths_value))
.expect("infallible: vec writer");
w.end_container().expect("infallible: vec writer");
buf
}