From cfd81ef6e4d36895883d596e009443eb9e4f286d Mon Sep 17 00:00:00 2001 From: damian-s Date: Mon, 26 Sep 2016 21:02:49 +0000 Subject: [PATCH] 98_DOIF.pm: states, readings in time functions, set enable, item helper, item summery git-svn-id: https://svn.fhem.de/fhem/trunk@12215 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/98_DOIF.pm | 95 ++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 38 deletions(-) diff --git a/fhem/FHEM/98_DOIF.pm b/fhem/FHEM/98_DOIF.pm index 91f68e414..7944a8ac8 100644 --- a/fhem/FHEM/98_DOIF.pm +++ b/fhem/FHEM/98_DOIF.pm @@ -1333,9 +1333,9 @@ DOIF_TimerTrigger ($) } sub -DOIF_DetTime($) +DOIF_DetTime($$) { - my ($timeStr) = @_; + my ($hash, $timeStr) = @_; my $rel=0; my $align; my $hr=0; @@ -1359,11 +1359,8 @@ DOIF_DetTime($) } elsif ($timeStr =~ m/^(\-?([0-9]+))$/) { $s=$1; } else { - if ($timeStr =~ m/^\$hms$/) { - $timeStr = sprintf("%02d:%02d:%02d", $hour, $min, $sec); - } elsif ($timeStr =~ m/^\$hm$/) { - $timeStr = sprintf("%02d:%02d", $hour, $min); - } + ($timeStr,$err)=ReplaceAllReadingsDoIf($hash,$timeStr,-3,1); + return ($err) if ($err); ($err, $h, $m, $s, $fn) = GetTimeSpec($timeStr); return $err if ($err); } @@ -1416,14 +1413,13 @@ DOIF_CalcTime($$) my $pos; my $ret; if ($block=~ m/^\+\[([0-9]+)\]:([0-5][0-9])$/) { - ($err,$rel,$block)=DOIF_DetTime($block); + ($err,$rel,$block)=DOIF_DetTime($hash,$block); return ($block,$err,$rel); } elsif ($block =~ /^\+\(/ or $block =~ /^\+\[/) { $relGlobal=1; #$pos=pos($block); $block=substr($block,1); } - if ($block =~ /^\(/) { ($beginning,$tailBlock,$err,$tailBlock)=GetBlockDoIf($block,'[\(\)]'); return ($tailBlock,$err) if ($err); @@ -1434,11 +1430,25 @@ DOIF_CalcTime($$) ($block,$err,$device,$reading,$internal)=ReplaceReadingEvalDoIf($hash,$block,1); return ($block,$err) if ($err); } - ($err,$rel,$block)=DOIF_DetTime($block); + ($err,$rel,$block)=DOIF_DetTime($hash, $block); $rel=1 if ($relGlobal); return ($block,$err,$rel); } $tailBlock=$block; + while ($tailBlock ne "") { + ($beginning,$block,$err,$tailBlock)=GetBlockDoIf($tailBlock,'[\{\}]'); + return ($block,$err) if ($err); + if ($block ne "") { + # $ret = eval $block; + # return($block." ",$@) if ($@); + # $block=$ret; + ($err,$rel,$block)=DOIF_DetTime($hash,"{".$block."}"); + return ($block,$err) if ($err); + } + $cmd.=$beginning.$block; + } + $tailBlock=$cmd; + $cmd=""; while ($tailBlock ne "") { ($beginning,$block,$err,$tailBlock)=GetBlockDoIf($tailBlock,'[\[\]]'); return ($block,$err) if ($err); @@ -1447,23 +1457,8 @@ DOIF_CalcTime($$) ($block,$err,$device,$reading,$internal)=ReplaceReadingEvalDoIf($hash,$block,1); return ($block,$err) if ($err); } - ($err,$rel,$block)=DOIF_DetTime($block); + ($err,$rel,$block)=DOIF_DetTime($hash,$block); return ($block,$err) if ($err); - - } - $cmd.=$beginning.$block; - } - $tailBlock=$cmd; - $cmd=""; - while ($tailBlock ne "") { - ($beginning,$block,$err,$tailBlock)=GetBlockDoIf($tailBlock,'[\{\}]'); - return ($block,$err) if ($err); - if ($block ne "") { - $ret = eval $block; - return($block." ",$@) if ($@); - $block=$ret; - ($err,$rel,$block)=DOIF_DetTime($block); - return ($block,$err) if ($err); } $cmd.=$beginning.$block; } @@ -1826,13 +1821,14 @@ DOIF_Set($@) my $arg = $a[1]; my $value = (defined $a[2]) ? $a[2] : ""; my $ret=""; - if ($arg eq "disable" or $arg eq "initialize") { + if ($arg eq "disable" or $arg eq "initialize" or $arg eq "enable") { if (AttrVal($hash->{NAME},"disable","")) { return ("modul ist deactivated by disable attribut, delete disable attribut first"); } } if ($arg eq "disable") { readingsBeginUpdate ($hash); + readingsBulkUpdate($hash,"last_cmd",ReadingsVal($pn,"state","")); readingsBulkUpdate($hash, "state", "disabled"); readingsBulkUpdate($hash, "mode", "disabled"); readingsEndUpdate ($hash, 1); @@ -1841,8 +1837,13 @@ DOIF_Set($@) delete ($defs{$hash->{NAME}}{READINGS}{cmd_nr}); delete ($defs{$hash->{NAME}}{READINGS}{cmd_event}); readingsSingleUpdate($hash, "state","initialize",1); + } elsif ($arg eq "enable" ) { + #delete ($defs{$hash->{NAME}}{READINGS}{mode}); + readingsSingleUpdate ($hash,"state",ReadingsVal($pn,"last_cmd",""),0) if (ReadingsVal($pn,"last_cmd","") ne ""); + delete ($defs{$hash->{NAME}}{READINGS}{last_cmd}); + readingsSingleUpdate ($hash,"mode","enable",1) } else { - return "$pn: unknown argument $a[1], choose one of disable initialize" + return "$pn: unknown argument $a[1], choose one of disable initialize enable" } return $ret; } @@ -1851,6 +1852,9 @@ DOIF_Set($@) 1; =pod +=item helper +=item summary universal module, it works event- and time-controlled +=item summary_DE universelles Modul, welches ereignis- und zeitgesteuert Anweisungen ausführt =begin html @@ -2065,7 +2069,8 @@ Das Modul wird getriggert, sobald das angegebene Device hier "remotecontrol" ein Ausgewertet wird hier der Zustand des Statuses von remotecontrol nicht das Event selbst. Die Ausführung erfolgt standardmäßig einmalig nur nach Zustandswechsel des Moduls. Das bedeutet, dass ein mehrmaliges Drücken der Fernbedienung auf "on" nur einmal "set garage on" ausführt. Die nächste mögliche Ausführung ist "set garage off", wenn Fernbedienung "off" liefert. -Wünscht man eine Ausführung des gleichen Befehls mehrfach nacheinander bei jedem Trigger, unabhängig davon welchen Zustand das DOIF-Modul hat, weil z. B. Garage nicht nur über die Fernbedienung geschaltet wird und dann muss man das per "do always"-Attribut angeben:
+Wünscht man eine Ausführung des gleichen Befehls mehrfach nacheinander bei jedem Trigger, unabhängig davon welchen Zustand das DOIF-Modul hat, +weil z. B. Garage nicht nur über die Fernbedienung geschaltet wird, dann muss man das per "do always"-Attribut angeben:

