-
-
Save jjensn/83dd60d96330bbf66e58dfae336187bf to your computer and use it in GitHub Desktop.
import logging | |
# Import the device class from the component that you want to support | |
from homeassistant.components import light | |
from homeassistant.const import (STATE_OFF, STATE_ON, SERVICE_TURN_ON, | |
SERVICE_TURN_OFF, ATTR_ENTITY_ID) | |
from homeassistant.components.light import (SUPPORT_BRIGHTNESS, | |
SUPPORT_RGB_COLOR, | |
SUPPORT_COLOR_TEMP, | |
SUPPORT_TRANSITION) | |
CONF_NAME = 'name' | |
CONF_ENTITIES = 'entities' # | |
_LOGGER = logging.getLogger(__name__) | |
SUPPORT_GROUP_LIGHT = (SUPPORT_BRIGHTNESS | SUPPORT_RGB_COLOR | | |
SUPPORT_COLOR_TEMP | SUPPORT_TRANSITION) | |
def setup_platform(hass, config, add_devices, discovery_info=None): | |
"""Initialize grouped light platform.""" | |
name = config.get(CONF_NAME) | |
entity_ids = config.get(CONF_ENTITIES) | |
if name is None or entity_ids is None or len(entity_ids) == 0: | |
_LOGGER.error('Invalid config. Excepted %s and %s', CONF_NAME, CONF_ENTITIES) | |
return False | |
add_devices([GroupedLight(hass, name, entity_ids)]) | |
class GroupedLight(light.Light): | |
"""Represents an Grouped Light in Home Assistant.""" | |
def __init__(self, hass, name, entity_ids): | |
"""Initialize a Grouped Light.""" | |
self.hass = hass | |
self._name = name | |
self._entity_ids = entity_ids | |
@property | |
def name(self): | |
return self._name | |
@property | |
def brightness(self): | |
"""Brightness of the light group""" | |
brightness = 0 | |
for state in self._light_states(): | |
if not 'brightness' in state.attributes: | |
return None | |
brightness += state.attributes.get('brightness') | |
brightness = brightness / float(len(self._entity_ids)) | |
return brightness | |
@property | |
def color_temp(self): | |
"""Return the CT color value.""" | |
for state in self._light_states(): | |
if not 'color_temp' in state.attributes: | |
return None | |
return state.attributes.get('color_temp') | |
@property | |
def xy_color(self): | |
"""Return the XY color value.""" | |
for state in self._light_states(): | |
if not 'xy_color' in state.attributes: | |
return None | |
#return the first value we get since merging color values does not make sense | |
return state.attributes.get('xy_color') | |
@property | |
def rgb_color(self): | |
"""Return the RGB color value.""" | |
for state in self._light_states(): | |
if not 'rgb_color' in state.attributes: | |
return None | |
#return the first value we get since merging color values does not make sense | |
return state.attributes.get('rgb_color') | |
@property | |
def is_on(self): | |
"""If light is on.""" | |
for state in self._light_states(): | |
if state.state == STATE_ON: | |
return True | |
return False | |
@property | |
def supported_features(self): | |
"""Flag supported features.""" | |
return SUPPORT_GROUP_LIGHT | |
def _light_states(self): | |
"""The states that the group is tracking.""" | |
states = [] | |
for entity_id in self._entity_ids: | |
state = self.hass.states.get(entity_id) | |
if state is not None: | |
states.append(state) | |
return states | |
def turn_on(self, **kwargs): | |
"""Forward the turn_on command to all lights in the group""" | |
for entity_id in self._entity_ids: | |
kwargs[ATTR_ENTITY_ID] = entity_id | |
self.hass.services.call('light', SERVICE_TURN_ON, kwargs, blocking=True) | |
def turn_off(self, **kwargs): | |
"""Forward the turn_off command to all lights in the group""" | |
for entity_id in self._entity_ids: | |
kwargs[ATTR_ENTITY_ID] = entity_id | |
self.hass.services.call('light', SERVICE_TURN_OFF, kwargs, blocking=True) | |
Updated to support attributes (now can be controlled by alexa)
How do you use this (in configuration.yaml)?
Thanks, this works great. :)
@timdonovanuk: just in case someone else has the same question later:
light:
- platform: grouped_light
name: "Test Grouped Light"
entities:
- light.first_light_name
- light.second_light_name
This is the best. 👍
Make sure you copy the 'grouped_light.py' into /custom_components/light or you will be getting all kinds of errors.
Great work with this custom component. Works very well. Shame it is not part of home-assistant by default.
Is it possible to add an event callback/listener so that if all the lights in the group are turned off, the grouped_light will change its state to off (like how the normal group component works)? Right now, if I turn off the individual lights instead of the grouped_light, the grouped_light for those individual lights are still considered to be "on".
Here is a version which updates when the other entities change. I also changed the way some properties are computed since the old version assumed all entities were in sync (or so it seamed)
import asyncio
import logging
# Import the device class from the component that you want to support
from homeassistant.core import callback
from homeassistant.components import light
from homeassistant.const import (STATE_OFF, STATE_ON, SERVICE_TURN_ON,
SERVICE_TURN_OFF, ATTR_ENTITY_ID)
from homeassistant.components.light import (SUPPORT_BRIGHTNESS,
SUPPORT_RGB_COLOR,
SUPPORT_COLOR_TEMP,
SUPPORT_TRANSITION)
from homeassistant.helpers.event import async_track_state_change
CONF_NAME = 'name'
CONF_ENTITIES = 'entities' #
_LOGGER = logging.getLogger(__name__)
SUPPORT_GROUP_LIGHT = (SUPPORT_BRIGHTNESS | SUPPORT_RGB_COLOR |
SUPPORT_COLOR_TEMP | SUPPORT_TRANSITION)
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Initialize grouped light platform."""
name = config.get(CONF_NAME)
entity_ids = config.get(CONF_ENTITIES)
if entity_ids is None:
_LOGGER.error('No entity_ids')
return False
if name is None or entity_ids is None or len(entity_ids) == 0:
_LOGGER.error('Invalid config. Excepted %s and %s', CONF_NAME, CONF_ENTITIES)
return False
lights = [GroupedLight(hass, name, entity_ids)]
async_add_devices(lights)
return True
class GroupedLight(light.Light):
"""Represents an Grouped Light in Home Assistant."""
def __init__(self, hass, name, entity_ids):
"""Initialize a Grouped Light."""
self.hass = hass
self._name = name
self._entity_ids = entity_ids
self._tracking = tuple(ent_id.lower() for ent_id in entity_ids)
#@callback
def async_state_changed_listener(entity_id, old_state, new_state):
"""Respond to a member state changing."""
self.hass.async_add_job(self.async_update_ha_state, True)
async_track_state_change(
self.hass, self._tracking, async_state_changed_listener
)
@property
def name(self):
return self._name
@property
def brightness(self):
"""Brightness of the light group"""
brightness = 0
count = 0
for state in self._light_states():
if 'brightness' in state.attributes and state.state == STATE_ON:
brightness += state.attributes.get('brightness')
count += 1
brightness = brightness / float(count or 1)
return brightness
@property
def color_temp(self):
"""Return the CT color value."""
for state in self._light_states():
if 'color_temp' in state.attributes and state.state == STATE_ON:
return state.attributes.get('color_temp')
return None
@property
def xy_color(self):
"""Return the XY color value."""
for state in self._light_states():
if 'xy_color' in state.attributes and state.state == STATE_ON:
return state.attributes.get('xy_color')
return None
@property
def rgb_color(self):
"""Return the RGB color value."""
for state in self._light_states():
if 'rgb_color' in state.attributes and state.state == STATE_ON:
return state.attributes.get('rgb_color')
return None
@property
def is_on(self):
"""If light is on."""
for state in self._light_states():
if state.state == STATE_ON:
return True
return False
@property
def supported_features(self):
"""Flag supported features."""
return SUPPORT_GROUP_LIGHT
def _light_states(self):
"""The states that the group is tracking."""
states = []
for entity_id in self._entity_ids:
state = self.hass.states.get(entity_id)
if state is not None:
states.append(state)
return states
def turn_on(self, **kwargs):
"""Forward the turn_on command to all lights in the group"""
for entity_id in self._entity_ids:
kwargs[ATTR_ENTITY_ID] = entity_id
self.hass.services.call('light', SERVICE_TURN_ON, kwargs, blocking=True)
def turn_off(self, **kwargs):
"""Forward the turn_off command to all lights in the group"""
for entity_id in self._entity_ids:
kwargs[ATTR_ENTITY_ID] = entity_id
self.hass.services.call('light', SERVICE_TURN_OFF, kwargs, blocking=True)
Wow I had no idea people were still using this
I have created a repo and will take everyone's PR requests:
https://github.com/jjensn/home-assistant-grouped-lights
Updated to add support for RGB bulbs