Files
HomeAssistantVS/custom_components/hilo/climate.py
T
2026-06-11 11:50:50 -04:00

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]
)