"""Support for control of ElkM1 outputs (relays).""" from datetime import timedelta from math import ceil from typing import Any, override from elkm1_lib.const import ThermostatMode, ThermostatSetting from elkm1_lib.elements import Element from elkm1_lib.elk import Elk from elkm1_lib.outputs import Output from elkm1_lib.thermostats import Thermostat import voluptuous as vol from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN, SwitchEntity from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv, service from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.typing import VolDictType from . import ElkM1ConfigEntry from .const import ATTR_DURATION, DOMAIN from .entity import ElkAttachedEntity, ElkEntity, create_elk_entities from .models import ELKM1Data SERVICE_SWITCH_OUTPUT_TURN_ON_FOR = "switch_output_turn_on_for" ELK_OUTPUT_TURN_ON_FOR_SERVICE_SCHEMA: VolDictType = { vol.Required(ATTR_DURATION): vol.All( cv.time_period, vol.Range(min=timedelta(seconds=1), max=timedelta(seconds=65535)), ), } async def async_setup_entry( hass: HomeAssistant, config_entry: ElkM1ConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Create the Elk-M1 switch platform.""" elk_data = config_entry.runtime_data elk = elk_data.elk entities: list[ElkEntity] = [] create_elk_entities(elk_data, elk.outputs, "output", ElkOutput, entities) create_elk_entities( elk_data, elk.thermostats, "thermostat", ElkThermostatEMHeat, entities ) async_add_entities(entities) service.async_register_platform_entity_service( hass, DOMAIN, SERVICE_SWITCH_OUTPUT_TURN_ON_FOR, entity_domain=SWITCH_DOMAIN, schema=ELK_OUTPUT_TURN_ON_FOR_SERVICE_SCHEMA, func="async_switch_output_turn_on_for", ) class ElkOutput(ElkAttachedEntity, SwitchEntity): """Elk output as switch.""" _element: Output @property @override def is_on(self) -> bool: """Get the current output status.""" return self._element.output_on @override async def async_turn_on(self, **kwargs: Any) -> None: """Turn on the output.""" self._element.turn_on(0) @override async def async_turn_off(self, **kwargs: Any) -> None: """Turn off the output.""" self._element.turn_off() async def async_switch_output_turn_on_for(self, duration: timedelta) -> None: """Turn on an output for specified length of time.""" self._element.turn_on(ceil(duration.total_seconds())) class ElkThermostatEMHeat(ElkEntity, SwitchEntity): """Elk Thermostat emergency heat as switch.""" _element: Thermostat def __init__(self, element: Element, elk: Elk, elk_data: ELKM1Data) -> None: """Initialize the emergency heat switch.""" super().__init__(element, elk, elk_data) self._unique_id = f"{self._unique_id}emheat" self._attr_name = f"{element.name} emergency heat" @property @override def is_on(self) -> bool: """Get the current emergency heat status.""" return self._element.mode is ThermostatMode.EMERGENCY_HEAT def _elk_set(self, mode: ThermostatMode) -> None: """Set the thermostat mode.""" self._element.set(ThermostatSetting.MODE, mode) @override async def async_turn_on(self, **kwargs: Any) -> None: """Turn on the output.""" self._elk_set(ThermostatMode.EMERGENCY_HEAT) @override async def async_turn_off(self, **kwargs: Any) -> None: """Turn off the output.""" self._elk_set(ThermostatMode.EMERGENCY_HEAT) async def async_switch_output_turn_on_for(self, duration: timedelta) -> None: """Turn on an output for specified length of time: not supported for thermostat.""" raise HomeAssistantError("supported only on ElkM1 output switch entities")