Add unique IDs to automation/scenes (#31150)
* Add unique IDs to automation and scenes * Fix typo
This commit is contained in:
parent
8fff6462a1
commit
1f0f62de7f
14 changed files with 123 additions and 27 deletions
|
@ -189,6 +189,11 @@ class AutomationEntity(ToggleEntity, RestoreEntity):
|
|||
"""Name of the automation."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return unique ID."""
|
||||
return self._id
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""No polling needed for automation entities."""
|
||||
|
|
|
@ -28,6 +28,8 @@ SECTIONS = (
|
|||
"scene",
|
||||
)
|
||||
ON_DEMAND = ("zwave",)
|
||||
ACTION_CREATE_UPDATE = "create_update"
|
||||
ACTION_DELETE = "delete"
|
||||
|
||||
|
||||
async def async_setup(hass, config):
|
||||
|
@ -152,7 +154,9 @@ class BaseEditConfigView(HomeAssistantView):
|
|||
await hass.async_add_executor_job(_write, path, current)
|
||||
|
||||
if self.post_write_hook is not None:
|
||||
hass.async_create_task(self.post_write_hook(hass))
|
||||
hass.async_create_task(
|
||||
self.post_write_hook(ACTION_CREATE_UPDATE, config_key)
|
||||
)
|
||||
|
||||
return self.json({"result": "ok"})
|
||||
|
||||
|
@ -170,7 +174,7 @@ class BaseEditConfigView(HomeAssistantView):
|
|||
await hass.async_add_executor_job(_write, path, current)
|
||||
|
||||
if self.post_write_hook is not None:
|
||||
hass.async_create_task(self.post_write_hook(hass))
|
||||
hass.async_create_task(self.post_write_hook(ACTION_DELETE, config_key))
|
||||
|
||||
return self.json({"result": "ok"})
|
||||
|
||||
|
|
|
@ -6,18 +6,30 @@ from homeassistant.components.automation import DOMAIN, PLATFORM_SCHEMA
|
|||
from homeassistant.components.automation.config import async_validate_config_item
|
||||
from homeassistant.config import AUTOMATION_CONFIG_PATH
|
||||
from homeassistant.const import CONF_ID, SERVICE_RELOAD
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers import config_validation as cv, entity_registry
|
||||
|
||||
from . import EditIdBasedConfigView
|
||||
from . import ACTION_DELETE, EditIdBasedConfigView
|
||||
|
||||
|
||||
async def async_setup(hass):
|
||||
"""Set up the Automation config API."""
|
||||
|
||||
async def hook(hass):
|
||||
async def hook(action, config_key):
|
||||
"""post_write_hook for Config View that reloads automations."""
|
||||
await hass.services.async_call(DOMAIN, SERVICE_RELOAD)
|
||||
|
||||
if action != ACTION_DELETE:
|
||||
return
|
||||
|
||||
ent_reg = await entity_registry.async_get_registry(hass)
|
||||
|
||||
entity_id = ent_reg.async_get_entity_id(DOMAIN, DOMAIN, config_key)
|
||||
|
||||
if entity_id is None:
|
||||
return
|
||||
|
||||
ent_reg.async_remove(entity_id)
|
||||
|
||||
hass.http.register_view(
|
||||
EditAutomationConfigView(
|
||||
DOMAIN,
|
||||
|
|
|
@ -12,7 +12,7 @@ CONFIG_PATH = "customize.yaml"
|
|||
async def async_setup(hass):
|
||||
"""Set up the Customize config API."""
|
||||
|
||||
async def hook(hass):
|
||||
async def hook(action, config_key):
|
||||
"""post_write_hook for Config View that reloads groups."""
|
||||
await hass.services.async_call(DOMAIN, SERVICE_RELOAD_CORE_CONFIG)
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ from . import EditKeyBasedConfigView
|
|||
async def async_setup(hass):
|
||||
"""Set up the Group config API."""
|
||||
|
||||
async def hook(hass):
|
||||
async def hook(action, config_key):
|
||||
"""post_write_hook for Config View that reloads groups."""
|
||||
await hass.services.async_call(DOMAIN, SERVICE_RELOAD)
|
||||
|
||||
|
|
|
@ -5,18 +5,31 @@ import uuid
|
|||
from homeassistant.components.scene import DOMAIN, PLATFORM_SCHEMA
|
||||
from homeassistant.config import SCENE_CONFIG_PATH
|
||||
from homeassistant.const import CONF_ID, SERVICE_RELOAD
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.core import DOMAIN as HA_DOMAIN
|
||||
from homeassistant.helpers import config_validation as cv, entity_registry
|
||||
|
||||
from . import EditIdBasedConfigView
|
||||
from . import ACTION_DELETE, EditIdBasedConfigView
|
||||
|
||||
|
||||
async def async_setup(hass):
|
||||
"""Set up the Scene config API."""
|
||||
|
||||
async def hook(hass):
|
||||
async def hook(action, config_key):
|
||||
"""post_write_hook for Config View that reloads scenes."""
|
||||
await hass.services.async_call(DOMAIN, SERVICE_RELOAD)
|
||||
|
||||
if action != ACTION_DELETE:
|
||||
return
|
||||
|
||||
ent_reg = await entity_registry.async_get_registry(hass)
|
||||
|
||||
entity_id = ent_reg.async_get_entity_id(DOMAIN, HA_DOMAIN, config_key)
|
||||
|
||||
if entity_id is None:
|
||||
return
|
||||
|
||||
ent_reg.async_remove(entity_id)
|
||||
|
||||
hass.http.register_view(
|
||||
EditSceneConfigView(
|
||||
DOMAIN,
|
||||
|
|
|
@ -10,7 +10,7 @@ from . import EditKeyBasedConfigView
|
|||
async def async_setup(hass):
|
||||
"""Set up the script config API."""
|
||||
|
||||
async def hook(hass):
|
||||
async def hook(action, config_key):
|
||||
"""post_write_hook for Config View that reloads scripts."""
|
||||
await hass.services.async_call(DOMAIN, SERVICE_RELOAD)
|
||||
|
||||
|
|
|
@ -261,6 +261,11 @@ class HomeAssistantScene(Scene):
|
|||
"""Return the name of the scene."""
|
||||
return self.scene_config.name
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return unique ID."""
|
||||
return self._id
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return the scene state attributes."""
|
||||
|
|
|
@ -61,10 +61,7 @@ async def async_setup(hass, config):
|
|||
|
||||
await component.async_setup(config)
|
||||
# Ensure Home Assistant platform always loaded.
|
||||
await component.async_setup_platform(
|
||||
HA_DOMAIN, {"platform": "homeasistant", STATES: []}
|
||||
)
|
||||
|
||||
await component.async_setup_platform(HA_DOMAIN, {"platform": HA_DOMAIN, STATES: []})
|
||||
component.async_register_entity_service(SERVICE_TURN_ON, {}, "async_activate")
|
||||
|
||||
return True
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Test Automation config panel."""
|
||||
import json
|
||||
from unittest.mock import patch
|
||||
|
||||
from asynctest import patch
|
||||
|
||||
from homeassistant.bootstrap import async_setup_component
|
||||
from homeassistant.components import config
|
||||
|
@ -47,7 +48,7 @@ async def test_update_device_config(hass, hass_client):
|
|||
|
||||
with patch("homeassistant.components.config._read", mock_read), patch(
|
||||
"homeassistant.components.config._write", mock_write
|
||||
):
|
||||
), patch("homeassistant.config.async_hass_config_yaml", return_value={}):
|
||||
resp = await client.post(
|
||||
"/api/config/automation/config/moon",
|
||||
data=json.dumps({"trigger": [], "action": [], "condition": []}),
|
||||
|
@ -89,11 +90,12 @@ async def test_bad_formatted_automations(hass, hass_client):
|
|||
|
||||
with patch("homeassistant.components.config._read", mock_read), patch(
|
||||
"homeassistant.components.config._write", mock_write
|
||||
):
|
||||
), patch("homeassistant.config.async_hass_config_yaml", return_value={}):
|
||||
resp = await client.post(
|
||||
"/api/config/automation/config/moon",
|
||||
data=json.dumps({"trigger": [], "action": [], "condition": []}),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert resp.status == 200
|
||||
result = await resp.json()
|
||||
|
@ -107,8 +109,31 @@ async def test_bad_formatted_automations(hass, hass_client):
|
|||
|
||||
async def test_delete_automation(hass, hass_client):
|
||||
"""Test deleting an automation."""
|
||||
ent_reg = await hass.helpers.entity_registry.async_get_registry()
|
||||
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
"automation",
|
||||
{
|
||||
"automation": [
|
||||
{
|
||||
"id": "sun",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {"service": "test.automation"},
|
||||
},
|
||||
{
|
||||
"id": "moon",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {"service": "test.automation"},
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
assert len(ent_reg.entities) == 2
|
||||
|
||||
with patch.object(config, "SECTIONS", ["automation"]):
|
||||
await async_setup_component(hass, "config", {})
|
||||
assert await async_setup_component(hass, "config", {})
|
||||
|
||||
client = await hass_client()
|
||||
|
||||
|
@ -126,8 +151,9 @@ async def test_delete_automation(hass, hass_client):
|
|||
|
||||
with patch("homeassistant.components.config._read", mock_read), patch(
|
||||
"homeassistant.components.config._write", mock_write
|
||||
):
|
||||
), patch("homeassistant.config.async_hass_config_yaml", return_value={}):
|
||||
resp = await client.delete("/api/config/automation/config/sun")
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert resp.status == 200
|
||||
result = await resp.json()
|
||||
|
@ -135,3 +161,5 @@ async def test_delete_automation(hass, hass_client):
|
|||
|
||||
assert len(written) == 1
|
||||
assert written[0][0]["id"] == "moon"
|
||||
|
||||
assert len(ent_reg.entities) == 1
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Test Customize config panel."""
|
||||
import json
|
||||
from unittest.mock import patch
|
||||
|
||||
from asynctest import patch
|
||||
|
||||
from homeassistant.bootstrap import async_setup_component
|
||||
from homeassistant.components import config
|
||||
|
@ -53,6 +54,8 @@ async def test_update_entity(hass, hass_client):
|
|||
hass.states.async_set("hello.world", "state", {"a": "b"})
|
||||
with patch("homeassistant.components.config._read", mock_read), patch(
|
||||
"homeassistant.components.config._write", mock_write
|
||||
), patch(
|
||||
"homeassistant.config.async_hass_config_yaml", return_value={},
|
||||
):
|
||||
resp = await client.post(
|
||||
"/api/config/customize/config/hello.world",
|
||||
|
@ -60,6 +63,7 @@ async def test_update_entity(hass, hass_client):
|
|||
{"name": "Beer", "entities": ["light.top", "light.bottom"]}
|
||||
),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert resp.status == 200
|
||||
result = await resp.json()
|
||||
|
|
|
@ -61,6 +61,7 @@ async def test_update_device_config(hass, hass_client):
|
|||
{"name": "Beer", "entities": ["light.top", "light.bottom"]}
|
||||
),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert resp.status == 200
|
||||
result = await resp.json()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Test Automation config panel."""
|
||||
import json
|
||||
from unittest.mock import patch
|
||||
|
||||
from asynctest import patch
|
||||
|
||||
from homeassistant.bootstrap import async_setup_component
|
||||
from homeassistant.components import config
|
||||
|
@ -29,7 +30,7 @@ async def test_update_scene(hass, hass_client):
|
|||
|
||||
with patch("homeassistant.components.config._read", mock_read), patch(
|
||||
"homeassistant.components.config._write", mock_write
|
||||
):
|
||||
), patch("homeassistant.config.async_hass_config_yaml", return_value={}):
|
||||
resp = await client.post(
|
||||
"/api/config/scene/config/light_off",
|
||||
data=json.dumps(
|
||||
|
@ -86,7 +87,7 @@ async def test_bad_formatted_scene(hass, hass_client):
|
|||
|
||||
with patch("homeassistant.components.config._read", mock_read), patch(
|
||||
"homeassistant.components.config._write", mock_write
|
||||
):
|
||||
), patch("homeassistant.config.async_hass_config_yaml", return_value={}):
|
||||
resp = await client.post(
|
||||
"/api/config/scene/config/light_off",
|
||||
data=json.dumps(
|
||||
|
@ -114,8 +115,23 @@ async def test_bad_formatted_scene(hass, hass_client):
|
|||
|
||||
async def test_delete_scene(hass, hass_client):
|
||||
"""Test deleting a scene."""
|
||||
ent_reg = await hass.helpers.entity_registry.async_get_registry()
|
||||
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
"scene",
|
||||
{
|
||||
"scene": [
|
||||
{"id": "light_on", "name": "Light on", "entities": {}},
|
||||
{"id": "light_off", "name": "Light off", "entities": {}},
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
assert len(ent_reg.entities) == 2
|
||||
|
||||
with patch.object(config, "SECTIONS", ["scene"]):
|
||||
await async_setup_component(hass, "config", {})
|
||||
assert await async_setup_component(hass, "config", {})
|
||||
|
||||
client = await hass_client()
|
||||
|
||||
|
@ -133,8 +149,9 @@ async def test_delete_scene(hass, hass_client):
|
|||
|
||||
with patch("homeassistant.components.config._read", mock_read), patch(
|
||||
"homeassistant.components.config._write", mock_write
|
||||
):
|
||||
), patch("homeassistant.config.async_hass_config_yaml", return_value={}):
|
||||
resp = await client.delete("/api/config/scene/config/light_on")
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert resp.status == 200
|
||||
result = await resp.json()
|
||||
|
@ -142,3 +159,5 @@ async def test_delete_scene(hass, hass_client):
|
|||
|
||||
assert len(written) == 1
|
||||
assert written[0][0]["id"] == "light_off"
|
||||
|
||||
assert len(ent_reg.entities) == 1
|
||||
|
|
|
@ -3,7 +3,7 @@ import io
|
|||
import unittest
|
||||
|
||||
from homeassistant.components import light, scene
|
||||
from homeassistant.setup import setup_component
|
||||
from homeassistant.setup import async_setup_component, setup_component
|
||||
from homeassistant.util.yaml import loader as yaml_loader
|
||||
|
||||
from tests.common import get_test_home_assistant
|
||||
|
@ -128,3 +128,11 @@ class TestScene(unittest.TestCase):
|
|||
assert self.light_1.is_on
|
||||
assert self.light_2.is_on
|
||||
assert 100 == self.light_2.last_call("turn_on")[1].get("brightness")
|
||||
|
||||
|
||||
async def test_services_registered(hass):
|
||||
"""Test we register services with empty config."""
|
||||
assert await async_setup_component(hass, "scene", {})
|
||||
assert hass.services.has_service("scene", "reload")
|
||||
assert hass.services.has_service("scene", "turn_on")
|
||||
assert hass.services.has_service("scene", "apply")
|
||||
|
|
Loading…
Add table
Reference in a new issue