Add input_datetime reload service. (#29581)

* Add input_datetime reload service.

* Add reload service test.
This commit is contained in:
Alexei Chetroi 2019-12-07 15:24:56 -05:00 committed by Paulus Schoutsen
parent ccb0fd5e32
commit 256056430e
3 changed files with 116 additions and 19 deletions

View File

@ -1,16 +1,22 @@
"""Support to select a date and/or a time.""" """Support to select a date and/or a time."""
import logging
import datetime import datetime
import logging
import voluptuous as vol import voluptuous as vol
from homeassistant.const import ATTR_DATE, ATTR_TIME, CONF_ICON, CONF_NAME from homeassistant.const import (
ATTR_DATE,
ATTR_TIME,
CONF_ICON,
CONF_NAME,
SERVICE_RELOAD,
)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.restore_state import RestoreEntity
import homeassistant.helpers.service
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DOMAIN = "input_datetime" DOMAIN = "input_datetime"
@ -52,27 +58,32 @@ CONFIG_SCHEMA = vol.Schema(
}, },
extra=vol.ALLOW_EXTRA, extra=vol.ALLOW_EXTRA,
) )
RELOAD_SERVICE_SCHEMA = vol.Schema({})
async def async_setup(hass, config): async def async_setup(hass, config):
"""Set up an input datetime.""" """Set up an input datetime."""
component = EntityComponent(_LOGGER, DOMAIN, hass) component = EntityComponent(_LOGGER, DOMAIN, hass)
entities = [] entities = await _async_process_config(config)
for object_id, cfg in config[DOMAIN].items(): async def reload_service_handler(service_call):
name = cfg.get(CONF_NAME) """Remove all entities and load new ones from config."""
has_time = cfg.get(CONF_HAS_TIME) conf = await component.async_prepare_reload()
has_date = cfg.get(CONF_HAS_DATE) if conf is None:
icon = cfg.get(CONF_ICON) return
initial = cfg.get(CONF_INITIAL) new_entities = await _async_process_config(conf)
entities.append( if new_entities:
InputDatetime(object_id, name, has_date, has_time, icon, initial) await component.async_add_entities(new_entities)
homeassistant.helpers.service.async_register_admin_service(
hass,
DOMAIN,
SERVICE_RELOAD,
reload_service_handler,
schema=RELOAD_SERVICE_SCHEMA,
) )
if not entities:
return False
async def async_set_datetime_service(entity, call): async def async_set_datetime_service(entity, call):
"""Handle a call to the input datetime 'set datetime' service.""" """Handle a call to the input datetime 'set datetime' service."""
time = call.data.get(ATTR_TIME) time = call.data.get(ATTR_TIME)
@ -108,10 +119,28 @@ async def async_setup(hass, config):
async_set_datetime_service, async_set_datetime_service,
) )
if entities:
await component.async_add_entities(entities) await component.async_add_entities(entities)
return True return True
async def _async_process_config(config):
"""Process config and create list of entities."""
entities = []
for object_id, cfg in config[DOMAIN].items():
name = cfg.get(CONF_NAME)
has_time = cfg.get(CONF_HAS_TIME)
has_date = cfg.get(CONF_HAS_DATE)
icon = cfg.get(CONF_ICON)
initial = cfg.get(CONF_INITIAL)
entities.append(
InputDatetime(object_id, name, has_date, has_time, icon, initial)
)
return entities
class InputDatetime(RestoreEntity): class InputDatetime(RestoreEntity):
"""Representation of a datetime input.""" """Representation of a datetime input."""

View File

@ -9,3 +9,6 @@ set_datetime:
example: '"time": "05:30:00"'} example: '"time": "05:30:00"'}
datetime: {description: The target date & time the entity should be set to. Do not use with date or time., datetime: {description: The target date & time the entity should be set to. Do not use with date or time.,
example: '"datetime": "2019-04-22 05:30:00"'} example: '"datetime": "2019-04-22 05:30:00"'}
reload:
description: Reload the input_datetime configuration.

View File

@ -2,20 +2,23 @@
# pylint: disable=protected-access # pylint: disable=protected-access
import asyncio import asyncio
import datetime import datetime
from unittest.mock import patch
import pytest import pytest
import voluptuous as vol import voluptuous as vol
from homeassistant.core import CoreState, State, Context
from homeassistant.setup import async_setup_component
from homeassistant.components.input_datetime import ( from homeassistant.components.input_datetime import (
DOMAIN,
ATTR_DATE, ATTR_DATE,
ATTR_DATETIME, ATTR_DATETIME,
ATTR_TIME, ATTR_TIME,
DOMAIN,
SERVICE_RELOAD,
SERVICE_SET_DATETIME, SERVICE_SET_DATETIME,
) )
from homeassistant.const import ATTR_ENTITY_ID from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import Context, CoreState, State
from homeassistant.exceptions import Unauthorized
from homeassistant.setup import async_setup_component
from tests.common import mock_restore_cache from tests.common import mock_restore_cache
@ -310,3 +313,65 @@ async def test_input_datetime_context(hass, hass_admin_user):
assert state2 is not None assert state2 is not None
assert state.state != state2.state assert state.state != state2.state
assert state2.context.user_id == hass_admin_user.id assert state2.context.user_id == hass_admin_user.id
async def test_reload(hass, hass_admin_user, hass_read_only_user):
"""Test reload service."""
count_start = len(hass.states.async_entity_ids())
assert await async_setup_component(
hass,
DOMAIN,
{
DOMAIN: {
"dt1": {"has_time": False, "has_date": True, "initial": "2019-1-1"},
}
},
)
assert count_start + 1 == len(hass.states.async_entity_ids())
state_1 = hass.states.get("input_datetime.dt1")
state_2 = hass.states.get("input_datetime.dt2")
dt_obj = datetime.datetime(2019, 1, 1, 0, 0)
assert state_1 is not None
assert state_2 is None
assert str(dt_obj.date()) == state_1.state
with patch(
"homeassistant.config.load_yaml_config_file",
autospec=True,
return_value={
DOMAIN: {
"dt1": {"has_time": True, "has_date": False, "initial": "23:32"},
"dt2": {"has_time": True, "has_date": True},
}
},
):
with patch("homeassistant.config.find_config_file", return_value=""):
with pytest.raises(Unauthorized):
await hass.services.async_call(
DOMAIN,
SERVICE_RELOAD,
blocking=True,
context=Context(user_id=hass_read_only_user.id),
)
await hass.services.async_call(
DOMAIN,
SERVICE_RELOAD,
blocking=True,
context=Context(user_id=hass_admin_user.id),
)
await hass.async_block_till_done()
assert count_start + 2 == len(hass.states.async_entity_ids())
state_1 = hass.states.get("input_datetime.dt1")
state_2 = hass.states.get("input_datetime.dt2")
dt_obj = datetime.datetime(2019, 1, 1, 23, 32)
assert state_1 is not None
assert state_2 is not None
assert str(dt_obj.time()) == state_1.state
assert str(datetime.datetime(1970, 1, 1, 0, 0)) == state_2.state