Several minor updates to the existing blueprints

This commit is contained in:
2026-02-28 22:10:11 +03:00
parent eefc8993e3
commit 4c03bc849e
5 changed files with 162 additions and 27 deletions

View File

@@ -275,9 +275,14 @@ variables:
# CONDITIONS
# =============================================================================
condition:
# Only process events from the configured vacuum entity
# Only process events from the configured vacuum entity.
# The Dreame Vacuum integration uses generate_entity_id() for the entity_id
# in event data, which may append a numeric suffix (e.g., _2) since the
# actual vacuum entity already occupies the base entity_id.
- condition: template
value_template: "{{ event_entity_id == vacuum_entity }}"
value_template: >
{{ event_entity_id == vacuum_entity
or event_entity_id.startswith(vacuum_entity ~ '_') }}
# =============================================================================
# ACTIONS

View File

@@ -4,8 +4,7 @@ This blueprint monitors Immich album changes and sends notifications when assets
## Features
- Filter by hub/instance name (for multi-hub setups)
- Monitor specific albums by name (whitelist)
- Monitor specific albums by ID (whitelist)
- Filter by asset type (track images only, videos only, or both)
- Filter by favorites only (only notify about favorite assets)
- Sort assets by date, rating, name, or keep original order
@@ -159,6 +158,8 @@ Select input_text entities containing Telegram chat IDs. Can be user IDs (positi
Sends a summary notification of tracked albums at configured times. Album names and share URLs are automatically read from the Album ID Entity's `album_name` and `share_url` attributes (if available). You can configure multiple notification times (e.g., "12:00, 18:00") using comma-separated 24-hour format with leading zeros.
Use **Summary Interval** to control how often summaries are sent (default: every day). Set it to `7` for weekly, `14` for bi-weekly, etc. The **Summary Start Date** anchors the interval — summaries are sent on that date and every N days after. For example, setting the start date to a Monday with an interval of 7 sends summaries every Monday.
When Telegram media is enabled, an optional image can be attached to the summary message. By default, the official Immich logo is used. Set the **Summary Image URL** to empty to send text-only notifications.
### Summary Message Template Variables

View File

@@ -19,20 +19,9 @@ blueprint:
# Hub & Album Configuration
# -------------------------------------------------------------------------
albums_group:
name: "Hub & Albums"
name: "Albums"
collapsed: false
input:
hub_names:
name: Hub Names to Track
description: >
List of Immich hub/instance names to monitor.
Only events from matching hubs will trigger notifications.
Leave empty to track all hubs.
default: []
selector:
text:
multiple: true
album_id_entities:
name: Album ID Entities
description: >
@@ -489,6 +478,28 @@ blueprint:
selector:
boolean:
periodic_summary_interval:
name: Summary Interval (Days)
description: >
Number of days between periodic summaries.
Set to 1 for daily, 7 for weekly, etc.
default: 1
selector:
number:
min: 1
max: 365
step: 1
mode: box
periodic_summary_start_date:
name: Summary Start Date
description: >
The date from which to start counting the summary interval.
Summaries are sent on this date and every N days after.
default: "2025-01-01"
selector:
date:
periodic_notification_times:
name: Summary Notification Times
description: >
@@ -886,7 +897,7 @@ variables:
# ---------------------------------------------------------------------------
# Input Variables
# ---------------------------------------------------------------------------
hub_names: !input hub_names
album_id_entities: !input album_id_entities
automation_id: !input automation_id
@@ -929,6 +940,8 @@ variables:
# Periodic Summary Settings
enable_periodic_summary: !input enable_periodic_summary
periodic_summary_interval: !input periodic_summary_interval
periodic_summary_start_date: !input periodic_summary_start_date
periodic_summary_message_template: !input periodic_summary_message
periodic_album_template: !input periodic_album_template
periodic_summary_image_url: !input periodic_summary_image_url
@@ -1033,10 +1046,6 @@ variables:
# ---------------------------------------------------------------------------
# Computed Values
# ---------------------------------------------------------------------------
# Check if this hub should be tracked (empty list = track all)
is_hub_tracked: >
{{ hub_names | length == 0 or event_hub_name in hub_names }}
# Check if this album should be tracked (empty list = track all)
is_album_tracked: >
{{ album_ids | length == 0 or event_album_id in album_ids }}
@@ -1249,13 +1258,15 @@ variables:
# ---------------------------------------------------------------------------
# Periodic Summary Variables
# ---------------------------------------------------------------------------
# Check if periodic summary should run (at configured times)
# Manual test event (immich_album_watcher_test_periodic_summary) bypasses time check
# Check if periodic summary should run (at configured times and interval)
# Manual test event (immich_album_watcher_test_periodic_summary) bypasses interval check
# If event data contains automation_id, only matching automations respond
should_send_periodic_summary: >
{% if enable_periodic_summary %}
{% if trigger.id == 'periodic_summary_timer' %}
{{ true }}
{% set start = periodic_summary_start_date | as_datetime %}
{% set days_elapsed = (now().date() - start.date()).days %}
{{ days_elapsed >= 0 and days_elapsed % periodic_summary_interval == 0 }}
{% elif trigger.platform == 'event' and trigger.event.event_type == 'immich_album_watcher_test_periodic_summary' %}
{% set event_automation_id = trigger.event.data.automation_id | default('') %}
{% if event_automation_id | length > 0 %}
@@ -1384,7 +1395,7 @@ condition:
{% elif trigger.platform == 'event' and trigger.event.event_type in ['immich_album_watcher_test_periodic_summary', 'immich_album_watcher_test_scheduled_assets', 'immich_album_watcher_test_memory_mode'] %}
{{ should_send_periodic_summary or should_send_scheduled_assets or should_send_memory_mode }}
{% else %}
{{ is_hub_tracked and is_album_tracked and should_notify }}
{{ is_album_tracked and should_notify }}
{% endif %}
# =============================================================================
@@ -2512,7 +2523,6 @@ action:
- {{ event_people | join(', ') if event_people | length > 0 else '(none)' }}
**Filtering:**
- Is Hub Tracked: {{ is_hub_tracked }}
- Is Album Tracked: {{ is_album_tracked }}
- Should Notify: {{ should_notify }}
- Track Images: {{ track_images }}

View File

@@ -951,6 +951,125 @@ action:
{% set new_automation_state = (automation_state | combine({ state_motion_light_state: automation_state_none })) %}
{{ automation_state_global | combine({ automation_state_key: new_automation_state }) | tojson }}
# Re-evaluate: if an external source turned off the light while
# the automation was actively controlling it, wait briefly and
# re-enable if conditions are still met.
# Safety: state_is_enabled/state_is_enabling reflect the state at
# run start (before reset). When CASE 3 turns off the light, it
# sets state to NONE first, so on restart state_is_none=true and
# this block is skipped — preventing unwanted re-enable.
- choose:
- conditions:
- condition: template
value_template: "{{ state_is_enabled or state_is_enabling }}"
sequence:
# Wait for the off-transition to finish
- delay:
seconds: "{{ transition_duration }}"
# Fresh condition check (evaluates current entity states)
- condition: template
value_template: >
{% set e = sensors if sensors is iterable else [sensors] %}
{% set motion_active = e | select('is_state', 'on') | list | length > 0 %}
{% set cond_ok = true %}
{% set cs = condition_switches if condition_switches is iterable else [condition_switches] %}
{% if cs | length > 0 %}
{% set cond_ok = (cs | select('is_state', 'on') | list | length) == (cs | length) %}
{% endif %}
{{ motion_active and cond_ok }}
# Re-read state from input_text (may have changed during delay)
- variables:
re_eval_state_global: >
{% set text = states(automation_state_entity) | string %}
{% if text in ['unknown','unavailable','none',''] %}
{{ dict() }}
{% else %}
{{ text | from_json }}
{% endif %}
re_eval_state: "{{ re_eval_state_global.get(automation_state_key, dict()) }}"
re_eval_motion_light_state: "{{ re_eval_state.get(state_motion_light_state, automation_state_none) }}"
# Only proceed if state is still NONE (no other run claimed it)
- condition: template
value_template: "{{ (re_eval_motion_light_state | string) == automation_state_none }}"
# --- Re-enable path (mirrors CASE 2) ---
# Set state to ENABLING before turning on
- service: input_text.set_value
target:
entity_id: "{{ automation_state_entity }}"
data:
value: >
{% set new_automation_state = (re_eval_state | combine({
state_motion_light_state: automation_state_enabling,
state_motion_light_last_action_timestamp: now(),
state_motion_light_last_brightness: 0
})) %}
{{ re_eval_state_global | combine({ automation_state_key: new_automation_state }) | tojson }}
# Scene or light activation
- choose:
- conditions:
- condition: template
value_template: "{{ use_scene_instead and effective_scene is not none }}"
sequence:
- service: scene.turn_on
target:
entity_id: "{{ effective_scene }}"
data:
transition: "{{ transition_duration }}"
default:
# Turn ON lights
- choose:
- conditions:
- condition: template
value_template: "{{ resolved_all_lights | length > 0 }}"
sequence:
- service: light.turn_on
target:
entity_id: "{{ resolved_all_lights }}"
data: >
{% set d = effective_light_data if effective_light_data else {} %}
{% if transition_duration > 0 %}
{% set d = d | combine({'transition': transition_duration}) %}
{% endif %}
{{ d }}
# Turn ON switches
- choose:
- conditions:
- condition: template
value_template: "{{ resolved_all_switches | length > 0 }}"
sequence:
- service: switch.turn_on
target:
entity_id: "{{ resolved_all_switches }}"
# Execute enable callback
- choose:
- conditions:
- condition: template
value_template: "{{ enable_action != [] }}"
sequence: !input enable_action
# Debug notification
- choose:
- conditions: "{{ enable_debug_notifications }}"
sequence:
- service: persistent_notification.create
data:
title: "Motion Light Debug"
message: >
Action: RE-ENABLE (external turn-off recovery)
Time: {{ now().strftime('%H:%M:%S') }}
Lights: {{ resolved_all_lights }}
Switches: {{ resolved_all_switches }}
Scene: {{ effective_scene if use_scene_instead else 'N/A' }}
# ----- Sub-case: Automation just turned on the light -----
# Transition from ENABLING to ENABLED, or disable immediately
# if motion already cleared during the ENABLING phase

View File

@@ -1,3 +1,3 @@
{
"version": "2.3.0"
"version": "2.4.0"
}