Move quiet hours from hub config to per-call service params
All checks were successful
Validate / Hassfest (push) Successful in 1m19s

Quiet hours are now specified per send_telegram_notification call via
quiet_hours_start/quiet_hours_end params instead of being a hub-wide
integration option. This allows different automations to use different
quiet hours windows (or none at all).

- Remove quiet_hours_start/end from config options UI and const.py
- Add quiet_hours_start/end as optional HH:MM params on the service
- Remove ignore_quiet_hours param (omit quiet hours params to send immediately)
- Queue stores quiet_hours_end per item; each unique end time gets its
  own async_track_time_change timer for replay
- On startup, items whose quiet hours have passed are sent immediately
- Add async_remove_indices() to NotificationQueue for selective removal
- Timers are cleaned up when no more items need them

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-19 12:04:20 +03:00
parent 678e8a6e62
commit 71b79cd919
8 changed files with 193 additions and 155 deletions

View File

@@ -25,8 +25,6 @@ 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,
@@ -247,26 +245,6 @@ 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={
@@ -279,8 +257,6 @@ 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,
},
)
@@ -300,12 +276,6 @@ 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 vol.Schema(
{
@@ -318,12 +288,6 @@ class ImmichAlbumWatcherOptionsFlow(OptionsFlow):
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,
}
)