Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow specifying an icon for a scene #31898

Merged
merged 1 commit into from Feb 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
41 changes: 28 additions & 13 deletions homeassistant/components/homeassistant/scene.py
Expand Up @@ -11,6 +11,7 @@
ATTR_ENTITY_ID,
ATTR_STATE,
CONF_ENTITIES,
CONF_ICON,
CONF_ID,
CONF_NAME,
CONF_PLATFORM,
Expand Down Expand Up @@ -75,16 +76,21 @@ def _ensure_no_intersection(value):
DATA_PLATFORM = f"homeassistant_scene"
STATES_SCHEMA = vol.All(dict, _convert_states)


PLATFORM_SCHEMA = vol.Schema(
{
vol.Required(CONF_PLATFORM): HA_DOMAIN,
vol.Required(STATES): vol.All(
cv.ensure_list,
[
{
vol.Required(CONF_NAME): cv.string,
vol.Required(CONF_ENTITIES): STATES_SCHEMA,
}
vol.Schema(
{
vol.Optional(CONF_ID): cv.string,
vol.Required(CONF_NAME): cv.string,
vol.Optional(CONF_ICON): cv.icon,
vol.Required(CONF_ENTITIES): STATES_SCHEMA,
}
)
],
),
},
Expand All @@ -105,7 +111,7 @@ def _ensure_no_intersection(value):

SERVICE_APPLY = "apply"
SERVICE_CREATE = "create"
SCENECONFIG = namedtuple("SceneConfig", [CONF_NAME, STATES])
SCENECONFIG = namedtuple("SceneConfig", [CONF_ID, CONF_NAME, CONF_ICON, STATES])
_LOGGER = logging.getLogger(__name__)


Expand Down Expand Up @@ -213,7 +219,7 @@ async def create_service(call):
_LOGGER.warning("Empty scenes are not allowed")
return

scene_config = SCENECONFIG(call.data[CONF_SCENE_ID], entities)
scene_config = SCENECONFIG(None, call.data[CONF_SCENE_ID], None, entities)
entity_id = f"{SCENE_DOMAIN}.{scene_config.name}"
old = platform.entities.get(entity_id)
if old is not None:
Expand All @@ -239,8 +245,12 @@ def _process_scenes_config(hass, async_add_entities, config):
async_add_entities(
HomeAssistantScene(
hass,
SCENECONFIG(scene[CONF_NAME], scene[CONF_ENTITIES]),
scene.get(CONF_ID),
SCENECONFIG(
scene.get(CONF_ID),
scene[CONF_NAME],
scene.get(CONF_ICON),
scene[CONF_ENTITIES],
),
)
for scene in scene_config
)
Expand All @@ -249,9 +259,8 @@ def _process_scenes_config(hass, async_add_entities, config):
class HomeAssistantScene(Scene):
"""A scene is a group of entities and the states we want them to be."""

def __init__(self, hass, scene_config, scene_id=None, from_service=False):
def __init__(self, hass, scene_config, from_service=False):
"""Initialize the scene."""
self._id = scene_id
self.hass = hass
self.scene_config = scene_config
self.from_service = from_service
Expand All @@ -261,17 +270,23 @@ def name(self):
"""Return the name of the scene."""
return self.scene_config.name

@property
def icon(self):
"""Return the icon of the scene."""
return self.scene_config.icon

@property
def unique_id(self):
"""Return unique ID."""
return self._id
return self.scene_config.id

@property
def device_state_attributes(self):
"""Return the scene state attributes."""
attributes = {ATTR_ENTITY_ID: list(self.scene_config.states)}
if self._id is not None:
attributes[CONF_ID] = self._id
unique_id = self.unique_id
if unique_id is not None:
attributes[CONF_ID] = unique_id
return attributes

async def async_activate(self):
Expand Down
30 changes: 30 additions & 0 deletions tests/components/homeassistant/test_scene.py
Expand Up @@ -258,3 +258,33 @@ async def test_entities_in_scene(hass):
("scene.scene_3", ["light.kitchen", "light.living_room"]),
):
assert ha_scene.entities_in_scene(hass, scene_id) == entities


async def test_config(hass):
"""Test passing config in YAML."""
assert await async_setup_component(
hass,
"scene",
{
"scene": [
{
"id": "scene_id",
"name": "Scene Icon",
"icon": "mdi:party",
"entities": {"light.kitchen": "on"},
},
{
"name": "Scene No Icon",
"entities": {"light.kitchen": {"state": "on"}},
},
]
},
)

icon = hass.states.get("scene.scene_icon")
assert icon is not None
assert icon.attributes["icon"] == "mdi:party"

no_icon = hass.states.get("scene.scene_no_icon")
assert no_icon is not None
assert "icon" not in no_icon.attributes