Honeywell unique id fix (#59393)

* Move error logging and remove reload

* Change device assignment and improve logging

* Use dictionary for devices

* Check if new device exists in API response

* Add test and make loop better

* Make test assert on error in log
This commit is contained in:
RDFurman 2021-12-13 21:38:43 -07:00 committed by GitHub
parent 228f141bfd
commit 1ed6abe23d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 14 deletions

View File

@ -30,14 +30,13 @@ async def async_setup_entry(hass, config):
loc_id = config.data.get(CONF_LOC_ID)
dev_id = config.data.get(CONF_DEV_ID)
devices = []
devices = {}
for location in client.locations_by_id.values():
for device in location.devices_by_id.values():
if (not loc_id or location.locationid == loc_id) and (
not dev_id or device.deviceid == dev_id
):
devices.append(device)
if not loc_id or location.locationid == loc_id:
for device in location.devices_by_id.values():
if not dev_id or device.deviceid == dev_id:
devices[device.deviceid] = device
if len(devices) == 0:
_LOGGER.debug("No devices found")
@ -107,23 +106,30 @@ class HoneywellData:
if self._client is None:
return False
devices = [
refreshed_devices = [
device
for location in self._client.locations_by_id.values()
for device in location.devices_by_id.values()
]
if len(devices) == 0:
_LOGGER.error("Failed to find any devices")
if len(refreshed_devices) == 0:
_LOGGER.error("Failed to find any devices after retry")
return False
self.devices = devices
for updated_device in refreshed_devices:
if updated_device.deviceid in self.devices:
self.devices[updated_device.deviceid] = updated_device
else:
_LOGGER.info(
"New device with ID %s detected, reload the honeywell integration if you want to access it in Home Assistant"
)
await self._hass.config_entries.async_reload(self._config.entry_id)
return True
async def _refresh_devices(self):
"""Refresh each enabled device."""
for device in self.devices:
for device in self.devices.values():
await self._hass.async_add_executor_job(device.refresh)
await asyncio.sleep(UPDATE_LOOP_SLEEP_TIME)
@ -143,11 +149,16 @@ class HoneywellData:
) as exp:
retries -= 1
if retries == 0:
_LOGGER.error(
"Ran out of retry attempts (3 attempts allocated). Error: %s",
exp,
)
raise exp
result = await self._retry()
if not result:
_LOGGER.error("Retry result was empty. Error: %s", exp)
raise exp
_LOGGER.error("SomeComfort update failed, Retrying - Error: %s", exp)
_LOGGER.info("SomeComfort update failed, retrying. Error: %s", exp)

View File

@ -122,7 +122,7 @@ async def async_setup_entry(hass, config, async_add_entities, discovery_info=Non
async_add_entities(
[
HoneywellUSThermostat(data, device, cool_away_temp, heat_away_temp)
for device in data.devices
for device in data.devices.values()
]
)

View File

@ -1,6 +1,8 @@
"""Test honeywell setup process."""
from unittest.mock import patch
from unittest.mock import create_autospec, patch
import somecomfort
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
@ -29,3 +31,20 @@ async def test_setup_multiple_thermostats(
await hass.async_block_till_done()
assert config_entry.state is ConfigEntryState.LOADED
assert hass.states.async_entity_ids_count() == 2
@patch("homeassistant.components.honeywell.UPDATE_LOOP_SLEEP_TIME", 0)
async def test_setup_multiple_thermostats_with_same_deviceid(
hass: HomeAssistant, caplog, config_entry: MockConfigEntry, device, client
) -> None:
"""Test Honeywell TCC API returning duplicate device IDs."""
mock_location2 = create_autospec(somecomfort.Location, instance=True)
mock_location2.locationid.return_value = "location2"
mock_location2.devices_by_id = {device.deviceid: device}
client.locations_by_id["location2"] = mock_location2
config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
assert config_entry.state is ConfigEntryState.LOADED
assert hass.states.async_entity_ids_count() == 1
assert "Platform honeywell does not generate unique IDs" not in caplog.text