Created
April 10, 2025 17:16
-
-
Save alec-pinson/f230b86b6c47091da81dabde20223757 to your computer and use it in GitHub Desktop.
My home assistant 'dynamic alert template' that I use on my phone and home assistant dashboard.
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
<p style="text-align: start"> | |
{%- if states('input_boolean.holiday_mode') == "on" -%} | |
{#- Holiday Mode -#} | |
🇬🇧 {{ now().timestamp() | timestamp_custom('%I:%M %p') }}<br> | |
{%- else %} | |
{#- Not Holiday Mode -#} | |
{#- Shell Home/Away -#} | |
{# {%- if states('person.shell') != "home" %} | |
👰 Away ({{ relative_time(states.person['shell'].last_changed) }} ago)<br> #} | |
{# {%- else %} | |
👰 Home ({{ relative_time(states.person['shell'].last_changed) }} ago)<br> #} | |
{# {%- endif %} #} | |
{%- endif %} | |
{%- if not is_state('sensor.resting_heart_rate', 'unknown') and not is_state('sensor.resting_heart_rate', 'unavailable') -%} | |
❤️ {{ states('sensor.resting_heart_rate') | round }} bpm<br> | |
{%- endif %} | |
{%- if not is_state('sensor.calories', 'unknown') and not is_state('sensor.calories', 'unavailable') -%} | |
{# 🔥 {{ states('sensor.calories') | round }} calories<br> #} | |
{%- endif %} | |
{#- Battery States -#} | |
{%- set result = namespace(sensors=[]) -%} | |
{%- set exclude_entity_id = | |
[ | |
"sensor.0xa4c138b759140edb_battery", | |
"sensor.x10_security_0d1c00_32_battery", | |
] | |
-%} | |
{%- for state in states.sensor | selectattr('attributes.device_class', '==', 'battery') -%} | |
{%- if 0 <= state.state | int(-1) < 16 | int and not state.entity_id in exclude_entity_id -%} | |
{%- set result.sensors = result.sensors + ['<b>' ~ state.name ~ ' ' ~ state.state ~ '%</b><br>'] -%} | |
{%- endif -%} | |
{%- endfor -%} | |
{%- for state in states.binary_sensor | selectattr('attributes.device_class', '==', 'battery') | selectattr('state', '==', 'on') -%} | |
{%- if not state.entity_id in exclude_entity_id -%} | |
{%- set result.sensors = result.sensors + [state.name] -%} | |
{%- endif -%} | |
{%- endfor -%} | |
{{result.sensors|join('<br>')|replace(' Battery ', ' 🪫 ')}} | |
{# - Check ZIgbee Device Count -#} | |
{%- if states('input_number.zigbee2mqtt_device_count') < states('input_number.zigbee2mqtt_expected_device_count') -%} | |
ZigBee device has dropped<br> | |
{%- elif states('input_number.zigbee2mqtt_device_count') > states('input_number.zigbee2mqtt_expected_device_count') -%} | |
New ZigBee devices added, increase expected count<br> | |
{%- endif -%} | |
{#- Offline Devices -#} | |
{%- set ignore_list = [ | |
"EPSON XP-750 Series", | |
"Plex (Plex for Android (Mobile) - Pixel 7)", | |
"Plex (Plex for Android (TV) - Chromecast Google TV)", | |
"Plex Client Service", | |
"3D Printer AMS", | |
"Dressing room speaker", | |
"Tank Night Light", | |
"Tank UVB Light", | |
"Downstairs Motion", | |
"Gecko Egg Motion", | |
"Bathroom speaker", | |
"Gecko Eggs", | |
"Alecs Office - LED 2", | |
"Alecs Office - LED 3", | |
"Alecs Office - LED 4", | |
"Alecs Office - LED 5", | |
"Alecs Office - LED 6", | |
"Alecs Office - LED 7", | |
"Alecs Office - LED 8", | |
"Google Generative AI", | |
"Google Pixel Watch", | |
"PT2262 ffffff", | |
"PT2262 025100", | |
"PT2262 bc7a7b", | |
"PT2262 c00200", | |
"PT2262 8ce540", | |
"PT2262 a80481", | |
"PT2262 c14320", | |
"PT2262 bdffff", | |
] | |
-%} | |
{%- if states('input_boolean.holiday_mode') == "on" -%} | |
{%- set holiday_ignore_list = [ | |
"Living Room TV", | |
"Living Room speaker", | |
"Bedroom speaker", | |
"Chromecast", | |
"Main Bedroom Bed Light", | |
"Upstairs", | |
"Kitchen display", | |
"Office display", | |
"3D Printer Plugs", | |
"Fly Tub", | |
] | |
-%} | |
{%- set normal_ignore_list = ignore_list -%} | |
{%- set ignore_list = holiday_ignore_list + normal_ignore_list -%} | |
{%- endif %} | |
{#- list all devices that have at least one unavailable entity -#} | |
{% set suspicious_devices = states | rejectattr('state','ne','unavailable') | map(attribute='entity_id') | map('device_id') | unique | reject('eq',None) | list -%} | |
{%- set ns = namespace(unavailables = []) -%} | |
{%- for device_id in suspicious_devices -%} | |
{%- set ids = device_attr(device_id, 'identifiers') -%} | |
{%- set integration = 'unknown' if (not ids or ids|list|length == 0 or ids|list|first|length!=2) else ids|list|first|first -%} | |
{#- exlude entities of i.e. powercalc which extends devices with power entities -#} | |
{%- set entities= device_entities(device_id) -%} | |
{%- set unavailable = expand(entities) | selectattr('state','eq','unavailable') |list|count -%} | |
{#- don't count available entities of connection type -#} | |
{%- set available = expand(entities) | selectattr('state','ne','unavailable') | list | count -%} | |
{#- so count connection entities in error state -#} | |
{%- set contypes = expand(entities) | selectattr('state','eq','off') | selectattr('attributes.device_class', 'defined') |selectattr('attributes.device_class','eq','connectivity') | list | count -%} | |
{%- if unavailable!=0 and available-contypes==0 -%} | |
{#- preferably use named_by_user -#} | |
{%- set name = device_attr(device_id, 'name_by_user') -%} | |
{%- set name = device_attr(device_id, 'name') if name==None else name -%} | |
{%- if (name != None) and (ignore_list|select('in', name)|list|length == 0) -%} | |
{%- set ns.unavailables = ns.unavailables + [ name ] -%} | |
{%- endif -%} | |
{%- endif -%} | |
{%- endfor -%} | |
{%- set ns.unavailables = ns.unavailables + [""] -%} | |
{{ns.unavailables|join(' is offline<br>\n')|replace('X10 Security 0d1c00:32 is offline','RFXCOM needs initialising')}} | |
{#- Front Door States -#} | |
{%- if states("binary_sensor.front_door_contact") == "on" -%} | |
<b>Front door open</b><br> | |
{%- endif %} | |
{%- if states("lock.front_door_lock") != "locked" -%} | |
<b>Front door unlocked</b><br> | |
{%- endif %} | |
{#- Gate States -#} | |
{%- if states("binary_sensor.gate_contact") == "on" -%} | |
<b>Gate open</b><br> | |
{%- endif %} | |
{#- Shed States -#} | |
{%- if states("binary_sensor.door_shed") == "on" -%} | |
<b>Shed open</b><br> | |
{%- endif %} | |
{#- Back Door States -#} | |
{%- if states("binary_sensor.back_door_contact") == "on" -%} | |
<b>Back door open</b><br> | |
{%- endif %} | |
{#- Sliding Back Door States -#} | |
{%- if states("binary_sensor.sliding_back_door_contact") == "on" -%} | |
<b>Sliding Back door open</b><br> | |
{%- endif %} | |
{#- Vaccum State -#} | |
{%- if is_state("vacuum.robot_vacuum", "unavailable") and states('input_boolean.holiday_mode') == "off" -%} | |
<b>Vacuum has lost WiFi connection</b><br> | |
{%- endif %} | |
{%- if is_state("vacuum.robot_vacuum", "cleaning") -%} | |
<b>🧹 Cleaning</b><br> | |
{%- endif %} | |
{%- if states("sensor.robot_vacuum_filter_lifespan") | int < 0 -%} | |
Vacuum filter needs replacing<br> | |
{%- endif %} | |
{%- if states("sensor.robot_vacuum_main_brush_lifespan") | int < 0 -%} | |
Vacuum main brush needs replacing<br> | |
{%- endif %} | |
{%- if states("sensor.robot_vacuum_side_brushes_lifespan") | int < 0 -%} | |
Vacuum side brushes need replacing<br> | |
{%- endif %} | |
{%- if states("sensor.robot_vacuum_unit_care_lifespan") | int < 0 -%} | |
Vacuum needs standard maintenance<br> | |
{%- endif %} | |
{#- Lawn Mower State -#} | |
{%- if is_state("lawn_mower.robot_lawn_mower", "unavailable") and states('input_boolean.holiday_mode') == "off" -%} | |
<b>Lawn Mower has lost WiFi connection</b><br> | |
{%- endif %} | |
{%- if is_state("lawn_mower.robot_lawn_mower", "cleaning") -%} | |
<b>🧑🌾🚜 Mowing Grass</b><br> | |
{%- endif %} | |
{%- if states("sensor.robot_lawn_mower_blade_lifespan") | int < 0 -%} | |
Lawn mower blades need replacing<br> | |
{%- endif %} | |
{%- if states("sensor.robot_lawn_mower_lens_brush_lifespan") | int < 0 -%} | |
Lawn mower lens requires cleaning<br> | |
{%- endif %} | |
{#- Terrarium 3 State -#} | |
{%- if states("sensor.0x00158d000ae0f3de_temperature") | float > 30 -%} | |
{%- set font_colour = "red" %} | |
{%- elif states("sensor.0x00158d000ae0f3de_temperature") | float < 18 -%} | |
{%- set font_colour = "blue" %} | |
{%- else -%} | |
{%- set font_colour = "" %} | |
{%- endif %} | |
{%- if font_colour != "" -%} | |
<font color="{{ font_colour }}"><b>Terrarium 3 🌡️</b> {{ states('sensor.0x00158d000ae0f3de_temperature') }}°c<br></font> | |
{%- endif %} | |
{%- if states("sensor.0x00158d000ae0f3de_humidity") | float > 96 -%} | |
{%- set font_colour = "red" %} | |
{%- elif states("sensor.0x00158d000ae0f3de_humidity") | float < 60 -%} | |
{%- set font_colour = "blue" %} | |
{%- else -%} | |
{%- set font_colour = "" %} | |
{%- endif %} | |
{%- if font_colour != "" -%} | |
<font color="{{ font_colour }}"><b>Terrarium 3 💧</b> {{ states('sensor.0x00158d000ae0f3de_humidity') }}%<br></font> | |
{%- endif %} | |
{%- if not states("binary_sensor.terrarium_3_bt_lights_lumenize_led_1_ble_connected") -%} | |
Connection Lost - Terrarium 3 LED<br> | |
{%- endif %} | |
{%- if not states("binary_sensor.terrarium_3_bt_lights_lumenize_pro_t5_1_ble_connected") -%} | |
Connection Lost - Terrarium 3 UVB<br> | |
{%- endif %} | |
{#- Flies State -#} | |
{%- if states("sensor.0x00158d000a840be6_battery") == "unavailable" -%} | |
<b>Fly temperature sensor offline</b><br> | |
{%- else -%} | |
{%- if states("sensor.fly_tub_temperature") | float > 24 -%} | |
{%- set font_colour = "red" %} | |
{%- elif states("sensor.fly_tub_temperature") | float < 20 -%} | |
{%- set font_colour = "blue" %} | |
{%- else -%} | |
{%- set font_colour = "" %} | |
{%- endif %} | |
{%- if font_colour != "" -%} | |
<font color="{{ font_colour }}"><b>Flies 🌡️</b> {{ states('sensor.fly_tub_temperature') }}°c<br></font> | |
{%- endif %} | |
{%- endif %} | |
{%- if state_attr('timer.fly_culture_ready', 'finishes_at') == None -%} | |
🪰 <b>Culture Ready</b><br> | |
{%- endif -%} | |
{#- Eggs State -#} | |
{# {%- if states("sensor.gecko_eggs_battery") == "unavailable" -%} | |
<b>Egg temperature sensor offline</b><br> | |
{%- else -%} | |
{%- if states("sensor.gecko_eggs_temperature") | float > 27 -%} | |
{%- set font_colour = "red" %} | |
{%- elif states("sensor.gecko_eggs_temperature") | float < 25 -%} | |
{%- set font_colour = "blue" %} | |
{%- else -%} | |
{%- set font_colour = "" %} | |
{%- endif %} | |
{%- if font_colour != "" -%} | |
<font color="{{ font_colour }}"><b>Eggs 🌡️</b> {{ states('sensor.gecko_eggs_temperature') }}°c<br></font> | |
{%- endif %} | |
{%- endif %} #} | |
{#- Printer State -#} | |
{%- if states("sensor.3d_printer_print_status") == "running" -%} | |
{%- set current_time = now() %} | |
{%- set future_time = as_local(states("sensor.3d_printer_end_time") | as_datetime) %} | |
{%- set time_difference = future_time - current_time %} | |
🖨️ {{ as_timestamp(states("sensor.3d_printer_end_time")) | timestamp_custom('%d/%m/%Y %H:%M') }} ({{ relative_time(current_time - time_difference) }})<br> | |
{%- endif %} | |
{#- Filament Dryer State -#} | |
{%- if states('sensor.0x00124b0022cead4c_humidity') | int < 20 and states('switch.3d_printer_plugs_l4') == "on" -%} | |
Filament has been dried, humidity<br> {{states('sensor.0x00124b0022cead4c_humidity')|round}}% | |
{%-endif-%} | |
{#- Egg Hatched -#} | |
{%- set minutes_since_gecko_egg_hatch = ((as_timestamp(now()) - as_timestamp(states.binary_sensor['0x00124b00292c587e_occupancy'].last_changed)) / 60)|int %} | |
{%- if ( as_timestamp(states.binary_sensor['0x00124b00292c587e_occupancy'].last_changed) - as_timestamp(states('sensor.uptime')) ) > 5 -%} | |
{%- if minutes_since_gecko_egg_hatch < 60 %} | |
🥚 Egg hatched ({{ relative_time(states.binary_sensor['0x00124b00292c587e_occupancy'].last_changed) }} ago) | |
{%- endif -%} | |
{%- endif -%} | |
</p><br><br><br><br><br> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment