From 8246fc78fa4fd906cc934a783e83bf1567daa45f Mon Sep 17 00:00:00 2001 From: Michael <35783820+mib1185@users.noreply.github.com> Date: Fri, 9 Jan 2026 10:52:44 +0100 Subject: [PATCH] Fix for older Fritzbox models which do not support smarthome triggers (#160555) --- .../components/fritzbox/coordinator.py | 11 ++++++-- tests/components/fritzbox/test_coordinator.py | 28 +++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/fritzbox/coordinator.py b/homeassistant/components/fritzbox/coordinator.py index 256c1258c38..1f1a2097efc 100644 --- a/homeassistant/components/fritzbox/coordinator.py +++ b/homeassistant/components/fritzbox/coordinator.py @@ -77,9 +77,14 @@ class FritzboxDataUpdateCoordinator(DataUpdateCoordinator[FritzboxCoordinatorDat ) LOGGER.debug("enable smarthome templates: %s", self.has_templates) - self.has_triggers = await self.hass.async_add_executor_job( - self.fritz.has_triggers - ) + try: + self.has_triggers = await self.hass.async_add_executor_job( + self.fritz.has_triggers + ) + except HTTPError: + # Fritz!OS < 7.39 just don't have this api endpoint + # so we need to fetch the HTTPError here and assume no triggers + self.has_triggers = False LOGGER.debug("enable smarthome triggers: %s", self.has_triggers) self.configuration_url = self.fritz.get_prefixed_host() diff --git a/tests/components/fritzbox/test_coordinator.py b/tests/components/fritzbox/test_coordinator.py index 794d6ac4397..37ac5f40440 100644 --- a/tests/components/fritzbox/test_coordinator.py +++ b/tests/components/fritzbox/test_coordinator.py @@ -6,9 +6,11 @@ from datetime import timedelta from unittest.mock import Mock from pyfritzhome import LoginError +import pytest from requests.exceptions import ConnectionError, HTTPError from homeassistant.components.fritzbox.const import DOMAIN +from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN from homeassistant.config_entries import ConfigEntryState from homeassistant.const import CONF_DEVICES from homeassistant.core import HomeAssistant @@ -20,6 +22,8 @@ from . import ( FritzDeviceSensorMock, FritzDeviceSwitchMock, FritzEntityBaseMock, + FritzTriggerMock, + setup_config_entry, ) from .const import MOCK_CONFIG @@ -184,3 +188,27 @@ async def test_coordinator_workaround_sub_units_without_main_device( assert len(device_entries) == 2 assert device_entries[0].identifiers == {(DOMAIN, "good_device")} assert device_entries[1].identifiers == {(DOMAIN, "bad_device")} + + +@pytest.mark.parametrize( + ("trigger", "side_effect", "switch_entity_count"), + [ + (None, None, 0), + (None, HTTPError(), 0), + (FritzTriggerMock(), None, 1), + ], +) +async def test_coordinator_has_triggers( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, + fritz: Mock, + trigger: Mock | None, + side_effect: Exception | None, + switch_entity_count: int, +) -> None: + """Test coordinator has_triggers property.""" + fritz().has_triggers.side_effect = side_effect + assert await setup_config_entry( + hass, MOCK_CONFIG[DOMAIN][CONF_DEVICES][0], fritz=fritz, trigger=trigger + ) + assert len(hass.states.async_all(SWITCH_DOMAIN)) == switch_entity_count