Handle exceptions from PyViCare library (#28536)

* ViCare: Handle exceptions from PyViCare library (#28072)

Sometimes Viessmann server failures or other connection problems may
lead to exceptions thrown when updating data.

This commit handles those exceptions with some error logging and
makes sure that the component does not break completely in that case.

* Remove unneeded returns

* Remove unneeded returns
This commit is contained in:
Hans Oischinger 2019-11-06 22:46:18 +01:00 committed by Martin Hjelmare
parent bb37bc32e3
commit 3d2ff841d3
2 changed files with 70 additions and 48 deletions

View File

@ -1,5 +1,7 @@
"""Viessmann ViCare climate device.""" """Viessmann ViCare climate device."""
import logging import logging
import requests
import simplejson
from homeassistant.components.climate import ClimateDevice from homeassistant.components.climate import ClimateDevice
from homeassistant.components.climate.const import ( from homeassistant.components.climate.const import (
@ -111,55 +113,64 @@ class ViCareClimate(ClimateDevice):
def update(self): def update(self):
"""Let HA know there has been an update from the ViCare API.""" """Let HA know there has been an update from the ViCare API."""
_room_temperature = self._api.getRoomTemperature() try:
_supply_temperature = self._api.getSupplyTemperature() _room_temperature = self._api.getRoomTemperature()
if _room_temperature is not None and _room_temperature != PYVICARE_ERROR: _supply_temperature = self._api.getSupplyTemperature()
self._current_temperature = _room_temperature if _room_temperature is not None and _room_temperature != PYVICARE_ERROR:
elif _supply_temperature != PYVICARE_ERROR: self._current_temperature = _room_temperature
self._current_temperature = _supply_temperature elif _supply_temperature != PYVICARE_ERROR:
else: self._current_temperature = _supply_temperature
self._current_temperature = None else:
self._current_program = self._api.getActiveProgram() self._current_temperature = None
self._current_program = self._api.getActiveProgram()
# The getCurrentDesiredTemperature call can yield 'error' (str) when the system is in standby # The getCurrentDesiredTemperature call can yield 'error' (str) when the system is in standby
desired_temperature = self._api.getCurrentDesiredTemperature() desired_temperature = self._api.getCurrentDesiredTemperature()
if desired_temperature == PYVICARE_ERROR: if desired_temperature == PYVICARE_ERROR:
desired_temperature = None desired_temperature = None
self._target_temperature = desired_temperature self._target_temperature = desired_temperature
self._current_mode = self._api.getActiveMode() self._current_mode = self._api.getActiveMode()
# Update the generic device attributes # Update the generic device attributes
self._attributes = {} self._attributes = {}
self._attributes["room_temperature"] = _room_temperature self._attributes["room_temperature"] = _room_temperature
self._attributes["supply_temperature"] = _supply_temperature self._attributes["supply_temperature"] = _supply_temperature
self._attributes["outside_temperature"] = self._api.getOutsideTemperature() self._attributes["outside_temperature"] = self._api.getOutsideTemperature()
self._attributes["active_vicare_program"] = self._current_program self._attributes["active_vicare_program"] = self._current_program
self._attributes["active_vicare_mode"] = self._current_mode self._attributes["active_vicare_mode"] = self._current_mode
self._attributes["heating_curve_slope"] = self._api.getHeatingCurveSlope() self._attributes["heating_curve_slope"] = self._api.getHeatingCurveSlope()
self._attributes["heating_curve_shift"] = self._api.getHeatingCurveShift() self._attributes["heating_curve_shift"] = self._api.getHeatingCurveShift()
self._attributes[ self._attributes[
"month_since_last_service" "month_since_last_service"
] = self._api.getMonthSinceLastService() ] = self._api.getMonthSinceLastService()
self._attributes["date_last_service"] = self._api.getLastServiceDate() self._attributes["date_last_service"] = self._api.getLastServiceDate()
self._attributes["error_history"] = self._api.getErrorHistory() self._attributes["error_history"] = self._api.getErrorHistory()
self._attributes["active_error"] = self._api.getActiveError() self._attributes["active_error"] = self._api.getActiveError()
self._attributes[ self._attributes[
"circulationpump_active" "circulationpump_active"
] = self._api.getCirculationPumpActive() ] = self._api.getCirculationPumpActive()
# Update the specific device attributes # Update the specific device attributes
if self._heating_type == HeatingType.gas: if self._heating_type == HeatingType.gas:
self._current_action = self._api.getBurnerActive() self._current_action = self._api.getBurnerActive()
self._attributes["burner_modulation"] = self._api.getBurnerModulation() self._attributes["burner_modulation"] = self._api.getBurnerModulation()
self._attributes["boiler_temperature"] = self._api.getBoilerTemperature() self._attributes[
"boiler_temperature"
] = self._api.getBoilerTemperature()
elif self._heating_type == HeatingType.heatpump: elif self._heating_type == HeatingType.heatpump:
self._current_action = self._api.getCompressorActive() self._current_action = self._api.getCompressorActive()
self._attributes["return_temperature"] = self._api.getReturnTemperature() self._attributes[
"return_temperature"
] = self._api.getReturnTemperature()
except requests.exceptions.ConnectionError:
_LOGGER.error("Unable to retrieve data from ViCare server")
except simplejson.errors.JSONDecodeError:
_LOGGER.error("Unable to decode data from ViCare server")
@property @property
def supported_features(self): def supported_features(self):

View File

@ -1,5 +1,7 @@
"""Viessmann ViCare water_heater device.""" """Viessmann ViCare water_heater device."""
import logging import logging
import requests
import simplejson
from homeassistant.components.water_heater import ( from homeassistant.components.water_heater import (
SUPPORT_TARGET_TEMPERATURE, SUPPORT_TARGET_TEMPERATURE,
@ -41,6 +43,8 @@ HA_TO_VICARE_HVAC_DHW = {
OPERATION_MODE_ON: VICARE_MODE_DHW, OPERATION_MODE_ON: VICARE_MODE_DHW,
} }
PYVICARE_ERROR = "error"
def setup_platform(hass, config, add_entities, discovery_info=None): def setup_platform(hass, config, add_entities, discovery_info=None):
"""Create the ViCare water_heater devices.""" """Create the ViCare water_heater devices."""
@ -75,15 +79,22 @@ class ViCareWater(WaterHeaterDevice):
def update(self): def update(self):
"""Let HA know there has been an update from the ViCare API.""" """Let HA know there has been an update from the ViCare API."""
current_temperature = self._api.getDomesticHotWaterStorageTemperature() try:
if current_temperature is not None and current_temperature != "error": current_temperature = self._api.getDomesticHotWaterStorageTemperature()
self._current_temperature = current_temperature if current_temperature != PYVICARE_ERROR:
else: self._current_temperature = current_temperature
self._current_temperature = None else:
self._current_temperature = None
self._target_temperature = self._api.getDomesticHotWaterConfiguredTemperature() self._target_temperature = (
self._api.getDomesticHotWaterConfiguredTemperature()
)
self._current_mode = self._api.getActiveMode() self._current_mode = self._api.getActiveMode()
except requests.exceptions.ConnectionError:
_LOGGER.error("Unable to retrieve data from ViCare server")
except simplejson.errors.JSONDecodeError:
_LOGGER.error("Unable to decode data from ViCare server")
@property @property
def supported_features(self): def supported_features(self):