From 1aabd00ebfa060de225472615304d784acceccc6 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Sat, 13 Jan 2024 09:54:42 +0100 Subject: [PATCH] Detect unknown source used in trend helpers (#560) --- .../spook/ectoplasms/trend/__init__.py | 1 + .../ectoplasms/trend/repairs/__init__.py | 1 + .../trend/repairs/unknown_source.py | 71 +++++++++++++++++++ custom_components/spook/translations/en.json | 4 ++ documentation/_toc.yml | 1 + documentation/enhanced_integrations.md | 5 ++ documentation/integrations/trend.md | 41 +++++++++++ 7 files changed, 124 insertions(+) create mode 100644 custom_components/spook/ectoplasms/trend/__init__.py create mode 100644 custom_components/spook/ectoplasms/trend/repairs/__init__.py create mode 100644 custom_components/spook/ectoplasms/trend/repairs/unknown_source.py create mode 100644 documentation/integrations/trend.md diff --git a/custom_components/spook/ectoplasms/trend/__init__.py b/custom_components/spook/ectoplasms/trend/__init__.py new file mode 100644 index 00000000..f673d532 --- /dev/null +++ b/custom_components/spook/ectoplasms/trend/__init__.py @@ -0,0 +1 @@ +"""Spook - Not your homie.""" diff --git a/custom_components/spook/ectoplasms/trend/repairs/__init__.py b/custom_components/spook/ectoplasms/trend/repairs/__init__.py new file mode 100644 index 00000000..f673d532 --- /dev/null +++ b/custom_components/spook/ectoplasms/trend/repairs/__init__.py @@ -0,0 +1 @@ +"""Spook - Not your homie.""" diff --git a/custom_components/spook/ectoplasms/trend/repairs/unknown_source.py b/custom_components/spook/ectoplasms/trend/repairs/unknown_source.py new file mode 100644 index 00000000..fbfd6e08 --- /dev/null +++ b/custom_components/spook/ectoplasms/trend/repairs/unknown_source.py @@ -0,0 +1,71 @@ +"""Spook - Not your homie.""" +from __future__ import annotations + +from homeassistant.components import binary_sensor +from homeassistant.const import EVENT_COMPONENT_LOADED +from homeassistant.helpers import entity_registry as er +from homeassistant.helpers.entity_platform import DATA_ENTITY_PLATFORM, EntityPlatform + +from ....const import LOGGER +from ....repairs import AbstractSpookRepair + + +class SpookRepair(AbstractSpookRepair): + """Spook repair tries to find unknown source entites for trend sensors.""" + + domain = "trend" + repair = "trend_unknown_source" + inspect_events = { + EVENT_COMPONENT_LOADED, + er.EVENT_ENTITY_REGISTRY_UPDATED, + } + inspect_on_reload = "trend" + + _issues: set[str] = set() + + async def async_inspect(self) -> None: + """Trigger a inspection.""" + LOGGER.debug("Spook is inspecting: %s", self.repair) + + platforms: list[EntityPlatform] | None + if not (platforms := self.hass.data[DATA_ENTITY_PLATFORM].get(self.domain)): + return # Nothing to do. + + entity_ids = { + entity.entity_id for entity in self.entity_registry.entities.values() + }.union(self.hass.states.async_entity_ids()) + + possible_issue_ids: set[str] = set() + for platform in platforms: + # We only care about the binary sensor domain + if platform.domain != binary_sensor.DOMAIN: + continue + + for entity in platform.entities.values(): + possible_issue_ids.add(entity.entity_id) + # pylint: disable-next=protected-access + source = entity._entity_id # noqa: SLF001 + if source not in entity_ids: + self.async_create_issue( + issue_id=entity.entity_id, + translation_placeholders={ + "entity_id": entity.entity_id, + "helper": entity.name, + "source": source, + }, + ) + self._issues.add(entity.entity_id) + LOGGER.debug( + "Spook found unknown source entity %s in %s " + "and created an issue for it", + source, + entity.entity_id, + ) + else: + self.async_delete_issue(entity.entity_id) + self._issues.add(entity.entity_id) + + # Remove issues that are no longer valid + for issue_id in self._issues - possible_issue_ids: + self.async_delete_issue(issue_id) + self._issues.discard(issue_id) diff --git a/custom_components/spook/translations/en.json b/custom_components/spook/translations/en.json index 6f4fbe3c..93e41cbf 100644 --- a/custom_components/spook/translations/en.json +++ b/custom_components/spook/translations/en.json @@ -269,6 +269,10 @@ "description": "Spook has found a ghost in your utility meter helpers 👻\n\nWhile floating around, Spook crossed path with the following helper:\n\n{helper} (`{entity_id}`)\n\nThis helper has a source entity unknown to Home Assistant:\n\n`{source}`\n\n\n\nTo fix this error, edit the helper and adjust the source entity (or remove the helper) and restart Home Assistant.\n\nSpook 👻 Not your homie.", "title": "Unknown source: {helper}" }, + "trend_unknown_source": { + "description": "Spook has found a ghost in your trend helpers 👻\n\nWhile floating around, Spook crossed path with the following helper:\n\n{helper} (`{entity_id}`)\n\nThis helper has a source entity unknown to Home Assistant:\n\n`{source}`\n\n\n\nTo fix this error, edit the helper and adjust the source entity (or remove the helper) and restart Home Assistant.\n\nSpook 👻 Not your homie.", + "title": "Unknown source: {helper}" + }, "user_issue": { "fix_flow": { "step": { diff --git a/documentation/_toc.yml b/documentation/_toc.yml index d6bd888f..fa4e9ad7 100644 --- a/documentation/_toc.yml +++ b/documentation/_toc.yml @@ -55,6 +55,7 @@ parts: - file: integrations/select - file: integrations/switch_as_x - file: integrations/timer + - file: integrations/trend - file: integrations/utility_meter - file: integrations/zone diff --git a/documentation/enhanced_integrations.md b/documentation/enhanced_integrations.md index f8a16826..2b0285c8 100644 --- a/documentation/enhanced_integrations.md +++ b/documentation/enhanced_integrations.md @@ -100,6 +100,11 @@ Spook enhances the following {term}`Home Assistant` {term}`integrations
+ +The trend {term}`helper ` integration show the trend of a numeric value over time. It does so by tracking the state of a source entity, such as a sensor, and calculating the trend based on the difference between the current and previous state. + +## Devices & entities + +Spook does not provide any new devices or entities for this integration. + +## Services + +Spook does not provide service enhancements for this integration. + +## Repairs + +While Spook is floating around in your Home Assistant instance, it will raise repairs issues if it has found something that is not right. + +### Unknown source entity + +Spook inspects all trend sensors created to find source entities they meter that no longer exist. If Spook finds such a case, it will raise a repair issue, informing you about the problematic trend helper and the source entity that is missing. + +To resolve the raised issue, you can either remove the trend helper or restore the referenced source entity. Spook will automatically remove the repair issue once the issue is fixed. + +## Features requests, ideas, and support + +If you have an idea on how to further enhance this integration, for example, by adding a new service, entity, or repairs detection; feel free to [let us know in our discussion forums](https://github.com/frenck/spook/discussions). + +Are you stuck using these new features? Or maybe you've run into a bug? Please check the [](../support) page on where to go for help.