use crate::config::{Context, Mode}; use crate::zabbix::api::get_zabbix_problems; use launchy::Color; use launchy::{self, Canvas, CanvasLayout, CanvasLayoutPoller, MsgPollingWrapper, Pad}; use std::thread::sleep; use std::time::Duration; const MATRIX_WIDTH: i32 = 8; const MATRIX_SIZE: i32 = MATRIX_WIDTH * MATRIX_WIDTH; const REQUEST_TIMEOUT: i32 = 5; const SLOWEFFECT_FACTOR: f32 = 800.0; pub fn run(ctx: &mut Context) { match ctx.mode { Some(Mode::Draw) => { let (mut canvas, mut _poller) = initpad(); draw(&mut canvas, ctx); } Some(Mode::Input) => { let (mut canvas, mut poller) = initpad(); input(&mut canvas, &mut poller); } Some(Mode::Effect) => { let (mut canvas, mut poller) = initpad(); effect(&mut canvas, &mut poller) } Some(Mode::Test) => test(ctx), None => { println!("No valid option choosen for mode"); } } } fn initpad() -> (CanvasLayout<'static>, CanvasLayoutPoller) { let (mut canvas, poller) = launchy::CanvasLayout::new_polling(); match canvas.add_by_guess::<launchy::mini_mk3::Canvas>(0, 0) { Ok(_) => { println!("Connected to device using USB"); clear(&mut canvas); } Err(err) => { eprintln!("Failed to connect to device, check USB connection {err}",); } }; canvas[Pad { x: 0, y: 0 }] = Color::BLUE; canvas.flush().unwrap(); sleep(Duration::from_millis(100)); (canvas, poller) } fn input(canvas: &mut CanvasLayout, poller: &mut CanvasLayoutPoller) { for color in (0u64..).map(|f| Color::red_green_color(f as f32 / 60.0 / 2.5)) { for msg in poller.iter_for_millis(17).filter(|msg| msg.is_press()) { canvas[msg.pad()] = color; println!("{msg:?}", msg = msg.pad()) } canvas.flush().unwrap(); } } fn test(ctx: &mut Context) { println!( "Refresh rate is {sec} seconds", sec = ctx.cfg.refresh.unwrap() ); loop { let zabbix_data = match get_zabbix_problems(&ctx.cfg) { Ok(z) => z, Err(_) => { println!( "Error requesting zabbix service, retrying in {} seconds", REQUEST_TIMEOUT ); sleep(Duration::from_secs(REQUEST_TIMEOUT as u64)); continue; } }; println!("{}", zabbix_data); ctx.hotreload(); } } fn draw(canvas: &mut CanvasLayout, ctx: &mut Context) { println!("Refresh rate is {} seconds", ctx.cfg.refresh.unwrap()); loop { let mut max = 0; let zabbix_data = match get_zabbix_problems(&ctx.cfg) { Ok(zabbix_data) => zabbix_data, Err(_) => { println!( "Error requesting zabbix service, retrying in {}", REQUEST_TIMEOUT ); sleep(Duration::from_secs(REQUEST_TIMEOUT as u64)); continue; } }; ctx.datamatrix.compute(&zabbix_data); clear(canvas); for (i, j) in ctx.datamatrix.layout.iter().enumerate() { let p = Pad { x: ((i as i32) % MATRIX_WIDTH), y: ((i as i32) / MATRIX_WIDTH) + 1, }; canvas[p] = match j.status { 5 => Color::RED, 4 => Color::new(1., 0.2, 0.), 3 => Color::new(1., 0.4, 0.), 2 => Color::new(1., 0.6, 0.), 1 => Color::BLUE, _ => Color::GREEN, }; if ctx.cfg.sloweffect.unwrap() { sleep(Duration::from_millis( (SLOWEFFECT_FACTOR * (1.0 / ctx.datamatrix.layout.len() as f32)) as u64, )); } canvas.flush().unwrap(); max += 1; if max >= MATRIX_SIZE { break; } } ctx.hotreload(); } } fn effect(canvas: &mut CanvasLayout, poller: &mut CanvasLayoutPoller) { loop { for color in (0u64..).map(|f| Color::red_green_color(f as f32 / 60.0 / 2.5)) { for msg in poller.iter_for_millis(17).filter(|msg| msg.is_press()) { canvas[msg.pad()] = color; println!("{msg:?}", msg = msg.pad()) } canvas.flush().unwrap(); canvas.iter().for_each(|pad| { let surrounding_color = pad .neighbors_5() .iter() .map(|&p| canvas.get(p).unwrap_or(Color::GREEN)) .sum::<Color>() / 5.0 / 1.05; canvas[pad] = canvas[pad].mix(surrounding_color, 0.4); }); } clear(canvas); } } fn clear(canvas: &mut CanvasLayout) { for a in 0..MATRIX_WIDTH { for b in 0..MATRIX_WIDTH + 1 { canvas[Pad { x: a, y: b }] = Color::BLACK; } } canvas.flush().unwrap(); }