Updated apps
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
"""Text entity for Watchman ignored labels."""
|
||||
from homeassistant.components.text import TextEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import issue_registry as ir, label_registry as lr
|
||||
from homeassistant.helpers.entity import EntityCategory
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.restore_state import RestoreEntity
|
||||
|
||||
from .const import CONF_IGNORED_LABELS, DOMAIN
|
||||
from .coordinator import WatchmanCoordinator
|
||||
|
||||
|
||||
class WatchmanIgnoredLabelsText(RestoreEntity, TextEntity):
|
||||
"""Text entity to manage ignored labels."""
|
||||
|
||||
_attr_has_entity_name = True
|
||||
_attr_translation_key = "ignored_labels"
|
||||
_attr_icon = "mdi:label-off"
|
||||
|
||||
def __init__(self, hass: HomeAssistant, coordinator: WatchmanCoordinator) -> None:
|
||||
"""Initialize the entity."""
|
||||
self.hass = hass
|
||||
self.coordinator = coordinator
|
||||
self._attr_unique_id = f"{DOMAIN}_ignored_labels"
|
||||
self.entity_id = f"text.{DOMAIN}_ignored_labels"
|
||||
self._attr_native_value = ""
|
||||
# Orphan entity: No device_info, so it won't appear on the device page
|
||||
|
||||
@property
|
||||
def native_value(self) -> str:
|
||||
"""Return the value of the text entity."""
|
||||
labels = self.coordinator.config_entry.data.get(CONF_IGNORED_LABELS, [])
|
||||
return ", ".join(labels)
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Handle entity which will be added."""
|
||||
await super().async_added_to_hass()
|
||||
|
||||
# Migration: Restore state to config entry if key is missing
|
||||
if CONF_IGNORED_LABELS not in self.coordinator.config_entry.data:
|
||||
if (state := await self.async_get_last_state()) is not None:
|
||||
restored_labels = self._parse_labels(state.state)
|
||||
if restored_labels:
|
||||
self.hass.config_entries.async_update_entry(
|
||||
self.coordinator.config_entry,
|
||||
data={**self.coordinator.config_entry.data, CONF_IGNORED_LABELS: restored_labels}
|
||||
)
|
||||
else:
|
||||
# If no restored state, initialize key to empty list to mark migration done
|
||||
self.hass.config_entries.async_update_entry(
|
||||
self.coordinator.config_entry,
|
||||
data={**self.coordinator.config_entry.data, CONF_IGNORED_LABELS: []}
|
||||
)
|
||||
|
||||
async def async_set_value(self, value: str) -> None:
|
||||
"""Set the text value."""
|
||||
# Create deprecation issue
|
||||
ir.async_create_issue(
|
||||
self.hass,
|
||||
DOMAIN,
|
||||
"deprecated_ignored_labels_entity",
|
||||
is_fixable=False,
|
||||
severity=ir.IssueSeverity.WARNING,
|
||||
translation_key="deprecated_text_entity",
|
||||
translation_placeholders={
|
||||
"entity_id": self.entity_id,
|
||||
},
|
||||
)
|
||||
|
||||
valid_labels, invalid_labels = self._validate_labels(value)
|
||||
|
||||
if invalid_labels:
|
||||
await self.hass.services.async_call(
|
||||
"persistent_notification",
|
||||
"create",
|
||||
{
|
||||
"title": "Watchman: Invalid Labels",
|
||||
"message": f"The following labels were not found and ignored: {', '.join(invalid_labels)}",
|
||||
"notification_id": "watchman_invalid_labels",
|
||||
},
|
||||
)
|
||||
|
||||
# Save to config entry (triggers reload)
|
||||
self.hass.config_entries.async_update_entry(
|
||||
self.coordinator.config_entry,
|
||||
data={**self.coordinator.config_entry.data, CONF_IGNORED_LABELS: valid_labels}
|
||||
)
|
||||
|
||||
def _parse_labels(self, value: str) -> list[str]:
|
||||
"""Parse comma-separated string to list."""
|
||||
if not value:
|
||||
return []
|
||||
return [x.strip() for x in value.split(",") if x.strip()]
|
||||
|
||||
def _validate_labels(self, value: str) -> tuple[list[str], list[str]]:
|
||||
"""Validate labels against registry."""
|
||||
registry = lr.async_get(self.hass)
|
||||
existing_labels = {l.label_id for l in registry.async_list_labels()}
|
||||
|
||||
input_labels = self._parse_labels(value)
|
||||
valid = []
|
||||
invalid = []
|
||||
|
||||
for label in input_labels:
|
||||
if label in existing_labels:
|
||||
valid.append(label)
|
||||
else:
|
||||
invalid.append(label)
|
||||
|
||||
return valid, invalid
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the text platform."""
|
||||
coordinator = config_entry.runtime_data.coordinator
|
||||
async_add_entities([WatchmanIgnoredLabelsText(hass, coordinator)])
|
||||
Reference in New Issue
Block a user