Add availability_template to Template Vacuum platform (#26514)
* Added availability_template to Template Vacuum platform * Added to test for invalid values in availability_template * Updated AVAILABILITY_TEMPLATE Rendering error * Moved const to package Const.py * Removed 'Magic' string * Cleaned up const and compare lowercase result to 'true' * reverted _available back to boolean * Fixed tests (async, magic values and state checks)pull/27034/head
parent
ed82ec5d8e
commit
11c9bab078
|
@ -44,6 +44,8 @@ from homeassistant.exceptions import TemplateError
|
|||
from homeassistant.helpers.entity import async_generate_entity_id
|
||||
from homeassistant.helpers.script import Script
|
||||
|
||||
from .const import CONF_AVAILABILITY_TEMPLATE
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONF_VACUUMS = "vacuums"
|
||||
|
@ -67,6 +69,7 @@ VACUUM_SCHEMA = vol.Schema(
|
|||
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_BATTERY_LEVEL_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_FAN_SPEED_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_AVAILABILITY_TEMPLATE): cv.template,
|
||||
vol.Required(SERVICE_START): cv.SCRIPT_SCHEMA,
|
||||
vol.Optional(SERVICE_PAUSE): cv.SCRIPT_SCHEMA,
|
||||
vol.Optional(SERVICE_STOP): cv.SCRIPT_SCHEMA,
|
||||
|
@ -94,6 +97,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
state_template = device_config.get(CONF_VALUE_TEMPLATE)
|
||||
battery_level_template = device_config.get(CONF_BATTERY_LEVEL_TEMPLATE)
|
||||
fan_speed_template = device_config.get(CONF_FAN_SPEED_TEMPLATE)
|
||||
availability_template = device_config.get(CONF_AVAILABILITY_TEMPLATE)
|
||||
|
||||
start_action = device_config[SERVICE_START]
|
||||
pause_action = device_config.get(SERVICE_PAUSE)
|
||||
|
@ -113,6 +117,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
(CONF_VALUE_TEMPLATE, state_template),
|
||||
(CONF_BATTERY_LEVEL_TEMPLATE, battery_level_template),
|
||||
(CONF_FAN_SPEED_TEMPLATE, fan_speed_template),
|
||||
(CONF_AVAILABILITY_TEMPLATE, availability_template),
|
||||
):
|
||||
if template is None:
|
||||
continue
|
||||
|
@ -152,6 +157,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
state_template,
|
||||
battery_level_template,
|
||||
fan_speed_template,
|
||||
availability_template,
|
||||
start_action,
|
||||
pause_action,
|
||||
stop_action,
|
||||
|
@ -178,6 +184,7 @@ class TemplateVacuum(StateVacuumDevice):
|
|||
state_template,
|
||||
battery_level_template,
|
||||
fan_speed_template,
|
||||
availability_template,
|
||||
start_action,
|
||||
pause_action,
|
||||
stop_action,
|
||||
|
@ -198,6 +205,7 @@ class TemplateVacuum(StateVacuumDevice):
|
|||
self._template = state_template
|
||||
self._battery_level_template = battery_level_template
|
||||
self._fan_speed_template = fan_speed_template
|
||||
self._availability_template = availability_template
|
||||
self._supported_features = SUPPORT_START
|
||||
|
||||
self._start_script = Script(hass, start_action)
|
||||
|
@ -235,6 +243,7 @@ class TemplateVacuum(StateVacuumDevice):
|
|||
self._state = None
|
||||
self._battery_level = None
|
||||
self._fan_speed = None
|
||||
self._available = True
|
||||
|
||||
if self._template:
|
||||
self._supported_features |= SUPPORT_STATE
|
||||
|
@ -280,6 +289,11 @@ class TemplateVacuum(StateVacuumDevice):
|
|||
"""Return the polling state."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Return if the device is available."""
|
||||
return self._available
|
||||
|
||||
async def async_start(self):
|
||||
"""Start or resume the cleaning task."""
|
||||
await self._start_script.async_run(context=self._context)
|
||||
|
@ -421,3 +435,16 @@ class TemplateVacuum(StateVacuumDevice):
|
|||
self._fan_speed_list,
|
||||
)
|
||||
self._fan_speed = None
|
||||
# Update availability if availability template is defined
|
||||
if self._availability_template is not None:
|
||||
try:
|
||||
self._available = (
|
||||
self._availability_template.async_render().lower() == "true"
|
||||
)
|
||||
except (TemplateError, ValueError) as ex:
|
||||
_LOGGER.error(
|
||||
"Could not render %s template %s: %s",
|
||||
CONF_AVAILABILITY_TEMPLATE,
|
||||
self._name,
|
||||
ex,
|
||||
)
|
||||
|
|
|
@ -3,7 +3,7 @@ import logging
|
|||
import pytest
|
||||
|
||||
from homeassistant import setup
|
||||
from homeassistant.const import STATE_ON, STATE_UNKNOWN
|
||||
from homeassistant.const import STATE_ON, STATE_OFF, STATE_UNKNOWN, STATE_UNAVAILABLE
|
||||
from homeassistant.components.vacuum import (
|
||||
ATTR_BATTERY_LEVEL,
|
||||
STATE_CLEANING,
|
||||
|
@ -210,6 +210,68 @@ async def test_invalid_templates(hass, calls):
|
|||
_verify(hass, STATE_UNKNOWN, None)
|
||||
|
||||
|
||||
async def test_available_template_with_entities(hass, calls):
|
||||
"""Test availability templates with values from other entities."""
|
||||
|
||||
assert await setup.async_setup_component(
|
||||
hass,
|
||||
"vacuum",
|
||||
{
|
||||
"vacuum": {
|
||||
"platform": "template",
|
||||
"vacuums": {
|
||||
"test_template_vacuum": {
|
||||
"availability_template": "{{ is_state('availability_state.state', 'on') }}",
|
||||
"start": {"service": "script.vacuum_start"},
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
await hass.async_start()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# When template returns true..
|
||||
hass.states.async_set("availability_state.state", STATE_ON)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Device State should not be unavailable
|
||||
assert hass.states.get("vacuum.test_template_vacuum").state != STATE_UNAVAILABLE
|
||||
|
||||
# When Availability template returns false
|
||||
hass.states.async_set("availability_state.state", STATE_OFF)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# device state should be unavailable
|
||||
assert hass.states.get("vacuum.test_template_vacuum").state == STATE_UNAVAILABLE
|
||||
|
||||
|
||||
async def test_invalid_availability_template_keeps_component_available(hass, caplog):
|
||||
"""Test that an invalid availability keeps the device available."""
|
||||
assert await setup.async_setup_component(
|
||||
hass,
|
||||
"vacuum",
|
||||
{
|
||||
"vacuum": {
|
||||
"platform": "template",
|
||||
"vacuums": {
|
||||
"test_template_vacuum": {
|
||||
"availability_template": "{{ x - 12 }}",
|
||||
"start": {"service": "script.vacuum_start"},
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
await hass.async_start()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get("vacuum.test_template_vacuum") != STATE_UNAVAILABLE
|
||||
assert ("UndefinedError: 'x' is undefined") in caplog.text
|
||||
|
||||
|
||||
# End of template tests #
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue