From 36836078203f620c68782fde9624dd96a2a218bd Mon Sep 17 00:00:00 2001 From: Michael <35783820+mib1185@users.noreply.github.com> Date: Wed, 29 Apr 2026 08:10:29 +0200 Subject: [PATCH] Deprecate firmware update button in FRITZ!Box Tools (#168117) --- homeassistant/components/fritz/button.py | 36 +++++++++++++++++++++ homeassistant/components/fritz/strings.json | 4 +++ tests/components/fritz/test_button.py | 20 ++++++++++++ 3 files changed, 60 insertions(+) diff --git a/homeassistant/components/fritz/button.py b/homeassistant/components/fritz/button.py index 25053abaca35..25f9449696ea 100644 --- a/homeassistant/components/fritz/button.py +++ b/homeassistant/components/fritz/button.py @@ -45,6 +45,7 @@ BUTTONS: Final = [ device_class=ButtonDeviceClass.UPDATE, entity_category=EntityCategory.CONFIG, press_action=lambda avm_wrapper: avm_wrapper.async_trigger_firmware_update(), + entity_registry_enabled_default=False, ), FritzButtonDescription( key="reboot", @@ -96,6 +97,33 @@ def repair_issue_cleanup(hass: HomeAssistant, avm_wrapper: AvmWrapper) -> None: ) +def repair_issue_firmware_update(hass: HomeAssistant, avm_wrapper: AvmWrapper) -> None: + """Repair issue for firmware update button.""" + entity_registry = er.async_get(hass) + + if ( + ( + entity_button := entity_registry.async_get_entity_id( + "button", DOMAIN, f"{avm_wrapper.unique_id}-firmware_update" + ) + ) + and (entity_entry := entity_registry.async_get(entity_button)) + and not entity_entry.disabled + ): + # Deprecate the 'firmware update' button: create a Repairs issue for users + ir.async_create_issue( + hass, + domain=DOMAIN, + issue_id="deprecated_firmware_update_button", + is_fixable=False, + is_persistent=True, + severity=ir.IssueSeverity.WARNING, + translation_key="deprecated_firmware_update_button", + translation_placeholders={"removal_version": "2026.11.0"}, + breaks_in_ha_version="2026.11.0", + ) + + async def async_setup_entry( hass: HomeAssistant, entry: FritzConfigEntry, @@ -112,6 +140,7 @@ async def async_setup_entry( if avm_wrapper.mesh_role == MeshRoles.SLAVE: async_add_entities(entities_list) repair_issue_cleanup(hass, avm_wrapper) + repair_issue_firmware_update(hass, avm_wrapper) return data_fritz = hass.data[FRITZ_DATA_KEY] @@ -131,6 +160,7 @@ async def async_setup_entry( ) repair_issue_cleanup(hass, avm_wrapper) + repair_issue_firmware_update(hass, avm_wrapper) class FritzButton(ButtonEntity): @@ -164,6 +194,12 @@ class FritzButton(ButtonEntity): "Please update your automations and dashboards to remove any usage of this button. " "The action is now performed automatically at each data refresh", ) + elif self.entity_description.key == "firmware_update": + _LOGGER.warning( + "The 'firmware update' button is deprecated and will be removed in Home Assistant Core " + "2026.11.0. It has been superseded by an update entity. Please update your automations " + "and dashboards to remove any usage of this button", + ) await self.entity_description.press_action(self.avm_wrapper) diff --git a/homeassistant/components/fritz/strings.json b/homeassistant/components/fritz/strings.json index 22cdd12bd20f..745a548aa748 100644 --- a/homeassistant/components/fritz/strings.json +++ b/homeassistant/components/fritz/strings.json @@ -211,6 +211,10 @@ "deprecated_cleanup_button": { "description": "The 'Cleanup' button is deprecated and will be removed in Home Assistant Core {removal_version}. Please update your automations and dashboards to remove any usage of this button. The action is now performed automatically at each data refresh.", "title": "'Cleanup' button is deprecated" + }, + "deprecated_firmware_update_button": { + "description": "The 'Firmware update' button is deprecated and will be removed in Home Assistant Core {removal_version}. It has been superseded by an update entity. Please update your automations and dashboards to remove any usage of this button.", + "title": "'Firmware update' button is deprecated" } }, "options": { diff --git a/tests/components/fritz/test_button.py b/tests/components/fritz/test_button.py index d5d5606b993c..a26eccd82b26 100644 --- a/tests/components/fritz/test_button.py +++ b/tests/components/fritz/test_button.py @@ -284,3 +284,23 @@ async def test_cleanup_button_deprecation_issue( issue_registry = ir.async_get(hass) assert issue_registry.async_get_issue(DOMAIN, "deprecated_cleanup_button") + + +@pytest.mark.usefixtures("entity_registry_enabled_by_default") +async def test_firmware_update_button_deprecation_issue( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, + fc_class_mock, + fh_class_mock, + fs_class_mock, +) -> None: + """Test deprecation issue is created when legacy firmware update button is enabled.""" + entry = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA) + entry.add_to_hass(hass) + + await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + assert entry.state is ConfigEntryState.LOADED + + issue_registry = ir.async_get(hass) + assert issue_registry.async_get_issue(DOMAIN, "deprecated_firmware_update_button")