Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save Ltek/0c9cecf632b9c32915130680d834bcf7 to your computer and use it in GitHub Desktop.

Select an option

Save Ltek/0c9cecf632b9c32915130680d834bcf7 to your computer and use it in GitHub Desktop.
Home Assistant Blueprint: Offline Devices Report
blueprint:
name: "⛔ Offline Devices Report with Notification Actions"
description: |
Offline Devices Report with Notification Actions
🚀 Version 2025.12.01.01
***Features***
📱 Device Notifications
- Send alerts to mobile devices via mobile_app integration
- iOS and Android specific notification options
- Configurable interruption levels and sounds
📢 Persistent Web UI Notifications
- Dashboard notifications for offline devices
- Optional "no issues" confirmation messages
🧭️ Execution methods
- Schedule Time and Day(s)
- Manual trigger via button
🚫️ Entity exclusion options
- Directly select specific entities
- Pattern-based exclusions using text strings
- Case-sensitive matching for precise control
🎯 Flexible display formats
- Friendly names only
- Entity IDs only
- Combined format (Friendly Name + Entity ID)
🎬 Custom actions after report
- Add offline devices to To-Do list automatically
- Action buttons in notifications for manual control
- Custom automation actions integration
- {{ offline_devices }} variable returns a formatted list of offline devices
- {{ offline_devices_count }} variable returns the count of offline devices
🔋 Smart device detection
- Automatic battery sensor identification
- Switch monitoring for offline states
- Combined or separate reporting options
📖 Logging
- Debug to Logbook
- Easy troubleshooting configuration
domain: automation
input:
trigger_settings:
name: ⚙️ Trigger Settings
description: You must enable at least one.
collapsed: true
input:
include_button:
name: Use Button Trigger?
description: Enable manual triggering via button
default: disable_button_trigger
selector:
select:
options:
- label: Enabled
value: enable_button_trigger
- label: Disabled
value: disable_button_trigger
button_entity:
name: Set Button Trigger
description: Button that will trigger the automation
default: []
selector:
entity:
domain:
- input_button
multiple: false
include_time:
name: Use an Automatic Reoccuring Report?
description: Day and Time to automatically run the report
default: time_disabled
selector:
select:
options:
- label: Enabled
value: time_enabled
- label: Disabled
value: time_disabled
time:
name: Set Reoccuring Time
description: When to run automatic checks
default: "05:00:00"
selector:
time: {}
weekday_options:
name: Set Reoccuring Days
description: Must select at least one day when enabled
default:
- mon
- tue
- wed
- thu
- fri
- sat
- sun
selector:
select:
multiple: true
mode: list
options:
- label: Monday
value: mon
- label: Tuesday
value: tue
- label: Wednesday
value: wed
- label: Thursday
value: thu
- label: Friday
value: fri
- label: Saturday
value: sat
- label: Sunday
value: sun
device_settings:
name: "🚫 Exclusion Settings"
description: Configure device monitoring parameters
collapsed: true
input:
exclude_entities:
name: Individual Entities
description: Manually select entities to ignore
default:
entity_id: []
selector:
target:
entity: []
exclude_strings:
name: Text Pattern Exclusions
description: 'Exclude entities containing specific text
type in one string per line ... CaSe SenSative!
Examples:
sensor.phone
_battery
temperature'
default: ''
selector:
text:
multiline: true
notification_settings:
name: "📢 Notification Settings"
description: Configure alert preferences
collapsed: true
input:
include_easy_notify:
name: Device Notifications
default: disabled_easy_notify
selector:
select:
options:
- label: Disabled
value: disabled_easy_notify
- label: Enabled
value: enable_easy_notify
- label: Enabled with No Issues confirmation
value: enable_easy_okay_notify
notify_device:
name: Devices to Notify
description: Select at least one if Device Notifications are enabled
default: []
selector:
device:
integration: mobile_app
multiple: true
notify_title:
name: Notification Title
default: Offline Devices Report
selector:
text: {}
notify_message:
name: Message Format
default: all_sensors
selector:
select:
options:
- label: All Offline Devices
value: all_sensors
- label: Only Battery Sensors
value: sensors
- label: Only Switches
value: switches
notify_okay_message:
name: No Issues Confirmation Message
default: No offline devices detected
selector:
text: {}
notify_interruption_level:
name: iOS Interruption Level
description: only for iOS
default: active
selector:
select:
options:
- label: Default
value: active
- label: Critical Notifications
value: critical
- label: Time Sensitive Notifications
value: time-sensitive
- label: Quiet Notifications Without Waking Screen
value: passive
notify_sound:
name: iOS Notification Sound
description: only for iOS
default: ''
selector:
text: {}
notify_data:
name: Android Options
description: Android-specific notification options
default: []
selector:
select:
multiple: true
options:
- label: High Priority
value: high_priority
- label: Sticky Notification
value: sticky
- label: Notification Channel
value: channel
notify_channel:
name: Android Notification Channel
description: only for Android
default: ''
selector:
text: {}
include_persistent_notification:
name: Persistent Notification
default: disabled_persistent_notification
selector:
select:
options:
- label: Disabled
value: disabled_persistent_notification
- label: Enabled
value: enable_persistent_notification
- label: Enabled with No Issues confirmation
value: enable_persistent_okay_notification
display_options:
name: Display Options
description: What the notifications will show
default: friendly_names
selector:
select:
options:
- label: Entity IDs
value: entity_ids
- label: Friendly Names
value: friendly_names
- label: Both
value: both
action_buttons_settings:
name: "🚀 Action Buttons"
description: Configure notification actions
collapsed: true
input:
auto_add_to_do:
name: Automatically Add to To-Do List
description: Automatically add offline devices to the To-Do list without requiring action button press
default: disable_auto_add_to_do
selector:
select:
options:
- label: Disabled
value: disable_auto_add_to_do
- label: Enabled
value: enable_auto_add_to_do
notify_tag:
name: Notification Action Tag
description: A unique tag to identify the action buttons for this notification. Helps prevent interference from other notifications.
default: offline_devices_report_action
selector:
text: {}
notify_action_buttons:
name: Action Buttons
default: disabled_notify_action_buttons
selector:
select:
options:
- label: Disabled
value: disabled_notify_action_buttons
- label: Add To-Do Button
value: enable_to_do_list_button
- label: Add To-Do with Confirmation
value: enable_to_do_list_button_and_confirmation
to_do_list:
name: To-Do List
default: []
selector:
entity:
domain:
- todo
multiple: false
to_do_task_title:
name: Task Title
default: Check Offline Devices
selector:
text: {}
action_button_to_do:
name: Action Button Text
default: Add to To-Do List
selector:
text: {}
action_button_cancel:
name: Cancel Button Text
default: Cancel
selector:
text: {}
action_button_confirmation_title:
name: Confirmation Title
default: Action Confirmation
selector:
text: {}
action_button_confirmation_message:
name: Confirmation Message
default: Task added to To-Do list
selector:
text: {}
cancel_action_button_confirmation_message:
name: Cancel Confirmation Message
default: Action cancelled
selector:
text: {}
custom_actions_settings:
name: ⚡ Custom Actions
description: Additional actions to run
collapsed: true
input:
include_custom_actions:
name: Enable Custom Actions
default: disabled_custom_actions
selector:
select:
options:
- label: Enabled
value: enable_custom_actions
- label: Disabled
value: disable_custom_actions
custom_actions:
name: Custom Actions
default: []
selector:
action: {}
global_conditions_settings:
name: "🌍 Global Conditions"
description: Additional conditions for automation
collapsed: true
input:
global_conditions:
name: Conditions
default: []
selector:
condition: {}
debug_settings:
name: "🛠 Debug Settings"
description: Configure debug options
collapsed: true
input:
include_logbook_debug:
name: Enable Logbook Debug
description: Enable or disable logging debug information
default: enable_logbook_debug
selector:
select:
options:
- label: Enabled
value: enable_logbook_debug
- label: Disabled
value: disable_logbook_debug
variables:
include_button: !input include_button
include_time: !input include_time
weekday_options: !input weekday_options
exclude_entities: !input exclude_entities
exclude_strings: !input exclude_strings
display_options: !input display_options
include_easy_notify: !input include_easy_notify
notify_device: !input notify_device
notify_title: !input notify_title
notify_message: !input notify_message
notify_okay_message: !input notify_okay_message
notify_interruption_level: !input notify_interruption_level
notify_sound: !input notify_sound
notify_data: !input notify_data
notify_channel: !input notify_channel
include_persistent_notification: !input include_persistent_notification
notify_action_buttons: !input notify_action_buttons
auto_add_to_do: !input auto_add_to_do
notify_tag: !input notify_tag
to_do_list: !input to_do_list
to_do_task_title: !input to_do_task_title
action_button_to_do: !input action_button_to_do
action_button_cancel: !input action_button_cancel
action_button_confirmation_title: !input action_button_confirmation_title
action_button_confirmation_message: !input action_button_confirmation_message
cancel_action_button_confirmation_message: !input cancel_action_button_confirmation_message
include_custom_actions: !input include_custom_actions
exclude_regex: "{% if exclude_strings is defined %}\n {% set patterns = exclude_strings.split('\\n') | map('trim') | reject('eq', '') | list %}\n {{ patterns | join('|') if patterns else 'a^' }}\n{% else %}\n a^\n{% endif %}"
all_exclude_entities: "{% if exclude_entities is defined %}\n {% set labels = label_entities(exclude_entities.label_id) if exclude_entities.label_id is defined and exclude_entities.label_id else [] %}\n {% set entities = exclude_entities.entity_id if exclude_entities.entity_id is defined and exclude_entities.entity_id else [] %}\n {{ (labels + entities) | unique | list }}\n{% else %}\n []\n{% endif %}"
# Core offline devices logic
_offline_devices: >
{% set exclude_entities_list = all_exclude_entities if all_exclude_entities is iterable else [all_exclude_entities] %}
{% set entities = states | map(attribute='entity_id') | reject('search', 'cloud') | reject('in', exclude_entities_list) | reject('search', exclude_regex) | list %}
{% set sensors = entities | select('search', '^(sensor|binary_sensor)') | list %}
{% set battery_entities = sensors | select('is_state_attr', 'device_class', 'battery') | reject('has_value') | list %}
{% set switches = entities | select('search', '^switch') | reject('has_value') | list %}
{% set offline_entities = (battery_entities + switches) | unique %}
{% if display_options == 'entity_ids' %}
{{ offline_entities | list }}
{% elif display_options == 'friendly_names' %}
{{ offline_entities | map('state_attr', 'friendly_name') | list }}
{% elif display_options == 'both' %}
{% set result = namespace(items=[]) %}
{% for e in offline_entities %}
{% set friendly_name = state_attr(e, 'friendly_name') %}
{% set item = friendly_name ~ ' (' ~ e ~ ')' if friendly_name else e %}
{% set result.items = result.items + [item] %}
{% endfor %}
{{ result.items }}
{% else %}
[]
{% endif %}
offline_devices: >
{% if _offline_devices | length > 0 %}
{{ '- ' ~ (_offline_devices | sort | join('\n- ')) }}
{% else %}
No offline devices detected.
{% endif %}
offline_devices_count: >
{{ _offline_devices | length }}
# Separate battery sensors and switches for notification options
_battery_sensors: >
{% set exclude_entities_list = all_exclude_entities if all_exclude_entities is iterable else [all_exclude_entities] %}
{% set entities = states | map(attribute='entity_id') | reject('search', 'cloud') | reject('in', exclude_entities_list) | reject('search', exclude_regex) | list %}
{% set sensors = entities | select('search', '^(sensor|binary_sensor)') | list %}
{% set battery_entities = sensors | select('is_state_attr', 'device_class', 'battery') | reject('has_value') | list %}
{% if display_options == 'entity_ids' %}
{{ battery_entities | list }}
{% elif display_options == 'friendly_names' %}
{{ battery_entities | map('state_attr', 'friendly_name') | list }}
{% elif display_options == 'both' %}
{% set result = namespace(items=[]) %}
{% for e in battery_entities %}
{% set friendly_name = state_attr(e, 'friendly_name') %}
{% set item = friendly_name ~ ' (' ~ e ~ ')' if friendly_name else e %}
{% set result.items = result.items + [item] %}
{% endfor %}
{{ result.items }}
{% else %}
[]
{% endif %}
_switches: >
{% set exclude_entities_list = all_exclude_entities if all_exclude_entities is iterable else [all_exclude_entities] %}
{% set entities = states | map(attribute='entity_id') | reject('search', 'cloud') | reject('in', exclude_entities_list) | reject('search', exclude_regex) | list %}
{% set switches = entities | select('search', '^switch') | reject('has_value') | list %}
{% if display_options == 'entity_ids' %}
{{ switches | list }}
{% elif display_options == 'friendly_names' %}
{{ switches | map('state_attr', 'friendly_name') | list }}
{% elif display_options == 'both' %}
{% set result = namespace(items=[]) %}
{% for e in switches %}
{% set friendly_name = state_attr(e, 'friendly_name') %}
{% set item = friendly_name ~ ' (' ~ e ~ ')' if friendly_name else e %}
{% set result.items = result.items + [item] %}
{% endfor %}
{{ result.items }}
{% else %}
[]
{% endif %}
# Formatted messages for notifications
all_sensors: >
{% if _offline_devices | length > 0 %}
{{ '' ~ offline_devices_count ~ ' Offline Devices\n\n' ~ ('- ' ~ (_offline_devices | sort | join('\n- '))) }}
{% else %}
''
{% endif %}
sensors: >
{% if _battery_sensors | length > 0 %}
{{ '🔋 ' ~ _battery_sensors | length ~ ' Offline Battery Sensor(s):\n\n' ~ ('- ' ~ (_battery_sensors | sort | join('\n- '))) }}
{% else %}
''
{% endif %}
switches: >
{% if _switches | length > 0 %}
{{ '🔌 ' ~ _switches | length ~ ' Offline Switch(es):\n\n' ~ ('- ' ~ (_switches | sort | join('\n- '))) }}
{% else %}
''
{% endif %}
# Message selection for notifications
easy_notify_message: >
{% if notify_message == 'all_sensors' %}
{{ all_sensors if all_sensors else '' }}
{% elif notify_message == 'sensors' %}
{{ sensors if sensors else '' }}
{% elif notify_message == 'switches' %}
{{ switches if switches else '' }}
{% else %}
''
{% endif %}
# Names only for To-Do list
sensors_names: >
{% if _battery_sensors | length > 0 %}
{{ (_battery_sensors | list | sort | join('\n')) }}
{% else %}
''
{% endif %}
switches_names: >
{% if _switches | length > 0 %}
{{ (_switches | list | sort | join('\n')) }}
{% else %}
''
{% endif %}
# Notification data templates
device_message_data: >
{% set message = namespace(data={}) %}
{% set push = namespace(data={}) %}
{% if notify_interruption_level in ['active', 'critical', 'time-sensitive', 'passive'] %}
{% set push.data = dict(push.data, **{ 'interruption-level': notify_interruption_level }) %}
{% endif %}
{% if notify_sound != '' %}
{% set push.data = dict(push.data, **{ 'sound': notify_sound }) %}
{% endif %}
{% if push.data %}
{% set message.data = dict(message.data, **{ 'push': push.data }) %}
{% endif %}
{% if 'high_priority' in notify_data %}
{% set message.data = dict(message.data, **{ 'ttl': 0, 'priority': 'high' }) %}
{% endif %}
{% if 'channel' in notify_data %}
{% set message.data = dict(message.data, **{ 'channel': notify_channel }) %}
{% endif %}
{% if 'sticky' in notify_data %}
{% set message.data = dict(message.data, **{ 'sticky': "true" }) %}
{% endif %}
{% set message.data = dict(message.data, **{ 'tag': notify_tag }) %}
{{ message.data }}
device_message_data_action_button: >
{% set message = namespace(data={}) %}
{% set push = namespace(data={}) %}
{% if notify_interruption_level in ['active', 'critical', 'time-sensitive', 'passive'] %}
{% set push.data = dict(push.data, **{ 'interruption-level': notify_interruption_level }) %}
{% endif %}
{% if notify_sound != '' %}
{% set push.data = dict(push.data, **{ 'sound': notify_sound }) %}
{% endif %}
{% if push.data %}
{% set message.data = dict(message.data, **{ 'push': push.data }) %}
{% endif %}
{% if 'high_priority' in notify_data %}
{% set message.data = dict(message.data, **{ 'ttl': 0, 'priority': 'high' }) %}
{% endif %}
{% if 'channel' in notify_data %}
{% set message.data = dict(message.data, **{ 'channel': notify_channel }) %}
{% endif %}
{% if 'sticky' in notify_data %}
{% set message.data = dict(message.data, **{ 'sticky': "true" }) %}
{% endif %}
{% set actions = [
{'action': action_button_to_do, 'title': action_button_to_do},
{'action': action_button_cancel, 'title': action_button_cancel}
] %}
{% set message.data = dict(message.data, **{ 'actions': actions, 'tag': notify_tag }) %}
{{ message.data }}
device_confirmation_message_data: >
{% set message = namespace(data={}) %}
{% set push = namespace(data={}) %}
{% if notify_interruption_level in ['active', 'critical', 'time-sensitive', 'passive'] %}
{% set push.data = dict(push.data, **{ 'interruption-level': notify_interruption_level }) %}
{% endif %}
{% if notify_sound != '' %}
{% set push.data = dict(push.data, **{ 'sound': notify_sound }) %}
{% endif %}
{% if push.data %}
{% set message.data = dict(message.data, **{ 'push': push.data }) %}
{% endif %}
{% if 'high_priority' in notify_data %}
{% set message.data = dict(message.data, **{ 'ttl': 0, 'priority': 'high' }) %}
{% endif %}
{% if 'channel' in notify_data %}
{% set message.data = dict(message.data, **{ 'channel': notify_channel }) %}
{% endif %}
{% if 'sticky' in notify_data %}
{% set message.data = dict(message.data, **{ 'sticky': "true" }) %}
{% endif %}
{% set message.data = dict(message.data, **{ 'tag': notify_tag }) %}
{{ message.data }}
trigger:
- platform: state
entity_id: !input button_entity
id: button_trigger
- platform: time
at: !input time
id: time_trigger
condition:
- condition: or
conditions:
- condition: and
conditions:
- condition: trigger
id: button_trigger
- condition: template
value_template: '{{ include_button == ''enable_button_trigger'' }}'
- condition: and
conditions:
- condition: trigger
id: time_trigger
- condition: template
value_template: '{{ include_time == ''time_enabled'' }}'
- condition: template
value_template: '{{ now().strftime(''%a'').lower() in weekday_options }}'
- condition: and
conditions: !input global_conditions
action:
- service: logbook.log
data:
name: Offline Devices Report Debug
message: 'Initial: include_easy_notify: {{ include_easy_notify | default(''undefined'') }}, include_persistent_notification: {{ include_persistent_notification | default(''undefined'') }}, notify_device: {{ notify_device | default(''undefined'') }}, offline_devices_count: {{ offline_devices_count | default(''0'') }}, _battery_sensors_count: {{ _battery_sensors | length | default(''0'') }}, _switches_count: {{ _switches | length | default(''0'') }}, easy_notify_message: {{ easy_notify_message | default(''undefined'') }}, to_do_list: {{ to_do_list | default(''undefined'') }}'
- choose:
- alias: Use the easy notify options
conditions:
- condition: template
value_template: '{{ include_easy_notify == ''enable_easy_notify'' or include_easy_notify == ''enable_easy_okay_notify'' }}'
- condition: template
value_template: '{{ notify_device | length > 0 }}'
sequence:
- alias: Send a notification to each device
repeat:
for_each: '{{ notify_device | default([]) }}'
sequence:
- choose:
- alias: Offline devices have been found
conditions:
- condition: template
value_template: '{{ easy_notify_message != '''' }}'
sequence:
- choose:
- alias: Easy notify with no action button
conditions:
- condition: template
value_template: '{{ notify_action_buttons == ''disabled_notify_action_buttons'' or auto_add_to_do == ''enable_auto_add_to_do'' }}'
sequence:
- service: notify.mobile_app_{{ device_attr(repeat.item, 'name') | slugify }}
data:
title: !input notify_title
message: '{{ easy_notify_message }}'
data: '{{ device_message_data }}'
- service: logbook.log
data:
name: Offline Devices Report Debug
message: 'Sent notification without action buttons to device: {{ device_attr(repeat.item, ''name'') | slugify }}, service: notify.mobile_app_{{ device_attr(repeat.item, ''name'') | slugify }}, tag: {{ notify_tag }}, message: {{ easy_notify_message }}'
- alias: Easy notify with action button
conditions:
- condition: template
value_template: '{{ notify_action_buttons != ''disabled_notify_action_buttons'' and auto_add_to_do != ''enable_auto_add_to_do'' }}'
sequence:
- service: notify.mobile_app_{{ device_attr(repeat.item, 'name') | slugify }}
data:
title: !input notify_title
message: '{{ easy_notify_message }}'
data: '{{ device_message_data_action_button }}'
- service: logbook.log
data:
name: Offline Devices Report Debug
message: 'Sent notification with action buttons to device: {{ device_attr(repeat.item, ''name'') | slugify }}, service: notify.mobile_app_{{ device_attr(repeat.item, ''name'') | slugify }}, tag: {{ notify_tag }}, actions: {{ device_message_data_action_button }}'
- alias: No offline devices have been found
conditions:
- condition: template
value_template: '{{ easy_notify_message == '''' }}'
- condition: template
value_template: '{{ include_easy_notify == ''enable_easy_okay_notify'' }}'
sequence:
- service: notify.mobile_app_{{ device_attr(repeat.item, 'name') | slugify }}
data:
title: !input notify_title
message: !input notify_okay_message
data: '{{ device_message_data }}'
- service: logbook.log
data:
name: Offline Devices Report Debug
message: 'Sent no-issues notification to device: {{ device_attr(repeat.item, ''name'') | slugify }}, service: notify.mobile_app_{{ device_attr(repeat.item, ''name'') | slugify }}, tag: {{ notify_tag }}, message: {{ notify_okay_message }}'
- choose:
- alias: Use the easy notify persistent notification options
conditions:
- condition: template
value_template: '{{ include_persistent_notification == ''enable_persistent_notification'' or include_persistent_notification == ''enable_persistent_okay_notification'' }}'
sequence:
- choose:
- alias: Offline devices have been found
conditions:
- condition: template
value_template: '{{ easy_notify_message != '''' }}'
sequence:
- service: persistent_notification.create
data:
title: "⛔ {{ notify_title }}"
message: '{{ easy_notify_message }}'
notification_id: offline_devices_report
- service: logbook.log
data:
name: Offline Devices Report Debug
message: 'Created persistent notification, id: offline_devices_report, message: {{ easy_notify_message }}'
- alias: No offline devices have been found
conditions:
- condition: template
value_template: '{{ easy_notify_message == '''' }}'
- condition: template
value_template: '{{ include_persistent_notification == ''enable_persistent_okay_notification'' }}'
sequence:
- service: persistent_notification.create
data:
title: "⛔ {{ notify_title }}"
message: !input notify_okay_message
notification_id: offline_devices_report_ok
- service: logbook.log
data:
name: Offline Devices Report Debug
message: 'Created persistent no-issues notification, id: offline_devices_report_ok, message: {{ notify_okay_message }}'
- choose:
- alias: Automatically add to To-Do list
conditions:
- condition: template
value_template: '{{ auto_add_to_do == ''enable_auto_add_to_do'' }}'
- condition: template
value_template: '{{ easy_notify_message != '''' }}'
- condition: template
value_template: '{{ to_do_list | length > 0 and is_state(to_do_list[0], ''unknown'') == false and is_state(to_do_list[0], ''unavailable'') == false }}'
sequence:
- service: todo.add_item
data:
entity_id: '{{ to_do_list[0] if to_do_list | length > 0 else "" }}'
item: !input to_do_task_title
description: '{{ easy_notify_message }}'
continue_on_error: true
- service: logbook.log
data:
name: Offline Devices Report Debug
message: 'Attempted to automatically add To-Do item to {{ to_do_list[0] if to_do_list | length > 0 else "no_list" }}: title={{ to_do_task_title }}, description={{ easy_notify_message }}, entity_state={{ states(to_do_list[0]) if to_do_list | length > 0 else "not_found" }}'
- if:
- condition: template
value_template: '{{ notify_action_buttons == ''enable_to_do_list_button_and_confirmation'' }}'
then:
- repeat:
for_each: '{{ notify_device | default([]) }}'
sequence:
- service: notify.mobile_app_{{ device_attr(repeat.item, 'name') | slugify }}
data:
title: !input action_button_confirmation_title
message: !input action_button_confirmation_message
data: '{{ device_confirmation_message_data }}'
continue_on_error: true
- service: logbook.log
data:
name: Offline Devices Report Debug
message: 'Sent auto-add confirmation notification to device: {{ device_attr(repeat.item, ''name'') | slugify }}, service: notify.mobile_app_{{ device_attr(repeat.item, ''name'') | slugify }}, tag: {{ notify_tag }}, message: {{ action_button_confirmation_message }}'
- choose:
- alias: Check if the To-Do action button is enabled
conditions:
- condition: template
value_template: '{{ include_easy_notify == ''enable_easy_notify'' or include_easy_notify == ''enable_easy_okay_notify'' }}'
- condition: template
value_template: '{{ notify_action_buttons == ''enable_to_do_list_button'' or notify_action_buttons == ''enable_to_do_list_button_and_confirmation'' }}'
- condition: template
value_template: '{{ auto_add_to_do != ''enable_auto_add_to_do'' }}'
- condition: template
value_template: '{{ notify_device | length > 0 }}'
- condition: template
value_template: '{{ to_do_list | length > 0 and is_state(to_do_list[0], ''unknown'') == false and is_state(to_do_list[0], ''unavailable'') == false }}'
sequence:
- alias: Wait for a response from the action buttons
wait_for_trigger:
- platform: event
event_type: mobile_app_notification_action
event_data:
action: '{{ action_button_to_do }}'
- platform: event
event_type: mobile_app_notification_action
event_data:
action: '{{ action_button_cancel }}'
timeout: 00:15:00
continue_on_timeout: true
- service: logbook.log
data:
name: Offline Devices Report Debug
message: 'Wait for trigger result: {{ wait.trigger | default(''no trigger received'', true) }}, action: {{ wait.trigger.event.data.action if wait.trigger else ''none'' }}, tag: {{ notify_tag if wait.trigger else ''none'' }}, event_data: {{ wait.trigger.event.data if wait.trigger else ''none'' }}'
- choose:
- alias: Check if confirmation message is disabled
conditions:
- condition: template
value_template: '{{ notify_action_buttons == ''enable_to_do_list_button'' }}'
sequence:
- if:
- condition: template
value_template: '{{ wait.trigger is not none and wait.trigger.event.data.action == action_button_to_do }}'
then:
- service: todo.add_item
data:
entity_id: '{{ to_do_list[0] if to_do_list | length > 0 else "" }}'
item: !input to_do_task_title
description: '{{ easy_notify_message }}'
continue_on_error: true
- service: logbook.log
data:
name: Offline Devices Report Debug
message: 'Attempted to add To-Do item to {{ to_do_list[0] if to_do_list | length > 0 else "no_list" }}: title={{ to_do_task_title }}, description={{ easy_notify_message }}, entity_state={{ states(to_do_list[0]) if to_do_list | length > 0 else "not_found" }}'
- if:
- condition: template
value_template: '{{ wait.trigger is not none and wait.trigger.event.data.action == action_button_cancel }}'
then:
- service: logbook.log
data:
name: Offline Devices Report Debug
message: 'Action cancelled for tag: {{ notify_tag }}'
- stop: Stop the automation
- alias: Check if confirmation message is enabled
conditions:
- condition: template
value_template: '{{ notify_action_buttons == ''enable_to_do_list_button_and_confirmation'' }}'
sequence:
- if:
- condition: template
value_template: '{{ wait.trigger is not none and wait.trigger.event.data.action == action_button_to_do }}'
then:
- service: todo.add_item
data:
entity_id: '{{ to_do_list[0] if to_do_list | length > 0 else "" }}'
item: !input to_do_task_title
description: '{{ easy_notify_message }}'
continue_on_error: true
- service: logbook.log
data:
name: Offline Devices Report Debug
message: 'Attempted to add To-Do item to {{ to_do_list[0] if to_do_list | length > 0 else "no_list" }}: title={{ to_do_task_title }}, description={{ easy_notify_message }}, entity_state={{ states(to_do_list[0]) if to_do_list | length > 0 else "not_found" }}'
- repeat:
for_each: '{{ notify_device | default([]) }}'
sequence:
- service: notify.mobile_app_{{ device_attr(repeat.item, 'name') | slugify }}
data:
title: !input action_button_confirmation_title
message: !input action_button_confirmation_message
data: '{{ device_confirmation_message_data }}'
continue_on_error: true
- service: logbook.log
data:
name: Offline Devices Report Debug
message: 'Sent confirmation notification to device: {{ device_attr(repeat.item, ''name'') | slugify }}, service: notify.mobile_app_{{ device_attr(repeat.item, ''name'') | slugify }}, tag: {{ notify_tag }}, message: {{ action_button_confirmation_message }}'
- if:
- condition: template
value_template: '{{ wait.trigger is not none and wait.trigger.event.data.action == action_button_cancel }}'
then:
- repeat:
for_each: '{{ notify_device | default([]) }}'
sequence:
- service: notify.mobile_app_{{ device_attr(repeat.item, 'name') | slugify }}
data:
title: !input action_button_confirmation_title
message: !input cancel_action_button_confirmation_message
data: '{{ device_message_data }}'
continue_on_error: true
- service: logbook.log
data:
name: Offline Devices Report Debug
message: 'Sent cancel confirmation notification to device: {{ device_attr(repeat.item, ''name'') | slugify }}, service: notify.mobile_app_{{ device_attr(repeat.item, ''name'') | slugify }}, tag: {{ notify_tag }}, message: {{ cancel_action_button_confirmation_message }}'
- choose:
- alias: Perform the custom actions
conditions:
- condition: template
value_template: '{{ include_custom_actions == ''enable_custom_actions'' }}'
sequence: !input custom_actions
mode: single
@Ltek
Copy link
Author

Ltek commented Mar 17, 2025 via email

@Sanbecr
Copy link

Sanbecr commented Sep 27, 2025

I found that the Combined version "Friendly Names (Entity IDs)" wasn't rendering the list properly in the notification, resulting in a list of single characters.

Fix:

    {% elif format_option == 'combined' %}
      {% set ns = namespace(combined_list=[]) %}
      {%- for e in offline_entities %}
        {% set friendly_name = state_attr(e, "friendly_name") | default(e) %}
        {% set ns.combined_list = ns.combined_list + [friendly_name ~ ' (' ~ e ~ ')'] %}
      {%- endfor %}
      {{ ns.combined_list }}
    {% else %}

Fork: https://gist.github.com/Sanbecr/f9f4dd608fcf9a29413ecb2b66d6f784

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment