lj_rust/src/redis_ctrl.rs

135 lines
3.7 KiB
Rust

use crate::device::Status;
use crate::errors::{LJError, LJResult};
use crate::worldstate::{WorldState, EDH};
use redis::{Client, Commands, Connection};
use ron::de::from_str;
// use log::info;
#[repr(u8)]
#[derive(Debug, PartialEq)]
pub enum Order {
Draw = 0,
Edh,
//homography
Black,
Grid,
Resampler,
ClientKey,
Intensity,
Kpps,
ColorBalance,
}
impl TryFrom<u8> for Order {
type Error = String;
fn try_from(value: u8) -> Result<Self, Self::Error> {
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<Self> {
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<Line> {
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<Order> {
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<WorldState> {
Ok(WorldState {
client_key: self.get_client_key().unwrap(),
edh: self.get_edh().unwrap(),
kpps: self.get_int("kpps").unwrap().try_into().unwrap(),
intensity: self.get_int("intensity").unwrap().try_into().unwrap(),
..WorldState::default()
})
}
pub fn get_edh(&mut self) -> LJResult<EDH> {
// Get new EDH
let edh_key = format!("/EDH/{}", self.laser_id);
let edh: String = self.connection.get(edh_key)?;
let edh: Vec<Vec<f32>> = from_str(&edh)?;
let edh = EDH::new(edh)?;
Ok(edh)
}
pub fn get_client_key(&mut self) -> LJResult<String> {
let key: String = self.connection.get("/clientkey")?;
Ok(key)
}
pub fn get_int(&mut self, key: &str) -> LJResult<u32> {
// Get new Int
let fmt = format!("/{key}/{}", self.laser_id);
let val: u32 = self.connection.get(fmt)?;
Ok(val)
}
}