Skip to content

Commit

Permalink
New climatisation controls with temperature
Browse files Browse the repository at this point in the history
  • Loading branch information
stickpin committed Feb 17, 2024
1 parent 3c17f11 commit d1940f7
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 96 deletions.
16 changes: 4 additions & 12 deletions custom_components/volkswagencarnet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,7 @@
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.icon import icon_for_battery_level
from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.update_coordinator import (
DataUpdateCoordinator,
UpdateFailed,
CoordinatorEntity,
)
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed, CoordinatorEntity
from volkswagencarnet.vw_connection import Connection
from volkswagencarnet.vw_dashboard import (
Instrument,
Expand Down Expand Up @@ -324,11 +320,7 @@ def async_write_ha_state(self) -> None:
prev: Optional[State] = self.hass.states.get(self.entity_id)

# This is not the best place to handle this, but... :shrug:..
if self.attribute == "requests_remaining" and self.state in [
-1,
STATE_UNAVAILABLE,
STATE_UNKNOWN,
]:
if self.attribute == "requests_remaining" and self.state in [-1, STATE_UNAVAILABLE, STATE_UNKNOWN]:
restored = prev or self.restored_state
if restored is not None:
try:
Expand All @@ -350,6 +342,7 @@ def async_write_ha_state(self) -> None:
prev is None
or str(prev.attributes.get("last_updated", None)) != str(backend_refresh_time)
or str(self.state or STATE_UNKNOWN) != str(prev.state)
or self.component == "climate"
):
super().async_write_ha_state()
else:
Expand Down Expand Up @@ -560,8 +553,7 @@ async def update(self) -> Optional[Vehicle]:
async def report_request(self, vehicle: Vehicle) -> None:
"""Request car to report itself an update to Volkswagen WeConnect."""
report_interval = self.entry.options.get(
CONF_REPORT_SCAN_INTERVAL,
self.entry.data.get(CONF_REPORT_SCAN_INTERVAL, DEFAULT_REPORT_UPDATE_INTERVAL),
CONF_REPORT_SCAN_INTERVAL, self.entry.data.get(CONF_REPORT_SCAN_INTERVAL, DEFAULT_REPORT_UPDATE_INTERVAL)
)

if not self.report_last_updated:
Expand Down
124 changes: 40 additions & 84 deletions custom_components/volkswagencarnet/climate.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
"""Climate support for Volkswagen WeConnect Platform."""

import logging

from homeassistant.components.climate import ClimateEntity
from homeassistant.components.climate.const import (
HVAC_MODE_COOL,
HVAC_MODE_HEAT,
HVAC_MODE_OFF,
SUPPORT_TARGET_TEMPERATURE,
from homeassistant.components.climate import (
ClimateEntity,
ClimateEntityFeature,
HVACMode,
)
from homeassistant.const import (
ATTR_TEMPERATURE,
STATE_UNKNOWN,
TEMP_CELSIUS,
UnitOfTemperature,
)

from . import VolkswagenEntity
from .const import DATA_KEY, DATA, DOMAIN
from . import VolkswagenEntity, VolkswagenData
from .const import DATA_KEY, DATA, DOMAIN, UPDATE_CALLBACK

SUPPORT_HVAC = [HVAC_MODE_COOL, HVAC_MODE_HEAT, HVAC_MODE_OFF]
_LOGGER = logging.getLogger(__name__)


Expand All @@ -39,6 +36,7 @@ async def async_setup_entry(hass, entry, async_add_devices):
vin=coordinator.vin,
component=instrument.component,
attribute=instrument.attr,
callback=hass.data[DOMAIN][entry.entry_id][UPDATE_CALLBACK],
)
for instrument in (instrument for instrument in data.instruments if instrument.component == "climate")
)
Expand All @@ -49,92 +47,50 @@ async def async_setup_entry(hass, entry, async_add_devices):
class VolkswagenClimate(VolkswagenEntity, ClimateEntity):
"""Representation of a Volkswagen WeConnect Climate."""

