diff --git a/.coveragerc b/.coveragerc index 83d143f83cb..07d84523780 100644 --- a/.coveragerc +++ b/.coveragerc @@ -412,7 +412,6 @@ omit = homeassistant/components/light/decora_wifi.py homeassistant/components/light/flux_led.py homeassistant/components/light/greenwave.py - homeassistant/components/light/group.py homeassistant/components/light/hue.py homeassistant/components/light/hyperion.py homeassistant/components/light/iglo.py diff --git a/homeassistant/components/light/group.py b/homeassistant/components/light/group.py index 768754ca1af..b4a5e9dddfb 100644 --- a/homeassistant/components/light/group.py +++ b/homeassistant/components/light/group.py @@ -1,5 +1,5 @@ """ -This component allows several lights to be grouped into one light. +This platform allows several lights to be grouped into one light. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/light.group/ @@ -29,11 +29,11 @@ import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) -DEFAULT_NAME = 'Group Light' +DEFAULT_NAME = 'Light Group' PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, - vol.Required(CONF_ENTITIES): cv.entities_domain('light') + vol.Required(CONF_ENTITIES): cv.entities_domain(light.DOMAIN) }) SUPPORT_GROUP_LIGHT = (SUPPORT_BRIGHTNESS | SUPPORT_COLOR_TEMP | SUPPORT_EFFECT @@ -44,15 +44,15 @@ SUPPORT_GROUP_LIGHT = (SUPPORT_BRIGHTNESS | SUPPORT_COLOR_TEMP | SUPPORT_EFFECT async def async_setup_platform(hass: HomeAssistantType, config: ConfigType, async_add_devices, discovery_info=None) -> None: """Initialize light.group platform.""" - async_add_devices([GroupLight(config.get(CONF_NAME), - config[CONF_ENTITIES])], True) + async_add_devices([LightGroup(config.get(CONF_NAME), + config[CONF_ENTITIES])]) -class GroupLight(light.Light): - """Representation of a group light.""" +class LightGroup(light.Light): + """Representation of a light group.""" def __init__(self, name: str, entity_ids: List[str]) -> None: - """Initialize a group light.""" + """Initialize a light group.""" self._name = name # type: str self._entity_ids = entity_ids # type: List[str] self._is_on = False # type: bool @@ -79,10 +79,11 @@ class GroupLight(light.Light): self._async_unsub_state_changed = async_track_state_change( self.hass, self._entity_ids, async_state_changed_listener) + await self.async_update() async def async_will_remove_from_hass(self): """Callback when removed from HASS.""" - if self._async_unsub_state_changed: + if self._async_unsub_state_changed is not None: self._async_unsub_state_changed() self._async_unsub_state_changed = None @@ -93,17 +94,17 @@ class GroupLight(light.Light): @property def is_on(self) -> bool: - """Return the on/off state of the light.""" + """Return the on/off state of the light group.""" return self._is_on @property def available(self) -> bool: - """Return whether the light is available.""" + """Return whether the light group is available.""" return self._available @property def brightness(self) -> Optional[int]: - """Return the brightness of this light between 0..255.""" + """Return the brightness of this light group between 0..255.""" return self._brightness @property @@ -123,17 +124,17 @@ class GroupLight(light.Light): @property def min_mireds(self) -> Optional[int]: - """Return the coldest color_temp that this light supports.""" + """Return the coldest color_temp that this light group supports.""" return self._min_mireds @property def max_mireds(self) -> Optional[int]: - """Return the warmest color_temp that this light supports.""" + """Return the warmest color_temp that this light group supports.""" return self._max_mireds @property def white_value(self) -> Optional[int]: - """Return the white value of this light between 0..255.""" + """Return the white value of this light group between 0..255.""" return self._white_value @property @@ -153,11 +154,11 @@ class GroupLight(light.Light): @property def should_poll(self) -> bool: - """No polling needed for a group light.""" + """No polling needed for a light group.""" return False async def async_turn_on(self, **kwargs): - """Forward the turn_on command to all lights in the group.""" + """Forward the turn_on command to all lights in the light group.""" data = {ATTR_ENTITY_ID: self._entity_ids} if ATTR_BRIGHTNESS in kwargs: @@ -188,7 +189,7 @@ class GroupLight(light.Light): light.DOMAIN, light.SERVICE_TURN_ON, data, blocking=True) async def async_turn_off(self, **kwargs): - """Forward the turn_off command to all lights in the group.""" + """Forward the turn_off command to all lights in the light group.""" data = {ATTR_ENTITY_ID: self._entity_ids} if ATTR_TRANSITION in kwargs: @@ -198,7 +199,7 @@ class GroupLight(light.Light): light.DOMAIN, light.SERVICE_TURN_OFF, data, blocking=True) async def async_update(self): - """Query all members and determine the group state.""" + """Query all members and determine the light group state.""" all_states = [self.hass.states.get(x) for x in self._entity_ids] states = list(filter(None, all_states)) on_states = [state for state in states if state.state == STATE_ON] diff --git a/tests/components/light/test_group.py b/tests/components/light/test_group.py index ac19f407066..3c94fa2af3e 100644 --- a/tests/components/light/test_group.py +++ b/tests/components/light/test_group.py @@ -37,22 +37,22 @@ async def test_state_reporting(hass): hass.states.async_set('light.test1', 'on') hass.states.async_set('light.test2', 'unavailable') await hass.async_block_till_done() - assert hass.states.get('light.group_light').state == 'on' + assert hass.states.get('light.light_group').state == 'on' hass.states.async_set('light.test1', 'on') hass.states.async_set('light.test2', 'off') await hass.async_block_till_done() - assert hass.states.get('light.group_light').state == 'on' + assert hass.states.get('light.light_group').state == 'on' hass.states.async_set('light.test1', 'off') hass.states.async_set('light.test2', 'off') await hass.async_block_till_done() - assert hass.states.get('light.group_light').state == 'off' + assert hass.states.get('light.light_group').state == 'off' hass.states.async_set('light.test1', 'unavailable') hass.states.async_set('light.test2', 'unavailable') await hass.async_block_till_done() - assert hass.states.get('light.group_light').state == 'unavailable' + assert hass.states.get('light.light_group').state == 'unavailable' async def test_brightness(hass): @@ -64,7 +64,7 @@ async def test_brightness(hass): hass.states.async_set('light.test1', 'on', {'brightness': 255, 'supported_features': 1}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.state == 'on' assert state.attributes['supported_features'] == 1 assert state.attributes['brightness'] == 255 @@ -72,14 +72,14 @@ async def test_brightness(hass): hass.states.async_set('light.test2', 'on', {'brightness': 100, 'supported_features': 1}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.state == 'on' assert state.attributes['brightness'] == 177 hass.states.async_set('light.test1', 'off', {'brightness': 255, 'supported_features': 1}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.state == 'on' assert state.attributes['supported_features'] == 1 assert state.attributes['brightness'] == 100 @@ -94,7 +94,7 @@ async def test_xy_color(hass): hass.states.async_set('light.test1', 'on', {'xy_color': (1.0, 1.0), 'supported_features': 64}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.state == 'on' assert state.attributes['supported_features'] == 64 assert state.attributes['xy_color'] == (1.0, 1.0) @@ -102,14 +102,14 @@ async def test_xy_color(hass): hass.states.async_set('light.test2', 'on', {'xy_color': (0.5, 0.5), 'supported_features': 64}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.state == 'on' assert state.attributes['xy_color'] == (0.75, 0.75) hass.states.async_set('light.test1', 'off', {'xy_color': (1.0, 1.0), 'supported_features': 64}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.state == 'on' assert state.attributes['xy_color'] == (0.5, 0.5) @@ -123,7 +123,7 @@ async def test_rgb_color(hass): hass.states.async_set('light.test1', 'on', {'rgb_color': (255, 0, 0), 'supported_features': 16}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.state == 'on' assert state.attributes['supported_features'] == 16 assert state.attributes['rgb_color'] == (255, 0, 0) @@ -132,13 +132,13 @@ async def test_rgb_color(hass): {'rgb_color': (255, 255, 255), 'supported_features': 16}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.attributes['rgb_color'] == (255, 127, 127) hass.states.async_set('light.test1', 'off', {'rgb_color': (255, 0, 0), 'supported_features': 16}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.attributes['rgb_color'] == (255, 255, 255) @@ -151,19 +151,19 @@ async def test_white_value(hass): hass.states.async_set('light.test1', 'on', {'white_value': 255, 'supported_features': 128}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.attributes['white_value'] == 255 hass.states.async_set('light.test2', 'on', {'white_value': 100, 'supported_features': 128}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.attributes['white_value'] == 177 hass.states.async_set('light.test1', 'off', {'white_value': 255, 'supported_features': 128}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.attributes['white_value'] == 100 @@ -176,19 +176,19 @@ async def test_color_temp(hass): hass.states.async_set('light.test1', 'on', {'color_temp': 2, 'supported_features': 2}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.attributes['color_temp'] == 2 hass.states.async_set('light.test2', 'on', {'color_temp': 1000, 'supported_features': 2}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.attributes['color_temp'] == 501 hass.states.async_set('light.test1', 'off', {'color_temp': 2, 'supported_features': 2}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.attributes['color_temp'] == 1000 @@ -202,7 +202,7 @@ async def test_min_max_mireds(hass): {'min_mireds': 2, 'max_mireds': 5, 'supported_features': 2}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.attributes['min_mireds'] == 2 assert state.attributes['max_mireds'] == 5 @@ -210,7 +210,7 @@ async def test_min_max_mireds(hass): {'min_mireds': 7, 'max_mireds': 1234567890, 'supported_features': 2}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.attributes['min_mireds'] == 2 assert state.attributes['max_mireds'] == 1234567890 @@ -218,7 +218,7 @@ async def test_min_max_mireds(hass): {'min_mireds': 1, 'max_mireds': 2, 'supported_features': 2}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.attributes['min_mireds'] == 1 assert state.attributes['max_mireds'] == 1234567890 @@ -232,21 +232,21 @@ async def test_effect_list(hass): hass.states.async_set('light.test1', 'on', {'effect_list': ['None', 'Random', 'Colorloop']}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert set(state.attributes['effect_list']) == { 'None', 'Random', 'Colorloop'} hass.states.async_set('light.test2', 'on', {'effect_list': ['None', 'Random', 'Rainbow']}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert set(state.attributes['effect_list']) == { 'None', 'Random', 'Colorloop', 'Rainbow'} hass.states.async_set('light.test1', 'off', {'effect_list': ['None', 'Colorloop', 'Seven']}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert set(state.attributes['effect_list']) == { 'None', 'Random', 'Colorloop', 'Seven', 'Rainbow'} @@ -261,19 +261,19 @@ async def test_effect(hass): hass.states.async_set('light.test1', 'on', {'effect': 'None', 'supported_features': 2}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.attributes['effect'] == 'None' hass.states.async_set('light.test2', 'on', {'effect': 'None', 'supported_features': 2}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.attributes['effect'] == 'None' hass.states.async_set('light.test3', 'on', {'effect': 'Random', 'supported_features': 2}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.attributes['effect'] == 'None' hass.states.async_set('light.test1', 'off', @@ -281,7 +281,7 @@ async def test_effect(hass): hass.states.async_set('light.test2', 'off', {'effect': 'None', 'supported_features': 2}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.attributes['effect'] == 'Random' @@ -294,25 +294,25 @@ async def test_supported_features(hass): hass.states.async_set('light.test1', 'on', {'supported_features': 0}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.attributes['supported_features'] == 0 hass.states.async_set('light.test2', 'on', {'supported_features': 2}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.attributes['supported_features'] == 2 hass.states.async_set('light.test1', 'off', {'supported_features': 41}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.attributes['supported_features'] == 43 hass.states.async_set('light.test2', 'off', {'supported_features': 256}) await hass.async_block_till_done() - state = hass.states.get('light.group_light') + state = hass.states.get('light.light_group') assert state.attributes['supported_features'] == 41 @@ -326,29 +326,29 @@ async def test_service_calls(hass): ]}) await hass.async_block_till_done() - assert hass.states.get('light.group_light').state == 'on' - light.async_toggle(hass, 'light.group_light') + assert hass.states.get('light.light_group').state == 'on' + light.async_toggle(hass, 'light.light_group') await hass.async_block_till_done() assert hass.states.get('light.bed_light').state == 'off' assert hass.states.get('light.ceiling_lights').state == 'off' assert hass.states.get('light.kitchen_lights').state == 'off' - light.async_turn_on(hass, 'light.group_light') + light.async_turn_on(hass, 'light.light_group') await hass.async_block_till_done() assert hass.states.get('light.bed_light').state == 'on' assert hass.states.get('light.ceiling_lights').state == 'on' assert hass.states.get('light.kitchen_lights').state == 'on' - light.async_turn_off(hass, 'light.group_light') + light.async_turn_off(hass, 'light.light_group') await hass.async_block_till_done() assert hass.states.get('light.bed_light').state == 'off' assert hass.states.get('light.ceiling_lights').state == 'off' assert hass.states.get('light.kitchen_lights').state == 'off' - light.async_turn_on(hass, 'light.group_light', brightness=128, + light.async_turn_on(hass, 'light.light_group', brightness=128, effect='Random', rgb_color=(42, 255, 255)) await hass.async_block_till_done()