Merge config subentry feature branch to dev (#136121)

* Reapply "Add support for subentries to config entries" (#133470) (#136061)

* Reapply "Add support for subentries to config entries" (#133470)

This reverts commit ecb3bf79f32a2e25d141ff467e5958826ed9fc3a.

* Update test snapshot

* Add config subentry support to device registry (#128157)

* Add config subentry support to device registry

* Apply suggestions from code review

* Update syrupy serializer

* Update snapshots

* Address review comments

* Allow a device to be connected to no or a single subentry of a config entry

* Update snapshots

* Revert "Allow a device to be connected to no or a single subentry of a config entry"

This reverts commit ec6f613151cb4a806b7961033c004b71b76510c2.

* Update test snapshots

* Bump release version in comments

* Rename config_subentries to config_entries_subentries

* Add config subentry support to entity registry (#128155)

* Add config subentry support to entity registry

* Update syrupy serializer

* Update snapshots

* Update snapshots

* Accept suggested changes

* Clean registries when removing subentry (#136671)

* Clean up registries when removing subentry

* Update tests

* Clean up subentries from deleted devices when removing config entry (#136669)

* Clean up subentries from deleted devices when removing config entry

* Move

* Add config subentry support to entity platform (#128161)

* Add config subentry support to entity platform

* Rename subentry_id to config_subentry_id

* Store subentry type in subentry (#136687)

* Add reconfigure support to config subentries (#133353)

* Add reconfigure support to config subentries

* Update test

* Minor adjustment

* Rename supported_subentry_flows to supported_subentry_types

* Address review comments

* Add subentry support to kitchen sink (#136755)

* Add subentry support to kitchen sink

* Add subentry reconfigure support to kitchen_sink

* Update kitchen_sink tests with subentry type stored in config entry

* Update kitchen_sink

* Update kitchen_sink

* Adjust kitchen sink tests

* Fix hassfest

* Apply suggestions from code review

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Improve docstrings and strings.json

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Update snapshots

* Update snapshots

* Update snapshots

* Update snapshots

* Update snapshots

* Update snapshots

* Update snapshots

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
Erik Montnemery 2025-02-10 16:40:07 +01:00 committed by GitHub
parent 854af1449b
commit 4b34d1bbb5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
668 changed files with 10982 additions and 153 deletions

View File

@ -46,6 +46,13 @@ def async_setup(hass: HomeAssistant) -> bool:
hass.http.register_view(OptionManagerFlowIndexView(hass.config_entries.options)) hass.http.register_view(OptionManagerFlowIndexView(hass.config_entries.options))
hass.http.register_view(OptionManagerFlowResourceView(hass.config_entries.options)) hass.http.register_view(OptionManagerFlowResourceView(hass.config_entries.options))
hass.http.register_view(
SubentryManagerFlowIndexView(hass.config_entries.subentries)
)
hass.http.register_view(
SubentryManagerFlowResourceView(hass.config_entries.subentries)
)
websocket_api.async_register_command(hass, config_entries_get) websocket_api.async_register_command(hass, config_entries_get)
websocket_api.async_register_command(hass, config_entry_disable) websocket_api.async_register_command(hass, config_entry_disable)
websocket_api.async_register_command(hass, config_entry_get_single) websocket_api.async_register_command(hass, config_entry_get_single)
@ -54,6 +61,9 @@ def async_setup(hass: HomeAssistant) -> bool:
websocket_api.async_register_command(hass, config_entries_progress) websocket_api.async_register_command(hass, config_entries_progress)
websocket_api.async_register_command(hass, ignore_config_flow) websocket_api.async_register_command(hass, ignore_config_flow)
websocket_api.async_register_command(hass, config_subentry_delete)
websocket_api.async_register_command(hass, config_subentry_list)
return True return True
@ -285,6 +295,66 @@ class OptionManagerFlowResourceView(
return await super().post(request, flow_id) return await super().post(request, flow_id)
class SubentryManagerFlowIndexView(
FlowManagerIndexView[config_entries.ConfigSubentryFlowManager]
):
"""View to create subentry flows."""
url = "/api/config/config_entries/subentries/flow"
name = "api:config:config_entries:subentries:flow"
@require_admin(
error=Unauthorized(perm_category=CAT_CONFIG_ENTRIES, permission=POLICY_EDIT)
)
@RequestDataValidator(
vol.Schema(
{
vol.Required("handler"): vol.All(vol.Coerce(tuple), (str, str)),
vol.Optional("show_advanced_options", default=False): cv.boolean,
},
extra=vol.ALLOW_EXTRA,
)
)
async def post(self, request: web.Request, data: dict[str, Any]) -> web.Response:
"""Handle a POST request.
handler in request is [entry_id, subentry_type].
"""
return await super()._post_impl(request, data)
def get_context(self, data: dict[str, Any]) -> dict[str, Any]:
"""Return context."""
context = super().get_context(data)
context["source"] = config_entries.SOURCE_USER
if subentry_id := data.get("subentry_id"):
context["source"] = config_entries.SOURCE_RECONFIGURE
context["subentry_id"] = subentry_id
return context
class SubentryManagerFlowResourceView(
FlowManagerResourceView[config_entries.ConfigSubentryFlowManager]
):
"""View to interact with the subentry flow manager."""
url = "/api/config/config_entries/subentries/flow/{flow_id}"
name = "api:config:config_entries:subentries:flow:resource"
@require_admin(
error=Unauthorized(perm_category=CAT_CONFIG_ENTRIES, permission=POLICY_EDIT)
)
async def get(self, request: web.Request, /, flow_id: str) -> web.Response:
"""Get the current state of a data_entry_flow."""
return await super().get(request, flow_id)
@require_admin(
error=Unauthorized(perm_category=CAT_CONFIG_ENTRIES, permission=POLICY_EDIT)
)
async def post(self, request: web.Request, flow_id: str) -> web.Response:
"""Handle a POST request."""
return await super().post(request, flow_id)
@websocket_api.require_admin @websocket_api.require_admin
@websocket_api.websocket_command({"type": "config_entries/flow/progress"}) @websocket_api.websocket_command({"type": "config_entries/flow/progress"})
def config_entries_progress( def config_entries_progress(
@ -589,3 +659,63 @@ async def _async_matching_config_entries_json_fragments(
) )
or (filter_is_not_helper and entry.domain not in integrations) or (filter_is_not_helper and entry.domain not in integrations)
] ]
@websocket_api.require_admin
@websocket_api.websocket_command(
{
"type": "config_entries/subentries/list",
"entry_id": str,
}
)
@websocket_api.async_response
async def config_subentry_list(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""List subentries of a config entry."""
entry = get_entry(hass, connection, msg["entry_id"], msg["id"])
if entry is None:
return
result = [
{
"subentry_id": subentry.subentry_id,
"subentry_type": subentry.subentry_type,
"title": subentry.title,
"unique_id": subentry.unique_id,
}
for subentry in entry.subentries.values()
]
connection.send_result(msg["id"], result)
@websocket_api.require_admin
@websocket_api.websocket_command(
{
"type": "config_entries/subentries/delete",
"entry_id": str,
"subentry_id": str,
}
)
@websocket_api.async_response
async def config_subentry_delete(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Delete a subentry of a config entry."""
entry = get_entry(hass, connection, msg["entry_id"], msg["id"])
if entry is None:
return
try:
hass.config_entries.async_remove_subentry(entry, msg["subentry_id"])
except config_entries.UnknownSubEntry:
connection.send_error(
msg["id"], websocket_api.const.ERR_NOT_FOUND, "Config subentry not found"
)
return
connection.send_result(msg["id"])

View File

@ -70,11 +70,11 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
return True return True
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set the config entry up.""" """Set the config entry up."""
# Set up demo platforms with config entry # Set up demo platforms with config entry
await hass.config_entries.async_forward_entry_setups( await hass.config_entries.async_forward_entry_setups(
config_entry, COMPONENTS_WITH_DEMO_PLATFORM entry, COMPONENTS_WITH_DEMO_PLATFORM
) )
# Create issues # Create issues
@ -85,7 +85,9 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
await _insert_statistics(hass) await _insert_statistics(hass)
# Start a reauth flow # Start a reauth flow
config_entry.async_start_reauth(hass) entry.async_start_reauth(hass)
entry.async_on_unload(entry.add_update_listener(_async_update_listener))
# Notify backup listeners # Notify backup listeners
hass.async_create_task(_notify_backup_listeners(hass), eager_start=False) hass.async_create_task(_notify_backup_listeners(hass), eager_start=False)
@ -93,6 +95,11 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
return True return True
async def _async_update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Handle update."""
await hass.config_entries.async_reload(entry.entry_id)
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload config entry.""" """Unload config entry."""
# Notify backup listeners # Notify backup listeners

View File

@ -12,7 +12,9 @@ from homeassistant.config_entries import (
ConfigEntry, ConfigEntry,
ConfigFlow, ConfigFlow,
ConfigFlowResult, ConfigFlowResult,
ConfigSubentryFlow,
OptionsFlow, OptionsFlow,
SubentryFlowResult,
) )
from homeassistant.core import callback from homeassistant.core import callback
@ -35,6 +37,14 @@ class KitchenSinkConfigFlow(ConfigFlow, domain=DOMAIN):
"""Get the options flow for this handler.""" """Get the options flow for this handler."""
return OptionsFlowHandler() return OptionsFlowHandler()
@classmethod
@callback
def async_get_supported_subentry_types(
cls, config_entry: ConfigEntry
) -> dict[str, type[ConfigSubentryFlow]]:
"""Return subentries supported by this handler."""
return {"entity": SubentryFlowHandler}
async def async_step_import(self, import_data: dict[str, Any]) -> ConfigFlowResult: async def async_step_import(self, import_data: dict[str, Any]) -> ConfigFlowResult:
"""Set the config entry up from yaml.""" """Set the config entry up from yaml."""
return self.async_create_entry(title="Kitchen Sink", data=import_data) return self.async_create_entry(title="Kitchen Sink", data=import_data)
@ -94,3 +104,60 @@ class OptionsFlowHandler(OptionsFlow):
} }
), ),
) )
class SubentryFlowHandler(ConfigSubentryFlow):
"""Handle subentry flow."""
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> SubentryFlowResult:
"""User flow to create a sensor subentry."""
return await self.async_step_add_sensor()
async def async_step_add_sensor(
self, user_input: dict[str, Any] | None = None
) -> SubentryFlowResult:
"""Add a new sensor."""
if user_input is not None:
title = user_input.pop("name")
return self.async_create_entry(data=user_input, title=title)
return self.async_show_form(
step_id="add_sensor",
data_schema=vol.Schema(
{
vol.Required("name"): str,
vol.Required("state"): int,
}
),
)
async def async_step_reconfigure(
self, user_input: dict[str, Any] | None = None
) -> SubentryFlowResult:
"""Reconfigure a sensor subentry."""
return await self.async_step_reconfigure_sensor()
async def async_step_reconfigure_sensor(
self, user_input: dict[str, Any] | None = None
) -> SubentryFlowResult:
"""Reconfigure a sensor."""
if user_input is not None:
title = user_input.pop("name")
return self.async_update_and_abort(
self._get_reconfigure_entry(),
self._get_reconfigure_subentry(),
data=user_input,
title=title,
)
return self.async_show_form(
step_id="reconfigure_sensor",
data_schema=vol.Schema(
{
vol.Required("name"): str,
vol.Required("state"): int,
}
),
)

View File

@ -11,7 +11,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import UnitOfPower from homeassistant.const import UnitOfPower
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.typing import UNDEFINED, StateType, UndefinedType from homeassistant.helpers.typing import UNDEFINED, StateType, UndefinedType
from . import DOMAIN from . import DOMAIN
@ -21,7 +21,8 @@ from .device import async_create_device
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: ConfigEntry, config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback, # pylint: disable-next=hass-argument-type
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None: ) -> None:
"""Set up the Everything but the Kitchen Sink config entry.""" """Set up the Everything but the Kitchen Sink config entry."""
async_create_device( async_create_device(
@ -90,6 +91,23 @@ async def async_setup_entry(
] ]
) )
for subentry_id, subentry in config_entry.subentries.items():
async_add_entities(
[
DemoSensor(
device_unique_id=subentry_id,
unique_id=subentry_id,
device_name=subentry.title,
entity_name=None,
state=subentry.data["state"],
device_class=None,
state_class=None,
unit_of_measurement=None,
)
],
config_subentry_id=subentry_id,
)
class DemoSensor(SensorEntity): class DemoSensor(SensorEntity):
"""Representation of a Demo sensor.""" """Representation of a Demo sensor."""

View File

@ -9,6 +9,27 @@
} }
} }
}, },
"config_subentries": {
"entity": {
"title": "Add entity",
"step": {
"add_sensor": {
"description": "Configure the new sensor",
"data": {
"name": "[%key:common::config_flow::data::name%]",
"state": "Initial state"
}
},
"reconfigure_sensor": {
"description": "Reconfigure the sensor",
"data": {
"name": "[%key:component::kitchen_sink::config_subentries::entity::step::reconfigure_sensor::data::state%]",
"state": "Initial state"
}
}
}
}
},
"options": { "options": {
"step": { "step": {
"init": { "init": {

View File

@ -15,6 +15,7 @@ from collections.abc import (
) )
from contextvars import ContextVar from contextvars import ContextVar
from copy import deepcopy from copy import deepcopy
from dataclasses import dataclass, field
from datetime import datetime from datetime import datetime
from enum import Enum, StrEnum from enum import Enum, StrEnum
import functools import functools
@ -22,7 +23,7 @@ from functools import cache
import logging import logging
from random import randint from random import randint
from types import MappingProxyType from types import MappingProxyType
from typing import TYPE_CHECKING, Any, Self, cast from typing import TYPE_CHECKING, Any, Self, TypedDict, cast
from async_interrupt import interrupt from async_interrupt import interrupt
from propcache.api import cached_property from propcache.api import cached_property
@ -127,7 +128,7 @@ HANDLERS: Registry[str, type[ConfigFlow]] = Registry()
STORAGE_KEY = "core.config_entries" STORAGE_KEY = "core.config_entries"
STORAGE_VERSION = 1 STORAGE_VERSION = 1
STORAGE_VERSION_MINOR = 4 STORAGE_VERSION_MINOR = 5
SAVE_DELAY = 1 SAVE_DELAY = 1
@ -253,6 +254,10 @@ class UnknownEntry(ConfigError):
"""Unknown entry specified.""" """Unknown entry specified."""
class UnknownSubEntry(ConfigError):
"""Unknown subentry specified."""
class OperationNotAllowed(ConfigError): class OperationNotAllowed(ConfigError):
"""Raised when a config entry operation is not allowed.""" """Raised when a config entry operation is not allowed."""
@ -297,6 +302,7 @@ class ConfigFlowResult(FlowResult[ConfigFlowContext, str], total=False):
minor_version: int minor_version: int
options: Mapping[str, Any] options: Mapping[str, Any]
subentries: Iterable[ConfigSubentryData]
version: int version: int
@ -310,6 +316,61 @@ def _validate_item(*, disabled_by: ConfigEntryDisabler | Any | None = None) -> N
) )
class ConfigSubentryData(TypedDict):
"""Container for configuration subentry data.
Returned by integrations, a subentry_id will be assigned automatically.
"""
data: Mapping[str, Any]
subentry_type: str
title: str
unique_id: str | None
class ConfigSubentryDataWithId(ConfigSubentryData):
"""Container for configuration subentry data.
This type is used when loading existing subentries from storage.
"""
subentry_id: str
class SubentryFlowContext(FlowContext, total=False):
"""Typed context dict for subentry flow."""
entry_id: str
subentry_id: str
class SubentryFlowResult(FlowResult[SubentryFlowContext, tuple[str, str]], total=False):
"""Typed result dict for subentry flow."""
unique_id: str | None
@dataclass(frozen=True, kw_only=True)
class ConfigSubentry:
"""Container for a configuration subentry."""
data: MappingProxyType[str, Any]
subentry_id: str = field(default_factory=ulid_util.ulid_now)
subentry_type: str
title: str
unique_id: str | None
def as_dict(self) -> ConfigSubentryDataWithId:
"""Return dictionary version of this subentry."""
return {
"data": dict(self.data),
"subentry_id": self.subentry_id,
"subentry_type": self.subentry_type,
"title": self.title,
"unique_id": self.unique_id,
}
class ConfigEntry[_DataT = Any]: class ConfigEntry[_DataT = Any]:
"""Hold a configuration entry.""" """Hold a configuration entry."""
@ -319,6 +380,7 @@ class ConfigEntry[_DataT = Any]:
data: MappingProxyType[str, Any] data: MappingProxyType[str, Any]
runtime_data: _DataT runtime_data: _DataT
options: MappingProxyType[str, Any] options: MappingProxyType[str, Any]
subentries: MappingProxyType[str, ConfigSubentry]
unique_id: str | None unique_id: str | None
state: ConfigEntryState state: ConfigEntryState
reason: str | None reason: str | None
@ -334,6 +396,7 @@ class ConfigEntry[_DataT = Any]:
supports_remove_device: bool | None supports_remove_device: bool | None
_supports_options: bool | None _supports_options: bool | None
_supports_reconfigure: bool | None _supports_reconfigure: bool | None
_supported_subentry_types: dict[str, dict[str, bool]] | None
update_listeners: list[UpdateListenerType] update_listeners: list[UpdateListenerType]
_async_cancel_retry_setup: Callable[[], Any] | None _async_cancel_retry_setup: Callable[[], Any] | None
_on_unload: list[Callable[[], Coroutine[Any, Any, None] | None]] | None _on_unload: list[Callable[[], Coroutine[Any, Any, None] | None]] | None
@ -363,6 +426,7 @@ class ConfigEntry[_DataT = Any]:
pref_disable_polling: bool | None = None, pref_disable_polling: bool | None = None,
source: str, source: str,
state: ConfigEntryState = ConfigEntryState.NOT_LOADED, state: ConfigEntryState = ConfigEntryState.NOT_LOADED,
subentries_data: Iterable[ConfigSubentryData | ConfigSubentryDataWithId] | None,
title: str, title: str,
unique_id: str | None, unique_id: str | None,
version: int, version: int,
@ -388,6 +452,25 @@ class ConfigEntry[_DataT = Any]:
# Entry options # Entry options
_setter(self, "options", MappingProxyType(options or {})) _setter(self, "options", MappingProxyType(options or {}))
# Subentries
subentries_data = subentries_data or ()
subentries = {}
for subentry_data in subentries_data:
subentry_kwargs = {}
if "subentry_id" in subentry_data:
# If subentry_data has key "subentry_id", we're loading from storage
subentry_kwargs["subentry_id"] = subentry_data["subentry_id"] # type: ignore[typeddict-item]
subentry = ConfigSubentry(
data=MappingProxyType(subentry_data["data"]),
subentry_type=subentry_data["subentry_type"],
title=subentry_data["title"],
unique_id=subentry_data.get("unique_id"),
**subentry_kwargs,
)
subentries[subentry.subentry_id] = subentry
_setter(self, "subentries", MappingProxyType(subentries))
# Entry system options # Entry system options
if pref_disable_new_entities is None: if pref_disable_new_entities is None:
pref_disable_new_entities = False pref_disable_new_entities = False
@ -424,6 +507,9 @@ class ConfigEntry[_DataT = Any]:
# Supports reconfigure # Supports reconfigure
_setter(self, "_supports_reconfigure", None) _setter(self, "_supports_reconfigure", None)
# Supports subentries
_setter(self, "_supported_subentry_types", None)
# Listeners to call on update # Listeners to call on update
_setter(self, "update_listeners", []) _setter(self, "update_listeners", [])
@ -496,6 +582,28 @@ class ConfigEntry[_DataT = Any]:
) )
return self._supports_reconfigure or False return self._supports_reconfigure or False
@property
def supported_subentry_types(self) -> dict[str, dict[str, bool]]:
"""Return supported subentry types."""
if self._supported_subentry_types is None and (
handler := HANDLERS.get(self.domain)
):
# work out sub entries supported by the handler
supported_flows = handler.async_get_supported_subentry_types(self)
object.__setattr__(
self,
"_supported_subentry_types",
{
subentry_flow_type: {
"supports_reconfigure": hasattr(
subentry_flow_handler, "async_step_reconfigure"
)
}
for subentry_flow_type, subentry_flow_handler in supported_flows.items()
},
)
return self._supported_subentry_types or {}
def clear_state_cache(self) -> None: def clear_state_cache(self) -> None:
"""Clear cached properties that are included in as_json_fragment.""" """Clear cached properties that are included in as_json_fragment."""
self.__dict__.pop("as_json_fragment", None) self.__dict__.pop("as_json_fragment", None)
@ -515,12 +623,14 @@ class ConfigEntry[_DataT = Any]:
"supports_remove_device": self.supports_remove_device or False, "supports_remove_device": self.supports_remove_device or False,
"supports_unload": self.supports_unload or False, "supports_unload": self.supports_unload or False,
"supports_reconfigure": self.supports_reconfigure, "supports_reconfigure": self.supports_reconfigure,
"supported_subentry_types": self.supported_subentry_types,
"pref_disable_new_entities": self.pref_disable_new_entities, "pref_disable_new_entities": self.pref_disable_new_entities,
"pref_disable_polling": self.pref_disable_polling, "pref_disable_polling": self.pref_disable_polling,
"disabled_by": self.disabled_by, "disabled_by": self.disabled_by,
"reason": self.reason, "reason": self.reason,
"error_reason_translation_key": self.error_reason_translation_key, "error_reason_translation_key": self.error_reason_translation_key,
"error_reason_translation_placeholders": self.error_reason_translation_placeholders, "error_reason_translation_placeholders": self.error_reason_translation_placeholders,
"num_subentries": len(self.subentries),
} }
return json_fragment(json_bytes(json_repr)) return json_fragment(json_bytes(json_repr))
@ -1012,6 +1122,7 @@ class ConfigEntry[_DataT = Any]:
"pref_disable_new_entities": self.pref_disable_new_entities, "pref_disable_new_entities": self.pref_disable_new_entities,
"pref_disable_polling": self.pref_disable_polling, "pref_disable_polling": self.pref_disable_polling,
"source": self.source, "source": self.source,
"subentries": [subentry.as_dict() for subentry in self.subentries.values()],
"title": self.title, "title": self.title,
"unique_id": self.unique_id, "unique_id": self.unique_id,
"version": self.version, "version": self.version,
@ -1497,6 +1608,7 @@ class ConfigEntriesFlowManager(
minor_version=result["minor_version"], minor_version=result["minor_version"],
options=result["options"], options=result["options"],
source=flow.context["source"], source=flow.context["source"],
subentries_data=result["subentries"],
title=result["title"], title=result["title"],
unique_id=flow.unique_id, unique_id=flow.unique_id,
version=result["version"], version=result["version"],
@ -1787,6 +1899,11 @@ class ConfigEntryStore(storage.Store[dict[str, list[dict[str, Any]]]]):
for entry in data["entries"]: for entry in data["entries"]:
entry["discovery_keys"] = {} entry["discovery_keys"] = {}
if old_minor_version < 5:
# Version 1.4 adds config subentries
for entry in data["entries"]:
entry.setdefault("subentries", entry.get("subentries", {}))
if old_major_version > 1: if old_major_version > 1:
raise NotImplementedError raise NotImplementedError
return data return data
@ -1803,6 +1920,7 @@ class ConfigEntries:
self.hass = hass self.hass = hass
self.flow = ConfigEntriesFlowManager(hass, self, hass_config) self.flow = ConfigEntriesFlowManager(hass, self, hass_config)
self.options = OptionsFlowManager(hass) self.options = OptionsFlowManager(hass)
self.subentries = ConfigSubentryFlowManager(hass)
self._hass_config = hass_config self._hass_config = hass_config
self._entries = ConfigEntryItems(hass) self._entries = ConfigEntryItems(hass)
self._store = ConfigEntryStore(hass) self._store = ConfigEntryStore(hass)
@ -2005,6 +2123,7 @@ class ConfigEntries:
pref_disable_new_entities=entry["pref_disable_new_entities"], pref_disable_new_entities=entry["pref_disable_new_entities"],
pref_disable_polling=entry["pref_disable_polling"], pref_disable_polling=entry["pref_disable_polling"],
source=entry["source"], source=entry["source"],
subentries_data=entry["subentries"],
title=entry["title"], title=entry["title"],
unique_id=entry["unique_id"], unique_id=entry["unique_id"],
version=entry["version"], version=entry["version"],
@ -2164,6 +2283,44 @@ class ConfigEntries:
If the entry was changed, the update_listeners are If the entry was changed, the update_listeners are
fired and this function returns True fired and this function returns True
If the entry was not changed, the update_listeners are
not fired and this function returns False
"""
return self._async_update_entry(
entry,
data=data,
discovery_keys=discovery_keys,
minor_version=minor_version,
options=options,
pref_disable_new_entities=pref_disable_new_entities,
pref_disable_polling=pref_disable_polling,
title=title,
unique_id=unique_id,
version=version,
)
@callback
def _async_update_entry(
self,
entry: ConfigEntry,
*,
data: Mapping[str, Any] | UndefinedType = UNDEFINED,
discovery_keys: MappingProxyType[str, tuple[DiscoveryKey, ...]]
| UndefinedType = UNDEFINED,
minor_version: int | UndefinedType = UNDEFINED,
options: Mapping[str, Any] | UndefinedType = UNDEFINED,
pref_disable_new_entities: bool | UndefinedType = UNDEFINED,
pref_disable_polling: bool | UndefinedType = UNDEFINED,
subentries: dict[str, ConfigSubentry] | UndefinedType = UNDEFINED,
title: str | UndefinedType = UNDEFINED,
unique_id: str | None | UndefinedType = UNDEFINED,
version: int | UndefinedType = UNDEFINED,
) -> bool:
"""Update a config entry.
If the entry was changed, the update_listeners are
fired and this function returns True
If the entry was not changed, the update_listeners are If the entry was not changed, the update_listeners are
not fired and this function returns False not fired and this function returns False
""" """
@ -2226,11 +2383,21 @@ class ConfigEntries:
changed = True changed = True
_setter(entry, "options", MappingProxyType(options)) _setter(entry, "options", MappingProxyType(options))
if subentries is not UNDEFINED:
if entry.subentries != subentries:
changed = True
_setter(entry, "subentries", MappingProxyType(subentries))
if not changed: if not changed:
return False return False
_setter(entry, "modified_at", utcnow()) _setter(entry, "modified_at", utcnow())
self._async_save_and_notify(entry)
return True
@callback
def _async_save_and_notify(self, entry: ConfigEntry) -> None:
for listener in entry.update_listeners: for listener in entry.update_listeners:
self.hass.async_create_task( self.hass.async_create_task(
listener(self.hass, entry), listener(self.hass, entry),
@ -2241,8 +2408,92 @@ class ConfigEntries:
entry.clear_state_cache() entry.clear_state_cache()
entry.clear_storage_cache() entry.clear_storage_cache()
self._async_dispatch(ConfigEntryChange.UPDATED, entry) self._async_dispatch(ConfigEntryChange.UPDATED, entry)
@callback
def async_add_subentry(self, entry: ConfigEntry, subentry: ConfigSubentry) -> bool:
"""Add a subentry to a config entry."""
self._raise_if_subentry_unique_id_exists(entry, subentry.unique_id)
return self._async_update_entry(
entry,
subentries=entry.subentries | {subentry.subentry_id: subentry},
)
@callback
def async_remove_subentry(self, entry: ConfigEntry, subentry_id: str) -> bool:
"""Remove a subentry from a config entry."""
subentries = dict(entry.subentries)
try:
subentries.pop(subentry_id)
except KeyError as err:
raise UnknownSubEntry from err
result = self._async_update_entry(entry, subentries=subentries)
dev_reg = dr.async_get(self.hass)
ent_reg = er.async_get(self.hass)
dev_reg.async_clear_config_subentry(entry.entry_id, subentry_id)
ent_reg.async_clear_config_subentry(entry.entry_id, subentry_id)
return result
@callback
def async_update_subentry(
self,
entry: ConfigEntry,
subentry: ConfigSubentry,
*,
data: Mapping[str, Any] | UndefinedType = UNDEFINED,
title: str | UndefinedType = UNDEFINED,
unique_id: str | None | UndefinedType = UNDEFINED,
) -> bool:
"""Update a config subentry.
If the subentry was changed, the update_listeners are
fired and this function returns True
If the subentry was not changed, the update_listeners are
not fired and this function returns False
"""
if entry.entry_id not in self._entries:
raise UnknownEntry(entry.entry_id)
if subentry.subentry_id not in entry.subentries:
raise UnknownSubEntry(subentry.subentry_id)
self.hass.verify_event_loop_thread("hass.config_entries.async_update_subentry")
changed = False
_setter = object.__setattr__
if unique_id is not UNDEFINED and subentry.unique_id != unique_id:
self._raise_if_subentry_unique_id_exists(entry, unique_id)
changed = True
_setter(subentry, "unique_id", unique_id)
if title is not UNDEFINED and subentry.title != title:
changed = True
_setter(subentry, "title", title)
if data is not UNDEFINED and subentry.data != data:
changed = True
_setter(subentry, "data", MappingProxyType(data))
if not changed:
return False
_setter(entry, "modified_at", utcnow())
self._async_save_and_notify(entry)
return True return True
def _raise_if_subentry_unique_id_exists(
self, entry: ConfigEntry, unique_id: str | None
) -> None:
"""Raise if a subentry with the same unique_id exists."""
if unique_id is None:
return
for existing_subentry in entry.subentries.values():
if existing_subentry.unique_id == unique_id:
raise data_entry_flow.AbortFlow("already_configured")
@callback @callback
def _async_dispatch( def _async_dispatch(
self, change_type: ConfigEntryChange, entry: ConfigEntry self, change_type: ConfigEntryChange, entry: ConfigEntry
@ -2579,6 +2830,14 @@ class ConfigFlow(ConfigEntryBaseFlow):
"""Return options flow support for this handler.""" """Return options flow support for this handler."""
return cls.async_get_options_flow is not ConfigFlow.async_get_options_flow return cls.async_get_options_flow is not ConfigFlow.async_get_options_flow
@classmethod
@callback
def async_get_supported_subentry_types(
cls, config_entry: ConfigEntry
) -> dict[str, type[ConfigSubentryFlow]]:
"""Return subentries supported by this handler."""
return {}
@callback @callback
def _async_abort_entries_match( def _async_abort_entries_match(
self, match_dict: dict[str, Any] | None = None self, match_dict: dict[str, Any] | None = None
@ -2887,6 +3146,7 @@ class ConfigFlow(ConfigEntryBaseFlow):
description: str | None = None, description: str | None = None,
description_placeholders: Mapping[str, str] | None = None, description_placeholders: Mapping[str, str] | None = None,
options: Mapping[str, Any] | None = None, options: Mapping[str, Any] | None = None,
subentries: Iterable[ConfigSubentryData] | None = None,
) -> ConfigFlowResult: ) -> ConfigFlowResult:
"""Finish config flow and create a config entry.""" """Finish config flow and create a config entry."""
if self.source in {SOURCE_REAUTH, SOURCE_RECONFIGURE}: if self.source in {SOURCE_REAUTH, SOURCE_RECONFIGURE}:
@ -2906,6 +3166,7 @@ class ConfigFlow(ConfigEntryBaseFlow):
result["minor_version"] = self.MINOR_VERSION result["minor_version"] = self.MINOR_VERSION
result["options"] = options or {} result["options"] = options or {}
result["subentries"] = subentries or ()
result["version"] = self.VERSION result["version"] = self.VERSION
return result return result
@ -3020,17 +3281,199 @@ class ConfigFlow(ConfigEntryBaseFlow):
) )
class OptionsFlowManager( class _ConfigSubFlowManager:
data_entry_flow.FlowManager[ConfigFlowContext, ConfigFlowResult] """Mixin class for flow managers which manage flows tied to a config entry."""
):
"""Flow to set options for a configuration entry."""
_flow_result = ConfigFlowResult hass: HomeAssistant
def _async_get_config_entry(self, config_entry_id: str) -> ConfigEntry: def _async_get_config_entry(self, config_entry_id: str) -> ConfigEntry:
"""Return config entry or raise if not found.""" """Return config entry or raise if not found."""
return self.hass.config_entries.async_get_known_entry(config_entry_id) return self.hass.config_entries.async_get_known_entry(config_entry_id)
class ConfigSubentryFlowManager(
data_entry_flow.FlowManager[
SubentryFlowContext, SubentryFlowResult, tuple[str, str]
],
_ConfigSubFlowManager,
):
"""Manage all the config subentry flows that are in progress."""
_flow_result = SubentryFlowResult
async def async_create_flow(
self,
handler_key: tuple[str, str],
*,
context: FlowContext | None = None,
data: dict[str, Any] | None = None,
) -> ConfigSubentryFlow:
"""Create a subentry flow for a config entry.
The entry_id and flow.handler[0] is the same thing to map entry with flow.
"""
if not context or "source" not in context:
raise KeyError("Context not set or doesn't have a source set")
entry_id, subentry_type = handler_key
entry = self._async_get_config_entry(entry_id)
handler = await _async_get_flow_handler(self.hass, entry.domain, {})
subentry_types = handler.async_get_supported_subentry_types(entry)
if subentry_type not in subentry_types:
raise data_entry_flow.UnknownHandler(
f"Config entry '{entry.domain}' does not support subentry '{subentry_type}'"
)
subentry_flow = subentry_types[subentry_type]()
subentry_flow.init_step = context["source"]
return subentry_flow
async def async_finish_flow(
self,
flow: data_entry_flow.FlowHandler[
SubentryFlowContext, SubentryFlowResult, tuple[str, str]
],
result: SubentryFlowResult,
) -> SubentryFlowResult:
"""Finish a subentry flow and add a new subentry to the configuration entry.
The flow.handler[0] and entry_id is the same thing to map flow with entry.
"""
flow = cast(ConfigSubentryFlow, flow)
if result["type"] != data_entry_flow.FlowResultType.CREATE_ENTRY:
return result
entry_id, subentry_type = flow.handler
entry = self.hass.config_entries.async_get_entry(entry_id)
if entry is None:
raise UnknownEntry(entry_id)
unique_id = result.get("unique_id")
if unique_id is not None and not isinstance(unique_id, str):
raise HomeAssistantError("unique_id must be a string")
self.hass.config_entries.async_add_subentry(
entry,
ConfigSubentry(
data=MappingProxyType(result["data"]),
subentry_type=subentry_type,
title=result["title"],
unique_id=unique_id,
),
)
result["result"] = True
return result
class ConfigSubentryFlow(
data_entry_flow.FlowHandler[
SubentryFlowContext, SubentryFlowResult, tuple[str, str]
]
):
"""Base class for config subentry flows."""
_flow_result = SubentryFlowResult
handler: tuple[str, str]
@callback
def async_create_entry(
self,
*,
title: str | None = None,
data: Mapping[str, Any],
description: str | None = None,
description_placeholders: Mapping[str, str] | None = None,
unique_id: str | None = None,
) -> SubentryFlowResult:
"""Finish config flow and create a config entry."""
if self.source != SOURCE_USER:
raise ValueError(f"Source is {self.source}, expected {SOURCE_USER}")
result = super().async_create_entry(
title=title,
data=data,
description=description,
description_placeholders=description_placeholders,
)
result["unique_id"] = unique_id
return result
@callback
def async_update_and_abort(
self,
entry: ConfigEntry,
subentry: ConfigSubentry,
*,
unique_id: str | None | UndefinedType = UNDEFINED,
title: str | UndefinedType = UNDEFINED,
data: Mapping[str, Any] | UndefinedType = UNDEFINED,
data_updates: Mapping[str, Any] | UndefinedType = UNDEFINED,
) -> SubentryFlowResult:
"""Update config subentry and finish subentry flow.
:param data: replace the subentry data with new data
:param data_updates: add items from data_updates to subentry data - existing
keys are overridden
:param title: replace the title of the subentry
:param unique_id: replace the unique_id of the subentry
"""
if data_updates is not UNDEFINED:
if data is not UNDEFINED:
raise ValueError("Cannot set both data and data_updates")
data = entry.data | data_updates
self.hass.config_entries.async_update_subentry(
entry=entry,
subentry=subentry,
unique_id=unique_id,
title=title,
data=data,
)
return self.async_abort(reason="reconfigure_successful")
@property
def _reconfigure_entry_id(self) -> str:
"""Return reconfigure entry id."""
if self.source != SOURCE_RECONFIGURE:
raise ValueError(f"Source is {self.source}, expected {SOURCE_RECONFIGURE}")
return self.handler[0]
@callback
def _get_reconfigure_entry(self) -> ConfigEntry:
"""Return the reconfigure config entry linked to the current context."""
return self.hass.config_entries.async_get_known_entry(
self._reconfigure_entry_id
)
@property
def _reconfigure_subentry_id(self) -> str:
"""Return reconfigure subentry id."""
if self.source != SOURCE_RECONFIGURE:
raise ValueError(f"Source is {self.source}, expected {SOURCE_RECONFIGURE}")
return self.context["subentry_id"]
@callback
def _get_reconfigure_subentry(self) -> ConfigSubentry:
"""Return the reconfigure config subentry linked to the current context."""
entry = self.hass.config_entries.async_get_known_entry(
self._reconfigure_entry_id
)
subentry_id = self._reconfigure_subentry_id
if subentry_id not in entry.subentries:
raise UnknownEntry
return entry.subentries[subentry_id]
class OptionsFlowManager(
data_entry_flow.FlowManager[ConfigFlowContext, ConfigFlowResult],
_ConfigSubFlowManager,
):
"""Manage all the config entry option flows that are in progress."""
_flow_result = ConfigFlowResult
async def async_create_flow( async def async_create_flow(
self, self,
handler_key: str, handler_key: str,
@ -3040,7 +3483,7 @@ class OptionsFlowManager(
) -> OptionsFlow: ) -> OptionsFlow:
"""Create an options flow for a config entry. """Create an options flow for a config entry.
Entry_id and flow.handler is the same thing to map entry with flow. The entry_id and the flow.handler is the same thing to map entry with flow.
""" """
entry = self._async_get_config_entry(handler_key) entry = self._async_get_config_entry(handler_key)
handler = await _async_get_flow_handler(self.hass, entry.domain, {}) handler = await _async_get_flow_handler(self.hass, entry.domain, {})
@ -3056,7 +3499,7 @@ class OptionsFlowManager(
This method is called when a flow step returns FlowResultType.ABORT or This method is called when a flow step returns FlowResultType.ABORT or
FlowResultType.CREATE_ENTRY. FlowResultType.CREATE_ENTRY.
Flow.handler and entry_id is the same thing to map flow with entry. The flow.handler and the entry_id is the same thing to map flow with entry.
""" """
flow = cast(OptionsFlow, flow) flow = cast(OptionsFlow, flow)

View File

@ -17,7 +17,7 @@ from . import config_validation as cv
_FlowManagerT = TypeVar( _FlowManagerT = TypeVar(
"_FlowManagerT", "_FlowManagerT",
bound=data_entry_flow.FlowManager[Any, Any], bound=data_entry_flow.FlowManager[Any, Any, Any],
default=data_entry_flow.FlowManager, default=data_entry_flow.FlowManager,
) )
@ -70,7 +70,7 @@ class FlowManagerIndexView(_BaseFlowManagerView[_FlowManagerT]):
async def post(self, request: web.Request, data: dict[str, Any]) -> web.Response: async def post(self, request: web.Request, data: dict[str, Any]) -> web.Response:
"""Initialize a POST request. """Initialize a POST request.
Override `_post_impl` in subclasses which need Override `post` and call `_post_impl` in subclasses which need
to implement their own `RequestDataValidator` to implement their own `RequestDataValidator`
""" """
return await self._post_impl(request, data) return await self._post_impl(request, data)

View File

@ -56,7 +56,7 @@ EVENT_DEVICE_REGISTRY_UPDATED: EventType[EventDeviceRegistryUpdatedData] = Event
) )
STORAGE_KEY = "core.device_registry" STORAGE_KEY = "core.device_registry"
STORAGE_VERSION_MAJOR = 1 STORAGE_VERSION_MAJOR = 1
STORAGE_VERSION_MINOR = 8 STORAGE_VERSION_MINOR = 9
CLEANUP_DELAY = 10 CLEANUP_DELAY = 10
@ -272,6 +272,7 @@ class DeviceEntry:
area_id: str | None = attr.ib(default=None) area_id: str | None = attr.ib(default=None)
config_entries: set[str] = attr.ib(converter=set, factory=set) config_entries: set[str] = attr.ib(converter=set, factory=set)
config_entries_subentries: dict[str, set[str | None]] = attr.ib(factory=dict)
configuration_url: str | None = attr.ib(default=None) configuration_url: str | None = attr.ib(default=None)
connections: set[tuple[str, str]] = attr.ib(converter=set, factory=set) connections: set[tuple[str, str]] = attr.ib(converter=set, factory=set)
created_at: datetime = attr.ib(factory=utcnow) created_at: datetime = attr.ib(factory=utcnow)
@ -311,6 +312,10 @@ class DeviceEntry:
"area_id": self.area_id, "area_id": self.area_id,
"configuration_url": self.configuration_url, "configuration_url": self.configuration_url,
"config_entries": list(self.config_entries), "config_entries": list(self.config_entries),
"config_entries_subentries": {
config_entry_id: list(subentries)
for config_entry_id, subentries in self.config_entries_subentries.items()
},
"connections": list(self.connections), "connections": list(self.connections),
"created_at": self.created_at.timestamp(), "created_at": self.created_at.timestamp(),
"disabled_by": self.disabled_by, "disabled_by": self.disabled_by,
@ -354,7 +359,13 @@ class DeviceEntry:
json_bytes( json_bytes(
{ {
"area_id": self.area_id, "area_id": self.area_id,
# The config_entries list can be removed from the storage
# representation in HA Core 2026.2
"config_entries": list(self.config_entries), "config_entries": list(self.config_entries),
"config_entries_subentries": {
config_entry_id: list(subentries)
for config_entry_id, subentries in self.config_entries_subentries.items()
},
"configuration_url": self.configuration_url, "configuration_url": self.configuration_url,
"connections": list(self.connections), "connections": list(self.connections),
"created_at": self.created_at, "created_at": self.created_at,
@ -384,6 +395,7 @@ class DeletedDeviceEntry:
"""Deleted Device Registry Entry.""" """Deleted Device Registry Entry."""
config_entries: set[str] = attr.ib() config_entries: set[str] = attr.ib()
config_entries_subentries: dict[str, set[str | None]] = attr.ib()
connections: set[tuple[str, str]] = attr.ib() connections: set[tuple[str, str]] = attr.ib()
identifiers: set[tuple[str, str]] = attr.ib() identifiers: set[tuple[str, str]] = attr.ib()
id: str = attr.ib() id: str = attr.ib()
@ -395,6 +407,7 @@ class DeletedDeviceEntry:
def to_device_entry( def to_device_entry(
self, self,
config_entry_id: str, config_entry_id: str,
config_subentry_id: str | None,
connections: set[tuple[str, str]], connections: set[tuple[str, str]],
identifiers: set[tuple[str, str]], identifiers: set[tuple[str, str]],
) -> DeviceEntry: ) -> DeviceEntry:
@ -402,6 +415,7 @@ class DeletedDeviceEntry:
return DeviceEntry( return DeviceEntry(
# type ignores: likely https://github.com/python/mypy/issues/8625 # type ignores: likely https://github.com/python/mypy/issues/8625
config_entries={config_entry_id}, # type: ignore[arg-type] config_entries={config_entry_id}, # type: ignore[arg-type]
config_entries_subentries={config_entry_id: {config_subentry_id}},
connections=self.connections & connections, # type: ignore[arg-type] connections=self.connections & connections, # type: ignore[arg-type]
created_at=self.created_at, created_at=self.created_at,
identifiers=self.identifiers & identifiers, # type: ignore[arg-type] identifiers=self.identifiers & identifiers, # type: ignore[arg-type]
@ -415,7 +429,13 @@ class DeletedDeviceEntry:
return json_fragment( return json_fragment(
json_bytes( json_bytes(
{ {
# The config_entries list can be removed from the storage
# representation in HA Core 2026.2
"config_entries": list(self.config_entries), "config_entries": list(self.config_entries),
"config_entries_subentries": {
config_entry_id: list(subentries)
for config_entry_id, subentries in self.config_entries_subentries.items()
},
"connections": list(self.connections), "connections": list(self.connections),
"created_at": self.created_at, "created_at": self.created_at,
"identifiers": list(self.identifiers), "identifiers": list(self.identifiers),
@ -458,7 +478,10 @@ class DeviceRegistryStore(storage.Store[dict[str, list[dict[str, Any]]]]):
old_data: dict[str, list[dict[str, Any]]], old_data: dict[str, list[dict[str, Any]]],
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Migrate to the new version.""" """Migrate to the new version."""
if old_major_version < 2: # Support for a future major version bump to 2 added in HA Core 2025.2.
# Major versions 1 and 2 will be the same, except that version 2 will no
# longer store a list of config_entries.
if old_major_version < 3:
if old_minor_version < 2: if old_minor_version < 2:
# Version 1.2 implements migration and freezes the available keys, # Version 1.2 implements migration and freezes the available keys,
# populate keys which were introduced before version 1.2 # populate keys which were introduced before version 1.2
@ -505,8 +528,20 @@ class DeviceRegistryStore(storage.Store[dict[str, list[dict[str, Any]]]]):
device["created_at"] = device["modified_at"] = created_at device["created_at"] = device["modified_at"] = created_at
for device in old_data["deleted_devices"]: for device in old_data["deleted_devices"]:
device["created_at"] = device["modified_at"] = created_at device["created_at"] = device["modified_at"] = created_at
if old_minor_version < 9:
# Introduced in 2025.2
for device in old_data["devices"]:
device["config_entries_subentries"] = {
config_entry_id: {None}
for config_entry_id in device["config_entries"]
}
for device in old_data["deleted_devices"]:
device["config_entries_subentries"] = {
config_entry_id: {None}
for config_entry_id in device["config_entries"]
}
if old_major_version > 1: if old_major_version > 2:
raise NotImplementedError raise NotImplementedError
return old_data return old_data
@ -722,6 +757,7 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]):
self, self,
*, *,
config_entry_id: str, config_entry_id: str,
config_subentry_id: str | None | UndefinedType = UNDEFINED,
configuration_url: str | URL | None | UndefinedType = UNDEFINED, configuration_url: str | URL | None | UndefinedType = UNDEFINED,
connections: set[tuple[str, str]] | None | UndefinedType = UNDEFINED, connections: set[tuple[str, str]] | None | UndefinedType = UNDEFINED,
created_at: str | datetime | UndefinedType = UNDEFINED, # will be ignored created_at: str | datetime | UndefinedType = UNDEFINED, # will be ignored
@ -812,7 +848,11 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]):
else: else:
self.deleted_devices.pop(deleted_device.id) self.deleted_devices.pop(deleted_device.id)
device = deleted_device.to_device_entry( device = deleted_device.to_device_entry(
config_entry_id, connections, identifiers config_entry_id,
# Interpret not specifying a subentry as None
config_subentry_id if config_subentry_id is not UNDEFINED else None,
connections,
identifiers,
) )
self.devices[device.id] = device self.devices[device.id] = device
# If creating a new device, default to the config entry name # If creating a new device, default to the config entry name
@ -846,6 +886,7 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]):
device.id, device.id,
allow_collisions=True, allow_collisions=True,
add_config_entry_id=config_entry_id, add_config_entry_id=config_entry_id,
add_config_subentry_id=config_subentry_id,
configuration_url=configuration_url, configuration_url=configuration_url,
device_info_type=device_info_type, device_info_type=device_info_type,
disabled_by=disabled_by, disabled_by=disabled_by,
@ -874,6 +915,7 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]):
device_id: str, device_id: str,
*, *,
add_config_entry_id: str | UndefinedType = UNDEFINED, add_config_entry_id: str | UndefinedType = UNDEFINED,
add_config_subentry_id: str | None | UndefinedType = UNDEFINED,
# Temporary flag so we don't blow up when collisions are implicitly introduced # Temporary flag so we don't blow up when collisions are implicitly introduced
# by calls to async_get_or_create. Must not be set by integrations. # by calls to async_get_or_create. Must not be set by integrations.
allow_collisions: bool = False, allow_collisions: bool = False,
@ -894,25 +936,58 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]):
new_connections: set[tuple[str, str]] | UndefinedType = UNDEFINED, new_connections: set[tuple[str, str]] | UndefinedType = UNDEFINED,
new_identifiers: set[tuple[str, str]] | UndefinedType = UNDEFINED, new_identifiers: set[tuple[str, str]] | UndefinedType = UNDEFINED,
remove_config_entry_id: str | UndefinedType = UNDEFINED, remove_config_entry_id: str | UndefinedType = UNDEFINED,
remove_config_subentry_id: str | None | UndefinedType = UNDEFINED,
serial_number: str | None | UndefinedType = UNDEFINED, serial_number: str | None | UndefinedType = UNDEFINED,
suggested_area: str | None | UndefinedType = UNDEFINED, suggested_area: str | None | UndefinedType = UNDEFINED,
sw_version: str | None | UndefinedType = UNDEFINED, sw_version: str | None | UndefinedType = UNDEFINED,
via_device_id: str | None | UndefinedType = UNDEFINED, via_device_id: str | None | UndefinedType = UNDEFINED,
) -> DeviceEntry | None: ) -> DeviceEntry | None:
"""Update device attributes.""" """Update device attributes.
:param add_config_subentry_id: Add the device to a specific subentry of add_config_entry_id
:param remove_config_subentry_id: Remove the device from a specific subentry of remove_config_subentry_id
"""
old = self.devices[device_id] old = self.devices[device_id]
new_values: dict[str, Any] = {} # Dict with new key/value pairs new_values: dict[str, Any] = {} # Dict with new key/value pairs
old_values: dict[str, Any] = {} # Dict with old key/value pairs old_values: dict[str, Any] = {} # Dict with old key/value pairs
config_entries = old.config_entries config_entries = old.config_entries
config_entries_subentries = old.config_entries_subentries
if add_config_entry_id is not UNDEFINED: if add_config_entry_id is not UNDEFINED:
if self.hass.config_entries.async_get_entry(add_config_entry_id) is None: if (
add_config_entry := self.hass.config_entries.async_get_entry(
add_config_entry_id
)
) is None:
raise HomeAssistantError( raise HomeAssistantError(
f"Can't link device to unknown config entry {add_config_entry_id}" f"Can't link device to unknown config entry {add_config_entry_id}"
) )
if add_config_subentry_id is not UNDEFINED:
if add_config_entry_id is UNDEFINED:
raise HomeAssistantError(
"Can't add config subentry without specifying config entry"
)
if (
add_config_subentry_id
# mypy says add_config_entry can be None. That's impossible, because we
# raise above if that happens
and add_config_subentry_id not in add_config_entry.subentries # type: ignore[union-attr]
):
raise HomeAssistantError(
f"Config entry {add_config_entry_id} has no subentry {add_config_subentry_id}"
)
if (
remove_config_subentry_id is not UNDEFINED
and remove_config_entry_id is UNDEFINED
):
raise HomeAssistantError(
"Can't remove config subentry without specifying config entry"
)
if not new_connections and not new_identifiers: if not new_connections and not new_identifiers:
raise HomeAssistantError( raise HomeAssistantError(
"A device must have at least one of identifiers or connections" "A device must have at least one of identifiers or connections"
@ -943,6 +1018,10 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]):
area_id = area.id area_id = area.id
if add_config_entry_id is not UNDEFINED: if add_config_entry_id is not UNDEFINED:
if add_config_subentry_id is UNDEFINED:
# Interpret not specifying a subentry as None (the main entry)
add_config_subentry_id = None
primary_entry_id = old.primary_config_entry primary_entry_id = old.primary_config_entry
if ( if (
device_info_type == "primary" device_info_type == "primary"
@ -962,11 +1041,41 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]):
if add_config_entry_id not in old.config_entries: if add_config_entry_id not in old.config_entries:
config_entries = old.config_entries | {add_config_entry_id} config_entries = old.config_entries | {add_config_entry_id}
config_entries_subentries = old.config_entries_subentries | {
add_config_entry_id: {add_config_subentry_id}
}
elif (
add_config_subentry_id
not in old.config_entries_subentries[add_config_entry_id]
):
config_entries_subentries = old.config_entries_subentries | {
add_config_entry_id: old.config_entries_subentries[
add_config_entry_id
]
| {add_config_subentry_id}
}
if ( if (
remove_config_entry_id is not UNDEFINED remove_config_entry_id is not UNDEFINED
and remove_config_entry_id in config_entries and remove_config_entry_id in config_entries
): ):
if remove_config_subentry_id is UNDEFINED:
config_entries_subentries = dict(old.config_entries_subentries)
del config_entries_subentries[remove_config_entry_id]
elif (
remove_config_subentry_id
in old.config_entries_subentries[remove_config_entry_id]
):
config_entries_subentries = old.config_entries_subentries | {
remove_config_entry_id: old.config_entries_subentries[
remove_config_entry_id
]
- {remove_config_subentry_id}
}
if not config_entries_subentries[remove_config_entry_id]:
del config_entries_subentries[remove_config_entry_id]
if remove_config_entry_id not in config_entries_subentries:
if config_entries == {remove_config_entry_id}: if config_entries == {remove_config_entry_id}:
self.async_remove_device(device_id) self.async_remove_device(device_id)
return None return None
@ -981,6 +1090,10 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]):
new_values["config_entries"] = config_entries new_values["config_entries"] = config_entries
old_values["config_entries"] = old.config_entries old_values["config_entries"] = old.config_entries
if config_entries_subentries != old.config_entries_subentries:
new_values["config_entries_subentries"] = config_entries_subentries
old_values["config_entries_subentries"] = old.config_entries_subentries
added_connections: set[tuple[str, str]] | None = None added_connections: set[tuple[str, str]] | None = None
added_identifiers: set[tuple[str, str]] | None = None added_identifiers: set[tuple[str, str]] | None = None
@ -1138,6 +1251,7 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]):
device = self.devices.pop(device_id) device = self.devices.pop(device_id)
self.deleted_devices[device_id] = DeletedDeviceEntry( self.deleted_devices[device_id] = DeletedDeviceEntry(
config_entries=device.config_entries, config_entries=device.config_entries,
config_entries_subentries=device.config_entries_subentries,
connections=device.connections, connections=device.connections,
created_at=device.created_at, created_at=device.created_at,
identifiers=device.identifiers, identifiers=device.identifiers,
@ -1168,7 +1282,13 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]):
for device in data["devices"]: for device in data["devices"]:
devices[device["id"]] = DeviceEntry( devices[device["id"]] = DeviceEntry(
area_id=device["area_id"], area_id=device["area_id"],
config_entries=set(device["config_entries"]), config_entries=set(device["config_entries_subentries"]),
config_entries_subentries={
config_entry_id: set(subentries)
for config_entry_id, subentries in device[
"config_entries_subentries"
].items()
},
configuration_url=device["configuration_url"], configuration_url=device["configuration_url"],
# type ignores (if tuple arg was cast): likely https://github.com/python/mypy/issues/8625 # type ignores (if tuple arg was cast): likely https://github.com/python/mypy/issues/8625
connections={ connections={
@ -1208,6 +1328,12 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]):
for device in data["deleted_devices"]: for device in data["deleted_devices"]:
deleted_devices[device["id"]] = DeletedDeviceEntry( deleted_devices[device["id"]] = DeletedDeviceEntry(
config_entries=set(device["config_entries"]), config_entries=set(device["config_entries"]),
config_entries_subentries={
config_entry_id: set(subentries)
for config_entry_id, subentries in device[
"config_entries_subentries"
].items()
},
connections={tuple(conn) for conn in device["connections"]}, connections={tuple(conn) for conn in device["connections"]},
created_at=datetime.fromisoformat(device["created_at"]), created_at=datetime.fromisoformat(device["created_at"]),
identifiers={tuple(iden) for iden in device["identifiers"]}, identifiers={tuple(iden) for iden in device["identifiers"]},
@ -1243,14 +1369,70 @@ class DeviceRegistry(BaseRegistry[dict[str, list[dict[str, Any]]]]):
if config_entries == {config_entry_id}: if config_entries == {config_entry_id}:
# Add a time stamp when the deleted device became orphaned # Add a time stamp when the deleted device became orphaned
self.deleted_devices[deleted_device.id] = attr.evolve( self.deleted_devices[deleted_device.id] = attr.evolve(
deleted_device, orphaned_timestamp=now_time, config_entries=set() deleted_device,
orphaned_timestamp=now_time,
config_entries=set(),
config_entries_subentries={},
) )
else: else:
config_entries = config_entries - {config_entry_id} config_entries = config_entries - {config_entry_id}
config_entries_subentries = dict(
deleted_device.config_entries_subentries
)
del config_entries_subentries[config_entry_id]
# No need to reindex here since we currently
# do not have a lookup by config entry
self.deleted_devices[deleted_device.id] = attr.evolve(
deleted_device,
config_entries=config_entries,
config_entries_subentries=config_entries_subentries,
)
self.async_schedule_save()
@callback
def async_clear_config_subentry(
self, config_entry_id: str, config_subentry_id: str
) -> None:
"""Clear config entry from registry entries."""
now_time = time.time()
now_time = time.time()
for device in self.devices.get_devices_for_config_entry_id(config_entry_id):
self.async_update_device(
device.id,
remove_config_entry_id=config_entry_id,
remove_config_subentry_id=config_subentry_id,
)
for deleted_device in list(self.deleted_devices.values()):
config_entries = deleted_device.config_entries
config_entries_subentries = deleted_device.config_entries_subentries
if (
config_entry_id not in config_entries_subentries
or config_subentry_id not in config_entries_subentries[config_entry_id]
):
continue
if config_entries_subentries == {config_entry_id: {config_subentry_id}}:
# We're removing the last config subentry from the last config
# entry, add a time stamp when the deleted device became orphaned
self.deleted_devices[deleted_device.id] = attr.evolve(
deleted_device,
orphaned_timestamp=now_time,
config_entries=set(),
config_entries_subentries={},
)
else:
config_entries_subentries = config_entries_subentries | {
config_entry_id: config_entries_subentries[config_entry_id]
- {config_subentry_id}
}
if not config_entries_subentries[config_entry_id]:
del config_entries_subentries[config_entry_id]
config_entries = config_entries - {config_entry_id}
# No need to reindex here since we currently # No need to reindex here since we currently
# do not have a lookup by config entry # do not have a lookup by config entry
self.deleted_devices[deleted_device.id] = attr.evolve( self.deleted_devices[deleted_device.id] = attr.evolve(
deleted_device, config_entries=config_entries deleted_device,
config_entries=config_entries,
config_entries_subentries=config_entries_subentries,
) )
self.async_schedule_save() self.async_schedule_save()

View File

@ -80,6 +80,22 @@ class AddEntitiesCallback(Protocol):
"""Define add_entities type.""" """Define add_entities type."""
class AddConfigEntryEntitiesCallback(Protocol):
"""Protocol type for EntityPlatform.add_entities callback."""
def __call__(
self,
new_entities: Iterable[Entity],
update_before_add: bool = False,
*,
config_subentry_id: str | None = None,
) -> None:
"""Define add_entities type.
:param config_subentry_id: subentry which the entities should be added to
"""
class EntityPlatformModule(Protocol): class EntityPlatformModule(Protocol):
"""Protocol type for entity platform modules.""" """Protocol type for entity platform modules."""
@ -105,7 +121,7 @@ class EntityPlatformModule(Protocol):
self, self,
hass: HomeAssistant, hass: HomeAssistant,
entry: config_entries.ConfigEntry, entry: config_entries.ConfigEntry,
async_add_entities: AddEntitiesCallback, async_add_entities: AddConfigEntryEntitiesCallback,
) -> None: ) -> None:
"""Set up an integration platform from a config entry.""" """Set up an integration platform from a config entry."""
@ -517,13 +533,21 @@ class EntityPlatform:
@callback @callback
def _async_schedule_add_entities_for_entry( def _async_schedule_add_entities_for_entry(
self, new_entities: Iterable[Entity], update_before_add: bool = False self,
new_entities: Iterable[Entity],
update_before_add: bool = False,
*,
config_subentry_id: str | None = None,
) -> None: ) -> None:
"""Schedule adding entities for a single platform async and track the task.""" """Schedule adding entities for a single platform async and track the task."""
assert self.config_entry assert self.config_entry
task = self.config_entry.async_create_task( task = self.config_entry.async_create_task(
self.hass, self.hass,
self.async_add_entities(new_entities, update_before_add=update_before_add), self.async_add_entities(
new_entities,
update_before_add=update_before_add,
config_subentry_id=config_subentry_id,
),
f"EntityPlatform async_add_entities_for_entry {self.domain}.{self.platform_name}", f"EntityPlatform async_add_entities_for_entry {self.domain}.{self.platform_name}",
eager_start=True, eager_start=True,
) )
@ -625,12 +649,27 @@ class EntityPlatform:
) )
async def async_add_entities( async def async_add_entities(
self, new_entities: Iterable[Entity], update_before_add: bool = False self,
new_entities: Iterable[Entity],
update_before_add: bool = False,
*,
config_subentry_id: str | None = None,
) -> None: ) -> None:
"""Add entities for a single platform async. """Add entities for a single platform async.
This method must be run in the event loop. This method must be run in the event loop.
:param subentry_id: subentry which the entities should be added to
""" """
if config_subentry_id and (
not self.config_entry
or config_subentry_id not in self.config_entry.subentries
):
raise HomeAssistantError(
f"Can't add entities to unknown subentry {config_subentry_id} of config "
f"entry {self.config_entry.entry_id if self.config_entry else None}"
)
# handle empty list from component/platform # handle empty list from component/platform
if not new_entities: # type: ignore[truthy-iterable] if not new_entities: # type: ignore[truthy-iterable]
return return
@ -641,7 +680,9 @@ class EntityPlatform:
entities: list[Entity] = [] entities: list[Entity] = []
for entity in new_entities: for entity in new_entities:
coros.append( coros.append(
self._async_add_entity(entity, update_before_add, entity_registry) self._async_add_entity(
entity, update_before_add, entity_registry, config_subentry_id
)
) )
entities.append(entity) entities.append(entity)
@ -720,6 +761,7 @@ class EntityPlatform:
entity: Entity, entity: Entity,
update_before_add: bool, update_before_add: bool,
entity_registry: EntityRegistry, entity_registry: EntityRegistry,
config_subentry_id: str | None,
) -> None: ) -> None:
"""Add an entity to the platform.""" """Add an entity to the platform."""
if entity is None: if entity is None:
@ -779,6 +821,7 @@ class EntityPlatform:
try: try:
device = dev_reg.async_get(self.hass).async_get_or_create( device = dev_reg.async_get(self.hass).async_get_or_create(
config_entry_id=self.config_entry.entry_id, config_entry_id=self.config_entry.entry_id,
config_subentry_id=config_subentry_id,
**device_info, **device_info,
) )
except dev_reg.DeviceInfoError as exc: except dev_reg.DeviceInfoError as exc:
@ -825,6 +868,7 @@ class EntityPlatform:
entity.unique_id, entity.unique_id,
capabilities=entity.capability_attributes, capabilities=entity.capability_attributes,
config_entry=self.config_entry, config_entry=self.config_entry,
config_subentry_id=config_subentry_id,
device_id=device.id if device else None, device_id=device.id if device else None,
disabled_by=disabled_by, disabled_by=disabled_by,
entity_category=entity.entity_category, entity_category=entity.entity_category,

