Add quiet hours, fix Telegram bugs, and improve cache performance
All checks were successful
Validate / Hassfest (push) Successful in 5s

- Add quiet hours support to queue notifications during configured time windows
- Fix UnboundLocalError when single-item document chunk exceeds max_asset_data_size
- Fix document-only multi-item chunks being silently dropped (missing skip guard)
- Fix notification queue entity lookup by storing entity_id in queued params
- Fix quiet hours using OS timezone instead of HA-configured timezone (dt_util.now)
- Fix chat_action schema rejecting empty string from "Disabled" selector
- Fix stale thumbhash cache entries not being removed on mismatch
- Fix translation descriptions for send_large_photos_as_documents
- Add batch async_set_many() to TelegramFileCache to reduce disk writes
- Add max-entries eviction (2000) for thumbhash cache to prevent unbounded growth
- Eliminate redundant _is_asset_id/get_asset_thumbhash lookups in media group loop

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-09 09:45:34 +03:00
parent dd7032b411
commit 678e8a6e62
8 changed files with 437 additions and 52 deletions

View File

@@ -25,6 +25,8 @@ from .const import (
CONF_API_KEY,
CONF_HUB_NAME,
CONF_IMMICH_URL,
CONF_QUIET_HOURS_END,
CONF_QUIET_HOURS_START,
CONF_SCAN_INTERVAL,
CONF_TELEGRAM_BOT_TOKEN,
CONF_TELEGRAM_CACHE_TTL,
@@ -245,6 +247,26 @@ class ImmichAlbumWatcherOptionsFlow(OptionsFlow):
) -> ConfigFlowResult:
"""Manage the options."""
if user_input is not None:
errors: dict[str, str] = {}
quiet_start = user_input.get(CONF_QUIET_HOURS_START, "")
quiet_end = user_input.get(CONF_QUIET_HOURS_END, "")
import re
time_pattern = re.compile(r"^(\d{2}:\d{2})?$")
if quiet_start and not time_pattern.match(quiet_start):
errors[CONF_QUIET_HOURS_START] = "invalid_time_format"
if quiet_end and not time_pattern.match(quiet_end):
errors[CONF_QUIET_HOURS_END] = "invalid_time_format"
if (quiet_start and not quiet_end) or (quiet_end and not quiet_start):
errors["base"] = "quiet_hours_incomplete"
if errors:
return self.async_show_form(
step_id="init",
data_schema=self._build_options_schema(),
errors=errors,
)
return self.async_create_entry(
title="",
data={
@@ -257,9 +279,18 @@ class ImmichAlbumWatcherOptionsFlow(OptionsFlow):
CONF_TELEGRAM_CACHE_TTL: user_input.get(
CONF_TELEGRAM_CACHE_TTL, DEFAULT_TELEGRAM_CACHE_TTL
),
CONF_QUIET_HOURS_START: quiet_start,
CONF_QUIET_HOURS_END: quiet_end,
},
)
return self.async_show_form(
step_id="init",
data_schema=self._build_options_schema(),
)
def _build_options_schema(self) -> vol.Schema:
"""Build the options form schema."""
current_interval = self._config_entry.options.get(
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
)
@@ -269,22 +300,31 @@ class ImmichAlbumWatcherOptionsFlow(OptionsFlow):
current_cache_ttl = self._config_entry.options.get(
CONF_TELEGRAM_CACHE_TTL, DEFAULT_TELEGRAM_CACHE_TTL
)
current_quiet_start = self._config_entry.options.get(
CONF_QUIET_HOURS_START, ""
)
current_quiet_end = self._config_entry.options.get(
CONF_QUIET_HOURS_END, ""
)
return self.async_show_form(
step_id="init",
data_schema=vol.Schema(
{
vol.Required(
CONF_SCAN_INTERVAL, default=current_interval
): vol.All(vol.Coerce(int), vol.Range(min=10, max=3600)),
vol.Optional(
CONF_TELEGRAM_BOT_TOKEN, default=current_bot_token
): str,
vol.Optional(
CONF_TELEGRAM_CACHE_TTL, default=current_cache_ttl
): vol.All(vol.Coerce(int), vol.Range(min=1, max=168)),
}
),
return vol.Schema(
{
vol.Required(
CONF_SCAN_INTERVAL, default=current_interval
): vol.All(vol.Coerce(int), vol.Range(min=10, max=3600)),
vol.Optional(
CONF_TELEGRAM_BOT_TOKEN, default=current_bot_token
): str,
vol.Optional(
CONF_TELEGRAM_CACHE_TTL, default=current_cache_ttl
): vol.All(vol.Coerce(int), vol.Range(min=1, max=168)),
vol.Optional(
CONF_QUIET_HOURS_START, default=current_quiet_start
): str,
vol.Optional(
CONF_QUIET_HOURS_END, default=current_quiet_end
): str,
}
)