From 3d983a00a3d48c657e184f347b25e6172dc790f6 Mon Sep 17 00:00:00 2001
From: Damian <>
Date: Tue, 20 Sep 2022 20:49:19 +0000
Subject: [PATCH] 98_DOIF.pm: card: more strokes on wide week and year charts,
small bug fixes in the documentation
git-svn-id: https://svn.fhem.de/fhem/trunk@26435 2b470e98-0d58-463d-a4d8-8e2adae1ed80
---
fhem/FHEM/98_DOIF.pm | 75 +++++++++++++++++++++++++++++---------------
1 file changed, 49 insertions(+), 26 deletions(-)
diff --git a/fhem/FHEM/98_DOIF.pm b/fhem/FHEM/98_DOIF.pm
index 2fac8182a..1abe7682f 100644
--- a/fhem/FHEM/98_DOIF.pm
+++ b/fhem/FHEM/98_DOIF.pm
@@ -3916,7 +3916,7 @@ DOIF_Set($@)
if ($arg eq "disable" or $arg eq "initialize" or $arg eq "enable") {
if (AttrVal($hash->{NAME},"disable","")) {
$hs=$cur_hs;
- return ("modul ist deactivated by disable attribut, delete disable attribut first");
+ return ("device is deactivated by disable attribute, delete disable attribute first");
}
}
if ($arg eq "disable") {
@@ -4990,36 +4990,58 @@ sub card
my $timebeginn=$time-$hours*3600;
my $scale;
+ my $scale_strokes;
+ my $description;
my $strokes;
my $div = $hours > 168 ? ($hours % 168 == 0 ? 168 : ($hours % 24 == 0 ? 24 : 1)):1;
if ($div==168 and $hours/$div/2 == 1) { #2w
$scale=$hours/7;
- $strokes=7;
+ $description=7;
+ $strokes=$description;
+ $scale_strokes=$scale;
} elsif ($hours <= 168*7) {
for (my $i=7;$i>=3;$i--) {
if ($hours/$div % $i == 0) {
$scale=$hours/$i;
- $strokes=$i;
+ $scale_strokes=$scale;
+ $description=$i;
+ $strokes=$description;
+ if ($div == 168 and $chart_dim > 130) {
+ $strokes=$description*7;
+ $scale_strokes=$scale/7;
+ }
last;
}
}
}
+
if (defined $scale) {
my ($sec,$minutes,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime($timebeginn);
my $beginhour=int($hour/$scale)*$scale;
my $diffsec=($hour-$beginhour)*3600+$minutes*60+$sec;
- my $pos=(1-$diffsec/($scale*3600))*$chart_dim/$strokes-$x_prop;
+ my $pos=(1-$diffsec/($scale*3600))*$chart_dim/$description-$x_prop;
+ my $pos_strokes=(1-$diffsec/($scale_strokes*3600))*$chart_dim/$strokes-$x_prop;
+
+ for (my $i=0;$i<=$strokes;$i++) {
+ my $x=int((($i)*($chart_dim/$strokes)+$pos_strokes)*10)/10;
+ $out.=sprintf('',$x,0,$x,50) if ($x >= 0 and $x <= $chart_dim);
+ }
- ##$out.=sprintf('%s',"chart_dim:$chart_dim, pos:$pos");
- for (my $i=0;$i<$strokes;$i++) {
+ # for (my $i=0;$i<$description;$i++) {
+ # my $x=int((($i)*($chart_dim/$description)+$pos)*10)/10;
+ # $out.=sprintf('',$x,0,$x,50) if ($x >= 0);
+ # }
+
+
+
+ for (my $i=0;$i<$description;$i++) {
my $h=$beginhour+($i+1)*$scale;
$hour=($h >= 24 ? $h % 24:$h);
- my $x=int((($i*($chart_dim/$strokes)+$pos))*10)/10;
- $out.=sprintf('',$x,0,$x,50) if ($x >= 0);
- ##$out.=sprintf('',$x,0,$x,50) if ($x >= 0);
+ my $x=int((($i*($chart_dim/$description)+$pos))*10)/10;
+ ##$out.=sprintf('',$x,0,$x,50) if ($x >= 0);
if ($hour == 0) {
if ($hours <= 168) {
$out.=sprintf('%s',$x,substr(::strftime("%a",localtime($timebeginn+$h*3600)),0,2));
@@ -5031,18 +5053,19 @@ sub card
}
}
} else {
- for (my $i=0;$i<=6;$i++) {
- my $x=int((($i)*($chart_dim/6)+1)*10)/10;
+ for (my $i=0;$i<=12;$i++) {
+ my $x=int((($i)*($chart_dim/12)+1)*10)/10;
$out.=sprintf('',$x,0,$x,50) if ($x >= 0 and $x <= $chart_dim);
}
+
for (my $i=0;$i<=3;$i++) {
my $x=int(($i*($chart_dim/3)-1)*10)/10;
if ($hours <=168) {
- $out.=sprintf('%s',$x,::strftime("%H:%M",localtime($time-$hours*3600*(1-$i/3))));
+ $out.=sprintf('%s',$x+2,::strftime("%H:%M",localtime($time-$hours*3600*(1-$i/3))));
} elsif ($hours <=168*7 and $hours % 24 == 0) {
$out.=sprintf('%s',$x,::strftime("%d.%H:",localtime($time-$hours*3600*(1-$i/3))));
} else {
- $out.=sprintf('%s',$x,::strftime("%d.%m",localtime($time-$hours*3600*(1-$i/3))));
+ $out.=sprintf('%s',$x+2,::strftime("%d.%m",localtime($time-$hours*3600*(1-$i/3))));
}
}
}
@@ -6544,7 +6567,7 @@ weil z. B. Garage nicht nur über die Fernbedienung geschaltet wird, dann muss m
Bei der Angabe von zyklisch sendenden Sensoren (Temperatur, Feuchtigkeit, Helligkeit usw.) wie z. B.:
-define di_heating DOIF ([sens:temperature] < 20) (set heating on)
+define di_heating DOIF ([sens:temperature] < 20) (set heating on)
ist die Nutzung des Attributes do always
nicht sinnvoll, da das entsprechende Kommando hier: "set heating on" jedes mal ausgeführt wird,
wenn der Temperatursensor in regelmäßigen Abständen eine Temperatur unter 20 Grad sendet.
@@ -6558,7 +6581,7 @@ Soll bei Nicht-Erfüllung aller Bedingungen ein Zustandswechsel erfolgen, so mus
Im Perl-Modus arbeitet das DOIF-Modul im Gegensatz zum FHEM-Modus ohne den eigenen Status auszuwerten. Es kommt immer zur Auswertung des definierten Block, wenn er getriggert wird.
Diese Verhalten entspricht dem Verhalten mit dem Attribut do always im FHEM-Modus. Damit bei zyklisch sendenden Sensoren nicht zum ständigen Schalten kommt, muss das Schalten unterbunden werden. Das obige Beispiel lässt sich, wie folgt definieren:
-define di_heating DOIF {if ([sens:temperature] < 20) {if (Value("heating") ne "on") {fhem_set"heating on"}}}
+define di_heating DOIF {if ([sens:temperature] < 20) {if (Value("heating") ne "on") {fhem_set"heating on"}}}
Teilausdrücke abfragen back
@@ -6635,11 +6658,11 @@ Syntax:
Anwendungsbeispiel:
-define di_warning DOIF ([":^temperature",0]< 0) (set pushmsg danger of frost $DEVICE)
+define di_warning DOIF ([":^temperature",0] < 0) (set pushmsg danger of frost $DEVICE)
attr di_warning do always
Perl-Modus:
-define di_warning DOIF {if ([":^temperature",0]< 0) {fhem_set"pushmsg danger of frost $DEVICE}}
+define di_warning DOIF {if ([":^temperature",0] < 0) {fhem_set"pushmsg danger of frost $DEVICE}}
Damit wird auf alle Devices getriggert, die mit "temperature" im Event beginnen. Zurückgeliefert wird der Wert, der im Event hinter "temperature: " steht.
Wenn kein Event stattfindet, wird der Defaultwert, hier 0, zurückgeliefert.
@@ -6871,11 +6894,11 @@ In der Aggregationsbedingung können alle in FHEM definierten Perlfu
Liste der Devices, die mit "rooms" enden und im Reading "temperature" einen Wert größer 20 haben:
-[@"rooms$":temperature:$_ > 20]
+[@"rooms$":temperature:$_ > 20]
Liste der Devices im Raum "livingroom", die mit "rooms" enden und im Reading "temperature" einen Wert größer 20 haben:
-[@"rooms$":temperature:$_ > 20 and $room eq "livingroom"]
+[@"rooms$":temperature:$_ > 20 and $room eq "livingroom"]
Liste der Devices in der Gruppe "windows", die mit "rooms" enden, deren Status (nicht state-Reading) "on" ist:
@@ -6924,13 +6947,13 @@ attr di_Fenster cmdState [$SELF:Device] zuletzt geöffnet|alle geschlossen
Raumtemperatur-Überwachung:
-define di_temp DOIF (([08:00] or [20:00]) and [?#"^Rooms":temperature: $_ < 20] != 0)
- (push "In folgenden Zimmern ist zu kalt [@"^Rooms":temperature:$_ < 20,"keine"]")
+define di_temp DOIF (([08:00] or [20:00]) and [?#"^Rooms":temperature: $_ < 20] != 0)
+ (push "In folgenden Zimmern ist zu kalt [@"^Rooms":temperature:$_ < 20,"keine"]")
DOELSE
(push "alle Zimmmer sind warm")
attr di_temp do always
-attr di_Raumtemp state In folgenden Zimmern ist zu kalt: [@"^Rooms":temperature:$_ < 20,"keine"])
+attr di_Raumtemp state In folgenden Zimmern ist zu kalt: [@"^Rooms":temperature:$_ < 20,"keine"])
Es soll beim Öffnen eines Fensters eine Meldung über alle geöffneten Fenster erfolgen:
@@ -6951,7 +6974,7 @@ Für reine Perlangaben gibt es eine entsprechende Perlfunktion namens Aggr
Perl-Modus:
define di_Fenster DOIF {if (["^Window:open"]) {foreach (AggrDoIf('@','^windows','state','"open"')) {Log3 "di_Fenster",3,"Das Fenster $_ ist noch offen"}}}
-define di_Temperature DOIF {if (["^room:temperature"]) {foreach (AggrDoIf('@','^room','temperature','$_ < 15')) {Log3 "di_Temperatur",3,"im Zimmer $_ ist zu kalt"}}
+define di_Temperature DOIF {if (["^room:temperature"]) {foreach (AggrDoIf('@','^room','temperature','$_ < 15')) {Log3 "di_Temperatur",3,"im Zimmer $_ ist zu kalt"}}
Zeitsteuerung back
@@ -7515,7 +7538,7 @@ In der angegebenen Zeitspanne wird ein Kommando nicht ausgeführt, auch wenn die
Anwendungsbeispiel: Meldung über Frostgefahr alle 60 Minuten
-define di_frost DOIF ([outdoor:temperature] < 0) (set pushmsg "danger of frost")
+define di_frost DOIF ([outdoor:temperature] < 0) (set pushmsg "danger of frost")
attr di_frost cmdpause 3600
attr di_frost do always
@@ -7768,7 +7791,7 @@ Beispiel
Perl-Modus:
define heating DOIF {if ([switch] eq "on" and [$SELF:frost]) {fhem_set"heating on"} else {fhem_set"heating off"}}
-attr heating DOIF_Readings frost:([outdoor:temperature] < 0)
+attr heating DOIF_Readings frost:([outdoor:temperature] < 0)
Das Reading frost triggert nur dann die definierte Abfrage, wenn sich sein Zustand ändert. Dadurch wird sichergestellt, dass ein wiederholtes Schalten der Heizung vermieden wird, obwohl der Sensor outdoor zyklisch sendet.
@@ -7926,7 +7949,7 @@ Zusätzlich führt die Definition von setList
zur Ausführung von <
Zweipunktregler a la THRESHOLD
-define di_threshold DOIF ([sensor:temperature] < [$SELF:desired]-1)
+define di_threshold DOIF ([sensor:temperature] < [$SELF:desired]-1)
(set heating on)
DOELSEIF ([sensor:temperature]>[$SELF:desired])
(set heating off)