Skip to content
Draft
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
564280c
Deprecate min_max and migrate to group sensor
gjohansson-ST Apr 8, 2026
5bbfe69
import
gjohansson-ST Apr 10, 2026
7288d19
Mods
gjohansson-ST Apr 10, 2026
6e92ba2
Mods
gjohansson-ST Apr 14, 2026
26d8dfb
Mods
gjohansson-ST Apr 14, 2026
d4fca37
Mods
gjohansson-ST Apr 14, 2026
49ce8ed
Mods
gjohansson-ST Apr 14, 2026
f821952
Test
gjohansson-ST Apr 14, 2026
d25f3c6
Delete
gjohansson-ST Apr 14, 2026
f006283
Mods
gjohansson-ST Apr 14, 2026
44b0717
Mods
gjohansson-ST Apr 14, 2026
7f1846b
comments
gjohansson-ST Apr 14, 2026
6d4f5a4
Mods to repair flow
gjohansson-ST May 4, 2026
d037f33
Fix config flow
gjohansson-ST May 4, 2026
983df39
Fixes
gjohansson-ST May 4, 2026
787929f
Mods
gjohansson-ST May 4, 2026
46a05e4
mod
gjohansson-ST May 4, 2026
379c0b1
Fixes
gjohansson-ST May 13, 2026
3f69014
strings
gjohansson-ST May 13, 2026
00e8a6c
Fix string
gjohansson-ST May 13, 2026
9fd0f99
Fix flow
gjohansson-ST May 13, 2026
e131b21
async_config_entry_title
gjohansson-ST May 13, 2026
5079709
Mods
gjohansson-ST May 13, 2026
80733a2
Handle missing entity
gjohansson-ST May 13, 2026
f4bccbb
fix yaml description
gjohansson-ST May 13, 2026
d8b23df
Mods
gjohansson-ST May 13, 2026
ee9326d
Somewhat stable id
gjohansson-ST May 13, 2026
2e1c4e0
Remove from future
gjohansson-ST May 13, 2026
fbda661
Restore options flow test
gjohansson-ST May 13, 2026
7c6ff3f
Fix review comments
gjohansson-ST May 14, 2026
30176c6
Remove issue on config entry removal
gjohansson-ST May 21, 2026
9634953
Fixes
gjohansson-ST May 21, 2026
aad7b6c
docstring
gjohansson-ST May 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions homeassistant/components/group/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@
ATTR_OBJECT_ID,
ATTR_ORDER,
ATTR_REMOVE_ENTITIES,
CONF_GROUP_TYPE,
CONF_HIDE_MEMBERS,
CONF_IGNORE_NON_NUMERIC,
DATA_COMPONENT,
DOMAIN,
GROUP_ORDER,
Expand Down
19 changes: 15 additions & 4 deletions homeassistant/components/group/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import voluptuous as vol

from homeassistant.components import websocket_api
from homeassistant.config_entries import ConfigFlowResult
from homeassistant.const import CONF_ENTITIES, CONF_TYPE
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
Expand All @@ -24,7 +25,7 @@

