Migrate growatt_server off hass.data[DOMAIN] (#177925)

This commit is contained in:
Sankalp Thakur
2026-08-03 17:20:04 +05:30
committed by GitHub
parent aa5ee6490a
commit 3c2d169c96
3 changed files with 10 additions and 17 deletions
@@ -23,7 +23,6 @@ Error handling pattern for reauth:
→ raise ConfigEntryAuthFailed
- All other errors → ConfigEntryError (setup) or UpdateFailed (coordinator)
"""
# pylint: disable=home-assistant-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
from collections.abc import Mapping
import datetime
@@ -49,7 +48,6 @@ from homeassistant.helpers.typing import ConfigType
from .const import (
AUTH_API_TOKEN,
AUTH_PASSWORD,
CACHED_API_KEY,
CONF_AUTH_TYPE,
CONF_PLANT_ID,
DEFAULT_PLANT_ID,
@@ -70,6 +68,11 @@ _LOGGER = logging.getLogger(__name__)
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
# Temporary handoff of authenticated Classic API sessions from async_migrate_entry
# to async_setup_entry. Avoids a second login() during the same startup, which
# would hit Growatt's 5-minute per-endpoint rate limit. Popped after first use.
_CACHED_APIS: dict[str, growattServer.GrowattApi] = {}
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the Growatt Server integration."""
@@ -196,8 +199,7 @@ async def async_migrate_entry(
)
# Cache the logged-in API instance for reuse in async_setup_entry()
hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][f"{CACHED_API_KEY}{config_entry.entry_id}"] = api
_CACHED_APIS[config_entry.entry_id] = api
_LOGGER.info(
"Migrated config entry to use specific plant_id '%s'",
@@ -347,9 +349,7 @@ async def async_setup_entry(
# Check if migration cached an authenticated API instance for us to reuse.
# This avoids calling login() twice (once in migration, once here) which
# would trigger rate limiting.
cached_api = hass.data.get(DOMAIN, {}).pop(
f"{CACHED_API_KEY}{config_entry.entry_id}", None
)
cached_api = _CACHED_APIS.pop(config_entry.entry_id, None)
if cached_api:
# Reuse the logged-in API instance from migration (rate limit optimization)
@@ -55,11 +55,6 @@ BATT_MODE_LOAD_FIRST = 0
BATT_MODE_BATTERY_FIRST = 1
BATT_MODE_GRID_FIRST = 2
# Internal key prefix for caching authenticated API instance
# Used to pass logged-in session from async_migrate_entry to async_setup_entry
# to avoid double login() calls that trigger API rate limiting
CACHED_API_KEY = "_cached_api_"
# Supported device types for coordinator creation
SUPPORTED_DEVICE_TYPES = ["inverter", "tlx", "storage", "mix", "min", "sph"]
+3 -5
View File
@@ -10,10 +10,10 @@ import pytest
import requests
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.growatt_server import _CACHED_APIS
from homeassistant.components.growatt_server.const import (
AUTH_API_TOKEN,
AUTH_PASSWORD,
CACHED_API_KEY,
CONF_AUTH_TYPE,
CONF_PLANT_ID,
DEFAULT_PLANT_ID,
@@ -733,10 +733,8 @@ async def test_setup_reuses_cached_api_from_migration(
# This confirms setup did NOT resolve plant_id again (optimization working)
mock_growatt_classic_api.plant_list.assert_called_once_with(123456)
# Verify the cached API was removed after use (should not be in hass.data anymore)
assert f"{CACHED_API_KEY}{mock_config_entry.entry_id}" not in hass.data.get(
DOMAIN, {}
)
# Verify the cached API was removed after use (one-time handoff)
assert mock_config_entry.entry_id not in _CACHED_APIS
async def test_migrate_failure_returns_false(