use std::net::Ipv4Addr; use std::str::FromStr; use huehue::color::{Component, RGB8}; use huehue::models::device_type::DeviceType; use huehue::{Hue, Light}; use serde::Serialize; use structopt::StructOpt; #[derive(Debug, StructOpt, Serialize)] struct XyArguments { #[structopt(long)] pub x: f32, #[structopt(long)] pub y: f32, } #[derive(Debug, StructOpt, Serialize)] struct RgbArguments { #[structopt(long)] pub r: u8, #[structopt(long)] pub g: u8, #[structopt(long)] pub b: u8, } #[derive(Debug, StructOpt, Serialize)] struct DimmArguments { #[structopt(long)] pub value: f32, } #[derive(Debug, StructOpt, Serialize)] enum ActionArguments { Switch, Dimm(DimmArguments), Xy(XyArguments), Rgb(RgbArguments), } #[derive(Debug, StructOpt, Serialize)] struct Arguments { #[structopt(subcommand)] pub action: ActionArguments, #[structopt(long, env = "RUES_BRIDGE")] pub bridge: Ipv4Addr, #[structopt(long, env = "RUES_DEVICE_TYPE")] pub device_type: String, #[structopt(long, env = "RUES_APPLICATION_KEY")] pub application_key: String, #[structopt(long)] pub id: uuid::Uuid, } fn print_light(light: &Light) { println!("> Light {}:", light.name); println!("\tIdentifier: {}", light.id); println!("\tOn: {}", light.on); if let Some(brightness) = &light.brightness { println!("\tBrightness: {}", brightness); } if let Some(color) = &light.color { println!("\tColor: ({}, {})", color.xy.x, color.xy.y); println!( "\tGamut: R={},{} G={},{} B={},{}", color.gamut.red.x, color.gamut.red.y, color.gamut.green.x, color.gamut.green.y, color.gamut.blue.x, color.gamut.blue.y ); } if let Some(temperature) = &light.temperature { if let Some(value) = &temperature.mirek { let mirek_schema = &temperature.mirek_schema; println!( "\tTemperature: {} (min: {}, max {})", value, mirek_schema.mirek_minimum, mirek_schema.mirek_maximum ); } } } #[tokio::main] async fn main() { let arguments = Arguments::from_args(); let device_type = DeviceType::from_str(arguments.device_type.as_str()).expect("Invalid device name."); let hue = Hue::new_with_key(arguments.bridge, device_type, arguments.application_key) .await .expect("Failed to read bridge information."); let light_opt = match hue.lights().await { Ok(lights) => lights.into_iter().filter(|light| light.id == arguments.id).next(), Err(e) => { println!("Unexpected Hue error {:?}.", e); return; }, }; let mut light = match light_opt { Some(light) => light, None => { println!("Light {} not found.", arguments.id); return; }, }; match arguments.action { ActionArguments::Switch => { match light.switch(!light.on).await { Ok(_) => (), Err(e) => { println!("Unexpected Hue error {:?}.", e); return; }, } }, ActionArguments::Xy(color) => { match light .set_color(Component::new(color.x, color.y).expect("Invalid color.")) .await { Ok(_) => (), Err(e) => { println!("Unexpected Hue error {:?}.", e); return; }, } }, ActionArguments::Rgb(color) => { match light.set_color_rgb(RGB8::new(color.r, color.g, color.b)).await { Ok(_) => (), Err(e) => { println!("Unexpected Hue error {:?}.", e); return; }, } }, ActionArguments::Dimm(dimm) => { match light.dimm(dimm.value).await { Ok(_) => (), Err(e) => { println!("Unexpected Hue error {:?}.", e); return; }, } }, } print_light(&light); }