Fix unavailable_entities self-reference loop + oversized recorder attribute; remove duplicate devices_currently_blocked/system_health_score block
This commit is contained in:
+513
@@ -0,0 +1,513 @@
|
|||||||
|
# sensors.yaml - All sensors for monitoring, device management, and household automation
|
||||||
|
|
||||||
|
# Hardware monitoring sensors
|
||||||
|
- platform: openhardwaremonitor
|
||||||
|
host: 10.0.0.245
|
||||||
|
port: 8085
|
||||||
|
|
||||||
|
# SNMP sensors for NVX monitoring
|
||||||
|
- platform: snmp
|
||||||
|
host: 10.0.0.232
|
||||||
|
baseoid: 1.3.6.1.2.1.1.5.0
|
||||||
|
name: "NVX Name"
|
||||||
|
|
||||||
|
- platform: snmp
|
||||||
|
host: 10.0.0.232
|
||||||
|
baseoid: 1.3.6.1.4.1.4526.18.4.1.2.1
|
||||||
|
name: "NVX Fan RPM"
|
||||||
|
|
||||||
|
- platform: snmp
|
||||||
|
host: 10.0.0.232
|
||||||
|
baseoid: 1.3.6.1.4.1.4526.18.5.1.2.1
|
||||||
|
name: "NVX Temp Value"
|
||||||
|
|
||||||
|
# Command line sensors
|
||||||
|
- platform: command_line
|
||||||
|
name: "Chore Summary"
|
||||||
|
command: "cat /config/www/chore_summary.txt"
|
||||||
|
scan_interval: 60
|
||||||
|
|
||||||
|
- platform: command_line
|
||||||
|
name: "Chore Log Raw"
|
||||||
|
command: "cat /config/www/chore_log.txt"
|
||||||
|
scan_interval: 60
|
||||||
|
|
||||||
|
# Time and date sensors
|
||||||
|
- platform: time_date
|
||||||
|
display_options:
|
||||||
|
- "time"
|
||||||
|
- "date"
|
||||||
|
|
||||||
|
# All template sensors (using legacy format for compatibility)
|
||||||
|
- platform: template
|
||||||
|
sensors:
|
||||||
|
# Waste collection sensors
|
||||||
|
green_bin:
|
||||||
|
friendly_name: "Greens Bin"
|
||||||
|
value_template: >
|
||||||
|
{% set start_date = as_timestamp('2026-04-12 00:00:00') %}
|
||||||
|
{% set now_ts = now().timestamp() %}
|
||||||
|
{% set weeks_since_start = ((now_ts - start_date) / 604800) | round(0, 'floor') | int %}
|
||||||
|
{{ now().weekday() == 6 and weeks_since_start % 2 == 0 }}
|
||||||
|
|
||||||
|
recycling_bin:
|
||||||
|
friendly_name: "Recycling Bin"
|
||||||
|
value_template: >
|
||||||
|
{% set start_date = as_timestamp('2026-04-12 00:00:00') %}
|
||||||
|
{% set now_ts = now().timestamp() %}
|
||||||
|
{% set weeks_since_start = ((now_ts - start_date) / 604800) | round(0, 'floor') | int %}
|
||||||
|
{{ now().weekday() == 6 and weeks_since_start % 2 == 1 }}
|
||||||
|
|
||||||
|
# Time-based sensors
|
||||||
|
is_weekday:
|
||||||
|
friendly_name: "Is Weekday"
|
||||||
|
value_template: >
|
||||||
|
{% set now = now() %}
|
||||||
|
{{ now.weekday() >= 0 and now.weekday() <= 4 }}
|
||||||
|
|
||||||
|
current_day_name:
|
||||||
|
friendly_name: "Current Day Name"
|
||||||
|
value_template: >
|
||||||
|
{% set now = now() %}
|
||||||
|
{% set day_number = now.weekday() %}
|
||||||
|
{{ ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'][day_number] }}
|
||||||
|
|
||||||
|
is_morning:
|
||||||
|
friendly_name: "Is Morning"
|
||||||
|
value_template: >
|
||||||
|
{% set now = now() %}
|
||||||
|
{{ now.hour >= 6 and now.hour < 12 }}
|
||||||
|
|
||||||
|
is_afternoon:
|
||||||
|
friendly_name: "Is Afternoon"
|
||||||
|
value_template: >
|
||||||
|
{% set now = now() %}
|
||||||
|
{{ now.hour >= 12 and now.hour < 18 }}
|
||||||
|
|
||||||
|
is_evening:
|
||||||
|
friendly_name: "Is Evening"
|
||||||
|
value_template: >
|
||||||
|
{% set now = now() %}
|
||||||
|
{{ now.hour >= 18 and now.hour < 21 }}
|
||||||
|
|
||||||
|
is_bedtime:
|
||||||
|
friendly_name: "Is Bedtime"
|
||||||
|
value_template: >
|
||||||
|
{% set now = now() %}
|
||||||
|
{{ now.hour >= 21 and now.hour <= 23 }}
|
||||||
|
|
||||||
|
is_weekend:
|
||||||
|
friendly_name: "Is Weekend"
|
||||||
|
value_template: >
|
||||||
|
{% set now = now() %}
|
||||||
|
{{ now.weekday() >= 5 }}
|
||||||
|
|
||||||
|
# School term sensors
|
||||||
|
school_term_1:
|
||||||
|
friendly_name: "School Term 1"
|
||||||
|
value_template: >
|
||||||
|
{% set now = as_timestamp(now()) %}
|
||||||
|
{% set start = as_timestamp(strptime('2026-01-27', '%Y-%m-%d')) %}
|
||||||
|
{% set end = as_timestamp(strptime('2026-04-02', '%Y-%m-%d')) %}
|
||||||
|
{{ now >= start and now <= end }}
|
||||||
|
|
||||||
|
school_term_2:
|
||||||
|
friendly_name: "School Term 2"
|
||||||
|
value_template: >
|
||||||
|
{% set now = as_timestamp(now()) %}
|
||||||
|
{% set start = as_timestamp(strptime('2026-04-20', '%Y-%m-%d')) %}
|
||||||
|
{% set end = as_timestamp(strptime('2026-06-26', '%Y-%m-%d')) %}
|
||||||
|
{{ now >= start and now <= end }}
|
||||||
|
|
||||||
|
school_term_3:
|
||||||
|
friendly_name: "School Term 3"
|
||||||
|
value_template: >
|
||||||
|
{% set now = as_timestamp(now()) %}
|
||||||
|
{% set start = as_timestamp(strptime('2026-07-13', '%Y-%m-%d')) %}
|
||||||
|
{% set end = as_timestamp(strptime('2026-09-18', '%Y-%m-%d')) %}
|
||||||
|
{{ now >= start and now <= end }}
|
||||||
|
|
||||||
|
school_term_4:
|
||||||
|
friendly_name: "School Term 4"
|
||||||
|
value_template: >
|
||||||
|
{% set now = as_timestamp(now()) %}
|
||||||
|
{% set start = as_timestamp(strptime('2026-10-05', '%Y-%m-%d')) %}
|
||||||
|
{% set end = as_timestamp(strptime('2026-12-18', '%Y-%m-%d')) %}
|
||||||
|
{{ now >= start and now <= end }}
|
||||||
|
|
||||||
|
is_school_term:
|
||||||
|
friendly_name: "Is School Term"
|
||||||
|
value_template: >
|
||||||
|
{{ states('sensor.school_term_1') == 'True' or
|
||||||
|
states('sensor.school_term_2') == 'True' or
|
||||||
|
states('sensor.school_term_3') == 'True' or
|
||||||
|
states('sensor.school_term_4') == 'True' }}
|
||||||
|
|
||||||
|
current_date_debug:
|
||||||
|
friendly_name: "Current Date Debug"
|
||||||
|
value_template: >
|
||||||
|
{{ now().date() }}
|
||||||
|
|
||||||
|
# Task management sensors
|
||||||
|
active_tasks_count:
|
||||||
|
friendly_name: "Active Tasks Count"
|
||||||
|
value_template: >
|
||||||
|
{% set tasks = [
|
||||||
|
'input_boolean.task_dishwasher_unload_pending',
|
||||||
|
'input_boolean.task_washing_machine_unload_pending',
|
||||||
|
'input_boolean.task_dryer_unload_pending',
|
||||||
|
'input_boolean.task_bins_out_pending',
|
||||||
|
'input_boolean.task_bins_in_pending',
|
||||||
|
'input_boolean.task_kitty_litter_clean_pending',
|
||||||
|
'input_boolean.task_kitty_litter_change_pending'
|
||||||
|
] %}
|
||||||
|
{{ tasks | select('is_state', 'on') | list | count }}
|
||||||
|
|
||||||
|
pending_tasks_list:
|
||||||
|
friendly_name: "Pending Tasks"
|
||||||
|
value_template: >
|
||||||
|
{% set task_names = {
|
||||||
|
'input_boolean.task_dishwasher_unload_pending': 'Unload Dishwasher',
|
||||||
|
'input_boolean.task_washing_machine_unload_pending': 'Unload Washing Machine',
|
||||||
|
'input_boolean.task_dryer_unload_pending': 'Unload Dryer',
|
||||||
|
'input_boolean.task_bins_out_pending': 'Put Bins Out',
|
||||||
|
'input_boolean.task_bins_in_pending': 'Bring Bins In',
|
||||||
|
'input_boolean.task_kitty_litter_clean_pending': 'Clean Kitty Litter',
|
||||||
|
'input_boolean.task_kitty_litter_change_pending': 'Change Kitty Litter'
|
||||||
|
} %}
|
||||||
|
{% set pending = [] %}
|
||||||
|
{% for entity, name in task_names.items() %}
|
||||||
|
{% if is_state(entity, 'on') %}
|
||||||
|
{% set pending = pending + [name] %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{{ pending | join(', ') }}
|
||||||
|
|
||||||
|
last_kitty_litter_change:
|
||||||
|
friendly_name: "Last Kitty Litter Change"
|
||||||
|
value_template: >
|
||||||
|
{{ states('input_datetime.last_kitty_litter_change') | as_timestamp | timestamp_custom('%Y-%m-%d')
|
||||||
|
if states('input_datetime.last_kitty_litter_change') != 'unknown' else 'Never' }}
|
||||||
|
|
||||||
|
# Weekly task totals for each person
|
||||||
|
lou_weekly_tasks:
|
||||||
|
friendly_name: "Lou's Weekly Tasks"
|
||||||
|
value_template: "{{ states('counter.chores_completed_lou') | int }}"
|
||||||
|
icon_template: mdi:account
|
||||||
|
|
||||||
|
jess_weekly_tasks:
|
||||||
|
friendly_name: "Jess's Weekly Tasks"
|
||||||
|
value_template: "{{ states('counter.chores_completed_jess') | int }}"
|
||||||
|
icon_template: mdi:account
|
||||||
|
|
||||||
|
william_weekly_tasks:
|
||||||
|
friendly_name: "William's Weekly Tasks"
|
||||||
|
value_template: "{{ states('counter.chores_completed_william') | int }}"
|
||||||
|
icon_template: mdi:account
|
||||||
|
|
||||||
|
xander_weekly_tasks:
|
||||||
|
friendly_name: "Xander's Weekly Tasks"
|
||||||
|
value_template: "{{ states('counter.chores_completed_xander') | int }}"
|
||||||
|
icon_template: mdi:account
|
||||||
|
|
||||||
|
bella_weekly_tasks:
|
||||||
|
friendly_name: "Bella's Weekly Tasks"
|
||||||
|
value_template: "{{ states('counter.chores_completed_bella') | int }}"
|
||||||
|
icon_template: mdi:account
|
||||||
|
|
||||||
|
# Total weekly tasks
|
||||||
|
total_weekly_tasks:
|
||||||
|
friendly_name: "Total Weekly Tasks"
|
||||||
|
value_template: >
|
||||||
|
{{ states('counter.chores_completed_lou') | int +
|
||||||
|
states('counter.chores_completed_jess') | int +
|
||||||
|
states('counter.chores_completed_william') | int +
|
||||||
|
states('counter.chores_completed_xander') | int +
|
||||||
|
states('counter.chores_completed_bella') | int }}
|
||||||
|
icon_template: mdi:clipboard-list
|
||||||
|
|
||||||
|
# Percentage calculations for pie chart
|
||||||
|
lou_percentage:
|
||||||
|
friendly_name: "Lou's Percentage"
|
||||||
|
value_template: >
|
||||||
|
{% set total = states('sensor.total_weekly_tasks') | int %}
|
||||||
|
{% set lou_tasks = states('counter.chores_completed_lou') | int %}
|
||||||
|
{% if total > 0 %}
|
||||||
|
{{ ((lou_tasks / total) * 100) | round(1) }}
|
||||||
|
{% else %}
|
||||||
|
0
|
||||||
|
{% endif %}
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
|
||||||
|
jess_percentage:
|
||||||
|
friendly_name: "Jess's Percentage"
|
||||||
|
value_template: >
|
||||||
|
{% set total = states('sensor.total_weekly_tasks') | int %}
|
||||||
|
{% set jess_tasks = states('counter.chores_completed_jess') | int %}
|
||||||
|
{% if total > 0 %}
|
||||||
|
{{ ((jess_tasks / total) * 100) | round(1) }}
|
||||||
|
{% else %}
|
||||||
|
0
|
||||||
|
{% endif %}
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
|
||||||
|
william_percentage:
|
||||||
|
friendly_name: "William's Percentage"
|
||||||
|
value_template: >
|
||||||
|
{% set total = states('sensor.total_weekly_tasks') | int %}
|
||||||
|
{% set william_tasks = states('counter.chores_completed_william') | int %}
|
||||||
|
{% if total > 0 %}
|
||||||
|
{{ ((william_tasks / total) * 100) | round(1) }}
|
||||||
|
{% else %}
|
||||||
|
0
|
||||||
|
{% endif %}
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
|
||||||
|
xander_percentage:
|
||||||
|
friendly_name: "Xander's Percentage"
|
||||||
|
value_template: >
|
||||||
|
{% set total = states('sensor.total_weekly_tasks') | int %}
|
||||||
|
{% set xander_tasks = states('counter.chores_completed_xander') | int %}
|
||||||
|
{% if total > 0 %}
|
||||||
|
{{ ((xander_tasks / total) * 100) | round(1) }}
|
||||||
|
{% else %}
|
||||||
|
0
|
||||||
|
{% endif %}
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
|
||||||
|
bella_percentage:
|
||||||
|
friendly_name: "Bella's Percentage"
|
||||||
|
value_template: >
|
||||||
|
{% set total = states('sensor.total_weekly_tasks') | int %}
|
||||||
|
{% set bella_tasks = states('counter.chores_completed_bella') | int %}
|
||||||
|
{% if total > 0 %}
|
||||||
|
{{ ((bella_tasks / total) * 100) | round(1) }}
|
||||||
|
{% else %}
|
||||||
|
0
|
||||||
|
{% endif %}
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
|
||||||
|
# Network and device management sensors
|
||||||
|
total_devices_online:
|
||||||
|
friendly_name: "Total Devices Online"
|
||||||
|
icon_template: mdi:devices
|
||||||
|
unit_of_measurement: "devices"
|
||||||
|
value_template: >
|
||||||
|
{{ [
|
||||||
|
states('device_tracker.william_pc'),
|
||||||
|
states('device_tracker.william_laptop'),
|
||||||
|
states('device_tracker.william_phone'),
|
||||||
|
states('device_tracker.jess_laptop_1'),
|
||||||
|
states('device_tracker.jess_phone'),
|
||||||
|
states('device_tracker.bella_desktop'),
|
||||||
|
states('device_tracker.bella_phone'),
|
||||||
|
states('device_tracker.xander_gaming_pc'),
|
||||||
|
states('device_tracker.xander_console')
|
||||||
|
] | select('eq', 'home') | list | count }}
|
||||||
|
availability_template: >
|
||||||
|
{{ has_value('device_tracker.william_pc')
|
||||||
|
and has_value('device_tracker.jess_laptop_1')
|
||||||
|
and has_value('device_tracker.bella_phone') }}
|
||||||
|
|
||||||
|
# NOTE: This sensor MUST exclude its own entity_id, otherwise every
|
||||||
|
# recalculation changes its own state, which retriggers the template,
|
||||||
|
# causing a "Template loop detected" storm. The full entity list is
|
||||||
|
# intentionally NOT stored as an attribute (it exceeded the 16384-byte
|
||||||
|
# recorder limit and was rejected every cycle); only a capped preview
|
||||||
|
# is exposed for dashboards.
|
||||||
|
unavailable_entities:
|
||||||
|
friendly_name: "Unavailable Entities"
|
||||||
|
icon_template: >
|
||||||
|
{{ 'mdi:check-circle' if states('sensor.unavailable_entities')|int == 0 else 'mdi:alert-circle' }}
|
||||||
|
unit_of_measurement: "entities"
|
||||||
|
value_template: >
|
||||||
|
{{ states | selectattr('state', 'in', ['unavailable', 'unknown'])
|
||||||
|
| rejectattr('domain', 'eq', 'group')
|
||||||
|
| rejectattr('entity_id', 'eq', 'sensor.unavailable_entities')
|
||||||
|
| rejectattr('entity_id', 'search', 'sun\.')
|
||||||
|
| list | count }}
|
||||||
|
attribute_templates:
|
||||||
|
# Capped to first 50 entity_ids to stay well under the 16 KB
|
||||||
|
# recorder attribute limit. Drop this block entirely if you don't
|
||||||
|
# need the preview on a dashboard.
|
||||||
|
entities_preview: >
|
||||||
|
{{ (states | selectattr('state', 'in', ['unavailable', 'unknown'])
|
||||||
|
| rejectattr('domain', 'eq', 'group')
|
||||||
|
| rejectattr('entity_id', 'eq', 'sensor.unavailable_entities')
|
||||||
|
| rejectattr('entity_id', 'search', 'sun\.')
|
||||||
|
| map(attribute='entity_id') | list | sort)[:50] }}
|
||||||
|
|
||||||
|
family_devices_status:
|
||||||
|
friendly_name: "Family Devices Status"
|
||||||
|
icon_template: mdi:account-multiple
|
||||||
|
value_template: >
|
||||||
|
{% set devices = [
|
||||||
|
'device_tracker.william_pc',
|
||||||
|
'device_tracker.william_phone',
|
||||||
|
'device_tracker.jess_laptop_1',
|
||||||
|
'device_tracker.jess_phone',
|
||||||
|
'device_tracker.bella_desktop',
|
||||||
|
'device_tracker.bella_phone',
|
||||||
|
'device_tracker.xander_gaming_pc'
|
||||||
|
] %}
|
||||||
|
{% set online = devices | select('is_state', 'home') | list | count %}
|
||||||
|
{% set total = devices | count %}
|
||||||
|
{{ online }}/{{ total }}
|
||||||
|
|
||||||
|
network_performance_score:
|
||||||
|
friendly_name: "Network Performance Score"
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
icon_template: >
|
||||||
|
{% set score = states('sensor.network_performance_score') | int(0) %}
|
||||||
|
{% if score >= 80 %}mdi:speedometer
|
||||||
|
{% elif score >= 60 %}mdi:speedometer-medium
|
||||||
|
{% else %}mdi:speedometer-slow
|
||||||
|
{% endif %}
|
||||||
|
value_template: >
|
||||||
|
{% if is_state('binary_sensor.ping_router', 'on') %}
|
||||||
|
{% set ping_time = state_attr('binary_sensor.ping_router', 'round_trip_time_avg') | float(0) %}
|
||||||
|
{% if ping_time < 10 %}100
|
||||||
|
{% elif ping_time < 50 %}80
|
||||||
|
{% elif ping_time < 100 %}60
|
||||||
|
{% elif ping_time < 200 %}40
|
||||||
|
{% else %}20
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
0
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
blocked_devices_count:
|
||||||
|
friendly_name: "Blocked Devices Count"
|
||||||
|
icon_template: mdi:block-helper
|
||||||
|
unit_of_measurement: "devices"
|
||||||
|
value_template: >
|
||||||
|
{{ states.input_boolean
|
||||||
|
| selectattr('entity_id', 'match', '.*_blocked$')
|
||||||
|
| selectattr('state', 'eq', 'on')
|
||||||
|
| list | count }}
|
||||||
|
attribute_templates:
|
||||||
|
blocked_devices: >
|
||||||
|
{{ states.input_boolean
|
||||||
|
| selectattr('entity_id', 'match', '.*_blocked$')
|
||||||
|
| selectattr('state', 'eq', 'on')
|
||||||
|
| map(attribute='name')
|
||||||
|
| list }}
|
||||||
|
|
||||||
|
bella_devices_status:
|
||||||
|
friendly_name: "Bella Devices Status"
|
||||||
|
icon_template: mdi:account-child
|
||||||
|
value_template: >
|
||||||
|
{% set blocked = states.input_boolean
|
||||||
|
| selectattr('entity_id', 'match', '^input_boolean\.bella_.*_blocked$')
|
||||||
|
| selectattr('state', 'eq', 'on')
|
||||||
|
| list | count %}
|
||||||
|
{% set total = 7 %}
|
||||||
|
{% if blocked == 0 %}All Access
|
||||||
|
{% elif blocked == total %}Fully Blocked
|
||||||
|
{% else %}{{ blocked }}/{{ total }} Blocked
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
xander_devices_status:
|
||||||
|
friendly_name: "Xander Devices Status"
|
||||||
|
icon_template: mdi:account-child
|
||||||
|
value_template: >
|
||||||
|
{% set blocked = states.input_boolean
|
||||||
|
| selectattr('entity_id', 'match', '^input_boolean\.xander_.*_blocked$')
|
||||||
|
| selectattr('state', 'eq', 'on')
|
||||||
|
| list | count %}
|
||||||
|
{% set total = 7 %}
|
||||||
|
{% if blocked == 0 %}All Access
|
||||||
|
{% elif blocked == total %}Fully Blocked
|
||||||
|
{% else %}{{ blocked }}/{{ total }} Blocked
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
william_devices_status:
|
||||||
|
friendly_name: "William Devices Status"
|
||||||
|
icon_template: mdi:account-child
|
||||||
|
value_template: >
|
||||||
|
{% set blocked = states.input_boolean
|
||||||
|
| selectattr('entity_id', 'match', '^input_boolean\.william_.*_blocked$')
|
||||||
|
| selectattr('state', 'eq', 'on')
|
||||||
|
| list | count %}
|
||||||
|
{% set total = 7 %}
|
||||||
|
{% if blocked == 0 %}All Access
|
||||||
|
{% elif blocked == total %}Fully Blocked
|
||||||
|
{% else %}{{ blocked }}/{{ total }} Blocked
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# Device blocking statistics
|
||||||
|
devices_currently_blocked:
|
||||||
|
friendly_name: "Devices Currently Blocked"
|
||||||
|
icon_template: mdi:shield-lock
|
||||||
|
unit_of_measurement: "devices"
|
||||||
|
value_template: >
|
||||||
|
{{ states.input_boolean
|
||||||
|
| selectattr('entity_id', 'match', '.*_blocked$')
|
||||||
|
| selectattr('state', 'eq', 'on')
|
||||||
|
| list | count }}
|
||||||
|
|
||||||
|
# System health monitoring
|
||||||
|
system_health_score:
|
||||||
|
friendly_name: "System Health Score"
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
icon_template: >
|
||||||
|
{% set score = states('sensor.system_health_score') | int(0) %}
|
||||||
|
{% if score >= 90 %}mdi:heart-pulse
|
||||||
|
{% elif score >= 70 %}mdi:heart-half-full
|
||||||
|
{% else %}mdi:heart-broken
|
||||||
|
{% endif %}
|
||||||
|
value_template: >
|
||||||
|
{% set router_ok = 1 if is_state('binary_sensor.ping_router', 'on') else 0 %}
|
||||||
|
{% set auth_ok = 1 if states('input_text.router_token') not in ['unknown', '', 'unavailable'] else 0 %}
|
||||||
|
{% set internet_ok = 1 if is_state('binary_sensor.internet_connectivity', 'on') else 0 %}
|
||||||
|
{% set unavailable = states('sensor.unavailable_entities') | int(0) %}
|
||||||
|
{% set health_penalty = (unavailable * 2) | int %}
|
||||||
|
{% set base_score = ((router_ok + auth_ok + internet_ok) * 30) | int %}
|
||||||
|
{{ [base_score - health_penalty, 0] | max }}
|
||||||
|
|
||||||
|
# Network security level
|
||||||
|
network_security_level:
|
||||||
|
friendly_name: "Network Security Level"
|
||||||
|
icon_template: >
|
||||||
|
{% set level = states('sensor.network_security_level') %}
|
||||||
|
{% if level == 'High' %}mdi:shield-check
|
||||||
|
{% elif level == 'Medium' %}mdi:shield-half-full
|
||||||
|
{% else %}mdi:shield-alert
|
||||||
|
{% endif %}
|
||||||
|
value_template: >
|
||||||
|
{% set blocked = states('sensor.devices_currently_blocked') | int(0) %}
|
||||||
|
{% if blocked >= 10 %}High
|
||||||
|
{% elif blocked >= 5 %}Medium
|
||||||
|
{% elif blocked >= 1 %}Low
|
||||||
|
{% else %}Off
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# Router device count
|
||||||
|
router_device_count:
|
||||||
|
friendly_name: "Router Connected Devices"
|
||||||
|
icon_template: mdi:devices
|
||||||
|
unit_of_measurement: "devices"
|
||||||
|
value_template: >
|
||||||
|
{{ states.input_boolean
|
||||||
|
| selectattr('entity_id', 'match', '.*_online$')
|
||||||
|
| selectattr('state', 'eq', 'on')
|
||||||
|
| list | count }}
|
||||||
|
|
||||||
|
# Router access control rules count
|
||||||
|
router_access_control_rules:
|
||||||
|
friendly_name: "Active Access Control Rules"
|
||||||
|
icon_template: mdi:shield-check
|
||||||
|
unit_of_measurement: "rules"
|
||||||
|
value_template: >
|
||||||
|
{{ states('sensor.devices_currently_blocked') | int(0) }}
|
||||||
|
|
||||||
|
# MAC address change detection
|
||||||
|
devices_with_changed_macs:
|
||||||
|
friendly_name: "Devices with Changed MACs"
|
||||||
|
icon_template: mdi:alert-circle
|
||||||
|
unit_of_measurement: "devices"
|
||||||
|
value_template: >
|
||||||
|
{{ states.input_boolean
|
||||||
|
| selectattr('entity_id', 'match', '.*_mac_changed$')
|
||||||
|
| selectattr('state', 'eq', 'on')
|
||||||
|
| list | count }}
|
||||||
Reference in New Issue
Block a user