def set_temperature(self, **kwargs) -> None:
"""Not implemented."""
raise NotImplementedError("Use async_set_temperature instead")

def set_humidity(self, humidity: int) -> None:
"""Not implemented."""
raise NotImplementedError

def set_fan_mode(self, fan_mode: str) -> None:
"""Not implemented."""
raise NotImplementedError

def set_hvac_mode(self, hvac_mode: str) -> None:
"""Not implemented."""
raise NotImplementedError("Use async_set_hvac_mode instead")

def set_swing_mode(self, swing_mode: str) -> None:
"""Not implemented."""
raise NotImplementedError

def set_preset_mode(self, preset_mode: str) -> None:
"""Not implemented."""
raise NotImplementedError

def turn_aux_heat_on(self) -> None:
"""Not implemented."""
raise NotImplementedError

def turn_aux_heat_off(self) -> None:
"""Not implemented."""
raise NotImplementedError

@property
def supported_features(self):
"""Return the list of supported features."""
return SUPPORT_TARGET_TEMPERATURE

@property
def hvac_mode(self):
"""Return hvac operation ie. heat, cool mode.
Need to be one of HVAC_MODE_*.
"""
if not self.instrument.hvac_mode:
return HVAC_MODE_OFF

hvac_modes = {
"HEATING": HVAC_MODE_HEAT,
"COOLING": HVAC_MODE_COOL,
}
return hvac_modes.get(self.instrument.hvac_mode, HVAC_MODE_OFF)

@property
def hvac_modes(self):
"""Return the list of available hvac operation modes.
Need to be a subset of HVAC_MODES.
"""
return SUPPORT_HVAC

@property
def temperature_unit(self):
"""Return the unit of measurement."""
return TEMP_CELSIUS

@property
def target_temperature(self):
"""Return the temperature we try to reach."""
if self.instrument.target_temperature:
return float(self.instrument.target_temperature)
_attr_temperature_unit = UnitOfTemperature.CELSIUS
_attr_target_temperature_step = 0.5
_attr_supported_features = (
ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.TURN_OFF | ClimateEntityFeature.TURN_ON
)
_attr_hvac_modes = [HVACMode.HEAT_COOL, HVACMode.OFF]
_attr_hvac_mode = HVACMode.HEAT_COOL
_attr_min_temp = 15.5
_attr_max_temp = 30
_enable_turn_on_off_backwards_compatibility = False # Remove after HA version 2025.1

def __init__(self, data: VolkswagenData, vin: str, component: str, attribute: str, callback=None):
"""Initialize switch."""
super().__init__(data, vin, component, attribute, callback)
self._update_state()

def _update_state(self) -> None:
self._attr_target_temperature = float(self.instrument.target_temperature)
if self.instrument.hvac_mode is True:
self._attr_hvac_mode = HVACMode.HEAT_COOL
else:
return STATE_UNKNOWN
self._attr_hvac_mode = HVACMode.OFF

async def async_turn_off(self) -> None:
await self.async_set_hvac_mode(HVACMode.OFF)

async def async_turn_on(self) -> None:
await self.async_set_hvac_mode(HVACMode.HEAT_COOL)

async def async_set_temperature(self, **kwargs):
"""Set new target temperatures."""
_LOGGER.debug("Setting temperature for: %s", self.instrument.attr)
temperature = kwargs.get(ATTR_TEMPERATURE)
if temperature:
await self.instrument.set_temperature(temperature)
self._update_state()
self.notify_updated()

async def async_set_hvac_mode(self, hvac_mode):
"""Set new target hvac mode."""
_LOGGER.debug("Setting mode for: %s", self.instrument.attr)
if hvac_mode == HVAC_MODE_OFF:
if hvac_mode == HVACMode.OFF:
await self.instrument.set_hvac_mode(False)
elif hvac_mode == HVAC_MODE_HEAT:
elif hvac_mode == HVACMode.HEAT_COOL:
await self.instrument.set_hvac_mode(True)
self._update_state()
self.notify_updated()

0 comments on commit d1940f7

Please sign in to comment.