mirror of
https://github.com/home-assistant/core.git
synced 2025-07-15 17:27:10 +00:00
Reload enphase_envoy integration upon envoy firmware change detection (#124650)
* Reload enphase_envoy integration upon envoy firmware change detection. * remove persistant notification
This commit is contained in:
parent
f52f60307b
commit
66f9e06c25
@ -24,6 +24,7 @@ SCAN_INTERVAL = timedelta(seconds=60)
|
|||||||
|
|
||||||
TOKEN_REFRESH_CHECK_INTERVAL = timedelta(days=1)
|
TOKEN_REFRESH_CHECK_INTERVAL = timedelta(days=1)
|
||||||
STALE_TOKEN_THRESHOLD = timedelta(days=30).total_seconds()
|
STALE_TOKEN_THRESHOLD = timedelta(days=30).total_seconds()
|
||||||
|
NOTIFICATION_ID = "enphase_envoy_notification"
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -35,6 +36,7 @@ class EnphaseUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
|||||||
"""DataUpdateCoordinator to gather data from any envoy."""
|
"""DataUpdateCoordinator to gather data from any envoy."""
|
||||||
|
|
||||||
envoy_serial_number: str
|
envoy_serial_number: str
|
||||||
|
envoy_firmware: str
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, hass: HomeAssistant, envoy: Envoy, entry: EnphaseConfigEntry
|
self, hass: HomeAssistant, envoy: Envoy, entry: EnphaseConfigEntry
|
||||||
@ -46,6 +48,7 @@ class EnphaseUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
|||||||
self.username = entry_data[CONF_USERNAME]
|
self.username = entry_data[CONF_USERNAME]
|
||||||
self.password = entry_data[CONF_PASSWORD]
|
self.password = entry_data[CONF_PASSWORD]
|
||||||
self._setup_complete = False
|
self._setup_complete = False
|
||||||
|
self.envoy_firmware = ""
|
||||||
self._cancel_token_refresh: CALLBACK_TYPE | None = None
|
self._cancel_token_refresh: CALLBACK_TYPE | None = None
|
||||||
super().__init__(
|
super().__init__(
|
||||||
hass,
|
hass,
|
||||||
@ -158,6 +161,24 @@ class EnphaseUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
|||||||
raise ConfigEntryAuthFailed from err
|
raise ConfigEntryAuthFailed from err
|
||||||
except EnvoyError as err:
|
except EnvoyError as err:
|
||||||
raise UpdateFailed(f"Error communicating with API: {err}") from err
|
raise UpdateFailed(f"Error communicating with API: {err}") from err
|
||||||
|
|
||||||
|
# if we have a firmware version from previous setup, compare to current one
|
||||||
|
# when envoy gets new firmware there will be an authentication failure
|
||||||
|
# which results in getting fw version again, if so reload the integration.
|
||||||
|
if (current_firmware := self.envoy_firmware) and current_firmware != (
|
||||||
|
new_firmware := envoy.firmware
|
||||||
|
):
|
||||||
|
_LOGGER.warning(
|
||||||
|
"Envoy firmware changed from: %s to: %s, reloading enphase envoy integration",
|
||||||
|
current_firmware,
|
||||||
|
new_firmware,
|
||||||
|
)
|
||||||
|
# reload the integration to get all established again
|
||||||
|
self.hass.async_create_task(
|
||||||
|
self.hass.config_entries.async_reload(self.entry.entry_id)
|
||||||
|
)
|
||||||
|
# remember firmware version for next time
|
||||||
|
self.envoy_firmware = envoy.firmware
|
||||||
_LOGGER.debug("Envoy data: %s", envoy_data)
|
_LOGGER.debug("Envoy data: %s", envoy_data)
|
||||||
return envoy_data.raw
|
return envoy_data.raw
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"""Test Enphase Envoy sensors."""
|
"""Test Enphase Envoy sensors."""
|
||||||
|
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
import logging
|
||||||
from unittest.mock import AsyncMock, patch
|
from unittest.mock import AsyncMock, patch
|
||||||
|
|
||||||
from freezegun.api import FrozenDateTimeFactory
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
@ -1002,3 +1003,36 @@ async def test_sensor_missing_data(
|
|||||||
# test the original inverter is now unknown
|
# test the original inverter is now unknown
|
||||||
assert (entity_state := hass.states.get("sensor.inverter_1"))
|
assert (entity_state := hass.states.get("sensor.inverter_1"))
|
||||||
assert entity_state.state == STATE_UNKNOWN
|
assert entity_state.state == STATE_UNKNOWN
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("mock_envoy"),
|
||||||
|
[
|
||||||
|
"envoy_metered_batt_relay",
|
||||||
|
],
|
||||||
|
indirect=["mock_envoy"],
|
||||||
|
)
|
||||||
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||||
|
async def test_fw_update(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
mock_envoy: AsyncMock,
|
||||||
|
entity_registry: er.EntityRegistry,
|
||||||
|
freezer: FrozenDateTimeFactory,
|
||||||
|
caplog: pytest.LogCaptureFixture,
|
||||||
|
) -> None:
|
||||||
|
"""Test enphase_envoy sensor update over fw update."""
|
||||||
|
logging.getLogger("homeassistant.components.enphase_envoy").setLevel(logging.DEBUG)
|
||||||
|
with patch("homeassistant.components.enphase_envoy.PLATFORMS", [Platform.SENSOR]):
|
||||||
|
await setup_integration(hass, config_entry)
|
||||||
|
|
||||||
|
# force HA to detect changed data by changing raw
|
||||||
|
mock_envoy.firmware = "0.0.0"
|
||||||
|
|
||||||
|
# Move time to next update
|
||||||
|
freezer.tick(SCAN_INTERVAL)
|
||||||
|
async_fire_time_changed(hass)
|
||||||
|
await hass.async_block_till_done(wait_background_tasks=True)
|
||||||
|
|
||||||
|
assert "firmware changed from: " in caplog.text
|
||||||
|
assert "to: 0.0.0, reloading enphase envoy integration" in caplog.text
|
||||||
|
Loading…
x
Reference in New Issue
Block a user