Add HAOS-Server sync for optional centralized management (Phase 5)
Some checks failed
Validate / Hassfest (push) Has been cancelled

Enable the HAOS integration to optionally connect to the standalone
Immich Watcher server for config sync and event reporting.

Server-side:
- New /api/sync/* endpoints: GET trackers, POST template render,
  POST event report
- API key auth via X-API-Key header (accepts JWT access tokens)

Integration-side:
- New sync.py: ServerSyncClient with graceful error handling
  (all methods return defaults on connection failure)
- Options flow: optional server_url and server_api_key fields
  with connection validation
- Coordinator: fire-and-forget event reporting to server when
  album changes are detected
- Translations: en.json and ru.json updated with new fields

The connection is fully additive -- the integration works identically
without a server URL configured. Server failures never break HA.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-19 14:10:29 +03:00
parent 2b487707ce
commit ab1c7ac0db
11 changed files with 441 additions and 20 deletions

View File

@@ -18,6 +18,8 @@ from .const import (
CONF_HUB_NAME,
CONF_IMMICH_URL,
CONF_SCAN_INTERVAL,
CONF_SERVER_API_KEY,
CONF_SERVER_URL,
CONF_TELEGRAM_CACHE_TTL,
DEFAULT_SCAN_INTERVAL,
DEFAULT_TELEGRAM_CACHE_TTL,
@@ -98,6 +100,15 @@ async def async_setup_entry(hass: HomeAssistant, entry: ImmichConfigEntry) -> bo
notification_queue = create_notification_queue(hass, entry.entry_id)
await notification_queue.async_load()
# Create optional server sync client
server_url = entry.options.get(CONF_SERVER_URL, "")
server_api_key = entry.options.get(CONF_SERVER_API_KEY, "")
sync_client = None
if server_url and server_api_key:
from .sync import ServerSyncClient
sync_client = ServerSyncClient(hass, server_url, server_api_key)
_LOGGER.info("Server sync enabled: %s", server_url)
# Store hub reference
hass.data[DOMAIN][entry.entry_id] = {
"hub": entry.runtime_data,
@@ -106,6 +117,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ImmichConfigEntry) -> bo
"telegram_cache": telegram_cache,
"telegram_asset_cache": telegram_asset_cache,
"notification_queue": notification_queue,
"sync_client": sync_client,
"quiet_hours_unsubs": {}, # keyed by "HH:MM" end time
}
@@ -161,6 +173,7 @@ async def _async_setup_subentry_coordinator(
storage=storage,
telegram_cache=telegram_cache,
telegram_asset_cache=telegram_asset_cache,
sync_client=hass.data[DOMAIN][entry.entry_id].get("sync_client"),
)
# Load persisted state before first refresh to detect changes during downtime