From 5eb5b93c0e637737111002573a7c2c7e8eea4062 Mon Sep 17 00:00:00 2001 From: Guido Schmitz Date: Fri, 7 Nov 2025 16:00:48 +0100 Subject: [PATCH] Allow devolo Home Control remote gateways to be offline (#152486) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: AbĂ­lio Costa --- .../devolo_home_control/__init__.py | 22 ++++++++++++------- .../devolo_home_control/manifest.json | 2 +- .../devolo_home_control/strings.json | 2 +- .../devolo_home_control/test_init.py | 14 +++++++++++- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/devolo_home_control/__init__.py b/homeassistant/components/devolo_home_control/__init__.py index 51e4152be98d..8c6a857dd48a 100644 --- a/homeassistant/components/devolo_home_control/__init__.py +++ b/homeassistant/components/devolo_home_control/__init__.py @@ -5,6 +5,7 @@ from __future__ import annotations import asyncio from collections.abc import Mapping from functools import partial +import logging from typing import Any from devolo_home_control_api.exceptions.gateway import GatewayOfflineError @@ -22,6 +23,8 @@ from .const import DOMAIN, PLATFORMS type DevoloHomeControlConfigEntry = ConfigEntry[list[HomeControl]] +_LOGGER = logging.getLogger(__name__) + async def async_setup_entry( hass: HomeAssistant, entry: DevoloHomeControlConfigEntry @@ -44,26 +47,29 @@ async def async_setup_entry( hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, shutdown) ) - try: - zeroconf_instance = await zeroconf.async_get_instance(hass) - entry.runtime_data = [] - for gateway_id in gateway_ids: + zeroconf_instance = await zeroconf.async_get_instance(hass) + entry.runtime_data = [] + offline_gateways = 0 + for gateway_id in gateway_ids: + try: entry.runtime_data.append( await hass.async_add_executor_job( partial( HomeControl, - gateway_id=str(gateway_id), + gateway_id=gateway_id, mydevolo_instance=mydevolo, zeroconf_instance=zeroconf_instance, ) ) ) - except GatewayOfflineError as err: + except GatewayOfflineError: + offline_gateways += 1 + _LOGGER.info("Central unit %s cannot be reached locally", gateway_id) + if len(gateway_ids) == offline_gateways: raise ConfigEntryNotReady( translation_domain=DOMAIN, translation_key="connection_failed", - translation_placeholders={"gateway_id": gateway_id}, - ) from err + ) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) diff --git a/homeassistant/components/devolo_home_control/manifest.json b/homeassistant/components/devolo_home_control/manifest.json index 983b2a33452b..427eb37159d7 100644 --- a/homeassistant/components/devolo_home_control/manifest.json +++ b/homeassistant/components/devolo_home_control/manifest.json @@ -7,7 +7,7 @@ "documentation": "https://www.home-assistant.io/integrations/devolo_home_control", "integration_type": "hub", "iot_class": "local_push", - "loggers": ["devolo_home_control_api"], + "loggers": ["HomeControl", "Mydevolo", "MprmRest", "MprmWebsocket", "Mprm"], "requirements": ["devolo-home-control-api==0.19.0"], "zeroconf": ["_dvl-deviceapi._tcp.local."] } diff --git a/homeassistant/components/devolo_home_control/strings.json b/homeassistant/components/devolo_home_control/strings.json index 96dc87588461..2dd828bf2efc 100644 --- a/homeassistant/components/devolo_home_control/strings.json +++ b/homeassistant/components/devolo_home_control/strings.json @@ -58,7 +58,7 @@ }, "exceptions": { "connection_failed": { - "message": "Failed to connect to devolo Home Control central unit {gateway_id}." + "message": "Failed to connect to any devolo Home Control central unit." }, "invalid_auth": { "message": "Authentication failed. Please re-authenticate with your mydevolo account." diff --git a/tests/components/devolo_home_control/test_init.py b/tests/components/devolo_home_control/test_init.py index c9b39366cdd6..488b3c53750f 100644 --- a/tests/components/devolo_home_control/test_init.py +++ b/tests/components/devolo_home_control/test_init.py @@ -47,7 +47,19 @@ async def test_setup_entry_maintenance( async def test_setup_gateway_offline(hass: HomeAssistant) -> None: - """Test setup entry fails on gateway offline.""" + """Test setup entry with one gateway online and one gateway offline.""" + entry = configure_integration(hass) + test_gateway = HomeControlMock() + with patch( + "homeassistant.components.devolo_home_control.HomeControl", + side_effect=[test_gateway, GatewayOfflineError], + ): + await hass.config_entries.async_setup(entry.entry_id) + assert entry.state is ConfigEntryState.LOADED + + +async def test_setup_all_gateways_offline(hass: HomeAssistant) -> None: + """Test setup entry fails on all gateways offline.""" entry = configure_integration(hass) with patch( "homeassistant.components.devolo_home_control.HomeControl",