Honeywell fixes and improvements (#8756)

* Honeywell fixes and improvements

Give the Honeywell device a state ('On', 'Off', etc) that
can be displayed to user and understood by other components.
Previously this was always 'Unknown'. Update also raises a
state_changed event when a new temperature is polled.

These two together fix an issue (#8688) where Honeywell
climate data couldn't be logged in InfluxDB.

* Roll back some changes

These were not necessary to achieve the result I wanted.

* Renamed RoundThermostat's 'device' member for greater clarity

Now called 'client'

* Improve and simplify discovering thermostat mode

Per code review, this is a rather neater way to discover the thermostat mode

* Update tests for compatibility with new component

The tests previously relied upon the update() method being
called in the constructor. This is no longer the case.

* Address formatting review comment

Parens not necessary

* This system mode is not certain to apply to domestic hot water

Moved the mode lookup to only happen on update of radiator devices,
since hot water devices seem to be treated differently and I can't test.
This commit is contained in:
Dan Sarginson 2017-08-01 15:18:14 +01:00 committed by Martin Hjelmare
parent 075422e7ad
commit 365f21b209
2 changed files with 19 additions and 11 deletions

View File

@ -75,7 +75,8 @@ def _setup_round(username, password, config, add_devices):
zones = evo_api.temperatures(force_refresh=True) zones = evo_api.temperatures(force_refresh=True)
for i, zone in enumerate(zones): for i, zone in enumerate(zones):
add_devices( add_devices(
[RoundThermostat(evo_api, zone['id'], i == 0, away_temp)] [RoundThermostat(evo_api, zone['id'], i == 0, away_temp)],
True
) )
except socket.error: except socket.error:
_LOGGER.error( _LOGGER.error(
@ -115,9 +116,9 @@ def _setup_us(username, password, config, add_devices):
class RoundThermostat(ClimateDevice): class RoundThermostat(ClimateDevice):
"""Representation of a Honeywell Round Connected thermostat.""" """Representation of a Honeywell Round Connected thermostat."""
def __init__(self, device, zone_id, master, away_temp): def __init__(self, client, zone_id, master, away_temp):
"""Initialize the thermostat.""" """Initialize the thermostat."""
self.device = device self.client = client
self._current_temperature = None self._current_temperature = None
self._target_temperature = None self._target_temperature = None
self._name = 'round connected' self._name = 'round connected'
@ -126,7 +127,6 @@ class RoundThermostat(ClimateDevice):
self._is_dhw = False self._is_dhw = False
self._away_temp = away_temp self._away_temp = away_temp
self._away = False self._away = False
self.update()
@property @property
def name(self): def name(self):
@ -155,12 +155,12 @@ class RoundThermostat(ClimateDevice):
temperature = kwargs.get(ATTR_TEMPERATURE) temperature = kwargs.get(ATTR_TEMPERATURE)
if temperature is None: if temperature is None:
return return
self.device.set_temperature(self._name, temperature) self.client.set_temperature(self._name, temperature)
@property @property
def current_operation(self: ClimateDevice) -> str: def current_operation(self: ClimateDevice) -> str:
"""Get the current operation of the system.""" """Get the current operation of the system."""
return getattr(self.device, ATTR_SYSTEM_MODE, None) return getattr(self.client, ATTR_SYSTEM_MODE, None)
@property @property
def is_away_mode_on(self): def is_away_mode_on(self):
@ -169,8 +169,8 @@ class RoundThermostat(ClimateDevice):
def set_operation_mode(self: ClimateDevice, operation_mode: str) -> None: def set_operation_mode(self: ClimateDevice, operation_mode: str) -> None:
"""Set the HVAC mode for the thermostat.""" """Set the HVAC mode for the thermostat."""
if hasattr(self.device, ATTR_SYSTEM_MODE): if hasattr(self.client, ATTR_SYSTEM_MODE):
self.device.system_mode = operation_mode self.client.system_mode = operation_mode
def turn_away_mode_on(self): def turn_away_mode_on(self):
"""Turn away on. """Turn away on.
@ -180,19 +180,19 @@ class RoundThermostat(ClimateDevice):
it doesn't get overwritten when away mode is switched on. it doesn't get overwritten when away mode is switched on.
""" """
self._away = True self._away = True
self.device.set_temperature(self._name, self._away_temp) self.client.set_temperature(self._name, self._away_temp)
def turn_away_mode_off(self): def turn_away_mode_off(self):
"""Turn away off.""" """Turn away off."""
self._away = False self._away = False
self.device.cancel_temp_override(self._name) self.client.cancel_temp_override(self._name)
def update(self): def update(self):
"""Get the latest date.""" """Get the latest date."""
try: try:
# Only refresh if this is the "master" device, # Only refresh if this is the "master" device,
# others will pick up the cache # others will pick up the cache
for val in self.device.temperatures(force_refresh=self._master): for val in self.client.temperatures(force_refresh=self._master):
if val['id'] == self._id: if val['id'] == self._id:
data = val data = val
@ -210,6 +210,12 @@ class RoundThermostat(ClimateDevice):
self._name = data['name'] self._name = data['name']
self._is_dhw = False self._is_dhw = False
# The underlying library doesn't expose the thermostat's mode
# but we can pull it out of the big dictionary of information.
device = self.client.devices[self._id]
self.client.system_mode = device[
'thermostat']['changeableValues']['mode']
class HoneywellUSThermostat(ClimateDevice): class HoneywellUSThermostat(ClimateDevice):
"""Representation of a Honeywell US Thermostat.""" """Representation of a Honeywell US Thermostat."""

View File

@ -275,8 +275,10 @@ class TestHoneywellRound(unittest.TestCase):
self.device.temperatures.side_effect = fake_temperatures self.device.temperatures.side_effect = fake_temperatures
self.round1 = honeywell.RoundThermostat(self.device, '1', self.round1 = honeywell.RoundThermostat(self.device, '1',
True, 16) True, 16)
self.round1.update()
self.round2 = honeywell.RoundThermostat(self.device, '2', self.round2 = honeywell.RoundThermostat(self.device, '2',
False, 17) False, 17)
self.round2.update()
def test_attributes(self): def test_attributes(self):
"""Test the attributes.""" """Test the attributes."""