use redis::{Client, Commands, Connection}; use ron::de::from_str; use crate::device::Status; use crate::errors::{LJError, LJResult}; use crate::worldstate::{WorldState,EDH}; // use log::info; #[repr(u8)] #[derive(Debug, PartialEq)] pub enum Order { Draw = 0, Edh, //homography Black, Grid, Resampler, ClientKey, Intensity, Kpps, ColorBalance, } impl TryFrom for Order { type Error = String; fn try_from(value: u8) -> Result { use Order::*; if value > 8 { return Err("order out of range".to_string()); } Ok(match value { 0 => Draw, 1 => Edh, 2 => Black, 3 => Grid, 4 => Resampler, 5 => ClientKey, 6 => Intensity, 7 => Kpps, 8 => ColorBalance, _ => unreachable!() }) } } pub type Line = Vec<(f32, f32, u32)>; pub struct RedisCtrl { pub client: Client, pub connection: Connection, laser_id: u8, } impl RedisCtrl { pub fn new(url: &str, laser_id: &u8) -> LJResult { let client = Client::open(url) .map_err(LJError::RedisConnect)?; let connection = client.get_connection() .map_err(LJError::RedisConnect)?; Ok(RedisCtrl { client, connection, laser_id: *laser_id }) } pub fn get_line(&mut self, key: &str) -> LJResult { let val: String = self.connection.get(key)?; let line: Line = from_str(&val)?; Ok(line) } pub fn set(&mut self, key: String, value: String) -> LJResult<()> { self.connection.set(key, value)?; Ok(()) } pub fn get_order(&mut self, id: u8) -> LJResult { let path = format!("/order/{id}"); let val: u8 = self.connection.get(path.clone())?; if val == 1 || val >= 4 { self.connection.set(path, 0)?; } Ok(val.try_into()?) } /** /lstt/lasernumber etherdream last_status.playback_state (0: idle 1: prepare 2: playing) /cap/lasernumber number of empty points sent to fill etherdream buffer (up to 1799) /lack/lasernumber "a": ACK "F": Full "I": invalid. 64 or 35 for no connection. **/ pub fn set_status(&mut self, status: Status) -> LJResult<()> { let lstt_key = format!("/lstt/{}", self.laser_id); let cap_key = format!("/cap/{}", self.laser_id); let lack_key = format!("/lack/{}", self.laser_id); self.set(lstt_key, status.playback_state.to_string())?; self.set(cap_key, status.capacity.to_string())?; self.set(lack_key, status.lack.to_string())?; Ok(()) } pub fn init_world_state( &mut self) -> LJResult{ Ok(WorldState { client_key: self.connection.get("/clientkey")?, edh: self.get_edh()?, kpps: self.get_int("kpps")?.try_into()?, intensity: self.get_int("intensity")?.try_into()?, ..WorldState::default() }) } pub fn get_edh( &mut self ) -> LJResult { // Get new EDH let edh_key = format!("/EDH/{}", self.laser_id); let edh : String = self.connection.get(edh_key)?; let edh : Vec> = from_str(&edh)?; let edh = EDH::new(edh)?; Ok(edh) } pub fn get_int(&mut self, key: &str ) -> LJResult { // Get new Int let fmt = format!("/{key}/{}", self.laser_id); let val : u32 = self.connection.get(fmt)?; Ok(val) } }