from .binary_sensor import CONF_ALL, async_create_preview_binary_sensor
from .button import async_create_preview_button
from .const import CONF_HIDE_MEMBERS, CONF_IGNORE_NON_NUMERIC, DOMAIN
from .const import CONF_GROUP_TYPE, CONF_HIDE_MEMBERS, CONF_IGNORE_NON_NUMERIC, DOMAIN
from .cover import async_create_preview_cover
from .entity import GroupEntity
from .event import async_create_preview_event
Expand Down Expand Up @@ -180,7 +181,7 @@ async def light_switch_options_schema(

async def choose_options_step(options: dict[str, Any]) -> str:
"""Return next step_id for options flow according to group_type."""
return cast(str, options["group_type"])
return cast(str, options[CONF_GROUP_TYPE])


def set_group_type(
Expand All @@ -194,7 +195,7 @@ async def _set_group_type(
handler: SchemaCommonFlowHandler, user_input: dict[str, Any]
) -> dict[str, Any]:
"""Add group type to user input."""
return {"group_type": group_type, **user_input}
return {CONF_GROUP_TYPE: group_type, **user_input}

return _set_group_type

Expand Down Expand Up @@ -344,6 +345,16 @@ class GroupConfigFlowHandler(SchemaConfigFlowHandler, domain=DOMAIN):
options_flow = OPTIONS_FLOW
options_flow_reloads = True

async def async_step_import(self, import_data: dict[str, Any]) -> ConfigFlowResult:
"""Import from a min_max config entry."""
new_data = import_data.copy()
new_data[CONF_ENTITIES] = new_data.pop("entity_ids")
new_data[CONF_GROUP_TYPE] = "sensor"
new_data[CONF_HIDE_MEMBERS] = False
new_data[CONF_IGNORE_NON_NUMERIC] = False

return self.async_create_entry(data=new_data)
Comment thread
gjohansson-ST marked this conversation as resolved.
Outdated

@callback
def async_config_entry_title(self, options: Mapping[str, Any]) -> str:
"""Return config entry title.
Expand Down Expand Up @@ -430,7 +441,7 @@ def ws_start_preview(
config_entry = hass.config_entries.async_get_entry(config_entry_id)
if not config_entry:
raise HomeAssistantError
group_type = config_entry.options["group_type"]
group_type = config_entry.options[CONF_GROUP_TYPE]
name = config_entry.options["name"]
validated = PREVIEW_OPTIONS_SCHEMA[group_type](msg["user_input"])
entity_registry = er.async_get(hass)
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/group/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

CONF_HIDE_MEMBERS = "hide_members"
CONF_IGNORE_NON_NUMERIC = "ignore_non_numeric"
CONF_GROUP_TYPE = "group_type"

DOMAIN = "group"
DATA_COMPONENT: HassKey[EntityComponent[Group]] = HassKey(DOMAIN)
Expand Down
63 changes: 60 additions & 3 deletions homeassistant/components/min_max/__init__.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,76 @@
"""The min_max component."""

from homeassistant.config_entries import ConfigEntry
from datetime import datetime
import logging
from types import MappingProxyType

from homeassistant.components.group import (
CONF_ENTITIES,
CONF_GROUP_TYPE,
CONF_HIDE_MEMBERS,
CONF_IGNORE_NON_NUMERIC,
DOMAIN as GROUP_DOMAIN,
)
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.config_entries import SOURCE_USER, ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.event import async_call_later

from .const import CONF_ENTITY_IDS, CONF_ROUND_DIGITS, DOMAIN

PLATFORMS = [Platform.SENSOR]
_LOGGER = logging.getLogger(__name__)


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Min/Max from a config entry."""
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

# Create group config from entry options
config = dict(entry.options)
config[CONF_ENTITIES] = config.pop(CONF_ENTITY_IDS)
config.pop(CONF_ROUND_DIGITS)
config[CONF_HIDE_MEMBERS] = False
config[CONF_IGNORE_NON_NUMERIC] = False
Comment thread
gjohansson-ST marked this conversation as resolved.
Outdated
config[CONF_GROUP_TYPE] = SENSOR_DOMAIN

# Create new config entry for group component and remove old entry
new_config_entry = ConfigEntry(
data={},
discovery_keys=MappingProxyType({}),
domain=GROUP_DOMAIN,
minor_version=1,
options=config,
source=SOURCE_USER,
subentries_data=[],
title=entry.title,
unique_id=None,
version=1,
)
Comment thread
gjohansson-ST marked this conversation as resolved.
Comment thread
gjohansson-ST marked this conversation as resolved.
await hass.config_entries.async_add(new_config_entry)

# Migrate entity from old entry to new entry
entity_reg = er.async_get(hass)
if old_entity := entity_reg.async_get_entity_id(
SENSOR_DOMAIN, DOMAIN, entry.entry_id
):
entity_reg.async_update_entity_platform(
old_entity, GROUP_DOMAIN, new_config_entry_id=new_config_entry.entry_id
)
Comment thread
gjohansson-ST marked this conversation as resolved.
Outdated
Comment thread
gjohansson-ST marked this conversation as resolved.
Outdated

# await hass.config_entries.async_remove(entry.entry_id)

async def remove_old_entry(now: datetime) -> None:
"""Remove the old config entry after migration."""
await hass.config_entries.async_remove(entry.entry_id)

async_call_later(hass, 60, remove_old_entry)
Comment thread
gjohansson-ST marked this conversation as resolved.
Outdated

return True


async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)

return True
51 changes: 51 additions & 0 deletions homeassistant/components/min_max/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"group": {
"created_at": "2026-04-10T14:33:19.033744+00:00",
"data": {},
"disabled_by": null,
"discovery_keys": {},
"domain": "group",
"entry_id": "01KNVWZHXSVPAZD4DGFF8TN94Z",
"minor_version": 1,
"modified_at": "2026-04-10T14:33:19.033750+00:00",
"options": {
"entities": ["sensor.carbon_dioxide", "sensor.carbon_monoxide"],
"group_type": "sensor",
"hide_members": false,
"ignore_non_numeric": false,
"name": "Olle",
"round_digits": 2.0,
"type": "min"
},
"pref_disable_new_entities": false,
"pref_disable_polling": false,
"source": "import",
"subentries": [],
"title": "Olle",
"unique_id": null,
"version": 1
},
"min_max": {
"created_at": "2026-04-10T14:13:58.312444+00:00",
"data": {},
"disabled_by": null,
"discovery_keys": {},
"domain": "min_max",
"entry_id": "01KNVVW4D8NK8ARQF8GCH7CD5A",
"minor_version": 1,
"modified_at": "2026-04-10T14:33:19.073168+00:00",
"options": {
"entity_ids": ["sensor.carbon_dioxide", "sensor.carbon_monoxide"],
"name": "Olle",
"round_digits": 2.0,
"type": "min"
},
"pref_disable_new_entities": false,
"pref_disable_polling": false,
"source": "user",
"subentries": [],
"title": "Olle",
"unique_id": null,
"version": 2
}
}
Comment thread
gjohansson-ST marked this conversation as resolved.
Outdated
Comment thread
gjohansson-ST marked this conversation as resolved.
Outdated
79 changes: 11 additions & 68 deletions homeassistant/components/min_max/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,20 @@

