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."""
|
"""The venstar component."""
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
from requests import RequestException
|
from requests import RequestException
|
||||||
from venstarcolortouch import VenstarColorTouch
|
from venstarcolortouch import VenstarColorTouch
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_HOST,
|
CONF_HOST,
|
||||||
CONF_PASSWORD,
|
CONF_PASSWORD,
|
||||||
@ -11,8 +13,9 @@ from homeassistant.const import (
|
|||||||
CONF_SSL,
|
CONF_SSL,
|
||||||
CONF_USERNAME,
|
CONF_USERNAME,
|
||||||
)
|
)
|
||||||
from homeassistant.exceptions import ConfigEntryNotReady
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers import update_coordinator
|
||||||
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from .const import _LOGGER, DOMAIN, VENSTAR_TIMEOUT
|
from .const import _LOGGER, DOMAIN, VENSTAR_TIMEOUT
|
||||||
|
|
||||||
@ -37,11 +40,13 @@ async def async_setup_entry(hass, config):
|
|||||||
proto=protocol,
|
proto=protocol,
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
venstar_data_coordinator = VenstarDataUpdateCoordinator(
|
||||||
await hass.async_add_executor_job(client.update_info)
|
hass,
|
||||||
except (OSError, RequestException) as ex:
|
venstar_connection=client,
|
||||||
raise ConfigEntryNotReady(f"Unable to connect to the thermostat: {ex}") from ex
|
)
|
||||||
hass.data.setdefault(DOMAIN, {})[config.entry_id] = 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)
|
hass.config_entries.async_setup_platforms(config, PLATFORMS)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
@ -55,35 +60,74 @@ async def async_unload_entry(hass, config):
|
|||||||
return unload_ok
|
return unload_ok
|
||||||
|
|
||||||
|
|
||||||
class VenstarEntity(Entity):
|
class VenstarDataUpdateCoordinator(update_coordinator.DataUpdateCoordinator):
|
||||||
"""Get the latest data and update."""
|
"""Class to manage fetching Venstar data."""
|
||||||
|
|
||||||
def __init__(self, config, client):
|
def __init__(
|
||||||
"""Initialize the data object."""
|
self,
|
||||||
self._config = config
|
hass: HomeAssistant,
|
||||||
self._client = client
|
*,
|
||||||
|
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."""
|
"""Update the state."""
|
||||||
try:
|
try:
|
||||||
info_success = await self.hass.async_add_executor_job(
|
await self.hass.async_add_executor_job(self.client.update_info)
|
||||||
self._client.update_info
|
|
||||||
)
|
|
||||||
except (OSError, RequestException) as ex:
|
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
|
# older venstars sometimes cannot handle rapid sequential connections
|
||||||
await asyncio.sleep(3)
|
await asyncio.sleep(3)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sensor_success = await self.hass.async_add_executor_job(
|
await self.hass.async_add_executor_job(self.client.update_sensors)
|
||||||
self._client.update_sensors
|
|
||||||
)
|
|
||||||
except (OSError, RequestException) as ex:
|
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
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
@ -102,8 +146,6 @@ class VenstarEntity(Entity):
|
|||||||
"identifiers": {(DOMAIN, self._config.entry_id)},
|
"identifiers": {(DOMAIN, self._config.entry_id)},
|
||||||
"name": self._client.name,
|
"name": self._client.name,
|
||||||
"manufacturer": "Venstar",
|
"manufacturer": "Venstar",
|
||||||
# pylint: disable=protected-access
|
"model": f"{self._client.model}-{self._client.get_type()}",
|
||||||
"model": f"{self._client.model}-{self._client._type}",
|
"sw_version": self._client.get_api_ver(),
|
||||||
# pylint: disable=protected-access
|
|
||||||
"sw_version": self._client._api_ver,
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
"""Support for Venstar WiFi Thermostats."""
|
"""Support for Venstar WiFi Thermostats."""
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.climate import PLATFORM_SCHEMA, ClimateEntity
|
from homeassistant.components.climate import PLATFORM_SCHEMA, ClimateEntity
|
||||||
@ -24,7 +26,7 @@ from homeassistant.components.climate.const import (
|
|||||||
SUPPORT_TARGET_TEMPERATURE,
|
SUPPORT_TARGET_TEMPERATURE,
|
||||||
SUPPORT_TARGET_TEMPERATURE_RANGE,
|
SUPPORT_TARGET_TEMPERATURE_RANGE,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import SOURCE_IMPORT
|
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_TEMPERATURE,
|
ATTR_TEMPERATURE,
|
||||||
CONF_HOST,
|
CONF_HOST,
|
||||||
@ -38,9 +40,11 @@ from homeassistant.const import (
|
|||||||
TEMP_CELSIUS,
|
TEMP_CELSIUS,
|
||||||
TEMP_FAHRENHEIT,
|
TEMP_FAHRENHEIT,
|
||||||
)
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import VenstarEntity
|
from . import VenstarDataUpdateCoordinator, VenstarEntity
|
||||||
from .const import (
|
from .const import (
|
||||||
_LOGGER,
|
_LOGGER,
|
||||||
ATTR_FAN_STATE,
|
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."""
|
"""Set up the Venstar thermostat."""
|
||||||
client = hass.data[DOMAIN][config_entry.entry_id]
|
venstar_data_coordinator = hass.data[DOMAIN][config_entry.entry_id]
|
||||||
async_add_entities([VenstarThermostat(config_entry, client)], True)
|
async_add_entities(
|
||||||
|
[
|
||||||
|
VenstarThermostat(
|
||||||
|
venstar_data_coordinator,
|
||||||
|
config_entry,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(hass, config, add_entities, discovery_info=None):
|
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):
|
class VenstarThermostat(VenstarEntity, ClimateEntity):
|
||||||
"""Representation of a Venstar thermostat."""
|
"""Representation of a Venstar thermostat."""
|
||||||
|
|
||||||
def __init__(self, config, client):
|
def __init__(
|
||||||
|
self,
|
||||||
|
venstar_data_coordinator: VenstarDataUpdateCoordinator,
|
||||||
|
config: ConfigEntry,
|
||||||
|
) -> None:
|
||||||
"""Initialize the thermostat."""
|
"""Initialize the thermostat."""
|
||||||
super().__init__(config, client)
|
super().__init__(venstar_data_coordinator, config)
|
||||||
self._mode_map = {
|
self._mode_map = {
|
||||||
HVAC_MODE_HEAT: self._client.MODE_HEAT,
|
HVAC_MODE_HEAT: self._client.MODE_HEAT,
|
||||||
HVAC_MODE_COOL: self._client.MODE_COOL,
|
HVAC_MODE_COOL: self._client.MODE_COOL,
|
||||||
@ -257,7 +276,12 @@ class VenstarThermostat(VenstarEntity, ClimateEntity):
|
|||||||
_LOGGER.error("Failed to change the operation mode")
|
_LOGGER.error("Failed to change the operation mode")
|
||||||
return success
|
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 a new target temperature."""
|
||||||
set_temp = True
|
set_temp = True
|
||||||
operation_mode = kwargs.get(ATTR_HVAC_MODE)
|
operation_mode = kwargs.get(ATTR_HVAC_MODE)
|
||||||
@ -295,7 +319,12 @@ class VenstarThermostat(VenstarEntity, ClimateEntity):
|
|||||||
if not success:
|
if not success:
|
||||||
_LOGGER.error("Failed to change the temperature")
|
_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."""
|
"""Set new target fan mode."""
|
||||||
if fan_mode == STATE_ON:
|
if fan_mode == STATE_ON:
|
||||||
success = self._client.set_fan(self._client.FAN_ON)
|
success = self._client.set_fan(self._client.FAN_ON)
|
||||||
@ -305,18 +334,33 @@ class VenstarThermostat(VenstarEntity, ClimateEntity):
|
|||||||
if not success:
|
if not success:
|
||||||
_LOGGER.error("Failed to change the fan mode")
|
_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."""
|
"""Set new target operation mode."""
|
||||||
self._set_operation_mode(hvac_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."""
|
"""Set new target humidity."""
|
||||||
success = self._client.set_hum_setpoint(humidity)
|
success = self._client.set_hum_setpoint(humidity)
|
||||||
|
|
||||||
if not success:
|
if not success:
|
||||||
_LOGGER.error("Failed to change the target humidity level")
|
_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."""
|
"""Set the hold mode."""
|
||||||
if preset_mode == PRESET_AWAY:
|
if preset_mode == PRESET_AWAY:
|
||||||
success = self._client.set_away(self._client.AWAY_AWAY)
|
success = self._client.set_away(self._client.AWAY_AWAY)
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/venstar",
|
"documentation": "https://www.home-assistant.io/integrations/venstar",
|
||||||
"requirements": [
|
"requirements": [
|
||||||
"venstarcolortouch==0.14"
|
"venstarcolortouch==0.15"
|
||||||
],
|
],
|
||||||
"codeowners": ["@garbled1"],
|
"codeowners": ["@garbled1"],
|
||||||
"iot_class": "local_polling"
|
"iot_class": "local_polling"
|
||||||
|
@ -2369,7 +2369,7 @@ vallox-websocket-api==2.8.1
|
|||||||
velbus-aio==2021.10.7
|
velbus-aio==2021.10.7
|
||||||
|
|
||||||
# homeassistant.components.venstar
|
# homeassistant.components.venstar
|
||||||
venstarcolortouch==0.14
|
venstarcolortouch==0.15
|
||||||
|
|
||||||
# homeassistant.components.vilfo
|
# homeassistant.components.vilfo
|
||||||
vilfo-api-client==0.3.2
|
vilfo-api-client==0.3.2
|
||||||
|
@ -1373,7 +1373,7 @@ uvcclient==0.11.0
|
|||||||
velbus-aio==2021.10.7
|
velbus-aio==2021.10.7
|
||||||
|
|
||||||
# homeassistant.components.venstar
|
# homeassistant.components.venstar
|
||||||
venstarcolortouch==0.14
|
venstarcolortouch==0.15
|
||||||
|
|
||||||
# homeassistant.components.vilfo
|
# homeassistant.components.vilfo
|
||||||
vilfo-api-client==0.3.2
|
vilfo-api-client==0.3.2
|
||||||
|
Loading…
x
Reference in New Issue
Block a user