View File

@ -79,7 +79,7 @@ EVENT_ENTITY_REGISTRY_UPDATED: EventType[EventEntityRegistryUpdatedData] = Event
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
STORAGE_VERSION_MAJOR = 1 STORAGE_VERSION_MAJOR = 1
STORAGE_VERSION_MINOR = 15 STORAGE_VERSION_MINOR = 16
STORAGE_KEY = "core.entity_registry" STORAGE_KEY = "core.entity_registry"
CLEANUP_INTERVAL = 3600 * 24 CLEANUP_INTERVAL = 3600 * 24
@ -177,6 +177,7 @@ class RegistryEntry:
categories: dict[str, str] = attr.ib(factory=dict) categories: dict[str, str] = attr.ib(factory=dict)
capabilities: Mapping[str, Any] | None = attr.ib(default=None) capabilities: Mapping[str, Any] | None = attr.ib(default=None)
config_entry_id: str | None = attr.ib(default=None) config_entry_id: str | None = attr.ib(default=None)
config_subentry_id: str | None = attr.ib(default=None)
created_at: datetime = attr.ib(factory=utcnow) created_at: datetime = attr.ib(factory=utcnow)
device_class: str | None = attr.ib(default=None) device_class: str | None = attr.ib(default=None)
device_id: str | None = attr.ib(default=None) device_id: str | None = attr.ib(default=None)
@ -280,6 +281,7 @@ class RegistryEntry:
"area_id": self.area_id, "area_id": self.area_id,
"categories": self.categories, "categories": self.categories,
"config_entry_id": self.config_entry_id, "config_entry_id": self.config_entry_id,
"config_subentry_id": self.config_subentry_id,
"created_at": self.created_at.timestamp(), "created_at": self.created_at.timestamp(),
"device_id": self.device_id, "device_id": self.device_id,
"disabled_by": self.disabled_by, "disabled_by": self.disabled_by,
@ -341,6 +343,7 @@ class RegistryEntry:
"categories": self.categories, "categories": self.categories,
"capabilities": self.capabilities, "capabilities": self.capabilities,
"config_entry_id": self.config_entry_id, "config_entry_id": self.config_entry_id,
"config_subentry_id": self.config_subentry_id,
"created_at": self.created_at, "created_at": self.created_at,
"device_class": self.device_class, "device_class": self.device_class,
"device_id": self.device_id, "device_id": self.device_id,
@ -405,6 +408,7 @@ class DeletedRegistryEntry:
unique_id: str = attr.ib() unique_id: str = attr.ib()
platform: str = attr.ib() platform: str = attr.ib()
config_entry_id: str | None = attr.ib() config_entry_id: str | None = attr.ib()
config_subentry_id: str | None = attr.ib()
domain: str = attr.ib(init=False, repr=False) domain: str = attr.ib(init=False, repr=False)
id: str = attr.ib() id: str = attr.ib()
orphaned_timestamp: float | None = attr.ib() orphaned_timestamp: float | None = attr.ib()
@ -424,6 +428,7 @@ class DeletedRegistryEntry:
json_bytes( json_bytes(
{ {
"config_entry_id": self.config_entry_id, "config_entry_id": self.config_entry_id,
"config_subentry_id": self.config_subentry_id,
"created_at": self.created_at, "created_at": self.created_at,
"entity_id": self.entity_id, "entity_id": self.entity_id,
"id": self.id, "id": self.id,
@ -539,6 +544,13 @@ class EntityRegistryStore(storage.Store[dict[str, list[dict[str, Any]]]]):
for entity in data["deleted_entities"]: for entity in data["deleted_entities"]:
entity["created_at"] = entity["modified_at"] = created_at entity["created_at"] = entity["modified_at"] = created_at
if old_minor_version < 16:
# Version 1.16 adds config_subentry_id
for entity in data["entities"]:
entity["config_subentry_id"] = None
for entity in data["deleted_entities"]:
entity["config_subentry_id"] = None
if old_major_version > 1: if old_major_version > 1:
raise NotImplementedError raise NotImplementedError
return data return data
@ -647,10 +659,12 @@ def _validate_item(
platform: str, platform: str,
*, *,
config_entry_id: str | None | UndefinedType = None, config_entry_id: str | None | UndefinedType = None,
config_subentry_id: str | None | UndefinedType = None,
device_id: str | None | UndefinedType = None, device_id: str | None | UndefinedType = None,
disabled_by: RegistryEntryDisabler | None | UndefinedType = None, disabled_by: RegistryEntryDisabler | None | UndefinedType = None,
entity_category: EntityCategory | None | UndefinedType = None, entity_category: EntityCategory | None | UndefinedType = None,
hidden_by: RegistryEntryHider | None | UndefinedType = None, hidden_by: RegistryEntryHider | None | UndefinedType = None,
old_config_subentry_id: str | None = None,
report_non_string_unique_id: bool = True, report_non_string_unique_id: bool = True,
unique_id: str | Hashable | UndefinedType | Any, unique_id: str | Hashable | UndefinedType | Any,
) -> None: ) -> None:
@ -676,6 +690,26 @@ def _validate_item(
raise ValueError( raise ValueError(
f"Can't link entity to unknown config entry {config_entry_id}" f"Can't link entity to unknown config entry {config_entry_id}"
) )
if (
config_entry_id
and config_entry_id is not UNDEFINED
and old_config_subentry_id
and config_subentry_id is UNDEFINED
):
raise ValueError("Can't change config entry without changing subentry")
if (
config_entry_id
and config_entry_id is not UNDEFINED
and config_subentry_id
and config_subentry_id is not UNDEFINED
):
if (
not (config_entry := hass.config_entries.async_get_entry(config_entry_id))
or config_subentry_id not in config_entry.subentries
):
raise ValueError(
f"Config entry {config_entry_id} has no subentry {config_subentry_id}"
)
if device_id and device_id is not UNDEFINED: if device_id and device_id is not UNDEFINED:
device_registry = dr.async_get(hass) device_registry = dr.async_get(hass)
if not device_registry.async_get(device_id): if not device_registry.async_get(device_id):
@ -826,6 +860,7 @@ class EntityRegistry(BaseRegistry):
# Data that we want entry to have # Data that we want entry to have
capabilities: Mapping[str, Any] | None | UndefinedType = UNDEFINED, capabilities: Mapping[str, Any] | None | UndefinedType = UNDEFINED,
config_entry: ConfigEntry | None | UndefinedType = UNDEFINED, config_entry: ConfigEntry | None | UndefinedType = UNDEFINED,
config_subentry_id: str | None | UndefinedType = UNDEFINED,
device_id: str | None | UndefinedType = UNDEFINED, device_id: str | None | UndefinedType = UNDEFINED,
entity_category: EntityCategory | UndefinedType | None = UNDEFINED, entity_category: EntityCategory | UndefinedType | None = UNDEFINED,
has_entity_name: bool | UndefinedType = UNDEFINED, has_entity_name: bool | UndefinedType = UNDEFINED,
@ -852,6 +887,7 @@ class EntityRegistry(BaseRegistry):
entity_id, entity_id,
capabilities=capabilities, capabilities=capabilities,
config_entry_id=config_entry_id, config_entry_id=config_entry_id,
config_subentry_id=config_subentry_id,
device_id=device_id, device_id=device_id,
entity_category=entity_category, entity_category=entity_category,
has_entity_name=has_entity_name, has_entity_name=has_entity_name,
@ -869,6 +905,7 @@ class EntityRegistry(BaseRegistry):
domain, domain,
platform, platform,
config_entry_id=config_entry_id, config_entry_id=config_entry_id,
config_subentry_id=config_subentry_id,
device_id=device_id, device_id=device_id,
disabled_by=disabled_by, disabled_by=disabled_by,
entity_category=entity_category, entity_category=entity_category,
@ -907,6 +944,7 @@ class EntityRegistry(BaseRegistry):
entry = RegistryEntry( entry = RegistryEntry(
capabilities=none_if_undefined(capabilities), capabilities=none_if_undefined(capabilities),
config_entry_id=none_if_undefined(config_entry_id), config_entry_id=none_if_undefined(config_entry_id),
config_subentry_id=none_if_undefined(config_subentry_id),
created_at=created_at, created_at=created_at,
device_id=none_if_undefined(device_id), device_id=none_if_undefined(device_id),
disabled_by=disabled_by, disabled_by=disabled_by,
@ -949,6 +987,7 @@ class EntityRegistry(BaseRegistry):
orphaned_timestamp = None if config_entry_id else time.time() orphaned_timestamp = None if config_entry_id else time.time()
self.deleted_entities[key] = DeletedRegistryEntry( self.deleted_entities[key] = DeletedRegistryEntry(
config_entry_id=config_entry_id, config_entry_id=config_entry_id,
config_subentry_id=entity.config_subentry_id,
created_at=entity.created_at, created_at=entity.created_at,
entity_id=entity_id, entity_id=entity_id,
id=entity.id, id=entity.id,
@ -1008,6 +1047,20 @@ class EntityRegistry(BaseRegistry):
): ):
self.async_remove(entity.entity_id) self.async_remove(entity.entity_id)
# Remove entities which belong to config subentries no longer associated with the
# device
entities = async_entries_for_device(
self, event.data["device_id"], include_disabled_entities=True
)
for entity in entities:
if (
(config_entry_id := entity.config_entry_id) is not None
and config_entry_id in device.config_entries
and entity.config_subentry_id
not in device.config_entries_subentries[config_entry_id]
):
self.async_remove(entity.entity_id)
# Re-enable disabled entities if the device is no longer disabled # Re-enable disabled entities if the device is no longer disabled
if not device.disabled: if not device.disabled:
entities = async_entries_for_device( entities = async_entries_for_device(
@ -1041,6 +1094,7 @@ class EntityRegistry(BaseRegistry):
categories: dict[str, str] | UndefinedType = UNDEFINED, categories: dict[str, str] | UndefinedType = UNDEFINED,
capabilities: Mapping[str, Any] | None | UndefinedType = UNDEFINED, capabilities: Mapping[str, Any] | None | UndefinedType = UNDEFINED,
config_entry_id: str | None | UndefinedType = UNDEFINED, config_entry_id: str | None | UndefinedType = UNDEFINED,
config_subentry_id: str | None | UndefinedType = UNDEFINED,
device_class: str | None | UndefinedType = UNDEFINED, device_class: str | None | UndefinedType = UNDEFINED,
device_id: str | None | UndefinedType = UNDEFINED, device_id: str | None | UndefinedType = UNDEFINED,
disabled_by: RegistryEntryDisabler | None | UndefinedType = UNDEFINED, disabled_by: RegistryEntryDisabler | None | UndefinedType = UNDEFINED,
@ -1073,6 +1127,7 @@ class EntityRegistry(BaseRegistry):
("categories", categories), ("categories", categories),
("capabilities", capabilities), ("capabilities", capabilities),
("config_entry_id", config_entry_id), ("config_entry_id", config_entry_id),
("config_subentry_id", config_subentry_id),
("device_class", device_class), ("device_class", device_class),
("device_id", device_id), ("device_id", device_id),
("disabled_by", disabled_by), ("disabled_by", disabled_by),
@ -1102,10 +1157,12 @@ class EntityRegistry(BaseRegistry):
old.domain, old.domain,
old.platform, old.platform,
config_entry_id=config_entry_id, config_entry_id=config_entry_id,
config_subentry_id=config_subentry_id,
device_id=device_id, device_id=device_id,
disabled_by=disabled_by, disabled_by=disabled_by,
entity_category=entity_category, entity_category=entity_category,
hidden_by=hidden_by, hidden_by=hidden_by,
old_config_subentry_id=old.config_subentry_id,
unique_id=new_unique_id, unique_id=new_unique_id,
) )
@ -1170,6 +1227,7 @@ class EntityRegistry(BaseRegistry):
categories: dict[str, str] | UndefinedType = UNDEFINED, categories: dict[str, str] | UndefinedType = UNDEFINED,
capabilities: Mapping[str, Any] | None | UndefinedType = UNDEFINED, capabilities: Mapping[str, Any] | None | UndefinedType = UNDEFINED,
config_entry_id: str | None | UndefinedType = UNDEFINED, config_entry_id: str | None | UndefinedType = UNDEFINED,
config_subentry_id: str | None | UndefinedType = UNDEFINED,
device_class: str | None | UndefinedType = UNDEFINED, device_class: str | None | UndefinedType = UNDEFINED,
device_id: str | None | UndefinedType = UNDEFINED, device_id: str | None | UndefinedType = UNDEFINED,
disabled_by: RegistryEntryDisabler | None | UndefinedType = UNDEFINED, disabled_by: RegistryEntryDisabler | None | UndefinedType = UNDEFINED,
@ -1196,6 +1254,7 @@ class EntityRegistry(BaseRegistry):
categories=categories, categories=categories,
capabilities=capabilities, capabilities=capabilities,
config_entry_id=config_entry_id, config_entry_id=config_entry_id,
config_subentry_id=config_subentry_id,
device_class=device_class, device_class=device_class,
device_id=device_id, device_id=device_id,
disabled_by=disabled_by, disabled_by=disabled_by,
@ -1222,6 +1281,7 @@ class EntityRegistry(BaseRegistry):
new_platform: str, new_platform: str,
*, *,
new_config_entry_id: str | UndefinedType = UNDEFINED, new_config_entry_id: str | UndefinedType = UNDEFINED,
new_config_subentry_id: str | UndefinedType = UNDEFINED,
new_unique_id: str | UndefinedType = UNDEFINED, new_unique_id: str | UndefinedType = UNDEFINED,
new_device_id: str | None | UndefinedType = UNDEFINED, new_device_id: str | None | UndefinedType = UNDEFINED,
) -> RegistryEntry: ) -> RegistryEntry:
@ -1246,6 +1306,7 @@ class EntityRegistry(BaseRegistry):
entity_id, entity_id,
new_unique_id=new_unique_id, new_unique_id=new_unique_id,
config_entry_id=new_config_entry_id, config_entry_id=new_config_entry_id,
config_subentry_id=new_config_subentry_id,
device_id=new_device_id, device_id=new_device_id,
platform=new_platform, platform=new_platform,
) )
@ -1308,6 +1369,7 @@ class EntityRegistry(BaseRegistry):
categories=entity["categories"], categories=entity["categories"],
capabilities=entity["capabilities"], capabilities=entity["capabilities"],
config_entry_id=entity["config_entry_id"], config_entry_id=entity["config_entry_id"],
config_subentry_id=entity["config_subentry_id"],
created_at=datetime.fromisoformat(entity["created_at"]), created_at=datetime.fromisoformat(entity["created_at"]),
device_class=entity["device_class"], device_class=entity["device_class"],
device_id=entity["device_id"], device_id=entity["device_id"],
@ -1357,6 +1419,7 @@ class EntityRegistry(BaseRegistry):
) )
deleted_entities[key] = DeletedRegistryEntry( deleted_entities[key] = DeletedRegistryEntry(
config_entry_id=entity["config_entry_id"], config_entry_id=entity["config_entry_id"],
config_subentry_id=entity["config_subentry_id"],
created_at=datetime.fromisoformat(entity["created_at"]), created_at=datetime.fromisoformat(entity["created_at"]),
entity_id=entity["entity_id"], entity_id=entity["entity_id"],
id=entity["id"], id=entity["id"],
@ -1415,6 +1478,30 @@ class EntityRegistry(BaseRegistry):
) )
self.async_schedule_save() self.async_schedule_save()
@callback
def async_clear_config_subentry(
self, config_entry_id: str, config_subentry_id: str
) -> None:
"""Clear config subentry from registry entries."""
now_time = time.time()
for entity_id in [
entry.entity_id
for entry in self.entities.get_entries_for_config_entry_id(config_entry_id)
if entry.config_subentry_id == config_subentry_id
]:
self.async_remove(entity_id)
for key, deleted_entity in list(self.deleted_entities.items()):
if config_subentry_id != deleted_entity.config_subentry_id:
continue
# Add a time stamp when the deleted entity became orphaned
self.deleted_entities[key] = attr.evolve(
deleted_entity,
orphaned_timestamp=now_time,
config_entry_id=None,
config_subentry_id=None,
)
self.async_schedule_save()
@callback @callback
def async_purge_expired_orphaned_entities(self) -> None: def async_purge_expired_orphaned_entities(self) -> None:
"""Purge expired orphaned entities from the registry. """Purge expired orphaned entities from the registry.

