Störmeldeliste erstellen

Begonnen von bismosa, 05 Dezember 2018, 08:09:36

Vorheriges Thema - Nächstes Thema

Gisbert

Hallo Thorsten,

manche nennen es Kram, Arbeit, Leben ... kenn ich nur zu gut. Alles außer Prio 1 bleibt ein Wunsch, bis man gaaanz viel Zeit hat, also ab 63~67 Jahre, ausgenommen Lottogewinn, Erbtante oder reiche Ehefrau.


Hallo Bismosa,

wenn du deine Lösung beschreiben magst, gerne. Ich bin allerdings weniger an einer Visualisierung als an den Informationen interessiert, aber vielleicht kommt ja der Appetit beim Essen.

Viele​ Grüße​ Gisbert​
Aktuelles FHEM | PROXMOX | Fujitsu Futro S740 | Debian 12 | UniFi | Homematic, VCCU, HMUART | ESP8266 | ATtiny85 | Wasser-, Stromzähler | Wlan-Kamera | SIGNALduino, Flamingo Rauchmelder FA21/22RF | RHASSPY

bismosa

Hallo,

eigentlich ist es gar nicht so kompliziert...

Mit einem DOIF triggere ich auf die Ereignisse. Außerdem erzeuge ich die readings in diesem Device.
Beispiel:

defmod di_Stoermeldeliste DOIF (["^Wassermelder_"]\
or [HeizungsStoerung]\
or ["^Fenster_"]\
or ["rpi_status"]\
or ["GPIO_Heizung_Brenner"]\
or ["chkBattFenster"]\
)({\
MeldeListeGet("$SELF");;\
})
attr di_Stoermeldeliste do always


Und in der myUtils gehe ich dann sämtliche Devices mit den "Störmeldungen durch. Dafür habe ich zwei hashes (Warnings/Errors).
Dort trage ich dann die eigentliche Meldung, eine Bedingung, ob ich die Meldung "bestätigen" möchte und das Symbol für die Meldung ein. da kann man natürlich auch alles andere unterbringen...
Ein hinzufügen weiterer Devices ist so recht einfach machbar.

################################################################
###                   Stör-Meldeliste in HTML                ###
################################################################
sub MeldeListeGet($){
my $SelfDevice=shift;
my %hashWarnings;
my %hashErrors;

my $FensterWarnungenCount=0;
my @Errors;
my $ErrorCount=0;
my @Warnings;
my $WarningCount=0;

######################################################################
##Fenstersensoren
##Abgefallen:
my @DevicesFensterKaputt=devspec2array("NAME=Fenster_.*:FILTER=STATE=Kaputt");
foreach my $Device (@DevicesFensterKaputt){
$ErrorCount+=1;
$FensterWarnungenCount+=1;
$hashErrors{$Device}{"Error"}="$Device abgefallen";
$hashErrors{$Device}{"Confirm"}="";
$hashErrors{$Device}{"Symbol"}="oa-message_attention";
}
##Batterie leer
my @DevicesFensterBatt=devspec2array("NAME=Fenster_.*:FILTER=battery!=ok");
##Log 1, Dumper(\@DevicesFensterBatt);
foreach my $Device (@DevicesFensterBatt){
$ErrorCount+=1;
$hashErrors{$Device."__Batt"}{"Error"}="$Device Batterie leer";
$hashErrors{$Device."__Batt"}{"Confirm"}="";
$hashErrors{$Device."__Batt"}{"Symbol"}="oa-measure_battery_0  fa-rotate-90";
}
######################################################################
##Wassermelder
##Ausgelöst
my @Wassermelder=devspec2array("NAME=Wassermelder_.*:FILTER=STATE=Alarm");
foreach my $Device (@Wassermelder){
if ($Device eq "Wassermelder_Heizung"){
$WarningCount+=1;
$hashWarnings{$Device}{"Error"}="$Device bitte Eimer leeren!";
$hashWarnings{$Device}{"Confirm"}="Btn";
$hashWarnings{$Device}{"Symbol"}="fa-exclamation";
} else {
$ErrorCount+=1;
$hashErrors{$Device}{"Error"}="$Device Überschwemmung!";
$hashErrors{$Device}{"Confirm"}="Btn";
$hashErrors{$Device}{"Symbol"}="oa-message_attention";
}
}
######################################################################
##Heizung Störung
if (InternalVal("HeizungsStoerung", "STATE", "off") ne "off"){
$hashErrors{"HeizungsStoerung"}{"Error"}="Heizung Störung!";
$hashErrors{"HeizungsStoerung"}{"Confirm"}="";
$hashErrors{"HeizungsStoerung"}{"Symbol"}="oa-message_attention";
$ErrorCount+=1;
}
######################################################################
##RPI Status
my $RPIVal;
my $MB;
##Device ist egal, wenn kein Button!

$RPIVal=ReadingsVal("rpi_status", "cam_SD1_free","0");
if ($RPIVal<=500000){
$ErrorCount+=1;
$MB=$RPIVal/1024;
$hashErrors{"cam_SD1_free"}{"Error"}="CAM SD1 nur ".sprintf("%.2f", $MB)."MB frei!";
$hashErrors{"cam_SD1_free"}{"Confirm"}="";
$hashErrors{"cam_SD1_free"}{"Symbol"}="mi-sd_storage";
}
$RPIVal=ReadingsVal("rpi_status", "cam_mem_free","0");
if ($RPIVal<=1000){
$ErrorCount+=1;
$MB=$RPIVal/1024;
$hashErrors{"cam_mem_free"}{"Error"}="CAM Memory nur ".sprintf("%.2f", $MB)."MB frei!";
$hashErrors{"cam_mem_free"}{"Confirm"}="";
$hashErrors{"cam_mem_free"}{"Symbol"}="mi-storage";
}
$RPIVal=ReadingsVal("rpi_status", "cam_online","0");
if ($RPIVal==0){
$ErrorCount+=1;
$hashErrors{"cam_online"}{"Error"}="Cam ist Offline!";
$hashErrors{"cam_online"}{"Confirm"}="";
$hashErrors{"cam_online"}{"Symbol"}="oa-message_attention";
}
######################################################################
##Verarbeiten
##HTML ausgabe
my $html='<div align="left"><table><tbody>';
##Erst Störmeldungen
##Log 1, Dumper(\%hashErrors);
$html.=MeldeListeGetHTML(\%hashErrors, "#FF0000");
$html.=MeldeListeGetHTML(\%hashWarnings, "yellow");


$html.="</tbody></table></div>";
##Nur, wenn sich etwas geändert hat das Reading neu setzen! (Events sparen)
if (ReadingsVal("$SelfDevice","HTML", "") ne "$html"){
fhem("sleep 0.1; setreading $SelfDevice HTML $html");
}
if (ReadingsVal("$SelfDevice","WarningCount", 0) ne "$WarningCount"){
fhem("setreading $SelfDevice WarningCount $WarningCount");
}
if (ReadingsVal("$SelfDevice","ErrorCount", 0) ne "$ErrorCount"){
fhem("setreading $SelfDevice ErrorCount $ErrorCount");
}
return $html;
}


