142 lines
4.5 KiB
Python
142 lines
4.5 KiB
Python
"""Support for Hilo Climate entities."""
|
|
|
|
from datetime import datetime, timedelta
|
|
|
|
from homeassistant.components.climate import ClimateEntity
|
|
from homeassistant.components.climate.const import (
|
|
ClimateEntityFeature,
|
|
HVACAction,
|
|
HVACMode,
|
|
)
|
|
from homeassistant.config_entries import ConfigEntry
|
|
from homeassistant.const import (
|
|
ATTR_TEMPERATURE,
|
|
PRECISION_TENTHS,
|
|
Platform,
|
|
UnitOfTemperature,
|
|
)
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|
from homeassistant.util import slugify
|
|
|
|
from . import Hilo
|
|
from .const import CLIMATE_CLASSES, DOMAIN, LOG
|
|
from .entity import HiloEntity
|
|
|
|
|
|
def validate_reduction_phase(events, tag):
|
|
"""Validate if current time is within a challenge lock reduction phase."""
|
|
if not events:
|
|
return
|
|
current = events[0]
|
|
phases = current["phases"]
|
|
start = phases["reduction_start"]
|
|
end = phases["reduction_end"]
|
|
if (
|
|
start + timedelta(minutes=2)
|
|
< datetime.now(start.tzinfo)
|
|
< end - timedelta(minutes=2)
|
|
):
|
|
LOG.warning(
|
|
f"{tag} Attempt to set temperature was blocked because challenge lock is active"
|
|
)
|
|
# Raising an exception here will raise it up to the GUI
|
|
raise Exception("Challenge lock is active, unable to change temperature target")
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
|
) -> None:
|
|
"""Set up Hilo climate entities from a config entry."""
|
|
hilo = hass.data[DOMAIN][entry.entry_id]
|
|
entities = []
|
|
for d in hilo.devices.all:
|
|
if d.type in CLIMATE_CLASSES:
|
|
d._entity = HiloClimate(hilo, d)
|
|
entities.append(d._entity)
|
|
async_add_entities(entities)
|
|
return True
|
|
|
|
|
|
class HiloClimate(HiloEntity, ClimateEntity):
|
|
"""Representation of a Hilo Climate entity."""
|
|
|
|
_attr_hvac_modes = [HVACMode.HEAT]
|
|
_attr_temperature_unit: str = UnitOfTemperature.CELSIUS
|
|
_attr_precision: float = PRECISION_TENTHS
|
|
_attr_supported_features: int = ClimateEntityFeature.TARGET_TEMPERATURE
|
|
|
|
def __init__(self, hilo: Hilo, device):
|
|
"""Initialize the climate entity."""
|
|
super().__init__(hilo, device=device, name=device.name)
|
|
old_unique_id = f"{slugify(device.name)}-climate"
|
|
self._attr_unique_id = f"{device.identifier.lower()}-climate"
|
|
hilo.async_migrate_unique_id(
|
|
old_unique_id, self._attr_unique_id, Platform.CLIMATE
|
|
)
|
|
hilo.async_migrate_unique_id(
|
|
f"{slugify(device.identifier)}-climate",
|
|
self._attr_unique_id,
|
|
Platform.CLIMATE,
|
|
)
|
|
self.operations = [HVACMode.HEAT]
|
|
self._has_operation = False
|
|
self._temperature_entity = None
|
|
LOG.debug("Setting up Climate entity: %s", self._attr_name)
|
|
|
|
@property
|
|
def current_temperature(self):
|
|
"""Return the current temperature."""
|
|
return self._device.current_temperature
|
|
|
|
@property
|
|
def target_temperature(self):
|
|
"""Return the target temperature."""
|
|
return self._device.target_temperature
|
|
|
|
@property
|
|
def max_temp(self):
|
|
"""Return the maximum temperature."""
|
|
return self._device.max_temp
|
|
|
|
@property
|
|
def min_temp(self):
|
|
"""Return the minimum temperature."""
|
|
return self._device.min_temp
|
|
|
|
def set_hvac_mode(self, hvac_mode):
|
|
"""Set hvac mode."""
|
|
return
|
|
|
|
@property
|
|
def hvac_mode(self):
|
|
"""Return hvac mode."""
|
|
return HVACMode.HEAT
|
|
|
|
@property
|
|
def hvac_action(self):
|
|
"""Return the current hvac action."""
|
|
return self._device.hvac_action
|
|
|
|
@property
|
|
def icon(self):
|
|
"""Return the icon to use in the frontend, based on hvac_action."""
|
|
if self._device.hvac_action == HVACAction.HEATING:
|
|
return "mdi:radiator"
|
|
return "mdi:radiator-disabled"
|
|
|
|
async def async_set_temperature(self, **kwargs):
|
|
"""Set new target temperature."""
|
|
if ATTR_TEMPERATURE in kwargs:
|
|
if self._hilo.challenge_lock:
|
|
challenge = self._hilo._hass.states.get("sensor.defi_hilo")
|
|
validate_reduction_phase(
|
|
challenge.attributes.get("next_events", []), self._device._tag
|
|
)
|
|
LOG.info(
|
|
f"{self._device._tag} Setting temperature to {kwargs[ATTR_TEMPERATURE]}"
|
|
)
|
|
await self._device.set_attribute(
|
|
"target_temperature", kwargs[ATTR_TEMPERATURE]
|
|
)
|