diff --git a/homeassistant/components/min_max/repairs.py b/homeassistant/components/min_max/repairs.py index 6d27a3953d41..bef006e426f8 100644 --- a/homeassistant/components/min_max/repairs.py +++ b/homeassistant/components/min_max/repairs.py @@ -1,7 +1,7 @@ """Repairs platform for the Min/Max integration.""" from types import MappingProxyType -from typing import Any, cast +from typing import TYPE_CHECKING, Any, cast import voluptuous as vol @@ -40,7 +40,6 @@ class MigrateToGroupSensorFlow(RepairsFlow): self, user_input: dict[str, Any] | None = None ) -> data_entry_flow.FlowResult: """Handle the migration step of a fix flow.""" - errors: dict[str, str] = {} entity_reg = er.async_get(self.hass) old_entity = entity_reg.async_get_entity_id( SENSOR_DOMAIN, DOMAIN, self.entry.entry_id @@ -71,14 +70,18 @@ class MigrateToGroupSensorFlow(RepairsFlow): disabled_by=ConfigEntryDisabler.USER, ) - await self.hass.config_entries.async_unload(self.entry.entry_id) + if not await self.hass.config_entries.async_unload(self.entry.entry_id): + return self.async_abort(reason="unload_failed") await self.hass.config_entries.async_add(new_config_entry) - entity_reg.async_update_entity_platform( - old_entity, - GROUP_DOMAIN, - new_config_entry_id=new_config_entry.entry_id, - new_unique_id=new_config_entry.entry_id, - ) + try: + entity_reg.async_update_entity_platform( + old_entity, + GROUP_DOMAIN, + new_config_entry_id=new_config_entry.entry_id, + new_unique_id=new_config_entry.entry_id, + ) + except ValueError: + return self.async_abort(reason="entity_update_failed") await self.hass.config_entries.async_set_disabled_by( entry_id=new_config_entry.entry_id, disabled_by=None ) @@ -87,13 +90,13 @@ class MigrateToGroupSensorFlow(RepairsFlow): return self.async_create_entry(data={}) entity_info = entity_reg.async_get(old_entity) - assert entity_info + if TYPE_CHECKING: + assert entity_info title = er.async_get_full_entity_name(self.hass, entity_info) return self.async_show_form( step_id="migrate", data_schema=vol.Schema({}), - errors=errors, description_placeholders={"title": title}, ) @@ -107,7 +110,8 @@ async def async_create_fix_flow( if data and (entry_id := data.get("entry_id")): entry_id = cast(str, entry_id) entry = hass.config_entries.async_get_entry(entry_id) - assert entry + if TYPE_CHECKING: + assert entry return MigrateToGroupSensorFlow(entry) return ConfirmRepairFlow() diff --git a/homeassistant/components/min_max/sensor.py b/homeassistant/components/min_max/sensor.py index a58273eed5e6..2f48ca1884b8 100644 --- a/homeassistant/components/min_max/sensor.py +++ b/homeassistant/components/min_max/sensor.py @@ -1,6 +1,8 @@ """Support for displaying minimal, maximal, mean or median values.""" from datetime import datetime +import hashlib +import json import logging import statistics from typing import Any, override @@ -37,7 +39,7 @@ from homeassistant.helpers.event import async_track_state_change_event from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from homeassistant.helpers.reload import async_setup_reload_service from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, StateType -from homeassistant.util import ulid as ulid_util, yaml as yaml_util +from homeassistant.util import yaml as yaml_util from . import PLATFORMS from .const import CONF_ENTITY_IDS, CONF_ROUND_DIGITS, DOMAIN @@ -120,11 +122,11 @@ async def yaml_deprecation_notice(hass: HomeAssistant, config: ConfigType) -> No yaml_config = yaml_config.replace("\n", "\n ") yaml_config = "```yaml\nsensor:\n - platform: group\n " + yaml_config + "\n```" - issue_id = "yaml_deprecated-" - if platform_config.get(CONF_UNIQUE_ID): - issue_id += f"{platform_config[CONF_UNIQUE_ID]}" - else: - issue_id += ulid_util.ulid() + def make_hash(config: dict[str, Any]) -> str: + d = hashlib.sha1(json.dumps(config, sort_keys=True).encode()) + return d.hexdigest() + + issue_id = f"yaml_deprecated-{make_hash(platform_config)}" async_create_issue( hass, DOMAIN, diff --git a/homeassistant/components/min_max/strings.json b/homeassistant/components/min_max/strings.json index 4b54fcfd64b4..2e0a18e7d44a 100644 --- a/homeassistant/components/min_max/strings.json +++ b/homeassistant/components/min_max/strings.json @@ -1,11 +1,11 @@ { "config": { "abort": { - "migrated_to_groups": "The Min/Max helper has been migrated to use group sensors. Please use the group helper instead." + "migrated_to_groups": "The Min/Max helper has been migrated to use Group sensors. Please use the Group helper instead." }, "step": { "user": { - "description": "Min/Max helper has been deprecated, please use the group helper instead.", + "description": "Min/Max helper has been deprecated, please use the Group helper instead.", "title": "[%key:component::min_max::title%]" } } @@ -14,11 +14,13 @@ "migrate_to_group_sensor": { "fix_flow": { "abort": { - "entity_not_found": "Entity could not be found, please restart repairing the issue." + "entity_not_found": "Entity could not be found, please restart repairing the issue.", + "entity_update_failed": "Failed to update the entity to a Group sensor, please manually remove the obsolete entity.", + "unload_failed": "Failed to unload the Min/Max helper, please restart repairing the issue." }, "step": { "migrate": { - "description": "The Min/Max helper has been deprecated and {title} will be migrated to a group sensor when you click submit to fix this repair.", + "description": "The Min/Max helper has been deprecated and {title} will be migrated to a Group sensor when you click submit to fix this repair.", "title": "[%key:component::min_max::issues::migrate_to_group_sensor::title%]" } } @@ -26,7 +28,7 @@ "title": "Min/Max helper has been deprecated" }, "yaml_deprecated": { - "description": "The Min/Max helper has been deprecated and you should use group sensors instead.\n\nReplace your Min/Max YAML configuration with this converted configuration:\n{yaml_config}\n\nOnce you have replaced your YAML configuration, restart Home Assistant to use the group helper instead.\n\nThe Group helper has more configuration possibilities. Refer to the documentation by clicking Learn More.", + "description": "The Min/Max helper has been deprecated and you should use Group sensors instead.\n\nReplace your Min/Max YAML configuration with this converted configuration:\n{yaml_config}\n\nOnce you have replaced your YAML configuration, restart Home Assistant to use the Group helper instead.\n\nThe Group helper has more configuration possibilities. Refer to the documentation by clicking Learn More.", "title": "[%key:component::min_max::issues::migrate_to_group_sensor::title%]" } }, diff --git a/tests/components/min_max/test_sensor.py b/tests/components/min_max/test_sensor.py index 2d40a52e21c7..863d16e99db7 100644 --- a/tests/components/min_max/test_sensor.py +++ b/tests/components/min_max/test_sensor.py @@ -62,19 +62,22 @@ async def test_deprecation_warning( ] } - with patch("homeassistant.util.ulid.ulid", return_value="1234"): - assert await async_setup_component(hass, "sensor", config) - await hass.async_block_till_done() + assert await async_setup_component(hass, "sensor", config) + await hass.async_block_till_done() - # Use ulid for issue id when unique_id is not set - issue = issue_registry.async_get_issue(DOMAIN, "yaml_deprecated-1234") + issue = issue_registry.async_get_issue( + DOMAIN, "yaml_deprecated-ddc87b71acd58a195502396b87387d910c36ff7c" + ) + issue2 = issue_registry.async_get_issue( + DOMAIN, "yaml_deprecated-6e9186f09cfb0959d0fe420ef3b01e1b25899b2f" + ) assert issue is not None assert issue.severity == ir.IssueSeverity.WARNING assert issue.translation_key == "yaml_deprecated" - # Use unique_id for issue id if exist - issue = issue_registry.async_get_issue(DOMAIN, "yaml_deprecated-my_unique_id") - assert issue is not None + assert issue2 is not None + assert issue2.severity == ir.IssueSeverity.WARNING + assert issue2.translation_key == "yaml_deprecated" async def test_default_name_sensor(hass: HomeAssistant) -> None: