mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Switch to update coordinator, and bump venstarcolortouch to 0.15 (#58601)
This commit is contained in:
parent
6c426fea9e
commit
f87f72bb8e
@ -1,9 +1,11 @@
|
||||
"""The venstar component."""
|
||||
import asyncio
|
||||
from datetime import timedelta
|
||||
|
||||
from requests import RequestException
|
||||
from venstarcolortouch import VenstarColorTouch
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
CONF_HOST,
|
||||
CONF_PASSWORD,
|
||||
@ -11,8 +13,9 @@ from homeassistant.const import (
|
||||
CONF_SSL,
|
||||
CONF_USERNAME,
|
||||
)
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import update_coordinator
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
from .const import _LOGGER, DOMAIN, VENSTAR_TIMEOUT
|
||||
|
||||
@ -37,11 +40,13 @@ async def async_setup_entry(hass, config):
|
||||
proto=protocol,
|
||||
)
|
||||
|
||||
try:
|
||||
await hass.async_add_executor_job(client.update_info)
|
||||
except (OSError, RequestException) as ex:
|
||||
raise ConfigEntryNotReady(f"Unable to connect to the thermostat: {ex}") from ex
|
||||
hass.data.setdefault(DOMAIN, {})[config.entry_id] = client
|
||||
venstar_data_coordinator = VenstarDataUpdateCoordinator(
|
||||
hass,
|
||||
venstar_connection=client,
|
||||
)
|
||||
await venstar_data_coordinator.async_config_entry_first_refresh()
|
||||
|
||||
hass.data.setdefault(DOMAIN, {})[config.entry_id] = venstar_data_coordinator
|
||||
hass.config_entries.async_setup_platforms(config, PLATFORMS)
|
||||
|
||||
return True
|
||||
@ -55,35 +60,74 @@ async def async_unload_entry(hass, config):
|
||||
return unload_ok
|
||||
|
||||
|
||||
class VenstarEntity(Entity):
|
||||
"""Get the latest data and update."""
|
||||
class VenstarDataUpdateCoordinator(update_coordinator.DataUpdateCoordinator):
|
||||
"""Class to manage fetching Venstar data."""
|
||||
|
||||
def __init__(self, config, client):
|
||||
"""Initialize the data object."""
|
||||
self._config = config
|
||||
self._client = client
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
*,
|
||||
venstar_connection: VenstarColorTouch,
|
||||
) -> None:
|
||||
"""Initialize global Venstar data updater."""
|
||||
self.client = venstar_connection
|
||||
|
||||
async def async_update(self):
|
||||
super().__init__(
|
||||
hass,
|
||||
_LOGGER,
|
||||
name=DOMAIN,
|
||||
update_interval=timedelta(seconds=60),
|
||||
)
|
||||
|
||||
async def _async_update_data(self) -> None:
|
||||
"""Update the state."""
|
||||
try:
|
||||
info_success = await self.hass.async_add_executor_job(
|
||||
self._client.update_info
|
||||
)
|
||||
await self.hass.async_add_executor_job(self.client.update_info)
|
||||
except (OSError, RequestException) as ex:
|
||||
_LOGGER.error("Exception during info update: %s", ex)
|
||||
raise update_coordinator.UpdateFailed(
|
||||
f"Exception during Venstar info update: {ex}"
|
||||
) from ex
|
||||
|
||||
# older venstars sometimes cannot handle rapid sequential connections
|
||||
await asyncio.sleep(3)
|
||||
|
||||
try:
|
||||
sensor_success = await self.hass.async_add_executor_job(
|
||||
self._client.update_sensors
|
||||
)
|
||||
await self.hass.async_add_executor_job(self.client.update_sensors)
|
||||
except (OSError, RequestException) as ex:
|
||||
_LOGGER.error("Exception during sensor update: %s", ex)
|
||||
raise update_coordinator.UpdateFailed(
|
||||
f"Exception during Venstar sensor update: {ex}"
|
||||
) from ex
|
||||
return None
|
||||
|
||||
if not info_success or not sensor_success:
|
||||
_LOGGER.error("Failed to update data")
|
||||
|
||||
class VenstarEntity(CoordinatorEntity):
|
||||
"""Representation of a Venstar entity."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
venstar_data_coordinator: VenstarDataUpdateCoordinator,
|
||||
config: ConfigEntry,
|
||||
) -> None:
|
||||
"""Initialize the data object."""
|
||||
super().__init__(venstar_data_coordinator)
|
||||
self._config = config
|
||||
self._update_attr()
|
||||
self.coordinator = venstar_data_coordinator
|
||||
|
||||
@property
|
||||
def _client(self):
|
||||
"""Return the venstar client."""
|
||||
return self.coordinator.client
|
||||
|
||||
@callback
|
||||
def _update_attr(self) -> None:
|
||||
"""Update the state and attributes."""
|
||||
|
||||
@callback
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Handle updated data from the coordinator."""
|
||||
self._update_attr()
|
||||
self.async_write_ha_state()
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
@ -102,8 +146,6 @@ class VenstarEntity(Entity):
|
||||
"identifiers": {(DOMAIN, self._config.entry_id)},
|
||||
"name": self._client.name,
|
||||
"manufacturer": "Venstar",
|
||||
# pylint: disable=protected-access
|
||||
"model": f"{self._client.model}-{self._client._type}",
|
||||
# pylint: disable=protected-access
|
||||
"sw_version": self._client._api_ver,
|
||||
"model": f"{self._client.model}-{self._client.get_type()}",
|
||||
"sw_version": self._client.get_api_ver(),
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
"""Support for Venstar WiFi Thermostats."""
|
||||
from functools import partial
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.climate import PLATFORM_SCHEMA, ClimateEntity
|
||||
@ -24,7 +26,7 @@ from homeassistant.components.climate.const import (
|
||||
SUPPORT_TARGET_TEMPERATURE,
|
||||
SUPPORT_TARGET_TEMPERATURE_RANGE,
|
||||
)
|
||||
from homeassistant.config_entries import SOURCE_IMPORT
|
||||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
||||
from homeassistant.const import (
|
||||
ATTR_TEMPERATURE,
|
||||
CONF_HOST,
|
||||
@ -38,9 +40,11 @@ from homeassistant.const import (
|
||||
TEMP_CELSIUS,
|
||||
TEMP_FAHRENHEIT,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import VenstarEntity
|
||||
from . import VenstarDataUpdateCoordinator, VenstarEntity
|
||||
from .const import (
|
||||
_LOGGER,
|
||||
ATTR_FAN_STATE,
|
||||
@ -68,10 +72,21 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the Venstar thermostat."""
|
||||
client = hass.data[DOMAIN][config_entry.entry_id]
|
||||
async_add_entities([VenstarThermostat(config_entry, client)], True)
|
||||
venstar_data_coordinator = hass.data[DOMAIN][config_entry.entry_id]
|
||||
async_add_entities(
|
||||
[
|
||||
VenstarThermostat(
|
||||
venstar_data_coordinator,
|
||||
config_entry,
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
@ -95,9 +110,13 @@ async def async_setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
class VenstarThermostat(VenstarEntity, ClimateEntity):
|
||||
"""Representation of a Venstar thermostat."""
|
||||
|
||||
def __init__(self, config, client):
|
||||
def __init__(
|
||||
self,
|
||||
venstar_data_coordinator: VenstarDataUpdateCoordinator,
|
||||
config: ConfigEntry,
|
||||
) -> None:
|
||||
"""Initialize the thermostat."""
|
||||
super().__init__(config, client)
|
||||
super().__init__(venstar_data_coordinator, config)
|
||||
self._mode_map = {
|
||||
HVAC_MODE_HEAT: self._client.MODE_HEAT,
|
||||
HVAC_MODE_COOL: self._client.MODE_COOL,
|
||||
@ -257,7 +276,12 @@ class VenstarThermostat(VenstarEntity, ClimateEntity):
|
||||
_LOGGER.error("Failed to change the operation mode")
|
||||
return success
|
||||
|
||||
def set_temperature(self, **kwargs):
|
||||
async def async_set_temperature(self, **kwargs):
|
||||
"""Set a new target temperature."""
|
||||
await self.hass.async_add_executor_job(partial(self._set_temperature, **kwargs))
|
||||
self.async_write_ha_state()
|
||||
|
||||
def _set_temperature(self, **kwargs):
|
||||
"""Set a new target temperature."""
|
||||
set_temp = True
|
||||
operation_mode = kwargs.get(ATTR_HVAC_MODE)
|
||||
@ -295,7 +319,12 @@ class VenstarThermostat(VenstarEntity, ClimateEntity):
|
||||
if not success:
|
||||
_LOGGER.error("Failed to change the temperature")
|
||||
|
||||
def set_fan_mode(self, fan_mode):
|
||||
async def async_set_fan_mode(self, fan_mode: str) -> None:
|
||||
"""Set a new target fan mode."""
|
||||
await self.hass.async_add_executor_job(self._set_fan_mode, fan_mode)
|
||||
self.async_write_ha_state()
|
||||
|
||||
def _set_fan_mode(self, fan_mode):
|
||||
"""Set new target fan mode."""
|
||||
if fan_mode == STATE_ON:
|
||||
success = self._client.set_fan(self._client.FAN_ON)
|
||||
@ -305,18 +334,33 @@ class VenstarThermostat(VenstarEntity, ClimateEntity):
|
||||
if not success:
|
||||
_LOGGER.error("Failed to change the fan mode")
|
||||
|
||||
def set_hvac_mode(self, hvac_mode):
|
||||
async def async_set_hvac_mode(self, hvac_mode: str) -> None:
|
||||
"""Set a new target operation mode."""
|
||||
await self.hass.async_add_executor_job(self._set_hvac_mode, hvac_mode)
|
||||
self.async_write_ha_state()
|
||||
|
||||
def _set_hvac_mode(self, hvac_mode):
|
||||
"""Set new target operation mode."""
|
||||
self._set_operation_mode(hvac_mode)
|
||||
|
||||
def set_humidity(self, humidity):
|
||||
async def async_set_humidity(self, humidity: int) -> None:
|
||||
"""Set a new target humidity."""
|
||||
await self.hass.async_add_executor_job(self._set_humidity, humidity)
|
||||
self.async_write_ha_state()
|
||||
|
||||
def _set_humidity(self, humidity):
|
||||
"""Set new target humidity."""
|
||||
success = self._client.set_hum_setpoint(humidity)
|
||||
|
||||
if not success:
|
||||
_LOGGER.error("Failed to change the target humidity level")
|
||||
|
||||
def set_preset_mode(self, preset_mode):
|
||||
async def async_set_preset_mode(self, preset_mode: str) -> None:
|
||||
"""Set the hold mode."""
|
||||
await self.hass.async_add_executor_job(self._set_preset_mode, preset_mode)
|
||||
self.async_write_ha_state()
|
||||
|
||||
def _set_preset_mode(self, preset_mode):
|
||||
"""Set the hold mode."""
|
||||
if preset_mode == PRESET_AWAY:
|
||||
success = self._client.set_away(self._client.AWAY_AWAY)
|
||||
|
@ -4,7 +4,7 @@
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/venstar",
|
||||
"requirements": [
|
||||
"venstarcolortouch==0.14"
|
||||
"venstarcolortouch==0.15"
|
||||
],
|
||||
"codeowners": ["@garbled1"],
|
||||
"iot_class": "local_polling"
|
||||
|
@ -2369,7 +2369,7 @@ vallox-websocket-api==2.8.1
|
||||
velbus-aio==2021.10.7
|
||||
|
||||
# homeassistant.components.venstar
|
||||
venstarcolortouch==0.14
|
||||
venstarcolortouch==0.15
|
||||
|
||||
# homeassistant.components.vilfo
|
||||
vilfo-api-client==0.3.2
|
||||
|
@ -1373,7 +1373,7 @@ uvcclient==0.11.0
|
||||
velbus-aio==2021.10.7
|
||||
|
||||
# homeassistant.components.venstar
|
||||
venstarcolortouch==0.14
|
||||
venstarcolortouch==0.15
|
||||
|
||||
# homeassistant.components.vilfo
|
||||
vilfo-api-client==0.3.2
|
||||
|
Loading…
x
Reference in New Issue
Block a user