mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Add homeassistant.reload_all service (#87769)
This commit is contained in:
parent
03710e58b5
commit
f1daeabff0
@ -15,6 +15,7 @@ from homeassistant.const import (
|
||||
RESTART_EXIT_CODE,
|
||||
SERVICE_HOMEASSISTANT_RESTART,
|
||||
SERVICE_HOMEASSISTANT_STOP,
|
||||
SERVICE_RELOAD,
|
||||
SERVICE_SAVE_PERSISTENT_STATES,
|
||||
SERVICE_TOGGLE,
|
||||
SERVICE_TURN_OFF,
|
||||
@ -40,6 +41,7 @@ SERVICE_RELOAD_CONFIG_ENTRY = "reload_config_entry"
|
||||
SERVICE_CHECK_CONFIG = "check_config"
|
||||
SERVICE_UPDATE_ENTITY = "update_entity"
|
||||
SERVICE_SET_LOCATION = "set_location"
|
||||
SERVICE_RELOAD_ALL = "reload_all"
|
||||
SCHEMA_UPDATE_ENTITY = vol.Schema({ATTR_ENTITY_ID: cv.entity_ids})
|
||||
SCHEMA_RELOAD_CONFIG_ENTRY = vol.All(
|
||||
vol.Schema(
|
||||
@ -275,4 +277,50 @@ async def async_setup(hass: ha.HomeAssistant, config: ConfigType) -> bool: # no
|
||||
schema=SCHEMA_RELOAD_CONFIG_ENTRY,
|
||||
)
|
||||
|
||||
async def async_handle_reload_all(call: ha.ServiceCall) -> None:
|
||||
"""Service handler for calling all integration reload services.
|
||||
|
||||
Calls all reload services on all active domains, which triggers the
|
||||
reload of YAML configurations for the domain that support it.
|
||||
|
||||
Additionally, it also calls the `homeasssitant.reload_core_config`
|
||||
service, as that reloads the core YAML configuration, and the
|
||||
`frontend.reload_themes` service, as that reloads the themes.
|
||||
|
||||
We only do so, if there are no configuration errors.
|
||||
"""
|
||||
|
||||
if errors := await conf_util.async_check_ha_config_file(hass):
|
||||
_LOGGER.error(
|
||||
"The system cannot reload because the configuration is not valid: %s",
|
||||
errors,
|
||||
)
|
||||
raise HomeAssistantError(
|
||||
"Cannot quick reload all YAML configurations because the "
|
||||
f"configuration is not valid: {errors}"
|
||||
)
|
||||
|
||||
services = hass.services.async_services()
|
||||
tasks = [
|
||||
hass.services.async_call(
|
||||
domain, SERVICE_RELOAD, context=call.context, blocking=True
|
||||
)
|
||||
for domain, domain_services in services.items()
|
||||
if domain != "notify" and SERVICE_RELOAD in domain_services
|
||||
] + [
|
||||
hass.services.async_call(
|
||||
domain, service, context=call.context, blocking=True
|
||||
)
|
||||
for domain, service in {
|
||||
ha.DOMAIN: SERVICE_RELOAD_CORE_CONFIG,
|
||||
"frontend": "reload_themes",
|
||||
}.items()
|
||||
]
|
||||
|
||||
await asyncio.gather(*tasks)
|
||||
|
||||
async_register_admin_service(
|
||||
hass, ha.DOMAIN, SERVICE_RELOAD_ALL, async_handle_reload_all
|
||||
)
|
||||
|
||||
return True
|
||||
|
@ -12,6 +12,7 @@ import homeassistant.components as comps
|
||||
from homeassistant.components.homeassistant import (
|
||||
ATTR_ENTRY_ID,
|
||||
SERVICE_CHECK_CONFIG,
|
||||
SERVICE_RELOAD_ALL,
|
||||
SERVICE_RELOAD_CORE_CONFIG,
|
||||
SERVICE_SET_LOCATION,
|
||||
)
|
||||
@ -572,3 +573,62 @@ async def test_save_persistent_states(hass: HomeAssistant) -> None:
|
||||
blocking=True,
|
||||
)
|
||||
assert mock_save.called
|
||||
|
||||
|
||||
async def test_reload_all(
|
||||
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""Test reload_all service."""
|
||||
await async_setup_component(hass, "homeassistant", {})
|
||||
test1 = async_mock_service(hass, "test1", "reload")
|
||||
test2 = async_mock_service(hass, "test2", "reload")
|
||||
no_reload = async_mock_service(hass, "test3", "not_reload")
|
||||
notify = async_mock_service(hass, "notify", "reload")
|
||||
core_config = async_mock_service(hass, "homeassistant", "reload_core_config")
|
||||
themes = async_mock_service(hass, "frontend", "reload_themes")
|
||||
|
||||
with patch(
|
||||
"homeassistant.config.async_check_ha_config_file",
|
||||
return_value=None,
|
||||
) as mock_async_check_ha_config_file:
|
||||
await hass.services.async_call(
|
||||
"homeassistant",
|
||||
SERVICE_RELOAD_ALL,
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
assert mock_async_check_ha_config_file.called
|
||||
assert len(test1) == 1
|
||||
assert len(test2) == 1
|
||||
assert len(no_reload) == 0
|
||||
assert len(notify) == 0
|
||||
assert len(core_config) == 1
|
||||
assert len(themes) == 1
|
||||
|
||||
with pytest.raises(
|
||||
HomeAssistantError,
|
||||
match=(
|
||||
"Cannot quick reload all YAML configurations because the configuration is "
|
||||
"not valid: Oh no, drama!"
|
||||
),
|
||||
), patch(
|
||||
"homeassistant.config.async_check_ha_config_file",
|
||||
return_value="Oh no, drama!",
|
||||
) as mock_async_check_ha_config_file:
|
||||
await hass.services.async_call(
|
||||
"homeassistant",
|
||||
SERVICE_RELOAD_ALL,
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
assert mock_async_check_ha_config_file.called
|
||||
assert (
|
||||
"The system cannot reload because the configuration is not valid: Oh no, drama!"
|
||||
in caplog.text
|
||||
)
|
||||
|
||||
# None have been called again
|
||||
assert len(test1) == 1
|
||||
assert len(test2) == 1
|
||||
assert len(core_config) == 1
|
||||
assert len(themes) == 1
|
||||
|
Loading…
x
Reference in New Issue
Block a user