Move Screenlogic lights to the light platform (#55467)

Co-authored-by: Kevin Worrel <37058192+dieselrabbit@users.noreply.github.com>
This commit is contained in:
J. Nick Koston 2021-10-20 12:38:21 -10:00 committed by GitHub
parent 18ce799f74
commit 20c35e6032
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 107 additions and 59 deletions

View file

@ -900,6 +900,7 @@ omit =
homeassistant/components/screenlogic/__init__.py homeassistant/components/screenlogic/__init__.py
homeassistant/components/screenlogic/binary_sensor.py homeassistant/components/screenlogic/binary_sensor.py
homeassistant/components/screenlogic/climate.py homeassistant/components/screenlogic/climate.py
homeassistant/components/screenlogic/light.py
homeassistant/components/screenlogic/sensor.py homeassistant/components/screenlogic/sensor.py
homeassistant/components/screenlogic/services.py homeassistant/components/screenlogic/services.py
homeassistant/components/screenlogic/switch.py homeassistant/components/screenlogic/switch.py

View file

@ -5,7 +5,9 @@ import logging
from screenlogicpy import ScreenLogicError, ScreenLogicGateway from screenlogicpy import ScreenLogicError, ScreenLogicGateway
from screenlogicpy.const import ( from screenlogicpy.const import (
DATA as SL_DATA,
EQUIPMENT, EQUIPMENT,
ON_OFF,
SL_GATEWAY_IP, SL_GATEWAY_IP,
SL_GATEWAY_NAME, SL_GATEWAY_NAME,
SL_GATEWAY_PORT, SL_GATEWAY_PORT,
@ -16,6 +18,7 @@ from homeassistant.const import CONF_IP_ADDRESS, CONF_PORT, CONF_SCAN_INTERVAL
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.debounce import Debouncer
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from homeassistant.helpers.update_coordinator import ( from homeassistant.helpers.update_coordinator import (
CoordinatorEntity, CoordinatorEntity,
@ -29,7 +32,10 @@ from .services import async_load_screenlogic_services, async_unload_screenlogic_
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
PLATFORMS = ["switch", "sensor", "binary_sensor", "climate"]
REQUEST_REFRESH_DELAY = 1
PLATFORMS = ["switch", "sensor", "binary_sensor", "climate", "light"]
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
@ -56,10 +62,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
await coordinator.async_config_entry_first_refresh() await coordinator.async_config_entry_first_refresh()
hass.data[DOMAIN][entry.entry_id] = { entry.async_on_unload(entry.add_update_listener(async_update_listener))
"coordinator": coordinator,
"listener": entry.add_update_listener(async_update_listener), hass.data[DOMAIN][entry.entry_id] = coordinator
}
hass.config_entries.async_setup_platforms(entry, PLATFORMS) hass.config_entries.async_setup_platforms(entry, PLATFORMS)
@ -134,6 +139,11 @@ class ScreenlogicDataUpdateCoordinator(DataUpdateCoordinator):
_LOGGER, _LOGGER,
name=DOMAIN, name=DOMAIN,
update_interval=interval, update_interval=interval,
# We don't want an immediate refresh since the device
# takes a moment to reflect the state change
request_refresh_debouncer=Debouncer(
hass, _LOGGER, cooldown=REQUEST_REFRESH_DELAY, immediate=False
),
) )
def reconnect_gateway(self): def reconnect_gateway(self):
@ -221,3 +231,44 @@ class ScreenlogicEntity(CoordinatorEntity):
"manufacturer": "Pentair", "manufacturer": "Pentair",
"model": equipment_model, "model": equipment_model,
} }
class ScreenLogicCircuitEntity(ScreenlogicEntity):
"""ScreenLogic circuit entity."""
@property
def name(self):
"""Get the name of the switch."""
return f"{self.gateway_name} {self.circuit['name']}"
@property
def is_on(self) -> bool:
"""Get whether the switch is in on state."""
return self.circuit["value"] == ON_OFF.ON
async def async_turn_on(self, **kwargs) -> None:
"""Send the ON command."""
await self._async_set_circuit(ON_OFF.ON)
async def async_turn_off(self, **kwargs) -> None:
"""Send the OFF command."""
await self._async_set_circuit(ON_OFF.OFF)
async def _async_set_circuit(self, circuit_value) -> None:
async with self.coordinator.api_lock:
success = await self.hass.async_add_executor_job(
self.gateway.set_circuit, self._data_key, circuit_value
)
if success:
_LOGGER.debug("Turn %s %s", self._data_key, circuit_value)
await self.coordinator.async_request_refresh()
else:
_LOGGER.warning(
"Failed to set_circuit %s %s", self._data_key, circuit_value
)
@property
def circuit(self):
"""Shortcut to access the circuit."""
return self.coordinator.data[SL_DATA.KEY_CIRCUITS][self._data_key]

View file

@ -15,7 +15,7 @@ SL_DEVICE_TYPE_TO_HA_DEVICE_CLASS = {DEVICE_TYPE.ALARM: DEVICE_CLASS_PROBLEM}
async def async_setup_entry(hass, config_entry, async_add_entities): async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up entry.""" """Set up entry."""
entities = [] entities = []
coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"] coordinator = hass.data[DOMAIN][config_entry.entry_id]
# Generic binary sensor # Generic binary sensor
entities.append(ScreenLogicBinarySensor(coordinator, "chem_alarm")) entities.append(ScreenLogicBinarySensor(coordinator, "chem_alarm"))

View file

@ -37,7 +37,7 @@ SUPPORTED_PRESETS = [
async def async_setup_entry(hass, config_entry, async_add_entities): async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up entry.""" """Set up entry."""
entities = [] entities = []
coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"] coordinator = hass.data[DOMAIN][config_entry.entry_id]
for body in coordinator.data[SL_DATA.KEY_BODIES]: for body in coordinator.data[SL_DATA.KEY_BODIES]:
entities.append(ScreenLogicClimate(coordinator, body)) entities.append(ScreenLogicClimate(coordinator, body))

View file

@ -1,5 +1,5 @@
"""Constants for the ScreenLogic integration.""" """Constants for the ScreenLogic integration."""
from screenlogicpy.const import COLOR_MODE from screenlogicpy.const import CIRCUIT_FUNCTION, COLOR_MODE
from homeassistant.util import slugify from homeassistant.util import slugify
@ -13,4 +13,6 @@ SUPPORTED_COLOR_MODES = {
slugify(name): num for num, name in COLOR_MODE.NAME_FOR_NUM.items() slugify(name): num for num, name in COLOR_MODE.NAME_FOR_NUM.items()
} }
LIGHT_CIRCUIT_FUNCTIONS = {CIRCUIT_FUNCTION.INTELLIBRITE, CIRCUIT_FUNCTION.LIGHT}
DISCOVERED_GATEWAYS = "_discovered_gateways" DISCOVERED_GATEWAYS = "_discovered_gateways"

