From b156ae7812251c064af23e6a3548b5f0ddc08a58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Arnauts?= Date: Mon, 12 Dec 2016 02:59:30 +0100 Subject: [PATCH] Add support for Hue LightGroups (#4744) * Add support for Hue LightGroup entity * Don't filter on LightGroup and add properties for a group * Reuse code from HueLight in HueLightGroup * Remove HueLightGroup and add is_group variable to HueLight * Make linter happy * Update light or lightgroup state when a new state is available * Use schedule_update_ha_state() to schedule the state update. Drop new_lightgroups and use new_lights instead. * code style fix --- homeassistant/components/light/hue.py | 66 ++++++++++++++++++++------- 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/homeassistant/components/light/hue.py b/homeassistant/components/light/hue.py index da2158ba78d..74247ad24ef 100644 --- a/homeassistant/components/light/hue.py +++ b/homeassistant/components/light/hue.py @@ -142,6 +142,7 @@ def setup_bridge(host, hass, add_devices, filename, allow_unreachable): configurator.request_done(request_id) lights = {} + lightgroups = {} @util.Throttle(MIN_TIME_BETWEEN_SCANS, MIN_TIME_BETWEEN_FORCED_SCANS) def update_lights(): @@ -153,9 +154,15 @@ def setup_bridge(host, hass, add_devices, filename, allow_unreachable): _LOGGER.exception("Cannot reach the bridge") return - api_states = api.get('lights') + api_lights = api.get('lights') - if not isinstance(api_states, dict): + if not isinstance(api_lights, dict): + _LOGGER.error("Got unexpected result from Hue API") + return + + api_groups = api.get('groups') + + if not isinstance(api_groups, dict): _LOGGER.error("Got unexpected result from Hue API") return @@ -167,7 +174,7 @@ def setup_bridge(host, hass, add_devices, filename, allow_unreachable): else: bridge_type = 'hue' - for light_id, info in api_states.items(): + for light_id, info in api_lights.items(): if light_id not in lights: lights[light_id] = HueLight(int(light_id), info, bridge, update_lights, @@ -175,6 +182,17 @@ def setup_bridge(host, hass, add_devices, filename, allow_unreachable): new_lights.append(lights[light_id]) else: lights[light_id].info = info + lights[light_id].schedule_update_ha_state() + + for lightgroup_id, info in api_groups.items(): + if lightgroup_id not in lightgroups: + lightgroups[lightgroup_id] = HueLight( + int(lightgroup_id), info, bridge, update_lights, + bridge_type, allow_unreachable, True) + new_lights.append(lightgroups[lightgroup_id]) + else: + lightgroups[lightgroup_id].info = info + lightgroups[lightgroup_id].schedule_update_ha_state() if new_lights: add_devices(new_lights) @@ -229,15 +247,20 @@ class HueLight(Light): """Representation of a Hue light.""" def __init__(self, light_id, info, bridge, update_lights, - bridge_type, allow_unreachable): + bridge_type, allow_unreachable, is_group=False): """Initialize the light.""" self.light_id = light_id self.info = info self.bridge = bridge self.update_lights = update_lights self.bridge_type = bridge_type - self.allow_unreachable = allow_unreachable + self.is_group = is_group + + if is_group: + self._command_func = self.bridge.set_group + else: + self._command_func = self.bridge.set_light @property def unique_id(self): @@ -247,33 +270,44 @@ class HueLight(Light): @property def name(self): - """Return the mame of the Hue light.""" + """Return the name of the Hue light.""" return self.info.get('name', DEVICE_DEFAULT_NAME) @property def brightness(self): """Return the brightness of this light between 0..255.""" - return self.info['state'].get('bri') + if self.is_group: + return self.info['action'].get('bri') + else: + return self.info['state'].get('bri') @property def xy_color(self): """Return the XY color value.""" - return self.info['state'].get('xy') + if self.is_group: + return self.info['action'].get('xy') + else: + return self.info['state'].get('xy') @property def color_temp(self): """Return the CT color value.""" - return self.info['state'].get('ct') + if self.is_group: + return self.info['action'].get('ct') + else: + return self.info['state'].get('ct') @property def is_on(self): """Return true if device is on.""" - self.update_lights() - - if self.allow_unreachable: - return self.info['state']['on'] + if self.is_group: + return self.info['state']['any_on'] else: - return self.info['state']['reachable'] and self.info['state']['on'] + if self.allow_unreachable: + return self.info['state']['on'] + else: + return self.info['state']['reachable'] and \ + self.info['state']['on'] @property def supported_features(self): @@ -322,7 +356,7 @@ class HueLight(Light): elif self.bridge_type == 'hue': command['effect'] = 'none' - self.bridge.set_light(self.light_id, command) + self._command_func(self.light_id, command) def turn_off(self, **kwargs): """Turn the specified or all lights off.""" @@ -344,7 +378,7 @@ class HueLight(Light): elif self.bridge_type == 'hue': command['alert'] = 'none' - self.bridge.set_light(self.light_id, command) + self._command_func(self.light_id, command) def update(self): """Synchronize state with bridge."""