Und das erzeugen des HTML-Codes aus den hashes:

sub MeldeListeGetHTML($$){
my %hashErrors=%{shift()};
my $Farbe=shift;
my $html="";

##Log 1, Dumper(\%hashErrors);
##sort muss!!! Sonst jedes Mal eine andere Reihenfolge!!
foreach my $DeviceName (sort keys %hashErrors){
my $Device=$DeviceName;
$Device =~ s/__Batt$//;
$Device =~ s/__BattAlt$//;
##Log 1, "Device: $Device";
#my $ErrorStr=$hashErrors{$DeviceName}{"Error"};
#my $ConfirmStr=$hashErrors{$DeviceName}{"Confirm"};
#Log 1, "Error: $ErrorStr";
#Log 1, "Confirm: $ConfirmStr";

##Symbol
$html.="<tr><td> <div class=\"tiny compressed\" data-type=\"symbol\" data-icon=\"";
my $Symbol=$hashErrors{$DeviceName}{"Symbol"};
$html.=$Symbol;
$html.="\" data-on-color=\"$Farbe\" data-off-color=\"$Farbe\"></div></td>";

##Text
my $Errortext=$hashErrors{$DeviceName}{"Error"};
$html.="<td><div style=\"color:$Farbe\">".$Errortext."</div></td>";

##ggf. Button zum Zurücksetzen
if ($hashErrors{$DeviceName}{"Confirm"} eq ""){
$html.="<td></td>";
} elsif ($hashErrors{$DeviceName}{"Confirm"} eq "Btn"){
$html.="<td><div data-type=\"switch\" class=\"small\" data-icon=\"oa-message_ok\" data-color=\"green\" data-device=\"";
$html.="$Device\" ";
if ("$Device" =~ /^Wassermelder_/){
$html.="data-set-on=\"off\" data-set-off=\"Alarm\" ";
}
$html.="> </div></td>";
} else {
$html.="<td><div data-type=\"switch\" class=\"small\" data-icon=\"oa-message_ok\" data-color=\"green\" data-device=\"";
$html.="$Device\" ";
$html.="data-cmd=\"".$hashErrors{$DeviceName}{"Confirm"}."\"";
$html.="> </div></td>";
}
$html.="</tr>"
}
return $html;
}


Das Ganze hat nur den Nachteil, das bei jedem auftretenden Event die ganze HTML-Erzeugung durchläuft...ist nicht unbedingt ressourcensparend. Aber bisher konnte ich auf meinem Raspberry noch keine Probleme feststellen.

Gruß
Bismosa
1x nanoCUL 433MHz (SlowRF Intertechno) für Fenstersensoren
1x nanoCUL 868Mhz für MAX (9x HT 1xWT)
1x ZigBee CUL
Weiteres: Squeezebox server, Kindle Display, ESP8266, Löterfahrung, ...

Damian

Man kann Listen von Geräten durchaus mit wenigen Zeilen erschlagen ohne html selbst bauen zu müssen.

Beispiel: Liste aller offener Fenster:

defmod di_Status_Meldungen DOIF ##
attr di_Status_Meldungen DOIF_Readings Fenster:[@s(<br>)"Fenster$":state:"open","keine"]
attr di_Status_Meldungen uiTable WID([$SELF:Fenster], "iconLabel,keine,fts_window_1w,.*,fts_window_1w_open\@DarkOrange") | STY([$SELF:Fenster], ([$SELF:Fenster] eq "keine" ? "" : "color:DarkOrange"))


Hier werden sogar verschiedene Farben je nach zustand gesetzt.

Und so sieht es aus in Kombination mit anderen Statusmeldungen in einem einzigen DOIF.

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF