diff --git a/homeassistant/components/fritzbox/coordinator.py b/homeassistant/components/fritzbox/coordinator.py index c16751c8c9f..6bc3bac623f 100644 --- a/homeassistant/components/fritzbox/coordinator.py +++ b/homeassistant/components/fritzbox/coordinator.py @@ -3,6 +3,7 @@ from __future__ import annotations from dataclasses import dataclass from datetime import timedelta +from xml.etree.ElementTree import ParseError from pyfritzhome import Fritzhome, FritzhomeDevice, LoginError from pyfritzhome.devicetypes import FritzhomeTemplate @@ -34,6 +35,13 @@ class FritzboxDataUpdateCoordinator(DataUpdateCoordinator[FritzboxCoordinatorDat self.entry = entry self.fritz: Fritzhome = hass.data[DOMAIN][self.entry.entry_id][CONF_CONNECTIONS] self.configuration_url = self.fritz.get_prefixed_host() + self.has_templates = True + try: + hass.async_add_executor_job(self.fritz.update_templates) + except ParseError: + LOGGER.info("Disable smarthome templates") + self.has_templates = False + super().__init__( hass, LOGGER, @@ -45,7 +53,8 @@ class FritzboxDataUpdateCoordinator(DataUpdateCoordinator[FritzboxCoordinatorDat """Update all fritzbox device data.""" try: self.fritz.update_devices() - self.fritz.update_templates() + if self.has_templates: + self.fritz.update_templates() except requests.exceptions.ConnectionError as ex: raise UpdateFailed from ex except requests.exceptions.HTTPError: @@ -55,7 +64,8 @@ class FritzboxDataUpdateCoordinator(DataUpdateCoordinator[FritzboxCoordinatorDat except LoginError as ex: raise ConfigEntryAuthFailed from ex self.fritz.update_devices() - self.fritz.update_templates() + if self.has_templates: + self.fritz.update_templates() devices = self.fritz.get_devices() device_data = {} @@ -75,10 +85,11 @@ class FritzboxDataUpdateCoordinator(DataUpdateCoordinator[FritzboxCoordinatorDat device_data[device.ain] = device - templates = self.fritz.get_templates() template_data = {} - for template in templates: - template_data[template.ain] = template + if self.has_templates: + templates = self.fritz.get_templates() + for template in templates: + template_data[template.ain] = template return FritzboxCoordinatorData(devices=device_data, templates=template_data) diff --git a/tests/components/fritzbox/test_init.py b/tests/components/fritzbox/test_init.py index d68d9e1679c..dbec8b4ec14 100644 --- a/tests/components/fritzbox/test_init.py +++ b/tests/components/fritzbox/test_init.py @@ -2,6 +2,7 @@ from __future__ import annotations from unittest.mock import Mock, call, patch +from xml.etree.ElementTree import ParseError from pyfritzhome import LoginError import pytest @@ -167,7 +168,7 @@ async def test_coordinator_update_after_reboot(hass: HomeAssistant, fritz: Mock) assert await hass.config_entries.async_setup(entry.entry_id) assert fritz().update_devices.call_count == 2 - assert fritz().update_templates.call_count == 1 + assert fritz().update_templates.call_count == 2 assert fritz().get_devices.call_count == 1 assert fritz().get_templates.call_count == 1 assert fritz().login.call_count == 2 @@ -265,3 +266,17 @@ async def test_raise_config_entry_not_ready_when_offline(hass: HomeAssistant): entries = hass.config_entries.async_entries() config_entry = entries[0] assert config_entry.state is ConfigEntryState.SETUP_ERROR + + +async def test_disable_smarthome_templates(hass: HomeAssistant, fritz: Mock): + """Test smarthome templates are disabled.""" + entry = MockConfigEntry( + domain=FB_DOMAIN, + data=MOCK_CONFIG[FB_DOMAIN][CONF_DEVICES][0], + unique_id="any", + ) + entry.add_to_hass(hass) + fritz().update_templates.side_effect = [ParseError(), ""] + + assert await hass.config_entries.async_setup(entry.entry_id) + assert fritz().update_templates.call_count == 1