From 0eb82b016ee128940a0e914fb353e83c67f16ddf Mon Sep 17 00:00:00 2001 From: Daniel Raper Date: Thu, 21 Nov 2024 14:16:49 +0000 Subject: [PATCH] Fix hass.data storage to add account_id --- custom_components/nissan_connect/__init__.py | 17 +++++++++++------ .../nissan_connect/binary_sensor.py | 6 ++++-- custom_components/nissan_connect/button.py | 10 ++++++---- custom_components/nissan_connect/climate.py | 8 +++++--- custom_components/nissan_connect/coordinator.py | 13 ++++++++----- .../nissan_connect/device_tracker.py | 6 ++++-- .../nissan_connect/kamereon/kamereon.py | 2 +- custom_components/nissan_connect/sensor.py | 8 +++++--- 8 files changed, 44 insertions(+), 26 deletions(-) diff --git a/custom_components/nissan_connect/__init__.py b/custom_components/nissan_connect/__init__.py index fe08ecb..f994023 100644 --- a/custom_components/nissan_connect/__init__.py +++ b/custom_components/nissan_connect/__init__.py @@ -14,24 +14,29 @@ async def async_setup(hass, config) -> bool: async def async_update_listener(hass, entry): """Handle options flow credentials update.""" config = entry.data + account_id = config['email'] + # Loop each vehicle and update its session with the new credentials - for vehicle in hass.data[DOMAIN][DATA_VEHICLES]: - await hass.async_add_executor_job(hass.data[DOMAIN][DATA_VEHICLES][vehicle].session.login, + for vehicle in hass.data[DOMAIN][account_id][DATA_VEHICLES]: + await hass.async_add_executor_job(hass.data[DOMAIN][account_id][DATA_VEHICLES][vehicle].session.login, config.get("email"), config.get("password") ) # Update intervals for coordinators - hass.data[DOMAIN][DATA_COORDINATOR_STATISTICS].update_interval = timedelta(minutes=config.get("interval_statistics", DEFAULT_INTERVAL_STATISTICS)) - hass.data[DOMAIN][DATA_COORDINATOR_FETCH].update_interval = timedelta(minutes=config.get("interval_fetch", DEFAULT_INTERVAL_FETCH)) + hass.data[DOMAIN][account_id][DATA_COORDINATOR_STATISTICS].update_interval = timedelta(minutes=config.get("interval_statistics", DEFAULT_INTERVAL_STATISTICS)) + hass.data[DOMAIN][account_id][DATA_COORDINATOR_FETCH].update_interval = timedelta(minutes=config.get("interval_fetch", DEFAULT_INTERVAL_FETCH)) # Refresh fetch coordinator - await hass.data[DOMAIN][DATA_COORDINATOR_FETCH].async_refresh() + await hass.data[DOMAIN][account_id][DATA_COORDINATOR_FETCH].async_refresh() async def async_setup_entry(hass, entry): """This is called from the config flow.""" + account_id = entry.data['email'] + hass.data.setdefault(DOMAIN, {}) + hass.data[DOMAIN].setdefault(account_id, {}) config = dict(entry.data) @@ -40,7 +45,7 @@ async def async_setup_entry(hass, entry): unique_id=entry.unique_id ) - data = hass.data[DOMAIN] = { + data = hass.data[DOMAIN][account_id] = { DATA_VEHICLES: {} } diff --git a/custom_components/nissan_connect/binary_sensor.py b/custom_components/nissan_connect/binary_sensor.py index f8aaf0a..5aa2a33 100644 --- a/custom_components/nissan_connect/binary_sensor.py +++ b/custom_components/nissan_connect/binary_sensor.py @@ -8,8 +8,10 @@ async def async_setup_entry(hass, config, async_add_entities): """Set up the Kamereon sensors.""" - data = hass.data[DOMAIN][DATA_VEHICLES] - coordinator = hass.data[DOMAIN][DATA_COORDINATOR_FETCH] + account_id = config.data['email'] + + data = hass.data[DOMAIN][account_id][DATA_VEHICLES] + coordinator = hass.data[DOMAIN][account_id][DATA_COORDINATOR_FETCH] entities = [] diff --git a/custom_components/nissan_connect/button.py b/custom_components/nissan_connect/button.py index bdb9a64..0b6c6f9 100644 --- a/custom_components/nissan_connect/button.py +++ b/custom_components/nissan_connect/button.py @@ -12,10 +12,12 @@ async def async_setup_entry(hass, config, async_add_entities): - data = hass.data[DOMAIN][DATA_VEHICLES] - coordinator = hass.data[DOMAIN][DATA_COORDINATOR_POLL] - coordinator_fetch = hass.data[DOMAIN][DATA_COORDINATOR_FETCH] - stats_coordinator = hass.data[DOMAIN][DATA_COORDINATOR_STATISTICS] + account_id = config.data['email'] + + data = hass.data[DOMAIN][account_id][DATA_VEHICLES] + coordinator = hass.data[DOMAIN][account_id][DATA_COORDINATOR_POLL] + coordinator_fetch = hass.data[DOMAIN][account_id][DATA_COORDINATOR_FETCH] + stats_coordinator = hass.data[DOMAIN][account_id][DATA_COORDINATOR_STATISTICS] entities = [] diff --git a/custom_components/nissan_connect/climate.py b/custom_components/nissan_connect/climate.py index 88a9178..9f85d99 100644 --- a/custom_components/nissan_connect/climate.py +++ b/custom_components/nissan_connect/climate.py @@ -19,8 +19,10 @@ async def async_setup_entry(hass, config, async_add_entities): - data = hass.data[DOMAIN][DATA_VEHICLES] - coordinator = hass.data[DOMAIN][DATA_COORDINATOR_FETCH] + account_id = config.data['email'] + + data = hass.data[DOMAIN][account_id][DATA_VEHICLES] + coordinator = hass.data[DOMAIN][account_id][DATA_COORDINATOR_FETCH] for vehicle in data: if Feature.CLIMATE_ON_OFF in data[vehicle].features: @@ -117,7 +119,7 @@ async def _async_fetch_loop(self, target_state): for _ in range(10): await loop.run_in_executor(None, self.vehicle.refresh) - await self._hass.data[DOMAIN][DATA_COORDINATOR_FETCH].async_refresh() + await self.coordinator.async_refresh() # We have our update, break out if target_state == self.vehicle.hvac_status: diff --git a/custom_components/nissan_connect/coordinator.py b/custom_components/nissan_connect/coordinator.py index 7fe4a0f..05301b2 100644 --- a/custom_components/nissan_connect/coordinator.py +++ b/custom_components/nissan_connect/coordinator.py @@ -19,7 +19,8 @@ def __init__(self, hass, config): update_interval=timedelta(minutes=config.get("interval_fetch", DEFAULT_INTERVAL_FETCH)), ) self._hass = hass - self._vehicles = hass.data[DOMAIN][DATA_VEHICLES] + self._account_id = config['email'] + self._vehicles = hass.data[DOMAIN][self._account_id][DATA_VEHICLES] async def _async_update_data(self): """Fetch data from API.""" @@ -31,7 +32,7 @@ async def _async_update_data(self): return False # Set interval for polling (the other coordinator) - self._hass.data[DOMAIN][DATA_COORDINATOR_POLL].set_next_interval() + self._hass.data[DOMAIN][self._account_id][DATA_COORDINATOR_POLL].set_next_interval() return True @@ -47,7 +48,8 @@ def __init__(self, hass, config): update_interval=timedelta(minutes=15), ) self._hass = hass - self._vehicles = hass.data[DOMAIN][DATA_VEHICLES] + self._account_id = config['email'] + self._vehicles = hass.data[DOMAIN][self._account_id][DATA_VEHICLES] self._config = config self._pluggednotcharging = {key: 0 for key in self._vehicles} @@ -114,7 +116,7 @@ async def _async_update_data(self): _LOGGER.warning("Error communicating with API") return False - self._hass.async_create_task(self._hass.data[DOMAIN][DATA_COORDINATOR_FETCH].async_refresh()) + self._hass.async_create_task(self._hass.data[DOMAIN][self._account_id][DATA_COORDINATOR_FETCH].async_refresh()) return True @@ -128,7 +130,8 @@ def __init__(self, hass, config): update_interval=timedelta(minutes=config.get("interval_statistics", DEFAULT_INTERVAL_STATISTICS)), ) self._hass = hass - self._vehicles = hass.data[DOMAIN][DATA_VEHICLES] + self._account_id = config['email'] + self._vehicles = hass.data[DOMAIN][self._account_id][DATA_VEHICLES] async def _async_update_data(self): """Fetch data from API.""" diff --git a/custom_components/nissan_connect/device_tracker.py b/custom_components/nissan_connect/device_tracker.py index 341e23a..cf89a0c 100644 --- a/custom_components/nissan_connect/device_tracker.py +++ b/custom_components/nissan_connect/device_tracker.py @@ -10,8 +10,10 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry(hass, entry, async_add_entities): - data = hass.data[DOMAIN][DATA_VEHICLES] - coordinator = hass.data[DOMAIN][DATA_COORDINATOR_FETCH] + account_id = entry.data['email'] + + data = hass.data[DOMAIN][account_id][DATA_VEHICLES] + coordinator = hass.data[DOMAIN][account_id][DATA_COORDINATOR_FETCH] entities = [] diff --git a/custom_components/nissan_connect/kamereon/kamereon.py b/custom_components/nissan_connect/kamereon/kamereon.py index 4d625ae..c07fdfd 100644 --- a/custom_components/nissan_connect/kamereon/kamereon.py +++ b/custom_components/nissan_connect/kamereon/kamereon.py @@ -330,7 +330,7 @@ def _request(self, method, url, headers=None, params=None, data=None, max_retrie _LOGGER.debug("Token expired. Refreshing session and retrying.") self.session.login() except Exception as e: - _LOGGER.warning(f"Request failed on attempt {attempt + 1} of {max_retries}: {e}") + _LOGGER.debug(f"Request failed on attempt {attempt + 1} of {max_retries}: {e}") if attempt == max_retries - 1: # Exhausted retries raise time.sleep(2 ** attempt) # Exponential backoff on retry diff --git a/custom_components/nissan_connect/sensor.py b/custom_components/nissan_connect/sensor.py index 99afef2..cc14331 100644 --- a/custom_components/nissan_connect/sensor.py +++ b/custom_components/nissan_connect/sensor.py @@ -15,9 +15,11 @@ async def async_setup_entry(hass, config, async_add_entities): """Set up the Kamereon sensors.""" - data = hass.data[DOMAIN][DATA_VEHICLES] - coordinator = hass.data[DOMAIN][DATA_COORDINATOR_FETCH] - coordinator_stats = hass.data[DOMAIN][DATA_COORDINATOR_STATISTICS] + account_id = config.data['email'] + + data = hass.data[DOMAIN][account_id][DATA_VEHICLES] + coordinator = hass.data[DOMAIN][account_id][DATA_COORDINATOR_FETCH] + coordinator_stats = hass.data[DOMAIN][account_id][DATA_COORDINATOR_STATISTICS] entities = []