Implement hub and subenty approach based on telegram bot integration implementation

This commit is contained in:
2026-01-30 02:39:59 +03:00
parent c8bd475a52
commit 60573374a4
11 changed files with 549 additions and 426 deletions

View File

@@ -9,18 +9,18 @@ from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.config_entries import ConfigEntry, ConfigSubentry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.device_registry import DeviceEntryType
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import (
ATTR_ADDED_COUNT,
ATTR_ALBUM_ID,
ATTR_ALBUM_NAME,
CONF_ALBUMS,
CONF_ALBUM_ID,
CONF_ALBUM_NAME,
DOMAIN,
NEW_ASSETS_RESET_DELAY,
)
@@ -35,15 +35,19 @@ async def async_setup_entry(
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up Immich Album Watcher binary sensors from a config entry."""
coordinator: ImmichAlbumWatcherCoordinator = hass.data[DOMAIN][entry.entry_id]
album_ids = entry.options.get(CONF_ALBUMS, [])
# Iterate through all album subentries
for subentry_id, subentry in entry.subentries.items():
subentry_data = hass.data[DOMAIN][entry.entry_id]["subentries"].get(subentry_id)
if not subentry_data:
_LOGGER.error("Subentry data not found for %s", subentry_id)
continue
entities = [
ImmichAlbumNewAssetsSensor(coordinator, entry, album_id)
for album_id in album_ids
]
coordinator = subentry_data.coordinator
async_add_entities(entities)
async_add_entities(
[ImmichAlbumNewAssetsSensor(coordinator, entry, subentry)],
config_subentry_id=subentry_id,
)
class ImmichAlbumNewAssetsSensor(
@@ -59,28 +63,27 @@ class ImmichAlbumNewAssetsSensor(
self,
coordinator: ImmichAlbumWatcherCoordinator,
entry: ConfigEntry,
album_id: str,
subentry: ConfigSubentry,
) -> None:
"""Initialize the binary sensor."""
super().__init__(coordinator)
self._album_id = album_id
self._entry = entry
self._attr_unique_id = f"{entry.entry_id}_{album_id}_new_assets"
self._reset_unsub = None
self._subentry = subentry
self._album_id = subentry.data[CONF_ALBUM_ID]
self._album_name = subentry.data.get(CONF_ALBUM_NAME, "Unknown Album")
self._attr_unique_id = f"{subentry.subentry_id}_new_assets"
@property
def _album_data(self) -> AlbumData | None:
"""Get the album data from coordinator."""
if self.coordinator.data is None:
return None
return self.coordinator.data.get(self._album_id)
return self.coordinator.data
@property
def translation_placeholders(self) -> dict[str, str]:
"""Return translation placeholders."""
if self._album_data:
return {"album_name": self._album_data.name}
return {"album_name": f"Album {self._album_id[:8]}"}
return {"album_name": self._album_name}
@property
def is_on(self) -> bool | None:
@@ -96,7 +99,7 @@ class ImmichAlbumNewAssetsSensor(
elapsed = datetime.now() - self._album_data.last_change_time
if elapsed > timedelta(seconds=NEW_ASSETS_RESET_DELAY):
# Auto-reset the flag
self.coordinator.clear_new_assets_flag(self._album_id)
self.coordinator.clear_new_assets_flag()
return False
return True
@@ -124,12 +127,13 @@ class ImmichAlbumNewAssetsSensor(
@property
def device_info(self) -> DeviceInfo:
"""Return device info."""
"""Return device info - one device per album."""
return DeviceInfo(
identifiers={(DOMAIN, self._entry.entry_id)},
name="Immich Album Watcher",
identifiers={(DOMAIN, self._subentry.subentry_id)},
name=self._album_name,
manufacturer="Immich",
entry_type="service",
entry_type=DeviceEntryType.SERVICE,
via_device=(DOMAIN, self._entry.entry_id),
)
@callback
@@ -139,5 +143,5 @@ class ImmichAlbumNewAssetsSensor(
async def async_turn_off(self, **kwargs) -> None:
"""Turn off the sensor (clear new assets flag)."""
self.coordinator.clear_new_assets_flag(self._album_id)
self.coordinator.clear_new_assets_flag()
self.async_write_ha_state()