diff --git a/homeassistant/components/hydrawise/__init__.py b/homeassistant/components/hydrawise/__init__.py index 1f1b2c03157..56ebdc0d88c 100644 --- a/homeassistant/components/hydrawise/__init__.py +++ b/homeassistant/components/hydrawise/__init__.py @@ -6,22 +6,11 @@ from hydrawiser.core import Hydrawiser from requests.exceptions import ConnectTimeout, HTTPError import voluptuous as vol -from homeassistant.components.binary_sensor import ( - DEVICE_CLASS_CONNECTIVITY, - DEVICE_CLASS_MOISTURE, -) -from homeassistant.components.sensor import DEVICE_CLASS_TIMESTAMP -from homeassistant.components.switch import DEVICE_CLASS_SWITCH -from homeassistant.const import ( - ATTR_ATTRIBUTION, - CONF_ACCESS_TOKEN, - CONF_SCAN_INTERVAL, - TIME_MINUTES, -) +from homeassistant.const import ATTR_ATTRIBUTION, CONF_ACCESS_TOKEN, CONF_SCAN_INTERVAL from homeassistant.core import callback import homeassistant.helpers.config_validation as cv from homeassistant.helpers.dispatcher import async_dispatcher_connect, dispatcher_send -from homeassistant.helpers.entity import Entity +from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.event import track_time_interval _LOGGER = logging.getLogger(__name__) @@ -39,27 +28,6 @@ DATA_HYDRAWISE = "hydrawise" DOMAIN = "hydrawise" DEFAULT_WATERING_TIME = 15 -DEVICE_MAP_INDEX = [ - "KEY_INDEX", - "ICON_INDEX", - "DEVICE_CLASS_INDEX", - "UNIT_OF_MEASURE_INDEX", -] -DEVICE_MAP = { - "auto_watering": ["Automatic Watering", None, DEVICE_CLASS_SWITCH, None], - "is_watering": ["Watering", None, DEVICE_CLASS_MOISTURE, None], - "manual_watering": ["Manual Watering", None, DEVICE_CLASS_SWITCH, None], - "next_cycle": ["Next Cycle", None, DEVICE_CLASS_TIMESTAMP, None], - "status": ["Status", None, DEVICE_CLASS_CONNECTIVITY, None], - "watering_time": ["Watering Time", "mdi:water-pump", None, TIME_MINUTES], -} - -BINARY_SENSORS = ["is_watering", "status"] - -SENSORS = ["next_cycle", "watering_time"] - -SWITCHES = ["auto_watering", "manual_watering"] - SCAN_INTERVAL = timedelta(seconds=30) SIGNAL_UPDATE_HYDRAWISE = "hydrawise_update" @@ -118,17 +86,11 @@ class HydrawiseHub: class HydrawiseEntity(Entity): """Entity class for Hydrawise devices.""" - def __init__(self, data, sensor_type): + def __init__(self, data, description: EntityDescription): """Initialize the Hydrawise entity.""" + self.entity_description = description self.data = data - self._sensor_type = sensor_type - self._name = f"{self.data['name']} {DEVICE_MAP[self._sensor_type][DEVICE_MAP_INDEX.index('KEY_INDEX')]}" - self._state = None - - @property - def name(self): - """Return the name of the sensor.""" - return self._name + self._attr_name = f"{self.data['name']} {description.name}" async def async_added_to_hass(self): """Register callbacks.""" @@ -147,15 +109,3 @@ class HydrawiseEntity(Entity): def extra_state_attributes(self): """Return the state attributes.""" return {ATTR_ATTRIBUTION: ATTRIBUTION, "identifier": self.data.get("relay")} - - @property - def device_class(self): - """Return the device class of the sensor type.""" - return DEVICE_MAP[self._sensor_type][ - DEVICE_MAP_INDEX.index("DEVICE_CLASS_INDEX") - ] - - @property - def icon(self): - """Return the icon to use in the frontend, if any.""" - return DEVICE_MAP[self._sensor_type][DEVICE_MAP_INDEX.index("ICON_INDEX")] diff --git a/homeassistant/components/hydrawise/binary_sensor.py b/homeassistant/components/hydrawise/binary_sensor.py index e39ffce73a9..7a673a1e7ae 100644 --- a/homeassistant/components/hydrawise/binary_sensor.py +++ b/homeassistant/components/hydrawise/binary_sensor.py @@ -1,20 +1,46 @@ """Support for Hydrawise sprinkler binary sensors.""" +from __future__ import annotations + import logging import voluptuous as vol -from homeassistant.components.binary_sensor import PLATFORM_SCHEMA, BinarySensorEntity +from homeassistant.components.binary_sensor import ( + DEVICE_CLASS_CONNECTIVITY, + DEVICE_CLASS_MOISTURE, + PLATFORM_SCHEMA, + BinarySensorEntity, + BinarySensorEntityDescription, +) from homeassistant.const import CONF_MONITORED_CONDITIONS import homeassistant.helpers.config_validation as cv -from . import BINARY_SENSORS, DATA_HYDRAWISE, HydrawiseEntity +from . import DATA_HYDRAWISE, HydrawiseEntity _LOGGER = logging.getLogger(__name__) +BINARY_SENSOR_STATUS = BinarySensorEntityDescription( + key="status", + name="Status", + device_class=DEVICE_CLASS_CONNECTIVITY, +) + +BINARY_SENSOR_TYPES: tuple[BinarySensorEntityDescription, ...] = ( + BinarySensorEntityDescription( + key="is_watering", + name="Watering", + device_class=DEVICE_CLASS_MOISTURE, + ), +) + +BINARY_SENSOR_KEYS: list[str] = [ + desc.key for desc in (BINARY_SENSOR_STATUS, *BINARY_SENSOR_TYPES) +] + PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { - vol.Optional(CONF_MONITORED_CONDITIONS, default=BINARY_SENSORS): vol.All( - cv.ensure_list, [vol.In(BINARY_SENSORS)] + vol.Optional(CONF_MONITORED_CONDITIONS, default=BINARY_SENSOR_KEYS): vol.All( + cv.ensure_list, [vol.In(BINARY_SENSOR_KEYS)] ) } ) @@ -23,35 +49,36 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( def setup_platform(hass, config, add_entities, discovery_info=None): """Set up a sensor for a Hydrawise device.""" hydrawise = hass.data[DATA_HYDRAWISE].data + monitored_conditions = config[CONF_MONITORED_CONDITIONS] - sensors = [] - for sensor_type in config.get(CONF_MONITORED_CONDITIONS): - if sensor_type == "status": - sensors.append( - HydrawiseBinarySensor(hydrawise.current_controller, sensor_type) - ) - else: - # create a sensor for each zone - for zone in hydrawise.relays: - sensors.append(HydrawiseBinarySensor(zone, sensor_type)) + entities = [] + if BINARY_SENSOR_STATUS.key in monitored_conditions: + entities.append( + HydrawiseBinarySensor(hydrawise.current_controller, BINARY_SENSOR_STATUS) + ) - add_entities(sensors, True) + # create a sensor for each zone + entities.extend( + [ + HydrawiseBinarySensor(zone, description) + for zone in hydrawise.relays + for description in BINARY_SENSOR_TYPES + if description.key in monitored_conditions + ] + ) + + add_entities(entities, True) class HydrawiseBinarySensor(HydrawiseEntity, BinarySensorEntity): """A sensor implementation for Hydrawise device.""" - @property - def is_on(self): - """Return true if the binary sensor is on.""" - return self._state - def update(self): """Get the latest data and updates the state.""" - _LOGGER.debug("Updating Hydrawise binary sensor: %s", self._name) + _LOGGER.debug("Updating Hydrawise binary sensor: %s", self.name) mydata = self.hass.data[DATA_HYDRAWISE].data - if self._sensor_type == "status": - self._state = mydata.status == "All good!" - elif self._sensor_type == "is_watering": + if self.entity_description.key == "status": + self._attr_is_on = mydata.status == "All good!" + elif self.entity_description.key == "is_watering": relay_data = mydata.relays[self.data["relay"] - 1] - self._state = relay_data["timestr"] == "Now" + self._attr_is_on = relay_data["timestr"] == "Now" diff --git a/homeassistant/components/hydrawise/sensor.py b/homeassistant/components/hydrawise/sensor.py index 0e9afb6d729..f8c02309569 100644 --- a/homeassistant/components/hydrawise/sensor.py +++ b/homeassistant/components/hydrawise/sensor.py @@ -1,21 +1,47 @@ """Support for Hydrawise sprinkler sensors.""" +from __future__ import annotations + import logging import voluptuous as vol -from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity -from homeassistant.const import CONF_MONITORED_CONDITIONS +from homeassistant.components.sensor import ( + PLATFORM_SCHEMA, + SensorEntity, + SensorEntityDescription, +) +from homeassistant.const import ( + CONF_MONITORED_CONDITIONS, + DEVICE_CLASS_TIMESTAMP, + TIME_MINUTES, +) import homeassistant.helpers.config_validation as cv from homeassistant.util import dt -from . import DATA_HYDRAWISE, DEVICE_MAP, DEVICE_MAP_INDEX, SENSORS, HydrawiseEntity +from . import DATA_HYDRAWISE, HydrawiseEntity _LOGGER = logging.getLogger(__name__) +SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( + SensorEntityDescription( + key="next_cycle", + name="Next Cycle", + device_class=DEVICE_CLASS_TIMESTAMP, + ), + SensorEntityDescription( + key="watering_time", + name="Watering Time", + icon="mdi:water-pump", + native_unit_of_measurement=TIME_MINUTES, + ), +) + +SENSOR_KEYS: list[str] = [desc.key for desc in SENSOR_TYPES] + PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { - vol.Optional(CONF_MONITORED_CONDITIONS, default=SENSORS): vol.All( - cv.ensure_list, [vol.In(SENSORS)] + vol.Optional(CONF_MONITORED_CONDITIONS, default=SENSOR_KEYS): vol.All( + cv.ensure_list, [vol.In(SENSOR_KEYS)] ) } ) @@ -27,43 +53,34 @@ WATERING_TIME_ICON = "mdi:water-pump" def setup_platform(hass, config, add_entities, discovery_info=None): """Set up a sensor for a Hydrawise device.""" hydrawise = hass.data[DATA_HYDRAWISE].data + monitored_conditions = config[CONF_MONITORED_CONDITIONS] - sensors = [] - for sensor_type in config.get(CONF_MONITORED_CONDITIONS): - for zone in hydrawise.relays: - sensors.append(HydrawiseSensor(zone, sensor_type)) + entities = [ + HydrawiseSensor(zone, description) + for zone in hydrawise.relays + for description in SENSOR_TYPES + if description.key in monitored_conditions + ] - add_entities(sensors, True) + add_entities(entities, True) class HydrawiseSensor(HydrawiseEntity, SensorEntity): """A sensor implementation for Hydrawise device.""" - @property - def native_value(self): - """Return the state of the sensor.""" - return self._state - - @property - def native_unit_of_measurement(self): - """Return the units of measurement.""" - return DEVICE_MAP[self._sensor_type][ - DEVICE_MAP_INDEX.index("UNIT_OF_MEASURE_INDEX") - ] - def update(self): """Get the latest data and updates the states.""" mydata = self.hass.data[DATA_HYDRAWISE].data - _LOGGER.debug("Updating Hydrawise sensor: %s", self._name) + _LOGGER.debug("Updating Hydrawise sensor: %s", self.name) relay_data = mydata.relays[self.data["relay"] - 1] - if self._sensor_type == "watering_time": + if self.entity_description.key == "watering_time": if relay_data["timestr"] == "Now": - self._state = int(relay_data["run"] / 60) + self._attr_native_value = int(relay_data["run"] / 60) else: - self._state = 0 + self._attr_native_value = 0 else: # _sensor_type == 'next_cycle' next_cycle = min(relay_data["time"], TWO_YEAR_SECONDS) _LOGGER.debug("New cycle time: %s", next_cycle) - self._state = dt.utc_from_timestamp( + self._attr_native_value = dt.utc_from_timestamp( dt.as_timestamp(dt.now()) + next_cycle ).isoformat() diff --git a/homeassistant/components/hydrawise/switch.py b/homeassistant/components/hydrawise/switch.py index a385e504d7f..8b3707ad5a0 100644 --- a/homeassistant/components/hydrawise/switch.py +++ b/homeassistant/components/hydrawise/switch.py @@ -1,9 +1,16 @@ """Support for Hydrawise cloud switches.""" +from __future__ import annotations + import logging import voluptuous as vol -from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity +from homeassistant.components.switch import ( + DEVICE_CLASS_SWITCH, + PLATFORM_SCHEMA, + SwitchEntity, + SwitchEntityDescription, +) from homeassistant.const import CONF_MONITORED_CONDITIONS import homeassistant.helpers.config_validation as cv @@ -12,16 +19,30 @@ from . import ( CONF_WATERING_TIME, DATA_HYDRAWISE, DEFAULT_WATERING_TIME, - SWITCHES, HydrawiseEntity, ) _LOGGER = logging.getLogger(__name__) +SWITCH_TYPES: tuple[SwitchEntityDescription, ...] = ( + SwitchEntityDescription( + key="auto_watering", + name="Automatic Watering", + device_class=DEVICE_CLASS_SWITCH, + ), + SwitchEntityDescription( + key="manual_watering", + name="Manual Watering", + device_class=DEVICE_CLASS_SWITCH, + ), +) + +SWITCH_KEYS: list[str] = [desc.key for desc in SWITCH_TYPES] + PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { - vol.Optional(CONF_MONITORED_CONDITIONS, default=SWITCHES): vol.All( - cv.ensure_list, [vol.In(SWITCHES)] + vol.Optional(CONF_MONITORED_CONDITIONS, default=SWITCH_KEYS): vol.All( + cv.ensure_list, [vol.In(SWITCH_KEYS)] ), vol.Optional(CONF_WATERING_TIME, default=DEFAULT_WATERING_TIME): vol.All( vol.In(ALLOWED_WATERING_TIME) @@ -33,57 +54,55 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( def setup_platform(hass, config, add_entities, discovery_info=None): """Set up a sensor for a Hydrawise device.""" hydrawise = hass.data[DATA_HYDRAWISE].data + monitored_conditions = config[CONF_MONITORED_CONDITIONS] + default_watering_timer = config[CONF_WATERING_TIME] - default_watering_timer = config.get(CONF_WATERING_TIME) + entities = [ + HydrawiseSwitch(zone, description, default_watering_timer) + for zone in hydrawise.relays + for description in SWITCH_TYPES + if description.key in monitored_conditions + ] - sensors = [] - for sensor_type in config.get(CONF_MONITORED_CONDITIONS): - # Create a switch for each zone - for zone in hydrawise.relays: - sensors.append(HydrawiseSwitch(default_watering_timer, zone, sensor_type)) - - add_entities(sensors, True) + add_entities(entities, True) class HydrawiseSwitch(HydrawiseEntity, SwitchEntity): """A switch implementation for Hydrawise device.""" - def __init__(self, default_watering_timer, *args): + def __init__( + self, data, description: SwitchEntityDescription, default_watering_timer + ): """Initialize a switch for Hydrawise device.""" - super().__init__(*args) + super().__init__(data, description) self._default_watering_timer = default_watering_timer - @property - def is_on(self): - """Return true if device is on.""" - return self._state - def turn_on(self, **kwargs): """Turn the device on.""" relay_data = self.data["relay"] - 1 - if self._sensor_type == "manual_watering": + if self.entity_description.key == "manual_watering": self.hass.data[DATA_HYDRAWISE].data.run_zone( self._default_watering_timer, relay_data ) - elif self._sensor_type == "auto_watering": + elif self.entity_description.key == "auto_watering": self.hass.data[DATA_HYDRAWISE].data.suspend_zone(0, relay_data) def turn_off(self, **kwargs): """Turn the device off.""" relay_data = self.data["relay"] - 1 - if self._sensor_type == "manual_watering": + if self.entity_description.key == "manual_watering": self.hass.data[DATA_HYDRAWISE].data.run_zone(0, relay_data) - elif self._sensor_type == "auto_watering": + elif self.entity_description.key == "auto_watering": self.hass.data[DATA_HYDRAWISE].data.suspend_zone(365, relay_data) def update(self): """Update device state.""" relay_data = self.data["relay"] - 1 mydata = self.hass.data[DATA_HYDRAWISE].data - _LOGGER.debug("Updating Hydrawise switch: %s", self._name) - if self._sensor_type == "manual_watering": - self._state = mydata.relays[relay_data]["timestr"] == "Now" - elif self._sensor_type == "auto_watering": - self._state = (mydata.relays[relay_data]["timestr"] != "") and ( + _LOGGER.debug("Updating Hydrawise switch: %s", self.name) + if self.entity_description.key == "manual_watering": + self._attr_is_on = mydata.relays[relay_data]["timestr"] == "Now" + elif self.entity_description.key == "auto_watering": + self._attr_is_on = (mydata.relays[relay_data]["timestr"] != "") and ( mydata.relays[relay_data]["timestr"] != "Now" )