use super::types::{
ActivityEventType, CLUSTER_EFFECT_PARAM_COUNT, PowerModeTarget, RgbPersistence, be16,
};
const POWER_TARGET_SHIFT: u8 = 2;
const FLAGS_FIELD_MASK: u8 = 0b11;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub enum RgbEffectsEvent {
EffectSync {
cluster_index: u8,
effect_counter: u16,
},
UserActivity(ActivityEventType),
ClusterChanged {
cluster_index: u8,
cluster_effect_index: u8,
params: [u8; CLUSTER_EFFECT_PARAM_COUNT],
persistence: RgbPersistence,
power_mode: Option<PowerModeTarget>,
},
}
pub(super) fn decode_event(sub_id: u8, payload: &[u8; 16]) -> Option<RgbEffectsEvent> {
match sub_id {
0 => Some(RgbEffectsEvent::EffectSync {
cluster_index: payload[0],
effect_counter: be16(payload, 1),
}),
1 => Some(RgbEffectsEvent::UserActivity(ActivityEventType::from(
payload[0],
))),
2 => {
let mut params = [0; CLUSTER_EFFECT_PARAM_COUNT];
params.copy_from_slice(&payload[2..2 + CLUSTER_EFFECT_PARAM_COUNT]);
let flags = payload[2 + CLUSTER_EFFECT_PARAM_COUNT];
Some(RgbEffectsEvent::ClusterChanged {
cluster_index: payload[0],
cluster_effect_index: payload[1],
params,
persistence: RgbPersistence::from_bits_retain(flags & FLAGS_FIELD_MASK),
power_mode: PowerModeTarget::try_from(
(flags >> POWER_TARGET_SHIFT) & FLAGS_FIELD_MASK,
)
.ok(),
})
}
_ => None,
}
}