Forked from Tahutipai/report_zigbee_zwave_devices_gone_offline.yaml
Last active
February 24, 2026 01:36
-
-
Save Ltek/0c9cecf632b9c32915130680d834bcf7 to your computer and use it in GitHub Desktop.
Home Assistant Blueprint: Offline Devices Report
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: "⛔ Offline Devices Report with Notification Actions" | |
| description: | | |
| ⛔ Offline Devices Report with Notification Actions | |
| 🚀 Version 2026.02.23.45c | |
| - ADDED: Custom Actions option to run only when offline devices are detected | |
| - Recent Fixes... Debug triggers, Template syntax errors, To-Do list output, Empty notifications, Button trigger fix | |
| - Important Update... Real-Time Debug trigger happened with every entity change so the trigger code is now commented out. If you want to use it you will need to modify the code to add it back in. Change made since lower-powered systems would see high CPU use with this code running. | |
| 📖 Community Discussion, Help, and Details... https://community.home-assistant.io/t/offline-devices-report-easy-customize-includes-excludes-notifications-more/887859 | |
| ***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 | |
| - Debug mode for immediate offline/unknown state changes | |
| 🚫️ Entity exclusion options | |
| - Directly select specific entities | |
| - Pattern-based exclusions using text strings | |
| - Case-sensitive matching for precise control | |
| - Checkbox to exclude Hidden Entities | |
| - **Note: Disabled entities are automatically excluded** (they are not loaded into the system) | |
| 📈 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 | |
| 🐛 Real-Time Debug Mode (Short-term troubleshooting only - must enable in code, not just in the UI) | |
| - Trigger on entity state changes to offline/unknown | |
| - Configurable delay to confirm persistent offline state | |
| - Uses same exclusions as scheduled reports | |
| 📡 Monitored Domains | |
| Monitors all sources... Zigbee, Z-Wave, WiFi, etc. | |
| Will list entities from these domains... | |
| - sensor.* | |
| - binary_sensor.* | |
| - switch.* | |
| These domains are NOT monitored at all... | |
| - climate.* | |
| - light.* | |
| - media_player.* | |
| - device_tracker.* | |
| - input_* | |
| - automation.* | |
| - script.* | |
| - scene.* | |
| - weather.* | |
| - camera.* | |
| - person.* | |
| - zone.* | |
| - sun.* | |
| - timer.* | |
| - counter.* | |
| - calendar.* | |
| domain: automation | |
| input: | |
| trigger_settings: | |
| name: ⚙️ Trigger Settings | |
| collapsed: true | |
| input: | |
| include_button: | |
| name: Use Button Trigger? | |
| 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 | |
| default: | |
| selector: | |
| entity: | |
| domain: [input_button, button] | |
| multiple: false | |
| include_time: | |
| name: Use an Automatic Reoccuring Report? | |
| default: time_disabled | |
| selector: | |
| select: | |
| options: | |
| - label: Enabled | |
| value: time_enabled | |
| - label: Disabled | |
| value: time_disabled | |
| time: | |
| name: Set Reoccuring Time | |
| default: "05:00:00" | |
| selector: | |
| time: {} | |
| weekday_options: | |
| name: Set Reoccuring Days | |
| 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" | |
| collapsed: true | |
| input: | |
| exclude_hidden_entities: | |
| name: Exclude Hidden Entities | |
| default: true | |
| selector: | |
| boolean: {} | |
| exclude_entities: | |
| name: Individual Entities | |
| default: [] | |
| selector: | |
| entity: | |
| multiple: true | |
| exclude_strings: | |
| name: Text Pattern Exclusions | |
| default: '' | |
| selector: | |
| text: | |
| multiline: true | |
| notification_settings: | |
| name: "📢 Notification Settings" | |
| collapsed: true | |
| input: | |
| include_easy_notify: | |
| name: Device Notifications | |
| default: disabled_easy_notify | |
| selector: | |
| select: | |
| options: | |
| - {label: Disabled, value: disabled_easy_notify} | |
| - {label: Enabled - notify only if offline devices found, value: enable_easy_notify} | |
| - {label: Enabled - notify even if no offline devices found, value: enable_easy_okay_notify} | |
| notify_device: | |
| name: Devices to Notify | |
| 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: Message when No Offline Devices found | |
| default: No offline devices detected | |
| selector: | |
| text: {} | |
| notify_interruption_level: | |
| name: iOS Interruption Level | |
| default: active | |
| selector: | |
| select: | |
| options: | |
| - {label: Default, value: active} | |
| - {label: Critical Notifications, value: critical} | |
| - {label: Time Sensitive, value: time-sensitive} | |
| - {label: Quiet, value: passive} | |
| notify_sound: | |
| name: iOS Notification Sound | |
| default: '' | |
| selector: | |
| text: {} | |
| notify_data: | |
| name: Android 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 | |
| default: '' | |
| selector: | |
| text: {} | |
| include_persistent_notification: | |
| name: Persistent UI Notifications | |
| default: disabled_persistent_notification | |
| selector: | |
| select: | |
| options: | |
| - {label: Disabled, value: disabled_persistent_notification} | |
| - {label: Notify only when offline devices are found, value: enable_persistent_notification} | |
| - {label: Notify always - even if no offline devices found, value: enable_persistent_okay_notification} | |
| display_options: | |
| name: Display Options | |
| 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" | |
| collapsed: true | |
| input: | |
| auto_add_to_do: | |
| name: Automatically Add to To-Do List | |
| 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 | |
| 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 | |
| collapsed: true | |
| input: | |
| include_custom_actions: | |
| name: Enable Custom Actions | |
| default: disable_custom_actions | |
| selector: | |
| select: | |
| options: | |
| - {label: Never, value: disable_custom_actions} | |
| - {label: Only when offline devices are found, value: enable_custom_actions_offline_only} | |
| - {label: Always (even if no offline devices found), value: enable_custom_actions_always} | |
| custom_actions: | |
| name: Custom Actions | |
| default: [] | |
| selector: | |
| action: {} | |
| global_conditions_settings: | |
| name: "🌍 Global Conditions" | |
| collapsed: true | |
| input: | |
| global_conditions: | |
| name: Conditions | |
| default: [] | |
| selector: | |
| condition: {} | |
| debug_settings: | |
| name: "🐛 Debug Settings" | |
| collapsed: true | |
| input: | |
| include_debug: | |
| name: Real-Time Debug Mode? | |
| default: debug_disabled | |
| selector: | |
| select: | |
| options: | |
| - {label: Enabled, value: debug_enabled} | |
| - {label: Disabled, value: debug_disabled} | |
| debug_offline_delay: | |
| name: Wait Time Confirmation | |
| default: "00:03:00" | |
| selector: | |
| duration: {} | |
| include_logbook_debug: | |
| name: Logbook Debug Messages | |
| default: logbook_realtime_only | |
| selector: | |
| select: | |
| options: | |
| - {label: Enabled (All Runs), value: logbook_enabled_all} | |
| - {label: Real-Time Debug Only, value: logbook_realtime_only} | |
| - {label: Disabled, value: logbook_disabled} | |
| include_system_log_debug: | |
| name: System Log Debug Messages | |
| default: systemlog_realtime_only | |
| selector: | |
| select: | |
| options: | |
| - {label: Enabled (All Runs), value: systemlog_enabled_all} | |
| - {label: Real-Time Debug Only, value: systemlog_realtime_only} | |
| - {label: Disabled, value: systemlog_disabled} | |
| include_debug_persistent_notification: | |
| name: Persistent UI Notifications | |
| default: persistent_realtime_only | |
| selector: | |
| select: | |
| options: | |
| - {label: Enabled, value: persistent_realtime_only} | |
| - {label: Disabled, value: persistent_disabled} | |
| variables: | |
| include_button: !input include_button | |
| button_entity: !input button_entity | |
| include_time: !input include_time | |
| include_debug: !input include_debug | |
| debug_offline_delay: !input debug_offline_delay | |
| include_logbook_debug: !input include_logbook_debug | |
| include_system_log_debug: !input include_system_log_debug | |
| include_debug_persistent_notification: !input include_debug_persistent_notification | |
| debug_offline_delay_seconds: > | |
| {% set delay = debug_offline_delay %} | |
| {% if delay is string %} | |
| {% set parts = delay.split(':') %} | |
| {% set hours = parts[0] | int %} | |
| {% set minutes = parts[1] | int if parts|length > 1 else 0 %} | |
| {% set seconds = parts[2] | int if parts|length > 2 else 0 %} | |
| {{ (hours * 3600 + minutes * 60 + seconds) | int }} | |
| {% elif delay is mapping and 'hours' in delay %} | |
| {{ (delay.hours * 3600 + delay.minutes * 60 + delay.seconds) | int }} | |
| {% else %} | |
| 180 | |
| {% endif %} | |
| weekday_options: !input weekday_options | |
| exclude_hidden_entities: !input exclude_hidden_entities | |
| 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 %} | |
| {% set patterns = exclude_strings.split('\n') | map('trim') | reject('eq', '') | list %} | |
| {{ patterns | join('|') if patterns else 'a^' }} | |
| {% else %} | |
| a^ | |
| {% endif %} | |
| all_exclude_entities: > | |
| {{ exclude_entities if exclude_entities is defined else [] }} | |
| _offline_devices: > | |
| {% set exclude_entities_list = all_exclude_entities %} | |
| {# Disabled entities are automatically excluded as they don't appear in states #} | |
| {% set entities = states | map(attribute='entity_id') | reject('search', 'cloud') | reject('in', exclude_entities_list) | reject('search', exclude_regex) | list %} | |
| {% if exclude_hidden_entities == true %} | |
| {% set entities = entities | reject('is_hidden_entity') | list %} | |
| {% endif %} | |
| {% 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 }} | |
| _battery_sensors: > | |
| {% set exclude_entities_list = all_exclude_entities %} | |
| {# Disabled entities are automatically excluded as they don't appear in states #} | |
| {% set entities = states | map(attribute='entity_id') | reject('search', 'cloud') | reject('in', exclude_entities_list) | reject('search', exclude_regex) | list %} | |
| {% if exclude_hidden_entities == true %} | |
| {% set entities = entities | reject('is_hidden_entity') | list %} | |
| {% endif %} | |
| {% set sensors = entities | select('search', '^(sensor|binary_sensor)') | list %} | |
| {% set battery_entities = sensors | select('is_state_attr', 'device_class', 'battery') | reject('has_value') | list %} | |
| {{ battery_entities }} | |
| _switches: > | |
| {% set exclude_entities_list = all_exclude_entities %} | |
| {# Disabled entities are automatically excluded as they don't appear in states #} | |
| {% set entities = states | map(attribute='entity_id') | reject('search', 'cloud') | reject('in', exclude_entities_list) | reject('search', exclude_regex) | list %} | |
| {% if exclude_hidden_entities == true %} | |
| {% set entities = entities | reject('is_hidden_entity') | list %} | |
| {% endif %} | |
| {% set switches = entities | select('search', '^switch') | reject('has_value') | list %} | |
| {{ switches }} | |
| 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 %} | |
| easy_notify_message: > | |
| {% if notify_message == 'all_sensors' %} | |
| {{ all_sensors }} | |
| {% elif notify_message == 'sensors' %} | |
| {{ sensors }} | |
| {% elif notify_message == 'switches' %} | |
| {{ switches }} | |
| {% else %} | |
| '' | |
| {% endif %} | |
| to_do_description: > | |
| {% set device_list = _offline_devices | join(', ') %} | |
| {% set cleaned = device_list | regex_replace('\\s*\\([^)]+\\)', '') %} | |
| {% if cleaned | length > 250 %} | |
| {{ cleaned[:250] ~ '...' }} | |
| {% else %} | |
| {{ cleaned }} | |
| {% endif %} | |
| 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 %} | |
| 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: | |
| ############################### | |
| # Real-Time Debug Code # | |
| ############################### | |
| # - platform: event | |
| # event_type: state_changed | |
| # event_data: {} | |
| # id: debug_trigger | |
| ############################### | |
| - platform: time | |
| at: !input time | |
| id: time_trigger | |
| - platform: event | |
| event_type: state_changed | |
| id: button_trigger | |
| condition: | |
| - condition: or | |
| conditions: | |
| - condition: and | |
| conditions: | |
| - condition: trigger | |
| id: button_trigger | |
| - condition: template | |
| value_template: '{{ include_button == "enable_button_trigger" }}' | |
| - condition: template | |
| value_template: '{{ button_entity is not none and button_entity != "" and trigger.event.data.entity_id == button_entity }}' | |
| - condition: template | |
| value_template: '{{ trigger.event.data.new_state.state not in ["unknown", "unavailable", "off"] }}' | |
| - 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: | |
| - condition: trigger | |
| id: debug_trigger | |
| - condition: template | |
| value_template: '{{ include_debug == "debug_enabled" }}' | |
| - condition: template | |
| value_template: > | |
| {{ trigger.event.data.new_state is not none | |
| and trigger.event.data.new_state.state in ["unavailable", "unknown"] | |
| and (trigger.event.data.old_state is none | |
| or trigger.event.data.old_state.state not in ["unavailable", "unknown"]) }} | |
| - condition: and | |
| conditions: !input global_conditions | |
| action: | |
| - choose: | |
| - conditions: | |
| - condition: trigger | |
| id: debug_trigger | |
| - condition: template | |
| value_template: '{{ include_debug == "debug_enabled" }}' | |
| sequence: | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_system_log_debug in ["systemlog_enabled_all", "systemlog_realtime_only"] }}' | |
| then: | |
| - service: system_log.write | |
| data: | |
| message: "Debug mode triggered by state_changed event" | |
| level: warning | |
| - variables: | |
| debug_entity: "{{ trigger.event.data.entity_id }}" | |
| debug_entity_state: "{{ trigger.event.data.new_state.state }}" | |
| debug_entity_name: '{{ trigger.event.data.new_state.attributes.friendly_name or trigger.event.data.entity_id }}' | |
| old_state: "{{ trigger.event.data.old_state.state if trigger.event.data.old_state else '' }}" | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_system_log_debug in ["systemlog_enabled_all", "systemlog_realtime_only"] }}' | |
| then: | |
| - service: system_log.write | |
| data: | |
| message: "Debug checking entity: {{ debug_entity }}, new_state: {{ debug_entity_state }}, old_state: {{ old_state }}" | |
| level: warning | |
| - if: | |
| - condition: template | |
| value_template: '{{ debug_entity_state not in ["unknown", "unavailable"] or old_state in ["unknown", "unavailable"] }}' | |
| then: | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_system_log_debug in ["systemlog_enabled_all", "systemlog_realtime_only"] }}' | |
| then: | |
| - service: system_log.write | |
| data: | |
| message: "Debug stopped: Not a change TO unknown/unavailable for {{ debug_entity }}" | |
| level: info | |
| - stop: 'Not a change TO unknown/unavailable state' | |
| - variables: | |
| entity_excluded: > | |
| {% if debug_entity in all_exclude_entities %} | |
| true | |
| {% elif exclude_regex != 'a^' and debug_entity is search(exclude_regex) %} | |
| true | |
| {% elif exclude_hidden_entities == true and is_hidden_entity(debug_entity) %} | |
| true | |
| {% elif debug_entity is search('cloud') %} | |
| true | |
| {% else %} | |
| false | |
| {% endif %} | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_system_log_debug in ["systemlog_enabled_all", "systemlog_realtime_only"] }}' | |
| then: | |
| - service: system_log.write | |
| data: | |
| message: "Debug exclusion check for {{ debug_entity }}: excluded={{ entity_excluded }}" | |
| level: info | |
| - if: | |
| - condition: template | |
| value_template: '{{ entity_excluded == true }}' | |
| then: | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_logbook_debug in ["logbook_enabled_all", "logbook_realtime_only"] }}' | |
| then: | |
| - service: logbook.log | |
| data: | |
| name: Offline Devices Debug Mode | |
| message: 'Debug ignored: {{ debug_entity_name }} is excluded' | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_system_log_debug in ["systemlog_enabled_all", "systemlog_realtime_only"] }}' | |
| then: | |
| - service: system_log.write | |
| data: | |
| message: "Debug ignored: {{ debug_entity_name }} ({{ debug_entity }}) is excluded from monitoring" | |
| level: info | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_debug_persistent_notification == "persistent_realtime_only" }}' | |
| then: | |
| - service: persistent_notification.create | |
| data: | |
| title: "🐛 Debug: Entity Excluded" | |
| message: 'Debug ignored: {{ debug_entity_name }} is excluded from monitoring' | |
| notification_id: 'debug_excluded_{{ debug_entity | replace(".", "_") }}' | |
| - stop: 'Entity excluded from debug' | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_logbook_debug in ["logbook_enabled_all", "logbook_realtime_only"] }}' | |
| then: | |
| - service: logbook.log | |
| data: | |
| name: Offline Devices Debug Mode | |
| message: 'Debug triggered: {{ debug_entity_name }} ({{ debug_entity }}) changed from {{ old_state }} to {{ debug_entity_state }}' | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_system_log_debug in ["systemlog_enabled_all", "systemlog_realtime_only"] }}' | |
| then: | |
| - service: system_log.write | |
| data: | |
| message: "🐛 DEBUG ALERT: {{ debug_entity_name }} ({{ debug_entity }}) went {{ debug_entity_state }}" | |
| level: warning | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_debug_persistent_notification in ["persistent_enabled_all", "persistent_realtime_only"] }}' | |
| then: | |
| - service: persistent_notification.create | |
| data: | |
| title: "🐛 Debug: Entity Offline Detected" | |
| message: '{{ debug_entity_name }} ({{ debug_entity }}) changed from {{ old_state }} to {{ debug_entity_state }}' | |
| notification_id: 'debug_trigger_{{ debug_entity | replace(".", "_") }}' | |
| - wait_template: '{{ states(debug_entity) in ["unknown","unavailable"] }}' | |
| timeout: '{{ debug_offline_delay_seconds }}' | |
| continue_on_timeout: false | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ wait is defined and wait.timed_out == true }}' | |
| sequence: | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_logbook_debug in ["logbook_enabled_all", "logbook_realtime_only"] }}' | |
| then: | |
| - service: logbook.log | |
| data: | |
| name: Offline Devices Debug Mode | |
| message: '{{ debug_entity_name }} ({{ debug_entity }}) stayed {{ debug_entity_state }} for {{ debug_offline_delay }}' | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_debug_persistent_notification in ["persistent_enabled_all", "persistent_realtime_only"] }}' | |
| then: | |
| - service: persistent_notification.create | |
| data: | |
| title: "🐛 Debug: Entity Confirmed Offline" | |
| message: '{{ debug_entity_name }} ({{ debug_entity }}) stayed {{ debug_entity_state }} for {{ debug_offline_delay }}' | |
| notification_id: 'debug_confirmed_{{ debug_entity | replace(".", "_") }}' | |
| - stop: 'Debug complete - entity stayed offline' | |
| - conditions: | |
| - condition: template | |
| value_template: '{{ wait is defined and wait.timed_out == false }}' | |
| sequence: | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_logbook_debug in ["logbook_enabled_all", "logbook_realtime_only"] }}' | |
| then: | |
| - service: logbook.log | |
| data: | |
| name: Offline Devices Debug Mode | |
| message: '{{ debug_entity_name }} ({{ debug_entity }}) came back online during wait period' | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_debug_persistent_notification in ["persistent_enabled_all", "persistent_realtime_only"] }}' | |
| then: | |
| - service: persistent_notification.create | |
| data: | |
| title: "🐛 Debug: Entity Back Online" | |
| message: '{{ debug_entity_name }} ({{ debug_entity }}) came back online during wait period' | |
| notification_id: 'debug_online_{{ debug_entity | replace(".", "_") }}' | |
| - stop: 'Debug cancelled - entity came back online' | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_logbook_debug == "logbook_enabled_all" or (include_logbook_debug == "logbook_realtime_only" and trigger.id == "debug_trigger") }}' | |
| then: | |
| - 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 length: {{ easy_notify_message | default('') | length }}, | |
| to_do_description length: {{ to_do_description | default('') | length }}, | |
| to_do_list: {{ to_do_list | default('undefined') }}, | |
| exclude_hidden_entities: {{ exclude_hidden_entities | 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 }}' | |
| - condition: template | |
| value_template: '{{ trigger.id != "debug_trigger" }}' | |
| 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: '{{ offline_devices_count > 0 }}' | |
| 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 }}' | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_logbook_debug == "logbook_enabled_all" }}' | |
| then: | |
| - 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 length: {{ easy_notify_message | length }}' | |
| - 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 }}' | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_logbook_debug == "logbook_enabled_all" }}' | |
| then: | |
| - 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: '{{ offline_devices_count == 0 }}' | |
| - 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: '{{ notify_okay_message }}' | |
| data: '{{ device_message_data }}' | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_logbook_debug == "logbook_enabled_all" }}' | |
| then: | |
| - 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" }}' | |
| - condition: template | |
| value_template: '{{ trigger.id != "debug_trigger" }}' | |
| sequence: | |
| - choose: | |
| - alias: Offline devices have been found | |
| conditions: | |
| - condition: template | |
| value_template: '{{ offline_devices_count > 0 }}' | |
| sequence: | |
| - service: persistent_notification.create | |
| data: | |
| title: "⛔ {{ notify_title }}" | |
| message: '{{ easy_notify_message }}' | |
| notification_id: offline_devices_report | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_logbook_debug == "logbook_enabled_all" }}' | |
| then: | |
| - service: logbook.log | |
| data: | |
| name: Offline Devices Report Debug | |
| message: 'Created persistent notification, id: offline_devices_report, message length: {{ easy_notify_message | length }}' | |
| - alias: No offline devices have been found | |
| conditions: | |
| - condition: template | |
| value_template: '{{ offline_devices_count == 0 }}' | |
| - condition: template | |
| value_template: '{{ include_persistent_notification == "enable_persistent_okay_notification" }}' | |
| sequence: | |
| - service: persistent_notification.create | |
| data: | |
| title: "⛔ {{ notify_title }}" | |
| message: '{{ notify_okay_message }}' | |
| notification_id: offline_devices_report_ok | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_logbook_debug == "logbook_enabled_all" }}' | |
| then: | |
| - 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: Auto-add to To-Do list when enabled | |
| conditions: | |
| - condition: template | |
| value_template: '{{ auto_add_to_do == "enable_auto_add_to_do" and to_do_description != "" }}' | |
| - condition: template | |
| value_template: '{{ to_do_list | length > 0 and is_state(to_do_list, "unknown") == false and is_state(to_do_list, "unavailable") == false }}' | |
| - condition: template | |
| value_template: '{{ trigger.id != "debug_trigger" }}' | |
| sequence: | |
| - service: todo.add_item | |
| data: | |
| entity_id: '{{ to_do_list }}' | |
| item: !input to_do_task_title | |
| description: '{{ to_do_description }}' | |
| continue_on_error: true | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_logbook_debug == "logbook_enabled_all" }}' | |
| then: | |
| - service: logbook.log | |
| data: | |
| name: Offline Devices Report Debug | |
| message: 'Auto-added To-Do item to {{ to_do_list }}: title={{ to_do_task_title }}, description length={{ to_do_description | length }}' | |
| - 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, "unknown") == false and is_state(to_do_list, "unavailable") == false }}' | |
| - condition: template | |
| value_template: '{{ trigger.id != "debug_trigger" }}' | |
| 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 | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_logbook_debug == "logbook_enabled_all" }}' | |
| then: | |
| - 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 }}' | |
| item: !input to_do_task_title | |
| description: '{{ to_do_description }}' | |
| continue_on_error: true | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_logbook_debug == "logbook_enabled_all" }}' | |
| then: | |
| - service: logbook.log | |
| data: | |
| name: Offline Devices Report Debug | |
| message: 'Added To-Do item to {{ to_do_list }}: title={{ to_do_task_title }}, description length={{ to_do_description | length }}' | |
| - if: | |
| - condition: template | |
| value_template: '{{ wait.trigger is not none and wait.trigger.event.data.action == action_button_cancel }}' | |
| then: | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_logbook_debug == "logbook_enabled_all" }}' | |
| then: | |
| - service: logbook.log | |
| data: | |
| name: Offline Devices Report Debug | |
| message: 'Action cancelled for tag: {{ notify_tag }}' | |
| - stop: 'Action cancelled' | |
| - 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 }}' | |
| item: !input to_do_task_title | |
| description: '{{ to_do_description }}' | |
| continue_on_error: true | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_logbook_debug == "logbook_enabled_all" }}' | |
| then: | |
| - service: logbook.log | |
| data: | |
| name: Offline Devices Report Debug | |
| message: 'Added To-Do item to {{ to_do_list }}: title={{ to_do_task_title }}, description length={{ to_do_description | length }}' | |
| - 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 | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_logbook_debug == "logbook_enabled_all" }}' | |
| then: | |
| - 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 | |
| - if: | |
| - condition: template | |
| value_template: '{{ include_logbook_debug == "logbook_enabled_all" }}' | |
| then: | |
| - 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_always" or | |
| (include_custom_actions == "enable_custom_actions_offline_only" and offline_devices_count | int > 0) }} | |
| - condition: template | |
| value_template: '{{ trigger.id != "debug_trigger" }}' | |
| sequence: !input custom_actions | |
| mode: single |
Comments are disabled for this gist.