1
0
mirror of https://github.com/home-assistant/core.git synced 2026-04-02 00:20:30 +01:00

Add common entity_entry_as_dict util to diagnostics (#165692)

This commit is contained in:
Artur Pragacz
2026-03-16 18:16:13 +01:00
committed by GitHub
parent e7c3a62569
commit 6f746c4375
7 changed files with 78 additions and 10 deletions

View File

@@ -38,9 +38,9 @@ from homeassistant.util.hass_dict import HassKey
from homeassistant.util.json import format_unserializable_data
from .const import DOMAIN, REDACTED, DiagnosticsSubType, DiagnosticsType
from .util import async_redact_data
from .util import async_redact_data, entity_entry_as_dict
__all__ = ["REDACTED", "async_redact_data"]
__all__ = ["REDACTED", "async_redact_data", "entity_entry_as_dict"]
_LOGGER = logging.getLogger(__name__)

View File

@@ -5,7 +5,10 @@ from __future__ import annotations
from collections.abc import Iterable, Mapping
from typing import Any, cast, overload
import attr
from homeassistant.core import callback
from homeassistant.helpers.entity_registry import RegistryEntry
from .const import REDACTED
@@ -42,3 +45,16 @@ def async_redact_data[_T](data: _T, to_redact: Iterable[Any]) -> _T:
redacted[key] = [async_redact_data(item, to_redact) for item in value]
return cast(_T, redacted)
def _entity_entry_filter(a: attr.Attribute, _: Any) -> bool:
return a.name != "_cache"
@callback
def entity_entry_as_dict(entry: RegistryEntry) -> dict[str, Any]:
"""Convert an entity registry entry to a dict for diagnostics.
This excludes internal fields that should not be exposed in diagnostics.
"""
return attr.asdict(entry, filter=_entity_entry_filter)

View File

@@ -11,7 +11,7 @@ from attr import asdict
from pyenphase.envoy import Envoy
from pyenphase.exceptions import EnvoyError
from homeassistant.components.diagnostics import async_redact_data
from homeassistant.components.diagnostics import async_redact_data, entity_entry_as_dict
from homeassistant.const import (
CONF_NAME,
CONF_PASSWORD,
@@ -111,8 +111,7 @@ async def async_get_config_entry_diagnostics(
if state := hass.states.get(entity.entity_id):
state_dict = dict(state.as_dict())
state_dict.pop("context", None)
entity_dict = asdict(entity)
entity_dict.pop("_cache", None)
entity_dict = entity_entry_as_dict(entity)
entities.append({"entity": entity_dict, "state": state_dict})
device_dict = asdict(device)
device_dict.pop("_cache", None)

View File

@@ -6,6 +6,7 @@ from typing import Any
from attr import asdict
from homeassistant.components.diagnostics import entity_entry_as_dict
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
@@ -44,7 +45,9 @@ async def async_get_config_entry_diagnostics(
state_dict = dict(state.as_dict())
state_dict.pop("context", None)
entities.append({"entry": asdict(entity_entry), "state": state_dict})
entities.append(
{"entry": entity_entry_as_dict(entity_entry), "state": state_dict}
)
devices.append({"device": asdict(device), "entities": entities})

View File

@@ -7,7 +7,7 @@ from typing import Any
import attr
from homeassistant.components.diagnostics import async_redact_data
from homeassistant.components.diagnostics import async_redact_data, entity_entry_as_dict
from homeassistant.const import ATTR_CONFIGURATION_URL, CONF_HOST
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import device_registry as dr, entity_registry as er
@@ -94,7 +94,7 @@ def _async_device_as_dict(hass: HomeAssistant, device: DeviceEntry) -> dict[str,
state_dict = dict(state.as_dict())
state_dict.pop("context", None)
entity = attr.asdict(entity_entry)
entity = entity_entry_as_dict(entity_entry)
entity["state"] = state_dict
entities.append(entity)

View File

@@ -6,6 +6,7 @@ from typing import Any
from attr import asdict
from homeassistant.components.diagnostics import entity_entry_as_dict
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
@@ -42,7 +43,9 @@ async def async_get_config_entry_diagnostics(
state_dict = dict(state.as_dict())
state_dict.pop("context", None)
entities.append({"entry": asdict(entity), "state": state_dict})
entities.append(
{"entry": entity_entry_as_dict(entity), "state": state_dict}
)
devices.append({"device": asdict(device), "entities": entities})

View File

@@ -1,6 +1,13 @@
"""Test Diagnostics utils."""
from homeassistant.components.diagnostics import REDACTED, async_redact_data
from datetime import datetime
from homeassistant.components.diagnostics import (
REDACTED,
async_redact_data,
entity_entry_as_dict,
)
from homeassistant.helpers.entity_registry import RegistryEntry
def test_redact() -> None:
@@ -41,3 +48,43 @@ def test_redact() -> None:
"key6": "",
"key7": REDACTED,
}
def test_entity_entry_as_dict() -> None:
"""Test entity_entry_as_dict."""
created = datetime.fromisoformat("2024-01-01T00:00:00+00:00")
entry = RegistryEntry(
entity_id="sensor.test_sensor",
unique_id="unique123",
platform="test",
capabilities=None,
config_entry_id=None,
config_subentry_id=None,
created_at=created,
device_id=None,
disabled_by=None,
entity_category=None,
has_entity_name=False,
hidden_by=None,
id=None,
options=None,
original_device_class=None,
original_icon=None,
original_name="Test Sensor",
object_id_base=None,
suggested_object_id=None,
supported_features=0,
translation_key=None,
unit_of_measurement=None,
)
result = entity_entry_as_dict(entry)
assert isinstance(result, dict)
assert "_cache" not in result
assert result["entity_id"] == "sensor.test_sensor"
assert result["unique_id"] == "unique123"
assert result["platform"] == "test"
assert result["original_name"] == "Test Sensor"
assert result["supported_features"] == 0
assert result["created_at"] == created