154 lines
5.0 KiB
Python
154 lines
5.0 KiB
Python
"""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()
|