Move RainMachine services to entity services (#44139)

This commit is contained in:
Aaron Bach 2021-01-04 12:01:14 -07:00 committed by GitHub
parent cd756f20b1
commit 7657a5c901
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 140 additions and 119 deletions

View File

@ -6,7 +6,6 @@ from functools import partial
from regenmaschine import Client
from regenmaschine.controller import Controller
from regenmaschine.errors import RainMachineError
import voluptuous as vol
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
@ -16,10 +15,9 @@ from homeassistant.const import (
CONF_PORT,
CONF_SSL,
)
from homeassistant.core import HomeAssistant, ServiceCall, callback
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import aiohttp_client, config_validation as cv
from homeassistant.helpers.service import verify_domain_control
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
DataUpdateCoordinator,
@ -35,15 +33,10 @@ from .const import (
DATA_RESTRICTIONS_CURRENT,
DATA_RESTRICTIONS_UNIVERSAL,
DATA_ZONES,
DEFAULT_ZONE_RUN,
DOMAIN,
LOGGER,
)
CONF_PROGRAM_ID = "program_id"
CONF_SECONDS = "seconds"
CONF_ZONE_ID = "zone_id"
DATA_LISTENER = "listener"
DEFAULT_ATTRIBUTION = "Data provided by Green Electronics LLC"
@ -51,29 +44,6 @@ DEFAULT_ICON = "mdi:water"
DEFAULT_SSL = True
DEFAULT_UPDATE_INTERVAL = timedelta(seconds=15)
SERVICE_ALTER_PROGRAM = vol.Schema({vol.Required(CONF_PROGRAM_ID): cv.positive_int})
SERVICE_ALTER_ZONE = vol.Schema({vol.Required(CONF_ZONE_ID): cv.positive_int})
SERVICE_PAUSE_WATERING = vol.Schema({vol.Required(CONF_SECONDS): cv.positive_int})
SERVICE_START_PROGRAM_SCHEMA = vol.Schema(
{vol.Required(CONF_PROGRAM_ID): cv.positive_int}
)
SERVICE_START_ZONE_SCHEMA = vol.Schema(
{
vol.Required(CONF_ZONE_ID): cv.positive_int,
vol.Optional(CONF_ZONE_RUN_TIME, default=DEFAULT_ZONE_RUN): cv.positive_int,
}
)
SERVICE_STOP_PROGRAM_SCHEMA = vol.Schema(
{vol.Required(CONF_PROGRAM_ID): cv.positive_int}
)
SERVICE_STOP_ZONE_SCHEMA = vol.Schema({vol.Required(CONF_ZONE_ID): cv.positive_int})
CONFIG_SCHEMA = cv.deprecated(DOMAIN)
PLATFORMS = ["binary_sensor", "sensor", "switch"]
@ -125,8 +95,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
if entry_updates:
hass.config_entries.async_update_entry(entry, **entry_updates)
_verify_domain_control = verify_domain_control(hass, DOMAIN)
websession = aiohttp_client.async_get_clientsession(hass)
client = Client(session=websession)
@ -192,92 +160,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass.config_entries.async_forward_entry_setup(entry, component)
)
@_verify_domain_control
async def disable_program(call: ServiceCall):
"""Disable a program."""
await controller.programs.disable(call.data[CONF_PROGRAM_ID])
await async_update_programs_and_zones(hass, entry)
@_verify_domain_control
async def disable_zone(call: ServiceCall):
"""Disable a zone."""
await controller.zones.disable(call.data[CONF_ZONE_ID])
await async_update_programs_and_zones(hass, entry)
@_verify_domain_control
async def enable_program(call: ServiceCall):
"""Enable a program."""
await controller.programs.enable(call.data[CONF_PROGRAM_ID])
await async_update_programs_and_zones(hass, entry)
@_verify_domain_control
async def enable_zone(call: ServiceCall):
"""Enable a zone."""
await controller.zones.enable(call.data[CONF_ZONE_ID])
await async_update_programs_and_zones(hass, entry)
@_verify_domain_control
async def pause_watering(call: ServiceCall):
"""Pause watering for a set number of seconds."""
await controller.watering.pause_all(call.data[CONF_SECONDS])
await async_update_programs_and_zones(hass, entry)
@_verify_domain_control
async def start_program(call: ServiceCall):
"""Start a particular program."""
await controller.programs.start(call.data[CONF_PROGRAM_ID])
await async_update_programs_and_zones(hass, entry)
@_verify_domain_control
async def start_zone(call: ServiceCall):
"""Start a particular zone for a certain amount of time."""
await controller.zones.start(
call.data[CONF_ZONE_ID], call.data[CONF_ZONE_RUN_TIME]
)
await async_update_programs_and_zones(hass, entry)
@_verify_domain_control
async def stop_all(call: ServiceCall):
"""Stop all watering."""
await controller.watering.stop_all()
await async_update_programs_and_zones(hass, entry)
@_verify_domain_control
async def stop_program(call: ServiceCall):
"""Stop a program."""
await controller.programs.stop(call.data[CONF_PROGRAM_ID])
await async_update_programs_and_zones(hass, entry)
@_verify_domain_control
async def stop_zone(call: ServiceCall):
"""Stop a zone."""
await controller.zones.stop(call.data[CONF_ZONE_ID])
await async_update_programs_and_zones(hass, entry)
@_verify_domain_control
async def unpause_watering(call: ServiceCall):
"""Unpause watering."""
await controller.watering.unpause_all()
await async_update_programs_and_zones(hass, entry)
for service, method, schema in [
("disable_program", disable_program, SERVICE_ALTER_PROGRAM),
("disable_zone", disable_zone, SERVICE_ALTER_ZONE),
("enable_program", enable_program, SERVICE_ALTER_PROGRAM),
("enable_zone", enable_zone, SERVICE_ALTER_ZONE),
("pause_watering", pause_watering, SERVICE_PAUSE_WATERING),
("start_program", start_program, SERVICE_START_PROGRAM_SCHEMA),
("start_zone", start_zone, SERVICE_START_ZONE_SCHEMA),
("stop_all", stop_all, {}),
("stop_program", stop_program, SERVICE_STOP_PROGRAM_SCHEMA),
("stop_zone", stop_zone, SERVICE_STOP_ZONE_SCHEMA),
("unpause_watering", unpause_watering, {}),
]:
hass.services.async_register(DOMAIN, service, method, schema=schema)
hass.data[DOMAIN][DATA_LISTENER][entry.entry_id] = entry.add_update_listener(
async_reload_entry
)
hass.data[DOMAIN][DATA_LISTENER] = entry.add_update_listener(async_reload_entry)
return True

