Last active
February 26, 2026 01:28
-
-
Save Ltek/0d88ed720f635a7579849aac93b9ff93 to your computer and use it in GitHub Desktop.
Home Assistant Blueprint : Repeating Alert Notifications by LTek
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| blueprint: | |
| name: ⚠️ Repeating Alert Notifications by LTek | |
| description: | | |
| **Repeating Alert Notifications ideal for doors, windows, locks, etc** | |
| 🚀 Version 2026.02.19.18c | |
| - IMPORTANT NOTE... DO NOT reuse prior automations, you will need to remake them; it will be worth it! | |
| Author: LTek | |
| 📖 Community Discussion, Help, and Details... https://community.home-assistant.io/t/repeating-alert-notifications/888294 | |
| **FEATURES** | |
| \ | |
| ⚡ Advanced Triggering — Any trigger type (state, numeric, template, event) with optional conditions and restart mode | |
| ❌ Notification Clearing — Dedicated clear trigger, auto-clear delay, and user-defined Notification ID to replace or clear alerts across automations | |
| ♻️ Repeating Alerts — Configurable repeat limits, intervals, and optional repeat counter appended to title | |
| ⏱️ Timing Controls — Initial delay before first alert, repeat intervals, and auto-clear delay after last repeat | |
| 🎬 Actionable Buttons — Up to 3 buttons + optional cancel, button timeout, and failsafe auto-action if all repeats go unanswered | |
| 📲 Multi-Device Delivery — Send to multiple mobile devices simultaneously | |
| 💬 Customizable Notifications — Templated titles and messages with built-in variables (see below) | |
| 👇 Tap Action — Open dashboards, URLs, or specific app views on notification tap | |
| ✅ Android and iOS Specific Options — Android icon, color, persistence, and channel; iOS interruption levels and sounds | |
| 💥️ Custom Actions — Run your own actions on first trigger, on each notification, and on clear | |
| **📖 Available Variables (use in Notification ID, title, and message)** | |
| - `{{ now().strftime('%I:%M %p') }}` — Local time (e.g. 3:45 PM) | |
| - `{{ now().strftime('%A') }}` — Day of week (e.g. Tuesday) | |
| - `{{ now().strftime('%Y%m%d') }}` — Date stamp (e.g. 20260219) | |
| - `{{ trigger.entity_id }}` — Entity that fired the trigger (if state-based) | |
| - `{{ states('sensor.my_sensor') }}` — Current state of any entity | |
| - `{{ trigger_entity_state }}` — State of the triggering entity at the time of trigger (e.g. on, off, open) | |
| - `{{ time_since_trigger }}` — Time elapsed since trigger entity last changed (e.g. 4 min 32 sec ago), updates on each repeat | |
| - `{{ friendly_name }}` - Friendly Name of the triggering entity or the user custom version | |
| - `{{ trigger_entity_state }}` - Display the actual state that triggered the automation | |
| **⚠️ Notification ID Note** | |
| The Notification ID (tag) is used to replace or clear notifications on devices. | |
| Sending a new notification with the same ID replaces the existing one. | |
| A companion automation sharing the same Notification ID can send clear_notification to dismiss it. | |
| If left blank, notifications cannot be replaced or cleared by this automation. | |
| **⚠️ Action Buttons — How It Works** | |
| Buttons appear on every notification including repeats. After each send the automation | |
| waits up to the Button Timeout for a press before continuing. | |
| - **Button pressed** → that button's action fires immediately, all remaining repeats are cancelled | |
| - **Cancel pressed** → automation stops immediately, no actions fire | |
| - **Timeout (mid-repeat)** → automation continues to the next repeat, no action fires yet | |
| - **Timeout (final repeat)** → Auto Actions fire as a one-time failsafe, then the automation ends | |
| Auto Actions are distinct from Custom Actions — Custom Actions fire on every notification, | |
| Auto Actions fire only once after all repeats are exhausted with no button ever pressed. | |
| source_url: https://gist.github.com/Ltek/0d88ed720f635a7579849aac93b9ff93 | |
| domain: automation | |
| input: | |
| # ── SECTION: Alert Trigger ──────────────────────────────────────────────── | |
| section_trigger: | |
| name: "Alert Trigger" | |
| icon: mdi:lightning-bolt | |
| collapsed: false | |
| input: | |
| alert_trigger: | |
| name: "Alert Trigger" | |
| description: > | |
| Define what triggers the alert notification. Supports any trigger | |
| type — state changes, numeric thresholds, templates, time patterns, etc. | |
| default: [] | |
| selector: | |
| trigger: {} | |
| duration_issue_state: | |
| name: "Time Delay before Alert is Sent" | |
| description: > | |
| How long to wait after the trigger fires before sending the alert. | |
| Useful to avoid spurious alerts (e.g. only notify if a door is open for 10 minutes). | |
| For state-based triggers, prefer setting the 'for' duration on the trigger itself | |
| for more reliable behaviour. | |
| default: | |
| minutes: 0 | |
| selector: | |
| duration: | |
| enable_day: true | |
| condition_send_notification: | |
| name: "Optional Trigger Conditions" | |
| description: > | |
| Conditions checked after the alert trigger fires. All conditions must be true | |
| for the notification to send. Useful for restricting alerts to specific times, | |
| modes, or entity states. | |
| default: [] | |
| selector: | |
| condition: {} | |
| # ── SECTION: Auto-Clear ─────────────────────────────────────────────────── | |
| section_clear: | |
| name: "Auto-Clear" | |
| icon: mdi:bell-off | |
| collapsed: true | |
| input: | |
| clear_trigger: | |
| name: "Trigger to Clear Notification" | |
| description: > | |
| When this trigger fires, the notification is immediately cleared on all devices | |
| using the Notification ID. Leave empty if you only want auto-clear by delay, | |
| or if clearing is handled externally. | |
| ⚠️ This trigger must be different from the Alert Trigger above. If both | |
| triggers fire at the same time or on the same condition, the automation | |
| will conflict — sending and clearing the notification simultaneously. | |
| default: [] | |
| selector: | |
| trigger: {} | |
| auto_clear_delay: | |
| name: "Auto-Clear Delay" | |
| description: > | |
| After all repeats have completed (or after the first notification if repeats | |
| are disabled), wait this duration then automatically clear the notification | |
| on all devices. Set to 0 to disable — clearing will only happen via the | |
| Trigger to Clear Notification above, or a companion automation sharing the same Notification ID. | |
| default: | |
| hours: 0 | |
| minutes: 0 | |
| seconds: 0 | |
| selector: | |
| duration: | |
| enable_day: false | |
| # ── SECTION: Repeat ─────────────────────────────────────────────────────── | |
| section_repeat: | |
| name: "Repeat Alerts" | |
| icon: mdi:repeat | |
| collapsed: true | |
| input: | |
| repeat_notification: | |
| name: "Repeat Alerts" | |
| description: > | |
| Repeat the notification at a set interval until auto-clear fires or the repeat limit is reached. | |
| If Action Buttons are configured, pressing a button on any repeat will cancel all remaining repeats. | |
| default: false | |
| selector: | |
| boolean: {} | |
| max_repeat_count: | |
| name: "Maximum Repeat Count" | |
| description: Maximum number of repeats. Set to 0 for unlimited. | |
| default: 0 | |
| selector: | |
| number: | |
| min: 0.0 | |
| max: 100.0 | |
| step: 1.0 | |
| mode: box | |
| time_between_repeat_notification: | |
| name: "Delay Between Repeats" | |
| description: Time between repeat notifications. | |
| default: | |
| minutes: 1 | |
| selector: | |
| duration: | |
| enable_day: true | |
| show_repeat_count: | |
| name: "Show Repeat Count in Title" | |
| description: > | |
| When enabled, appends the current repeat number to the notification title. | |
| Format: "Your Title (1)", "Your Title (2)", "Your Title (3)", etc. | |
| The first notification shows (1), each repeat increments by one. | |
| default: false | |
| selector: | |
| boolean: {} | |
| # ── SECTION: Action Buttons ─────────────────────────────────────────────── | |
| section_buttons: | |
| name: "Action Buttons" | |
| icon: mdi:gesture-tap-button | |
| collapsed: true | |
| input: | |
| include_action_buttons: | |
| name: "Enable Action Buttons" | |
| description: > | |
| Select which buttons to show on the first notification. | |
| Buttons only appear on the first notification, not on repeats. | |
| If a button is pressed, the repeat loop is skipped and the button's action fires instead. | |
| default: [] | |
| selector: | |
| select: | |
| options: | |
| - label: "Button 1" | |
| value: enable_action_button_1 | |
| - label: "Button 2" | |
| value: enable_action_button_2 | |
| - label: "Button 3" | |
| value: enable_action_button_3 | |
| multiple: true | |
| custom_value: false | |
| sort: false | |
| action_button_1_label: | |
| name: "Button 1 Label" | |
| description: Text displayed on button 1. | |
| default: 'Acknowledge' | |
| selector: | |
| text: {} | |
| action_button_2_label: | |
| name: "Button 2 Label" | |
| description: Text displayed on button 2. | |
| default: 'Snooze' | |
| selector: | |
| text: {} | |
| action_button_3_label: | |
| name: "Button 3 Label" | |
| description: Text displayed on button 3. | |
| default: 'Ignore' | |
| selector: | |
| text: {} | |
| action_button_stop_label: | |
| name: "Cancel Button Label" | |
| description: > | |
| Text for an optional cancel button. Shown when any button above is enabled. | |
| Pressing cancel stops the automation — no actions fire and repeats are cancelled. | |
| default: 'Cancel' | |
| selector: | |
| text: {} | |
| action_button_timeout: | |
| name: "Button Timeout" | |
| description: > | |
| How long to wait for a button press before continuing automatically. | |
| When timeout expires with no press, auto-actions fire (if configured) and the repeat loop starts. | |
| default: | |
| hours: 0 | |
| minutes: 5 | |
| seconds: 0 | |
| selector: | |
| duration: {} | |
| action_button_1_action: | |
| name: "Button 1 Action" | |
| description: Actions to run when Button 1 is pressed. | |
| default: [] | |
| selector: | |
| action: {} | |
| action_button_2_action: | |
| name: "Button 2 Action" | |
| description: Actions to run when Button 2 is pressed. | |
| default: [] | |
| selector: | |
| action: {} | |
| action_button_3_action: | |
| name: "Button 3 Action" | |
| description: Actions to run when Button 3 is pressed. | |
| default: [] | |
| selector: | |
| action: {} | |
| include_auto_actions: | |
| name: "Auto Actions on Timeout (Failsafe)" | |
| description: > | |
| Select which button actions should fire automatically as a failsafe if all repeats | |
| complete and no button was ever pressed. Fires once only, after the final repeat times out. | |
| If no repeats are configured, fires after the first (and only) notification times out. | |
| Leave empty to take no automatic action. | |
| default: [] | |
| selector: | |
| select: | |
| options: | |
| - label: "Button 1 Action" | |
| value: enable_auto_action_1 | |
| - label: "Button 2 Action" | |
| value: enable_auto_action_2 | |
| - label: "Button 3 Action" | |
| value: enable_auto_action_3 | |
| multiple: true | |
| custom_value: false | |
| sort: false | |
| # ── SECTION: Notification Settings ─────────────────────────────────────── | |
| section_content: | |
| name: "Notification Settings" | |
| icon: mdi:message-text | |
| collapsed: true | |
| input: | |
| notify_device: | |
| name: "Devices to Notify" | |
| description: Select mobile devices to receive notifications (Home Assistant companion app). | |
| default: [] | |
| selector: | |
| device: | |
| integration: mobile_app | |
| multiple: true | |
| notification_id: | |
| name: "Notification ID" | |
| description: > | |
| A unique tag used to replace or clear this notification on devices. | |
| Supports template variables (e.g. front-door-alert or alert-{{ now().strftime('%Y%m%d') }}). | |
| ⚠️ If left blank, notifications cannot be replaced or cleared by this automation. | |
| Multiple automations sharing the same Notification ID can replace/clear each other's alerts. | |
| default: '' | |
| selector: | |
| text: | |
| multiple: false | |
| multiline: false | |
| friendly_name: | |
| name: "Custom Friendly Name" | |
| description: Override the friendly name used in notification templates (e.g. Fridge, Front Door). | |
| default: '' | |
| selector: | |
| text: | |
| multiple: false | |
| multiline: false | |
| notification_title: | |
| name: "Notification Title" | |
| description: "Supports template variables. See descritpion above." | |
| default: '{{ friendly_name }} changed to {{ trigger_entity_state }}' | |
| selector: | |
| text: | |
| multiple: false | |
| multiline: false | |
| notification_message: | |
| name: "Notification Message" | |
| description: "Supports template variables. See descritpion above." | |
| default: "Trigger started {{ time_since_trigger }} ago" | |
| selector: | |
| text: | |
| multiple: false | |
| multiline: false | |
| notification_click_url: | |
| name: "Open URL with tap" | |
| description: URL that opens when the notification is tapped. | |
| default: '' | |
| selector: | |
| text: | |
| multiple: false | |
| multiline: false | |
| # ── SECTION: Android Options ────────────────────────────────────────────── | |
| section_android: | |
| name: "Android Options" | |
| icon: mdi:robot | |
| collapsed: true | |
| input: | |
| notification_icon_warning: | |
| name: "Notification Icon (Android Only)" | |
| description: The icon shown in the alert notification. | |
| default: alert | |
| selector: | |
| select: | |
| options: | |
| - alert | |
| - alert-circle | |
| - door | |
| - door-open | |
| - motion-sensor | |
| - fridge | |
| - fridge-alert | |
| - home | |
| - home-alert | |
| - home-assistant | |
| - window-closed | |
| - window-open | |
| - window-open-variant | |
| custom_value: false | |
| multiple: false | |
| sort: false | |
| notification_color: | |
| name: "Notification Color (Android Only)" | |
| description: The color of the notification. | |
| default: red | |
| selector: | |
| select: | |
| options: | |
| - red | |
| - orange | |
| - yellow | |
| - green | |
| - blue | |
| - purple | |
| custom_value: false | |
| multiple: false | |
| sort: false | |
| notification_persistent: | |
| name: "Persistent Notification (Android Only)" | |
| description: > | |
| Notification cannot be closed manually — stays until auto-clear fires | |
| or a companion automation clears it. Works well combined with Repeat Alerts. | |
| default: false | |
| selector: | |
| boolean: {} | |
| # ── SECTION: iOS Options ────────────────────────────────────────────────── | |
| section_ios: | |
| name: "iOS Options" | |
| icon: mdi:apple | |
| collapsed: true | |
| input: | |
| notification_interruption_level: | |
| name: "Interruption Level (iOS Only)" | |
| description: Controls the intrusiveness of the notification on iOS devices. | |
| default: active | |
| selector: | |
| select: | |
| options: | |
| - passive | |
| - active | |
| - time-sensitive | |
| - critical | |
| custom_value: false | |
| multiple: false | |
| sort: false | |
| # ── SECTION: Custom Actions ─────────────────────────────────────────────── | |
| section_actions: | |
| name: "Custom Actions" | |
| icon: mdi:cog | |
| collapsed: true | |
| input: | |
| custom_action_first_trigger: | |
| name: "Custom Action - On First Trigger" | |
| description: > | |
| Actions run once when the alert first triggers, before the first notification is sent. | |
| Runs only on the initial trigger, not on repeats. | |
| default: [] | |
| selector: | |
| action: {} | |
| custom_action_issue_state: | |
| name: "Custom Action - On Each Notification" | |
| description: Actions run each time a notification is sent (including repeats). | |
| default: [] | |
| selector: | |
| action: {} | |
| custom_action_on_clear: | |
| name: "Custom Action - On Clear" | |
| description: Actions run after the notification is cleared (via clear trigger or auto-clear delay). | |
| default: [] | |
| selector: | |
| action: {} | |
| mode: restart | |
| max_exceeded: silent | |
| trigger_variables: | |
| _alert_triggers: !input alert_trigger | |
| # ── Top-level variables (all declared at top level — cannot be nested) ──────── | |
| variables: | |
| custom_friendly_name: !input friendly_name | |
| notification_id_template: !input notification_id | |
| duration_issue_state: !input duration_issue_state | |
| condition_send_notification: !input condition_send_notification | |
| notify_device: !input notify_device | |
| notification_click_url: !input notification_click_url | |
| repeat_notification: !input repeat_notification | |
| show_repeat_count: !input show_repeat_count | |
| max_repeat_count: !input max_repeat_count | |
| time_between_repeat_notification: !input time_between_repeat_notification | |
| notification_icon_warning: !input notification_icon_warning | |
| notification_color: !input notification_color | |
| notification_persistent: !input notification_persistent | |
| notification_interruption_level: !input notification_interruption_level | |
| include_action_buttons: !input include_action_buttons | |
| action_button_1_label: !input action_button_1_label | |
| action_button_2_label: !input action_button_2_label | |
| action_button_3_label: !input action_button_3_label | |
| action_button_stop_label: !input action_button_stop_label | |
| action_button_timeout: !input action_button_timeout | |
| include_auto_actions: !input include_auto_actions | |
| custom_action_first_trigger: !input custom_action_first_trigger | |
| custom_action_issue_state: !input custom_action_issue_state | |
| custom_action_on_clear: !input custom_action_on_clear | |
| auto_clear_delay: !input auto_clear_delay | |
| repeat_count: 0 | |
| triggers: | |
| - triggers: !input alert_trigger | |
| - triggers: !input clear_trigger | |
| action: | |
| - variables: | |
| notify_services_list: > | |
| {% set ns = namespace(services=[]) %} | |
| {% for device_id in notify_device %} | |
| {% set matched = device_entities(device_id) | |
| | select('match', 'notify\.mobile_app_') | |
| | list %} | |
| {% if matched | length > 0 %} | |
| {% set ns.services = ns.services + [matched[0]] %} | |
| {% else %} | |
| {% set device_name = device_attr(device_id, 'name') | slugify %} | |
| {% set ns.services = ns.services + ['notify.mobile_app_' ~ device_name] %} | |
| {% endif %} | |
| {% endfor %} | |
| {{ ns.services }} | |
| number_of_notify_services: '{{ notify_services_list | count }}' | |
| notification_tag: '{{ notification_id_template }}' | |
| trigger_fired_at: '{{ trigger.from_state.last_changed | as_timestamp }}' | |
| trigger_entity_state: '{{ trigger.to_state.state if trigger.to_state is defined else states(trigger.entity_id) }}' | |
| friendly_name: > | |
| {% if custom_friendly_name != '' %} | |
| {{ custom_friendly_name }} | |
| {% else %} | |
| {{ state_attr(trigger.entity_id, 'friendly_name') | default(trigger.entity_id) | default('Alert') }} | |
| {% endif %} | |
| rendered_title: !input notification_title | |
| - condition: template | |
| value_template: '{{ trigger.idx in ["0", "1"] }}' | |
| - choose: | |
| # ── CLEAR TRIGGER FIRED ─────────────────────────────────────────────── | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ trigger.idx == "1" }}' | |
| sequence: | |
| - repeat: | |
| count: '{{ number_of_notify_services }}' | |
| sequence: | |
| - service: '{{ notify_services_list[repeat.index-1] }}' | |
| data: | |
| message: clear_notification | |
| data: | |
| tag: '{{ notification_tag }}' | |
| - choose: [] | |
| default: !input custom_action_on_clear | |
| # ── ALERT TRIGGER FIRED ─────────────────────────────────────────────────── | |
| default: | |
| # ── OPTIONAL CONDITIONS ─────────────────────────────────────────────────── | |
| - condition: !input condition_send_notification | |
| # ── INITIAL DELAY ───────────────────────────────────────────────────────── | |
| - if: | |
| - condition: template | |
| value_template: > | |
| {{ (duration_issue_state.hours | default(0) | int) + | |
| (duration_issue_state.minutes | default(0) | int) + | |
| (duration_issue_state.seconds | default(0) | int) > 0 }} | |
| then: | |
| - delay: !input duration_issue_state | |
| # ── CUSTOM ACTION: ON FIRST TRIGGER ─────────────────────────────────────── | |
| - choose: [] | |
| default: !input custom_action_first_trigger | |
| # ── BUILD ACTION BUTTONS ────────────────────────────────────────────────── | |
| - variables: | |
| action_btn_1: '{{ "BTN1_" ~ context.id }}' | |
| action_btn_2: '{{ "BTN2_" ~ context.id }}' | |
| action_btn_3: '{{ "BTN3_" ~ context.id }}' | |
| action_btn_stop: '{{ "STOP_" ~ context.id }}' | |
| actions_list: > | |
| {% set actions = [] %} | |
| {% if 'enable_action_button_1' in include_action_buttons and action_button_1_label != '' %} | |
| {% set actions = actions + [{'action': 'BTN1_' ~ context.id, 'title': action_button_1_label}] %} | |
| {% endif %} | |
| {% if 'enable_action_button_2' in include_action_buttons and action_button_2_label != '' %} | |
| {% set actions = actions + [{'action': 'BTN2_' ~ context.id, 'title': action_button_2_label}] %} | |
| {% endif %} | |
| {% if 'enable_action_button_3' in include_action_buttons and action_button_3_label != '' %} | |
| {% set actions = actions + [{'action': 'BTN3_' ~ context.id, 'title': action_button_3_label}] %} | |
| {% endif %} | |
| {% if include_action_buttons | length > 0 and action_button_stop_label != '' %} | |
| {% set actions = actions + [{'action': 'STOP_' ~ context.id, 'title': action_button_stop_label}] %} | |
| {% endif %} | |
| {{ actions }} | |
| # ── FIRST NOTIFICATION ──────────────────────────────────────────────────── | |
| - parallel: | |
| - repeat: | |
| count: '{{ number_of_notify_services }}' | |
| sequence: | |
| - variables: | |
| time_since_trigger: > | |
| {% set diff = (as_timestamp(now()) - trigger_fired_at) | int %} | |
| {% set h = diff // 3600 %} | |
| {% set m = (diff % 3600) // 60 %} | |
| {% set s = diff % 60 %} | |
| {% if h > 0 %}{{ h }} hr {% endif %}{% if m > 0 %}{{ m }} min {% endif %}{{ s }} sec | |
| - variables: | |
| current_message: !input notification_message | |
| - service: '{{ notify_services_list[repeat.index-1] }}' | |
| data: | |
| message: '{{ current_message }}' | |
| title: > | |
| {{ rendered_title }}{% if show_repeat_count %} ({{ repeat_count + 1 }}){% endif %} | |
| data: | |
| clickAction: !input notification_click_url | |
| url: !input notification_click_url | |
| tag: '{{ notification_tag }}' | |
| color: !input notification_color | |
| notification_icon: 'mdi:{{ notification_icon_warning }}' | |
| push: | |
| interruption-level: !input notification_interruption_level | |
| persistent: !input notification_persistent | |
| sticky: !input notification_persistent | |
| actions: '{{ actions_list }}' | |
| - choose: [] | |
| default: !input custom_action_issue_state | |
| # ── WAIT FOR BUTTON PRESS (first notification) ──────────────────────────── | |
| - variables: | |
| last_wait_timed_out: false | |
| - if: | |
| - condition: template | |
| value_template: '{{ actions_list | length > 0 }}' | |
| then: | |
| - wait_for_trigger: | |
| - platform: event | |
| event_type: mobile_app_notification_action | |
| event_data: | |
| action: '{{ action_btn_1 }}' | |
| - platform: event | |
| event_type: mobile_app_notification_action | |
| event_data: | |
| action: '{{ action_btn_2 }}' | |
| - platform: event | |
| event_type: mobile_app_notification_action | |
| event_data: | |
| action: '{{ action_btn_3 }}' | |
| - platform: event | |
| event_type: mobile_app_notification_action | |
| event_data: | |
| action: '{{ action_btn_stop }}' | |
| timeout: !input action_button_timeout | |
| continue_on_timeout: true | |
| # ── BUTTON PRESSED → fire action and stop ───────────────────────────── | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ wait.trigger is not none and wait.trigger.event.data.action == action_btn_1 }}' | |
| sequence: | |
| - sequence: !input action_button_1_action | |
| - stop: "Button 1 pressed" | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ wait.trigger is not none and wait.trigger.event.data.action == action_btn_2 }}' | |
| sequence: | |
| - sequence: !input action_button_2_action | |
| - stop: "Button 2 pressed" | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ wait.trigger is not none and wait.trigger.event.data.action == action_btn_3 }}' | |
| sequence: | |
| - sequence: !input action_button_3_action | |
| - stop: "Button 3 pressed" | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ wait.trigger is not none and wait.trigger.event.data.action == action_btn_stop }}' | |
| sequence: | |
| - stop: "Alert cancelled by user" | |
| # ── TIMEOUT → track it, fall through to repeat loop ────────────────── | |
| - variables: | |
| last_wait_timed_out: '{{ wait.trigger is none }}' | |
| # ── REPEAT LOOP ─────────────────────────────────────────────────────────── | |
| - if: | |
| - condition: template | |
| value_template: '{{ repeat_notification and (max_repeat_count == 0 or repeat_count < max_repeat_count) }}' | |
| then: | |
| - variables: | |
| repeat_count: '{{ repeat_count + 1 }}' | |
| - delay: !input time_between_repeat_notification | |
| - repeat: | |
| while: | |
| - condition: template | |
| value_template: '{{ repeat_notification and (max_repeat_count == 0 or repeat_count < max_repeat_count) }}' | |
| sequence: | |
| - parallel: | |
| - repeat: | |
| count: '{{ number_of_notify_services }}' | |
| sequence: | |
| - variables: | |
| time_since_trigger: > | |
| {% set diff = (as_timestamp(now()) - trigger_fired_at) | int %} | |
| {% set h = diff // 3600 %} | |
| {% set m = (diff % 3600) // 60 %} | |
| {% set s = diff % 60 %} | |
| {% if h > 0 %}{{ h }} hr {% endif %}{% if m > 0 %}{{ m }} min {% endif %}{{ s }} sec | |
| - variables: | |
| current_message: !input notification_message | |
| - service: '{{ notify_services_list[repeat.index-1] }}' | |
| data: | |
| message: '{{ current_message }}' | |
| title: > | |
| {{ rendered_title }}{% if show_repeat_count %} ({{ repeat_count + 1 }}){% endif %} | |
| data: | |
| clickAction: !input notification_click_url | |
| url: !input notification_click_url | |
| tag: '{{ notification_tag }}' | |
| color: !input notification_color | |
| notification_icon: 'mdi:{{ notification_icon_warning }}' | |
| push: | |
| interruption-level: !input notification_interruption_level | |
| persistent: !input notification_persistent | |
| sticky: !input notification_persistent | |
| actions: '{{ actions_list }}' | |
| - choose: [] | |
| default: !input custom_action_issue_state | |
| # ── WAIT FOR BUTTON PRESS ON REPEAT ─────────────────────────── | |
| - if: | |
| - condition: template | |
| value_template: '{{ actions_list | length > 0 }}' | |
| then: | |
| - wait_for_trigger: | |
| - platform: event | |
| event_type: mobile_app_notification_action | |
| event_data: | |
| action: '{{ action_btn_1 }}' | |
| - platform: event | |
| event_type: mobile_app_notification_action | |
| event_data: | |
| action: '{{ action_btn_2 }}' | |
| - platform: event | |
| event_type: mobile_app_notification_action | |
| event_data: | |
| action: '{{ action_btn_3 }}' | |
| - platform: event | |
| event_type: mobile_app_notification_action | |
| event_data: | |
| action: '{{ action_btn_stop }}' | |
| timeout: !input action_button_timeout | |
| continue_on_timeout: true | |
| # ── BUTTON PRESSED → fire action and stop repeats ────────── | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ wait.trigger is not none and wait.trigger.event.data.action == action_btn_1 }}' | |
| sequence: | |
| - sequence: !input action_button_1_action | |
| - stop: "Button 1 pressed" | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ wait.trigger is not none and wait.trigger.event.data.action == action_btn_2 }}' | |
| sequence: | |
| - sequence: !input action_button_2_action | |
| - stop: "Button 2 pressed" | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ wait.trigger is not none and wait.trigger.event.data.action == action_btn_3 }}' | |
| sequence: | |
| - sequence: !input action_button_3_action | |
| - stop: "Button 3 pressed" | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ wait.trigger is not none and wait.trigger.event.data.action == action_btn_stop }}' | |
| sequence: | |
| - stop: "Alert cancelled by user" | |
| # ── TIMEOUT → track it, continue loop ───────────────────── | |
| - variables: | |
| last_wait_timed_out: '{{ wait.trigger is none }}' | |
| - variables: | |
| repeat_count: '{{ repeat_count + 1 }}' | |
| - delay: !input time_between_repeat_notification | |
| # ── AUTO-ACTIONS (failsafe — fires only if all repeats exhausted unanswered) | |
| - if: | |
| - condition: template | |
| value_template: '{{ actions_list | length > 0 and last_wait_timed_out }}' | |
| then: | |
| - if: | |
| - condition: template | |
| value_template: '{{ "enable_auto_action_1" in include_auto_actions }}' | |
| then: !input action_button_1_action | |
| - if: | |
| - condition: template | |
| value_template: '{{ "enable_auto_action_2" in include_auto_actions }}' | |
| then: !input action_button_2_action | |
| - if: | |
| - condition: template | |
| value_template: '{{ "enable_auto_action_3" in include_auto_actions }}' | |
| then: !input action_button_3_action | |
| # ── AUTO-CLEAR ──────────────────────────────────────────────────────────── | |
| - if: | |
| - condition: template | |
| value_template: > | |
| {{ notification_tag != '' and | |
| (auto_clear_delay.hours | default(0) | int) + | |
| (auto_clear_delay.minutes | default(0) | int) + | |
| (auto_clear_delay.seconds | default(0) | int) > 0 }} | |
| then: | |
| - delay: !input auto_clear_delay | |
| - repeat: | |
| count: '{{ number_of_notify_services }}' | |
| sequence: | |
| - service: '{{ notify_services_list[repeat.index-1] }}' | |
| data: | |
| message: clear_notification | |
| data: | |
| tag: '{{ notification_tag }}' | |
| - choose: [] | |
| default: !input custom_action_on_clear |
Comments are disabled for this gist.