FHEM Forum

FHEM => Codeschnipsel => Thema gestartet von: Benni am 23 März 2015, 19:16:13

Titel: Batteriewarnung mal anders (mit Dummy als "Container")
Beitrag von: Benni am 23 März 2015, 19:16:13
Ich habe mal die Batteriewarnung aus dem FHEM-Wiki http://www.fhemwiki.de/wiki/Batterie%C3%BCberwachung (http://www.fhemwiki.de/wiki/Batterie%C3%BCberwachung) etwas erweitert:

Vor allem um mir einfach anzeigen zu lassen, dass es aktuell Batteriewarnungen gibt und für welches Gerät diese vorliegen und zwar mit Zeitstempel, wann die jeweilige Batteriewarnung aufgetreten ist.
Für die ganze Aktion habe ich einfach mal einen Dummy genommen, mit dem ich das ganze abbilden werde, und der quasi als Containier für das Sammeln der Batteriewarnungen dient.

Ich habe im Folgenden für die benötigten devices jeweils ein list aufgeführt und bewußt keinen Auszug aus der fhem.cfg oder einer Auflistung der für das Anlegen notwendigen Befehle. Alles notwendige (und vllt. auch überflüssige) ist in den dargestellten list-Auszügen enthalten.

Im Gegenzug habe ich aber den Code der subs, die benötigt werden vielleicht etwas überkommentiert. In der Hoffnung, dass jeweils auch von weniger versierten Usern  (wobei meine Versiertheit in Perl auch noch zu wünschen übrig lässt ;) ) verstanden wird, was da genau passiert.

Dazu habe ich mir zunächst mal jenen besagten Dummy angelegt:


Internals:
   CFGFN
   NAME       HG.XX.DM.Battery.Warning
   NR         543
   STATE      off
   TYPE       dummy
   Readings:
     2015-03-20 17:01:22   state           off
Attributes:
   alias      Batteriewarnungen
   group      Warnungen
   room       00.00_Uebersicht,Homematic
   setList    on off
   webCmd     on:off


Dieser Dummy wird später im Falle einer Batteriewarnung auf on gesetzt.
Zusätzlich werden dann außerdem in den Readings des Dummys die Geräte abgelegt, die eine Batteriewarnung ausgegeben haben.

Als nächstes habe ich das Notify für die Batteriewarnung aus dem Wiki  (Link siehe oben) übenrommen und rufe damit eine sub in meiner 99_MyUtils auf und übergebe den NAME des Device, das die Batteriewarnung erzeugt hat:


Internals:
   CFGFN
   DEF        .*:[Bb]attery:.* {
if($EVENT !~ m/ok/) {
batteryWarning($NAME);
}
}
   NAME       HG.XX.NY.BatteryEvent
   NR         285
   NTFY_ORDER 50-HG.XX.NY.BatteryEvent
   REGEXP     .*:[Bb]attery:.*
   STATE      2015-03-23 18:21:41
   TYPE       notify
   Readings:
     2015-03-22 21:03:32   state           active
Attributes:
   group      Warnungen
   room       Homematic


In Meiner 99_MyUtils.pm ist dazu dann folgendes definiert:


#Der Name des Dummy für die Batteriewarnungsanzeige wird in der 99_MyUtils als
# "globale" Variable definiert, da wir dies in 2 subs als Information benötigen
my $warnDummy='HG.XX.DM.Battery.Warning';

