Skip to content

Instantly share code, notes, and snippets.

@miguelpucela
Last active October 14, 2021 23:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save miguelpucela/4c6a4877becf46139caac549f826cb44 to your computer and use it in GitHub Desktop.
Save miguelpucela/4c6a4877becf46139caac549f826cb44 to your computer and use it in GitHub Desktop.
Unchanged Sensor Detection and Notification
#######################################################################################################################
## Sensor - Unchanged Entities Sensors
## Count and list of entities which have not changed for the last 'time' matching the pattern and device_class
## Based on jazzyisj/package_unavailable_entities.yaml. Thanks for his code.
## - state: number of unchanged sensors
## - attribute: sensor_names - comma separated list of unchanged sensor names
## - attribute: sensor_entities: - comma separated list of unchanged sensor entity id's
## - updates every minute (sensor.time)
## - sensor entity_id's in ignored_sensors are filtered from this sensor
## - group.ignored_sensors MUST exist even if empty for sensor template to render
## - configuration variables:
## pattern: sensor entity_ids pattern to take into account
## device_class: device_class of the sensors to take into account
## time: lapse of time before present to check if sensors have changed its state
## input_datetime.unchanged_time: time to check during which sensors have not changed its value
#######################################################################################################################
sensor:
- platform: template
sensors:
unchanged_sensors:
entity_id:
- sensor.time
- input_datetime.unchanged_time
friendly_name_template: >
{% if states('sensor.unchanged_sensors') | int == 0 %}
All Sensors Changed Lately
{% else %}
Sensors Unchanged Lately
{% endif %}
icon_template: >-
{% if states('sensor.unchanged_sensors') | int == 0 %}
mdi:thumb-up
{% else %}
mdi:thumb-down
{% endif %}
value_template: >
{% set ignored_sensors = state_attr('group.ignored_sensors', 'entity_id') %}
{% set pattern = 'sensor.sonoff' %}
{% set device_class = 'temperature' %}
{% set unchanged_seconds = state_attr('input_datetime.unchanged_time', 'timestamp') %}
{% set time = now() - timedelta(seconds = unchanged_seconds) %}
{% set unchanged = states.sensor | selectattr('last_changed', '<', time)
| selectattr('entity_id', 'search', pattern)
| selectattr('attributes.device_class', 'eq', device_class)
| rejectattr('entity_id', 'in', ignored_sensors)
| map(attribute='entity_id')
| list
| length %}
{{ unchanged }}
attribute_templates:
sensor_names: >
{% set ignored_sensors = state_attr('group.ignored_sensors', 'entity_id') %}
{% set pattern = 'sensor.sonoff' %}
{% set device_class = 'temperature' %}
{% set unchanged_seconds = state_attr('input_datetime.unchanged_time', 'timestamp') %}
{% set time = now() - timedelta(seconds = unchanged_seconds) %}
{% set sensor_names = states.sensor | selectattr('last_changed', '<', time)
| selectattr('entity_id', 'search', pattern)
| selectattr('attributes.device_class', 'eq', device_class)
| rejectattr('entity_id', 'in', ignored_sensors)
| map(attribute='name')
| list
| join(', ') %}
{{ sensor_names }}
sensor_entity_ids: >
{% set ignored_sensors = state_attr('group.ignored_sensors', 'entity_id') %}
{% set pattern = 'sensor.sonoff' %}
{% set device_class = 'temperature' %}
{% set unchanged_seconds = state_attr('input_datetime.unchanged_time', 'timestamp') %}
{% set time = now() - timedelta(seconds = unchanged_seconds) %}
{% set sensor_ids = states.sensor | selectattr('last_changed', '<', time)
| selectattr('entity_id', 'search', pattern)
| selectattr('attributes.device_class', 'eq', device_class)
| rejectattr('entity_id', 'in', ignored_sensors)
| map(attribute='entity_id')
| list
| join(', ') %}
{{ sensor_ids }}
group:
ignored_sensors:
entities:
- sensor.fordpass_elveh
automation:
- id: sensor_unchanged_notification
alias: "Sensor Unchanged Notification"
description: "Send notification when sensor not updated for some time."
trigger:
# run whenever unchanged sensors sensor state changes
- platform: state
entity_id: sensor.unchanged_sensors
condition:
# only run if the number of unchanged sensors had gone up
- condition: template
value_template: "{{ trigger.to_state.state | int > trigger.from_state.state | int }}"
action:
# wait 30 seconds before rechecking sensor state
- delay:
seconds: 30
# make sure the sensor is updated before we check the state
- service: homeassistant.update_entity
entity_id: sensor.unchanged_sensors
# only continue if current number of sensors is equal or more than the number when triggered
- condition: template
value_template: "{{ states('sensor.unchanged_sensors') | int >= trigger.to_state.state | int }} "
# create a persistent notification
- service: persistent_notification.create
data_template:
title: "Sensor Unchanged"
message: "### Unchanged Sensors: {{ '\n' + state_attr('sensor.unchanged_sensors','sensor_names').split(', ') | join('\n') }}"
notification_id: 'sensor_alert'
- id: dismiss_sensor_unchanged_notification
alias: "Dismiss Sensor Unchanged Notification"
description: "Send notification when sensor not updated for some time."
trigger:
# run when there are no more unchanged
- platform: numeric_state
entity_id: sensor.unchanged_sensors
below: 1
action:
# dismiss the persistent notification
- service: persistent_notification.dismiss
data:
notification_id: 'sensor_alert'
@miguelpucela
Copy link
Author

I've added the possibility to match several patterns and use of search instead of match, which only matches the begining of the string.

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