Fix coordinator wiring after refactor
Two bugs left from the hass.data move that surfaced as soon as the integration ran on the live HA: * In async_setup_entry, devices were stored in hass.data AFTER coordinator.async_config_entry_first_refresh(), but _async_update_data reads them from hass.data — so the very first refresh raised KeyError 'devices' and the entry stayed in setup_retry. Move the hass.data update before first_refresh. * SmartThingsDeviceTracker called self.async_on_update(...) which isn't a method on TrackerEntity. Without a working listener registration the tracker stayed restored=true / unavailable forever. Subscribe in async_added_to_hass and use async_on_remove for cleanup, which is the documented pattern. Verified end-to-end on a live HA: phones/watch produce GPS, battery sensors populate, and the Ring button triggers a SmartTag. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
73aa86cfb5
commit
7457a8284b
2 changed files with 17 additions and 9 deletions
|
|
@ -55,25 +55,27 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
|
|
||||||
# Load all SmartThings-Find devices from the users account
|
# Load all SmartThings-Find devices from the users account
|
||||||
devices = await get_devices(hass, session, entry.entry_id)
|
devices = await get_devices(hass, session, entry.entry_id)
|
||||||
|
|
||||||
# Create an update coordinator. This is responsible to regularly
|
# Create an update coordinator. This is responsible to regularly
|
||||||
# fetch data from STF and update the device_tracker and sensor
|
# fetch data from STF and update the device_tracker and sensor
|
||||||
# entities
|
# entities
|
||||||
update_interval = entry.options.get(CONF_UPDATE_INTERVAL, CONF_UPDATE_INTERVAL_DEFAULT)
|
update_interval = entry.options.get(CONF_UPDATE_INTERVAL, CONF_UPDATE_INTERVAL_DEFAULT)
|
||||||
coordinator = SmartThingsFindCoordinator(hass, session, entry.entry_id, update_interval)
|
coordinator = SmartThingsFindCoordinator(hass, session, entry.entry_id, update_interval)
|
||||||
|
|
||||||
# This is what makes the whole integration slow to load (around 10-15
|
# Store everything the coordinator needs BEFORE the first refresh,
|
||||||
# seconds for my 15 devices) but it is the right way to do it. Only if
|
# because _async_update_data reads `devices` out of hass.data.
|
||||||
# it succeeds, the integration will be marked as successfully loaded.
|
|
||||||
await coordinator.async_config_entry_first_refresh()
|
|
||||||
|
|
||||||
hass.data[DOMAIN][entry.entry_id].update({
|
hass.data[DOMAIN][entry.entry_id].update({
|
||||||
CONF_JSESSIONID: jsessionid,
|
CONF_JSESSIONID: jsessionid,
|
||||||
"session": session,
|
"session": session,
|
||||||
"coordinator": coordinator,
|
"coordinator": coordinator,
|
||||||
"devices": devices
|
"devices": devices,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# This is what makes the whole integration slow to load (around 10-15
|
||||||
|
# seconds for my 15 devices) but it is the right way to do it. Only if
|
||||||
|
# it succeeds, the integration will be marked as successfully loaded.
|
||||||
|
await coordinator.async_config_entry_first_refresh()
|
||||||
|
|
||||||
hass.async_create_task(
|
hass.async_create_task(
|
||||||
hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,14 @@ class SmartThingsDeviceTracker(DeviceTrackerEntity):
|
||||||
|
|
||||||
if 'icons' in device['data'] and 'coloredIcon' in device['data']['icons']:
|
if 'icons' in device['data'] and 'coloredIcon' in device['data']['icons']:
|
||||||
self._attr_entity_picture = device['data']['icons']['coloredIcon']
|
self._attr_entity_picture = device['data']['icons']['coloredIcon']
|
||||||
self.async_on_update(coordinator.async_add_listener(self.async_write_ha_state))
|
|
||||||
|
async def async_added_to_hass(self) -> None:
|
||||||
|
"""Subscribe to coordinator updates once added to HA."""
|
||||||
|
await super().async_added_to_hass()
|
||||||
|
self.async_on_remove(
|
||||||
|
self.coordinator.async_add_listener(self.async_write_ha_state)
|
||||||
|
)
|
||||||
|
|
||||||
def async_write_ha_state(self):
|
def async_write_ha_state(self):
|
||||||
if not self.enabled:
|
if not self.enabled:
|
||||||
_LOGGER.debug(f"Ignoring state write request for disabled entity '{self.entity_id}'")
|
_LOGGER.debug(f"Ignoring state write request for disabled entity '{self.entity_id}'")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue