Refactor Rest Binary sensor with ManualTriggerEntity (#97400)
* Refactor Rest Binary sensor w/ ManualTriggerEntity * test availability * review comments * Use super * Fix config
This commit is contained in:
parent
9b74321487
commit
4531dbbe62
4 changed files with 65 additions and 13 deletions
|
@ -14,6 +14,8 @@ from homeassistant.components.binary_sensor import (
|
|||
from homeassistant.const import (
|
||||
CONF_DEVICE_CLASS,
|
||||
CONF_FORCE_UPDATE,
|
||||
CONF_ICON,
|
||||
CONF_NAME,
|
||||
CONF_RESOURCE,
|
||||
CONF_RESOURCE_TEMPLATE,
|
||||
CONF_UNIQUE_ID,
|
||||
|
@ -24,7 +26,11 @@ from homeassistant.exceptions import PlatformNotReady
|
|||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.template import Template
|
||||
from homeassistant.helpers.template_entity import TemplateEntity
|
||||
from homeassistant.helpers.template_entity import (
|
||||
CONF_AVAILABILITY,
|
||||
CONF_PICTURE,
|
||||
ManualTriggerEntity,
|
||||
)
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||
|
||||
|
@ -42,6 +48,14 @@ PLATFORM_SCHEMA = vol.All(
|
|||
cv.has_at_least_one_key(CONF_RESOURCE, CONF_RESOURCE_TEMPLATE), PLATFORM_SCHEMA
|
||||
)
|
||||
|
||||
TRIGGER_ENTITY_OPTIONS = (
|
||||
CONF_AVAILABILITY,
|
||||
CONF_DEVICE_CLASS,
|
||||
CONF_ICON,
|
||||
CONF_PICTURE,
|
||||
CONF_UNIQUE_ID,
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_platform(
|
||||
hass: HomeAssistant,
|
||||
|
@ -74,7 +88,14 @@ async def async_setup_platform(
|
|||
raise PlatformNotReady from rest.last_exception
|
||||
raise PlatformNotReady
|
||||
|
||||
unique_id = conf.get(CONF_UNIQUE_ID)
|
||||
name = conf.get(CONF_NAME) or Template(DEFAULT_BINARY_SENSOR_NAME, hass)
|
||||
|
||||
trigger_entity_config = {CONF_NAME: name}
|
||||
|
||||
for key in TRIGGER_ENTITY_OPTIONS:
|
||||
if key not in conf:
|
||||
continue
|
||||
trigger_entity_config[key] = conf[key]
|
||||
|
||||
async_add_entities(
|
||||
[
|
||||
|
@ -83,13 +104,13 @@ async def async_setup_platform(
|
|||
coordinator,
|
||||
rest,
|
||||
conf,
|
||||
unique_id,
|
||||
trigger_entity_config,
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
class RestBinarySensor(RestEntity, TemplateEntity, BinarySensorEntity):
|
||||
class RestBinarySensor(ManualTriggerEntity, RestEntity, BinarySensorEntity):
|
||||
"""Representation of a REST binary sensor."""
|
||||
|
||||
def __init__(
|
||||
|
@ -98,9 +119,10 @@ class RestBinarySensor(RestEntity, TemplateEntity, BinarySensorEntity):
|
|||
coordinator: DataUpdateCoordinator[None] | None,
|
||||
rest: RestData,
|
||||
config: ConfigType,
|
||||
unique_id: str | None,
|
||||
trigger_entity_config: ConfigType,
|
||||
) -> None:
|
||||
"""Initialize a REST binary sensor."""
|
||||
ManualTriggerEntity.__init__(self, hass, trigger_entity_config)
|
||||
RestEntity.__init__(
|
||||
self,
|
||||
coordinator,
|
||||
|
@ -108,19 +130,17 @@ class RestBinarySensor(RestEntity, TemplateEntity, BinarySensorEntity):
|
|||
config.get(CONF_RESOURCE_TEMPLATE),
|
||||
config[CONF_FORCE_UPDATE],
|
||||
)
|
||||
TemplateEntity.__init__(
|
||||
self,
|
||||
hass,
|
||||
config=config,
|
||||
fallback_name=DEFAULT_BINARY_SENSOR_NAME,
|
||||
unique_id=unique_id,
|
||||
)
|
||||
self._previous_data = None
|
||||
self._value_template: Template | None = config.get(CONF_VALUE_TEMPLATE)
|
||||
if (value_template := self._value_template) is not None:
|
||||
value_template.hass = hass
|
||||
|
||||
self._attr_device_class = config.get(CONF_DEVICE_CLASS)
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Return if entity is available."""
|
||||
available1 = RestEntity.available.fget(self) # type: ignore[attr-defined]
|
||||
available2 = ManualTriggerEntity.available.fget(self) # type: ignore[attr-defined]
|
||||
return bool(available1 and available2)
|
||||
|
||||
def _update_from_rest_data(self) -> None:
|
||||
"""Update state from the rest data."""
|
||||
|
@ -130,6 +150,8 @@ class RestBinarySensor(RestEntity, TemplateEntity, BinarySensorEntity):
|
|||
|
||||
response = self.rest.data
|
||||
|
||||
raw_value = response
|
||||
|
||||
if self._value_template is not None:
|
||||
response = self._value_template.async_render_with_possible_json_value(
|
||||
self.rest.data, False
|
||||
|
@ -144,3 +166,6 @@ class RestBinarySensor(RestEntity, TemplateEntity, BinarySensorEntity):
|
|||
"open": True,
|
||||
"yes": True,
|
||||
}.get(response.lower(), False)
|
||||
|
||||
self._process_manual_data(raw_value)
|
||||
self.async_write_ha_state()
|
||||
|
|
|
@ -28,6 +28,7 @@ from homeassistant.const import (
|
|||
)
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.template_entity import (
|
||||
CONF_AVAILABILITY,
|
||||
TEMPLATE_ENTITY_BASE_SCHEMA,
|
||||
TEMPLATE_SENSOR_BASE_SCHEMA,
|
||||
)
|
||||
|
@ -82,6 +83,7 @@ BINARY_SENSOR_SCHEMA = {
|
|||
vol.Optional(CONF_DEVICE_CLASS): BINARY_SENSOR_DEVICE_CLASSES_SCHEMA,
|
||||
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_FORCE_UPDATE, default=DEFAULT_FORCE_UPDATE): cv.boolean,
|
||||
vol.Optional(CONF_AVAILABILITY): cv.template,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -564,6 +564,7 @@ class TriggerBaseEntity(Entity):
|
|||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Handle being added to Home Assistant."""
|
||||
await super().async_added_to_hass()
|
||||
template_attach(self.hass, self._config)
|
||||
|
||||
def _set_unique_id(self, unique_id: str | None) -> None:
|
||||
|
|
|
@ -500,3 +500,27 @@ async def test_entity_config(hass: HomeAssistant) -> None:
|
|||
"friendly_name": "REST Binary Sensor",
|
||||
"icon": "mdi:one_two_three",
|
||||
}
|
||||
|
||||
|
||||
@respx.mock
|
||||
async def test_availability_in_config(hass: HomeAssistant) -> None:
|
||||
"""Test entity configuration."""
|
||||
|
||||
config = {
|
||||
BINARY_SENSOR_DOMAIN: {
|
||||
# REST configuration
|
||||
"platform": DOMAIN,
|
||||
"method": "GET",
|
||||
"resource": "http://localhost",
|
||||
# Entity configuration
|
||||
"availability": "{{value==1}}",
|
||||
"name": "{{'REST' + ' ' + 'Binary Sensor'}}",
|
||||
},
|
||||
}
|
||||
|
||||
respx.get("http://localhost") % HTTPStatus.OK
|
||||
assert await async_setup_component(hass, BINARY_SENSOR_DOMAIN, config)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("binary_sensor.rest_binary_sensor")
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
|
|
Loading…
Add table
Reference in a new issue