use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use serde::{Deserialize, Serialize};
use smart_leds_trait::{SmartLedsWrite, RGB8};
pub static LED_CHANNEL: embassy_sync::channel::Channel<CriticalSectionRawMutex, LEDCommand, 16> =
embassy_sync::channel::Channel::new();
const LED_COUNT: usize = 2;
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
#[serde(tag = "lc", rename_all = "snake_case")]
pub enum LEDCommand {
On,
Off,
SC { r: u8, g: u8, b: u8 },
}
pub struct LedModule<Driver> {
driver: Driver,
is_on: bool,
last_color: Option<RGB8>,
}
impl<Driver, E> LedModule<Driver>
where
Driver: SmartLedsWrite<Color = RGB8, Error = E>,
{
pub fn new(driver: Driver) -> Self {
Self {
driver,
is_on: false,
last_color: None,
}
}
pub fn ex_command(
&mut self,
cmd: LEDCommand,
) -> Result<(), E> {
match cmd {
LEDCommand::On => {
self.is_on = true;
let color = self.last_color.unwrap_or(RGB8 {
r: 255,
g: 255,
b: 255,
});
self.set_all(color)?;
}
LEDCommand::Off => {
self.is_on = false;
self.set_all(RGB8 { r: 0, g: 0, b: 0 })?;
}
LEDCommand::SC { r, g, b } => {
let new_color = RGB8 { r, g, b };
self.last_color = Some(new_color);
if self.is_on {
self.set_all(new_color)?;
}
}
}
Ok(())
}
fn set_all(
&mut self,
color: RGB8,
) -> Result<(), E> {
let data = core::iter::repeat(color).take(LED_COUNT);
self.driver.write(data)
}
}