-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #388 from cr/cr-huecolor
Adding Color support for Philips Hue
- Loading branch information
Showing
5 changed files
with
281 additions
and
77 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,8 @@ pub struct Light { | |
pub get_available_id: Id<Getter>, | ||
pub get_power_id: Id<Getter>, | ||
pub set_power_id: Id<Setter>, | ||
pub get_color_id: Id<Getter>, | ||
pub set_color_id: Id<Setter>, | ||
} | ||
|
||
impl Light { | ||
|
@@ -45,6 +47,8 @@ impl Light { | |
get_available_id: create_getter_id("available", &hub_id, &light_id), | ||
get_power_id: create_getter_id("power", &hub_id, &light_id), | ||
set_power_id: create_setter_id("power", &hub_id, &light_id), | ||
get_color_id: create_getter_id("color", &hub_id, &light_id), | ||
set_color_id: create_setter_id("color", &hub_id, &light_id), | ||
} | ||
} | ||
pub fn start(&self) { | ||
|
@@ -58,9 +62,12 @@ impl Light { | |
{ | ||
let adapter_id = create_adapter_id(); | ||
let status = self.api.lock().unwrap().get_light_status(&self.light_id); | ||
|
||
if status.lighttype == "Extended color light" { | ||
info!("New Philips Hue Extended Color Light service for light {} on bridge {}", | ||
|
||
info!("New Philips Hue `Extended Color Light` service for light {} on bridge {}", | ||
self.light_id, self.hub_id); | ||
|
||
let mut service = Service::empty(self.service_id.clone(), adapter_id.clone()); | ||
service.properties.insert(CUSTOM_PROPERTY_MANUFACTURER.to_owned(), | ||
status.manufacturername.to_owned()); | ||
|
@@ -119,6 +126,104 @@ impl Light { | |
}, | ||
})); | ||
|
||
try!(manager.add_getter(Channel { | ||
tags: HashSet::new(), | ||
adapter: adapter_id.clone(), | ||
id: self.get_color_id.clone(), | ||
last_seen: None, | ||
service: self.service_id.clone(), | ||
mechanism: Getter { | ||
kind: ChannelKind::Extension { | ||
vendor: Id::new("[email protected]"), | ||
adapter: Id::new("Philips Hue Adapter"), | ||
kind: Id::new("Color"), | ||
typ: Type::Color, | ||
}, | ||
updated: None, | ||
}, | ||
})); | ||
|
||
try!(manager.add_setter(Channel { | ||
tags: HashSet::new(), | ||
adapter: adapter_id.clone(), | ||
id: self.set_color_id.clone(), | ||
last_seen: None, | ||
service: self.service_id.clone(), | ||
mechanism: Setter { | ||
kind: ChannelKind::Extension { | ||
vendor: Id::new("[email protected]"), | ||
adapter: Id::new("Philips Hue Adapter"), | ||
kind: Id::new("Color"), | ||
typ: Type::Color, | ||
}, | ||
updated: None, | ||
}, | ||
})); | ||
|
||
let mut services_lock = services.lock().unwrap(); | ||
services_lock.getters.insert(self.get_available_id.clone(), self.clone()); | ||
services_lock.getters.insert(self.get_power_id.clone(), self.clone()); | ||
services_lock.setters.insert(self.set_power_id.clone(), self.clone()); | ||
services_lock.getters.insert(self.get_color_id.clone(), self.clone()); | ||
services_lock.setters.insert(self.set_color_id.clone(), self.clone()); | ||
|
||
} else if status.lighttype == "Dimmable light" { | ||
info!("New Philips Hue `Dimmable Light` service for light {} on bridge {}", | ||
self.light_id, self.hub_id); | ||
let mut service = Service::empty(self.service_id.clone(), adapter_id.clone()); | ||
service.properties.insert(CUSTOM_PROPERTY_MANUFACTURER.to_owned(), | ||
status.manufacturername.to_owned()); | ||
service.properties.insert(CUSTOM_PROPERTY_MODEL.to_owned(), | ||
status.modelid.to_owned()); | ||
service.properties.insert(CUSTOM_PROPERTY_NAME.to_owned(), | ||
status.name.to_owned()); | ||
service.properties.insert(CUSTOM_PROPERTY_TYPE.to_owned(), | ||
"Light/DimmerLight".to_owned()); | ||
service.tags.insert(tag_id!("type:Light/DimmerLight")); | ||
|
||
try!(manager.add_service(service)); | ||
|
||
try!(manager.add_getter(Channel { | ||
tags: HashSet::new(), | ||
adapter: adapter_id.clone(), | ||
id: self.get_available_id.clone(), | ||
last_seen: None, | ||
service: self.service_id.clone(), | ||
mechanism: Getter { | ||
kind: ChannelKind::Extension { | ||
vendor: Id::new("[email protected]"), | ||
adapter: Id::new("Philips Hue Adapter"), | ||
kind: Id::new("available"), | ||
typ: Type::OnOff, | ||
}, | ||
updated: None, | ||
}, | ||
})); | ||
|
||
try!(manager.add_getter(Channel { | ||
tags: HashSet::new(), | ||
adapter: adapter_id.clone(), | ||
id: self.get_power_id.clone(), | ||
last_seen: None, | ||
service: self.service_id.clone(), | ||
mechanism: Getter { | ||
kind: ChannelKind::LightOn, | ||
updated: None, | ||
}, | ||
})); | ||
|
||
try!(manager.add_setter(Channel { | ||
tags: HashSet::new(), | ||
adapter: adapter_id.clone(), | ||
id: self.set_power_id.clone(), | ||
last_seen: None, | ||
service: self.service_id.clone(), | ||
mechanism: Setter { | ||
kind: ChannelKind::LightOn, | ||
updated: None, | ||
}, | ||
})); | ||
|
||
let mut services_lock = services.lock().unwrap(); | ||
services_lock.getters.insert(self.get_available_id.clone(), self.clone()); | ||
services_lock.getters.insert(self.get_power_id.clone(), self.clone()); | ||
|
@@ -145,4 +250,45 @@ impl Light { | |
self.api.lock().unwrap().set_light_power(&self.light_id, on); | ||
} | ||
|
||
#[allow(dead_code)] | ||
pub fn get_brightness(&self) -> f64 { | ||
// Hue API gives brightness value in [0, 254] | ||
let ls = self.api.lock().unwrap().get_light_status(&self.light_id); | ||
ls.state.bri as f64 / 254f64 | ||
} | ||
|
||
#[allow(dead_code)] | ||
pub fn set_brightness(&self, bri: f64) { | ||
// Hue API takes brightness value in [0, 254] | ||
let bri = bri.max(0f64).min(1f64); // [0,1] | ||
|
||
// convert to value space used by Hue | ||
let bri: u32 = (bri * 254f64) as u32; | ||
|
||
self.api.lock().unwrap().set_light_brightness(&self.light_id, bri); | ||
} | ||
|
||
pub fn get_color(&self) -> (f64, f64, f64) { | ||
// Hue API gives hue angle in [0, 65535], and sat and val in [0, 254] | ||
let ls = self.api.lock().unwrap().get_light_status(&self.light_id); | ||
let hue: f64 = ls.state.hue.unwrap_or(0) as f64 / 65536f64 * 360f64; | ||
let sat: f64 = ls.state.sat.unwrap_or(0) as f64 / 254f64; | ||
let val: f64 = ls.state.bri as f64 / 254f64; | ||
(hue, sat, val) | ||
} | ||
|
||
pub fn set_color(&self, hsv: (f64, f64, f64)) { | ||
// Hue API takes hue angle in [0, 65535], and sat and val in [0, 254] | ||
let (hue, sat, val) = hsv; | ||
let hue = ((hue % 360f64) + 360f64) % 360f64; // [0,360) | ||
let sat = sat.max(0f64).min(1f64); // [0,1] | ||
let val = val.max(0f64).min(1f64); // [0,1] | ||
|
||
// convert to value space used by Hue | ||
let hue: u32 = (hue * 65536f64 / 360f64) as u32; | ||
let sat: u32 = (sat * 254f64) as u32; | ||
let val: u32 = (val * 254f64) as u32; | ||
|
||
self.api.lock().unwrap().set_light_color(&self.light_id, (hue, sat, val)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.