Fix late group platform registration (#119789)
* Fix late group platform registration * use a callback instead * Run thread safe * Not working domain filter * Also update if a group has nested group's * Only update if the siingle state type key could change * Avoid redundant regisister hooks * Use set, add comment * Revert changes * Keep callback cleanup const * Cleanup after dependencies * Preimport and cleanup excluded domains * Revert test changes as we assume early set up now * Migrate alarm_control_panel * Migrate climate * Migrate cover * Migrate device_tracker * Migrate lock * Migrate media_player * Migrate person * Migrate plant * Migrate vacuum * Migrate water_heater * Remove water_heater group_pre_import * Use Platform enum if possible * Also use platform enum for excluded domains * Set registry to self._registry * move deregistering call back hook to async_added_to_hass * Add comment * Do no pass mutable reference to EXCLUDED_DOMAINS * Remove unneeded type hint
This commit is contained in:
parent
edb391a0bd
commit
66faeb28d7
30 changed files with 140 additions and 406 deletions
|
@ -17,7 +17,6 @@ from homeassistant.helpers.entity import Entity
|
||||||
from homeassistant.helpers.entity_component import EntityComponent
|
from homeassistant.helpers.entity_component import EntityComponent
|
||||||
from homeassistant.helpers.typing import ConfigType, StateType
|
from homeassistant.helpers.typing import ConfigType, StateType
|
||||||
|
|
||||||
from . import group as group_pre_import # noqa: F401
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
|
||||||
_LOGGER: Final = logging.getLogger(__name__)
|
_LOGGER: Final = logging.getLogger(__name__)
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
"""Describe group states."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from homeassistant.components.group import GroupIntegrationRegistry
|
|
||||||
|
|
||||||
from .const import DOMAIN
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def async_describe_on_off_states(
|
|
||||||
hass: HomeAssistant, registry: GroupIntegrationRegistry
|
|
||||||
) -> None:
|
|
||||||
"""Describe group on off states."""
|
|
||||||
registry.exclude_domain(DOMAIN)
|
|
|
@ -34,7 +34,6 @@ from homeassistant.helpers.entity import Entity, EntityDescription
|
||||||
from homeassistant.helpers.entity_component import EntityComponent
|
from homeassistant.helpers.entity_component import EntityComponent
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
|
|
||||||
from . import group as group_pre_import # noqa: F401
|
|
||||||
from .const import ( # noqa: F401
|
from .const import ( # noqa: F401
|
||||||
_DEPRECATED_FORMAT_NUMBER,
|
_DEPRECATED_FORMAT_NUMBER,
|
||||||
_DEPRECATED_FORMAT_TEXT,
|
_DEPRECATED_FORMAT_TEXT,
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
"""Describe group states."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from homeassistant.const import (
|
|
||||||
STATE_ALARM_ARMED_AWAY,
|
|
||||||
STATE_ALARM_ARMED_CUSTOM_BYPASS,
|
|
||||||
STATE_ALARM_ARMED_HOME,
|
|
||||||
STATE_ALARM_ARMED_NIGHT,
|
|
||||||
STATE_ALARM_ARMED_VACATION,
|
|
||||||
STATE_ALARM_TRIGGERED,
|
|
||||||
STATE_OFF,
|
|
||||||
STATE_ON,
|
|
||||||
)
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
|
||||||
|
|
||||||
from .const import DOMAIN
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from homeassistant.components.group import GroupIntegrationRegistry
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def async_describe_on_off_states(
|
|
||||||
hass: HomeAssistant, registry: GroupIntegrationRegistry
|
|
||||||
) -> None:
|
|
||||||
"""Describe group on off states."""
|
|
||||||
registry.on_off_states(
|
|
||||||
DOMAIN,
|
|
||||||
{
|
|
||||||
STATE_ON,
|
|
||||||
STATE_ALARM_ARMED_AWAY,
|
|
||||||
STATE_ALARM_ARMED_CUSTOM_BYPASS,
|
|
||||||
STATE_ALARM_ARMED_HOME,
|
|
||||||
STATE_ALARM_ARMED_NIGHT,
|
|
||||||
STATE_ALARM_ARMED_VACATION,
|
|
||||||
STATE_ALARM_TRIGGERED,
|
|
||||||
},
|
|
||||||
STATE_ON,
|
|
||||||
STATE_OFF,
|
|
||||||
)
|
|
|
@ -45,7 +45,6 @@ from homeassistant.helpers.typing import ConfigType
|
||||||
from homeassistant.loader import async_get_issue_tracker, async_suggest_report_issue
|
from homeassistant.loader import async_get_issue_tracker, async_suggest_report_issue
|
||||||
from homeassistant.util.unit_conversion import TemperatureConverter
|
from homeassistant.util.unit_conversion import TemperatureConverter
|
||||||
|
|
||||||
from . import group as group_pre_import # noqa: F401
|
|
||||||
from .const import ( # noqa: F401
|
from .const import ( # noqa: F401
|
||||||
_DEPRECATED_HVAC_MODE_AUTO,
|
_DEPRECATED_HVAC_MODE_AUTO,
|
||||||
_DEPRECATED_HVAC_MODE_COOL,
|
_DEPRECATED_HVAC_MODE_COOL,
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
"""Describe group states."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from homeassistant.const import STATE_OFF, STATE_ON
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
|
||||||
|
|
||||||
from .const import DOMAIN, HVACMode
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from homeassistant.components.group import GroupIntegrationRegistry
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def async_describe_on_off_states(
|
|
||||||
hass: HomeAssistant, registry: GroupIntegrationRegistry
|
|
||||||
) -> None:
|
|
||||||
"""Describe group on off states."""
|
|
||||||
registry.on_off_states(
|
|
||||||
DOMAIN,
|
|
||||||
{
|
|
||||||
STATE_ON,
|
|
||||||
HVACMode.HEAT,
|
|
||||||
HVACMode.COOL,
|
|
||||||
HVACMode.HEAT_COOL,
|
|
||||||
HVACMode.AUTO,
|
|
||||||
HVACMode.FAN_ONLY,
|
|
||||||
},
|
|
||||||
STATE_ON,
|
|
||||||
STATE_OFF,
|
|
||||||
)
|
|
|
@ -45,7 +45,6 @@ from homeassistant.helpers.entity_component import EntityComponent
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
from homeassistant.loader import bind_hass
|
from homeassistant.loader import bind_hass
|
||||||
|
|
||||||
from . import group as group_pre_import # noqa: F401
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
"""Describe group states."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from homeassistant.const import STATE_CLOSED, STATE_OPEN
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
|
||||||
|
|
||||||
from .const import DOMAIN
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from homeassistant.components.group import GroupIntegrationRegistry
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def async_describe_on_off_states(
|
|
||||||
hass: HomeAssistant, registry: GroupIntegrationRegistry
|
|
||||||
) -> None:
|
|
||||||
"""Describe group on off states."""
|
|
||||||
# On means open, Off means closed
|
|
||||||
registry.on_off_states(DOMAIN, {STATE_OPEN}, STATE_OPEN, STATE_CLOSED)
|
|
|
@ -14,7 +14,6 @@ from homeassistant.helpers.deprecation import (
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
from homeassistant.loader import bind_hass
|
from homeassistant.loader import bind_hass
|
||||||
|
|
||||||
from . import group as group_pre_import # noqa: F401
|
|
||||||
from .config_entry import ( # noqa: F401
|
from .config_entry import ( # noqa: F401
|
||||||
ScannerEntity,
|
ScannerEntity,
|
||||||
TrackerEntity,
|
TrackerEntity,
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
"""Describe group states."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from homeassistant.const import STATE_HOME, STATE_NOT_HOME
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
|
||||||
|
|
||||||
from .const import DOMAIN
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from homeassistant.components.group import GroupIntegrationRegistry
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def async_describe_on_off_states(
|
|
||||||
hass: HomeAssistant, registry: GroupIntegrationRegistry
|
|
||||||
) -> None:
|
|
||||||
"""Describe group on off states."""
|
|
||||||
registry.on_off_states(DOMAIN, {STATE_HOME}, STATE_HOME, STATE_NOT_HOME)
|
|
|
@ -265,16 +265,16 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||||
if ATTR_ADD_ENTITIES in service.data:
|
if ATTR_ADD_ENTITIES in service.data:
|
||||||
delta = service.data[ATTR_ADD_ENTITIES]
|
delta = service.data[ATTR_ADD_ENTITIES]
|
||||||
entity_ids = set(group.tracking) | set(delta)
|
entity_ids = set(group.tracking) | set(delta)
|
||||||
await group.async_update_tracked_entity_ids(entity_ids)
|
group.async_update_tracked_entity_ids(entity_ids)
|
||||||
|
|
||||||
if ATTR_REMOVE_ENTITIES in service.data:
|
if ATTR_REMOVE_ENTITIES in service.data:
|
||||||
delta = service.data[ATTR_REMOVE_ENTITIES]
|
delta = service.data[ATTR_REMOVE_ENTITIES]
|
||||||
entity_ids = set(group.tracking) - set(delta)
|
entity_ids = set(group.tracking) - set(delta)
|
||||||
await group.async_update_tracked_entity_ids(entity_ids)
|
group.async_update_tracked_entity_ids(entity_ids)
|
||||||
|
|
||||||
if ATTR_ENTITIES in service.data:
|
if ATTR_ENTITIES in service.data:
|
||||||
entity_ids = service.data[ATTR_ENTITIES]
|
entity_ids = service.data[ATTR_ENTITIES]
|
||||||
await group.async_update_tracked_entity_ids(entity_ids)
|
group.async_update_tracked_entity_ids(entity_ids)
|
||||||
|
|
||||||
if ATTR_NAME in service.data:
|
if ATTR_NAME in service.data:
|
||||||
group.set_name(service.data[ATTR_NAME])
|
group.set_name(service.data[ATTR_NAME])
|
||||||
|
|
|
@ -133,6 +133,7 @@ class Group(Entity):
|
||||||
tracking: tuple[str, ...]
|
tracking: tuple[str, ...]
|
||||||
trackable: tuple[str, ...]
|
trackable: tuple[str, ...]
|
||||||
single_state_type_key: SingleStateType | None
|
single_state_type_key: SingleStateType | None
|
||||||
|
_registry: GroupIntegrationRegistry
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
@ -261,7 +262,8 @@ class Group(Entity):
|
||||||
"""Test if any member has an assumed state."""
|
"""Test if any member has an assumed state."""
|
||||||
return self._assumed_state
|
return self._assumed_state
|
||||||
|
|
||||||
async def async_update_tracked_entity_ids(
|
@callback
|
||||||
|
def async_update_tracked_entity_ids(
|
||||||
self, entity_ids: Collection[str] | None
|
self, entity_ids: Collection[str] | None
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Update the member entity IDs.
|
"""Update the member entity IDs.
|
||||||
|
@ -284,7 +286,7 @@ class Group(Entity):
|
||||||
self.single_state_type_key = None
|
self.single_state_type_key = None
|
||||||
return
|
return
|
||||||
|
|
||||||
registry: GroupIntegrationRegistry = self.hass.data[REG_KEY]
|
registry = self._registry
|
||||||
excluded_domains = registry.exclude_domains
|
excluded_domains = registry.exclude_domains
|
||||||
|
|
||||||
tracking: list[str] = []
|
tracking: list[str] = []
|
||||||
|
@ -313,7 +315,6 @@ class Group(Entity):
|
||||||
registry.state_group_mapping[self.entity_id] = self.single_state_type_key
|
registry.state_group_mapping[self.entity_id] = self.single_state_type_key
|
||||||
else:
|
else:
|
||||||
self.single_state_type_key = None
|
self.single_state_type_key = None
|
||||||
self.async_on_remove(self._async_deregister)
|
|
||||||
|
|
||||||
self.trackable = tuple(trackable)
|
self.trackable = tuple(trackable)
|
||||||
self.tracking = tuple(tracking)
|
self.tracking = tuple(tracking)
|
||||||
|
@ -321,7 +322,7 @@ class Group(Entity):
|
||||||
@callback
|
@callback
|
||||||
def _async_deregister(self) -> None:
|
def _async_deregister(self) -> None:
|
||||||
"""Deregister group entity from the registry."""
|
"""Deregister group entity from the registry."""
|
||||||
registry: GroupIntegrationRegistry = self.hass.data[REG_KEY]
|
registry = self._registry
|
||||||
if self.entity_id in registry.state_group_mapping:
|
if self.entity_id in registry.state_group_mapping:
|
||||||
registry.state_group_mapping.pop(self.entity_id)
|
registry.state_group_mapping.pop(self.entity_id)
|
||||||
|
|
||||||
|
@ -363,8 +364,10 @@ class Group(Entity):
|
||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Handle addition to Home Assistant."""
|
"""Handle addition to Home Assistant."""
|
||||||
|
self._registry = self.hass.data[REG_KEY]
|
||||||
self._set_tracked(self._entity_ids)
|
self._set_tracked(self._entity_ids)
|
||||||
self.async_on_remove(start.async_at_start(self.hass, self._async_start))
|
self.async_on_remove(start.async_at_start(self.hass, self._async_start))
|
||||||
|
self.async_on_remove(self._async_deregister)
|
||||||
|
|
||||||
async def async_will_remove_from_hass(self) -> None:
|
async def async_will_remove_from_hass(self) -> None:
|
||||||
"""Handle removal from Home Assistant."""
|
"""Handle removal from Home Assistant."""
|
||||||
|
@ -405,7 +408,7 @@ class Group(Entity):
|
||||||
entity_id = new_state.entity_id
|
entity_id = new_state.entity_id
|
||||||
domain = new_state.domain
|
domain = new_state.domain
|
||||||
state = new_state.state
|
state = new_state.state
|
||||||
registry: GroupIntegrationRegistry = self.hass.data[REG_KEY]
|
registry = self._registry
|
||||||
self._assumed[entity_id] = bool(new_state.attributes.get(ATTR_ASSUMED_STATE))
|
self._assumed[entity_id] = bool(new_state.attributes.get(ATTR_ASSUMED_STATE))
|
||||||
|
|
||||||
if domain not in registry.on_states_by_domain:
|
if domain not in registry.on_states_by_domain:
|
||||||
|
|
|
@ -1,18 +1,6 @@
|
||||||
{
|
{
|
||||||
"domain": "group",
|
"domain": "group",
|
||||||
"name": "Group",
|
"name": "Group",
|
||||||
"after_dependencies": [
|
|
||||||
"alarm_control_panel",
|
|
||||||
"climate",
|
|
||||||
"cover",
|
|
||||||
"device_tracker",
|
|
||||||
"lock",
|
|
||||||
"media_player",
|
|
||||||
"person",
|
|
||||||
"plant",
|
|
||||||
"vacuum",
|
|
||||||
"water_heater"
|
|
||||||
],
|
|
||||||
"codeowners": ["@home-assistant/core"],
|
"codeowners": ["@home-assistant/core"],
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/group",
|
"documentation": "https://www.home-assistant.io/integrations/group",
|
||||||
|
|
|
@ -8,7 +8,41 @@ from __future__ import annotations
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Protocol
|
from typing import Protocol
|
||||||
|
|
||||||
from homeassistant.const import STATE_OFF, STATE_ON
|
from homeassistant.components.climate import HVACMode
|
||||||
|
from homeassistant.components.vacuum import STATE_CLEANING, STATE_ERROR, STATE_RETURNING
|
||||||
|
from homeassistant.components.water_heater import (
|
||||||
|
STATE_ECO,
|
||||||
|
STATE_ELECTRIC,
|
||||||
|
STATE_GAS,
|
||||||
|
STATE_HEAT_PUMP,
|
||||||
|
STATE_HIGH_DEMAND,
|
||||||
|
STATE_PERFORMANCE,
|
||||||
|
)
|
||||||
|
from homeassistant.const import (
|
||||||
|
STATE_ALARM_ARMED_AWAY,
|
||||||
|
STATE_ALARM_ARMED_CUSTOM_BYPASS,
|
||||||
|
STATE_ALARM_ARMED_HOME,
|
||||||
|
STATE_ALARM_ARMED_NIGHT,
|
||||||
|
STATE_ALARM_ARMED_VACATION,
|
||||||
|
STATE_ALARM_TRIGGERED,
|
||||||
|
STATE_CLOSED,
|
||||||
|
STATE_HOME,
|
||||||
|
STATE_IDLE,
|
||||||
|
STATE_LOCKED,
|
||||||
|
STATE_LOCKING,
|
||||||
|
STATE_NOT_HOME,
|
||||||
|
STATE_OFF,
|
||||||
|
STATE_OK,
|
||||||
|
STATE_ON,
|
||||||
|
STATE_OPEN,
|
||||||
|
STATE_OPENING,
|
||||||
|
STATE_PAUSED,
|
||||||
|
STATE_PLAYING,
|
||||||
|
STATE_PROBLEM,
|
||||||
|
STATE_UNLOCKED,
|
||||||
|
STATE_UNLOCKING,
|
||||||
|
Platform,
|
||||||
|
)
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.integration_platform import (
|
from homeassistant.helpers.integration_platform import (
|
||||||
async_process_integration_platforms,
|
async_process_integration_platforms,
|
||||||
|
@ -16,6 +50,92 @@ from homeassistant.helpers.integration_platform import (
|
||||||
|
|
||||||
from .const import DOMAIN, REG_KEY
|
from .const import DOMAIN, REG_KEY
|
||||||
|
|
||||||
|
# EXCLUDED_DOMAINS and ON_OFF_STATES are considered immutable
|
||||||
|
# in respect that new platforms should not be added.
|
||||||
|
# The the only maintenance allowed here is
|
||||||
|
# if existing platforms add new ON or OFF states.
|
||||||
|
EXCLUDED_DOMAINS: set[Platform | str] = {
|
||||||
|
Platform.AIR_QUALITY,
|
||||||
|
Platform.SENSOR,
|
||||||
|
Platform.WEATHER,
|
||||||
|
}
|
||||||
|
|
||||||
|
ON_OFF_STATES: dict[Platform | str, tuple[set[str], str, str]] = {
|
||||||
|
Platform.ALARM_CONTROL_PANEL: (
|
||||||
|
{
|
||||||
|
STATE_ON,
|
||||||
|
STATE_ALARM_ARMED_AWAY,
|
||||||
|
STATE_ALARM_ARMED_CUSTOM_BYPASS,
|
||||||
|
STATE_ALARM_ARMED_HOME,
|
||||||
|
STATE_ALARM_ARMED_NIGHT,
|
||||||
|
STATE_ALARM_ARMED_VACATION,
|
||||||
|
STATE_ALARM_TRIGGERED,
|
||||||
|
},
|
||||||
|
STATE_ON,
|
||||||
|
STATE_OFF,
|
||||||
|
),
|
||||||
|
Platform.CLIMATE: (
|
||||||
|
{
|
||||||
|
STATE_ON,
|
||||||
|
HVACMode.HEAT,
|
||||||
|
HVACMode.COOL,
|
||||||
|
HVACMode.HEAT_COOL,
|
||||||
|
HVACMode.AUTO,
|
||||||
|
HVACMode.FAN_ONLY,
|
||||||
|
},
|
||||||
|
STATE_ON,
|
||||||
|
STATE_OFF,
|
||||||
|
),
|
||||||
|
Platform.COVER: ({STATE_OPEN}, STATE_OPEN, STATE_CLOSED),
|
||||||
|
Platform.DEVICE_TRACKER: ({STATE_HOME}, STATE_HOME, STATE_NOT_HOME),
|
||||||
|
Platform.LOCK: (
|
||||||
|
{
|
||||||
|
STATE_LOCKING,
|
||||||
|
STATE_OPEN,
|
||||||
|
STATE_OPENING,
|
||||||
|
STATE_UNLOCKED,
|
||||||
|
STATE_UNLOCKING,
|
||||||
|
},
|
||||||
|
STATE_UNLOCKED,
|
||||||
|
STATE_LOCKED,
|
||||||
|
),
|
||||||
|
Platform.MEDIA_PLAYER: (
|
||||||
|
{
|
||||||
|
STATE_ON,
|
||||||
|
STATE_PAUSED,
|
||||||
|
STATE_PLAYING,
|
||||||
|
STATE_IDLE,
|
||||||
|
},
|
||||||
|
STATE_ON,
|
||||||
|
STATE_OFF,
|
||||||
|
),
|
||||||
|
"person": ({STATE_HOME}, STATE_HOME, STATE_NOT_HOME),
|
||||||
|
"plant": ({STATE_PROBLEM}, STATE_PROBLEM, STATE_OK),
|
||||||
|
Platform.VACUUM: (
|
||||||
|
{
|
||||||
|
STATE_ON,
|
||||||
|
STATE_CLEANING,
|
||||||
|
STATE_RETURNING,
|
||||||
|
STATE_ERROR,
|
||||||
|
},
|
||||||
|
STATE_ON,
|
||||||
|
STATE_OFF,
|
||||||
|
),
|
||||||
|
Platform.WATER_HEATER: (
|
||||||
|
{
|
||||||
|
STATE_ON,
|
||||||
|
STATE_ECO,
|
||||||
|
STATE_ELECTRIC,
|
||||||
|
STATE_PERFORMANCE,
|
||||||
|
STATE_HIGH_DEMAND,
|
||||||
|
STATE_HEAT_PUMP,
|
||||||
|
STATE_GAS,
|
||||||
|
},
|
||||||
|
STATE_ON,
|
||||||
|
STATE_OFF,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async def async_setup(hass: HomeAssistant) -> None:
|
async def async_setup(hass: HomeAssistant) -> None:
|
||||||
"""Set up the Group integration registry of integration platforms."""
|
"""Set up the Group integration registry of integration platforms."""
|
||||||
|
@ -61,8 +181,10 @@ class GroupIntegrationRegistry:
|
||||||
self.on_off_mapping: dict[str, str] = {STATE_ON: STATE_OFF}
|
self.on_off_mapping: dict[str, str] = {STATE_ON: STATE_OFF}
|
||||||
self.off_on_mapping: dict[str, str] = {STATE_OFF: STATE_ON}
|
self.off_on_mapping: dict[str, str] = {STATE_OFF: STATE_ON}
|
||||||
self.on_states_by_domain: dict[str, set[str]] = {}
|
self.on_states_by_domain: dict[str, set[str]] = {}
|
||||||
self.exclude_domains: set[str] = set()
|
self.exclude_domains = EXCLUDED_DOMAINS.copy()
|
||||||
self.state_group_mapping: dict[str, SingleStateType] = {}
|
self.state_group_mapping: dict[str, SingleStateType] = {}
|
||||||
|
for domain, on_off_states in ON_OFF_STATES.items():
|
||||||
|
self.on_off_states(domain, *on_off_states)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def exclude_domain(self, domain: str) -> None:
|
def exclude_domain(self, domain: str) -> None:
|
||||||
|
@ -71,7 +193,11 @@ class GroupIntegrationRegistry:
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def on_off_states(
|
def on_off_states(
|
||||||
self, domain: str, on_states: set[str], default_on_state: str, off_state: str
|
self,
|
||||||
|
domain: Platform | str,
|
||||||
|
on_states: set[str],
|
||||||
|
default_on_state: str,
|
||||||
|
off_state: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Register on and off states for the current domain.
|
"""Register on and off states for the current domain.
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@ from homeassistant.helpers.entity import Entity, EntityDescription
|
||||||
from homeassistant.helpers.entity_component import EntityComponent
|
from homeassistant.helpers.entity_component import EntityComponent
|
||||||
from homeassistant.helpers.typing import ConfigType, StateType
|
from homeassistant.helpers.typing import ConfigType, StateType
|
||||||
|
|
||||||
from . import group as group_pre_import # noqa: F401
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
"""Describe group states."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from homeassistant.const import (
|
|
||||||
STATE_LOCKED,
|
|
||||||
STATE_LOCKING,
|
|
||||||
STATE_OPEN,
|
|
||||||
STATE_OPENING,
|
|
||||||
STATE_UNLOCKED,
|
|
||||||
STATE_UNLOCKING,
|
|
||||||
)
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
|
||||||
|
|
||||||
from .const import DOMAIN
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from homeassistant.components.group import GroupIntegrationRegistry
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def async_describe_on_off_states(
|
|
||||||
hass: HomeAssistant, registry: GroupIntegrationRegistry
|
|
||||||
) -> None:
|
|
||||||
"""Describe group on off states."""
|
|
||||||
registry.on_off_states(
|
|
||||||
DOMAIN,
|
|
||||||
{
|
|
||||||
STATE_LOCKING,
|
|
||||||
STATE_OPEN,
|
|
||||||
STATE_OPENING,
|
|
||||||
STATE_UNLOCKED,
|
|
||||||
STATE_UNLOCKING,
|
|
||||||
},
|
|
||||||
STATE_UNLOCKED,
|
|
||||||
STATE_LOCKED,
|
|
||||||
)
|
|
|
@ -64,7 +64,6 @@ from homeassistant.helpers.network import get_url
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
from homeassistant.loader import bind_hass
|
from homeassistant.loader import bind_hass
|
||||||
|
|
||||||
from . import group as group_pre_import # noqa: F401
|
|
||||||
from .browse_media import BrowseMedia, async_process_play_media_url # noqa: F401
|
from .browse_media import BrowseMedia, async_process_play_media_url # noqa: F401
|
||||||
from .const import ( # noqa: F401
|
from .const import ( # noqa: F401
|
||||||
ATTR_APP_ID,
|
ATTR_APP_ID,
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
"""Describe group states."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from homeassistant.const import (
|
|
||||||
STATE_IDLE,
|
|
||||||
STATE_OFF,
|
|
||||||
STATE_ON,
|
|
||||||
STATE_PAUSED,
|
|
||||||
STATE_PLAYING,
|
|
||||||
)
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
|
||||||
|
|
||||||
from .const import DOMAIN
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from homeassistant.components.group import GroupIntegrationRegistry
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def async_describe_on_off_states(
|
|
||||||
hass: HomeAssistant, registry: GroupIntegrationRegistry
|
|
||||||
) -> None:
|
|
||||||
"""Describe group on off states."""
|
|
||||||
registry.on_off_states(
|
|
||||||
DOMAIN,
|
|
||||||
{
|
|
||||||
STATE_ON,
|
|
||||||
STATE_PAUSED,
|
|
||||||
STATE_PLAYING,
|
|
||||||
STATE_IDLE,
|
|
||||||
},
|
|
||||||
STATE_ON,
|
|
||||||
STATE_OFF,
|
|
||||||
)
|
|
|
@ -53,7 +53,6 @@ from homeassistant.helpers.storage import Store
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
from homeassistant.loader import bind_hass
|
from homeassistant.loader import bind_hass
|
||||||
|
|
||||||
from . import group as group_pre_import # noqa: F401
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
"""Describe group states."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from homeassistant.const import STATE_HOME, STATE_NOT_HOME
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
|
||||||
|
|
||||||
from .const import DOMAIN
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from homeassistant.components.group import GroupIntegrationRegistry
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def async_describe_on_off_states(
|
|
||||||
hass: HomeAssistant, registry: GroupIntegrationRegistry
|
|
||||||
) -> None:
|
|
||||||
"""Describe group on off states."""
|
|
||||||
registry.on_off_states(DOMAIN, {STATE_HOME}, STATE_HOME, STATE_NOT_HOME)
|
|
|
@ -35,7 +35,6 @@ from homeassistant.helpers.event import async_track_state_change_event
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
from . import group as group_pre_import # noqa: F401
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ATTR_DICT_OF_UNITS_OF_MEASUREMENT,
|
ATTR_DICT_OF_UNITS_OF_MEASUREMENT,
|
||||||
ATTR_MAX_BRIGHTNESS_HISTORY,
|
ATTR_MAX_BRIGHTNESS_HISTORY,
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
"""Describe group states."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from homeassistant.const import STATE_OK, STATE_PROBLEM
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
|
||||||
|
|
||||||
from .const import DOMAIN
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from homeassistant.components.group import GroupIntegrationRegistry
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def async_describe_on_off_states(
|
|
||||||
hass: HomeAssistant, registry: GroupIntegrationRegistry
|
|
||||||
) -> None:
|
|
||||||
"""Describe group on off states."""
|
|
||||||
registry.on_off_states(DOMAIN, {STATE_PROBLEM}, STATE_PROBLEM, STATE_OK)
|
|
|
@ -68,7 +68,6 @@ from homeassistant.helpers.typing import UNDEFINED, ConfigType, StateType, Undef
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
from homeassistant.util.enum import try_parse_enum
|
from homeassistant.util.enum import try_parse_enum
|
||||||
|
|
||||||
from . import group as group_pre_import # noqa: F401
|
|
||||||
from .const import ( # noqa: F401
|
from .const import ( # noqa: F401
|
||||||
_DEPRECATED_STATE_CLASS_MEASUREMENT,
|
_DEPRECATED_STATE_CLASS_MEASUREMENT,
|
||||||
_DEPRECATED_STATE_CLASS_TOTAL,
|
_DEPRECATED_STATE_CLASS_TOTAL,
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
"""Describe group states."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from homeassistant.components.group import GroupIntegrationRegistry
|
|
||||||
|
|
||||||
from .const import DOMAIN
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def async_describe_on_off_states(
|
|
||||||
hass: HomeAssistant, registry: GroupIntegrationRegistry
|
|
||||||
) -> None:
|
|
||||||
"""Describe group on off states."""
|
|
||||||
registry.exclude_domain(DOMAIN)
|
|
|
@ -34,7 +34,6 @@ from homeassistant.helpers.icon import icon_for_battery_level
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
from homeassistant.loader import bind_hass
|
from homeassistant.loader import bind_hass
|
||||||
|
|
||||||
from . import group as group_pre_import # noqa: F401
|
|
||||||
from .const import DOMAIN, STATE_CLEANING, STATE_DOCKED, STATE_ERROR, STATE_RETURNING
|
from .const import DOMAIN, STATE_CLEANING, STATE_DOCKED, STATE_ERROR, STATE_RETURNING
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
"""Describe group states."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from homeassistant.const import STATE_OFF, STATE_ON
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from homeassistant.components.group import GroupIntegrationRegistry
|
|
||||||
|
|
||||||
from .const import DOMAIN, STATE_CLEANING, STATE_ERROR, STATE_RETURNING
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def async_describe_on_off_states(
|
|
||||||
hass: HomeAssistant, registry: GroupIntegrationRegistry
|
|
||||||
) -> None:
|
|
||||||
"""Describe group on off states."""
|
|
||||||
registry.on_off_states(
|
|
||||||
DOMAIN,
|
|
||||||
{
|
|
||||||
STATE_ON,
|
|
||||||
STATE_CLEANING,
|
|
||||||
STATE_RETURNING,
|
|
||||||
STATE_ERROR,
|
|
||||||
},
|
|
||||||
STATE_ON,
|
|
||||||
STATE_OFF,
|
|
||||||
)
|
|
|
@ -42,7 +42,6 @@ from homeassistant.helpers.temperature import display_temp as show_temp
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
from homeassistant.util.unit_conversion import TemperatureConverter
|
from homeassistant.util.unit_conversion import TemperatureConverter
|
||||||
|
|
||||||
from . import group as group_pre_import # noqa: F401
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
|
|
||||||
DEFAULT_MIN_TEMP = 110
|
DEFAULT_MIN_TEMP = 110
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
"""Describe group states."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from homeassistant.const import STATE_OFF, STATE_ON
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from homeassistant.components.group import GroupIntegrationRegistry
|
|
||||||
|
|
||||||
from .const import (
|
|
||||||
DOMAIN,
|
|
||||||
STATE_ECO,
|
|
||||||
STATE_ELECTRIC,
|
|
||||||
STATE_GAS,
|
|
||||||
STATE_HEAT_PUMP,
|
|
||||||
STATE_HIGH_DEMAND,
|
|
||||||
STATE_PERFORMANCE,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def async_describe_on_off_states(
|
|
||||||
hass: HomeAssistant, registry: GroupIntegrationRegistry
|
|
||||||
) -> None:
|
|
||||||
"""Describe group on off states."""
|
|
||||||
registry.on_off_states(
|
|
||||||
DOMAIN,
|
|
||||||
{
|
|
||||||
STATE_ON,
|
|
||||||
STATE_ECO,
|
|
||||||
STATE_ELECTRIC,
|
|
||||||
STATE_PERFORMANCE,
|
|
||||||
STATE_HIGH_DEMAND,
|
|
||||||
STATE_HEAT_PUMP,
|
|
||||||
STATE_GAS,
|
|
||||||
},
|
|
||||||
STATE_ON,
|
|
||||||
STATE_OFF,
|
|
||||||
)
|
|
|
@ -47,7 +47,6 @@ from homeassistant.util.dt import utcnow
|
||||||
from homeassistant.util.json import JsonValueType
|
from homeassistant.util.json import JsonValueType
|
||||||
from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM
|
from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM
|
||||||
|
|
||||||
from . import group as group_pre_import # noqa: F401
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ATTR_WEATHER_APPARENT_TEMPERATURE,
|
ATTR_WEATHER_APPARENT_TEMPERATURE,
|
||||||
ATTR_WEATHER_CLOUD_COVERAGE,
|
ATTR_WEATHER_CLOUD_COVERAGE,
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
"""Describe group states."""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from homeassistant.components.group import GroupIntegrationRegistry
|
|
||||||
|
|
||||||
from .const import DOMAIN
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def async_describe_on_off_states(
|
|
||||||
hass: HomeAssistant, registry: GroupIntegrationRegistry
|
|
||||||
) -> None:
|
|
||||||
"""Describe group on off states."""
|
|
||||||
registry.exclude_domain(DOMAIN)
|
|
Loading…
Add table
Reference in a new issue