1
mirror of https://github.com/home-assistant/core synced 2024-09-28 03:04:04 +02:00

Fix reload service in Command Line (#94436)

* Fix reload in Command Line

* Add read new yaml
This commit is contained in:
G Johansson 2023-06-12 21:51:57 +02:00 committed by GitHub
parent f931cc3d1c
commit bd74f03d0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 101 additions and 58 deletions

View File

@ -46,12 +46,15 @@ from homeassistant.const import (
CONF_UNIQUE_ID,
CONF_UNIT_OF_MEASUREMENT,
CONF_VALUE_TEMPLATE,
SERVICE_RELOAD,
Platform,
)
from homeassistant.core import HomeAssistant
from homeassistant.core import Event, HomeAssistant, ServiceCall
from homeassistant.helpers import discovery
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.reload import async_setup_reload_service
from homeassistant.helpers.entity_platform import async_get_platforms
from homeassistant.helpers.reload import async_integration_yaml_config
from homeassistant.helpers.service import async_register_admin_service
from homeassistant.helpers.typing import ConfigType
from .const import CONF_COMMAND_TIMEOUT, DEFAULT_TIMEOUT, DOMAIN
@ -163,14 +166,39 @@ CONFIG_SCHEMA = vol.Schema(
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up Command Line from yaml config."""
command_line_config: list[dict[str, dict[str, Any]]] = config.get(DOMAIN, [])
async def _reload_config(call: Event | ServiceCall) -> None:
"""Reload Command Line."""
reload_config = await async_integration_yaml_config(hass, "command_line")
reset_platforms = async_get_platforms(hass, "command_line")
for reset_platform in reset_platforms:
_LOGGER.debug("Reload resetting platform: %s", reset_platform.domain)
await reset_platform.async_reset()
if not reload_config:
return
await async_load_platforms(hass, reload_config.get(DOMAIN, []), reload_config)
async_register_admin_service(hass, DOMAIN, SERVICE_RELOAD, _reload_config)
await async_load_platforms(hass, config.get(DOMAIN, []), config)
return True
async def async_load_platforms(
hass: HomeAssistant,
command_line_config: list[dict[str, dict[str, Any]]],
config: ConfigType,
) -> None:
"""Load platforms from yaml."""
if not command_line_config:
return True
return
_LOGGER.debug("Full config loaded: %s", command_line_config)
load_coroutines: list[Coroutine[Any, Any, None]] = []
platforms: list[Platform] = []
reload_configs: list[tuple] = []
for platform_config in command_line_config:
for platform, _config in platform_config.items():
if (mapped_platform := PLATFORM_MAPPING[platform]) not in platforms:
@ -180,6 +208,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
platform_config,
PLATFORM_MAPPING[platform],
)
reload_configs.append((PLATFORM_MAPPING[platform], _config))
load_coroutines.append(
discovery.async_load_platform(
hass,
@ -190,10 +219,6 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
)
)
await async_setup_reload_service(hass, DOMAIN, platforms)
if load_coroutines:
_LOGGER.debug("Loading platforms: %s", platforms)
await asyncio.gather(*load_coroutines)
return True

View File

@ -1,6 +1,7 @@
cover:
- platform: command_line
covers:
from_yaml:
command_state: "echo closed"
value_template: "{{ value }}"
command_line:
- "binary_sensor":
"name": "Test"
"command": "echo 1"
"payload_on": "1"
"payload_off": "0"
"command_timeout": 15

View File

@ -9,7 +9,7 @@ from unittest.mock import patch
import pytest
from homeassistant import config as hass_config, setup
from homeassistant import setup
from homeassistant.components.command_line import DOMAIN
from homeassistant.components.command_line.cover import CommandCover
from homeassistant.components.cover import DOMAIN as COVER_DOMAIN, SCAN_INTERVAL
@ -21,7 +21,6 @@ from homeassistant.const import (
ATTR_ENTITY_ID,
SERVICE_CLOSE_COVER,
SERVICE_OPEN_COVER,
SERVICE_RELOAD,
SERVICE_STOP_COVER,
)
from homeassistant.core import HomeAssistant
@ -29,7 +28,7 @@ from homeassistant.helpers import entity_registry as er
import homeassistant.helpers.issue_registry as ir
import homeassistant.util.dt as dt_util
from tests.common import async_fire_time_changed, get_fixture_path
from tests.common import async_fire_time_changed
async def test_no_covers_platform_yaml(
@ -214,45 +213,6 @@ async def test_state_value(hass: HomeAssistant) -> None:
assert entity_state.state == "closed"
@pytest.mark.parametrize(
"get_config",
[
{
"command_line": [
{
"cover": {
"command_state": "echo open",
"value_template": "{{ value }}",
"name": "Test",
}
}
]
}
],
)
async def test_reload(hass: HomeAssistant, load_yaml_integration: None) -> None:
"""Verify we can reload command_line covers."""
entity_state = hass.states.get("cover.test")
assert entity_state
assert entity_state.state == "unknown"
yaml_path = get_fixture_path("configuration.yaml", "command_line")
with patch.object(hass_config, "YAML_CONFIG_FILE", yaml_path):
await hass.services.async_call(
"command_line",
SERVICE_RELOAD,
{},
blocking=True,
)
await hass.async_block_till_done()
assert len(hass.states.async_all()) == 1
assert not hass.states.get("cover.test")
assert hass.states.get("cover.from_yaml")
@pytest.mark.parametrize(
"get_config",
[

View File

@ -2,12 +2,17 @@
from __future__ import annotations
from datetime import timedelta
from unittest.mock import patch
from homeassistant.const import STATE_ON, STATE_OPEN
import pytest
from homeassistant import config as hass_config
from homeassistant.components.command_line.const import DOMAIN
from homeassistant.const import SERVICE_RELOAD, STATE_ON, STATE_OPEN
from homeassistant.core import HomeAssistant
import homeassistant.util.dt as dt_util
from tests.common import async_fire_time_changed
from tests.common import async_fire_time_changed, get_fixture_path
async def test_setup_config(hass: HomeAssistant, load_yaml_integration: None) -> None:
@ -25,3 +30,55 @@ async def test_setup_config(hass: HomeAssistant, load_yaml_integration: None) ->
assert state_sensor.state == "5"
assert state_cover.state == STATE_OPEN
assert state_switch.state == STATE_ON
async def test_reload_service(
hass: HomeAssistant, load_yaml_integration: None, caplog: pytest.LogCaptureFixture
) -> None:
"""Test reload serviice."""
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=10))
await hass.async_block_till_done()
state_binary_sensor = hass.states.get("binary_sensor.test")
state_sensor = hass.states.get("sensor.test")
assert state_binary_sensor.state == STATE_ON
assert state_sensor.state == "5"
caplog.clear()
yaml_path = get_fixture_path("configuration.yaml", "command_line")
with patch.object(hass_config, "YAML_CONFIG_FILE", yaml_path):
await hass.services.async_call(
DOMAIN,
SERVICE_RELOAD,
{},
blocking=True,
)
await hass.async_block_till_done()
assert "Loading config" in caplog.text
state_binary_sensor = hass.states.get("binary_sensor.test")
state_sensor = hass.states.get("sensor.test")
assert state_binary_sensor.state == STATE_ON
assert not state_sensor
caplog.clear()
yaml_path = get_fixture_path("configuration_empty.yaml", "command_line")
with patch.object(hass_config, "YAML_CONFIG_FILE", yaml_path):
await hass.services.async_call(
DOMAIN,
SERVICE_RELOAD,
{},
blocking=True,
)
await hass.async_block_till_done()
state_binary_sensor = hass.states.get("binary_sensor.test")
state_sensor = hass.states.get("sensor.test")
assert not state_binary_sensor
assert not state_sensor
assert "Loading config" not in caplog.text