diff --git a/homeassistant/components/rachio/device.py b/homeassistant/components/rachio/device.py index c018d7e6f86..09f7eaf1b06 100644 --- a/homeassistant/components/rachio/device.py +++ b/homeassistant/components/rachio/device.py @@ -350,11 +350,9 @@ class RachioBaseStation: def __init__( self, rachio: Rachio, data: dict[str, Any], coordinator: RachioUpdateCoordinator ) -> None: - """Initialize a hose time base station.""" + """Initialize a smart hose timer base station.""" self.rachio = rachio self._id = data[KEY_ID] - self.serial_number = data[KEY_SERIAL_NUMBER] - self.mac_address = data[KEY_MAC_ADDRESS] self.coordinator = coordinator def start_watering(self, valve_id: str, duration: int) -> None: diff --git a/homeassistant/components/rachio/entity.py b/homeassistant/components/rachio/entity.py index fc0dc1f1aae..27564f1caca 100644 --- a/homeassistant/components/rachio/entity.py +++ b/homeassistant/components/rachio/entity.py @@ -1,10 +1,24 @@ """Adapter to wrap the rachiopy api for home assistant.""" +from abc import abstractmethod +from typing import Any + +from homeassistant.core import callback from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity import Entity +from homeassistant.helpers.update_coordinator import CoordinatorEntity -from .const import DEFAULT_NAME, DOMAIN +from .const import ( + DEFAULT_NAME, + DOMAIN, + KEY_CONNECTED, + KEY_ID, + KEY_NAME, + KEY_REPORTED_STATE, + KEY_STATE, +) +from .coordinator import RachioUpdateCoordinator from .device import RachioIro @@ -35,3 +49,44 @@ class RachioDevice(Entity): manufacturer=DEFAULT_NAME, configuration_url="https://app.rach.io", ) + + +class RachioHoseTimerEntity(CoordinatorEntity[RachioUpdateCoordinator]): + """Base class for smart hose timer entities.""" + + _attr_has_entity_name = True + + def __init__( + self, data: dict[str, Any], coordinator: RachioUpdateCoordinator + ) -> None: + """Initialize a Rachio smart hose timer entity.""" + super().__init__(coordinator) + self.id = data[KEY_ID] + self._name = data[KEY_NAME] + self._attr_device_info = DeviceInfo( + identifiers={(DOMAIN, self.id)}, + model="Smart Hose Timer", + name=self._name, + manufacturer=DEFAULT_NAME, + configuration_url="https://app.rach.io", + ) + + @property + def available(self) -> bool: + """Return if the entity is available.""" + return ( + super().available + and self.coordinator.data[self.id][KEY_STATE][KEY_REPORTED_STATE][ + KEY_CONNECTED + ] + ) + + @abstractmethod + def _update_attr(self) -> None: + """Update the state and attributes.""" + + @callback + def _handle_coordinator_update(self) -> None: + """Handle updated data from the coordinator.""" + self._update_attr() + super()._handle_coordinator_update() diff --git a/homeassistant/components/rachio/switch.py b/homeassistant/components/rachio/switch.py index fe3d455df3c..0f696baad3a 100644 --- a/homeassistant/components/rachio/switch.py +++ b/homeassistant/components/rachio/switch.py @@ -13,25 +13,17 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_ENTITY_ID, ATTR_ID from homeassistant.core import CALLBACK_TYPE, HomeAssistant, ServiceCall, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers import ( - config_validation as cv, - device_registry as dr, - entity_platform, -) -from homeassistant.helpers.device_registry import DeviceInfo +from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.event import async_track_point_in_utc_time -from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util.dt import as_timestamp, now, parse_datetime, utc_from_timestamp from .const import ( CONF_MANUAL_RUN_MINS, DEFAULT_MANUAL_RUN_MINS, - DEFAULT_NAME, DOMAIN as DOMAIN_RACHIO, - KEY_CONNECTED, KEY_CURRENT_STATUS, KEY_CUSTOM_CROP, KEY_CUSTOM_SHADE, @@ -67,9 +59,8 @@ from .const import ( SLOPE_SLIGHT, SLOPE_STEEP, ) -from .coordinator import RachioUpdateCoordinator from .device import RachioPerson -from .entity import RachioDevice +from .entity import RachioDevice, RachioHoseTimerEntity from .webhooks import ( SUBTYPE_RAIN_DELAY_OFF, SUBTYPE_RAIN_DELAY_ON, @@ -546,39 +537,19 @@ class RachioSchedule(RachioSwitch): ) -class RachioValve(CoordinatorEntity[RachioUpdateCoordinator], SwitchEntity): +class RachioValve(RachioHoseTimerEntity, SwitchEntity): """Representation of one smart hose timer valve.""" - def __init__( - self, person, base, data, coordinator: RachioUpdateCoordinator - ) -> None: + _attr_name = None + + def __init__(self, person, base, data, coordinator) -> None: """Initialize a new smart hose valve.""" - super().__init__(coordinator) + super().__init__(data, coordinator) self._person = person self._base = base - self.id = data[KEY_ID] - self._attr_name = data[KEY_NAME] self._attr_unique_id = f"{self.id}-valve" self._static_attrs = data[KEY_STATE][KEY_REPORTED_STATE] self._attr_is_on = KEY_CURRENT_STATUS in self._static_attrs - self._attr_device_info = DeviceInfo( - identifiers={ - ( - DOMAIN_RACHIO, - self.id, - ) - }, - connections={(dr.CONNECTION_NETWORK_MAC, self._base.mac_address)}, - manufacturer=DEFAULT_NAME, - model="Smart Hose Timer", - name=self._attr_name, - configuration_url="https://app.rach.io", - ) - - @property - def available(self) -> bool: - """Return if the valve is available.""" - return super().available and self._static_attrs[KEY_CONNECTED] def turn_on(self, **kwargs: Any) -> None: """Turn on this valve.""" @@ -594,20 +565,19 @@ class RachioValve(CoordinatorEntity[RachioUpdateCoordinator], SwitchEntity): self._base.start_watering(self.id, manual_run_time.seconds) self._attr_is_on = True self.schedule_update_ha_state(force_refresh=True) - _LOGGER.debug("Starting valve %s for %s", self.name, str(manual_run_time)) + _LOGGER.debug("Starting valve %s for %s", self._name, str(manual_run_time)) def turn_off(self, **kwargs: Any) -> None: """Turn off this valve.""" self._base.stop_watering(self.id) self._attr_is_on = False self.schedule_update_ha_state(force_refresh=True) - _LOGGER.debug("Stopping watering on valve %s", self.name) + _LOGGER.debug("Stopping watering on valve %s", self._name) @callback - def _handle_coordinator_update(self) -> None: + def _update_attr(self) -> None: """Handle updated coordinator data.""" data = self.coordinator.data[self.id] self._static_attrs = data[KEY_STATE][KEY_REPORTED_STATE] self._attr_is_on = KEY_CURRENT_STATUS in self._static_attrs - super()._handle_coordinator_update()