sub batteryWarning($) {
    #Das notify übergibt uns den Namen des Device, das die Batteriewarnung
    #ausgelöst hat, das holen wir uns in die Variable $dev
my ($dev)=@_;

    #Die Warnung wird erst einmal ins Log geschrieben ...
Log 3, "Batteriewarnung für $dev";

    #Wenn der o.a. Dummy für die Batteriewarnung existiert....
    if($defs{$warnDummy}) {
        #.. wird dieser zunächst mal auf on gesetzt.
    fhem("set $warnDummy on");
       
        #Dann wird das Reading warn_cnt des Dummys ausgelesen, das enthält nämlich
        #die Anzahl, der Geräte, die eine Batteriewarnung abgesetzt haben.
        #(existiert es nicht, wird 0 angenommen, d.h. es gab bis dahin noch keine Batteriewarnung, die im Dummy abgelegt ist)
    my $warncnt=ReadingsVal($warnDummy,"warn_cnt","0");
        #Dieser Zähler wird nun um eins erhöht und stellt somit den Index (xx)
        #für das neue Warn-Reading im Dummy dar, in das der Gerätename eintetragen wird
        $warncnt++;
        #Den Zähler schreiben wir in das Reading warn_cnt im Dummy
fhem("setreading $warnDummy warn_cnt $warncnt");
        #und in das Reading "warncnt_xx" wird der Gerätename eingetragen.
        fhem("setreading $warnDummy warn_$warncnt $dev");
       
    #Falls der Dummy nicht existiert, tragen wir das wenigstens mal ins log ein, damit deser Fehler auch gefunden und behoben werden kann.
    } else { Log 3, "Fehler: $warnDummy existiert nicht!";}
   
}


Der Dummy zeigt uns nun also an, dass eine Batteriewarnung aufgetreten ist (on) und in seinen Readings stehen das, bzw. die Geräte, die die Batteriewarnung ausgelöst haben.

Wenn der Dummy nun manuell auf off gesetzt wird. Was man sinnvollerweise dann tut, wenn man die Geräte überprüft hat und ggf. die Batterien gewechselt hat, so sollen auch die erzeugten Readings wieder gelöscht werden.
Dazu gibt es ein weiteres Notify, das auf das Ausschalten des Dummy reagiert:


Internals:
   CFGFN
   DEF        HG.XX.DM.Battery.Warning:off {
fhem("sleep 0.1");
clearBatteryWarnings();
}
   NAME       HG.XX.NY.Battery.Warning.OFF
   NOTIFYDEV  HG.XX.DM.Battery.Warning
   NR         544
   NTFY_ORDER 50-HG.XX.NY.Battery.Warning.OFF
   REGEXP     HG.XX.DM.Battery.Warning:off
   STATE      active
   TYPE       notify
   Readings:
     2015-03-22 21:03:34   state           active
Attributes:
   group      Warnungen
   room       Homematic


Das Notify ruft dann folgende sub in der 99_MyUtils auf (das ist dann die oben erwähnte 2. sub, die den Dummynamen als Info benötigt):


sub clearBatteryWarnings{
   
    #Wiederum prüfen, ob der Dummy überhaupt existiert
    if($defs{$warnDummy}) {
        #und alle Readings aus dem Dummy löschen, die mit "warn" anfangen.
        #Damit werden alle warn_xx gelöscht, ebenso wie der Zähler warn_cnt
        fhem("deletereading $warnDummy warn.*");   
    } else { Log 3, "Fehler: $warnDummy existiert nicht!";}
}


Das wars auch schon. Damit erhalte ich eine schöne übersicht, über evtl. aufgetretene Batteriewarnungen, direkt in den Readings eines Dummys und der Dummy selbst signalisiert mir über STATE=on, dass eine oder mehrere Batteriewarnungen vorliegen.
Wenn ich die Batterien geprüft und oder gewechselt habe, setze ich den Dummy manuell auf off und alle Warnungen werden wieder aus den Readings gelöscht.

Das geht sicher auch auf vielfältige Weise anders oder besser (readingsGroup o.ä.), das war aber etwas was mir mal so eingefallen ist und das ich ausprobieren wollte, nicht zuletzt um etwas dabei zu lernen und das habe ich dabei auf jeden Fall.
Das ganze ist natürlich  auch nicht auf Batteriewarnungen beschränkt, sondern kann für beliebige Events genutzt werden.

Im Anhang finden sich noch ein paar Screenshots dazu.

Vielleicht kann/möchte es ja jemand tatsächlich so einsetzen oder kann zumindest auch was davon lernen.


Gruß Benni.

Titel: Antw:Batteriewarnung mal anders (mit Dummy als "Container")
Beitrag von: betateilchen am 23 März 2015, 19:23:48
und wer nur Homematic Komponenten im Einsatz hat, bekommt das alles schon ganz automatisch aus HMinfo :)