Idee: Ein Reboot tut immer gut
Ich denke, es ist gut seine Hardware oder bestimmte Komponenten nach gewisser Zeit immer einmal durchzustarten. Denken tue ich jedoch nur manchmal daran aber ich habe ja Homeassi zur Überwachung/Automatisierung.
Automatisation
Jede Nacht 2 Uhr startet eine Automatisation und überprüft ob der letzte Neustart eines definierten Gerätes bereits eine festgelegte Tagesanzahl überschritten hat. Wenn ja, dann triggert sie den Neustart des ältesten Gerätes.
Pro Nacht wird immer nur 1 Gerät gestartet und auch nur wenn jemand zu Hause ist. Im Urlaub soll es keine automatisierten Neustarts geben.
Visualisierung
Visualisierung auf dem Dashboard ist immer gut. Ich habe mich für eine Markdownkarte entschieden. Diese kann unabhängig von der Automatisation verwendet werden.
Sie zeigt dynamisch die letzten Neustartdaten und welches Gerät wann genau als nächstes gestartet wird. Sensorenfehler fängt sie genauso ab wie eine Neustart-Warteschlange.
Die Geräte bzw. deren Neustartsensoren definierst Du direkt im Variablenteil des Codes.
Wichtig: Der Code in der Karte startet niemals irgendeinen Neustart! Es ist nur eine Visualisierung uns sie funktioniert auch ohne Automatisation.
Code Markdownkarte
Öffne eine Markdownkarte und kopiere diesen Code in das Inhaltsfenster (nicht “Code-Editor anzeigen”)
Zusammenfassung
{# Version 1.1 #}
{# ------------ Was die Karte macht ------------#}
{#
Die Karte zeigt Dir zum einen die letzten Neustarts Deiner hier definierten Geräte
und zum anderen, wann der nächste Neustart entweder stattfinden sollte
oder automatisiert stattfindet.
In der Karte definierst Du:
- Deine Gerätesensoren, die den letzten Neustart enthalten, sowie einen eigenen Namen
- die Anzahl der Tage bis zum nächsten Neustart (manuell oder aus einem Helfer)
- eine Uhrzeit, zu der Deine Prüf-/Neustart-Automation täglich startet (*)
Die Karte zeigt weiterhin:
- farblich abgestuft den nächsten Neustart, welches Gerät betroffen ist
(<= 3 Tage rot, <= 7 Tage orange, ansonsten blau)
- sofern bei mehreren Geräten der Neustart zu lange her ist, werden auch diese Geräte gelistet
- wenn es Probleme mit Deinen definierten Sensoren gibt (z. B. `unavailable`)
(*)
Ich habe eine Automation, die nächtlich um 2 Uhr prüft, ob bei einem Gerät
der letzte Neustart länger als die definierte Anzahl von Tagen zurückliegt
und das Gerät entsprechend neu startet.
Solltest Du keine Automation haben, geht der Kartencode davon aus,
dass eine solche existiert und entsprechend der Variable `uhrzeit_aut`
täglich ausgeführt wird.
Es ist nur Kosmetik –> die Karte zeigt lediglich Informationen an
und triggert selbst niemals einen Neustart!
#}
{# -------------- Konfiguration ----------------#}
{#
Hier die "Letzter Neustart" Sensoren der Geräte einfügen und ein Label
Wichtig: Die Sensoren müssen als State einen Zeitstempel ausgeben.
#}
{% set sensors = {
'sensor.fritz_box_7590_letzter_neustart': 'Fritzbox',
'sensor.fritzrepeateruntenax_letzter_neustart': 'Repeater Unten',
'sensor.fritzrepeatermitteax_letzter_neustart': 'Repeater Mitte',
'sensor.fritzrepeateroben_letzter_neustart': 'Repeater Oben',
'sensor.system_monitor_last_boot': 'Homeassi echter Boot (nur Anzeige)',
'sensor.uptime': 'Homeassi Soft Reboot',
'input_datetime.zigbee_bridge_connection_off': 'Zigbee Bridge (Ann.: Off = Restart)'
} %}
{#
Tage nachdem ein Neustart erfolgt oder folgen sollte.
ich habe dafür einen Helfer, der auch in der Automatisation verwendet wird.
Du kannst auch einfach die Zahl hier fest setzen:
Kann man die folgende Zeile und kopiere sie nach der anderen '{% set critical_restart_days =...'
{% set critical_restart_days = 40 %}
#}
{% set critical_restart_days =
states('input_number.neustart_fritzbox_und_komponenten_erfolgt_nach_xxx_tagen')
| int(30)
%}
{# Um wieviel Uhr startet die tägliche die reale oder fiktive Automatisation? #}
{% set uhrzeit_aut = '02:00' %}
{# ----------------- Logik ---------------------#}
{% set data = namespace(valid=[], invalid=[]) %}
{% set now_ts = now().timestamp() %}
{% set next_device = none %}
{% set hh = uhrzeit_aut.split(':')[0] | int %}
{% set mm = uhrzeit_aut.split(':')[1] | int %}
{% for entity, label in sensors.items() %}
{# Prüfung ob valider Zeitstempel #}
{% set ts_raw = states(entity) %}
{% set ts_parsed = as_timestamp(ts_raw, default=none) %}
{% if ts_parsed is none %}
{% set data.invalid = data.invalid + [label] %}
{% else %}
{% set dt = as_local(as_datetime(ts_parsed)) %}
{% set diff_hours = ((now_ts - dt.timestamp()) / 3600) | int %}
{% set days = (diff_hours // 24) | int %}
{# relative Anzeige in Klammern #}
{% if diff_hours < 24 %}
{% set rel = 'vor ' ~ diff_hours ~ ' h' %}
{% else %}
{% if days == 1 %}
{% set rel = 'vor 1 Tag' %}
{% else %}
{% set rel = 'vor ' ~ days ~ ' Tagen' %}
{% endif %}
{% endif %}
{# --- Berechnung der Neustartzeit --- #}
{# Ziel: Es wird immer 2 Uhr bzw. zur der in der Variable uhrzeit_aut gesetzten Zeit gestartet: Heute noch oder morgen? #}
{% set allowed_earliest_restart = dt + timedelta(days=critical_restart_days) %}
{% set base = [allowed_earliest_restart, now()] | max %}
{% set candidate = base.replace(hour=hh, minute=mm, second=0, microsecond=0) %}
{% if candidate <= base %}
{% set candidate = candidate + timedelta(days=1) %}
{% endif %}
{% set next_restart_fix = as_local(candidate) %}
{# Anlegen / Befüllen einer Liste mit allen Geräten mit validem Zeitstempel #}
{% set data.valid = data.valid + [
{
'name': label,
'dt': dt,
'days': days,
'rel': rel,
'allowed_earliest_restart': allowed_earliest_restart,
'next_restart_fix': next_restart_fix
}
] %}
{% endif %}
{% endfor %}
{# Gerät mit dem frühesten nächsten Neustart #}
{% if data.valid | length > 0 %}
{% set next_device = (
data.valid
| sort(attribute='dt')
)[0] %}
{% endif %}
{# Geräte, die das Restart-Limit erreicht oder überschritten haben aber ohne das Gerät mit frühesten Neustart (weil es extra angezeigt wird)#}
{% if next_device is not none %}
{% set overdue = data.valid
| selectattr('allowed_earliest_restart', '<=', now())
| rejectattr('name', 'equalto', next_device.name)
| sort(attribute='allowed_earliest_restart')
| list
%}
{% else %}
{% set overdue = [] %}
{% endif %}
{# -------------- Darstellung ------------------#}
## Übersicht letzter und anstehender Neustarts
<center>🔄 <font size=4><b>Letzte Neustarts</b></font></center>
{% for item in data.valid | sort(attribute='dt', reverse=True) %}
- **{{ item.name }}**<br><font color=gray>{{ item.dt.strftime('%d.%m., %H:%M Uhr') }} (<b>{{ item.rel }}</b>)</font>
{% endfor %}
{% if data.invalid | length > 0 %}
## ❌ Probleme mit
{% for name in data.invalid %}
- <font color=red>{{ name }} (Zeitstempel falsch)</font>{% endfor %}
{% endif %}
-----
<center>🔔 <font size=4><b>Nächster Neustart</b></font> 🔔</center>
{% if next_device is not none %}
{% set days_until =
((next_device.next_restart_fix.timestamp() - now_ts) / 86400)
| round(0, 'ceil')
%}
{% if days_until <= 3 %}
{% set color = 'red' %}
{% elif days_until <= 7 %}
{% set color = 'orange' %}
{% else %}
{% set color = '#23A3FF' %}
{% endif %}
<center>
<font color={{ color }} size=3>
<b>{{ next_device.name | upper }} am {{ next_device.next_restart_fix.strftime('%d.%m.%Y um %H:%M Uhr') }}</b>
</font>
</center>
<br>
<font size=2> Der Durchstart erfolgt bzw. sollte erfolgen sobald der letzte Neustart bereits mehr als {{critical_restart_days}} Tagen her ist.</font>
{% else %}
Das kann momentan nicht ermittelt werden.
{% endif %}
{% if overdue | length > 0 %}
-----
🟠 <font size=4><b>Andere überfällige Geräte (Neustart > {{critical_restart_days}} Tage) </b></font><br>
{% for item in overdue %}
- {{ item.name }}{% endfor %}
{% endif %}
Automatisation
Das ist nur ein Beispiel und muß auf Deine Bedürfnisse angepaßt werden.
Wichtige Schrauben sind der Jinja Code in den Variablen sowie die konkreten Neustartbefehle Deiner Geräte. Teste jeden einzelnen Schritt.
Zusammenfassung
alias: om_aut_tech_neustart_infrastructure
description: >-
## Nächtliche Prüfung ob letzter Neustart eines Gerätes schon zu lange her ist
und entsprechender Durchstart
- Die Prüflogik liegt in der Jinjja Logik der Variablen 'neustartvon'
- Es wird immer nur 1 Gerät pro Nach durchgestartet (sichergestellt über
Optionen -> erster Match gewinnt)
- Helper input_number.neustart_fritzbox_und_komponenten_erfolgt_nach_xxx_tagen
bestimmt die Tagesgrenze
- Als Bedingung JZH = on damit bei Abwesenheit nichts automatisch
durchgestartet wird so daß ich im Falle von Problemen besser etwas tun kann
triggers:
- at: "02:00:00"
trigger: time
conditions:
- condition: state
entity_id: input_boolean.jemand_zu_hause
state:
- "on"
actions:
- variables:
wichtig: >-
Die in Sensors verwendeten Labels werden später in der Automatisation
als Bedingung genommen. Schreibweise muß gleich sein. Trim ist aktiv
neustartvon: >-
{# Ergibt das Label des Sensors sofern der Sensor Zeitstempel die im
Helfer
hinterlegten Tage überschritten hat #}
{% set sensors = {
'sensor.fritz_box_7590_letzter_neustart': 'Fritzbox',
'sensor.fritzrepeateruntenax_letzter_neustart': 'RepeaterUnten',
'sensor.fritzrepeatermitteax_letzter_neustart': 'RepeaterMitte',
'sensor.fritzrepeateroben_letzter_neustart': 'RepeaterOben',
'sensor.uptime': 'HomeassiSoftReboot',
'input_datetime.zigbee_bridge_connection_off': 'ZigbeeBridge'
} -%} {% set critical_restart_days =
states('input_number.neustart_fritzbox_und_komponenten_erfolgt_nach_xxx_tagen')
| int(30) -%}
{# Zum Debuggen #} {#% set critical_restart_days = 0 %#}
{% set critical_restart_sec = critical_restart_days * 24 * 60 * 60 -%}
{% set ns = namespace(sensor_oldest_ts = none, oldest_label = '') -%}
{% for entity, label in sensors.items() -%}
{% set sensor_ts = as_timestamp(states(entity), default=none) -%}
{# Nur gültige Sensoren und wenn Neustart fällig #}
{% if sensor_ts is not none and (as_timestamp(now()) - sensor_ts) > critical_restart_sec -%}
{% if ns.sensor_oldest_ts is none or sensor_ts < ns.sensor_oldest_ts -%}
{% set ns.sensor_oldest_ts = sensor_ts -%}
{% set ns.oldest_label = label -%}
{% endif -%}
{% endif -%}
{% endfor -%} {% if ns.sensor_oldest_ts is not none -%}
{{ ns.oldest_label | trim }}
{% else -%}
Kein Neustart
{% endif %}
anzahltage: >-
{{states('input_number.neustart_fritzbox_und_komponenten_erfolgt_nach_xxx_tagen')
| int}}
- variables:
mailtitle: >-
{{states('sensor.uhrzeit_momentan_formatiert_hh_mm')}} Aut. Durchstarten
von [{{neustartvon}}] weil letzter Neustart > {{anzahltage}} Tage
- choose:
- conditions:
- condition: template
value_template: "{{neustartvon | lower == 'fritzbox' | lower}}"
sequence:
- action: notify.gmxolaf3
metadata: {}
data:
title: "{{mailtitle}}"
message: om_aut_tech_neustart_infrastructure
- device_id: 341326e3031a6a18186d53624b25d8ea
domain: button
entity_id: 82cd50616efe0ffc55b37be609245a05
type: press
enabled: true
- conditions:
- condition: template
value_template: "{{neustartvon | lower == 'RepeaterUnten' | lower}}"
sequence:
- action: notify.gmxolaf3
metadata: {}
data:
title: "{{mailtitle}}"
message: om_aut_tech_neustart_infrastructure
- device_id: 8d84b357a16c3a4360855ecd5298f325
domain: button
entity_id: 7b94db32a99c4ba0f067eaea768bb966
type: press
enabled: true
- conditions:
- condition: template
value_template: "{{neustartvon | lower == 'RepeaterMitte' | lower}}"
sequence:
- action: notify.gmxolaf3
metadata: {}
data:
title: "{{mailtitle}}"
message: om_aut_tech_neustart_infrastructure
- device_id: 3db9cd2267e067e9c72b33199977cff8
domain: button
entity_id: e78112ab998fdc85128dbe23cfc81b49
type: press
enabled: true
- conditions:
- condition: template
value_template: "{{neustartvon | lower == 'RepeaterOben' | lower}}"
sequence:
- action: notify.gmxolaf3
metadata: {}
data:
title: "{{mailtitle}}"
message: om_aut_tech_neustart_infrastructure
- device_id: 629d3c7b3273fe22fa05d19f91e6ccf2
domain: button
entity_id: 0602b8c2468abbfe0225577e8148fc21
type: press
enabled: true
- conditions:
- condition: template
value_template: "{{neustartvon | lower == 'HomeassiSoftReboot' | lower}}"
sequence:
- metadata: {}
data: {}
target:
entity_id: input_boolean.ha_neustart_durch_ha_getriggert
action: input_boolean.turn_on
enabled: true
- action: notify.gmxolaf3
metadata: {}
data:
title: "{{mailtitle}}"
message: om_aut_tech_neustart_infrastructure
- data: {}
action: homeassistant.restart
enabled: true
- variables:
comment: >-
Jeder Befehl ab hier ist wirkungslos. Ein Neustart von HA bricht
dieses Script ab.
- conditions:
- condition: template
value_template: "{{neustartvon | lower == 'ZigbeeBridge' | lower}}"
sequence:
- action: notify.gmxolaf3
metadata: {}
data:
title: "{{mailtitle}}"
message: om_aut_tech_neustart_infrastructure
- action: button.press
metadata: {}
data: {}
target:
entity_id: button.zigbee2mqtt_bridge_restart
enabled: true
mode: single
Sowohl die Automatisation als auch die Markdownkarte berücksichtigen einen Helfer, der die Grenztage angibt nach dem ein Neustart angezeigt oder durchgeführt werden soll.
Man kann in beiden Codes aber auch eine statische Zahl verwenden.
Weitere Hinweise findest Du im Code als Kommentare.
Wie immer sind Kommentare und Verbesserungen willkommen!
Viel Spaß und gutes Gelingen
EDIT1
Beim nochmaligem Querlesen fiel mir ein Darstellungsfehler in der Markdownkarte auf → version 1.1

