use super::ffi;
use huesmith_core::light::command::{
LightCommand, DEFAULT_COLOR_TRANSITION_TENTHS, DEFAULT_LEVEL_TRANSITION_TENTHS,
};
pub fn parse_set_attribute(
cluster_id: u16,
attr_id: u16,
size: u16,
data: *const core::ffi::c_void,
) -> Option<LightCommand> {
match cluster_id {
ffi::CLUSTER_ON_OFF => match attr_id {
ffi::ATTR_ON_OFF => {
if size < 1 {
return None;
}
let on = unsafe { (data as *const u8).read() != 0 };
Some(if on {
LightCommand::On
} else {
LightCommand::Off
})
}
_ => None,
},
ffi::CLUSTER_LEVEL_CONTROL => match attr_id {
ffi::ATTR_LEVEL_CURRENT_LEVEL => {
if size < 1 {
return None;
}
let level = unsafe { (data as *const u8).read() };
Some(LightCommand::SetLevel {
level,
transition_time: DEFAULT_LEVEL_TRANSITION_TENTHS,
})
}
_ => None,
},
ffi::CLUSTER_COLOR_CONTROL => match attr_id {
ffi::ATTR_COLOR_CURRENT_X => {
if size < 2 {
return None;
}
let x = unsafe { (data as *const u16).read_unaligned() };
Some(LightCommand::MoveToColor {
x: Some(x),
y: None,
transition_time: DEFAULT_COLOR_TRANSITION_TENTHS,
})
}
ffi::ATTR_COLOR_CURRENT_Y => {
if size < 2 {
return None;
}
let y = unsafe { (data as *const u16).read_unaligned() };
Some(LightCommand::MoveToColor {
x: None,
y: Some(y),
transition_time: DEFAULT_COLOR_TRANSITION_TENTHS,
})
}
ffi::ATTR_COLOR_TEMPERATURE_MIREDS => {
if size < 2 {
return None;
}
let mireds = unsafe { (data as *const u16).read_unaligned() };
Some(LightCommand::MoveToColorTemp {
mireds,
transition_time: DEFAULT_COLOR_TRANSITION_TENTHS,
})
}
ffi::ATTR_COLOR_CURRENT_HUE => {
if size < 1 {
return None;
}
let hue = unsafe { (data as *const u8).read() };
Some(LightCommand::MoveToHueAndSaturation {
hue: Some(hue),
saturation: None,
transition_time: DEFAULT_COLOR_TRANSITION_TENTHS,
})
}
ffi::ATTR_COLOR_CURRENT_SATURATION => {
if size < 1 {
return None;
}
let sat = unsafe { (data as *const u8).read() };
Some(LightCommand::MoveToHueAndSaturation {
hue: None,
saturation: Some(sat),
transition_time: DEFAULT_COLOR_TRANSITION_TENTHS,
})
}
ffi::ATTR_COLOR_ENHANCED_CURRENT_HUE => {
if size < 2 {
return None;
}
let enhanced = unsafe { (data as *const u16).read_unaligned() };
Some(LightCommand::EnhancedMoveToHueAndSaturation {
enhanced_hue: enhanced,
saturation: None,
transition_time: DEFAULT_COLOR_TRANSITION_TENTHS,
})
}
ffi::ATTR_COLOR_MODE | ffi::ATTR_COLOR_ENHANCED_COLOR_MODE => None,
_ => None,
},
ffi::CLUSTER_IDENTIFY => match attr_id {
0x0000 => {
if size < 2 {
return None;
}
let duration = unsafe { (data as *const u16).read_unaligned() };
Some(LightCommand::Identify { duration })
}
_ => None,
},
_ => None,
}
}