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
pull/4822/head^2
Michaël Arnauts 2016-12-12 02:59:30 +01:00 committed by Paulus Schoutsen
parent 48928d1f9e
commit b156ae7812
1 changed files with 50 additions and 16 deletions

View File

@ -142,6 +142,7 @@ def setup_bridge(host, hass, add_devices, filename, allow_unreachable):
configurator.request_done(request_id) configurator.request_done(request_id)
lights = {} lights = {}
lightgroups = {}
@util.Throttle(MIN_TIME_BETWEEN_SCANS, MIN_TIME_BETWEEN_FORCED_SCANS) @util.Throttle(MIN_TIME_BETWEEN_SCANS, MIN_TIME_BETWEEN_FORCED_SCANS)
def update_lights(): def update_lights():
@ -153,9 +154,15 @@ def setup_bridge(host, hass, add_devices, filename, allow_unreachable):
_LOGGER.exception("Cannot reach the bridge") _LOGGER.exception("Cannot reach the bridge")
return 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") _LOGGER.error("Got unexpected result from Hue API")
return return
@ -167,7 +174,7 @@ def setup_bridge(host, hass, add_devices, filename, allow_unreachable):
else: else:
bridge_type = 'hue' 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: if light_id not in lights:
lights[light_id] = HueLight(int(light_id), info, lights[light_id] = HueLight(int(light_id), info,
bridge, update_lights, bridge, update_lights,
@ -175,6 +182,17 @@ def setup_bridge(host, hass, add_devices, filename, allow_unreachable):
new_lights.append(lights[light_id]) new_lights.append(lights[light_id])
else: else:
lights[light_id].info = info 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: if new_lights:
add_devices(new_lights) add_devices(new_lights)
@ -229,15 +247,20 @@ class HueLight(Light):
"""Representation of a Hue light.""" """Representation of a Hue light."""
def __init__(self, light_id, info, bridge, update_lights, def __init__(self, light_id, info, bridge, update_lights,
bridge_type, allow_unreachable): bridge_type, allow_unreachable, is_group=False):
"""Initialize the light.""" """Initialize the light."""
self.light_id = light_id self.light_id = light_id
self.info = info self.info = info
self.bridge = bridge self.bridge = bridge
self.update_lights = update_lights self.update_lights = update_lights
self.bridge_type = bridge_type self.bridge_type = bridge_type
self.allow_unreachable = allow_unreachable 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 @property
def unique_id(self): def unique_id(self):
@ -247,33 +270,44 @@ class HueLight(Light):
@property @property
def name(self): 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) return self.info.get('name', DEVICE_DEFAULT_NAME)
@property @property
def brightness(self): def brightness(self):
"""Return the brightness of this light between 0..255.""" """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 @property
def xy_color(self): def xy_color(self):
"""Return the XY color value.""" """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 @property
def color_temp(self): def color_temp(self):
"""Return the CT color value.""" """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 @property
def is_on(self): def is_on(self):
"""Return true if device is on.""" """Return true if device is on."""
self.update_lights() if self.is_group:
return self.info['state']['any_on']
if self.allow_unreachable:
return self.info['state']['on']
else: 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 @property
def supported_features(self): def supported_features(self):
@ -322,7 +356,7 @@ class HueLight(Light):
elif self.bridge_type == 'hue': elif self.bridge_type == 'hue':
command['effect'] = 'none' command['effect'] = 'none'
self.bridge.set_light(self.light_id, command) self._command_func(self.light_id, command)
def turn_off(self, **kwargs): def turn_off(self, **kwargs):
"""Turn the specified or all lights off.""" """Turn the specified or all lights off."""
@ -344,7 +378,7 @@ class HueLight(Light):
elif self.bridge_type == 'hue': elif self.bridge_type == 'hue':
command['alert'] = 'none' command['alert'] = 'none'
self.bridge.set_light(self.light_id, command) self._command_func(self.light_id, command)
def update(self): def update(self):
"""Synchronize state with bridge.""" """Synchronize state with bridge."""