View file

@ -0,0 +1,29 @@
"""Support for a ScreenLogic light 'circuit' switch."""
import logging
from screenlogicpy.const import DATA as SL_DATA, GENERIC_CIRCUIT_NAMES
from homeassistant.components.light import LightEntity
from . import ScreenLogicCircuitEntity
from .const import DOMAIN, LIGHT_CIRCUIT_FUNCTIONS
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up entry."""
coordinator = hass.data[DOMAIN][config_entry.entry_id]
async_add_entities(
[
ScreenLogicLight(
coordinator, circuit_num, circuit["name"] not in GENERIC_CIRCUIT_NAMES
)
for circuit_num, circuit in coordinator.data[SL_DATA.KEY_CIRCUITS].items()
if circuit["function"] in LIGHT_CIRCUIT_FUNCTIONS
]
)
class ScreenLogicLight(ScreenLogicCircuitEntity, LightEntity):
"""Class to represent a ScreenLogic Light."""

View file

@ -51,7 +51,7 @@ SL_DEVICE_TYPE_TO_HA_DEVICE_CLASS = {
async def async_setup_entry(hass, config_entry, async_add_entities): async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up entry.""" """Set up entry."""
entities = [] entities = []
coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"] coordinator = hass.data[DOMAIN][config_entry.entry_id]
equipment_flags = coordinator.data[SL_DATA.KEY_CONFIG]["equipment_flags"] equipment_flags = coordinator.data[SL_DATA.KEY_CONFIG]["equipment_flags"]
# Generic sensors # Generic sensors

View file

@ -51,7 +51,7 @@ def async_load_screenlogic_services(hass: HomeAssistant):
) )
color_num = SUPPORTED_COLOR_MODES[service_call.data[ATTR_COLOR_MODE]] color_num = SUPPORTED_COLOR_MODES[service_call.data[ATTR_COLOR_MODE]]
for entry_id in screenlogic_entry_ids: for entry_id in screenlogic_entry_ids:
coordinator = hass.data[DOMAIN][entry_id]["coordinator"] coordinator = hass.data[DOMAIN][entry_id]
_LOGGER.debug( _LOGGER.debug(
"Service %s called on %s with mode %s", "Service %s called on %s with mode %s",
SERVICE_SET_COLOR_MODE, SERVICE_SET_COLOR_MODE,

View file

@ -1,64 +1,29 @@
"""Support for a ScreenLogic 'circuit' switch.""" """Support for a ScreenLogic 'circuit' switch."""
import logging import logging
from screenlogicpy.const import DATA as SL_DATA, GENERIC_CIRCUIT_NAMES, ON_OFF from screenlogicpy.const import DATA as SL_DATA, GENERIC_CIRCUIT_NAMES
from homeassistant.components.switch import SwitchEntity from homeassistant.components.switch import SwitchEntity
from . import ScreenlogicEntity from . import ScreenLogicCircuitEntity
from .const import DOMAIN from .const import DOMAIN, LIGHT_CIRCUIT_FUNCTIONS
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
async def async_setup_entry(hass, config_entry, async_add_entities): async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up entry.""" """Set up entry."""
entities = [] coordinator = hass.data[DOMAIN][config_entry.entry_id]
coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"] async_add_entities(
[
for circuit_num, circuit in coordinator.data[SL_DATA.KEY_CIRCUITS].items(): ScreenLogicSwitch(
enabled = circuit["name"] not in GENERIC_CIRCUIT_NAMES coordinator, circuit_num, circuit["name"] not in GENERIC_CIRCUIT_NAMES
entities.append(ScreenLogicSwitch(coordinator, circuit_num, enabled)) )
for circuit_num, circuit in coordinator.data[SL_DATA.KEY_CIRCUITS].items()
async_add_entities(entities) if circuit["function"] not in LIGHT_CIRCUIT_FUNCTIONS
]
class ScreenLogicSwitch(ScreenlogicEntity, SwitchEntity):
"""ScreenLogic switch entity."""
@property
def name(self):
"""Get the name of the switch."""
return f"{self.gateway_name} {self.circuit['name']}"
@property
def is_on(self) -> bool:
"""Get whether the switch is in on state."""
return self.circuit["value"] == 1
async def async_turn_on(self, **kwargs) -> None:
"""Send the ON command."""
return await self._async_set_circuit(ON_OFF.ON)
async def async_turn_off(self, **kwargs) -> None:
"""Send the OFF command."""
return await self._async_set_circuit(ON_OFF.OFF)
async def _async_set_circuit(self, circuit_value) -> None:
async with self.coordinator.api_lock:
success = await self.hass.async_add_executor_job(
self.gateway.set_circuit, self._data_key, circuit_value
) )
if success:
_LOGGER.debug("Turn %s %s", self._data_key, circuit_value)
await self.coordinator.async_request_refresh()
else:
_LOGGER.warning(
"Failed to set_circuit %s %s", self._data_key, circuit_value
)
@property class ScreenLogicSwitch(ScreenLogicCircuitEntity, SwitchEntity):
def circuit(self): """Class to represent a ScreenLogic Switch."""
"""Shortcut to access the circuit."""
return self.coordinator.data[SL_DATA.KEY_CIRCUITS][self._data_key]