core/homeassistant/components/screenlogic/entity.py

163 lines
5.4 KiB
Python
Raw Normal View History

"""Base ScreenLogicEntity definitions."""
from datetime import datetime
import logging
from typing import Any
from screenlogicpy import ScreenLogicGateway
from screenlogicpy.const import CODE, DATA as SL_DATA, EQUIPMENT, ON_OFF
from homeassistant.core import callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import ScreenlogicDataUpdateCoordinator
_LOGGER = logging.getLogger(__name__)
class ScreenlogicEntity(CoordinatorEntity[ScreenlogicDataUpdateCoordinator]):
"""Base class for all ScreenLogic entities."""
def __init__(
self,
coordinator: ScreenlogicDataUpdateCoordinator,
data_key: str,
enabled: bool = True,
) -> None:
"""Initialize of the entity."""
super().__init__(coordinator)
self._data_key = data_key
self._attr_entity_registry_enabled_default = enabled
self._attr_unique_id = f"{self.mac}_{self._data_key}"
controller_type = self.config_data["controller_type"]
hardware_type = self.config_data["hardware_type"]
try:
equipment_model = EQUIPMENT.CONTROLLER_HARDWARE[controller_type][
hardware_type
]
except KeyError:
equipment_model = f"Unknown Model C:{controller_type} H:{hardware_type}"
mac = self.mac
assert mac is not None
self._attr_device_info = DeviceInfo(
connections={(dr.CONNECTION_NETWORK_MAC, mac)},
manufacturer="Pentair",
model=equipment_model,
name=self.gateway_name,
sw_version=self.gateway.version,
)
@property
def mac(self) -> str | None:
"""Mac address."""
assert self.coordinator.config_entry is not None
return self.coordinator.config_entry.unique_id
@property
def config_data(self) -> dict[str | int, Any]:
"""Shortcut for config data."""
return self.gateway_data[SL_DATA.KEY_CONFIG]
@property
def gateway(self) -> ScreenLogicGateway:
"""Return the gateway."""
return self.coordinator.gateway
@property
def gateway_data(self) -> dict[str | int, Any]:
"""Return the gateway data."""
return self.gateway.get_data()
@property
def gateway_name(self) -> str:
"""Return the configured name of the gateway."""
return self.gateway.name
async def _async_refresh(self) -> None:
"""Refresh the data from the gateway."""
await self.coordinator.async_refresh()
# Second debounced refresh to catch any secondary
# changes in the device
await self.coordinator.async_request_refresh()
async def _async_refresh_timed(self, now: datetime) -> None:
"""Refresh from a timed called."""
await self.coordinator.async_request_refresh()
class ScreenLogicPushEntity(ScreenlogicEntity):
"""Base class for all ScreenLogic push entities."""
def __init__(
self,
coordinator: ScreenlogicDataUpdateCoordinator,
data_key: str,
message_code: CODE,
enabled: bool = True,
) -> None:
"""Initialize the entity."""
super().__init__(coordinator, data_key, enabled)
self._update_message_code = message_code
2023-03-17 20:10:37 +00:00
self._last_update_success = True
@callback
def _async_data_updated(self) -> None:
"""Handle data updates."""
2023-03-17 20:10:37 +00:00
self._last_update_success = self.coordinator.last_update_success
self.async_write_ha_state()
async def async_added_to_hass(self) -> None:
"""When entity is added to hass."""
2023-03-17 20:10:37 +00:00
await super().async_added_to_hass()
self.async_on_remove(
await self.gateway.async_subscribe_client(
self._async_data_updated, self._update_message_code
)
)
2023-03-17 20:10:37 +00:00
@callback
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
# For push entities, only take updates from the coordinator if availability changes.
if self.coordinator.last_update_success != self._last_update_success:
self._async_data_updated()
class ScreenLogicCircuitEntity(ScreenLogicPushEntity):
"""Base class for all ScreenLogic switch and light entities."""
_attr_has_entity_name = True
@property
def name(self) -> str:
"""Get the name of the switch."""
return 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: Any) -> None:
"""Send the ON command."""
await self._async_set_circuit(ON_OFF.ON)
async def async_turn_off(self, **kwargs: Any) -> None:
"""Send the OFF command."""
await self._async_set_circuit(ON_OFF.OFF)
async def _async_set_circuit(self, circuit_value: int) -> None:
if not await self.gateway.async_set_circuit(self._data_key, circuit_value):
raise HomeAssistantError(
f"Failed to set_circuit {self._data_key} {circuit_value}"
)
_LOGGER.debug("Turn %s %s", self._data_key, circuit_value)
@property
def circuit(self) -> dict[str | int, Any]:
"""Shortcut to access the circuit."""
return self.gateway_data[SL_DATA.KEY_CIRCUITS][self._data_key]