View File

@ -285,6 +285,15 @@ def gen_strings_schema(config: Config, integration: Integration) -> vol.Schema:
"user" if integration.integration_type == "helper" else None "user" if integration.integration_type == "helper" else None
), ),
), ),
vol.Optional("config_subentries"): cv.schema_with_slug_keys(
gen_data_entry_schema(
config=config,
integration=integration,
flow_title=REQUIRED,
require_step_title=False,
),
slug_validator=vol.Any("_", cv.slug),
),
vol.Optional("options"): gen_data_entry_schema( vol.Optional("options"): gen_data_entry_schema(
config=config, config=config,
integration=integration, integration=integration,

View File

@ -1004,6 +1004,7 @@ class MockConfigEntry(config_entries.ConfigEntry):
reason=None, reason=None,
source=config_entries.SOURCE_USER, source=config_entries.SOURCE_USER,
state=None, state=None,
subentries_data=None,
title="Mock Title", title="Mock Title",
unique_id=None, unique_id=None,
version=1, version=1,
@ -1020,6 +1021,7 @@ class MockConfigEntry(config_entries.ConfigEntry):
"options": options or {}, "options": options or {},
"pref_disable_new_entities": pref_disable_new_entities, "pref_disable_new_entities": pref_disable_new_entities,
"pref_disable_polling": pref_disable_polling, "pref_disable_polling": pref_disable_polling,
"subentries_data": subentries_data or (),
"title": title, "title": title,
"unique_id": unique_id, "unique_id": unique_id,
"version": version, "version": version,
@ -1092,6 +1094,28 @@ class MockConfigEntry(config_entries.ConfigEntry):
}, },
) )
async def start_subentry_reconfigure_flow(
self,
hass: HomeAssistant,
subentry_flow_type: str,
subentry_id: str,
*,
show_advanced_options: bool = False,
) -> ConfigFlowResult:
"""Start a subentry reconfiguration flow."""
if self.entry_id not in hass.config_entries._entries:
raise ValueError(
"Config entry must be added to hass to start reconfiguration flow"
)
return await hass.config_entries.subentries.async_init(
(self.entry_id, subentry_flow_type),
context={
"source": config_entries.SOURCE_RECONFIGURE,
"subentry_id": subentry_id,
"show_advanced_options": show_advanced_options,
},
)
async def start_reauth_flow( async def start_reauth_flow(
hass: HomeAssistant, hass: HomeAssistant,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -52,6 +53,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -98,6 +100,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -3,6 +3,7 @@
DeviceRegistryEntrySnapshot({ DeviceRegistryEntrySnapshot({
'area_id': 'kitchen', 'area_id': 'kitchen',
'config_entries': <ANY>, 'config_entries': <ANY>,
'config_entries_subentries': <ANY>,
'configuration_url': None, 'configuration_url': None,
'connections': set({ 'connections': set({
tuple( tuple(

View File

@ -8,6 +8,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -59,6 +60,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -113,6 +115,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -15,6 +15,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -80,6 +81,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -145,6 +147,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -210,6 +213,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -275,6 +279,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -333,6 +338,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -385,6 +391,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -440,6 +447,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -489,6 +497,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -537,6 +546,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -585,6 +595,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -633,6 +644,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -681,6 +693,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -729,6 +742,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -777,6 +791,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -825,6 +840,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -873,6 +889,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -921,6 +938,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -969,6 +987,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1016,6 +1035,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1063,6 +1083,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1110,6 +1131,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1157,6 +1179,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1204,6 +1227,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1251,6 +1275,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1298,6 +1323,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1345,6 +1371,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1392,6 +1419,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1441,6 +1469,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1491,6 +1520,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1540,6 +1570,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1589,6 +1620,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1638,6 +1670,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1687,6 +1720,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1736,6 +1770,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1784,6 +1819,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1832,6 +1868,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1880,6 +1917,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1928,6 +1966,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1978,6 +2017,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2028,6 +2068,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2077,6 +2118,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2126,6 +2168,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2175,6 +2218,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2224,6 +2268,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2275,6 +2320,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2328,6 +2374,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2387,6 +2434,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2440,6 +2488,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2489,6 +2538,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2538,6 +2588,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2587,6 +2638,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2636,6 +2688,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2687,6 +2740,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2737,6 +2791,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2786,6 +2841,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2835,6 +2891,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2884,6 +2941,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2933,6 +2991,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2982,6 +3041,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3031,6 +3091,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3080,6 +3141,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3129,6 +3191,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3178,6 +3241,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3229,6 +3293,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3279,6 +3344,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3328,6 +3394,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3377,6 +3444,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3426,6 +3494,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3475,6 +3544,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3524,6 +3594,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3573,6 +3644,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3622,6 +3694,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3671,6 +3744,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3720,6 +3794,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3769,6 +3844,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3818,6 +3894,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3867,6 +3944,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3916,6 +3994,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3965,6 +4044,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4014,6 +4094,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4063,6 +4144,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4112,6 +4194,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4161,6 +4244,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4210,6 +4294,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4261,6 +4346,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4311,6 +4397,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4359,6 +4446,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4407,6 +4495,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4455,6 +4544,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4503,6 +4593,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4551,6 +4642,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4599,6 +4691,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4647,6 +4740,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4695,6 +4789,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4743,6 +4838,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4791,6 +4887,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4840,6 +4937,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4889,6 +4987,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4938,6 +5037,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -4987,6 +5087,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5038,6 +5139,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5088,6 +5190,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5137,6 +5240,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5186,6 +5290,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5235,6 +5340,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5284,6 +5390,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5335,6 +5442,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5387,6 +5495,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5439,6 +5548,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5489,6 +5599,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5539,6 +5650,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5589,6 +5701,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5639,6 +5752,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5689,6 +5803,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5739,6 +5854,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5789,6 +5905,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5839,6 +5956,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5889,6 +6007,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5939,6 +6058,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -5991,6 +6111,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -6041,6 +6162,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -6091,6 +6213,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -6141,6 +6264,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -6191,6 +6315,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -6241,6 +6366,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -6291,6 +6417,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -6341,6 +6468,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -6391,6 +6519,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -6441,6 +6570,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -6491,6 +6621,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -247,6 +247,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -22,6 +22,8 @@
'pref_disable_new_entities': False, 'pref_disable_new_entities': False,
'pref_disable_polling': False, 'pref_disable_polling': False,
'source': 'user', 'source': 'user',
'subentries': list([
]),
'title': 'Mock Title', 'title': 'Mock Title',
'unique_id': '**REDACTED**', 'unique_id': '**REDACTED**',
'version': 1, 'version': 1,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -52,6 +53,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -98,6 +100,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -3,6 +3,7 @@
DeviceRegistryEntrySnapshot({ DeviceRegistryEntrySnapshot({
'area_id': None, 'area_id': None,
'config_entries': <ANY>, 'config_entries': <ANY>,
'config_entries_subentries': <ANY>,
'configuration_url': None, 'configuration_url': None,
'connections': set({ 'connections': set({
}), }),
@ -35,6 +36,7 @@
DeviceRegistryEntrySnapshot({ DeviceRegistryEntrySnapshot({
'area_id': None, 'area_id': None,
'config_entries': <ANY>, 'config_entries': <ANY>,
'config_entries_subentries': <ANY>,
'configuration_url': None, 'configuration_url': None,
'connections': set({ 'connections': set({
}), }),

View File

@ -11,6 +11,7 @@
'step': 1, 'step': 1,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -67,6 +68,7 @@
'step': 1, 'step': 1,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -15,6 +15,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -74,6 +75,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -129,6 +131,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -184,6 +187,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -240,6 +244,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -299,6 +304,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -360,6 +366,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -422,6 +429,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -481,6 +489,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -539,6 +548,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -600,6 +610,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -8,6 +8,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -57,6 +58,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -105,6 +107,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -157,6 +160,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -213,6 +217,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -266,6 +271,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -315,6 +321,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -368,6 +375,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -422,6 +430,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -469,6 +478,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -519,6 +529,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -569,6 +580,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -620,6 +632,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -671,6 +684,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -722,6 +736,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -772,6 +787,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -823,6 +839,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -873,6 +890,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -924,6 +942,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -975,6 +994,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1022,6 +1042,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1070,6 +1091,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1120,6 +1142,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1167,6 +1190,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1217,6 +1241,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1267,6 +1292,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1317,6 +1343,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1368,6 +1395,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1415,6 +1443,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -19,6 +19,8 @@
'pref_disable_new_entities': False, 'pref_disable_new_entities': False,
'pref_disable_polling': False, 'pref_disable_polling': False,
'source': 'user', 'source': 'user',
'subentries': list([
]),
'title': 'Home', 'title': 'Home',
'unique_id': '**REDACTED**', 'unique_id': '**REDACTED**',
'version': 1, 'version': 1,

View File

@ -8,6 +8,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -62,6 +63,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -118,6 +120,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -173,6 +176,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -230,6 +234,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -287,6 +292,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -342,6 +348,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -399,6 +406,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -456,6 +464,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -511,6 +520,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -568,6 +578,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -35,6 +35,8 @@
'pref_disable_new_entities': False, 'pref_disable_new_entities': False,
'pref_disable_polling': False, 'pref_disable_polling': False,
'source': 'user', 'source': 'user',
'subentries': list([
]),
'title': '**REDACTED**', 'title': '**REDACTED**',
'unique_id': '**REDACTED**', 'unique_id': '**REDACTED**',
'version': 2, 'version': 2,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -55,6 +56,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -47,6 +47,8 @@
'pref_disable_new_entities': False, 'pref_disable_new_entities': False,
'pref_disable_polling': False, 'pref_disable_polling': False,
'source': 'user', 'source': 'user',
'subentries': list([
]),
'title': '**REDACTED**', 'title': '**REDACTED**',
'unique_id': '**REDACTED**', 'unique_id': '**REDACTED**',
'version': 3, 'version': 3,

View File

@ -101,6 +101,8 @@
'pref_disable_new_entities': False, 'pref_disable_new_entities': False,
'pref_disable_polling': False, 'pref_disable_polling': False,
'source': 'user', 'source': 'user',
'subentries': list([
]),
'title': 'Mock Title', 'title': 'Mock Title',
'unique_id': 'XXXXXXX', 'unique_id': 'XXXXXXX',
'version': 1, 'version': 1,

View File

@ -289,6 +289,8 @@
'pref_disable_new_entities': False, 'pref_disable_new_entities': False,
'pref_disable_polling': False, 'pref_disable_polling': False,
'source': 'user', 'source': 'user',
'subentries': list([
]),
'title': 'Mock Title', 'title': 'Mock Title',
'unique_id': '**REDACTED**', 'unique_id': '**REDACTED**',
'version': 1, 'version': 1,

View File

@ -101,6 +101,8 @@
'pref_disable_new_entities': False, 'pref_disable_new_entities': False,
'pref_disable_polling': False, 'pref_disable_polling': False,
'source': 'user', 'source': 'user',
'subentries': list([
]),
'title': 'Mock Title', 'title': 'Mock Title',
'unique_id': 'installation1', 'unique_id': 'installation1',
'version': 1, 'version': 1,

View File

@ -8,6 +8,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -67,6 +68,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -126,6 +128,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -182,6 +185,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -238,6 +242,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -297,6 +302,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -353,6 +359,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -407,6 +414,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -458,6 +466,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -517,6 +526,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -576,6 +586,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -635,6 +646,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -691,6 +703,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -746,6 +759,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -803,6 +817,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -857,6 +872,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -916,6 +932,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -975,6 +992,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1034,6 +1052,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1093,6 +1112,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1149,6 +1169,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1205,6 +1226,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1264,6 +1286,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1320,6 +1343,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1374,6 +1398,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1425,6 +1450,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1484,6 +1510,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1543,6 +1570,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1602,6 +1630,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1658,6 +1687,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1713,6 +1743,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1770,6 +1801,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1824,6 +1856,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1883,6 +1916,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1942,6 +1976,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2000,6 +2035,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2058,6 +2094,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2113,6 +2150,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2168,6 +2206,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2226,6 +2265,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2281,6 +2321,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2336,6 +2377,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2394,6 +2436,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2452,6 +2495,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2510,6 +2554,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2565,6 +2610,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2619,6 +2665,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2675,6 +2722,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2728,6 +2776,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2786,6 +2835,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -17,6 +17,8 @@
'pref_disable_new_entities': False, 'pref_disable_new_entities': False,
'pref_disable_polling': False, 'pref_disable_polling': False,
'source': 'user', 'source': 'user',
'subentries': list([
]),
'title': '**REDACTED**', 'title': '**REDACTED**',
'unique_id': '**REDACTED**', 'unique_id': '**REDACTED**',
'version': 2, 'version': 2,

View File

@ -8,6 +8,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -58,6 +59,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -108,6 +110,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -158,6 +161,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -208,6 +212,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -258,6 +263,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -308,6 +314,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -3,6 +3,7 @@
DeviceRegistryEntrySnapshot({ DeviceRegistryEntrySnapshot({
'area_id': 'basement', 'area_id': 'basement',
'config_entries': <ANY>, 'config_entries': <ANY>,
'config_entries_subentries': <ANY>,
'configuration_url': None, 'configuration_url': None,
'connections': set({ 'connections': set({
}), }),

View File

@ -8,6 +8,7 @@
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>, 'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -60,6 +61,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -9,6 +9,7 @@
'min_temp': 95, 'min_temp': 95,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -71,6 +72,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -53,6 +54,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -100,6 +102,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -147,6 +150,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -11,6 +11,7 @@
'step': 1, 'step': 1,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -8,6 +8,7 @@
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>, 'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -59,6 +60,7 @@
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>, 'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -110,6 +112,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -161,6 +164,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -212,6 +216,7 @@
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>, 'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -263,6 +268,7 @@
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>, 'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -314,6 +320,7 @@
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>, 'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -365,6 +372,7 @@
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>, 'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -416,6 +424,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -56,6 +57,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -104,6 +106,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -154,6 +157,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -202,6 +206,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -256,6 +261,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -8,6 +8,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -43,6 +44,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -78,6 +80,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -113,6 +116,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -148,6 +152,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -183,6 +188,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -218,6 +224,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -3,6 +3,7 @@
DeviceRegistryEntrySnapshot({ DeviceRegistryEntrySnapshot({
'area_id': 'tmt100_name', 'area_id': 'tmt100_name',
'config_entries': <ANY>, 'config_entries': <ANY>,
'config_entries_subentries': <ANY>,
'configuration_url': 'https://account.august.com', 'configuration_url': 'https://account.august.com',
'connections': set({ 'connections': set({
}), }),

View File

@ -3,6 +3,7 @@
DeviceRegistryEntrySnapshot({ DeviceRegistryEntrySnapshot({
'area_id': 'online_with_doorsense_name', 'area_id': 'online_with_doorsense_name',
'config_entries': <ANY>, 'config_entries': <ANY>,
'config_entries_subentries': <ANY>,
'configuration_url': 'https://account.august.com', 'configuration_url': 'https://account.august.com',
'connections': set({ 'connections': set({
tuple( tuple(

View File

@ -8,6 +8,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -59,6 +60,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -110,6 +112,7 @@
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>, 'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -161,6 +164,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -212,6 +216,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -263,6 +268,7 @@
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>, 'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -314,6 +320,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -365,6 +372,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -416,6 +424,7 @@
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>, 'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -467,6 +476,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -518,6 +528,7 @@
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>, 'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -569,6 +580,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -620,6 +632,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -671,6 +684,7 @@
'state_class': <SensorStateClass.TOTAL: 'total'>, 'state_class': <SensorStateClass.TOTAL: 'total'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -722,6 +736,7 @@
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>, 'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -773,6 +788,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -53,6 +54,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -100,6 +102,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -147,6 +150,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -194,6 +198,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -241,6 +246,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -288,6 +294,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -335,6 +342,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -382,6 +390,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -429,6 +438,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -476,6 +486,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -56,6 +57,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -47,6 +47,8 @@
'pref_disable_new_entities': False, 'pref_disable_new_entities': False,
'pref_disable_polling': False, 'pref_disable_polling': False,
'source': 'user', 'source': 'user',
'subentries': list([
]),
'title': 'Mock Title', 'title': 'Mock Title',
'unique_id': '**REDACTED**', 'unique_id': '**REDACTED**',
'version': 3, 'version': 3,

View File

@ -3,6 +3,7 @@
DeviceRegistryEntrySnapshot({ DeviceRegistryEntrySnapshot({
'area_id': None, 'area_id': None,
'config_entries': <ANY>, 'config_entries': <ANY>,
'config_entries_subentries': <ANY>,
'configuration_url': 'http://1.2.3.4:80', 'configuration_url': 'http://1.2.3.4:80',
'connections': set({ 'connections': set({
tuple( tuple(
@ -39,6 +40,7 @@
DeviceRegistryEntrySnapshot({ DeviceRegistryEntrySnapshot({
'area_id': None, 'area_id': None,
'config_entries': <ANY>, 'config_entries': <ANY>,
'config_entries_subentries': <ANY>,
'configuration_url': 'http://1.2.3.4:80', 'configuration_url': 'http://1.2.3.4:80',
'connections': set({ 'connections': set({
tuple( tuple(

View File

@ -10,6 +10,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -53,6 +54,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -100,6 +102,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -147,6 +150,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -64,6 +65,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -111,6 +113,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -157,6 +160,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -204,6 +208,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -250,6 +255,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -296,6 +302,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -342,6 +349,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -388,6 +396,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -435,6 +444,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -53,6 +54,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -100,6 +102,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -17,6 +17,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -8,6 +8,7 @@
'preset_modes': None, 'preset_modes': None,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -10,6 +10,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -11,6 +11,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -18,6 +18,8 @@
'pref_disable_new_entities': False, 'pref_disable_new_entities': False,
'pref_disable_polling': False, 'pref_disable_polling': False,
'source': 'user', 'source': 'user',
'subentries': list([
]),
'title': 'Beosound Balance-11111111', 'title': 'Beosound Balance-11111111',
'unique_id': '11111111', 'unique_id': '11111111',
'version': 1, 'version': 1,

View File

@ -48,6 +48,8 @@
'pref_disable_new_entities': False, 'pref_disable_new_entities': False,
'pref_disable_polling': False, 'pref_disable_polling': False,
'source': 'user', 'source': 'user',
'subentries': list([
]),
'title': 'Mock Title', 'title': 'Mock Title',
'unique_id': None, 'unique_id': None,
'version': 3, 'version': 3,

View File

@ -8,6 +8,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -59,6 +60,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -110,6 +112,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -161,6 +164,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -212,6 +216,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -53,6 +54,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -100,6 +102,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -153,6 +156,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -200,6 +204,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -248,6 +253,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -302,6 +308,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -348,6 +355,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -397,6 +405,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -444,6 +453,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -492,6 +502,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -550,6 +561,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -597,6 +609,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -645,6 +658,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -698,6 +712,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -744,6 +759,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -796,6 +812,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -843,6 +860,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -891,6 +909,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -949,6 +968,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -996,6 +1016,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1044,6 +1065,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1098,6 +1120,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1144,6 +1167,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1196,6 +1220,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1245,6 +1270,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1306,6 +1332,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1354,6 +1381,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1407,6 +1435,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -52,6 +53,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -98,6 +100,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -144,6 +147,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -190,6 +194,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -236,6 +241,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -282,6 +288,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -328,6 +335,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -374,6 +382,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -420,6 +429,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -466,6 +476,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -512,6 +523,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -558,6 +570,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -604,6 +617,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -650,6 +664,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -696,6 +711,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -742,6 +758,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -788,6 +805,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -834,6 +852,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -54,6 +55,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -102,6 +104,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -150,6 +153,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -11,6 +11,7 @@
'step': 5.0, 'step': 5.0,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -67,6 +68,7 @@
'step': 5.0, 'step': 5.0,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -12,6 +12,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -79,6 +80,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -147,6 +149,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -214,6 +217,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -282,6 +286,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -57,6 +58,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -104,6 +106,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -166,6 +169,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -227,6 +231,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -279,6 +284,7 @@
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>, 'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -333,6 +339,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -387,6 +394,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -441,6 +449,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -494,6 +503,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -548,6 +558,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -602,6 +613,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -654,6 +666,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -705,6 +718,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -752,6 +766,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -814,6 +829,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -875,6 +891,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -933,6 +950,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -989,6 +1007,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1046,6 +1065,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1103,6 +1123,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1160,6 +1181,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1217,6 +1239,7 @@
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>, 'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1271,6 +1294,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1328,6 +1352,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1385,6 +1410,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1442,6 +1468,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1499,6 +1526,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1553,6 +1581,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1607,6 +1636,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1659,6 +1689,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1710,6 +1741,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1757,6 +1789,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1819,6 +1852,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1880,6 +1914,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1938,6 +1973,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1994,6 +2030,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2051,6 +2088,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2108,6 +2146,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2165,6 +2204,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2222,6 +2262,7 @@
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>, 'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2276,6 +2317,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2333,6 +2375,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2390,6 +2433,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2447,6 +2491,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2504,6 +2549,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2558,6 +2604,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2612,6 +2659,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2672,6 +2720,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2728,6 +2777,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2785,6 +2835,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2842,6 +2893,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2899,6 +2951,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -2956,6 +3009,7 @@
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>, 'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3010,6 +3064,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3067,6 +3122,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3124,6 +3180,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3181,6 +3238,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3238,6 +3296,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3292,6 +3351,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3345,6 +3405,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -3399,6 +3460,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -52,6 +53,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -98,6 +100,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -144,6 +147,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -19,6 +19,8 @@
'pref_disable_new_entities': False, 'pref_disable_new_entities': False,
'pref_disable_polling': False, 'pref_disable_polling': False,
'source': 'user', 'source': 'user',
'subentries': list([
]),
'title': 'Mock Title', 'title': 'Mock Title',
'unique_id': 'very_unique_string', 'unique_id': 'very_unique_string',
'version': 1, 'version': 1,

View File

@ -12,6 +12,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -95,6 +96,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -59,6 +60,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -111,6 +113,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -181,6 +184,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -250,6 +254,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -297,6 +302,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -350,6 +356,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -402,6 +409,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -472,6 +480,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -541,6 +550,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -53,6 +54,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -8,6 +8,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -58,6 +59,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -108,6 +110,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -158,6 +161,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -208,6 +212,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -258,6 +263,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -308,6 +314,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -358,6 +365,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -408,6 +416,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -458,6 +467,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -508,6 +518,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -558,6 +569,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -608,6 +620,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -658,6 +671,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -708,6 +722,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -758,6 +773,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -806,6 +822,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -855,6 +872,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -905,6 +923,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -955,6 +974,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1005,6 +1025,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1055,6 +1076,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1105,6 +1127,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1153,6 +1176,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1201,6 +1225,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1251,6 +1276,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1301,6 +1327,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -1351,6 +1378,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -21,6 +21,7 @@
'min_temp': 45, 'min_temp': 45,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -18,6 +18,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -91,6 +92,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -8,6 +8,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -59,6 +60,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -14,6 +14,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -3,6 +3,7 @@
DeviceRegistryEntrySnapshot({ DeviceRegistryEntrySnapshot({
'area_id': None, 'area_id': None,
'config_entries': <ANY>, 'config_entries': <ANY>,
'config_entries_subentries': <ANY>,
'configuration_url': 'http://192.168.20.218', 'configuration_url': 'http://192.168.20.218',
'connections': set({ 'connections': set({
}), }),

View File

@ -12,6 +12,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -69,6 +70,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -52,6 +53,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -28,6 +28,7 @@
'target_temp_step': 1, 'target_temp_step': 1,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -83,6 +84,7 @@
'target_temp_step': 1, 'target_temp_step': 1,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -218,6 +220,7 @@
'target_temp_step': 1, 'target_temp_step': 1,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -273,6 +276,7 @@
'target_temp_step': 1, 'target_temp_step': 1,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -17,6 +17,8 @@
'pref_disable_new_entities': False, 'pref_disable_new_entities': False,
'pref_disable_polling': False, 'pref_disable_polling': False,
'source': 'user', 'source': 'user',
'subentries': list([
]),
'title': 'Mock Title', 'title': 'Mock Title',
'unique_id': None, 'unique_id': None,
'version': 1, 'version': 1,

View File

@ -8,6 +8,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -60,6 +61,7 @@
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>, 'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -44,6 +44,8 @@
'pref_disable_new_entities': False, 'pref_disable_new_entities': False,
'pref_disable_polling': False, 'pref_disable_polling': False,
'source': 'user', 'source': 'user',
'subentries': list([
]),
'title': '**REDACTED**', 'title': '**REDACTED**',
'unique_id': None, 'unique_id': None,
'version': 1, 'version': 1,

View File

@ -71,6 +71,8 @@
'pref_disable_new_entities': False, 'pref_disable_new_entities': False,
'pref_disable_polling': False, 'pref_disable_polling': False,
'source': 'user', 'source': 'user',
'subentries': list([
]),
'title': 'Mock Title', 'title': 'Mock Title',
'unique_id': None, 'unique_id': None,
'version': 1, 'version': 1,
@ -135,6 +137,8 @@
'pref_disable_new_entities': False, 'pref_disable_new_entities': False,
'pref_disable_polling': False, 'pref_disable_polling': False,
'source': 'user', 'source': 'user',
'subentries': list([
]),
'title': 'Mock Title', 'title': 'Mock Title',
'unique_id': None, 'unique_id': None,
'version': 1, 'version': 1,

View File

@ -139,11 +139,13 @@ async def test_get_entries(hass: HomeAssistant, client: TestClient) -> None:
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla", "source": "bla",
"state": core_ce.ConfigEntryState.NOT_LOADED.value, "state": core_ce.ConfigEntryState.NOT_LOADED.value,
"supported_subentry_types": {},
"supports_options": True, "supports_options": True,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -157,11 +159,13 @@ async def test_get_entries(hass: HomeAssistant, client: TestClient) -> None:
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": "Unsupported API", "reason": "Unsupported API",
"source": "bla2", "source": "bla2",
"state": core_ce.ConfigEntryState.SETUP_ERROR.value, "state": core_ce.ConfigEntryState.SETUP_ERROR.value,
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -175,11 +179,13 @@ async def test_get_entries(hass: HomeAssistant, client: TestClient) -> None:
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla3", "source": "bla3",
"state": core_ce.ConfigEntryState.NOT_LOADED.value, "state": core_ce.ConfigEntryState.NOT_LOADED.value,
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -193,11 +199,13 @@ async def test_get_entries(hass: HomeAssistant, client: TestClient) -> None:
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla4", "source": "bla4",
"state": core_ce.ConfigEntryState.NOT_LOADED.value, "state": core_ce.ConfigEntryState.NOT_LOADED.value,
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -211,11 +219,13 @@ async def test_get_entries(hass: HomeAssistant, client: TestClient) -> None:
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla5", "source": "bla5",
"state": core_ce.ConfigEntryState.NOT_LOADED.value, "state": core_ce.ConfigEntryState.NOT_LOADED.value,
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -573,11 +583,13 @@ async def test_create_account(hass: HomeAssistant, client: TestClient) -> None:
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": core_ce.SOURCE_USER, "source": core_ce.SOURCE_USER,
"state": core_ce.ConfigEntryState.LOADED.value, "state": core_ce.ConfigEntryState.LOADED.value,
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -588,6 +600,7 @@ async def test_create_account(hass: HomeAssistant, client: TestClient) -> None:
"description_placeholders": None, "description_placeholders": None,
"options": {}, "options": {},
"minor_version": 1, "minor_version": 1,
"subentries": [],
} }
@ -656,11 +669,13 @@ async def test_two_step_flow(hass: HomeAssistant, client: TestClient) -> None:
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": core_ce.SOURCE_USER, "source": core_ce.SOURCE_USER,
"state": core_ce.ConfigEntryState.LOADED.value, "state": core_ce.ConfigEntryState.LOADED.value,
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -671,6 +686,7 @@ async def test_two_step_flow(hass: HomeAssistant, client: TestClient) -> None:
"description_placeholders": None, "description_placeholders": None,
"options": {}, "options": {},
"minor_version": 1, "minor_version": 1,
"subentries": [],
} }
@ -1125,6 +1141,326 @@ async def test_options_flow_with_invalid_data(
assert data == {"errors": {"choices": "invalid is not a valid option"}} assert data == {"errors": {"choices": "invalid is not a valid option"}}
async def test_subentry_flow(hass: HomeAssistant, client) -> None:
"""Test we can start a subentry flow."""
class TestFlow(core_ce.ConfigFlow):
class SubentryFlowHandler(core_ce.ConfigSubentryFlow):
async def async_step_init(self, user_input=None):
raise NotImplementedError
async def async_step_user(self, user_input=None):
schema = {}
schema[vol.Required("enabled")] = bool
return self.async_show_form(
step_id="user",
data_schema=schema,
description_placeholders={"enabled": "Set to true to be true"},
)
@classmethod
@callback
def async_get_supported_subentry_types(
cls, config_entry: core_ce.ConfigEntry
) -> dict[str, type[core_ce.ConfigSubentryFlow]]:
return {"test": TestFlow.SubentryFlowHandler}
mock_integration(hass, MockModule("test"))
mock_platform(hass, "test.config_flow", None)
MockConfigEntry(
domain="test",
entry_id="test1",
source="bla",
).add_to_hass(hass)
entry = hass.config_entries.async_entries()[0]
with mock_config_flow("test", TestFlow):
url = "/api/config/config_entries/subentries/flow"
resp = await client.post(url, json={"handler": [entry.entry_id, "test"]})
assert resp.status == HTTPStatus.OK
data = await resp.json()
data.pop("flow_id")
assert data == {
"type": "form",
"handler": ["test1", "test"],
"step_id": "user",
"data_schema": [{"name": "enabled", "required": True, "type": "boolean"}],
"description_placeholders": {"enabled": "Set to true to be true"},
"errors": None,
"last_step": None,
"preview": None,
}
async def test_subentry_reconfigure_flow(hass: HomeAssistant, client) -> None:
"""Test we can start a subentry reconfigure flow."""
class TestFlow(core_ce.ConfigFlow):
class SubentryFlowHandler(core_ce.ConfigSubentryFlow):
async def async_step_init(self, user_input=None):
raise NotImplementedError
async def async_step_user(self, user_input=None):
raise NotImplementedError
async def async_step_reconfigure(self, user_input=None):
schema = {}
schema[vol.Required("enabled")] = bool
return self.async_show_form(
step_id="reconfigure",
data_schema=schema,
description_placeholders={"enabled": "Set to true to be true"},
)
@classmethod
@callback
def async_get_supported_subentry_types(
cls, config_entry: core_ce.ConfigEntry
) -> dict[str, type[core_ce.ConfigSubentryFlow]]:
return {"test": TestFlow.SubentryFlowHandler}
mock_integration(hass, MockModule("test"))
mock_platform(hass, "test.config_flow", None)
MockConfigEntry(
domain="test",
entry_id="test1",
source="bla",
subentries_data=[
core_ce.ConfigSubentryData(
data={},
subentry_id="mock_id",
subentry_type="test",
title="Title",
unique_id=None,
)
],
).add_to_hass(hass)
entry = hass.config_entries.async_entries()[0]
with mock_config_flow("test", TestFlow):
url = "/api/config/config_entries/subentries/flow"
resp = await client.post(
url, json={"handler": [entry.entry_id, "test"], "subentry_id": "mock_id"}
)
assert resp.status == HTTPStatus.OK
data = await resp.json()
data.pop("flow_id")
assert data == {
"type": "form",
"handler": ["test1", "test"],
"step_id": "reconfigure",
"data_schema": [{"name": "enabled", "required": True, "type": "boolean"}],
"description_placeholders": {"enabled": "Set to true to be true"},
"errors": None,
"last_step": None,
"preview": None,
}
@pytest.mark.parametrize(
("endpoint", "method"),
[
("/api/config/config_entries/subentries/flow", "post"),
("/api/config/config_entries/subentries/flow/1", "get"),
("/api/config/config_entries/subentries/flow/1", "post"),
],
)
async def test_subentry_flow_unauth(
hass: HomeAssistant, client, hass_admin_user: MockUser, endpoint: str, method: str
) -> None:
"""Test unauthorized on subentry flow."""
class TestFlow(core_ce.ConfigFlow):
class SubentryFlowHandler(core_ce.ConfigSubentryFlow):
async def async_step_init(self, user_input=None):
schema = {}
schema[vol.Required("enabled")] = bool
return self.async_show_form(
step_id="user",
data_schema=schema,
description_placeholders={"enabled": "Set to true to be true"},
)
@classmethod
@callback
def async_get_supported_subentry_types(
cls, config_entry: core_ce.ConfigEntry
) -> dict[str, type[core_ce.ConfigSubentryFlow]]:
return {"test": TestFlow.SubentryFlowHandler}
mock_integration(hass, MockModule("test"))
mock_platform(hass, "test.config_flow", None)
MockConfigEntry(
domain="test",
entry_id="test1",
source="bla",
).add_to_hass(hass)
entry = hass.config_entries.async_entries()[0]
hass_admin_user.groups = []
with mock_config_flow("test", TestFlow):
resp = await getattr(client, method)(endpoint, json={"handler": entry.entry_id})
assert resp.status == HTTPStatus.UNAUTHORIZED
async def test_two_step_subentry_flow(hass: HomeAssistant, client) -> None:
"""Test we can finish a two step subentry flow."""
mock_integration(
hass, MockModule("test", async_setup_entry=AsyncMock(return_value=True))
)
mock_platform(hass, "test.config_flow", None)
class TestFlow(core_ce.ConfigFlow):
class SubentryFlowHandler(core_ce.ConfigSubentryFlow):
async def async_step_user(self, user_input=None):
return await self.async_step_finish()
async def async_step_finish(self, user_input=None):
if user_input:
return self.async_create_entry(
title="Mock title", data=user_input, unique_id="test"
)
return self.async_show_form(
step_id="finish", data_schema=vol.Schema({"enabled": bool})
)
@classmethod
@callback
def async_get_supported_subentry_types(
cls, config_entry: core_ce.ConfigEntry
) -> dict[str, type[core_ce.ConfigSubentryFlow]]:
return {"test": TestFlow.SubentryFlowHandler}
MockConfigEntry(
domain="test",
entry_id="test1",
source="bla",
).add_to_hass(hass)
entry = hass.config_entries.async_entries()[0]
with mock_config_flow("test", TestFlow):
url = "/api/config/config_entries/subentries/flow"
resp = await client.post(url, json={"handler": [entry.entry_id, "test"]})
assert resp.status == HTTPStatus.OK
data = await resp.json()
flow_id = data["flow_id"]
expected_data = {
"data_schema": [{"name": "enabled", "type": "boolean"}],
"description_placeholders": None,
"errors": None,
"flow_id": flow_id,
"handler": ["test1", "test"],
"last_step": None,
"preview": None,
"step_id": "finish",
"type": "form",
}
assert data == expected_data
resp = await client.get(f"/api/config/config_entries/subentries/flow/{flow_id}")
assert resp.status == HTTPStatus.OK
data = await resp.json()
assert data == expected_data
resp = await client.post(
f"/api/config/config_entries/subentries/flow/{flow_id}",
json={"enabled": True},
)
assert resp.status == HTTPStatus.OK
data = await resp.json()
assert data == {
"description_placeholders": None,
"description": None,
"flow_id": flow_id,
"handler": ["test1", "test"],
"title": "Mock title",
"type": "create_entry",
"unique_id": "test",
}
async def test_subentry_flow_with_invalid_data(hass: HomeAssistant, client) -> None:
"""Test a subentry flow with invalid_data."""
mock_integration(
hass, MockModule("test", async_setup_entry=AsyncMock(return_value=True))
)
mock_platform(hass, "test.config_flow", None)
class TestFlow(core_ce.ConfigFlow):
class SubentryFlowHandler(core_ce.ConfigSubentryFlow):
async def async_step_user(self, user_input=None):
return self.async_show_form(
step_id="finish",
data_schema=vol.Schema(
{
vol.Required(
"choices", default=["invalid", "valid"]
): cv.multi_select({"valid": "Valid"})
}
),
)
async def async_step_finish(self, user_input=None):
return self.async_create_entry(title="Enable disable", data=user_input)
@classmethod
@callback
def async_get_supported_subentry_types(
cls, config_entry: core_ce.ConfigEntry
) -> dict[str, type[core_ce.ConfigSubentryFlow]]:
return {"test": TestFlow.SubentryFlowHandler}
MockConfigEntry(
domain="test",
entry_id="test1",
source="bla",
).add_to_hass(hass)
entry = hass.config_entries.async_entries()[0]
with mock_config_flow("test", TestFlow):
url = "/api/config/config_entries/subentries/flow"
resp = await client.post(url, json={"handler": [entry.entry_id, "test"]})
assert resp.status == HTTPStatus.OK
data = await resp.json()
flow_id = data.pop("flow_id")
assert data == {
"type": "form",
"handler": ["test1", "test"],
"step_id": "finish",
"data_schema": [
{
"default": ["invalid", "valid"],
"name": "choices",
"options": {"valid": "Valid"},
"required": True,
"type": "multi_select",
}
],
"description_placeholders": None,
"errors": None,
"last_step": None,
"preview": None,
}
with mock_config_flow("test", TestFlow):
resp = await client.post(
f"/api/config/config_entries/subentries/flow/{flow_id}",
json={"choices": ["valid", "invalid"]},
)
assert resp.status == HTTPStatus.BAD_REQUEST
data = await resp.json()
assert data == {"errors": {"choices": "invalid is not a valid option"}}
@pytest.mark.usefixtures("freezer") @pytest.mark.usefixtures("freezer")
async def test_get_single( async def test_get_single(
hass: HomeAssistant, hass_ws_client: WebSocketGenerator hass: HomeAssistant, hass_ws_client: WebSocketGenerator
@ -1157,11 +1493,13 @@ async def test_get_single(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "user", "source": "user",
"state": "loaded", "state": "loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -1517,11 +1855,13 @@ async def test_get_matching_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla", "source": "bla",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -1536,11 +1876,13 @@ async def test_get_matching_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": "Unsupported API", "reason": "Unsupported API",
"source": "bla2", "source": "bla2",
"state": "setup_error", "state": "setup_error",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -1555,11 +1897,13 @@ async def test_get_matching_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla3", "source": "bla3",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -1574,11 +1918,13 @@ async def test_get_matching_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla4", "source": "bla4",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -1593,11 +1939,13 @@ async def test_get_matching_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla5", "source": "bla5",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -1623,11 +1971,13 @@ async def test_get_matching_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla", "source": "bla",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -1652,11 +2002,13 @@ async def test_get_matching_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla4", "source": "bla4",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -1671,11 +2023,13 @@ async def test_get_matching_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla5", "source": "bla5",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -1700,11 +2054,13 @@ async def test_get_matching_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla", "source": "bla",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -1719,11 +2075,13 @@ async def test_get_matching_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla3", "source": "bla3",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -1754,11 +2112,13 @@ async def test_get_matching_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla", "source": "bla",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -1773,11 +2133,13 @@ async def test_get_matching_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": "Unsupported API", "reason": "Unsupported API",
"source": "bla2", "source": "bla2",
"state": "setup_error", "state": "setup_error",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -1792,11 +2154,13 @@ async def test_get_matching_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla3", "source": "bla3",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -1811,11 +2175,13 @@ async def test_get_matching_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla4", "source": "bla4",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -1830,11 +2196,13 @@ async def test_get_matching_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": timestamp, "modified_at": timestamp,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla5", "source": "bla5",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -1937,11 +2305,13 @@ async def test_subscribe_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": created, "modified_at": created,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla", "source": "bla",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -1959,11 +2329,13 @@ async def test_subscribe_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": created, "modified_at": created,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": "Unsupported API", "reason": "Unsupported API",
"source": "bla2", "source": "bla2",
"state": "setup_error", "state": "setup_error",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -1981,11 +2353,13 @@ async def test_subscribe_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": created, "modified_at": created,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla3", "source": "bla3",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -2009,11 +2383,13 @@ async def test_subscribe_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": modified, "modified_at": modified,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla", "source": "bla",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -2038,11 +2414,13 @@ async def test_subscribe_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": modified, "modified_at": modified,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla", "source": "bla",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -2066,11 +2444,13 @@ async def test_subscribe_entries_ws(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": entry.modified_at.timestamp(), "modified_at": entry.modified_at.timestamp(),
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla", "source": "bla",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -2156,11 +2536,13 @@ async def test_subscribe_entries_ws_filtered(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": created, "modified_at": created,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla", "source": "bla",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -2178,11 +2560,13 @@ async def test_subscribe_entries_ws_filtered(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": created, "modified_at": created,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla3", "source": "bla3",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -2208,11 +2592,13 @@ async def test_subscribe_entries_ws_filtered(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": modified, "modified_at": modified,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla", "source": "bla",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -2234,11 +2620,13 @@ async def test_subscribe_entries_ws_filtered(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": modified, "modified_at": modified,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla3", "source": "bla3",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -2264,11 +2652,13 @@ async def test_subscribe_entries_ws_filtered(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": modified, "modified_at": modified,
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla", "source": "bla",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -2292,11 +2682,13 @@ async def test_subscribe_entries_ws_filtered(
"error_reason_translation_key": None, "error_reason_translation_key": None,
"error_reason_translation_placeholders": None, "error_reason_translation_placeholders": None,
"modified_at": entry.modified_at.timestamp(), "modified_at": entry.modified_at.timestamp(),
"num_subentries": 0,
"pref_disable_new_entities": False, "pref_disable_new_entities": False,
"pref_disable_polling": False, "pref_disable_polling": False,
"reason": None, "reason": None,
"source": "bla", "source": "bla",
"state": "not_loaded", "state": "not_loaded",
"supported_subentry_types": {},
"supports_options": False, "supports_options": False,
"supports_reconfigure": False, "supports_reconfigure": False,
"supports_remove_device": False, "supports_remove_device": False,
@ -2507,3 +2899,142 @@ async def test_does_not_support_reconfigure(
response response
== '{"message":"Handler ConfigEntriesFlowManager doesn\'t support step reconfigure"}' == '{"message":"Handler ConfigEntriesFlowManager doesn\'t support step reconfigure"}'
) )
async def test_list_subentries(
hass: HomeAssistant, hass_ws_client: WebSocketGenerator
) -> None:
"""Test that we can list subentries."""
assert await async_setup_component(hass, "config", {})
ws_client = await hass_ws_client(hass)
entry = MockConfigEntry(
domain="test",
state=core_ce.ConfigEntryState.LOADED,
subentries_data=[
core_ce.ConfigSubentryData(
data={"test": "test"},
subentry_id="mock_id",
subentry_type="test",
title="Mock title",
unique_id="test",
)
],
)
entry.add_to_hass(hass)
assert entry.pref_disable_new_entities is False
assert entry.pref_disable_polling is False
await ws_client.send_json_auto_id(
{
"type": "config_entries/subentries/list",
"entry_id": entry.entry_id,
}
)
response = await ws_client.receive_json()
assert response["success"]
assert response["result"] == [
{
"subentry_id": "mock_id",
"subentry_type": "test",
"title": "Mock title",
"unique_id": "test",
},
]
# Try listing subentries for an unknown entry
await ws_client.send_json_auto_id(
{
"type": "config_entries/subentries/list",
"entry_id": "no_such_entry",
}
)
response = await ws_client.receive_json()
assert not response["success"]
assert response["error"] == {
"code": "not_found",
"message": "Config entry not found",
}
async def test_delete_subentry(
hass: HomeAssistant, hass_ws_client: WebSocketGenerator
) -> None:
"""Test that we can delete a subentry."""
assert await async_setup_component(hass, "config", {})
ws_client = await hass_ws_client(hass)
entry = MockConfigEntry(
domain="test",
state=core_ce.ConfigEntryState.LOADED,
subentries_data=[
core_ce.ConfigSubentryData(
data={"test": "test"},
subentry_id="mock_id",
subentry_type="test",
title="Mock title",
)
],
)
entry.add_to_hass(hass)
assert entry.pref_disable_new_entities is False
assert entry.pref_disable_polling is False
await ws_client.send_json_auto_id(
{
"type": "config_entries/subentries/delete",
"entry_id": entry.entry_id,
"subentry_id": "mock_id",
}
)
response = await ws_client.receive_json()
assert response["success"]
assert response["result"] is None
await ws_client.send_json_auto_id(
{
"type": "config_entries/subentries/list",
"entry_id": entry.entry_id,
}
)
response = await ws_client.receive_json()
assert response["success"]
assert response["result"] == []
# Try deleting the subentry again
await ws_client.send_json_auto_id(
{
"type": "config_entries/subentries/delete",
"entry_id": entry.entry_id,
"subentry_id": "mock_id",
}
)
response = await ws_client.receive_json()
assert not response["success"]
assert response["error"] == {
"code": "not_found",
"message": "Config subentry not found",
}
# Try deleting subentry from an unknown entry
await ws_client.send_json_auto_id(
{
"type": "config_entries/subentries/delete",
"entry_id": "no_such_entry",
"subentry_id": "mock_id",
}
)
response = await ws_client.receive_json()
assert not response["success"]
assert response["error"] == {
"code": "not_found",
"message": "Config entry not found",
}

View File

@ -65,6 +65,7 @@ async def test_list_devices(
{ {
"area_id": None, "area_id": None,
"config_entries": [entry.entry_id], "config_entries": [entry.entry_id],
"config_entries_subentries": {entry.entry_id: [None]},
"configuration_url": None, "configuration_url": None,
"connections": [["ethernet", "12:34:56:78:90:AB:CD:EF"]], "connections": [["ethernet", "12:34:56:78:90:AB:CD:EF"]],
"created_at": utcnow().timestamp(), "created_at": utcnow().timestamp(),
@ -87,6 +88,7 @@ async def test_list_devices(
{ {
"area_id": None, "area_id": None,
"config_entries": [entry.entry_id], "config_entries": [entry.entry_id],
"config_entries_subentries": {entry.entry_id: [None]},
"configuration_url": None, "configuration_url": None,
"connections": [], "connections": [],
"created_at": utcnow().timestamp(), "created_at": utcnow().timestamp(),
@ -121,6 +123,7 @@ async def test_list_devices(
{ {
"area_id": None, "area_id": None,
"config_entries": [entry.entry_id], "config_entries": [entry.entry_id],
"config_entries_subentries": {entry.entry_id: [None]},
"configuration_url": None, "configuration_url": None,
"connections": [["ethernet", "12:34:56:78:90:AB:CD:EF"]], "connections": [["ethernet", "12:34:56:78:90:AB:CD:EF"]],
"created_at": utcnow().timestamp(), "created_at": utcnow().timestamp(),

View File

@ -67,6 +67,7 @@ async def test_list_entities(
"area_id": None, "area_id": None,
"categories": {}, "categories": {},
"config_entry_id": None, "config_entry_id": None,
"config_subentry_id": None,
"created_at": utcnow().timestamp(), "created_at": utcnow().timestamp(),
"device_id": None, "device_id": None,
"disabled_by": None, "disabled_by": None,
@ -89,6 +90,7 @@ async def test_list_entities(
"area_id": None, "area_id": None,
"categories": {}, "categories": {},
"config_entry_id": None, "config_entry_id": None,
"config_subentry_id": None,
"created_at": utcnow().timestamp(), "created_at": utcnow().timestamp(),
"device_id": None, "device_id": None,
"disabled_by": None, "disabled_by": None,
@ -138,6 +140,7 @@ async def test_list_entities(
"area_id": None, "area_id": None,
"categories": {}, "categories": {},
"config_entry_id": None, "config_entry_id": None,
"config_subentry_id": None,
"created_at": utcnow().timestamp(), "created_at": utcnow().timestamp(),
"device_id": None, "device_id": None,
"disabled_by": None, "disabled_by": None,
@ -374,6 +377,7 @@ async def test_get_entity(hass: HomeAssistant, client: MockHAClientWebSocket) ->
"capabilities": None, "capabilities": None,
"categories": {}, "categories": {},
"config_entry_id": None, "config_entry_id": None,
"config_subentry_id": None,
"created_at": name_created_at.timestamp(), "created_at": name_created_at.timestamp(),
"device_class": None, "device_class": None,
"device_id": None, "device_id": None,
@ -410,6 +414,7 @@ async def test_get_entity(hass: HomeAssistant, client: MockHAClientWebSocket) ->
"capabilities": None, "capabilities": None,
"categories": {}, "categories": {},
"config_entry_id": None, "config_entry_id": None,
"config_subentry_id": None,
"created_at": no_name_created_at.timestamp(), "created_at": no_name_created_at.timestamp(),
"device_class": None, "device_class": None,
"device_id": None, "device_id": None,
@ -477,6 +482,7 @@ async def test_get_entities(hass: HomeAssistant, client: MockHAClientWebSocket)
"capabilities": None, "capabilities": None,
"categories": {}, "categories": {},
"config_entry_id": None, "config_entry_id": None,
"config_subentry_id": None,
"created_at": name_created_at.timestamp(), "created_at": name_created_at.timestamp(),
"device_class": None, "device_class": None,
"device_id": None, "device_id": None,
@ -504,6 +510,7 @@ async def test_get_entities(hass: HomeAssistant, client: MockHAClientWebSocket)
"capabilities": None, "capabilities": None,
"categories": {}, "categories": {},
"config_entry_id": None, "config_entry_id": None,
"config_subentry_id": None,
"created_at": no_name_created_at.timestamp(), "created_at": no_name_created_at.timestamp(),
"device_class": None, "device_class": None,
"device_id": None, "device_id": None,
@ -586,6 +593,7 @@ async def test_update_entity(
"categories": {"scope1": "id", "scope2": "id"}, "categories": {"scope1": "id", "scope2": "id"},
"created_at": created.timestamp(), "created_at": created.timestamp(),
"config_entry_id": None, "config_entry_id": None,
"config_subentry_id": None,
"device_class": "custom_device_class", "device_class": "custom_device_class",
"device_id": None, "device_id": None,
"disabled_by": None, "disabled_by": None,
@ -668,6 +676,7 @@ async def test_update_entity(
"capabilities": None, "capabilities": None,
"categories": {"scope1": "id", "scope2": "id"}, "categories": {"scope1": "id", "scope2": "id"},
"config_entry_id": None, "config_entry_id": None,
"config_subentry_id": None,
"created_at": created.timestamp(), "created_at": created.timestamp(),
"device_class": "custom_device_class", "device_class": "custom_device_class",
"device_id": None, "device_id": None,
@ -714,6 +723,7 @@ async def test_update_entity(
"capabilities": None, "capabilities": None,
"categories": {"scope1": "id", "scope2": "id"}, "categories": {"scope1": "id", "scope2": "id"},
"config_entry_id": None, "config_entry_id": None,
"config_subentry_id": None,
"created_at": created.timestamp(), "created_at": created.timestamp(),
"device_class": "custom_device_class", "device_class": "custom_device_class",
"device_id": None, "device_id": None,
@ -759,6 +769,7 @@ async def test_update_entity(
"capabilities": None, "capabilities": None,
"categories": {"scope1": "id", "scope2": "id", "scope3": "id"}, "categories": {"scope1": "id", "scope2": "id", "scope3": "id"},
"config_entry_id": None, "config_entry_id": None,
"config_subentry_id": None,
"created_at": created.timestamp(), "created_at": created.timestamp(),
"device_class": "custom_device_class", "device_class": "custom_device_class",
"device_id": None, "device_id": None,
@ -804,6 +815,7 @@ async def test_update_entity(
"capabilities": None, "capabilities": None,
"categories": {"scope1": "id", "scope2": "id", "scope3": "other_id"}, "categories": {"scope1": "id", "scope2": "id", "scope3": "other_id"},
"config_entry_id": None, "config_entry_id": None,
"config_subentry_id": None,
"created_at": created.timestamp(), "created_at": created.timestamp(),
"device_class": "custom_device_class", "device_class": "custom_device_class",
"device_id": None, "device_id": None,
@ -849,6 +861,7 @@ async def test_update_entity(
"capabilities": None, "capabilities": None,
"categories": {"scope1": "id", "scope3": "other_id"}, "categories": {"scope1": "id", "scope3": "other_id"},
"config_entry_id": None, "config_entry_id": None,
"config_subentry_id": None,
"created_at": created.timestamp(), "created_at": created.timestamp(),
"device_class": "custom_device_class", "device_class": "custom_device_class",
"device_id": None, "device_id": None,
@ -911,6 +924,7 @@ async def test_update_entity_require_restart(
"capabilities": None, "capabilities": None,
"categories": {}, "categories": {},
"config_entry_id": config_entry.entry_id, "config_entry_id": config_entry.entry_id,
"config_subentry_id": None,
"created_at": created.timestamp(), "created_at": created.timestamp(),
"device_class": None, "device_class": None,
"device_id": None, "device_id": None,
@ -1032,6 +1046,7 @@ async def test_update_entity_no_changes(
"capabilities": None, "capabilities": None,
"categories": {}, "categories": {},
"config_entry_id": None, "config_entry_id": None,
"config_subentry_id": None,
"created_at": created.timestamp(), "created_at": created.timestamp(),
"device_class": None, "device_class": None,
"device_id": None, "device_id": None,
@ -1129,6 +1144,7 @@ async def test_update_entity_id(
"capabilities": None, "capabilities": None,
"categories": {}, "categories": {},
"config_entry_id": None, "config_entry_id": None,
"config_subentry_id": None,
"created_at": created.timestamp(), "created_at": created.timestamp(),
"device_class": None, "device_class": None,
"device_id": None, "device_id": None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -12,6 +12,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -64,6 +65,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -53,6 +54,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -10,6 +10,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -66,6 +67,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -121,6 +123,7 @@
]), ]),
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -55,6 +56,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -103,6 +105,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -150,6 +153,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -197,6 +201,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -247,6 +252,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -294,6 +300,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -341,6 +348,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -389,6 +397,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -436,6 +445,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -484,6 +494,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -531,6 +542,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -578,6 +590,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -627,6 +640,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -676,6 +690,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -725,6 +740,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -772,6 +788,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -819,6 +836,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -875,6 +893,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -925,6 +944,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -972,6 +992,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

View File

@ -6,6 +6,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,
@ -53,6 +54,7 @@
'area_id': None, 'area_id': None,
'capabilities': None, 'capabilities': None,
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None, 'device_class': None,
'device_id': <ANY>, 'device_id': <ANY>,
'disabled_by': None, 'disabled_by': None,

Some files were not shown because too many files have changed in this diff Show More