-
-
Notifications
You must be signed in to change notification settings - Fork 37.5k
Deprecate min_max and migrate to group sensor #167718
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 29 commits
564280c
5bbfe69
7288d19
6e92ba2
26d8dfb
d4fca37
49ce8ed
f821952
d25f3c6
f006283
44b0717
7f1846b
6d4f5a4
d037f33
983df39
787929f
46a05e4
379c0b1
3f69014
00e8a6c
9fd0f99
e131b21
5079709
80733a2
f4bccbb
d8b23df
ee9326d
2e1c4e0
fbda661
7c6ff3f
30176c6
9634953
aad7b6c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| """Repairs platform for the Min/Max integration.""" | ||
|
|
||
| from types import MappingProxyType | ||
| from typing import Any, cast | ||
|
|
||
| import voluptuous as vol | ||
|
|
||
| from homeassistant import data_entry_flow | ||
| from homeassistant.components.group import ( | ||
| CONF_ENTITIES, | ||
| CONF_GROUP_TYPE, | ||
| CONF_HIDE_MEMBERS, | ||
| CONF_IGNORE_NON_NUMERIC, | ||
| DOMAIN as GROUP_DOMAIN, | ||
| ) | ||
| from homeassistant.components.repairs import ConfirmRepairFlow, RepairsFlow | ||
| from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN | ||
| from homeassistant.config_entries import SOURCE_USER, ConfigEntry, ConfigEntryDisabler | ||
| from homeassistant.core import HomeAssistant | ||
| from homeassistant.helpers import entity_registry as er | ||
|
|
||
| from .const import CONF_ENTITY_IDS, CONF_ROUND_DIGITS, DOMAIN | ||
|
|
||
|
|
||
| class MigrateToGroupSensorFlow(RepairsFlow): | ||
| """Handler for an issue fixing flow.""" | ||
|
gjohansson-ST marked this conversation as resolved.
Outdated
|
||
|
|
||
| def __init__(self, entry: ConfigEntry) -> None: | ||
| """Create flow.""" | ||
| self.entry = entry | ||
| super().__init__() | ||
|
|
||
| async def async_step_init( | ||
| self, user_input: dict[str, str] | None = None | ||
| ) -> data_entry_flow.FlowResult: | ||
| """Handle the first step of a fix flow.""" | ||
| return await self.async_step_migrate() | ||
|
|
||
| async def async_step_migrate( | ||
| self, user_input: dict[str, Any] | None = None | ||
| ) -> data_entry_flow.FlowResult: | ||
| """Handle the migration step of a fix flow.""" | ||
| errors: dict[str, str] = {} | ||
|
gjohansson-ST marked this conversation as resolved.
Outdated
|
||
| entity_reg = er.async_get(self.hass) | ||
| old_entity = entity_reg.async_get_entity_id( | ||
| SENSOR_DOMAIN, DOMAIN, self.entry.entry_id | ||
| ) | ||
| if not old_entity: | ||
| return self.async_abort(reason="entity_not_found") | ||
|
|
||
|
emontnemery marked this conversation as resolved.
|
||
| if user_input is not None: | ||
| config = dict(self.entry.options) | ||
| config[CONF_ENTITIES] = config.pop(CONF_ENTITY_IDS) | ||
| config.pop(CONF_ROUND_DIGITS) | ||
| # Set group sensor defaults | ||
| config[CONF_HIDE_MEMBERS] = False | ||
| config[CONF_IGNORE_NON_NUMERIC] = False | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd think we should migrate to group default ( |
||
| config[CONF_GROUP_TYPE] = SENSOR_DOMAIN | ||
|
|
||
| new_config_entry = ConfigEntry( | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can't we use a normal config flow on the group domain to create the new entry, instead of adding it directly?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That would be a bit difficult as we need to unload
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This sort of thing would normally be in the group integration's config flow with a custom initial step for the |
||
| data={}, | ||
| discovery_keys=MappingProxyType({}), | ||
| domain=GROUP_DOMAIN, | ||
| minor_version=1, | ||
| options=config, | ||
| source=SOURCE_USER, | ||
| subentries_data=[], | ||
| title=self.entry.title, | ||
| unique_id=None, | ||
| version=1, | ||
| disabled_by=ConfigEntryDisabler.USER, | ||
| ) | ||
|
|
||
| await self.hass.config_entries.async_unload(self.entry.entry_id) | ||
| 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, | ||
| ) | ||
| await self.hass.config_entries.async_set_disabled_by( | ||
| entry_id=new_config_entry.entry_id, disabled_by=None | ||
| ) | ||
| await self.hass.config_entries.async_remove(self.entry.entry_id) | ||
|
|
||
| return self.async_create_entry(data={}) | ||
|
Comment on lines
+85
to
+90
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Repairing the issue does that?! |
||
|
|
||
| entity_info = entity_reg.async_get(old_entity) | ||
| assert entity_info | ||
|
gjohansson-ST marked this conversation as resolved.
Outdated
|
||
| 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, | ||
|
gjohansson-ST marked this conversation as resolved.
Outdated
|
||
| description_placeholders={"title": title}, | ||
| ) | ||
|
|
||
|
|
||
| async def async_create_fix_flow( | ||
| hass: HomeAssistant, | ||
| issue_id: str, | ||
| data: dict[str, Any] | None, | ||
| ) -> RepairsFlow: | ||
| """Create 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 | ||
|
gjohansson-ST marked this conversation as resolved.
Outdated
|
||
| return MigrateToGroupSensorFlow(entry) | ||
|
|
||
| return ConfirmRepairFlow() | ||
|
Comment on lines
+108
to
+117
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,7 @@ | |
|
|
||
| import voluptuous as vol | ||
|
|
||
| from homeassistant.components.group import CONF_ENTITIES | ||
| from homeassistant.components.sensor import ( | ||
|
gjohansson-ST marked this conversation as resolved.
|
||
| PLATFORM_SCHEMA as SENSOR_PLATFORM_SCHEMA, | ||
| SensorDeviceClass, | ||
|
|
@@ -20,6 +21,7 @@ | |
| ATTR_ENTITY_ID, | ||
| ATTR_UNIT_OF_MEASUREMENT, | ||
| CONF_NAME, | ||
| CONF_PLATFORM, | ||
| CONF_TYPE, | ||
| CONF_UNIQUE_ID, | ||
| STATE_UNAVAILABLE, | ||
|
|
@@ -34,8 +36,10 @@ | |
| AddEntitiesCallback, | ||
| ) | ||
| 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 . import PLATFORMS | ||
| from .const import CONF_ENTITY_IDS, CONF_ROUND_DIGITS, DOMAIN | ||
|
|
@@ -53,6 +57,7 @@ | |
| ATTR_RANGE = "range" | ||
| ATTR_SUM = "sum" | ||
|
|
||
|
|
||
| ICON = "mdi:calculator" | ||
|
|
||
| SENSOR_TYPES = { | ||
|
|
@@ -105,6 +110,36 @@ async def async_setup_entry( | |
| ) | ||
|
|
||
|
|
||
| async def yaml_deprecation_notice(hass: HomeAssistant, config: ConfigType) -> None: | ||
| """Raise repair issue for YAML configuration deprecation.""" | ||
| platform_config = config.copy() | ||
| platform_config[CONF_ENTITIES] = platform_config.pop(CONF_ENTITY_IDS) | ||
| platform_config.pop(CONF_ROUND_DIGITS) | ||
|
gjohansson-ST marked this conversation as resolved.
|
||
| platform_config.pop(CONF_PLATFORM) | ||
| if CONF_NAME not in platform_config: | ||
| platform_config[CONF_NAME] = f"{platform_config[CONF_TYPE]} sensor".capitalize() | ||
| yaml_config = yaml_util.dump(platform_config) | ||
| yaml_config = yaml_config.replace("\n", "\n ") | ||
| yaml_config = "```yaml\nsensor:\n - platform: group\n " + yaml_config + "\n```" | ||
|
Comment on lines
+117
to
+125
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As above |
||
|
|
||
| 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() | ||
| async_create_issue( | ||
|
gjohansson-ST marked this conversation as resolved.
Outdated
|
||
| hass, | ||
| DOMAIN, | ||
| issue_id, | ||
| breaks_in_ha_version="2026.12.0", | ||
|
gjohansson-ST marked this conversation as resolved.
|
||
| is_fixable=False, | ||
| severity=IssueSeverity.WARNING, | ||
| learn_more_url="https://www.home-assistant.io/integrations/group/", | ||
| translation_key="yaml_deprecated", | ||
| translation_placeholders={"yaml_config": yaml_config}, | ||
| ) | ||
|
gjohansson-ST marked this conversation as resolved.
gjohansson-ST marked this conversation as resolved.
gjohansson-ST marked this conversation as resolved.
gjohansson-ST marked this conversation as resolved.
|
||
|
|
||
|
|
||
| async def async_setup_platform( | ||
| hass: HomeAssistant, | ||
| config: ConfigType, | ||
|
|
@@ -119,6 +154,7 @@ async def async_setup_platform( | |
| unique_id = config.get(CONF_UNIQUE_ID) | ||
|
|
||
| await async_setup_reload_service(hass, DOMAIN, PLATFORMS) | ||
| await yaml_deprecation_notice(hass, config) | ||
|
|
||
| async_add_entities( | ||
| [MinMaxSensor(entity_ids, name, sensor_type, round_digits, unique_id)] | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please move the entity registry changes to a separate PR with a clear motivation for the change as well as updated tests.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See #171773 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1932,7 +1932,7 @@ def async_update_entity_platform( | |
| """ | ||
| if ( | ||
| state := self.hass.states.get(entity_id) | ||
| ) is not None and state.state != STATE_UNKNOWN: | ||
| ) is not None and state.state not in (STATE_UNKNOWN, STATE_UNAVAILABLE): | ||
|
gjohansson-ST marked this conversation as resolved.
|
||
| raise ValueError("Only entities that haven't been loaded can be migrated") | ||
|
Comment on lines
1933
to
1936
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should fix this in that case in a separate PR since
Comment on lines
1933
to
1936
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I already commented on this above, but I think another PR needs to fix that and look on the integration rather than an entity state (as
Comment on lines
1933
to
1936
|
||
|
|
||
| old = self.entities[entity_id] | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.