lifx-mqtt-bridge/src/light.rs

104 lines
2.5 KiB
Rust
Raw Normal View History

2019-01-20 12:02:39 +00:00
use log::warn;
2019-01-20 09:02:44 +00:00
#[derive(Deserialize, Debug, Clone)]
2019-01-15 20:41:43 +00:00
pub struct Color {
2019-02-09 17:32:23 +00:00
pub hue: f32,
2019-01-15 20:41:43 +00:00
pub saturation: f32,
2019-01-20 12:02:39 +00:00
pub kelvin: i16,
2019-01-15 20:41:43 +00:00
}
2019-01-20 09:02:44 +00:00
#[derive(Deserialize, Debug, Clone)]
2019-01-15 20:41:43 +00:00
pub struct Light {
pub id: String,
pub label: String,
pub connected: bool,
pub power: String,
pub color: Color,
pub brightness: f32,
}
2019-01-20 09:02:44 +00:00
pub const POWER: &str = "power";
pub const BRIGHTNESS: &str = "brightness";
2019-01-20 12:02:39 +00:00
pub const HUE: &str = "hue";
pub const SATURATION: &str = "saturation";
pub const KELVIN: &str = "kelvin";
2019-01-16 21:46:12 +00:00
pub enum Value {
Power(String),
Brightness(f32),
2019-02-09 17:32:23 +00:00
Hue(f32),
2019-01-20 12:02:39 +00:00
Saturation(f32),
Kelvin(i16),
2019-01-16 21:46:12 +00:00
}
impl Value {
2019-01-20 12:02:39 +00:00
pub fn new(label: &str, value: Vec<u8>) -> Option<Self> {
2019-01-16 21:46:12 +00:00
match label {
2019-01-20 12:02:39 +00:00
POWER => Some(Value::Power(
String::from_utf8(value.clone())
.or_else(|x| {
warn!("{:#?}: {}", value, x);
Err(x)
})
.ok()?,
)),
BRIGHTNESS => Some(Value::Brightness(vec_to_f32(value)?)),
2019-02-09 17:32:23 +00:00
HUE => Some(Value::Hue(vec_to_f32(value)?)),
2019-01-20 12:02:39 +00:00
SATURATION => Some(Value::Saturation(vec_to_f32(value)?)),
KELVIN => Some(Value::Kelvin(vec_to_i16(value)?)),
2019-01-16 21:46:12 +00:00
_ => unimplemented!(),
}
}
pub fn unravel(self) -> (&'static str, Vec<u8>) {
match self {
Value::Power(val) => (POWER, val.into_bytes()),
2019-01-20 09:02:44 +00:00
Value::Brightness(val) => (BRIGHTNESS, (val as u32).to_ne_bytes().to_vec()),
2019-01-20 12:02:39 +00:00
Value::Hue(val) => (HUE, (val as u32).to_ne_bytes().to_vec()),
Value::Saturation(val) => (SATURATION, (val as u32).to_ne_bytes().to_vec()),
Value::Kelvin(val) => (KELVIN, (val as u32).to_ne_bytes().to_vec()),
2019-01-16 21:46:12 +00:00
}
}
}
2019-01-20 12:02:39 +00:00
fn vec_to_f32(value: Vec<u8>) -> Option<f32> {
if value.len() == 4 {
Some(u32::from_ne_bytes([value[0], value[1], value[2], value[3]]) as f32)
} else {
None
}
}
fn vec_to_i16(value: Vec<u8>) -> Option<i16> {
if value.len() == 2 {
Some(i16::from_ne_bytes([value[0], value[1]]))
} else {
None
}
2019-01-20 09:02:44 +00:00
}
2019-01-16 21:46:12 +00:00
pub struct Command {
2019-02-09 17:32:23 +00:00
pub lightname: String,
2019-01-16 21:46:12 +00:00
pub command: Value,
}
pub struct Update {
2019-02-09 17:32:23 +00:00
pub lightname: String,
2019-01-16 21:46:12 +00:00
pub status: Value,
}
2019-01-20 09:02:44 +00:00
impl Update {
2019-02-09 17:32:23 +00:00
pub fn new(lightname: &str, status: Value) -> Self {
2019-01-20 09:02:44 +00:00
Update {
2019-02-09 17:32:23 +00:00
lightname: lightname.to_owned(),
2019-01-20 09:02:44 +00:00
status,
}
}
}
2019-01-16 21:46:12 +00:00
pub enum Status {
Update(Update),
New(Light),
Remove(String),
}