Last active
February 26, 2026 18:55
-
-
Save Ltek/f45e05a47c1e7e7e5bcaf0791e2f360d to your computer and use it in GitHub Desktop.
Home Assistant Blueprint: Smart Camera 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: "📸 Smart Camera Notifications" | |
| description: | | |
| **📸 Smart Camera Notifications** | |
| Actionable Notifications with Camera Snapshots and extensive customization options. | |
| Author: LTek | |
| 🚀 Version 2026.02.26.22c | |
| **FEATURES** | |
| 🎯 Conditional Triggering - Multiple trigger support using Home Assistant condition blocks | |
| ⏱️ Timing Controls - Separate delays for snapshot capture and notification sending | |
| 📱 Multi-Platform Notifications - Full support for Android, iOS, and Android TV | |
| 🔔 Extensive Notification Options - Action buttons, camera snapshots, custom sounds, colors, icons, etc | |
| ⚡ Performance - Parallel execution mode for faster processing | |
| ✅ Archive System - Optional snapshot archiving with separate conditions and configurable file paths | |
| 🎛️ Advanced Controls - Custom actions before/after snapshot, notification grouping | |
| 📖 Community Discussion, Help, and Details... https://community.home-assistant.io/t/smart-camera-notifications/989940 | |
| **BUILT-IN TEMPLATE VARIABLES:** | |
| **Time/Date Variables:** | |
| `{{ now() }}` — Current date and time | |
| `{{ now().strftime("%H:%M") }}` — Current time (14:30) | |
| `{{ now().strftime("%I:%M %p") }}` — Current time (02:30 PM) | |
| `{{ now().strftime("%A, %B %d") }}` — Day of week, Month Day (Tuesday, January 10) | |
| `{{ now().strftime("%Y-%m-%d") }}` — Date (2025-01-10) | |
| **Camera/Entity Variables:** | |
| `{{ camera }}` — Entity ID of camera | |
| `{{ camera_name }}` — Friendly name of camera | |
| `{{ states[camera].name }}` — Alternative way to get camera name | |
| `{{ states[camera].attributes.friendly_name }}` — Camera friendly name | |
| `{{ states[camera].object_id }}` — Entity ID without domain (e.g., "front_door_camera") | |
| **Trigger/Context Variables:** | |
| `{{ trigger.entity_id }}` — Which entity triggered | |
| `{{ trigger.to_state.state }}` — New state of triggering entity | |
| `{{ trigger.from_state.state }}` — Previous state | |
| `{{ trigger.to_state.attributes.friendly_name }}` — Friendly name of triggering entity | |
| **EXAMPLE TEMPLATES:** | |
| Title: `📸 {{ camera_name }} {{ now().strftime("%H:%M") }}` | |
| Message: `Motion at {{ now().strftime("%I:%M %p on %A") }}` | |
| Advanced: `{{ camera_name }} - {{ trigger.to_state.attributes.friendly_name }} triggered at {{ now().strftime("%H:%M") }}` | |
| 📖 Community Discussion, Help, and Details... https://community.home-assistant.io/ | |
| domain: automation | |
| source_url: https://gist.github.com/Ltek/ | |
| input: | |
| # ------------------------------------------------------------ | |
| # TRIGGERS | |
| # ------------------------------------------------------------ | |
| trigger_additional: | |
| name: Triggers | |
| description: | | |
| Best to use Entity triggers — HA's Target triggers are not all working properly yet. | |
| Use Conditions for fine-tuned control. | |
| default: [] | |
| selector: | |
| trigger: {} | |
| # ------------------------------------------------------------ | |
| # OPTIONAL CONDITIONS | |
| # ------------------------------------------------------------ | |
| use_conditions: | |
| name: Use Conditions? | |
| description: Adds condition blocks to fine-tune when the automation will (or will not) run. | |
| default: false | |
| selector: | |
| boolean: {} | |
| custom_conditions: | |
| name: Conditions | |
| description: | | |
| Only evaluated when Use Conditions is enabled. | |
| Add any Home Assistant condition blocks here (including AND/OR logic if needed). | |
| default: [] | |
| selector: | |
| condition: {} | |
| # ------------------------------------------------------------ | |
| # CAMERA | |
| # ------------------------------------------------------------ | |
| camera: | |
| name: Camera | |
| description: The camera which creates the snapshot | |
| selector: | |
| entity: | |
| domain: | |
| - camera | |
| multiple: false | |
| delay: | |
| name: Snapshot Delay | |
| description: Wait before creating camera snapshot, in seconds. (normally 0 to 2 seconds) | |
| default: 0.5 | |
| selector: | |
| number: | |
| min: 0 | |
| max: 30 | |
| unit_of_measurement: seconds | |
| mode: slider | |
| step: 0.5 | |
| # ------------------------------------------------------------ | |
| # ACTION TIMING CONTROLS | |
| # ------------------------------------------------------------ | |
| action_timing_section: | |
| name: Action Timing Controls | |
| description: Control when additional actions run relative to snapshot capture | |
| icon: mdi:timer-cog-outline | |
| collapsed: true | |
| input: | |
| additional_actions_before: | |
| name: Additional Actions Before Snapshot | |
| description: Add additional actions to the script. Will execute before everything | |
| else. Useful to turn on a light before the snapshot! | |
| default: [] | |
| selector: | |
| action: {} | |
| additional_actions: | |
| name: Additional Actions After Snapshot | |
| description: Add additional actions to the script. Will execute after everything else. | |
| default: [] | |
| selector: | |
| action: {} | |
| # ------------------------------------------------------------ | |
| # NOTIFICATION SETTINGS | |
| # ------------------------------------------------------------ | |
| notification_section: | |
| name: Notification Settings | |
| description: Configure notification behavior and recipients | |
| icon: mdi:bell | |
| collapsed: true | |
| input: | |
| notify: | |
| name: Send Notifications | |
| description: Enable or disable notifications | |
| default: true | |
| selector: | |
| boolean: {} | |
| notify_device: | |
| name: Device(s) to Notify | |
| description: | | |
| Device must run the official Home Assistant Companion app. | |
| For Google TV devices, try [Notifications for Android TV](https://play.google.com/store/apps/details?id=de.cyberdream.androidtv.notifications.google&pcampaignid=web_share). | |
| To notify multiple devices, create a [Notification Group](https://companion.home-assistant.io/docs/notifications/notifications-basic/#sending-notifications-to-multiple-devices) and use the **Notify a Group or Android TV** field below instead. | |
| default: false | |
| selector: | |
| device: | |
| integration: mobile_app | |
| multiple: true | |
| notification_title: | |
| name: Notification Title | |
| description: Supports template variables — see blueprint description for examples. | |
| default: '{{ camera_name }} at {{ time }}' | |
| notification_message: | |
| name: Notification Message | |
| description: Supports template variables — see blueprint description for examples. | |
| default: 'Motion detected at {{ camera_name }}' | |
| condition: | |
| name: Notification Conditions | |
| description: Optional conditions to check before sending notification | |
| default: [] | |
| selector: | |
| condition: {} | |
| delay_send: | |
| name: Delay the first Notification? | |
| description: Wait before sending a notification. 0 to 30 seconds (0.5 increments) | |
| default: 0 | |
| selector: | |
| number: | |
| min: 0 | |
| max: 30 | |
| unit_of_measurement: seconds | |
| mode: slider | |
| step: 0.5 | |
| delay_notification: | |
| name: Delay additional Notifications? | |
| description: | | |
| Does not send a notification for this period of time, but other automation actions will still run. | |
| For when you want Actions to run with each trigger, but don't want to see every notification. | |
| (300 sec = 5 min, max 3600 sec = 1 hr) | |
| default: 60 | |
| selector: | |
| number: | |
| min: 0 | |
| max: 3600 | |
| unit_of_measurement: seconds | |
| mode: slider | |
| step: 1 | |
| notification_group: | |
| name: Notification Group Name | |
| description: The group name that will determine if notifications are grouped on your mobile device. | |
| default: '{{ camera_name }} Snapshot' | |
| # ------------------------------------------------------------ | |
| # ACTIONABLE NOTIFICATION BUTTONS | |
| # ------------------------------------------------------------ | |
| actionable_buttons_section: | |
| name: Actionable Notification Buttons | |
| description: | | |
| **Button Types** | |
| `URI` — Opens a link or deep link when the button is tapped (use with Button URI field) | |
| `REQUEST_LOCATION_UPDATES` — Requests a location update from the device | |
| `UPDATE_SENSORS` — Forces a sensor update from the device | |
| `FIRE_EVENT` — Fires a custom Home Assistant event | |
| `Disabled` — Disables the button | |
| **URI Examples** (for Notification Click URL and Button URIs) | |
| `entityId:camera.your_camera` → Open Live Camera *default* | |
| `/dashboard/camera` | |
| → Open a dashboard tab | |
| `/lovelace` | |
| → Open Lovelace UI | |
| `homeassistant://navigate/lovelace/0` | |
| → Deep link to a specific Lovelace view | |
| `homeassistant://media_player/media_play` | |
| → Control a media player | |
| `tel:1234567890` | |
| → Make a phone call | |
| `https://example.com` | |
| → Open a website | |
| `intent:#Intent;action=android.intent.action.VIEW;end` | |
| → Android intent | |
| icon: mdi:gesture-tap-button | |
| collapsed: true | |
| input: | |
| # Main notification click action (when tapping the notification body) | |
| notification_click_url_input: | |
| name: Notification Click URL | |
| description: | | |
| URL to open when tapping the notification body. Leave blank to default to the camera more-info popup. | |
| default: '' | |
| # Button 1 configuration | |
| action_type_1: | |
| name: Button 1 Type | |
| default: URI | |
| selector: | |
| select: | |
| mode: dropdown | |
| options: | |
| - label: Disabled | |
| value: disabled | |
| - label: URI | |
| value: URI | |
| - label: REQUEST_LOCATION_UPDATES | |
| value: REQUEST_LOCATION_UPDATES | |
| - label: UPDATE_SENSORS | |
| value: UPDATE_SENSORS | |
| - label: FIRE_EVENT | |
| value: FIRE_EVENT | |
| action_title_1: | |
| name: Button 1 Title | |
| default: '' | |
| action_uri_1: | |
| name: Button 1 URI | |
| description: See URI Examples in the section description above. | |
| default: '' | |
| # Button 2 configuration | |
| action_type_2: | |
| name: Button 2 Type | |
| default: disabled | |
| selector: | |
| select: | |
| mode: dropdown | |
| options: | |
| - label: Disabled | |
| value: disabled | |
| - label: URI | |
| value: URI | |
| - label: REQUEST_LOCATION_UPDATES | |
| value: REQUEST_LOCATION_UPDATES | |
| - label: UPDATE_SENSORS | |
| value: UPDATE_SENSORS | |
| - label: FIRE_EVENT | |
| value: FIRE_EVENT | |
| action_title_2: | |
| name: Button 2 Title | |
| default: '' | |
| action_uri_2: | |
| name: Button 2 URI | |
| description: See URI Examples in the section description above. | |
| default: '' | |
| # Button 3 configuration | |
| action_type_3: | |
| name: Button 3 Type | |
| default: disabled | |
| selector: | |
| select: | |
| mode: dropdown | |
| options: | |
| - label: Disabled | |
| value: disabled | |
| - label: URI | |
| value: URI | |
| - label: REQUEST_LOCATION_UPDATES | |
| value: REQUEST_LOCATION_UPDATES | |
| - label: UPDATE_SENSORS | |
| value: UPDATE_SENSORS | |
| - label: FIRE_EVENT | |
| value: FIRE_EVENT | |
| action_title_3: | |
| name: Button 3 Title | |
| default: '' | |
| action_uri_3: | |
| name: Button 3 URI | |
| description: See URI Examples in the section description above. | |
| default: '' | |
| # ------------------------------------------------------------ | |
| # ANDROID OPTIONS | |
| # ------------------------------------------------------------ | |
| android_section: | |
| name: Android Options | |
| description: These only work on Android | |
| icon: mdi:android | |
| collapsed: true | |
| input: | |
| notification_channel: | |
| name: Notification Channel | |
| description: | | |
| Creates a named channel on your Android device, enabling custom sounds, vibration patterns, and Do Not Disturb overrides. | |
| Configured on the device at: Home Assistant App → Settings → Notifications. | |
| default: '{{ camera_name }} Snapshot' | |
| notification_sticky: | |
| name: Sticky | |
| description: When enabled, the notification persists after tapping and must be swiped away manually. | |
| default: true | |
| selector: | |
| boolean: {} | |
| notify_group: | |
| name: Notify a Group or Android TV | |
| description: | | |
| Overrides the individual device selector above. Enter the group or TV name (e.g. `all_devices`). | |
| ⚠️ Groups mixing mobile devices and TVs won't show snapshots on the TV unless Android TV mode is enabled — but that prevents phones from receiving snapshots. | |
| To notify multiple devices, create a [Notification Group](https://companion.home-assistant.io/docs/notifications/notifications-basic/#sending-notifications-to-multiple-devices). | |
| default: '' | |
| notification_color: | |
| name: Notification Color | |
| description: Sets the accent color of the notification on Android. | |
| default: '#03a9f4' | |
| selector: | |
| select: | |
| options: | |
| - label: 'Steelblue - #03a9f4' | |
| value: '#03a9f4' | |
| - label: 'Red - #f44336' | |
| value: '#f44336' | |
| - label: 'Pink - #e91e63' | |
| value: '#e91e63' | |
| - label: 'Purple - #926bc7' | |
| value: '#926bc7' | |
| - label: 'Deep Purple - #6e41ab' | |
| value: '#6e41ab' | |
| - label: 'Indigo - #3f51b5' | |
| value: '#3f51b5' | |
| - label: 'Blue - #2196f3' | |
| value: '#2196f3' | |
| - label: 'Light Blue - #03a9f4' | |
| value: '#03a9f4' | |
| - label: 'Cyan - #00bcd4' | |
| value: '#00bcd4' | |
| - label: 'Teal - #009688' | |
| value: '#009688' | |
| - label: 'Green - #4caf50' | |
| value: '#4caf50' | |
| - label: 'Light Green - #8bc34a' | |
| value: '#8bc34a' | |
| - label: 'Lime - #cddc39' | |
| value: '#cddc39' | |
| - label: 'Yellow - #ffeb3b' | |
| value: '#ffeb3b' | |
| - label: 'Amber - #ffc107' | |
| value: '#ffc107' | |
| - label: 'Orange - #ff9800' | |
| value: '#ff9800' | |
| - label: 'Deep Orange - #ff5722' | |
| value: '#ff5722' | |
| - label: 'Brown - #795548' | |
| value: '#795548' | |
| - label: 'Light Grey - #bdbdbd' | |
| value: '#bdbdbd' | |
| - label: 'Grey - #9e9e9e' | |
| value: '#9e9e9e' | |
| - label: 'Dark Grey - #606060' | |
| value: '#606060' | |
| - label: 'Blue Grey - #607d8b' | |
| value: '#607d8b' | |
| - label: 'Black - #000000' | |
| value: '#000000' | |
| - label: White -#ffffff | |
| value: '#ffffff' | |
| custom_value: true | |
| sort: false | |
| multiple: false | |
| notification_icon: | |
| name: Notification Status Bar Icon | |
| description: Icon shown in the Android status bar for this notification. | |
| default: mdi:cctv | |
| selector: | |
| icon: | |
| placeholder: mdi:cctv | |
| notification_alert_once: | |
| name: Alert Once | |
| description: Only the first notification plays a sound — subsequent updates for the same event are silent. | |
| default: false | |
| selector: | |
| boolean: {} | |
| # ------------------------------------------------------------ | |
| # ANDROID TV OPTIONS | |
| # ------------------------------------------------------------ | |
| tv_section: | |
| name: Android TV Options | |
| description: These are Android TV options | |
| icon: mdi:youtube-tv | |
| collapsed: true | |
| input: | |
| android_tv: | |
| name: Android TV - LEGACY | |
| description: Enable when sending to an Android TV device. | |
| default: false | |
| selector: | |
| boolean: {} | |
| tv_position: | |
| name: TV Notification Position | |
| description: Set the position of the notification on your TV | |
| default: center | |
| selector: | |
| select: | |
| mode: dropdown | |
| options: | |
| - bottom-right | |
| - bottom-left | |
| - top-right | |
| - top-left | |
| - center | |
| sort: false | |
| custom_value: false | |
| multiple: false | |
| tv_size: | |
| name: TV Notification Size | |
| description: Set the size of the notification on your TV. | |
| default: large | |
| selector: | |
| select: | |
| mode: dropdown | |
| options: | |
| - small | |
| - medium | |
| - large | |
| - max | |
| sort: false | |
| custom_value: false | |
| multiple: false | |
| tv_duration: | |
| name: TV Notification Duration | |
| description: Duration Notifications will display on your TV. (seconds) | |
| default: 10 | |
| selector: | |
| number: | |
| max: 300.0 | |
| min: 0.0 | |
| unit_of_measurement: seconds | |
| step: 1.0 | |
| mode: slider | |
| tv_transparency: | |
| name: TV notification Transparency | |
| description: Set the transparency of the notification on your TV. | |
| default: 0% | |
| selector: | |
| select: | |
| mode: dropdown | |
| options: | |
| - 0% | |
| - 25% | |
| - 50% | |
| - 75% | |
| - 100% | |
| sort: false | |
| custom_value: false | |
| multiple: false | |
| tv_interrupt: | |
| name: TV Notification Interrupt | |
| description: | | |
| Makes the notification interactive — it can be dismissed or expanded for more detail. | |
| ⚠️ May interrupt playback depending on the running app (e.g. Netflix). | |
| default: false | |
| selector: | |
| boolean: {} | |
| # ------------------------------------------------------------ | |
| # iOS OPTIONS | |
| # ------------------------------------------------------------ | |
| ios_section: | |
| name: iOS Options | |
| description: These only work on iOS | |
| icon: mdi:apple-ios | |
| collapsed: true | |
| input: | |
| notification_sound: | |
| name: Notification Sound - iOS Only | |
| description: | | |
| Sound file to play with the notification. Import a custom file into Home Assistant, or use a [pre-installed sound](https://companion.home-assistant.io/docs/notifications/notification-sounds/#pre-installed-notification-sounds). | |
| Example: `US-EN-Alexa-Motion-Detected-Generic.wav` | |
| default: default | |
| selector: | |
| select: | |
| mode: dropdown | |
| options: | |
| - label: Default | |
| value: default | |
| - label: None | |
| value: none | |
| - label: Alexa Motion Detected | |
| value: US-EN-Alexa-Motion-Detected-Generic.wav | |
| - label: Morgan Freeman Motion Detected | |
| value: US-EN-Morgan-Freeman-Motion-Detected.wav | |
| custom_value: true | |
| sort: false | |
| multiple: false | |
| notification_volume: | |
| name: Volume Sound - iOS Only | |
| description: Notification sound volume (iOS only). | |
| default: 1 | |
| selector: | |
| number: | |
| max: 1.0 | |
| min: 0.0 | |
| unit_of_measurement: '%' | |
| step: 1.0 | |
| mode: slider | |
| notification_critical: | |
| name: Critical Notification - iOS Only | |
| description: Bypasses silent and vibrate modes — notification will always play a sound. | |
| default: false | |
| selector: | |
| boolean: {} | |
| # ------------------------------------------------------------ | |
| # FILE STORAGE OPTIONS | |
| # ------------------------------------------------------------ | |
| storage_section: | |
| name: File Storage Options | |
| description: Configure where snapshots are saved | |
| icon: mdi:folder-image | |
| collapsed: true | |
| input: | |
| file_path: | |
| name: File Path | |
| description: | | |
| Path where the latest snapshot is saved. Do **not** add `/local` — the blueprint handles that automatically. | |
| Default: `/media/snapshots/<camera_name>/last_motion.jpg` | |
| If you have issues try: `/config/www/snapshots/{{ states[camera].object_id }}/last_motion.jpg` | |
| default: /media/snapshots/{{ states[camera].object_id }}/last_motion.jpg | |
| save_archive_file: | |
| name: Save Archive Files? | |
| description: When enabled, each snapshot is also saved to the archive path with a timestamp. | |
| default: false | |
| selector: | |
| boolean: {} | |
| conditionSave: | |
| name: Conditions to Archive Snapshot | |
| description: Optional conditions to evaluate before saving the archive snapshot. | |
| default: [] | |
| selector: | |
| condition: {} | |
| archive_file_path: | |
| name: Archive File Path | |
| description: | | |
| Path for archived snapshots. Do **not** add `/local` — handled automatically. | |
| Default: `/media/snapshots/<camera_name>/archive/` | |
| default: /media/snapshots/{{ states[camera].object_id }}/archive/motion_{{ now().strftime("%Y%m%d-%H%M%S") }}.jpg | |
| # ------------------------------------------------------------ | |
| # EXPERT SETTINGS | |
| # ------------------------------------------------------------ | |
| expert_section: | |
| name: Expert Settings | |
| description: Changes automation behavior - make sure you know what you are doing! | |
| icon: mdi:tune | |
| collapsed: true | |
| input: | |
| # ── NEW: Global Cooldown ────────────────────────────────── | |
| cooldown_time: | |
| name: Global Cooldown | |
| description: | | |
| Seconds to wait after the automation finishes before allowing it to run again. | |
| ... no snapshot or actions will run for this period of time after the last run. | |
| Set to 0 to disable. | |
| ⚠️ Execution Mode must be **Single** for Cooldown to work consistantly. | |
| Common values: 30, 60, 120, 300 (5 min). | |
| default: 0 | |
| selector: | |
| number: | |
| min: 0 | |
| max: 3600 | |
| unit_of_measurement: seconds | |
| mode: slider | |
| step: 5 | |
| # ───────────────────────────────────────────────────────── | |
| mode_select: | |
| name: Execution Mode Select | |
| description: | | |
| **Single** — recommended for most use cases. New triggers are dropped while the automation is running. | |
| **Restart** — cancels the current run and starts fresh on each new trigger. | |
| **Queued** — queues additional triggers to run after the current one finishes. | |
| **Parallel** — allows multiple simultaneous runs. | |
| default: single | |
| selector: | |
| select: | |
| mode: dropdown | |
| options: | |
| - label: 'Single' | |
| value: 'single' | |
| - label: 'Restart' | |
| value: 'restart' | |
| - label: 'Queued' | |
| value: 'queued' | |
| - label: 'Parallel' | |
| value: 'parallel' | |
| # ------------------------------------------------------------ | |
| # TRIGGER | |
| # ------------------------------------------------------------ | |
| trigger: !input trigger_additional | |
| # ------------------------------------------------------------ | |
| # VARIABLES | |
| # ------------------------------------------------------------ | |
| variables: | |
| use_conditions: !input use_conditions | |
| camera: !input camera | |
| camera_name: '{{ states[camera].name }}' | |
| notify_device: !input notify_device | |
| time: '{{ now().strftime("%H:%M") }}' | |
| date: '{{ now().strftime("%Y-%m-%d") }}' | |
| notification_title: !input notification_title | |
| notification_message: !input notification_message | |
| file_path: !input file_path | |
| archive_file_path: !input archive_file_path | |
| delay: !input delay | |
| delay_notification: !input delay_notification | |
| snapshot_create_file_path: !input file_path | |
| snapshot_access_file_path: '{{ snapshot_create_file_path | replace(''/config/www'', ''/local'') | replace(''/media'', ''/media/local'') }}' | |
| condition: !input condition | |
| conditionSave: !input conditionSave | |
| notification_click_url_input: !input notification_click_url_input | |
| notification_click_url: "{{ notification_click_url_input if notification_click_url_input else 'entityId:' ~ camera }}" | |
| save_archive_file: !input save_archive_file | |
| additional_actions: !input additional_actions | |
| additional_actions_before: !input additional_actions_before | |
| notify: !input notify | |
| notify_group: !input notify_group | |
| notify_group_target: "{{ notify_group | lower | regex_replace('^notify\\.', '') | replace(' ','_') }}" | |
| notification_channel: !input notification_channel | |
| notification_group: !input notification_group | |
| notification_sticky: !input notification_sticky | |
| notification_color: !input notification_color | |
| notification_critical: !input notification_critical | |
| notification_alert_once: !input notification_alert_once | |
| notification_icon: !input notification_icon | |
| notification_sound: !input notification_sound | |
| notification_volume: !input notification_volume | |
| android_tv: !input android_tv | |
| action_type_1: !input action_type_1 | |
| action_title_1: !input action_title_1 | |
| action_uri_1: !input action_uri_1 | |
| action_type_2: !input action_type_2 | |
| action_title_2: !input action_title_2 | |
| action_uri_2: !input action_uri_2 | |
| action_type_3: !input action_type_3 | |
| action_title_3: !input action_title_3 | |
| action_uri_3: !input action_uri_3 | |
| tv_position: !input tv_position | |
| tv_size: !input tv_size | |
| tv_duration: !input tv_duration | |
| tv_transparency: !input tv_transparency | |
| tv_interrupt: !input tv_interrupt | |
| mode_select: !input mode_select | |
| delay_send: !input delay_send | |
| # NEW: cooldown | |
| cooldown_time: !input cooldown_time | |
| # ------------------------------------------------------------ | |
| # CONDITIONS | |
| # ------------------------------------------------------------ | |
| condition: | |
| - condition: or | |
| conditions: | |
| - condition: template | |
| value_template: "{{ use_conditions == false }}" | |
| - condition: and | |
| conditions: | |
| - condition: template | |
| value_template: "{{ use_conditions == true }}" | |
| - condition: !input custom_conditions | |
| # ------------------------------------------------------------ | |
| # ACTIONS | |
| # ------------------------------------------------------------ | |
| action: | |
| - choose: [] | |
| default: !input additional_actions_before | |
| - delay: !input delay | |
| - service: camera.snapshot | |
| entity_id: !input camera | |
| data: | |
| filename: !input file_path | |
| - delay: !input delay_send | |
| - if: | |
| - condition: template | |
| value_template: !input notify | |
| then: | |
| - if: | |
| - condition: !input condition | |
| then: | |
| - if: | |
| - condition: template | |
| value_template: '{{ not this.attributes.last_triggered or (now() - this.attributes.last_triggered).seconds > delay_notification }}' | |
| then: | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ notify_group_target != "" and android_tv }}' | |
| sequence: | |
| - service: notify.{{ notify_group_target }} | |
| data: | |
| title: !input notification_title | |
| message: !input notification_message | |
| data: | |
| channel: !input notification_channel | |
| group: !input notification_group | |
| color: !input notification_color | |
| clickAction: '{{ notification_click_url }}' | |
| sticky: !input notification_sticky | |
| notification_icon: !input notification_icon | |
| ttl: 0 | |
| priority: high | |
| image: | |
| path: '{{ snapshot_access_file_path }}' | |
| fontsize: '{{tv_size}}' | |
| position: '{{tv_position}}' | |
| duration: '{{tv_duration}}' | |
| transparency: '{{tv_transparency}}' | |
| interrupt: '{{tv_interrupt}}' | |
| timeout: 30 | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ notify_group_target != "" and not android_tv }}' | |
| sequence: | |
| - service: notify.{{ notify_group_target }} | |
| data_template: | |
| title: '{{ notification_title }}' | |
| message: '{{ notification_message }}' | |
| data: | |
| channel: '{{ notification_channel }}' | |
| group: '{{ notification_group }}' | |
| color: '{{ notification_color }}' | |
| image: '{{ snapshot_access_file_path }}' | |
| clickAction: '{{ notification_click_url }}' | |
| sticky: '{{ notification_sticky }}' | |
| alert_once: '{{ notification_alert_once }}' | |
| notification_icon: '{{ notification_icon }}' | |
| ttl: 0 | |
| priority: high | |
| attachment: | |
| url: '{{ snapshot_access_file_path }}' | |
| content_type: JPEG | |
| url: '{{ notification_click_url }}' | |
| push: | |
| sound: | |
| name: '{{ notification_sound }}' | |
| volume: '{{ notification_volume }}' | |
| critical: '{{ 1 if notification_critical else 0 }}' | |
| actions: > | |
| [{% if action_type_1 != "disabled" %} | |
| { | |
| "action": "{{ action_type_1 }}", | |
| "title": "{{ action_title_1 }}" | |
| {% if action_type_1 == "URI" and action_uri_1 %}, | |
| "uri": "{{ action_uri_1 }}" | |
| {% endif %} | |
| }{% endif %} | |
| {% if action_type_2 != "disabled" %}{% if action_type_1 != "disabled" %},{% endif %} | |
| { | |
| "action": "{{ action_type_2 }}", | |
| "title": "{{ action_title_2 }}" | |
| {% if action_type_2 == "URI" and action_uri_2 %}, | |
| "uri": "{{ action_uri_2 }}" | |
| {% endif %} | |
| }{% endif %} | |
| {% if action_type_3 != "disabled" %}{% if action_type_1 != "disabled" or action_type_2 != "disabled" %},{% endif %} | |
| { | |
| "action": "{{ action_type_3 }}", | |
| "title": "{{ action_title_3 }}" | |
| {% if action_type_3 == "URI" and action_uri_3 %}, | |
| "uri": "{{ action_uri_3 }}" | |
| {% endif %} | |
| }{% endif %} | |
| ] | |
| default: | |
| - condition: template | |
| value_template: '{{ notify_device != false }}' | |
| - repeat: | |
| for_each: !input notify_device | |
| sequence: | |
| - variables: | |
| # Explicitly scope the path variable inside the loop sequence | |
| img_path: '{{ snapshot_access_file_path }}' | |
| - service: "notify.mobile_app_{{ device_attr(repeat.item, 'name') | slugify }}" | |
| data_template: | |
| title: '{{ notification_title }}' | |
| message: '{{ notification_message }}' | |
| data: | |
| # Android standard key | |
| image: '{{ img_path }}' | |
| # iOS standard key | |
| attachment: | |
| url: '{{ img_path }}' | |
| content_type: JPEG | |
| channel: '{{ notification_channel }}' | |
| group: '{{ notification_group }}' | |
| color: '{{ notification_color }}' | |
| clickAction: '{{ notification_click_url }}' | |
| sticky: '{{ notification_sticky }}' | |
| alert_once: '{{ notification_alert_once }}' | |
| notification_icon: '{{ notification_icon }}' | |
| ttl: 0 | |
| priority: high | |
| url: '{{ notification_click_url }}' | |
| push: | |
| sound: | |
| name: '{{ notification_sound }}' | |
| volume: '{{ notification_volume }}' | |
| critical: '{{ notification_critical }}' | |
| actions: > | |
| [{% if action_type_1 != "disabled" %} | |
| { | |
| "action": "{{ action_type_1 }}", | |
| "title": "{{ action_title_1 }}" | |
| {% if action_type_1 == "URI" and action_uri_1 %}, | |
| "uri": "{{ action_uri_1 }}" | |
| {% endif %} | |
| }{% endif %} | |
| {% if action_type_2 != "disabled" %}{% if action_type_1 != "disabled" %},{% endif %} | |
| { | |
| "action": "{{ action_type_2 }}", | |
| "title": "{{ action_title_2 }}" | |
| {% if action_type_2 == "URI" and action_uri_2 %}, | |
| "uri": "{{ action_uri_2 }}" | |
| {% endif %} | |
| }{% endif %} | |
| {% if action_type_3 != "disabled" %}{% if action_type_1 != "disabled" or action_type_2 != "disabled" %},{% endif %} | |
| { | |
| "action": "{{ action_type_3 }}", | |
| "title": "{{ action_title_3 }}" | |
| {% if action_type_3 == "URI" and action_uri_3 %}, | |
| "uri": "{{ action_uri_3 }}" | |
| {% endif %} | |
| }{% endif %} | |
| ] | |
| - if: | |
| - condition: template | |
| value_template: !input save_archive_file | |
| then: | |
| - if: | |
| - condition: !input conditionSave | |
| then: | |
| - service: camera.snapshot | |
| entity_id: !input camera | |
| data: | |
| filename: !input archive_file_path | |
| - choose: [] | |
| default: !input additional_actions | |
| # NEW: Cooldown — hold the automation open so Single mode blocks re-triggers. | |
| # Set Execution Mode to Single for this to work correctly. | |
| - if: | |
| - condition: template | |
| value_template: "{{ cooldown_time > 0 }}" | |
| then: | |
| - delay: | |
| seconds: "{{ cooldown_time }}" | |
| mode: !input mode_select |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment