Skip to content

Commit 365442f

Browse files
committed
Add disabled devices and ignored label filters.
1 parent f1e3d3c commit 365442f

File tree

3 files changed

+68
-31
lines changed

3 files changed

+68
-31
lines changed

README.md

+32-16
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ to use the example lovelace card. They are both available on [HACS](https://www
1212

1313
## What does this package do?
1414

15-
This package creates a group of entities that have no value (a state of unknown or unavailable) and a sensor that provides a count of the entities in this group.
15+
This package creates a group of entities that have no value (a state of unknown or unavailable) and a sensor that provides a count of the entities in this group. This can help you discover entities which should to be disabled or deleted and help you identify misbehaving or failed devices.
16+
17+
By default, entities belonging to disabled devices are ignored by the unavailable entities sensor. Entities belonging a devices labelled "Ignored" and individual entities labled "Ignored" are also ignored. The default label "Ignored" can be changed in the group.unavavailable_entities template. The label is not case sensitive.
1618

1719
## How do I install it?
1820

@@ -51,7 +53,7 @@ Example - add the `switch` domain.
5153

5254
### Ignore Specific Entities
5355

54-
Uncomment the `group.ignored_unavailable_entities` declaration and add the entity_id's to ignore to the group entities list.
56+
To ignore specific entities, add them to the `group.ignored_unavailable_entities` declaration.
5557

5658
### Ignore Matching Entities
5759

@@ -104,19 +106,33 @@ You can exclude entities from a specific integration by using an `in` test for t
104106
data:
105107
object_id: unavailable_entities
106108
entities: >
107-
{{ states
108-
| rejectattr('domain', 'in', ['button', 'conversation', 'event', 'group', 'image',
109-
'input_button', 'input_text', 'remote', 'tts', 'scene', 'stt'])
110-
| rejectattr('entity_id', 'in', state_attr('group.ignored_entities', 'entity_id'))
111-
| rejectattr('entity_id', 'eq', 'group.unavailable_entities')
112-
| rejectattr('domain', 'in', ['button', 'event', 'group', 'input_button', 'input_text', 'scene'])
113-
| rejectattr('entity_id', 'search', 'browser_')
114-
| rejectattr('entity_id', 'search', '_alarm_volume|_next_alarm|_alarms')
115-
| rejectattr('entity_id', 'contains', '_memory_percent')
116-
| rejectattr('entity_id', 'in',integration_entities('hassio'))
117-
| rejectattr('entity_id', 'in',device_entities('fffe8e4c87c68ee60e0ae84c295676ce'))
118-
| selectattr('state', 'in', ['unknown', 'unavailable'])
119-
| map(attribute='entity_id') | list | sort }}
109+
{% set ignore_seconds = 60 %}
110+
{% set ignore_label = 'ignored' %}
111+
{% set ignored_domains = ['button', 'conversation', 'event', 'group', 'image',
112+
'input_button', 'input_text', 'remote', 'tts', 'scene', 'stt', 'update'] %}
113+
{% set ignore_ts = (now().timestamp() - ignore_seconds)|as_datetime %}
114+
{% set disabled_device_entities = state_attr('sensor.disabled_device_entities', 'entities')
115+
| regex_replace(find='\[|\]|\{|\}|\'entity_id\':', replace='') %}
116+
{% set ignored_devices = label_devices(ignore_label | lower) %}
117+
{% set ignored_device_entities = namespace(value=[]) %}
118+
{% for device in ignored_devices %}
119+
{% set ignored_device_entities.value = ignored_device_entities.value + device_entities(device) %}
120+
{% endfor %}
121+
{{ states
122+
| rejectattr('domain', 'in', ignored_domains)
123+
| rejectattr('entity_id', 'in', disabled_device_entities)
124+
| rejectattr('entity_id', 'in', state_attr('group.ignored_entities', 'entity_id'))
125+
| rejectattr('entity_id', 'in', ['group.unavailable_entities', 'group.ignored_entities'])
126+
| rejectattr('entity_id', 'in', ignored_device_entities.value)
127+
| rejectattr('entity_id', 'in', label_entities(ignore_label | lower))
128+
| rejectattr('last_changed', 'ge', ignore_ts)
129+
| rejectattr('entity_id', 'search', 'browser_')
130+
| rejectattr('entity_id', 'search', '_alarm_volume|_next_alarm|_alarms')
131+
| rejectattr('entity_id', 'contains', '_memory_percent')
132+
| rejectattr('entity_id', 'in', integration_entities('hassio'))
133+
| rejectattr('entity_id', 'in', device_entities('fffe8e4c87c68ee60e0ae84c295676ce'))
134+
| selectattr('state', 'in', ['unknown', 'unavailable'])
135+
| map(attribute='entity_id') | list | sort }}
120136

121137
See [Home Assistant Templating](https://www.home-assistant.io/docs/configuration/templating/) for additional options.
122138

@@ -152,7 +168,7 @@ This is useful to create sensors that monitor specific domains, integrations etc
152168
| map(attribute='entity_id') | list | sort }}
153169

154170
## Using With Automations
155-
There is an example automation provided in the package that will display unavailable entities as a persistent notification. You can change this automation to meet your requirements. This automation is enabled by default. You can comment it out or delete it if not required.
171+
There is an example automation provided in the package that will display unavailable entities as a persistent notification. You can change this automation to meet your requirements. This automation is enabled by default. You can comment it out or delete it if not required. See the examples folder for more automations.
156172

157173
## Display in the UI
158174
To display a list of unavailable entities open the more-info dialogue of group.unavailable_entities.

package_unavailable_entities.yaml

+33-9
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
###################################################################################################
2-
## PACKAGE: Unavailable Entities Sensor v2.2
2+
## PACKAGE: Unavailable Entities Sensor v2.4
33
## DESCRIPTION: Count and list entities with a state of unknown or unavailable
44
## REQUIREMENTS: Home Assistant v2024.8
55
## USAGE: https://github.com/jazzyisj/unavailable-entities-sensor/blob/main/README.md
66
###################################################################################################
77

8-
# REQUIRED - This is the template sensor
8+
#REQUIRED - List of disabled device entities
9+
command_line:
10+
sensor:
11+
name: Disabled Device Entities
12+
unique_id: disabled_device_entities
13+
json_attributes:
14+
- entities
15+
value_template: "{{ value_json.entities | length }}"
16+
command: 'jq ''.data.entities |= map(select(.disabled_by? != null) | {entity_id: .entity_id}) | del(.data.deleted_entities) | flatten | .[3]'' < .storage/core.entity_registry'
17+
18+
#REQUIRED - Count of unavailable entities
919
template:
1020
- sensor:
1121
- name: "Unavailable Entities"
@@ -16,12 +26,13 @@ template:
1626
{% set entities = state_attr('group.unavailable_entities', 'entity_id') %}
1727
{{ entities | count if entities != none else -1 }}
1828
19-
# REQUIRED - Add individual entities to ignore to this group.
29+
#REQUIRED - Group of individually ignored entities
30+
#TODO - Add entities to group
2031
group:
2132
ignored_entities:
2233
entities: []
2334

24-
# REQUIRED - This is required to create and update the monitored entities group. Updates once every minute.
35+
#REQUIRED - Create and update the monitored entities group. Updates once per minute.
2536
automation:
2637
- id: update_unavailable_entities_group
2738
alias: "Update Unavailable Entities Group"
@@ -38,23 +49,36 @@ automation:
3849
- trigger: time_pattern
3950
minutes: "/1"
4051
actions:
41-
# IMPORTANT - This is the template to edit to exclude entities with filters.
52+
#IMPORTANT - This is the template to edit to exclude entities with filters.
53+
#TODO - Change ignore_seconds, ignore_label, ignored_domains, and filters to desired values
4254
- action: group.set
4355
data:
4456
object_id: unavailable_entities
4557
entities: >
4658
{% set ignore_seconds = 60 %}
59+
{% set ignore_label = 'ignored' %}
60+
{% set ignored_domains = ['button', 'conversation', 'event', 'group', 'image',
61+
'input_button', 'input_text', 'remote', 'tts', 'scene', 'stt', 'update'] %}
4762
{% set ignore_ts = (now().timestamp() - ignore_seconds)|as_datetime %}
63+
{% set disabled_device_entities = state_attr('sensor.disabled_device_entities', 'entities')
64+
| regex_replace(find='\[|\]|\{|\}|\'entity_id\':', replace='') %}
65+
{% set ignored_devices = label_devices(ignore_label | lower) %}
66+
{% set ignored_device_entities = namespace(value=[]) %}
67+
{% for device in ignored_devices %}
68+
{% set ignored_device_entities.value = ignored_device_entities.value + device_entities(device) %}
69+
{% endfor %}
4870
{{ states
49-
| rejectattr('domain', 'in', ['button', 'conversation', 'event', 'group', 'image',
50-
'input_button', 'input_text', 'remote', 'tts', 'scene', 'stt', 'update'])
71+
| rejectattr('domain', 'in', ignored_domains)
72+
| rejectattr('entity_id', 'in', disabled_device_entities)
5173
| rejectattr('entity_id', 'in', state_attr('group.ignored_entities', 'entity_id'))
52-
| rejectattr('entity_id', 'eq', 'group.unavailable_entities')
74+
| rejectattr('entity_id', 'in', ['group.unavailable_entities', 'group.ignored_entities'])
75+
| rejectattr('entity_id', 'in', ignored_device_entities.value)
76+
| rejectattr('entity_id', 'in', label_entities(ignore_label | lower))
5377
| rejectattr('last_changed', 'ge', ignore_ts)
5478
| selectattr('state', 'in', ['unknown', 'unavailable'])
5579
| map(attribute='entity_id') | list | sort }}
5680
57-
# OPTIONAL - Example automation to demonstrate how you can utilize this sensor, see example folder for more.
81+
#OPTIONAL - Example notfication automation to demonstrate how you can utilize this sensor. (See example folder for more.)
5882
- id: unavailable_entities_notification
5983
alias: "Unavailable Entities Notification"
6084
description: "Create persistent notification if unavailable entities, dismiss if none."

v1/package_unavailable_entities_old.yaml renamed to v1/package_unavailable_entities_v1.yaml

+3-6
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
## USAGE: https://github.com/jazzyisj/unavailable-entities-sensor/blob/main/README.md
66
###################################################################################################
77

8-
# REQUIRED - This is the template sensor
9-
8+
#REQUIRED - This is the template sensor
109
template:
1110
- sensor:
1211
- name: "Unavailable Entities"
@@ -28,15 +27,13 @@ template:
2827
{% set entities = entities | rejectattr('entity_id', 'in', ignored) if ignored != none else entities %}
2928
{{ entities | map(attribute='entity_id') | reject('has_value') | list | sort }}
3029
31-
# OPTIONAL - Add entities you want to ignore to this group. Delete if not using group.
32-
30+
#OPTIONAL - Add entities you want to ignore to this group. Delete if not using group.
3331
group:
3432
ignored_unavailable_entities:
3533
entities:
3634
- sensor.example_ignored_entity
3735

38-
# OPTIONAL Example automation to demonstrate how you can utilize this sensor, other examples in examples folder
39-
36+
#OPTIONAL Example automation to demonstrate how you can utilize this sensor, other examples in examples folder
4037
automation:
4138
- id: unavailable_entities_notification
4239
alias: "Unavailable Entities Notification"

0 commit comments

Comments
 (0)