"""Support for Digital Loggers DIN III Relays.""" from __future__ import annotations from datetime import timedelta import logging import dlipower import voluptuous as vol from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity from homeassistant.const import ( CONF_HOST, CONF_NAME, CONF_PASSWORD, CONF_TIMEOUT, CONF_USERNAME, ) from homeassistant.core import HomeAssistant import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.util import Throttle _LOGGER = logging.getLogger(__name__) CONF_CYCLETIME = "cycletime" DEFAULT_NAME = "DINRelay" DEFAULT_USERNAME = "admin" DEFAULT_PASSWORD = "admin" DEFAULT_TIMEOUT = 20 DEFAULT_CYCLETIME = 2 MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=5) PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Required(CONF_HOST): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_USERNAME, default=DEFAULT_USERNAME): cv.string, vol.Optional(CONF_PASSWORD, default=DEFAULT_PASSWORD): cv.string, vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): vol.All( vol.Coerce(int), vol.Range(min=1, max=600) ), vol.Optional(CONF_CYCLETIME, default=DEFAULT_CYCLETIME): vol.All( vol.Coerce(int), vol.Range(min=1, max=600) ), } ) def setup_platform( hass: HomeAssistant, config: ConfigType, add_entities: AddEntitiesCallback, discovery_info: DiscoveryInfoType | None = None, ) -> None: """Find and return DIN III Relay switch.""" host = config[CONF_HOST] controller_name = config[CONF_NAME] user = config[CONF_USERNAME] pswd = config[CONF_PASSWORD] tout = config[CONF_TIMEOUT] cycl = config[CONF_CYCLETIME] power_switch = dlipower.PowerSwitch( hostname=host, userid=user, password=pswd, timeout=tout, cycletime=cycl ) if not power_switch.verify(): _LOGGER.error("Could not connect to DIN III Relay") return entities: list[DINRelay] = [] parent_device = DINRelayDevice(power_switch) entities.extend( DINRelay(controller_name, parent_device, outlet) for outlet in power_switch[0:] ) add_entities(entities) class DINRelay(SwitchEntity): """Representation of an individual DIN III relay port.""" def __init__(self, controller_name, parent_device, outlet): """Initialize the DIN III Relay switch.""" self._controller_name = controller_name self._parent_device = parent_device self._outlet = outlet self._outlet_number = self._outlet.outlet_number self._name = self._outlet.description self._state = self._outlet.state == "ON" @property def name(self): """Return the display name of this relay.""" return f"{self._controller_name}_{self._name}" @property def is_on(self): """Return true if relay is on.""" return self._state def turn_on(self, **kwargs): """Instruct the relay to turn on.""" self._outlet.on() def turn_off(self, **kwargs): """Instruct the relay to turn off.""" self._outlet.off() def update(self): """Trigger update for all switches on the parent device.""" self._parent_device.update() outlet_status = self._parent_device.get_outlet_status(self._outlet_number) self._name = outlet_status[1] self._state = outlet_status[2] == "ON" class DINRelayDevice: """Device representation for per device throttling.""" def __init__(self, power_switch): """Initialize the DINRelay device.""" self._power_switch = power_switch self._statuslist = None def get_outlet_status(self, outlet_number): """Get status of outlet from cached status list.""" return self._statuslist[outlet_number - 1] @Throttle(MIN_TIME_BETWEEN_UPDATES) def update(self): """Fetch new state data for this device.""" self._statuslist = self._power_switch.statuslist()