Vor einiger Zeit, habe ich von ZigBee2MQTT zu ZHA gewechselt.
Nun wollte ich mir ansehen, wieviele Router im Netzwerk sind und musste feststellen, dass es mit ZHA gar nicht so einfach ist.
Aber nach dem Motto: Geht nicht, gibt’s nicht!
Musste halt ein Template her.
## ZigBee
{% set zha_devices = integration_entities('zha')
| map('device_id')
| unique
| list %}
{% set ns = namespace(battery=0, mains=0) %}
{% for device in zha_devices %}
{% set entities = device_entities(device) %}
{% if entities
| select('is_state_attr', 'device_class', 'battery')
| list
| count > 0 %}
{% set ns.battery = ns.battery + 1 %}
{% else %}
{% set ns.mains = ns.mains + 1 %}
{% endif %}
{% endfor %}
{% set offline =['zha']
| map('integration_entities')
| sum(start=[])
| select('is_state', 'unavailable')
| map('device_attr','name_by_user')
| unique
| list
| count
%}
🔋 Baterie: {{ ns.battery }}
🔌 Router: {{ ns.mains }}
⛔ Offline: {{ offline }}
### Gesamt: {{ zha_devices | count }}
Das Ganze dann in einen Markdown Karte verpackt und ab auf’s Dashboard.
Damit die ZigBee Geräte nicht ganz alleine da stehen, habe ich noch die Matter und Z-Wave Geräte dazu gepackt.
Eine erweiterte Darstellung. Alle ZigBee Geräte sortiert nach Räumen.
- Dimmschalter → die Batterie ist leer.
- Haustür → Ikea Parasoll. Der ist einfach Müll und geht alle ein paar Stunden offline. Bin noch nicht dazu gekommen diesen zu demontieren und zu entsorgen
- Motion Schuppen → Ikea BM. Leider auch nicht sehr zuverlässig.
{%- set zha_devices = integration_entities('zha') | map('device_id') | unique | list -%}
{%- set ns = namespace(
bat_tot=0, bat_on=0, bat_off=0,
main_tot=0, main_on=0, main_off=0,
rows=[],
offline_list=[]
) -%}
{%- for device in zha_devices -%}
{%- set entities = device_entities(device) -%}
{%- set real_entities = entities | select('match', '^(light|switch|sensor|binary_sensor|lock|cover|climate|fan)\..*') | list -%}
{%- set check_list = real_entities if real_entities | count > 0 else entities -%}
{%- set offline_entities = check_list | select('is_state', 'unavailable') | list -%}
{%- set is_offline = offline_entities | count > 0 -%}
{%- set is_battery = entities | select('is_state_attr', 'device_class', 'battery') | list | count > 0 -%}
{%- set area = area_name(device) | default('Unassigned', true) -%}
{%- set dev_name = device_attr(device, 'name_by_user') | default(device_attr(device, 'name'), true) -%}
{%- set type_str = "Bat" if is_battery else "Pwr" -%}
{%- if is_battery -%}
{%- set ns.bat_tot = ns.bat_tot + 1 -%}
{%- if is_offline -%}
{%- set ns.bat_off = ns.bat_off + 1 -%}
{%- else -%}
{%- set ns.bat_on = ns.bat_on + 1 -%}
{%- endif -%}
{%- else -%}
{%- set ns.main_tot = ns.main_tot + 1 -%}
{%- if is_offline -%}
{%- set ns.main_off = ns.main_off + 1 -%}
{%- else -%}
{%- set ns.main_on = ns.main_on + 1 -%}
{%- endif -%}
{%- endif -%}
{%- set status_str = "OFF" if is_offline else " OK" -%}
{%- set ns.rows = ns.rows + [{'area': area, 'type': type_str, 'status': status_str}] -%}
{%- if is_offline -%}
{%- set ns.offline_list = ns.offline_list + [{'name': dev_name, 'area': area, 'type': type_str}] -%}
{%- endif -%}
{%- endfor -%}
## 📡 ZigBee Netzwerk Gesundheit
```text
Zusammenfasung
---------------------------------
TYPE | GESAMT | OK | OFF
---------------------------------
Mains(Pwr)| {{ '%-5d' % ns.main_tot }}| {{ '%-5d' % ns.main_on }}| {{ ns.main_off }}
Battery | {{ '%-5d' % ns.bat_tot }}| {{ '%-5d' % ns.bat_on }}| {{ ns.bat_off }}
---------------------------------
Details (Offline/Online Anzahl)
-------------------------------------------
RAUM | PWR (OK/OFF) | BAT (OK/OFF)
-------------------------------------------
{% for area in ns.rows | map(attribute='area') | unique | sort %}
{%- set area_devices = ns.rows | selectattr('area', 'eq', area) | list -%}
{%- set pwr_ok = area_devices | selectattr('type','eq','Pwr') | selectattr('status','eq',' OK') | list | count -%}
{%- set pwr_off = area_devices | selectattr('type','eq','Pwr') | selectattr('status','eq','OFF') | list | count -%}
{%- set bat_ok = area_devices | selectattr('type','eq','Bat') | selectattr('status','eq',' OK') | list | count -%}
{%- set bat_off = area_devices | selectattr('type','eq','Bat') | selectattr('status','eq','OFF') | list | count -%}
{%- set area_print = (area[:12] + '..') if area|length > 14 else area -%}
{{ '%-14s' % area_print }}| {{ '%2d' % pwr_ok }} / {{ '%-2d' % pwr_off }} | {{ '%2d' % bat_ok }} / {{ '%-2d' % bat_off }}
{% endfor %}```
### 💀 Offline Geräte
{% if ns.offline_list | count > 0 %} ```text
{{ '%-20s' % 'Gerät' }} | {{ '%-15s' % 'Raum' }} | TYPE
----------------------------------------------
{% for dev in ns.offline_list | sort(attribute='area') %}
{%- set name_print = (dev.name[:23] + '..') if dev.name|length > 25 else dev.name -%}
{%- set area_print = (dev.area[:23] + '..') if dev.area|length > 25 else dev.area -%} {{ '%-20s' % name_print }} | {{ '%-15s' % area_print }} | {{ dev.type }}
{% endfor %}```
{% else %}
🎉 **Alle Geräte sind online!**
{% endif %}
Gruß Osorkon

