/// /// Configure udev: /// https://github.com/Grix/helios_dac/blob/master/docs/udev_rules_for_linux.md /// mod redis_ctrl; mod conf; mod errors; use helios_dac::{ NativeHeliosDacController, NativeHeliosDac, // Coordinate, Color, DeviceStatus, Frame, Point, }; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use redis_ctrl::{RedisCtrl,Order}; use conf::Conf; use errors::LJError; const CENTER : (u16,u16) = (2000, 2000); pub fn main() { match run_all() { Ok(()) => {}, Err(err) => { println!("Error: {}", err); } } } fn run_all() -> Result<(), Box> { let Some(filename) = std::env::args().nth(1) else { return Err(Box::new(LJError::ConfigFileMissing)); }; let config = Conf::new(&filename)?; let mut rs = RedisCtrl::new(&config.redis_url)?; let running = Arc::new(AtomicBool::new(true)); let r = running.clone(); ctrlc::set_handler(move || { r.store(false, Ordering::SeqCst); })?; let mut device = get_helios_device()?; while running.load(Ordering::SeqCst) { let order = rs.get_order(config.laser_id)?; if order != Order::Draw { println!("{:?}", order); } let frame = get_next_frame(&config, 1000, &mut rs, order == Order::Black)?; while let Ok(DeviceStatus::NotReady) = device.status() { } device.write_frame(frame)?; } println!("Exiting, stoping device."); device.stop()?; Ok(()) } fn get_helios_device() -> Result> { let controller = NativeHeliosDacController::new()?; let devices = controller.list_devices()?; let Some(device) = devices.into_iter().next() else { return Err(Box::new(LJError::HeliosDeviceMissing)); }; let device = device.open()?; Ok(device) } fn get_next_frame( config: &Conf, speed: u32, rs: &mut RedisCtrl, _black: bool ) -> Result> { let line = rs.get(&format!("/pl/{}/0", config.laser_id))?; let line: Vec = line.iter().map(tuple_to_point).collect(); let mut line2 = vec![]; while line2.len() < 48 { for p in &line { line2.push(*p); } } println!("{:?}", line2); Ok(Frame::new(speed, line2)) } fn tuple_to_point(tpl: &(f32, f32, u32)) -> Point { let (x, y, col) = tpl; let r = (col >> 16) as u8 ; let g = ((col >> 8) & 255) as u8 ; let b = (col & 255) as u8 ; let x = CENTER.0 + *x as u16 * 2; let y = CENTER.1 + *y as u16 * 2; if x >= 4096 || y >= 4096 { println!("WARN: coordinate out of range: {} {}", x, y); } let x = x.clamp(0, 4095); let y = y.clamp(0, 4095); Point { coordinate: (x, y).into(), color: Color::new(r, g, b), intensity: 0xFF, } }