mirror of
https://github.com/home-assistant/core.git
synced 2026-09-24 07:25:52 -05:00
Centralize ViCare error handling in base entity class (#162619)
This commit is contained in:
@@ -12,14 +12,7 @@ from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig
|
||||
from PyViCare.PyViCareHeatingDevice import (
|
||||
HeatingDeviceWithComponent as PyViCareHeatingDeviceComponent,
|
||||
)
|
||||
from PyViCare.PyViCareUtils import (
|
||||
PyViCareDeviceCommunicationError,
|
||||
PyViCareInternalServerError,
|
||||
PyViCareInvalidDataError,
|
||||
PyViCareNotSupportedFeatureError,
|
||||
PyViCareRateLimitError,
|
||||
)
|
||||
import requests
|
||||
from PyViCare.PyViCareUtils import PyViCareNotSupportedFeatureError
|
||||
|
||||
from homeassistant.components.binary_sensor import (
|
||||
BinarySensorDeviceClass,
|
||||
@@ -233,18 +226,5 @@ class ViCareBinarySensor(ViCareEntity, BinarySensorEntity):
|
||||
|
||||
def update(self) -> None:
|
||||
"""Update state of sensor."""
|
||||
try:
|
||||
with suppress(PyViCareNotSupportedFeatureError):
|
||||
self._attr_is_on = self.entity_description.value_getter(self._api)
|
||||
except requests.exceptions.ConnectionError:
|
||||
_LOGGER.error("Unable to retrieve data from ViCare server")
|
||||
except ValueError:
|
||||
_LOGGER.error("Unable to decode data from ViCare server")
|
||||
except PyViCareRateLimitError as limit_exception:
|
||||
_LOGGER.error("Vicare API rate limit exceeded: %s", limit_exception)
|
||||
except PyViCareInvalidDataError as invalid_data_exception:
|
||||
_LOGGER.error("Invalid data from Vicare server: %s", invalid_data_exception)
|
||||
except PyViCareDeviceCommunicationError as comm_exception:
|
||||
_LOGGER.warning("Device communication error: %s", comm_exception)
|
||||
except PyViCareInternalServerError as server_exception:
|
||||
_LOGGER.warning("Vicare server error: %s", server_exception)
|
||||
with self.vicare_api_handler(), suppress(PyViCareNotSupportedFeatureError):
|
||||
self._attr_is_on = self.entity_description.value_getter(self._api)
|
||||
|
||||
@@ -8,14 +8,7 @@ import logging
|
||||
|
||||
from PyViCare.PyViCareDevice import Device as PyViCareDevice
|
||||
from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig
|
||||
from PyViCare.PyViCareUtils import (
|
||||
PyViCareDeviceCommunicationError,
|
||||
PyViCareInternalServerError,
|
||||
PyViCareInvalidDataError,
|
||||
PyViCareNotSupportedFeatureError,
|
||||
PyViCareRateLimitError,
|
||||
)
|
||||
import requests
|
||||
from PyViCare.PyViCareUtils import PyViCareNotSupportedFeatureError
|
||||
|
||||
from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
|
||||
from homeassistant.const import EntityCategory
|
||||
@@ -104,18 +97,5 @@ class ViCareButton(ViCareEntity, ButtonEntity):
|
||||
|
||||
def press(self) -> None:
|
||||
"""Handle the button press."""
|
||||
try:
|
||||
with suppress(PyViCareNotSupportedFeatureError):
|
||||
self.entity_description.value_setter(self._api)
|
||||
except requests.exceptions.ConnectionError:
|
||||
_LOGGER.error("Unable to retrieve data from ViCare server")
|
||||
except ValueError:
|
||||
_LOGGER.error("Unable to decode data from ViCare server")
|
||||
except PyViCareRateLimitError as limit_exception:
|
||||
_LOGGER.error("Vicare API rate limit exceeded: %s", limit_exception)
|
||||
except PyViCareInvalidDataError as invalid_data_exception:
|
||||
_LOGGER.error("Invalid data from Vicare server: %s", invalid_data_exception)
|
||||
except PyViCareDeviceCommunicationError as comm_exception:
|
||||
_LOGGER.warning("Device communication error: %s", comm_exception)
|
||||
except PyViCareInternalServerError as server_exception:
|
||||
_LOGGER.warning("Vicare server error: %s", server_exception)
|
||||
with self.vicare_api_handler(), suppress(PyViCareNotSupportedFeatureError):
|
||||
self.entity_description.value_setter(self._api)
|
||||
|
||||
@@ -11,13 +11,8 @@ from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig
|
||||
from PyViCare.PyViCareHeatingDevice import HeatingCircuit as PyViCareHeatingCircuit
|
||||
from PyViCare.PyViCareUtils import (
|
||||
PyViCareCommandError,
|
||||
PyViCareDeviceCommunicationError,
|
||||
PyViCareInternalServerError,
|
||||
PyViCareInvalidDataError,
|
||||
PyViCareNotSupportedFeatureError,
|
||||
PyViCareRateLimitError,
|
||||
)
|
||||
import requests
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.climate import (
|
||||
@@ -160,7 +155,7 @@ class ViCareClimate(ViCareEntity, ClimateEntity):
|
||||
|
||||
def update(self) -> None:
|
||||
"""Let HA know there has been an update from the ViCare API."""
|
||||
try:
|
||||
with self.vicare_api_handler():
|
||||
_room_temperature = None
|
||||
with suppress(PyViCareNotSupportedFeatureError):
|
||||
self._attributes["room_temperature"] = _room_temperature = (
|
||||
@@ -216,19 +211,6 @@ class ViCareClimate(ViCareEntity, ClimateEntity):
|
||||
self._current_action or compressor.getActive()
|
||||
)
|
||||
|
||||
except requests.exceptions.ConnectionError:
|
||||
_LOGGER.error("Unable to retrieve data from ViCare server")
|
||||
except PyViCareRateLimitError as limit_exception:
|
||||
_LOGGER.error("Vicare API rate limit exceeded: %s", limit_exception)
|
||||
except ValueError:
|
||||
_LOGGER.error("Unable to decode data from ViCare server")
|
||||
except PyViCareInvalidDataError as invalid_data_exception:
|
||||
_LOGGER.error("Invalid data from Vicare server: %s", invalid_data_exception)
|
||||
except PyViCareDeviceCommunicationError as comm_exception:
|
||||
_LOGGER.warning("Device communication error: %s", comm_exception)
|
||||
except PyViCareInternalServerError as server_exception:
|
||||
_LOGGER.warning("Vicare server error: %s", server_exception)
|
||||
|
||||
@property
|
||||
def hvac_mode(self) -> HVACMode | None:
|
||||
"""Return current hvac mode."""
|
||||
|
||||
@@ -1,22 +1,53 @@
|
||||
"""Entities for the ViCare integration."""
|
||||
|
||||
from collections.abc import Generator
|
||||
from contextlib import contextmanager
|
||||
import logging
|
||||
|
||||
from PyViCare.PyViCareDevice import Device as PyViCareDevice
|
||||
from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig
|
||||
from PyViCare.PyViCareHeatingDevice import (
|
||||
HeatingDeviceWithComponent as PyViCareHeatingDeviceComponent,
|
||||
)
|
||||
from PyViCare.PyViCareUtils import (
|
||||
PyViCareDeviceCommunicationError,
|
||||
PyViCareInternalServerError,
|
||||
PyViCareInvalidDataError,
|
||||
PyViCareRateLimitError,
|
||||
)
|
||||
from requests.exceptions import ConnectionError as RequestConnectionError
|
||||
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
from .const import DOMAIN, VIESSMANN_DEVELOPER_PORTAL
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ViCareEntity(Entity):
|
||||
"""Base class for ViCare entities."""
|
||||
|
||||
_attr_has_entity_name = True
|
||||
|
||||
@contextmanager
|
||||
def vicare_api_handler(self) -> Generator[None]:
|
||||
"""Handle common ViCare API errors."""
|
||||
try:
|
||||
yield
|
||||
except RequestConnectionError:
|
||||
_LOGGER.error("Unable to retrieve data from ViCare server")
|
||||
except ValueError:
|
||||
_LOGGER.error("Unable to decode data from ViCare server")
|
||||
except PyViCareRateLimitError as err:
|
||||
_LOGGER.error("ViCare API rate limit exceeded: %s", err)
|
||||
except PyViCareInvalidDataError as err:
|
||||
_LOGGER.error("Invalid data from ViCare server: %s", err)
|
||||
except PyViCareDeviceCommunicationError as err:
|
||||
_LOGGER.warning("Device communication error: %s", err)
|
||||
except PyViCareInternalServerError as err:
|
||||
_LOGGER.warning("ViCare server error: %s", err)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
unique_id_suffix: str,
|
||||
|
||||
@@ -9,14 +9,7 @@ from typing import Any
|
||||
|
||||
from PyViCare.PyViCareDevice import Device as PyViCareDevice
|
||||
from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig
|
||||
from PyViCare.PyViCareUtils import (
|
||||
PyViCareDeviceCommunicationError,
|
||||
PyViCareInternalServerError,
|
||||
PyViCareInvalidDataError,
|
||||
PyViCareNotSupportedFeatureError,
|
||||
PyViCareRateLimitError,
|
||||
)
|
||||
from requests.exceptions import ConnectionError as RequestConnectionError
|
||||
from PyViCare.PyViCareUtils import PyViCareNotSupportedFeatureError
|
||||
|
||||
from homeassistant.components.fan import FanEntity, FanEntityFeature
|
||||
from homeassistant.core import HomeAssistant
|
||||
@@ -173,7 +166,7 @@ class ViCareFan(ViCareEntity, FanEntity):
|
||||
def update(self) -> None:
|
||||
"""Update state of fan."""
|
||||
level: str | None = None
|
||||
try:
|
||||
with self.vicare_api_handler():
|
||||
with suppress(PyViCareNotSupportedFeatureError):
|
||||
self._attr_preset_mode = VentilationMode.from_vicare_mode(
|
||||
self._api.getActiveVentilationMode()
|
||||
@@ -187,18 +180,6 @@ class ViCareFan(ViCareEntity, FanEntity):
|
||||
)
|
||||
else:
|
||||
self._attr_percentage = 0
|
||||
except RequestConnectionError:
|
||||
_LOGGER.error("Unable to retrieve data from ViCare server")
|
||||
except ValueError:
|
||||
_LOGGER.error("Unable to decode data from ViCare server")
|
||||
except PyViCareRateLimitError as limit_exception:
|
||||
_LOGGER.error("Vicare API rate limit exceeded: %s", limit_exception)
|
||||
except PyViCareInvalidDataError as invalid_data_exception:
|
||||
_LOGGER.error("Invalid data from Vicare server: %s", invalid_data_exception)
|
||||
except PyViCareDeviceCommunicationError as comm_exception:
|
||||
_LOGGER.warning("Device communication error: %s", comm_exception)
|
||||
except PyViCareInternalServerError as server_exception:
|
||||
_LOGGER.warning("Vicare server error: %s", server_exception)
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool | None:
|
||||
|
||||
@@ -13,14 +13,7 @@ from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig
|
||||
from PyViCare.PyViCareHeatingDevice import (
|
||||
HeatingDeviceWithComponent as PyViCareHeatingDeviceComponent,
|
||||
)
|
||||
from PyViCare.PyViCareUtils import (
|
||||
PyViCareDeviceCommunicationError,
|
||||
PyViCareInternalServerError,
|
||||
PyViCareInvalidDataError,
|
||||
PyViCareNotSupportedFeatureError,
|
||||
PyViCareRateLimitError,
|
||||
)
|
||||
from requests.exceptions import ConnectionError as RequestConnectionError
|
||||
from PyViCare.PyViCareUtils import PyViCareNotSupportedFeatureError
|
||||
|
||||
from homeassistant.components.number import (
|
||||
NumberDeviceClass,
|
||||
@@ -437,38 +430,23 @@ class ViCareNumber(ViCareEntity, NumberEntity):
|
||||
|
||||
def update(self) -> None:
|
||||
"""Update state of number."""
|
||||
try:
|
||||
with suppress(PyViCareNotSupportedFeatureError):
|
||||
self._attr_native_value = self.entity_description.value_getter(
|
||||
self._api
|
||||
)
|
||||
with self.vicare_api_handler(), suppress(PyViCareNotSupportedFeatureError):
|
||||
self._attr_native_value = self.entity_description.value_getter(self._api)
|
||||
|
||||
if min_value := _get_value(
|
||||
self.entity_description.min_value_getter, self._api
|
||||
):
|
||||
self._attr_native_min_value = min_value
|
||||
if min_value := _get_value(
|
||||
self.entity_description.min_value_getter, self._api
|
||||
):
|
||||
self._attr_native_min_value = min_value
|
||||
|
||||
if max_value := _get_value(
|
||||
self.entity_description.max_value_getter, self._api
|
||||
):
|
||||
self._attr_native_max_value = max_value
|
||||
if max_value := _get_value(
|
||||
self.entity_description.max_value_getter, self._api
|
||||
):
|
||||
self._attr_native_max_value = max_value
|
||||
|
||||
if stepping_value := _get_value(
|
||||
self.entity_description.stepping_getter, self._api
|
||||
):
|
||||
self._attr_native_step = stepping_value
|
||||
except RequestConnectionError:
|
||||
_LOGGER.error("Unable to retrieve data from ViCare server")
|
||||
except ValueError:
|
||||
_LOGGER.error("Unable to decode data from ViCare server")
|
||||
except PyViCareRateLimitError as limit_exception:
|
||||
_LOGGER.error("Vicare API rate limit exceeded: %s", limit_exception)
|
||||
except PyViCareInvalidDataError as invalid_data_exception:
|
||||
_LOGGER.error("Invalid data from Vicare server: %s", invalid_data_exception)
|
||||
except PyViCareDeviceCommunicationError as comm_exception:
|
||||
_LOGGER.warning("Device communication error: %s", comm_exception)
|
||||
except PyViCareInternalServerError as server_exception:
|
||||
_LOGGER.warning("Vicare server error: %s", server_exception)
|
||||
if stepping_value := _get_value(
|
||||
self.entity_description.stepping_getter, self._api
|
||||
):
|
||||
self._attr_native_step = stepping_value
|
||||
|
||||
|
||||
def _get_value(
|
||||
|
||||
@@ -12,14 +12,7 @@ from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig
|
||||
from PyViCare.PyViCareHeatingDevice import (
|
||||
HeatingDeviceWithComponent as PyViCareHeatingDeviceComponent,
|
||||
)
|
||||
from PyViCare.PyViCareUtils import (
|
||||
PyViCareDeviceCommunicationError,
|
||||
PyViCareInternalServerError,
|
||||
PyViCareInvalidDataError,
|
||||
PyViCareNotSupportedFeatureError,
|
||||
PyViCareRateLimitError,
|
||||
)
|
||||
import requests
|
||||
from PyViCare.PyViCareUtils import PyViCareNotSupportedFeatureError
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
@@ -1556,26 +1549,11 @@ class ViCareSensor(ViCareEntity, SensorEntity):
|
||||
def update(self) -> None:
|
||||
"""Update state of sensor."""
|
||||
vicare_unit = None
|
||||
try:
|
||||
with suppress(PyViCareNotSupportedFeatureError):
|
||||
self._attr_native_value = self.entity_description.value_getter(
|
||||
self._api
|
||||
)
|
||||
with self.vicare_api_handler(), suppress(PyViCareNotSupportedFeatureError):
|
||||
self._attr_native_value = self.entity_description.value_getter(self._api)
|
||||
|
||||
if self.entity_description.unit_getter:
|
||||
vicare_unit = self.entity_description.unit_getter(self._api)
|
||||
except requests.exceptions.ConnectionError:
|
||||
_LOGGER.error("Unable to retrieve data from ViCare server")
|
||||
except ValueError:
|
||||
_LOGGER.error("Unable to decode data from ViCare server")
|
||||
except PyViCareRateLimitError as limit_exception:
|
||||
_LOGGER.error("Vicare API rate limit exceeded: %s", limit_exception)
|
||||
except PyViCareInvalidDataError as invalid_data_exception:
|
||||
_LOGGER.error("Invalid data from Vicare server: %s", invalid_data_exception)
|
||||
except PyViCareDeviceCommunicationError as comm_exception:
|
||||
_LOGGER.warning("Device communication error: %s", comm_exception)
|
||||
except PyViCareInternalServerError as server_exception:
|
||||
_LOGGER.warning("Vicare server error: %s", server_exception)
|
||||
if self.entity_description.unit_getter:
|
||||
vicare_unit = self.entity_description.unit_getter(self._api)
|
||||
|
||||
if vicare_unit is not None:
|
||||
if (
|
||||
|
||||
@@ -9,14 +9,7 @@ from typing import Any
|
||||
from PyViCare.PyViCareDevice import Device as PyViCareDevice
|
||||
from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig
|
||||
from PyViCare.PyViCareHeatingDevice import HeatingCircuit as PyViCareHeatingCircuit
|
||||
from PyViCare.PyViCareUtils import (
|
||||
PyViCareDeviceCommunicationError,
|
||||
PyViCareInternalServerError,
|
||||
PyViCareInvalidDataError,
|
||||
PyViCareNotSupportedFeatureError,
|
||||
PyViCareRateLimitError,
|
||||
)
|
||||
import requests
|
||||
from PyViCare.PyViCareUtils import PyViCareNotSupportedFeatureError
|
||||
|
||||
from homeassistant.components.water_heater import (
|
||||
WaterHeaterEntity,
|
||||
@@ -120,7 +113,7 @@ class ViCareWater(ViCareEntity, WaterHeaterEntity):
|
||||
|
||||
def update(self) -> None:
|
||||
"""Let HA know there has been an update from the ViCare API."""
|
||||
try:
|
||||
with self.vicare_api_handler():
|
||||
with suppress(PyViCareNotSupportedFeatureError):
|
||||
self._attr_current_temperature = (
|
||||
self._api.getDomesticHotWaterStorageTemperature()
|
||||
@@ -137,19 +130,6 @@ class ViCareWater(ViCareEntity, WaterHeaterEntity):
|
||||
with suppress(PyViCareNotSupportedFeatureError):
|
||||
self._dhw_active = self._api.getDomesticHotWaterActive()
|
||||
|
||||
except requests.exceptions.ConnectionError:
|
||||
_LOGGER.error("Unable to retrieve data from ViCare server")
|
||||
except PyViCareRateLimitError as limit_exception:
|
||||
_LOGGER.error("Vicare API rate limit exceeded: %s", limit_exception)
|
||||
except ValueError:
|
||||
_LOGGER.error("Unable to decode data from ViCare server")
|
||||
except PyViCareInvalidDataError as invalid_data_exception:
|
||||
_LOGGER.error("Invalid data from Vicare server: %s", invalid_data_exception)
|
||||
except PyViCareDeviceCommunicationError as comm_exception:
|
||||
_LOGGER.warning("Device communication error: %s", comm_exception)
|
||||
except PyViCareInternalServerError as server_exception:
|
||||
_LOGGER.warning("Vicare server error: %s", server_exception)
|
||||
|
||||
def set_temperature(self, **kwargs: Any) -> None:
|
||||
"""Set new target temperatures."""
|
||||
if (temp := kwargs.get(ATTR_TEMPERATURE)) is not None:
|
||||
|
||||
Reference in New Issue
Block a user