Replace two RainMachine binary sensors with config switches (#76478)

This commit is contained in:
Aaron Bach 2022-09-23 17:05:07 -06:00 committed by GitHub
parent a495df9759
commit 55b214c911
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 112 additions and 9 deletions

View file

@ -2,6 +2,7 @@
from dataclasses import dataclass
from homeassistant.components.binary_sensor import (
DOMAIN as BINARY_SENSOR_DOMAIN,
BinarySensorEntity,
BinarySensorEntityDescription,
)
@ -21,7 +22,11 @@ from .model import (
RainMachineEntityDescription,
RainMachineEntityDescriptionMixinDataKey,
)
from .util import key_exists
from .util import (
EntityDomainReplacementStrategy,
async_finish_entity_domain_replacements,
key_exists,
)
TYPE_FLOW_SENSOR = "flow_sensor"
TYPE_FREEZE = "freeze"
@ -125,6 +130,27 @@ async def async_setup_entry(
"""Set up RainMachine binary sensors based on a config entry."""
data: RainMachineData = hass.data[DOMAIN][entry.entry_id]
async_finish_entity_domain_replacements(
hass,
entry,
(
EntityDomainReplacementStrategy(
BINARY_SENSOR_DOMAIN,
f"{data.controller.mac}_freeze_protection",
f"switch.{data.controller.name.lower()}_freeze_protect_enabled",
breaks_in_ha_version="2022.12.0",
remove_old_entity=False,
),
EntityDomainReplacementStrategy(
BINARY_SENSOR_DOMAIN,
f"{data.controller.mac}_extra_water_on_hot_days",
f"switch.{data.controller.name.lower()}_hot_days_extra_watering",
breaks_in_ha_version="2022.12.0",
remove_old_entity=False,
),
),
)
api_category_sensor_map = {
DATA_PROVISION_SETTINGS: ProvisionSettingsBinarySensor,
DATA_RESTRICTIONS_CURRENT: CurrentRestrictionsBinarySensor,

View file

@ -24,11 +24,16 @@ from . import RainMachineData, RainMachineEntity, async_update_programs_and_zone
from .const import (
CONF_ZONE_RUN_TIME,
DATA_PROGRAMS,
DATA_RESTRICTIONS_UNIVERSAL,
DATA_ZONES,
DEFAULT_ZONE_RUN,
DOMAIN,
)
from .model import RainMachineEntityDescription, RainMachineEntityDescriptionMixinUid
from .model import (
RainMachineEntityDescription,
RainMachineEntityDescriptionMixinDataKey,
RainMachineEntityDescriptionMixinUid,
)
from .util import RUN_STATE_MAP
ATTR_AREA = "area"
@ -130,11 +135,45 @@ def raise_on_request_error(
class RainMachineSwitchDescription(
SwitchEntityDescription,
RainMachineEntityDescription,
RainMachineEntityDescriptionMixinUid,
):
"""Describe a RainMachine switch."""
@dataclass
class RainMachineActivitySwitchDescription(
RainMachineSwitchDescription, RainMachineEntityDescriptionMixinUid
):
"""Describe a RainMachine activity (program/zone) switch."""
@dataclass
class RainMachineRestrictionSwitchDescription(
RainMachineSwitchDescription, RainMachineEntityDescriptionMixinDataKey
):
"""Describe a RainMachine restriction switch."""
TYPE_RESTRICTIONS_FREEZE_PROTECT_ENABLED = "freeze_protect_enabled"
TYPE_RESTRICTIONS_HOT_DAYS_EXTRA_WATERING = "hot_days_extra_watering"
RESTRICTIONS_SWITCH_DESCRIPTIONS = (
RainMachineRestrictionSwitchDescription(
key=TYPE_RESTRICTIONS_FREEZE_PROTECT_ENABLED,
name="Freeze protection",
icon="mdi:snowflake-alert",
api_category=DATA_RESTRICTIONS_UNIVERSAL,
data_key="freezeProtectEnabled",
),
RainMachineRestrictionSwitchDescription(
key=TYPE_RESTRICTIONS_HOT_DAYS_EXTRA_WATERING,
name="Extra water on hot days",
icon="mdi:heat-wave",
api_category=DATA_RESTRICTIONS_UNIVERSAL,
data_key="hotDaysExtraWatering",
),
)
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
@ -158,8 +197,8 @@ async def async_setup_entry(
platform.async_register_entity_service(service_name, schema, method)
data: RainMachineData = hass.data[DOMAIN][entry.entry_id]
entities: list[RainMachineBaseSwitch] = []
entities: list[RainMachineActivitySwitch | RainMachineEnabledSwitch] = []
for kind, api_category, switch_class, switch_enabled_class in (
("program", DATA_PROGRAMS, RainMachineProgram, RainMachineProgramEnabled),
("zone", DATA_ZONES, RainMachineZone, RainMachineZoneEnabled),
@ -173,10 +212,9 @@ async def async_setup_entry(
switch_class(
entry,
data,
RainMachineSwitchDescription(
RainMachineActivitySwitchDescription(
key=f"{kind}_{uid}",
name=name,
icon="mdi:water",
api_category=api_category,
uid=uid,
),
@ -188,17 +226,19 @@ async def async_setup_entry(
switch_enabled_class(
entry,
data,
RainMachineSwitchDescription(
RainMachineActivitySwitchDescription(
key=f"{kind}_{uid}_enabled",
name=f"{name} enabled",
entity_category=EntityCategory.CONFIG,
icon="mdi:cog",
api_category=api_category,
uid=uid,
),
)
)
# Add switches to control restrictions:
for description in RESTRICTIONS_SWITCH_DESCRIPTIONS:
entities.append(RainMachineRestrictionSwitch(entry, data, description))
async_add_entities(entities)
@ -246,6 +286,9 @@ class RainMachineBaseSwitch(RainMachineEntity, SwitchEntity):
class RainMachineActivitySwitch(RainMachineBaseSwitch):
"""Define a RainMachine switch to start/stop an activity (program or zone)."""
_attr_icon = "mdi:water"
entity_description: RainMachineActivitySwitchDescription
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the switch off.
@ -284,6 +327,10 @@ class RainMachineActivitySwitch(RainMachineBaseSwitch):
class RainMachineEnabledSwitch(RainMachineBaseSwitch):
"""Define a RainMachine switch to enable/disable an activity (program or zone)."""
_attr_entity_category = EntityCategory.CONFIG
_attr_icon = "mdi:cog"
entity_description: RainMachineActivitySwitchDescription
@callback
def update_from_latest_data(self) -> None:
"""Update the entity when new data is received."""
@ -360,6 +407,36 @@ class RainMachineProgramEnabled(RainMachineEnabledSwitch):
self._update_activities()
class RainMachineRestrictionSwitch(RainMachineBaseSwitch):
"""Define a RainMachine restriction setting."""
_attr_entity_category = EntityCategory.CONFIG
entity_description: RainMachineRestrictionSwitchDescription
@raise_on_request_error
async def async_turn_off(self, **kwargs: Any) -> None:
"""Disable the restriction."""
await self._data.controller.restrictions.set_universal(
{self.entity_description.data_key: False}
)
self._attr_is_on = False
self.async_write_ha_state()
@raise_on_request_error
async def async_turn_on(self, **kwargs: Any) -> None:
"""Enable the restriction."""
await self._data.controller.restrictions.set_universal(
{self.entity_description.data_key: True}
)
self._attr_is_on = True
self.async_write_ha_state()
@callback
def update_from_latest_data(self) -> None:
"""Update the entity when new data is received."""
self._attr_is_on = self.coordinator.data[self.entity_description.data_key]
class RainMachineZone(RainMachineActivitySwitch):
"""Define a RainMachine zone."""