Batterieüberwachung: Unterschied zwischen den Versionen
K (Fehlender : eingefügt) |
(Code für pushover geändert (Leerzeichen, Log3)) |
||
Zeile 30: | Zeile 30: | ||
Wer statt einer email lieber eine Pushover-Nachricht auf sein Smartphone bekommen möchte, kann diesen Code benutzen: | Wer statt einer email lieber eine Pushover-Nachricht auf sein Smartphone bekommen möchte, kann diesen Code benutzen: | ||
<nowiki>define n_batt_chk notify .*:[Bb]attery:|.*:[Bb]atteryS { if($EVENT !~ m/ok/) { \ | <nowiki>define n_batt_chk notify .*:[Bb]attery:|.*:[Bb]atteryS { if($EVENT !~ m/ok/) { \ | ||
fhem ("set PushoverChristoph msg FHEM Batteriewarnung, $NAME: $EVENT:\nBatterien sollten demnächst gewechselt werden!");; \ | |||
Log3($NAME, 3, "Batteriewarnung $EVENT");; \ | |||
} \ | } \ | ||
}</nowiki> | }</nowiki> |
Aktuelle Version vom 29. Dezember 2020, 10:56 Uhr
Verschiedene batteriebetriebene Geräte (Homematic, RFXtrx, ZWave,..) übermitteln unter anderem den Zustand der eingelegten Batterie. Bei diesen kann der Batteriestatus übersichtlich dargestellt und / oder aktiv überwacht werden. Bei Geräten ohne eigenen Batteriestatus muss man diesen "nachrüsten".
Geräte mit Batteriestatus
Übersichtsdarstellung per readingsGroup
Mit Hilfe einer ReadingsGroup kann einfach eine Übersicht aller Geräte mit "battery"-Reading erstellt werden, s. hier.
Benachrichtigung per notify
Um Ausfälle frühzeitig zu erkennen, kann man sich per E-Mail benachrichtigen lassen, sobald eine Batteriemeldung mit etwas anderem als "ok" gesendet wird (z.B. "low"). Zusätzlich erzeugt der unten stehende Code einen Eintrag im Logfile. Der Code ist für die Raw Definition und nicht für den DEF Editor!
define n_batt_chk notify .*:[Bb]attery.* { if ($EVENT !~ m/ok/) { \ { FB_mail('recipient@internet.de', 'FHEM Batteriewarnung', $NAME.': '.$EVENT)};; \ Log 3, "$NAME : Batteriewarnung $EVENT";; \ } \ }
Achtung: Für Nutzer eines HM-CC-RT-DN muss der Code anders aussehen, da mit diesem Thermostat erstmalig der aktuelle Spannungswert der Batterie gesendet wird, also z.B.:
UG.Treppe.Heizung batteryLevel: 3.1 V
Man würde bei der Verwendung des o.g. Codes bei jeder Batteriemeldung eines HM-CC-RT-DN eine E-Mail erhalten. Daher muss der o.g. Code wie folgt geändert werden (Doppelpunkt hinter "[Bb]attery"):
define n_batt_chk notify .*:[Bb]attery:|.*:[Bb]atteryS { if($EVENT !~ m/ok/) { \ { FB_mail('recipient@internet.de', 'FHEM Batteriewarnung', $NAME.': '.$EVENT)};; \ Log 3, "$NAME: Batteriewarnung $EVENT";; \ } \ }
Achtung: FB_mail setzt die Installation auf einer FritzBox voraus. Für andere Hardware-/OS-Plattformen ist die Vorgehensweise unter dem Titel E-Mail_senden beschrieben.
Wer statt einer email lieber eine Pushover-Nachricht auf sein Smartphone bekommen möchte, kann diesen Code benutzen:
define n_batt_chk notify .*:[Bb]attery:|.*:[Bb]atteryS { if($EVENT !~ m/ok/) { \ fhem ("set PushoverChristoph msg FHEM Batteriewarnung, $NAME: $EVENT:\nBatterien sollten demnächst gewechselt werden!");; \ Log3($NAME, 3, "Batteriewarnung $EVENT");; \ } \ }
Natürlich muß dafür eine Pushover-Installation in fhem vorhanden sein - sonst bitte gem. Pushover nachholen.
Testen kann man dies z.B. mit trigger HeizungWZ Battery:low
Man sollte auch darauf achten, dass sich das Ereignis, auf das man triggert, nicht zu häufig wiederholt (z.B. durch das Attribut event-on-change-reading
).
Geräte ohne Batteriestatus
Bei Geräten ohne Reading für den Batteriestatus kann man diesen auf verschiedene Weisen schätzen und als Reading eintragen. Dies funktioniert aber natürlich nur, wenn das Gerät sendet - bei einem rein empfangenden Aktor wie dem FHT Stellantrieb klappt es also nicht...
Erweiterung des Geräts um battery-Reading
Mit Hilfe von userReadings kann man recht einfach einen Batteriestatus schätzen und als Reading bereitstellen. Dann greift auch direkt die oben beschriebene Auswertung.
Die Idee ist, den zeitlichen Abstand des aktuellen Timestamps mit dem letzten geloggten Timestamp zu vergleichen und daraus auf den Batteriestatus zu schliessen - bspw. Abstand > 10min = Batterie low.
Dazu muss lediglich folgendes userReading für jedes batteriebetriebene Device (ohne Batteriestatus) angelegt werden (um bei >10min "low" zu setzen):
- Konfiguration
Lediglich der Schwellwert (600) braucht nach Wunsch angepasst zu werden, alles andere passt automatisch (vgl. Notify#Hinweise).
- Im Webinterface
battery { return "ok" if ( (time_str2num(ReadingsTimestamp($NAME,"state","0")) - time_str2num(OldTimestamp($NAME))) < 600 ); return "low" }
- Alternativ im Config-File
attr MeinSensor userReadings battery { return "ok" if ( (time_str2num(ReadingsTimestamp($NAME,"state","0")) - time_str2num(OldTimestamp($NAME))) < 600 ); return "low" }
- Erläuterung
$NAME
- ist die Variable für das Device (und braucht nicht angepasst zu werden)battery {...}
- Name des userreadings mit Spezifikation, vgl. commandref/userReadings.return "ok" if ( ... ); return "low"
- Spezifikation: Reading = "ok", wenn if erfüllt, sonst "low"time_str2num(ReadingsTimestamp($NAME,"state","0")
- Aktueller Timestamp in Sekunden, vgl. commandref/perl, Notify#Hinweisetime_str2num(OldTimestamp($NAME))
- Letzter Timestamp im Log in Sekunden (egal ob FileLog oder DbLog), vgl. commandref/perl, Notify#Hinweise600
- Schwellwert für "low" (600 sec = 10 min), nach Bedarf anpassen
Alternativ per Skript
Andere Komponenten, wie z. B. FS20 Komponenten, übermitteln keinen Batteriestatus.
Um dort dennoch einen Test darauf zu machen, ob die Batterie evtl. leer ist, kann man z. B. prüfen, wann der letzte Status des jeweiligen Gerätes empfangen wurde, etwa mit folgender Funktion in 99_myUtils.pm:
sub check_if_alive($$) { # Expects: # 1. Devicename to be checked # 2. Age in hours, after the expiry of which with no new state the device will be considered as dead. # Returns: # 0 -> Device dead # 1 -> Device alive # 2 -> Error my ($Device,$hours_threshold) = @_; my ($Device) = @_; my $now = time; my $Timestamp = ReadingsTimestamp($Device,"state","0"); if ($Timestamp eq "0") { return 2; } my @splitdatetime = split(/ /,$Timestamp); my @splitdate = split(/-/, $splitdatetime[0]); my @splittime = split(/:/, $splitdatetime[1]); my $last_state_time = timelocal($splittime[2], $splittime[1], $splittime[0], $splitdate[2], $splitdate[1]-1, $splitdate[0]); my $age_in_hours = ($now - $last_state_time) / 3600; if ($age_in_hours > $hours_threshold) { Log 1, ("check_if_alive: $Device dead, last state was $age_in_hours hours ago"); return 0; } else { return 1; } }
Diese Funktion kann man z.B. in einem at je zu prüfendem Gerät regelmäßig (z. B. einmal am Tag um 05:55 Uhr) aufrufen, und testen, ob die letzten 12 Stunden etwas empfangen wurde:
*05:55:55 { check_if_alive("KS300", 12); }
KS300 ist dabei der Name des Devices in fhem.
Wenn das Gerät nicht geantwortet hat, erzeugt die oben vorgeschlagene Funktion einen Logeintrag.
Hinweis: Dieser Batterietest schlägt natürlich auch an, wenn die FS20 Geräte noch funktionieren, aber der CUL zum Empfangen der Signale nicht mehr funktioniert. In dem Fall sind dann auf einen Schlag angeblich alle Batterien leer. Um dies zumindest teilweise abzufangen, könnte man vor dem Erzeugen des Logeintrags noch auf den state des CUL testen, dass dieser nicht "disconnected" ist.
Visualisierung
Der Abschnitt Links unten enthält einen Verweis, wie man den Batteriestatus visuell anzeigen kann. Das funktioniert mit der oben vorgeschlagenen Funktion mit einigen Ergänzungen auch, wenn das Gerät selbst keinen Batteriestatus anzeigt.
Dafür braucht man einen zusätzlichen Dummy je zu überwachendem Gerät, mit dem Namen dum_<zu_überwachendes_Gerät>_dead. Für das Gerät KS300 heißt dieser dummy also z. B. dum_KS300_dead:
Internals: NAME dum_KS300_dead NR 795 STATE nein TYPE dummy Readings: 2015-04-28 07:47:48 state nein Attributes: devStateIcon ja:measure_battery_50@red nein:measure_battery_100@green
Dieser dummy soll hier die Zustände "ja" und "nein" annehmen können. Bei ja ist ihm über devStateIcon ein rotes Icon einer eher leeren Batterie zugewiesen, bei nein ein grünes Icon einer vollen Batterie.
Nun muss noch die oben vorgeschlagene Funktion angepasst werden, um den Zustand des dummy entsprechend dem ermittelten Batteriestatus neu zu setzen. Dafür wird die Abfrage des Alters am Ende der Funktion um eine Zeile erweitert, die den Status des dummy setzt:
if ($age_in_hours > $hours_threshold) { Log 1, ("check_if_alive: $Device dead, last state was $age_in_hours hours ago"); fhem("set dum_".$Device."_dead ja"); return 0; } else { fhem("set dum_".$Device."_dead nein"); return 1; }
Den Dummy mit diesem devStateIcon kann man so der unter "Links" unten vorgeschlagenen readingsGroup hinzufügen, und damit auch Geräte ohne eigenen Batteriestatus überwachen.
Links
- visuelle Batterieüberwachung mit readingsGroup
- commandref/userReadings - userReadings
- commandref/perl - Perl specials
- Hinweise zu Variablen (ansonsten auch an div. Stellen in der commandref)