2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-03 16:56:54 +00:00

57_SSCal: contrib 1.8.0

git-svn-id: https://svn.fhem.de/fhem/trunk@21177 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2020-02-11 09:11:52 +00:00
parent 443fe698d1
commit 331d1e0ae5

View File

@ -48,6 +48,7 @@ eval "use FHEM::Meta;1" or my $modMetaAbsent = 1;
# Versions History intern # Versions History intern
my %SSCal_vNotesIntern = ( my %SSCal_vNotesIntern = (
"1.8.0" => "09.02.2020 evaluate icons for DaysLeft, Map and State in sub SSCal_evalTableSpecs , fix no table is shown after FHEM restart ",
"1.7.0" => "09.02.2020 respect global language setting for some presentation, new attributes tableSpecs & tableColumnMap, days left in overview ". "1.7.0" => "09.02.2020 respect global language setting for some presentation, new attributes tableSpecs & tableColumnMap, days left in overview ".
"formatting overview table, feature smallScreen for tableSpecs, rename attributes to tableFields, ". "formatting overview table, feature smallScreen for tableSpecs, rename attributes to tableFields, ".
"tableInDetail, tableInRoom, correct enddate/time if is_all_day incl. bugfix API, function SSCal_boolean ". "tableInDetail, tableInRoom, correct enddate/time if is_all_day incl. bugfix API, function SSCal_boolean ".
@ -174,7 +175,7 @@ sub SSCal_Initialize($) {
"showPassInLog:1,0 ". "showPassInLog:1,0 ".
"tableInDetail:0,1 ". "tableInDetail:0,1 ".
"tableInRoom:0,1 ". "tableInRoom:0,1 ".
"tableFields:multiple-strict,Begin,End,Summary,Status,Location,Description,Map,Calendar,Completion,Timezone,Days,EventId ". "tableFields:multiple-strict,Begin,End,Summary,Status,Location,Description,Map,Calendar,Completion,Timezone,DaysLeft,EventId ".
"timeout ". "timeout ".
"usedCalendars:--wait#for#Calendar#list-- ". "usedCalendars:--wait#for#Calendar#list-- ".
$readingFnAttributes; $readingFnAttributes;
@ -337,9 +338,11 @@ sub SSCal_Attr($$$$) {
return " The attribute \"$aName\" is only valid for devices of MODEL \"Diary\"! Please set this attribute in a device of this model."; return " The attribute \"$aName\" is only valid for devices of MODEL \"Diary\"! Please set this attribute in a device of this model.";
} }
if ($attrVal =~ m/^\{.*\}$/s && $attrVal =~ m/=>/ && $attrVal !~ m/\$/) { if ($attrVal =~ m/^\{.*\}$/s && $attrVal =~ m/=>/) {
$attrVal =~ s/\@/\\\@/g;
$attrVal =~ s/\$/\\\$/g;
my $av = eval $attrVal; my $av = eval $attrVal;
# Log3($name, 1, "$name - av: ".$av);
if($@) { if($@) {
Log3($name, 2, "$name - Error while evaluate: ".$@); Log3($name, 2, "$name - Error while evaluate: ".$@);
return $@; return $@;
@ -3277,10 +3280,10 @@ sub SSCal_calAsHtml($;$) {
# Entscheidung ob Tabelle für Small Screen optimiert # Entscheidung ob Tabelle für Small Screen optimiert
my $small = 0; my $small = 0;
if ($FW_wname && $hash->{HELPER}{tableSpecs}{smallScreen}) { # Aufruf durch FHEMWEB und smallScreen-Eigenschaft gesetzt if ($FW_wname && $hash->{HELPER}{tableSpecs}{smallScreenStyles}) { # Aufruf durch FHEMWEB und smallScreen-Eigenschaft gesetzt
my %specs; my %specs;
my $FW_style = AttrVal($FW_wname, "stylesheetPrefix", "default"); my $FW_style = AttrVal($FW_wname, "stylesheetPrefix", "default");
my @scspecs = split(",", $hash->{HELPER}{tableSpecs}{smallScreen}); # Eigenschaft smallScreen in Array lesen my @scspecs = split(",", $hash->{HELPER}{tableSpecs}{smallScreenStyles}); # Eigenschaft smallScreen in Array lesen
grep { !$specs{$_}++ } @scspecs; grep { !$specs{$_}++ } @scspecs;
$small = 1 if($specs{$FW_style}); # Tabelle für small-Style anpassen $small = 1 if($specs{$FW_style}); # Tabelle für small-Style anpassen
} }
@ -3312,7 +3315,7 @@ sub SSCal_calAsHtml($;$) {
$out .= "<td class='cal calbold calcenter'> ".(($de)?'----' :'----')." </td>" if($seen{End}); $out .= "<td class='cal calbold calcenter'> ".(($de)?'----' :'----')." </td>" if($seen{End});
} }
$out .= "<td class='cal calbold calcenter'> ".(($de)?'Resttage' :'Days left')." </td>" if($seen{Days}); $out .= "<td class='cal calbold calcenter'> ".(($de)?'Resttage' :'Days left')." </td>" if($seen{DaysLeft});
$out .= "<td class='cal calbold calcenter'> ".(($de)?'Zeitzone' :'Timezone')." </td>" if($seen{Timezone}); $out .= "<td class='cal calbold calcenter'> ".(($de)?'Zeitzone' :'Timezone')." </td>" if($seen{Timezone});
$out .= "<td class='cal calbold calcenter'> ".(($de)?'Zusammenfassung' :'Summary')." </td>" if($seen{Summary}); $out .= "<td class='cal calbold calcenter'> ".(($de)?'Zusammenfassung' :'Summary')." </td>" if($seen{Summary});
$out .= "<td class='cal calbold calcenter'> ".(($de)?'Beschreibung' :'Description')." </td>" if($seen{Description}); $out .= "<td class='cal calbold calcenter'> ".(($de)?'Beschreibung' :'Description')." </td>" if($seen{Description});
@ -3323,8 +3326,6 @@ sub SSCal_calAsHtml($;$) {
$out .= "<td class='cal calbold calcenter'> ".(($de)?'Kalender' :'Calendar')." </td>" if($seen{Calendar}); $out .= "<td class='cal calbold calcenter'> ".(($de)?'Kalender' :'Calendar')." </td>" if($seen{Calendar});
$out .= "<td class='cal calbold calcenter'> ".(($de)?'ID' :'ID')." </td>" if($seen{EventId}); $out .= "<td class='cal calbold calcenter'> ".(($de)?'ID' :'ID')." </td>" if($seen{EventId});
my $l = length(keys %{$data{SSCal}{$name}{eventlist}});
my $maxbnr; my $maxbnr;
foreach my $key (keys %{$defs{$name}{READINGS}}) { foreach my $key (keys %{$defs{$name}{READINGS}}) {
next if $key !~ /^(\d+)_\d+_EventId$/; next if $key !~ /^(\d+)_\d+_EventId$/;
@ -3333,41 +3334,43 @@ sub SSCal_calAsHtml($;$) {
return "" if(!defined $maxbnr); return "" if(!defined $maxbnr);
my $l = length($maxbnr);
my $k; my $k;
for ($k=0;$k<=$maxbnr;$k++) { for ($k=0;$k<=$maxbnr;$k++) {
my $prestr = sprintf("%0$l.0f", $k); # Prestring erstellen my $bnr = sprintf("%0$l.0f", $k); # Prestring erstellen
last if(!ReadingsVal($name, $prestr."_98_EventId", "")); # keine Ausgabe wenn es keine EventId mit Blocknummer 0 gibt -> kein Event/Aufgabe vorhanden last if(!ReadingsVal($name, $bnr."_98_EventId", "")); # keine Ausgabe wenn es keine EventId mit Blocknummer 0 gibt -> kein Event/Aufgabe vorhanden
($begind,$begint,$endd,$endt,$gps) = ("","","","",""); ($begind,$begint,$endd,$endt,$gps) = ("","","","","");
$summary = ReadingsVal($name, $prestr."_01_Summary", ""); $summary = ReadingsVal($name, $bnr."_01_Summary", "");
$desc = ReadingsVal($name, $prestr."_03_Description", ""); $desc = ReadingsVal($name, $bnr."_03_Description", "");
$begin = ReadingsVal($name, $prestr."_05_Begin", ""); $begin = ReadingsVal($name, $bnr."_05_Begin", "");
$end = ReadingsVal($name, $prestr."_10_End", ""); $end = ReadingsVal($name, $bnr."_10_End", "");
$tz = ReadingsVal($name, $prestr."_15_Timezone", ""); $tz = ReadingsVal($name, $bnr."_15_Timezone", "");
$status = ReadingsVal($name, $prestr."_17_Status", ""); $status = ReadingsVal($name, $bnr."_17_Status", "");
$dleft = ReadingsVal($name, $prestr."_20_daysLeft", ""); $dleft = ReadingsVal($name, $bnr."_20_daysLeft", "");
$location = ReadingsVal($name, $prestr."_35_Location", ""); $location = ReadingsVal($name, $bnr."_35_Location", "");
$gpsa = ReadingsVal($name, $prestr."_40_gpsAddress", ""); $gpsa = ReadingsVal($name, $bnr."_40_gpsAddress", "");
$gpsc = ReadingsVal($name, $prestr."_45_gpsCoordinates", ""); $gpsc = ReadingsVal($name, $bnr."_45_gpsCoordinates", "");
$completion = ReadingsVal($name, $prestr."_85_percentComplete", ""); $completion = ReadingsVal($name, $bnr."_85_percentComplete", "");
$cal = ReadingsVal($name, $prestr."_90_calName", ""); $cal = ReadingsVal($name, $bnr."_90_calName", "");
$id = ReadingsVal($name, $prestr."_98_EventId", ""); $id = ReadingsVal($name, $bnr."_98_EventId", "");
$isallday = ReadingsVal($name, $prestr."_50_isAllday", ""); $isallday = ReadingsVal($name, $bnr."_50_isAllday", "");
if($gpsc) { if($gpsc) {
my $micon; my $micon;
if ($mi eq "icon") { if ($mi eq "icon") {
# Karten-Icon auswählen
my $di = "it_i-net"; my $di = "it_i-net";
my $ui = $hash->{HELPER}{tableSpecs}{columnMapIcon}; my $ui = SSCal_evalTableSpecs ($hash,$di,$hash->{HELPER}{tableSpecs}{columnMapIcon},$bnr);
$di = $ui ? $ui : $di; $micon = FW_makeImage($ui);
$micon = FW_makeImage($di);
} elsif ($mi eq "data") { } elsif ($mi eq "data") {
$micon = join(" ", split(",", $gpsc)); $micon = join(" ", split(",", $gpsc));
} elsif ($mi eq "text") { } elsif ($mi eq "text") {
# Karten-Text auswählen
my $dt = "link"; my $dt = "link";
my $ut = $hash->{HELPER}{tableSpecs}{columnMapText}; $micon = SSCal_evalTableSpecs ($hash,$dt,$hash->{HELPER}{tableSpecs}{columnMapText},$bnr);
$micon = $ut ? $ut : $dt;
} else { } else {
$micon = ""; $micon = "";
} }
@ -3376,7 +3379,8 @@ sub SSCal_calAsHtml($;$) {
$lat = (split("=", $lat))[1]; $lat = (split("=", $lat))[1];
$lng = (split("=", $lng))[1]; $lng = (split("=", $lng))[1];
my $up = $hash->{HELPER}{tableSpecs}{columnMapProvider} || ""; # Kartenanbieter auswählen
my $up = SSCal_evalTableSpecs ($hash,"",$hash->{HELPER}{tableSpecs}{columnMapProvider},$bnr);
if ($up eq "GoogleMaps") { # Kartenprovider: Google Maps if ($up eq "GoogleMaps") { # Kartenprovider: Google Maps
$gps = "<a href='https://www.google.de/maps/place/$gpsa/\@$lat,$lng' target='_blank'> $micon </a>"; $gps = "<a href='https://www.google.de/maps/place/$gpsa/\@$lat,$lng' target='_blank'> $micon </a>";
} elsif ($up eq "OpenStreetMap") { } elsif ($up eq "OpenStreetMap") {
@ -3426,7 +3430,10 @@ sub SSCal_calAsHtml($;$) {
} }
} }
# Icon für Spalte Resttage spezifizieren
$dleft = SSCal_evalTableSpecs ($hash,$dleft,$hash->{HELPER}{tableSpecs}{columnDaysLeftIcon},$bnr,@allrds);
# Icon für Spalte Status spezifizieren
$status = SSCal_evalTableSpecs ($hash,$status,$hash->{HELPER}{tableSpecs}{columnStateIcon},$bnr,@allrds);
$out .= "<tr class='".($k&1?"odd":"even")."'>"; $out .= "<tr class='".($k&1?"odd":"even")."'>";
if($small) { if($small) {
@ -3438,7 +3445,7 @@ sub SSCal_calAsHtml($;$) {
$out .= "<td class='cal calcenter'> $endd </td>" if($seen{End}); $out .= "<td class='cal calcenter'> $endd </td>" if($seen{End});
$out .= "<td class='cal calcenter'> $endt </td>" if($seen{End}); $out .= "<td class='cal calcenter'> $endt </td>" if($seen{End});
} }
$out .= "<td class='cal calcenter'> $dleft </td>" if($seen{Days}); $out .= "<td class='cal calcenter'> $dleft </td>" if($seen{DaysLeft});
$out .= "<td class='cal' > $tz </td>" if($seen{Timezone}); $out .= "<td class='cal' > $tz </td>" if($seen{Timezone});
$out .= "<td class='cal' > $summary </td>" if($seen{Summary}); $out .= "<td class='cal' > $summary </td>" if($seen{Summary});
$out .= "<td class='cal' > $desc </td>" if($seen{Description}); $out .= "<td class='cal' > $desc </td>" if($seen{Description});
@ -3457,6 +3464,118 @@ sub SSCal_calAsHtml($;$) {
return $out; return $out;
} }
######################################################################################
# Evaluiere Eigenschaften von Attribut "tableSpecs"
#
# $hash: Devicehash
# $default: Standardwert - wird wieder zurückgegeben wenn kein Funktionsergebnis
# $specs: Basisschlüssel (z.B. $hash->{HELPER}{tableSpecs}{columnDaysLeft})
# @allreads: alle vorhandenen Readings
# $bnr: Blocknummer Readings
#
######################################################################################
sub SSCal_evalTableSpecs (@){
my ($hash,$default,$specs,$bnr,@allrds)= @_;
my $name = $hash->{NAME};
my $check;
# anonymous sub für Abarbeitung Perl-Kommandos
$check = sub ($) {
my ($specs) = @_;
my $ret = AnalyzePerlCommand(undef, $specs);
return $ret;
};
no warnings;
if ($specs) { # Eigenschaft muß Wert haben
my ($rn,$reading,$uval,$ui,$rval);
if (ref($specs) eq "ARRAY") { # Wenn Schlüssel ein ARRAY enthält
my $i = 0;
while ($specs->[$i]) {
my $n = keys %{$specs->[$i]}; # Anzahl Elemente (Entscheidungskriterien) in Hash
foreach my $k (keys %{$specs->[$i]}) {
if ($k eq "icon") {
$ui = $specs->[$i]{$k};
$n--;
next;
}
foreach my $r (@allrds) { # alle vorhandenen Readings evaluieren
if($r =~ m/$k$/) {
(undef,$rn,$reading) = split("_", $r); # Readingnummer evaluieren
$uval = $specs->[$i]{$k}; # Vergleichswert
last;
}
}
$rval = ReadingsVal($name, $bnr."_".$rn."_".$reading, "empty");
$rval = "\"".$rval."\"";
if ( eval ($rval . $uval) ) {
$ui = $specs->[$i]{icon};
$n--;
} else {
$ui = "";
}
}
if($n == 0 && $ui) {
$default = FW_makeImage($ui); # Defaultwert mit Icon ersetzen wenn alle Bedingungen erfüllt
}
$i++;
}
} elsif (ref($specs) eq "HASH") { # Wenn Schlüssel ein HASH enthält
my $n = keys %{$specs}; # Anzahl Elemente (Entscheidungskriterien) in Hash
foreach my $k (keys %{$specs}) {
if ($k eq "icon") {
$ui = $specs->{$k};
$n--;
next;
}
foreach my $r (@allrds) { # alle vorhandenen Readings evaluieren
if($r =~ m/$k$/) {
(undef,$rn,$reading) = split("_", $r); # Readingnummer evaluieren
$uval = $specs->{$k}; # Vergleichswert
last;
}
}
$rval = ReadingsVal($name, $bnr."_".$rn."_".$reading, "empty");
$rval = "\"".$rval."\"";
if ( eval ($rval . $uval) ) {
$ui = $specs->{icon};
$n--;
} else {
$ui = "";
}
}
if($n == 0 && $ui) {
$default = FW_makeImage($ui); # Defaultwert mit Icon ersetzen wenn alle Bedingungen erfüllt
}
} else { # ref Wert der Eigenschaft ist nicht HASH oder ARRAY
if($specs =~ m/^\{.*\}$/s) { # den Wert als Perl-Funktion ausführen wenn in {}
$specs =~ s/\$NAME/$name/g; # Platzhalter $NAME, $BNR ersetzen
$specs =~ s/\$BNR/$bnr/g;
$default = $check->($specs);
} else { # einfache key-value Zuweisung
eval ($default = $specs);
}
}
}
use warnings;
return $default;
}
############################################################################################# #############################################################################################
# Hint Hash EN # Hint Hash EN
############################################################################################# #############################################################################################