Add super chlorination services to screenlogic (#108048)
Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
parent
134cc78400
commit
02f7165ca5
5 changed files with 133 additions and 33 deletions
|
@ -56,14 +56,14 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
hass, config_entry=entry, gateway=gateway
|
||||
)
|
||||
|
||||
async_load_screenlogic_services(hass)
|
||||
|
||||
await coordinator.async_config_entry_first_refresh()
|
||||
|
||||
entry.async_on_unload(entry.add_update_listener(async_update_listener))
|
||||
|
||||
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator
|
||||
|
||||
async_load_screenlogic_services(hass, entry)
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
|
||||
return True
|
||||
|
|
|
@ -24,6 +24,13 @@ SERVICE_SET_COLOR_MODE = "set_color_mode"
|
|||
ATTR_COLOR_MODE = "color_mode"
|
||||
SUPPORTED_COLOR_MODES = {slugify(cm.name): cm.value for cm in COLOR_MODE}
|
||||
|
||||
SERVICE_START_SUPER_CHLORINATION = "start_super_chlorination"
|
||||
ATTR_RUNTIME = "runtime"
|
||||
MAX_RUNTIME = 72
|
||||
MIN_RUNTIME = 0
|
||||
|
||||
SERVICE_STOP_SUPER_CHLORINATION = "stop_super_chlorination"
|
||||
|
||||
LIGHT_CIRCUIT_FUNCTIONS = {
|
||||
FUNCTION.COLOR_WHEEL,
|
||||
FUNCTION.DIMMER,
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
import logging
|
||||
|
||||
from screenlogicpy import ScreenLogicError
|
||||
from screenlogicpy.device_const.system import EQUIPMENT_FLAG
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant, ServiceCall, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
@ -12,10 +14,16 @@ from homeassistant.helpers.service import async_extract_config_entry_ids
|
|||
|
||||
from .const import (
|
||||
ATTR_COLOR_MODE,
|
||||
ATTR_RUNTIME,
|
||||
DOMAIN,
|
||||
MAX_RUNTIME,
|
||||
MIN_RUNTIME,
|
||||
SERVICE_SET_COLOR_MODE,
|
||||
SERVICE_START_SUPER_CHLORINATION,
|
||||
SERVICE_STOP_SUPER_CHLORINATION,
|
||||
SUPPORTED_COLOR_MODES,
|
||||
)
|
||||
from .coordinator import ScreenlogicDataUpdateCoordinator
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -25,35 +33,38 @@ SET_COLOR_MODE_SCHEMA = cv.make_entity_service_schema(
|
|||
},
|
||||
)
|
||||
|
||||
TURN_ON_SUPER_CHLOR_SCHEMA = cv.make_entity_service_schema(
|
||||
{
|
||||
vol.Optional(ATTR_RUNTIME, default=24): vol.Clamp(
|
||||
min=MIN_RUNTIME, max=MAX_RUNTIME
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@callback
|
||||
def async_load_screenlogic_services(hass: HomeAssistant):
|
||||
def async_load_screenlogic_services(hass: HomeAssistant, entry: ConfigEntry):
|
||||
"""Set up services for the ScreenLogic integration."""
|
||||
if hass.services.has_service(DOMAIN, SERVICE_SET_COLOR_MODE):
|
||||
# Integration-level services have already been added. Return.
|
||||
return
|
||||
|
||||
async def extract_screenlogic_config_entry_ids(service_call: ServiceCall):
|
||||
return [
|
||||
entry_id
|
||||
for entry_id in await async_extract_config_entry_ids(hass, service_call)
|
||||
if (entry := hass.config_entries.async_get_entry(entry_id))
|
||||
and entry.domain == DOMAIN
|
||||
]
|
||||
|
||||
async def async_set_color_mode(service_call: ServiceCall) -> None:
|
||||
if not (
|
||||
screenlogic_entry_ids := await extract_screenlogic_config_entry_ids(
|
||||
service_call
|
||||
)
|
||||
screenlogic_entry_ids := [
|
||||
entry_id
|
||||
for entry_id in await async_extract_config_entry_ids(hass, service_call)
|
||||
if (entry := hass.config_entries.async_get_entry(entry_id))
|
||||
and entry.domain == DOMAIN
|
||||
]
|
||||
):
|
||||
raise HomeAssistantError(
|
||||
f"Failed to call service '{SERVICE_SET_COLOR_MODE}'. Config entry for"
|
||||
f"Failed to call service '{service_call.service}'. Config entry for"
|
||||
" target not found"
|
||||
)
|
||||
return screenlogic_entry_ids
|
||||
|
||||
async def async_set_color_mode(service_call: ServiceCall) -> None:
|
||||
color_num = SUPPORTED_COLOR_MODES[service_call.data[ATTR_COLOR_MODE]]
|
||||
for entry_id in screenlogic_entry_ids:
|
||||
coordinator = hass.data[DOMAIN][entry_id]
|
||||
for entry_id in await extract_screenlogic_config_entry_ids(service_call):
|
||||
coordinator: ScreenlogicDataUpdateCoordinator = hass.data[DOMAIN][entry_id]
|
||||
_LOGGER.debug(
|
||||
"Service %s called on %s with mode %s",
|
||||
SERVICE_SET_COLOR_MODE,
|
||||
|
@ -62,26 +73,77 @@ def async_load_screenlogic_services(hass: HomeAssistant):
|
|||
)
|
||||
try:
|
||||
await coordinator.gateway.async_set_color_lights(color_num)
|
||||
# Debounced refresh to catch any secondary
|
||||
# changes in the device
|
||||
# Debounced refresh to catch any secondary changes in the device
|
||||
await coordinator.async_request_refresh()
|
||||
except ScreenLogicError as error:
|
||||
raise HomeAssistantError(error) from error
|
||||
|
||||
hass.services.async_register(
|
||||
DOMAIN, SERVICE_SET_COLOR_MODE, async_set_color_mode, SET_COLOR_MODE_SCHEMA
|
||||
)
|
||||
async def async_set_super_chlor(
|
||||
service_call: ServiceCall,
|
||||
is_on: bool,
|
||||
runtime: int | None = None,
|
||||
) -> None:
|
||||
for entry_id in await extract_screenlogic_config_entry_ids(service_call):
|
||||
coordinator: ScreenlogicDataUpdateCoordinator = hass.data[DOMAIN][entry_id]
|
||||
_LOGGER.debug(
|
||||
"Service %s called on %s with runtime %s",
|
||||
SERVICE_START_SUPER_CHLORINATION,
|
||||
coordinator.gateway.name,
|
||||
runtime,
|
||||
)
|
||||
try:
|
||||
await coordinator.gateway.async_set_scg_config(
|
||||
super_chlor_timer=runtime, super_chlorinate=is_on
|
||||
)
|
||||
# Debounced refresh to catch any secondary changes in the device
|
||||
await coordinator.async_request_refresh()
|
||||
except ScreenLogicError as error:
|
||||
raise HomeAssistantError(error) from error
|
||||
|
||||
async def async_start_super_chlor(service_call: ServiceCall) -> None:
|
||||
runtime = service_call.data[ATTR_RUNTIME]
|
||||
await async_set_super_chlor(service_call, True, runtime)
|
||||
|
||||
async def async_stop_super_chlor(service_call: ServiceCall) -> None:
|
||||
await async_set_super_chlor(service_call, False)
|
||||
|
||||
if not hass.services.has_service(DOMAIN, SERVICE_SET_COLOR_MODE):
|
||||
hass.services.async_register(
|
||||
DOMAIN, SERVICE_SET_COLOR_MODE, async_set_color_mode, SET_COLOR_MODE_SCHEMA
|
||||
)
|
||||
|
||||
coordinator: ScreenlogicDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
||||
equipment_flags = coordinator.gateway.equipment_flags
|
||||
|
||||
if EQUIPMENT_FLAG.CHLORINATOR in equipment_flags:
|
||||
if not hass.services.has_service(DOMAIN, SERVICE_START_SUPER_CHLORINATION):
|
||||
hass.services.async_register(
|
||||
DOMAIN,
|
||||
SERVICE_START_SUPER_CHLORINATION,
|
||||
async_start_super_chlor,
|
||||
TURN_ON_SUPER_CHLOR_SCHEMA,
|
||||
)
|
||||
|
||||
if not hass.services.has_service(DOMAIN, SERVICE_STOP_SUPER_CHLORINATION):
|
||||
hass.services.async_register(
|
||||
DOMAIN,
|
||||
SERVICE_STOP_SUPER_CHLORINATION,
|
||||
async_stop_super_chlor,
|
||||
)
|
||||
|
||||
|
||||
@callback
|
||||
def async_unload_screenlogic_services(hass: HomeAssistant):
|
||||
"""Unload services for the ScreenLogic integration."""
|
||||
if hass.data[DOMAIN]:
|
||||
# There is still another config entry for this domain, don't remove services.
|
||||
return
|
||||
|
||||
if not hass.services.has_service(DOMAIN, SERVICE_SET_COLOR_MODE):
|
||||
return
|
||||
|
||||
_LOGGER.info("Unloading ScreenLogic Services")
|
||||
hass.services.async_remove(domain=DOMAIN, service=SERVICE_SET_COLOR_MODE)
|
||||
if not hass.data[DOMAIN]:
|
||||
_LOGGER.debug("Unloading all ScreenLogic services")
|
||||
for service in hass.services.async_services_for_domain(DOMAIN):
|
||||
hass.services.async_remove(DOMAIN, service)
|
||||
elif not any(
|
||||
EQUIPMENT_FLAG.CHLORINATOR in coordinator.gateway.equipment_flags
|
||||
for coordinator in hass.data[DOMAIN].values()
|
||||
):
|
||||
_LOGGER.debug("Unloading ScreenLogic chlorination services")
|
||||
hass.services.async_remove(DOMAIN, SERVICE_START_SUPER_CHLORINATION)
|
||||
hass.services.async_remove(DOMAIN, SERVICE_STOP_SUPER_CHLORINATION)
|
||||
|
|
|
@ -31,3 +31,20 @@ set_color_mode:
|
|||
- sunset
|
||||
- thumper
|
||||
- white
|
||||
start_super_chlorination:
|
||||
target:
|
||||
device:
|
||||
integration: screenlogic
|
||||
fields:
|
||||
runtime:
|
||||
default: 24
|
||||
selector:
|
||||
number:
|
||||
min: 0
|
||||
max: 72
|
||||
unit_of_measurement: hours
|
||||
mode: slider
|
||||
stop_super_chlorination:
|
||||
target:
|
||||
device:
|
||||
integration: screenlogic
|
||||
|
|
|
@ -46,6 +46,20 @@
|
|||
"description": "The ScreenLogic color mode to set."
|
||||
}
|
||||
}
|
||||
},
|
||||
"start_super_chlorination": {
|
||||
"name": "Start Super Chlorination",
|
||||
"description": "Begins super chlorination, running for the specified period or 24 hours if none is specified.",
|
||||
"fields": {
|
||||
"runtime": {
|
||||
"name": "Run Time",
|
||||
"description": "Number of hours for super chlorination to run."
|
||||
}
|
||||
}
|
||||
},
|
||||
"stop_super_chlorination": {
|
||||
"name": "Stop Super Chlorination",
|
||||
"description": "Stops super chlorination."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue