"""Climate platform for Teslemetry integration.""" from __future__ import annotations from typing import Any, cast from tesla_fleet_api.const import Scope from homeassistant.components.climate import ( ATTR_HVAC_MODE, ClimateEntity, ClimateEntityFeature, HVACMode, ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, PRECISION_HALVES, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import TeslemetryClimateSide from .entity import TeslemetryVehicleEntity from .models import TeslemetryVehicleData DEFAULT_MIN_TEMP = 15 DEFAULT_MAX_TEMP = 28 async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: """Set up the Teslemetry Climate platform from a config entry.""" async_add_entities( TeslemetryClimateEntity( vehicle, TeslemetryClimateSide.DRIVER, entry.runtime_data.scopes ) for vehicle in entry.runtime_data.vehicles ) class TeslemetryClimateEntity(TeslemetryVehicleEntity, ClimateEntity): """Vehicle Location Climate Class.""" _attr_precision = PRECISION_HALVES _attr_temperature_unit = UnitOfTemperature.CELSIUS _attr_hvac_modes = [HVACMode.HEAT_COOL, HVACMode.OFF] _attr_supported_features = ( ClimateEntityFeature.TURN_ON | ClimateEntityFeature.TURN_OFF | ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.PRESET_MODE ) _attr_preset_modes = ["off", "keep", "dog", "camp"] _enable_turn_on_off_backwards_compatibility = False def __init__( self, data: TeslemetryVehicleData, side: TeslemetryClimateSide, scopes: Scope, ) -> None: """Initialize the climate.""" self.scoped = Scope.VEHICLE_CMDS in scopes if not self.scoped: self._attr_supported_features = ClimateEntityFeature(0) super().__init__( data, side, ) def _async_update_attrs(self) -> None: """Update the attributes of the entity.""" value = self.get("climate_state_is_climate_on") if value is None: self._attr_hvac_mode = None elif value: self._attr_hvac_mode = HVACMode.HEAT_COOL else: self._attr_hvac_mode = HVACMode.OFF self._attr_current_temperature = self.get("climate_state_inside_temp") self._attr_target_temperature = self.get(f"climate_state_{self.key}_setting") self._attr_preset_mode = self.get("climate_state_climate_keeper_mode") self._attr_min_temp = cast( float, self.get("climate_state_min_avail_temp", DEFAULT_MIN_TEMP) ) self._attr_max_temp = cast( float, self.get("climate_state_max_avail_temp", DEFAULT_MAX_TEMP) ) async def async_turn_on(self) -> None: """Set the climate state to on.""" self.raise_for_scope() await self.wake_up_if_asleep() await self.handle_command(self.api.auto_conditioning_start()) self._attr_hvac_mode = HVACMode.HEAT_COOL self.async_write_ha_state() async def async_turn_off(self) -> None: """Set the climate state to off.""" self.raise_for_scope() await self.wake_up_if_asleep() await self.handle_command(self.api.auto_conditioning_stop()) self._attr_hvac_mode = HVACMode.OFF self._attr_preset_mode = self._attr_preset_modes[0] self.async_write_ha_state() async def async_set_temperature(self, **kwargs: Any) -> None: """Set the climate temperature.""" if temp := kwargs.get(ATTR_TEMPERATURE): await self.wake_up_if_asleep() await self.handle_command( self.api.set_temps( driver_temp=temp, passenger_temp=temp, ) ) self._attr_target_temperature = temp if mode := kwargs.get(ATTR_HVAC_MODE): # Set HVAC mode will call write_ha_state await self.async_set_hvac_mode(mode) else: self.async_write_ha_state() async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None: """Set the climate mode and state.""" if hvac_mode == HVACMode.OFF: await self.async_turn_off() else: await self.async_turn_on() async def async_set_preset_mode(self, preset_mode: str) -> None: """Set the climate preset mode.""" await self.wake_up_if_asleep() await self.handle_command( self.api.set_climate_keeper_mode( climate_keeper_mode=self._attr_preset_modes.index(preset_mode) ) ) self._attr_preset_mode = preset_mode if preset_mode == self._attr_preset_modes[0]: self._attr_hvac_mode = HVACMode.OFF else: self._attr_hvac_mode = HVACMode.HEAT_COOL self.async_write_ha_state()