From 4cc80ea51073055dd13565b3a9a4eb48d99aebd5 Mon Sep 17 00:00:00 2001 From: Sawyer McLane Date: Mon, 16 Dec 2024 14:14:42 -0700 Subject: [PATCH] Add scene management functionality with color application and tests --- README.md | 2 ++ src/device_info.rs | 7 ++++ src/lib.rs | 1 + src/scenes.rs | 87 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+) create mode 100644 src/scenes.rs diff --git a/README.md b/README.md index ef8d8f8..6a8186d 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ Mantle is a desktop application for controlling LIFX lights, born from the ashes You can download the latest release [here](https://github.com/samclane/mantle/releases). +**Note:** Right now I'm only building for Windows, but it should build on Linux and MacOS as well. Still getting GitHub Actions set up for that. + ## Screenshots ![Mantle](res/screenshot.png) diff --git a/src/device_info.rs b/src/device_info.rs index e8ad676..32ae66e 100644 --- a/src/device_info.rs +++ b/src/device_info.rs @@ -158,6 +158,13 @@ impl DeviceInfo { DeviceInfo::Group(g) => Some(g.label.to_string()), } } + + pub fn color(&self) -> Option<&HSBK> { + match self { + DeviceInfo::Bulb(b) => b.get_color(), + DeviceInfo::Group(_) => None, // TODO: Implement group color + } + } } impl BulbInfo { diff --git a/src/lib.rs b/src/lib.rs index f2671a5..530217f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ pub mod device_manager; pub mod listener; pub mod products; pub mod refreshable_data; +pub mod scenes; pub mod screencap; pub mod serializers; pub mod settings; diff --git a/src/scenes.rs b/src/scenes.rs new file mode 100644 index 0000000..705f8e3 --- /dev/null +++ b/src/scenes.rs @@ -0,0 +1,87 @@ +use lifx_core::HSBK; + +use crate::{color::default_hsbk, device_info::DeviceInfo, LifxManager}; + +pub struct Scene { + pub device_color_pairs: Vec<(DeviceInfo, HSBK)>, +} + +impl Scene { + /// A scene defines a set of devices and their colors so that they can be applied all at once. + /// This is useful for setting up a specific lighting configuration that you want to be able to + /// apply quickly. + + pub fn new(device_color_pairs: Vec<(DeviceInfo, HSBK)>) -> Self { + Self { device_color_pairs } + } + + pub fn apply(&self, lifx_manager: &mut LifxManager) { + for (device, color) in &self.device_color_pairs { + match device { + DeviceInfo::Bulb(bulb) => { + lifx_manager.set_color(&&**bulb, *color, None).unwrap(); + } + DeviceInfo::Group(group) => { + lifx_manager + .set_group_color(group, *color, &lifx_manager.bulbs.lock().unwrap(), None) + .unwrap(); + } + } + } + } +} + +impl From> for Scene { + fn from(devices: Vec) -> Self { + let device_color_pairs = devices + .into_iter() + .map(|device| (device.clone(), *device.color().unwrap_or(&default_hsbk()))) + .collect(); + + Self::new(device_color_pairs) + } +} + +#[cfg(test)] +mod test { + use std::net::{IpAddr, Ipv4Addr, SocketAddr}; + + use super::*; + use crate::device_info::BulbInfo; + + #[test] + fn test_scene_from_vec() { + let source = 1234; + let target = 5678; + let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 56700); + let mut bulb = BulbInfo::new(source, target, addr); + bulb.update(addr); + let scene = Scene::from(vec![DeviceInfo::Bulb(Box::new(bulb.clone()))]); + + assert_eq!(scene.device_color_pairs.len(), 1); + assert_eq!( + scene.device_color_pairs[0].0, + DeviceInfo::Bulb(Box::new(bulb)) + ); + } + + #[test] + fn test_create_scene() { + let source = 1234; + let target = 5678; + let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 56700); + let mut bulb = BulbInfo::new(source, target, addr); + bulb.update(addr); + let scene = Scene::new(vec![( + DeviceInfo::Bulb(Box::new(bulb.clone())), + default_hsbk(), + )]); + + assert_eq!(scene.device_color_pairs.len(), 1); + assert_eq!( + scene.device_color_pairs[0].0, + DeviceInfo::Bulb(Box::new(bulb)) + ); + assert_eq!(scene.device_color_pairs[0].1, default_hsbk()); + } +}