core/homeassistant/components/switch_as_x/valve.py

96 lines
2.8 KiB
Python

"""Valve support for switch entities."""
from __future__ import annotations
from typing import Any
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
from homeassistant.components.valve import (
DOMAIN as VALVE_DOMAIN,
ValveEntity,
ValveEntityFeature,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_ENTITY_ID,
CONF_ENTITY_ID,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
STATE_ON,
)
from homeassistant.core import Event, EventStateChangedData, HomeAssistant, callback
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import CONF_INVERT
from .entity import BaseInvertableEntity
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Initialize Valve Switch config entry."""
registry = er.async_get(hass)
entity_id = er.async_validate_entity_id(
registry, config_entry.options[CONF_ENTITY_ID]
)
async_add_entities(
[
ValveSwitch(
hass,
config_entry.title,
VALVE_DOMAIN,
config_entry.options[CONF_INVERT],
entity_id,
config_entry.entry_id,
)
]
)
class ValveSwitch(BaseInvertableEntity, ValveEntity):
"""Represents a Switch as a Valve."""
_attr_supported_features = ValveEntityFeature.OPEN | ValveEntityFeature.CLOSE
_attr_reports_position = False
async def async_open_valve(self, **kwargs: Any) -> None:
"""Open the valve."""
await self.hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF if self._invert_state else SERVICE_TURN_ON,
{ATTR_ENTITY_ID: self._switch_entity_id},
blocking=True,
context=self._context,
)
async def async_close_valve(self, **kwargs: Any) -> None:
"""Close valve."""
await self.hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON if self._invert_state else SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: self._switch_entity_id},
blocking=True,
context=self._context,
)
@callback
def async_state_changed_listener(
self, event: Event[EventStateChangedData] | None = None
) -> None:
"""Handle child updates."""
super().async_state_changed_listener(event)
if (
not self.available
or (state := self.hass.states.get(self._switch_entity_id)) is None
):
return
if self._invert_state:
self._attr_is_closed = state.state == STATE_ON
else:
self._attr_is_closed = state.state != STATE_ON