View File

@ -2,42 +2,63 @@
disable_program:
description: Disable a program.
fields:
entity_id:
description: An entity from the desired RainMachine controller
example: switch.zone_1
program_id:
description: The program to disable.
example: 3
disable_zone:
description: Disable a zone.
fields:
entity_id:
description: An entity from the desired RainMachine controller
example: switch.zone_1
zone_id:
description: The zone to disable.
example: 3
enable_program:
description: Enable a program.
fields:
entity_id:
description: An entity from the desired RainMachine controller
example: switch.zone_1
program_id:
description: The program to enable.
example: 3
enable_zone:
description: Enable a zone.
fields:
entity_id:
description: An entity from the desired RainMachine controller
example: switch.zone_1
zone_id:
description: The zone to enable.
example: 3
pause_watering:
description: Pause all watering for a number of seconds.
fields:
entity_id:
description: An entity from the desired RainMachine controller
example: switch.zone_1
seconds:
description: The number of seconds to pause.
example: 30
start_program:
description: Start a program.
fields:
entity_id:
description: An entity from the desired RainMachine controller
example: switch.zone_1
program_id:
description: The program to start.
example: 3
start_zone:
description: Start a zone for a set number of seconds.
fields:
entity_id:
description: An entity from the desired RainMachine controller
example: switch.zone_1
zone_id:
description: The zone to start.
example: 3
@ -46,17 +67,31 @@ start_zone:
example: 120
stop_all:
description: Stop all watering activities.
fields:
entity_id:
description: An entity from the desired RainMachine controller
example: switch.zone_1
stop_program:
description: Stop a program.
fields:
entity_id:
description: An entity from the desired RainMachine controller
example: switch.zone_1
program_id:
description: The program to stop.
example: 3
stop_zone:
description: Stop a zone.
fields:
entity_id:
description: An entity from the desired RainMachine controller
example: switch.zone_1
zone_id:
description: The zone to stop.
example: 3
unpause_watering:
description: Unpause all watering.
fields:
entity_id:
description: An entity from the desired RainMachine controller
example: switch.zone_1

View File

