Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions homeassistant/components/template/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from collections.abc import Callable
from contextlib import suppress
import itertools
import logging
from typing import Any

Expand Down Expand Up @@ -346,12 +347,21 @@ async def async_validate_config_section(

async def async_validate_config(hass: HomeAssistant, config: ConfigType) -> ConfigType:
"""Validate config."""
if DOMAIN not in config:

configs = []
for key in config:
if DOMAIN not in key:
continue

if key == DOMAIN or (key.startswith(DOMAIN) and len(key.split()) > 1):
configs.append(cv.ensure_list(config[key]))

if not configs:
return config

config_sections = []

for cfg in cv.ensure_list(config[DOMAIN]):
for cfg in itertools.chain(*configs):
try:
template_config: TemplateConfig = await async_validate_config_section(
hass, cfg
Expand Down
69 changes: 69 additions & 0 deletions tests/components/template/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,3 +475,72 @@ async def test_invalid_schema_raises_issue(

assert issue.domain == "template"
assert issue.severity == ir.IssueSeverity.WARNING


async def test_multiple_configuration_keys(
hass: HomeAssistant,
) -> None:
"""Test multiple configurations keys create entities."""
await async_setup_component(
hass,
"template",
{
"template": [{"binary_sensor": [{"name": "Foo", "state": "{{ True }}"}]}],
"template mytemplates": [
{
"sensor": [
{"name": "Foo", "state": "{{ 'bar' }}"},
{"name": "Bar", "state": "{{ 'foo' }}"},
]
}
],
"template y": [
{
"cover": [
{
"name": "Shades Curtain",
"unique_id": "shades_curtain",
"open_cover": [],
"close_cover": [],
"stop_cover": [],
}
]
},
{
"cover": [
{
"open_cover": {
"target": {"entity_id": ["cover.shades_curtain"]},
"action": "cover.close_cover",
},
"close_cover": {
"target": {"entity_id": ["cover.shades_curtain"]},
"action": "cover.open_cover",
},
"stop_cover": {
"target": {"entity_id": ["cover.shades_curtain"]},
"action": "cover.stop_cover",
},
"default_entity_id": "cover.shades_reversed",
"icon": "{% set s = states('cover.shades_curtain') %}\n{% if s == 'open' %}\n mdi:curtains-closed\n{% else %}\n mdi:curtains\n{% endif %}",
"name": "Shades Reversed",
"unique_id": "c0223bcb-32c6-430e-a2c1-3545f8031796",
"state": "{% set s = states('cover.shades_curtain') %}\n{% if s == 'open' %}\n closed\n{% elif s == 'closed' %}\n open\n{% elif s == 'opening' %}\n closing\n{% elif s == 'closing' %}\n opening\n{% else %}\n unknown\n{% endif %}",
}
]
},
],
},
)
await hass.async_block_till_done()

for entity_id, expected in (
("binary_sensor.foo", "on"),
("sensor.foo", "bar"),
("sensor.bar", "foo"),
("cover.shades_curtain", "unknown"),
("cover.shades_reversed", "unknown"),
):
state = hass.states.get(entity_id)
assert state
assert state.state == expected
Loading