use crate::conf::HeliosConf; use crate::device::{Device, PlaybackState, Status}; use crate::errors::{LJError, LJResult}; use crate::point::{Color, Point}; use chrono::Utc; use helios_dac::{ // Coordinate, // Color, DeviceStatus, Frame, // Point as HeliosPoint, }; /// /// Configure udev: /// https://github.com/Grix/helios_dac/blob/master/docs/udev_rules_for_linux.md /// use helios_dac::{NativeHeliosDac, NativeHeliosDacController}; pub struct HeliosDevice { pub conf: HeliosConf, dac: NativeHeliosDac, sent_points: u16, state: PlaybackState, lack: String, last_traced_at: String, } impl HeliosDevice { pub fn new(conf: &HeliosConf) -> LJResult { let id = conf.id; let controller = NativeHeliosDacController::new()?; let devices = controller.list_devices()?; let Some(device) = devices.into_iter().nth(id as usize) else { return Err(Box::new(LJError::HeliosDeviceMissing)); }; let dac = device.open()?; Ok(Self { conf: (*conf).clone(), dac, sent_points: 0, state: PlaybackState::PREPARE, lack: "".to_string(), last_traced_at: "1985-04-12T23:20:50.52Z".to_string(), }) } } impl Device for HeliosDevice { fn status(&mut self) -> Status { let lack = self.lack.clone(); Status { last_traced_at: self.last_traced_at.clone(), properties: vec!["foo".to_string()], playback_state: self.state, capacity: self.sent_points, lack, } } fn draw(&mut self, line: Vec, speed: u32) -> LJResult<()> { self.state = PlaybackState::IDLE; while let Ok(DeviceStatus::NotReady) = self.dac.status() {} self.state = PlaybackState::PLAYING; let points: Vec = line.into_iter().map(|p| p.into()).collect(); let frame = Frame::new(speed, points.clone()); self.dac.write_frame(frame.clone())?; self.sent_points = points.len() as u16; self.last_traced_at = Utc::now().to_rfc3339(); Ok(()) } fn stop(&mut self) -> LJResult<()> { self.dac.stop()?; Ok(()) } fn grid(&mut self) -> Vec { let dim_min = 0 as f32; let dim_mid = 2047 as f32; let dim_max = 4095 as f32; let col_min = Color { r: 0, g: 0, b: 0 }; let col_max = Color { r: 255, g: 255, b: 255, }; vec![ Point { x: dim_min, y: dim_max, color: col_min, }, Point { x: dim_min, y: dim_max, color: col_max, }, Point { x: dim_max, y: dim_max, color: col_max, }, Point { x: dim_max, y: dim_min, color: col_max, }, Point { x: dim_min, y: dim_min, color: col_max, }, Point { x: dim_min, y: dim_min, color: col_min, }, Point { x: dim_min, y: dim_mid, color: col_min, }, Point { x: dim_min, y: dim_mid, color: col_max, }, Point { x: dim_mid, y: dim_mid, color: col_max, }, Point { x: dim_mid, y: dim_min, color: col_max, }, Point { x: dim_min, y: dim_min, color: col_max, }, Point { x: dim_min, y: dim_min, color: col_min, }, ] } }