Remove states UI options in group integration (#32021)

This commit is contained in:
Franck Nijhof 2020-02-20 17:26:41 +01:00 committed by GitHub
parent 7e3841e172
commit 2ad1f7fd02
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 14 additions and 223 deletions

View file

@ -30,7 +30,6 @@ from homeassistant.const import (
)
from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.config_validation import make_entity_service_schema
from homeassistant.helpers.entity import Entity, async_generate_entity_id
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.event import async_track_state_change
@ -44,26 +43,18 @@ DOMAIN = "group"
ENTITY_ID_FORMAT = DOMAIN + ".{}"
CONF_ENTITIES = "entities"
CONF_VIEW = "view"
CONF_CONTROL = "control"
CONF_ALL = "all"
ATTR_ADD_ENTITIES = "add_entities"
ATTR_AUTO = "auto"
ATTR_CONTROL = "control"
ATTR_ENTITIES = "entities"
ATTR_OBJECT_ID = "object_id"
ATTR_ORDER = "order"
ATTR_VIEW = "view"
ATTR_VISIBLE = "visible"
ATTR_ALL = "all"
SERVICE_SET_VISIBILITY = "set_visibility"
SERVICE_SET = "set"
SERVICE_REMOVE = "remove"
CONTROL_TYPES = vol.In(["hidden", None])
_LOGGER = logging.getLogger(__name__)
@ -76,15 +67,11 @@ def _conf_preprocess(value):
GROUP_SCHEMA = vol.All(
cv.deprecated(CONF_CONTROL, invalidation_version="0.107.0"),
cv.deprecated(CONF_VIEW, invalidation_version="0.107.0"),
vol.Schema(
{
vol.Optional(CONF_ENTITIES): vol.Any(cv.entity_ids, None),
CONF_VIEW: cv.boolean,
CONF_NAME: cv.string,
CONF_ICON: cv.icon,
CONF_CONTROL: CONTROL_TYPES,
CONF_ALL: cv.boolean,
}
),
@ -257,7 +244,7 @@ async def async_setup(hass, config):
extra_arg = {
attr: service.data[attr]
for attr in (ATTR_VISIBLE, ATTR_ICON, ATTR_VIEW, ATTR_CONTROL)
for attr in (ATTR_ICON)
if service.data.get(attr) is not None
}
@ -293,22 +280,10 @@ async def async_setup(hass, config):
group.name = service.data[ATTR_NAME]
need_update = True
if ATTR_VISIBLE in service.data:
group.visible = service.data[ATTR_VISIBLE]
need_update = True
if ATTR_ICON in service.data:
group.icon = service.data[ATTR_ICON]
need_update = True
if ATTR_CONTROL in service.data:
group.control = service.data[ATTR_CONTROL]
need_update = True
if ATTR_VIEW in service.data:
group.view = service.data[ATTR_VIEW]
need_update = True
if ATTR_ALL in service.data:
group.mode = all if service.data[ATTR_ALL] else any
need_update = True
@ -327,17 +302,11 @@ async def async_setup(hass, config):
SERVICE_SET,
locked_service_handler,
schema=vol.All(
cv.deprecated(ATTR_CONTROL, invalidation_version="0.107.0"),
cv.deprecated(ATTR_VIEW, invalidation_version="0.107.0"),
cv.deprecated(ATTR_VISIBLE, invalidation_version="0.107.0"),
vol.Schema(
{
vol.Required(ATTR_OBJECT_ID): cv.slug,
vol.Optional(ATTR_NAME): cv.string,
vol.Optional(ATTR_VIEW): cv.boolean,
vol.Optional(ATTR_ICON): cv.string,
vol.Optional(ATTR_CONTROL): CONTROL_TYPES,
vol.Optional(ATTR_VISIBLE): cv.boolean,
vol.Optional(ATTR_ALL): cv.boolean,
vol.Exclusive(ATTR_ENTITIES, "entities"): cv.entity_ids,
vol.Exclusive(ATTR_ADD_ENTITIES, "entities"): cv.entity_ids,
@ -353,32 +322,6 @@ async def async_setup(hass, config):
schema=vol.Schema({vol.Required(ATTR_OBJECT_ID): cv.slug}),
)
async def visibility_service_handler(service):
"""Change visibility of a group."""
visible = service.data.get(ATTR_VISIBLE)
_LOGGER.warning(
"The group.set_visibility service has been deprecated and will"
"be removed in Home Assistant 0.107.0."
)
tasks = []
for group in await component.async_extract_from_service(
service, expand_group=False
):
group.visible = visible
tasks.append(group.async_update_ha_state())
if tasks:
await asyncio.wait(tasks)
hass.services.async_register(
DOMAIN,
SERVICE_SET_VISIBILITY,
visibility_service_handler,
schema=make_entity_service_schema({vol.Required(ATTR_VISIBLE): cv.boolean}),
)
return True
@ -388,21 +331,12 @@ async def _async_process_config(hass, config, component):
name = conf.get(CONF_NAME, object_id)
entity_ids = conf.get(CONF_ENTITIES) or []
icon = conf.get(CONF_ICON)
view = conf.get(CONF_VIEW)
control = conf.get(CONF_CONTROL)
mode = conf.get(CONF_ALL)
# Don't create tasks and await them all. The order is important as
# groups get a number based on creation order.
await Group.async_create_group(
hass,
name,
entity_ids,
icon=icon,
view=view,
control=control,
object_id=object_id,
mode=mode,
hass, name, entity_ids, icon=icon, object_id=object_id, mode=mode,
)
@ -414,10 +348,7 @@ class Group(Entity):
hass,
name,
order=None,
visible=True,
icon=None,
view=False,
control=None,
user_defined=True,
entity_ids=None,
mode=None,
@ -430,15 +361,12 @@ class Group(Entity):
self._name = name
self._state = STATE_UNKNOWN
self._icon = icon
self.view = view
if entity_ids:
self.tracking = tuple(ent_id.lower() for ent_id in entity_ids)
else:
self.tracking = tuple()
self.group_on = None
self.group_off = None
self.visible = visible
self.control = control
self.user_defined = user_defined
self.mode = any
if mode:
@ -453,26 +381,14 @@ class Group(Entity):
name,
entity_ids=None,
user_defined=True,
visible=True,
icon=None,
view=False,
control=None,
object_id=None,
mode=None,
):
"""Initialize a group."""
return asyncio.run_coroutine_threadsafe(
Group.async_create_group(
hass,
name,
entity_ids,
user_defined,
visible,
icon,
view,
control,
object_id,
mode,
hass, name, entity_ids, user_defined, icon, object_id, mode,
),
hass.loop,
).result()
@ -483,10 +399,7 @@ class Group(Entity):
name,
entity_ids=None,
user_defined=True,
visible=True,
icon=None,
view=False,
control=None,
object_id=None,
mode=None,
):
@ -498,10 +411,7 @@ class Group(Entity):
hass,
name,
order=len(hass.states.async_entity_ids(DOMAIN)),
visible=visible,
icon=icon,
view=view,
control=control,
user_defined=user_defined,
entity_ids=entity_ids,
mode=mode,
@ -551,23 +461,12 @@ class Group(Entity):
"""Set Icon for group."""
self._icon = value
@property
def hidden(self):
"""If group should be hidden or not."""
if self.visible and not self.view:
return False
return True
@property
def state_attributes(self):
"""Return the state attributes for the group."""
data = {ATTR_ENTITY_ID: self.tracking, ATTR_ORDER: self._order}
if not self.user_defined:
data[ATTR_AUTO] = True
if self.view:
data[ATTR_VIEW] = True
if self.control:
data[ATTR_CONTROL] = self.control
return data
@property

View file

@ -3,37 +3,18 @@
reload:
description: Reload group configuration.
set_visibility:
description: Hide or show a group.
fields:
entity_id:
description: Name(s) of entities to set value.
example: 'group.travel'
visible:
description: True if group should be shown or False if it should be hidden.
example: True
set:
description: Create/Update a user group.
fields:
object_id:
description: Group id and part of entity id.
example: 'test_group'
example: "test_group"
name:
description: Name of group
example: 'My test group'
view:
description: Boolean for if the group is a view.
example: True
example: "My test group"
icon:
description: Name of icon for the group.
example: 'mdi:camera'
control:
description: Value for control the group control.
example: 'hidden'
visible:
description: If the group is visible on UI.
example: True
example: "mdi:camera"
entities:
description: List of all members in the group. Not compatible with 'delta'.
example: domain.entity_id1, domain.entity_id2
@ -49,5 +30,4 @@ remove:
fields:
object_id:
description: Group id and part of entity id.
example: 'test_group'
example: "test_group"

View file

@ -5,17 +5,13 @@ components. Instead call the service directly.
"""
from homeassistant.components.group import (
ATTR_ADD_ENTITIES,
ATTR_CONTROL,
ATTR_ENTITIES,
ATTR_OBJECT_ID,
ATTR_VIEW,
ATTR_VISIBLE,
DOMAIN,
SERVICE_REMOVE,
SERVICE_SET,
SERVICE_SET_VISIBILITY,
)
from homeassistant.const import ATTR_ENTITY_ID, ATTR_ICON, ATTR_NAME, SERVICE_RELOAD
from homeassistant.const import ATTR_ICON, ATTR_NAME, SERVICE_RELOAD
from homeassistant.core import callback
from homeassistant.loader import bind_hass
@ -35,43 +31,18 @@ def async_reload(hass):
@bind_hass
def set_group(
hass,
object_id,
name=None,
entity_ids=None,
visible=None,
icon=None,
view=None,
control=None,
add=None,
hass, object_id, name=None, entity_ids=None, icon=None, add=None,
):
"""Create/Update a group."""
hass.add_job(
async_set_group,
hass,
object_id,
name,
entity_ids,
visible,
icon,
view,
control,
add,
async_set_group, hass, object_id, name, entity_ids, icon, add,
)
@callback
@bind_hass
def async_set_group(
hass,
object_id,
name=None,
entity_ids=None,
visible=None,
icon=None,
view=None,
control=None,
add=None,
hass, object_id, name=None, entity_ids=None, icon=None, add=None,
):
"""Create/Update a group."""
data = {
@ -80,10 +51,7 @@ def async_set_group(
(ATTR_OBJECT_ID, object_id),
(ATTR_NAME, name),
(ATTR_ENTITIES, entity_ids),
(ATTR_VISIBLE, visible),
(ATTR_ICON, icon),
(ATTR_VIEW, view),
(ATTR_CONTROL, control),
(ATTR_ADD_ENTITIES, add),
]
if value is not None
@ -98,10 +66,3 @@ def async_remove(hass, object_id):
"""Remove a user group."""
data = {ATTR_OBJECT_ID: object_id}
hass.async_add_job(hass.services.async_call(DOMAIN, SERVICE_REMOVE, data))
@bind_hass
def set_visibility(hass, entity_id=None, visible=True):
"""Hide or shows a group."""
data = {ATTR_ENTITY_ID: entity_id, ATTR_VISIBLE: visible}
hass.services.call(DOMAIN, SERVICE_SET_VISIBILITY, data)

View file

@ -8,7 +8,6 @@ import homeassistant.components.group as group
from homeassistant.const import (
ATTR_ASSUMED_STATE,
ATTR_FRIENDLY_NAME,
ATTR_HIDDEN,
ATTR_ICON,
STATE_HOME,
STATE_NOT_HOME,
@ -291,8 +290,6 @@ class TestComponentsGroup(unittest.TestCase):
group_conf["second_group"] = {
"entities": "light.Bowl, " + test_group.entity_id,
"icon": "mdi:work",
"view": True,
"control": "hidden",
}
group_conf["test_group"] = "hello.world,sensor.happy"
group_conf["empty_group"] = {"name": "Empty Group", "entities": None}
@ -308,9 +305,6 @@ class TestComponentsGroup(unittest.TestCase):
)
assert group_state.attributes.get(group.ATTR_AUTO) is None
assert "mdi:work" == group_state.attributes.get(ATTR_ICON)
assert group_state.attributes.get(group.ATTR_VIEW)
assert "hidden" == group_state.attributes.get(group.ATTR_CONTROL)
assert group_state.attributes.get(ATTR_HIDDEN)
assert 1 == group_state.attributes.get(group.ATTR_ORDER)
group_state = self.hass.states.get(group.ENTITY_ID_FORMAT.format("test_group"))
@ -320,9 +314,6 @@ class TestComponentsGroup(unittest.TestCase):
)
assert group_state.attributes.get(group.ATTR_AUTO) is None
assert group_state.attributes.get(ATTR_ICON) is None
assert group_state.attributes.get(group.ATTR_VIEW) is None
assert group_state.attributes.get(group.ATTR_CONTROL) is None
assert group_state.attributes.get(ATTR_HIDDEN) is None
assert 2 == group_state.attributes.get(group.ATTR_ORDER)
def test_groups_get_unique_names(self):
@ -394,11 +385,7 @@ class TestComponentsGroup(unittest.TestCase):
"group",
{
"group": {
"second_group": {
"entities": "light.Bowl",
"icon": "mdi:work",
"view": True,
},
"second_group": {"entities": "light.Bowl", "icon": "mdi:work"},
"test_group": "hello.world,sensor.happy",
"empty_group": {"name": "Empty Group", "entities": None},
}
@ -420,13 +407,7 @@ class TestComponentsGroup(unittest.TestCase):
with patch(
"homeassistant.config.load_yaml_config_file",
return_value={
"group": {
"hello": {
"entities": "light.Bowl",
"icon": "mdi:work",
"view": True,
}
}
"group": {"hello": {"entities": "light.Bowl", "icon": "mdi:work"}}
},
):
common.reload(self.hass)
@ -438,26 +419,6 @@ class TestComponentsGroup(unittest.TestCase):
]
assert self.hass.bus.listeners["state_changed"] == 2
def test_changing_group_visibility(self):
"""Test that a group can be hidden and shown."""
assert setup_component(
self.hass, "group", {"group": {"test_group": "hello.world,sensor.happy"}}
)
group_entity_id = group.ENTITY_ID_FORMAT.format("test_group")
# Hide the group
common.set_visibility(self.hass, group_entity_id, False)
self.hass.block_till_done()
group_state = self.hass.states.get(group_entity_id)
assert group_state.attributes.get(ATTR_HIDDEN)
# Show it again
common.set_visibility(self.hass, group_entity_id, True)
self.hass.block_till_done()
group_state = self.hass.states.get(group_entity_id)
assert group_state.attributes.get(ATTR_HIDDEN) is None
def test_modify_group(self):
"""Test modifying a group."""
group_conf = OrderedDict()
@ -503,19 +464,13 @@ async def test_service_group_set_group_remove_group(hass):
assert group_state.attributes["friendly_name"] == "Test"
common.async_set_group(
hass,
"user_test_group",
view=True,
visible=False,
entity_ids=["test.entity_bla1"],
hass, "user_test_group", entity_ids=["test.entity_bla1"],
)
await hass.async_block_till_done()
group_state = hass.states.get("group.user_test_group")
assert group_state
assert group_state.attributes[group.ATTR_VIEW]
assert group_state.attributes[group.ATTR_AUTO]
assert group_state.attributes["hidden"]
assert group_state.attributes["friendly_name"] == "Test"
assert list(group_state.attributes["entity_id"]) == ["test.entity_bla1"]
@ -524,19 +479,15 @@ async def test_service_group_set_group_remove_group(hass):
"user_test_group",
icon="mdi:camera",
name="Test2",
control="hidden",
add=["test.entity_id2"],
)
await hass.async_block_till_done()
group_state = hass.states.get("group.user_test_group")
assert group_state
assert group_state.attributes[group.ATTR_VIEW]
assert group_state.attributes[group.ATTR_AUTO]
assert group_state.attributes["hidden"]
assert group_state.attributes["friendly_name"] == "Test2"
assert group_state.attributes["icon"] == "mdi:camera"
assert group_state.attributes[group.ATTR_CONTROL] == "hidden"
assert sorted(list(group_state.attributes["entity_id"])) == sorted(
["test.entity_bla1", "test.entity_id2"]
)