attr di_garage do always
@@ -2322,9 +2327,14 @@ Statt fester Zeitangaben können Stati, Readings oder Internals angegeben werden
define time dummy
set time 08:00
-define di_time DOIF ([[time]])(set lamp on)

+define di_time DOIF ([[time]])(set lamp on)
+attr di_time do always

-Ebenfalls kann das Dummy mit einer Sekundenzahl belegt werden, oder als indirekte Zeit angegeben werden, hier z. B. schalten alle 300 Sekunden:
+Die indirekte Angabe kann ebenfalls mit einer Zeitfunktion belegt werden. Z. B.
+
+set time {sunset()}
+
+Das Dummy kann auch mit einer Sekundenzahl belegt werden, oder als relative Zeit angegeben werden, hier z. B. schalten alle 300 Sekunden:

define time dummy
set time 300
@@ -2340,12 +2350,18 @@ set end 10:00

define di_time DOIF ([[begin]-[end]]) (set radio on) DOELSE (set radio off)


+Indirekte Zeitangaben können auch als Übergabeparameter für Zeitfunktionen, wie z. B. sunset oder sunrise übergeben werden:
+
+define di_time DOIF ([{sunrise(0,"[begin]","09:00")-{sunset(0,"18:00","[end]")]) (set lamp off) DOELSE (set lamp on)
+
Bei einer Änderung des angebenen Status oder Readings wird die geänderte Zeit sofort im Modul aktualisiert.

Angabe eines Readings als Zeitangabe. Beispiel: Schalten anhand eines Twilight-Readings:

define di_time DOIF ([[myTwilight:ss_weather]])(set lamp on)

+ + Dynamische Änderung einer Zeitangabe.

Anwendungsbeispiel: Die Endzeit soll abhängig von der Beginnzeit mit Hilfe einer eigenen Perl-Funktion, hier: OffTime(), bestimmt werden. begin und end sind Dummys, wie oben definiert:
@@ -2710,7 +2726,7 @@ Das ist insb. dann interessant, wenn ein Modul verschiedene Readings zu untersch
Beispiele:

-define di_lamp ([mytwilight:light] < 3) (set lamp on) DOELSEIF ([mytwilight:light] > 3) (set lamp off)
+define di_lamp DOIF ([mytwilight:light] < 3) (set lamp on) DOELSEIF ([mytwilight:light] > 3) (set lamp off)
attr di_lamp checkReadingEvent 1


Ebenso gilt die Einschränkung für indirekte Timer:
@@ -2964,7 +2980,7 @@ Hier passiert das nicht mehr, da die ursprünglichen Zustände cmd_1 und cmd_2 j
verwendete Timer mit Angabe des nächsten Zeitpunktes

wait_timer
-
Angabe des aktueller Wait-Timers
+
Angabe des aktuellen Wait-Timers

@@ -2997,8 +3013,8 @@ Hier passiert das nicht mehr, da die ursprünglichen Zustände cmd_1 und cmd_2 j
$SELF
für den Gerätenamen des DOIF

-
<globale Variable>
-
Variablen für Zeit- und Datumsangaben, siehe auch PERL Besonderheiten
+
<Perl-Funktionen>
+
vorhandene und selbsterstellte Perl-Funktionen

@@ -3007,7 +3023,7 @@ Hier passiert das nicht mehr, da die ursprünglichen Zustände cmd_1 und cmd_2 j @@ -3059,6 +3075,9 @@ Hier passiert das nicht mehr, da die ursprünglichen Zustände cmd_1 und cmd_2 j
initialize set <name> initialize
initialisiert das DOIF und aktiviert die Befehlsausführung
+
+
enable set <name> enable
+
aktiviert die Befehlsausführung, im Gegensatz zur obigen Initialisierung bleibt der letzte Zustand des Moduls erhalten