@ -4,11 +4,13 @@ from typing import Callable, Coroutine
from regenmaschine.controller import Controller
from regenmaschine.errors import RequestError
import voluptuous as vol
from homeassistant.components.switch import SwitchEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_ID
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import config_validation as cv, entity_platform
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from . import RainMachineEntity, async_update_programs_and_zones
@ -18,6 +20,7 @@ from .const import (
DATA_COORDINATOR,
DATA_PROGRAMS,
DATA_ZONES,
DEFAULT_ZONE_RUN,
DOMAIN,
LOGGER,
)
@ -43,6 +46,10 @@ ATTR_TIME_REMAINING = "time_remaining"
ATTR_VEGETATION_TYPE = "vegetation_type"
ATTR_ZONES = "zones"
CONF_PROGRAM_ID = "program_id"
CONF_SECONDS = "seconds"
CONF_ZONE_ID = "zone_id"
DAYS = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
RUN_STATUS_MAP = {0: "Not Running", 1: "Running", 2: "Queued"}
@ -103,6 +110,47 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: Callable
) -> None:
"""Set up RainMachine switches based on a config entry."""
platform = entity_platform.current_platform.get()
alter_program_schema = {vol.Required(CONF_PROGRAM_ID): cv.positive_int}
alter_zone_schema = {vol.Required(CONF_ZONE_ID): cv.positive_int}
for service_name, schema, method in [
("disable_program", alter_program_schema, "async_disable_program"),
("disable_zone", alter_zone_schema, "async_disable_zone"),
("enable_program", alter_program_schema, "async_enable_program"),
("enable_zone", alter_zone_schema, "async_enable_zone"),
(
"pause_watering",
{vol.Required(CONF_SECONDS): cv.positive_int},
"async_pause_watering",
),
(
"start_program",
{vol.Required(CONF_PROGRAM_ID): cv.positive_int},
"async_start_program",
),
(
"start_zone",
{
vol.Required(CONF_ZONE_ID): cv.positive_int,
vol.Optional(
CONF_ZONE_RUN_TIME, default=DEFAULT_ZONE_RUN
): cv.positive_int,
},
"async_start_zone",
),
("stop_all", {}, "async_stop_all"),
(
"stop_program",
{vol.Required(CONF_PROGRAM_ID): cv.positive_int},
"async_stop_program",
),
("stop_zone", {vol.Required(CONF_ZONE_ID): cv.positive_int}, "async_stop_zone"),
("unpause_watering", {}, "async_unpause_watering"),
]:
platform.async_register_entity_service(service_name, schema, method)
controller = hass.data[DOMAIN][DATA_CONTROLLER][entry.entry_id]
programs_coordinator = hass.data[DOMAIN][DATA_COORDINATOR][entry.entry_id][
DATA_PROGRAMS
@ -193,6 +241,61 @@ class RainMachineSwitch(RainMachineEntity, SwitchEntity):
async_update_programs_and_zones(self.hass, self._entry)
)
async def async_disable_program(self, *, program_id):
"""Disable a program."""
await self._controller.programs.disable(program_id)
await async_update_programs_and_zones(self.hass, self._entry)
async def async_disable_zone(self, *, zone_id):
"""Disable a zone."""
await self._controller.zones.disable(zone_id)
await async_update_programs_and_zones(self.hass, self._entry)
async def async_enable_program(self, *, program_id):
"""Enable a program."""
await self._controller.programs.enable(program_id)
await async_update_programs_and_zones(self.hass, self._entry)
async def async_enable_zone(self, *, zone_id):
"""Enable a zone."""
await self._controller.zones.enable(zone_id)
await async_update_programs_and_zones(self.hass, self._entry)
async def async_pause_watering(self, *, seconds):
"""Pause watering for a set number of seconds."""
await self._controller.watering.pause_all(seconds)
await async_update_programs_and_zones(self.hass, self._entry)
async def async_start_program(self, *, program_id):
"""Start a particular program."""
await self._controller.programs.start(program_id)
await async_update_programs_and_zones(self.hass, self._entry)
async def async_start_zone(self, *, zone_id, zone_run_time):
"""Start a particular zone for a certain amount of time."""
await self._controller.zones.start(zone_id, zone_run_time)
await async_update_programs_and_zones(self.hass, self._entry)
async def async_stop_all(self):
"""Stop all watering."""
await self._controller.watering.stop_all()
await async_update_programs_and_zones(self.hass, self._entry)
async def async_stop_program(self, *, program_id):
"""Stop a program."""
await self._controller.programs.stop(program_id)
await async_update_programs_and_zones(self.hass, self._entry)
async def async_stop_zone(self, *, zone_id):
"""Stop a zone."""
await self._controller.zones.stop(zone_id)
await async_update_programs_and_zones(self.hass, self._entry)
async def async_unpause_watering(self):
"""Unpause watering."""
await self._controller.watering.unpause_all()
await async_update_programs_and_zones(self.hass, self._entry)
@callback
def update_from_latest_data(self) -> None:
"""Update the state."""