from __future__ import annotations

from collections.abc import Mapping
from typing import Any, cast
from typing import Any

import voluptuous as vol
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult

from homeassistant.components.input_number import DOMAIN as INPUT_NUMBER_DOMAIN
from homeassistant.components.number import DOMAIN as NUMBER_DOMAIN
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.const import CONF_TYPE
from homeassistant.helpers import selector
from homeassistant.helpers.schema_config_entry_flow import (
SchemaConfigFlowHandler,
SchemaFlowFormStep,
)
from .const import DOMAIN

from .const import CONF_ENTITY_IDS, CONF_ROUND_DIGITS, DOMAIN

_STATISTIC_MEASURES = [
"min",
"max",
"mean",
"median",
"last",
"range",
"sum",
]
class MinMaxConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for min_max integration."""

VERSION = 1

OPTIONS_SCHEMA = vol.Schema(
{
vol.Required(CONF_ENTITY_IDS): selector.EntitySelector(
selector.EntitySelectorConfig(
domain=[SENSOR_DOMAIN, NUMBER_DOMAIN, INPUT_NUMBER_DOMAIN],
multiple=True,
),
),
vol.Required(CONF_TYPE): selector.SelectSelector(
selector.SelectSelectorConfig(
options=_STATISTIC_MEASURES, translation_key=CONF_TYPE
),
),
vol.Required(CONF_ROUND_DIGITS, default=2): selector.NumberSelector(
selector.NumberSelectorConfig(
min=0, max=6, mode=selector.NumberSelectorMode.BOX
),
),
}
)

CONFIG_SCHEMA = vol.Schema(
{
vol.Required("name"): selector.TextSelector(),
}
).extend(OPTIONS_SCHEMA.schema)

CONFIG_FLOW = {
"user": SchemaFlowFormStep(CONFIG_SCHEMA),
}

OPTIONS_FLOW = {
"init": SchemaFlowFormStep(OPTIONS_SCHEMA),
}


class ConfigFlowHandler(SchemaConfigFlowHandler, domain=DOMAIN):
"""Handle a config or options flow for Min/Max."""

config_flow = CONFIG_FLOW
options_flow = OPTIONS_FLOW
options_flow_reloads = True

def async_config_entry_title(self, options: Mapping[str, Any]) -> str:
"""Return config entry title."""
return cast(str, options["name"]) if "name" in options else ""
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle the user step."""
return self.async_abort(reason="migrated_to_groups")
Comment thread
gjohansson-ST marked this conversation as resolved.
Outdated
Loading
Loading