various tidyups
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
#:########################################################################################:#
|
||||
# Battery Notes Alerts Package #
|
||||
#:########################################################################################:#
|
||||
#
|
||||
# TITLE:
|
||||
# Battery Notes Alerts
|
||||
#
|
||||
# FILE:
|
||||
# packages/battery_notes_alerts.yaml
|
||||
#
|
||||
# VERSION:
|
||||
# V1.0.1 2026-08-25
|
||||
#
|
||||
# PURPOSE:
|
||||
# Sends immediate and weekly Pushover alerts for non-temporary Battery Notes devices.
|
||||
# Device lists are generated from Battery Notes at runtime, so adding a note starts
|
||||
# monitoring the device without maintaining a second entity list.
|
||||
#
|
||||
# CONTROLS:
|
||||
# - Battery Notes - Immediate Alert and Battery Notes - Weekly Digest are independent
|
||||
# automation entities. Each can be enabled or disabled in Home Assistant Automations.
|
||||
#
|
||||
# DEPENDENCIES:
|
||||
# - Battery Notes integration
|
||||
# - packages/view_road_announcement_router.yaml
|
||||
#
|
||||
# VERSION HISTORY:
|
||||
# - V1.0.1 2026-08-25: Bound companion lookups and prevent oversized template output.
|
||||
# - V1.0.0 2026-08-25: Initial immediate and Thursday weekly battery alerts.
|
||||
#
|
||||
#:########################################################################################:#
|
||||
|
||||
automation:
|
||||
- id: battery_notes_immediate_alert
|
||||
alias: "Battery Notes - Immediate Alert"
|
||||
description: >
|
||||
Sends a Pushover alert when a monitored Battery Notes device newly reports
|
||||
low battery or becomes unavailable. Temporary Battery Notes devices are ignored.
|
||||
mode: single
|
||||
max_exceeded: silent
|
||||
triggers:
|
||||
- trigger: event
|
||||
event_type: state_changed
|
||||
conditions:
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{{ trigger.event.data.entity_id is match('^(sensor|binary_sensor)\\..*_battery_plus(?:_low)?$') }}
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{% set old = trigger.event.data.old_state %}
|
||||
{% set new = trigger.event.data.new_state %}
|
||||
{{ old is not none
|
||||
and new is not none
|
||||
and old.state not in ['unknown', 'unavailable']
|
||||
and old.state != new.state }}
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{% set new = trigger.event.data.new_state %}
|
||||
{% set note = new.attributes.note | default('', true) | lower %}
|
||||
{{ new.attributes.device_id | default('') | bool
|
||||
and 'temporary' not in note }}
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{%- set old = trigger.event.data.old_state -%}
|
||||
{%- set new = trigger.event.data.new_state -%}
|
||||
{%- set device_id = new.attributes.device_id -%}
|
||||
{%- set companions = namespace(percentage_id='', qualitative_id='') -%}
|
||||
{%- for entity_id in device_entities(device_id) -%}
|
||||
{%- if entity_id.startswith('sensor.') and entity_id.endswith('_battery_plus') -%}
|
||||
{%- set companions.percentage_id = entity_id -%}
|
||||
{%- elif entity_id.startswith('sensor.') and entity_id.endswith('_battery_state') -%}
|
||||
{%- set companions.qualitative_id = entity_id -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- set source_id = companions.percentage_id or new.entity_id -%}
|
||||
{%- set qualitative_available = companions.qualitative_id
|
||||
and states(companions.qualitative_id) in ['high', 'medium', 'low'] -%}
|
||||
{%- set newly_low = new.attributes.battery_low | default(false)
|
||||
and not old.attributes.battery_low | default(false) -%}
|
||||
{%- set newly_binary_low = new.entity_id.startswith('binary_sensor.')
|
||||
and new.state == 'on' -%}
|
||||
{%- set newly_unavailable = new.state in ['unknown', 'unavailable']
|
||||
and source_id == new.entity_id
|
||||
and not qualitative_available -%}
|
||||
{{ newly_low or newly_binary_low or newly_unavailable }}
|
||||
variables:
|
||||
alert_name: >-
|
||||
{% set new = trigger.event.data.new_state %}
|
||||
{{ new.attributes.device_name
|
||||
| default(new.attributes.friendly_name, true)
|
||||
| default(new.name, true) }}
|
||||
alert_type: >-
|
||||
{{ trigger.event.data.new_state.attributes.battery_type_and_quantity
|
||||
| default('Not recorded', true) }}
|
||||
alert_level: >-
|
||||
{%- set device_id = trigger.event.data.new_state.attributes.device_id -%}
|
||||
{%- set level = namespace(value='') -%}
|
||||
{%- for entity_id in device_entities(device_id) -%}
|
||||
{%- if entity_id.startswith('sensor.')
|
||||
and entity_id.endswith('_battery_plus')
|
||||
and states(entity_id) not in ['unknown', 'unavailable'] -%}
|
||||
{%- set level.value = states(entity_id) -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{{ level.value ~ '%' if level.value else '' }}
|
||||
alert_line: >-
|
||||
{% if trigger.event.data.new_state.state in ['unknown', 'unavailable'] %}
|
||||
New Alert: {{ alert_name }}, Battery Unavailable {{ alert_type }}
|
||||
{% else %}
|
||||
New Alert: {{ alert_name }}, Battery Low {{ alert_level }} {{ alert_type }}
|
||||
{% endif %}
|
||||
alert_summary: &battery_notes_summary >-
|
||||
{%- set monitored = namespace(device_ids=[], low=[], unavailable=[]) -%}
|
||||
{%- for item in states -%}
|
||||
{%- set note = item.attributes.note | default('', true) | lower -%}
|
||||
{%- set device_id = item.attributes.device_id | default('') -%}
|
||||
{%- if item.entity_id is match('^(sensor|binary_sensor)\\..*_battery_plus(?:_low)?$')
|
||||
and device_id
|
||||
and 'temporary' not in note
|
||||
and device_id not in monitored.device_ids -%}
|
||||
{%- set monitored.device_ids = monitored.device_ids + [device_id] -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- for device_id in monitored.device_ids -%}
|
||||
{%- set device = namespace(percentage_id='', low_id='', qualitative_id='') -%}
|
||||
{%- for entity_id in device_entities(device_id) -%}
|
||||
{%- if entity_id.startswith('sensor.') and entity_id.endswith('_battery_plus') -%}
|
||||
{%- set device.percentage_id = entity_id -%}
|
||||
{%- elif entity_id.startswith('binary_sensor.') and entity_id.endswith('_battery_plus_low') -%}
|
||||
{%- set device.low_id = entity_id -%}
|
||||
{%- elif entity_id.startswith('sensor.') and entity_id.endswith('_battery_state') -%}
|
||||
{%- set device.qualitative_id = entity_id -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- set source_id = device.percentage_id or device.low_id -%}
|
||||
{%- set source_state = states(source_id) -%}
|
||||
{%- set qualitative_state = states(device.qualitative_id) if device.qualitative_id else '' -%}
|
||||
{%- set name = state_attr(source_id, 'device_name')
|
||||
or state_attr(source_id, 'friendly_name')
|
||||
or source_id -%}
|
||||
{%- set battery_type = state_attr(source_id, 'battery_type_and_quantity')
|
||||
or 'Not recorded' -%}
|
||||
{%- set low = state_attr(source_id, 'battery_low') | default(false, true)
|
||||
or (device.low_id and is_state(device.low_id, 'on'))
|
||||
or qualitative_state == 'low' -%}
|
||||
{%- set unavailable = source_state in ['unknown', 'unavailable']
|
||||
and qualitative_state not in ['high', 'medium', 'low'] -%}
|
||||
{%- if low -%}
|
||||
{%- set level = source_state ~ '%'
|
||||
if device.percentage_id and source_state not in ['unknown', 'unavailable']
|
||||
else '' -%}
|
||||
{%- set monitored.low = monitored.low
|
||||
+ [name ~ ' (' ~ level ~ (', ' if level else '') ~ battery_type ~ ')'] -%}
|
||||
{%- endif -%}
|
||||
{%- if unavailable -%}
|
||||
{%- set monitored.unavailable = monitored.unavailable
|
||||
+ [name ~ ' (' ~ battery_type ~ ')'] -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
Summary: {{ monitored.device_ids | count }} Battery Notes devices,
|
||||
{{ monitored.unavailable | count }} unavailable,
|
||||
{{ monitored.low | count }} battery low.
|
||||
Low Battery Devices: {{ monitored.low | join(', ') if monitored.low else 'None' }}
|
||||
Unavailable Devices: {{ monitored.unavailable | join(', ') if monitored.unavailable else 'None' }}
|
||||
actions:
|
||||
- action: script.view_road_announcement
|
||||
data:
|
||||
channels: "pushover_zorruno"
|
||||
title: "Battery Alert"
|
||||
short_announcement: "{{ alert_line }}"
|
||||
long_announcement: >-
|
||||
{{ alert_line }}
|
||||
|
||||
{{ alert_summary }}
|
||||
|
||||
- id: battery_notes_weekly_digest
|
||||
alias: "Battery Notes - Weekly Digest"
|
||||
description: >
|
||||
Sends the Battery Notes health summary to Pushover every Thursday at 19:00.
|
||||
Temporary Battery Notes devices are excluded.
|
||||
mode: single
|
||||
triggers:
|
||||
- trigger: time
|
||||
at: "19:00:00"
|
||||
conditions:
|
||||
- condition: time
|
||||
weekday:
|
||||
- thu
|
||||
variables:
|
||||
alert_summary: *battery_notes_summary
|
||||
actions:
|
||||
- action: script.view_road_announcement
|
||||
data:
|
||||
channels: "pushover_zorruno"
|
||||
title: "Weekly Battery Digest"
|
||||
short_announcement: "Weekly Battery Digest"
|
||||
long_announcement: "{{ alert_summary }}"
|
||||
Reference in New Issue
Block a user