From b17b0bd209be103bb7f21ec09bf5f3685abcbf3d Mon Sep 17 00:00:00 2001 From: Damian Date: Tue, 5 Dec 2017 16:53:14 +0000 Subject: [PATCH] 98_DOIF.pm: new attributes uiTable and DOIF_Readings git-svn-id: https://svn.fhem.de/fhem/trunk@15558 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/98_DOIF.pm | 1308 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 1144 insertions(+), 164 deletions(-) diff --git a/fhem/FHEM/98_DOIF.pm b/fhem/FHEM/98_DOIF.pm index 8c822ee5e..449b4e25a 100644 --- a/fhem/FHEM/98_DOIF.pm +++ b/fhem/FHEM/98_DOIF.pm @@ -1,5 +1,5 @@ ############################################# -# $Id$# +# $Id$ # # This file is part of fhem. # @@ -21,11 +21,13 @@ package main; use strict; use warnings; +use Color; +use vars qw($FW_wname); # Web instance name sub DOIF_cmd ($$$$); +sub DOIF_Notify ($$); -sub -DOIF_delTimer($) +sub DOIF_delTimer($) { my ($hash) = @_; RemoveInternalTimer($hash); @@ -34,8 +36,7 @@ DOIF_delTimer($) } } -sub -DOIF_delAll($) +sub DOIF_delAll($) { my ($hash) = @_; delete ($hash->{helper}); @@ -55,17 +56,15 @@ DOIF_delAll($) delete ($hash->{trigger}); delete ($hash->{triggertime}); delete ($hash->{interval}); - delete ($hash->{regexp}); - #delete ($hash->{state}); - #delete ($defs{$hash->{NAME}}{READINGS}); + foreach my $key (keys %{$hash->{Regex}}) { + delete $hash->{Regex}{$key} if ($key !~ "STATE|DOIF_Readings|uiTable"); + } foreach my $key (keys %{$defs{$hash->{NAME}}{READINGS}}) { delete $defs{$hash->{NAME}}{READINGS}{$key} if ($key =~ "^(Device|state|error|warning|cmd|e_|timer_|wait_|matched_|last_cmd|mode)"); } } -######################### -sub -DOIF_Initialize($) +sub DOIF_Initialize($) { my ($hash) = @_; $hash->{DefFn} = "DOIF_Define"; @@ -73,13 +72,487 @@ DOIF_Initialize($) $hash->{UndefFn} = "DOIF_Undef"; $hash->{AttrFn} = "DOIF_Attr"; $hash->{NotifyFn} = "DOIF_Notify"; - $hash->{AttrList} = "disable:0,1 loglevel:0,1,2,3,4,5,6 wait do:always,resetwait cmdState state initialize repeatsame repeatcmd waitsame waitdel cmdpause timerWithWait:1,0 notexist selftrigger:wait,all timerevent:1,0 checkReadingEvent:1,0 addStateEvent:1,0 checkall:event,timer,all weekdays setList:textField-long readingList ".$readingFnAttributes; + $hash->{FW_deviceOverview} = 1; + $hash->{FW_addDetailToSummary} = 1; + $hash->{FW_detailFn} = "DOIF_detailFn"; + $hash->{FW_summaryFn} = "DOIF_summaryFn"; + #$hash->{FW_atPageEnd} = 1; + + $data{FWEXT}{DOIF}{SCRIPT} = "doif.js"; + + $hash->{AttrList} = "disable:0,1 loglevel:0,1,2,3,4,5,6 wait do:always,resetwait cmdState state initialize repeatsame repeatcmd waitsame waitdel cmdpause timerWithWait:1,0 notexist selftrigger:wait,all timerevent:1,0 checkReadingEvent:1,0 addStateEvent:1,0 checkall:event,timer,all weekdays setList:textField-long readingList DOIF_Readings:textField-long uiTable:textField-long ".$readingFnAttributes; +} + +# uiTable +sub DOIF_reloadFW { + map { FW_directNotify("#FHEMWEB:$_", "location.reload()", "") } devspec2array("TYPE=FHEMWEB"); +} + +sub DOIF_hsv +{ + my ($cur,$min,$max,$min_s,$max_s,$s,$v)=@_; + + my $m=($max_s-$min_s)/($max-$min); + my $n=$min_s-$min*$m; + if ($cur>$max) { + $cur=$max; + } elsif ($cur<$min) { + $cur=$min; + } + + my $h=$cur*$m+$n; + $h /=360; + $s /=100; + $v /=100; + + my($r,$g,$b)=Color::hsv2rgb ($h,$s,$v); + $r *= 255; + $g *= 255; + $b *= 255; + return sprintf("#%02X%02X%02X", $r+0.5, $g+0.5, $b+0.5); } +sub DOIF_rgb { + my ($sc,$ec,$pct,$max,$cur) = @_; + $cur = ($cur =~ /(-?\d+(\.\d+)?)/ ? $1 : 0); + $pct = ($cur-$pct)/($max-$pct) if (@_ == 5); + my $prefix = ""; + $prefix = "#" if ("$sc $ec"=~"#"); + $sc =~ s/^#//; + $ec =~ s/^#//; + $pct = $pct > 1 ? 1 : $pct; + $pct = $pct < 0 ? 0 : $pct; + $sc =~/([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})/; + my @sc = (hex($1),hex($2),hex($3)); + $ec =~/([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})/; + my @ec = (hex($1),hex($2),hex($3)); + my @rgb; + for (0..2) { + $rgb[$_] = sprintf("%02X", int(($ec[$_] - $sc[$_])*$pct + $sc[$_] + .5)); + } + return $prefix.join("",@rgb); +} -sub -GetBlockDoIf ($$) +#sub DOIF_Icon { +# my ($dev, $reading, $icon, $cmd, $type) = @_; +# my $val = ReadingsVal($dev,$reading,"???"); +# $type= $reading eq 'state' ? 'set' : 'setreading' if (!defined $type); +# my $ret = FW_makeImage($icon,$cmd,"icon"); +# $ret = FW_pH "cmd.$dev=$type $dev $reading $cmd", $ret, 0, "webCmd", 1; +# return "$ret"; +#} + +sub DOIF_UpdateCell +{ + my ($hash,$doifId,$dev,$reading) =@_; + my $pn = $hash->{NAME}; + my $retVal=""; + my $retStyle=""; + my $reg=""; + my $VALUE=""; + if ($doifId =~ /.*_(.*)_c_(.*)_(.*)_(.*)_(.*)$/) { + eval ($hash->{$1}{table}{$2}{$3}{$4}{$5}); + if ($@) { + my $err="$pn: eval: $hash->{$1}{table}{$2}{$3}{$4}{$5} error: $@" ; + Log3 $pn,3,$err; + } + } +} + +sub DOIF_Widget +{ + my ($hash,$reg,$doifId,$value,$style,$widget,$dev,$reading,$command)=@_; + if ($reg) { + return DOIF_Widget_Register($doifId,$value,$style,$widget,$dev,$reading,$command); + } else { + DOIF_Widget_Update($hash->{NAME},$doifId,$value,$style,$widget,$dev,$reading,$command); + } +} + +sub DOIF_Widget_Update +{ + my ($pn,$doifId,$value,$style,$widget,$dev,$reading,$command)=@_; + if (defined $widget) { + if (1) { + map { + FW_directNotify("#FHEMWEB:$_", "doifUpdateCell('$pn','informid','$dev-$reading','$value')","") + } devspec2array("TYPE=FHEMWEB"); + } + } else { + map { + FW_directNotify("#FHEMWEB:$_", "doifUpdateCell('$pn','doifId','$doifId','$value','display:inline;$style')","") + } devspec2array("TYPE=FHEMWEB") if ($value ne ""); + } +} + +sub DOIF_Widget_Register +{ + my ($doifId,$value,$style,$widget,$dev,$reading,$command)=@_; + my $type; + my $cmd=''; + if (defined $widget) { + if (defined $command) { + if ($command =~ /^([^ ]*) *(.*)/) { + $type = !defined $1 ? '': $1; + $cmd = !defined $2 ? '': $2; + } else { + $type=$command; + } + } else { + $type= $reading eq 'state' ? 'set' : 'setreading'; + } + $cmd = $cmd eq '' ? $reading : $cmd; + return "
"; + } else { + return "
$value
"; + } +} + +sub DOIF_RegisterCell +{ + my ($hash,$table,$func,$r,$c,$cc,$cr) =@_; + my $event; + my $err; + my $dev=""; + my $reading=""; + my $value=""; + my $expr; + my $style; + my $widget; + my $command; + my $cell; + my $widsty=0; + my $trigger=0; + + if ($func=~ /^\s*(STY[ \t]*\(|WID[ \t]*\()/) { + my ($beginning,$currentBlock,$err,$tailBlock)=GetBlockDoIf($func,'[\(\)]'); + if ($err) { + return $err; + } elsif ($currentBlock ne "") { + $cell=$currentBlock; + } + } else { + $cell=$func; + } + + my $doifId="$hash->{NAME}_".$table."_c_".$r."_".$c."_".$cc."_".$cr; + if ($func=~ /^\s*STY[ \t]*\(/) { + $widsty=1; + ($expr,$style) = SplitDoIf(',',$cell); + } elsif ($func=~ /^\s*WID[ \t]*\(/) { + $widsty=2; + ($expr,$widget,$command) = SplitDoIf(',',$cell); + } else { + $expr=$cell; + } + ($expr,$err,$event)=ReplaceAllReadingsDoIf($hash,$expr,($table eq "uiTable" ? -5:-6),0,$doifId); + if ($err) { + $err="'error $err: in expression: $expr'"; + return $err; + } else { + eval $expr; + if ($@) { + return "'error $@ in expression: $expr'"; + } + } + $trigger=$event; + if (defined($widget)) { + if ($event) { + $dev=$hash->{$table}{dev} if (defined $hash->{$table}{dev}); + $reading=$hash->{$table}{reading} if (defined $hash->{$table}{reading}); + } else { + return "'no trigger reading in widget: $expr'"; + } + ($widget,$err,$event)=ReplaceAllReadingsDoIf($hash,$widget,($table eq "uiTable" ? -5:-6),0,$doifId); + $trigger=$event if ($event); + if ($err) { + $err="'error $err: in widget: $widget'"; + return $err; + } else { + eval $widget; + if ($@) { + return "'error $@ in widget: $widget'"; + } + } + } else { + $widget=""; + } + if (defined $style) { + ($style,$err,$event)=ReplaceAllReadingsDoIf($hash,$style,($table eq "uiTable" ? -5:-6),0,$doifId); + $trigger=$event if ($event); + if ($err) { + $err="'error $err: in style: $style'"; + return $err; + } else { + eval $style; + if ($@) { + return "'error $@ in style: $style'"; + } + } + } else { + $style='""'; + } + + if ($widsty==2) { + $reading="state" if ($reading eq '&STATE'); + return "DOIF_Widget(".'$hash,$reg,'."'$doifId',$expr,$style,$widget,'$dev','$reading'".(defined $command ? ",$command)":")"); + } elsif (($widsty==1) or $trigger) { + return "DOIF_Widget(".'$hash,$reg,'."'$doifId',$expr,$style)"; + } else { + return $expr; + } + return "" +} + +sub parse_tpl +{ + my ($hash,$wcmd,$table) = @_; + my $d=$hash->{NAME}; + my $err=""; + while ($wcmd =~ /(?:^|\n)\s*IMPORT\s*(.*)(\n|$)/g) { + $err=import_tpl($hash,$1,$table); + return ($err,"") if ($err); + } + + #$wcmd =~ s/(^|\n)\s*\#.*(\n|$)/\n/g; + #$wcmd =~ s/(#.*\n)|(#.*$)|\n/ /g; + $wcmd =~ s/(##.*\n)|(##.*$)/\n/g; + $wcmd =~ s/(^|\n)\s*IMPORT.*(\n|$)//g; + $wcmd =~ s/\$TPL\{/\$hash->\{$table\}\{template\}\{/g; + #$wcmd =~ s/\$TD{/\$hash->{$table}{td}{/g; + #$wcmd =~ s/\$TC{/\$hash->{$table}{tc}{/g; + $wcmd =~ s/\$ATTRIBUTESFIRST/\$hash->{$table}{attributesfirst}/; + + $wcmd =~ s/\$TC\{/\$hash->{$table}{tc}\{/g; + $wcmd =~ s/\$hash->\{$table\}\{tc\}\{([\d,.]*)?\}.*(\".*\")/for my \$i ($1) \{\$hash->\{$table\}\{tc\}\{\$i\} = $2\}/g; + + $wcmd =~ s/\$TR\{/\$hash->{$table}{tr}\{/g; + $wcmd =~ s/\$hash->\{$table\}\{tr\}\{([\d,.]*)?\}.*(\".*\")/for my \$i ($1) \{\$hash->\{$table\}\{tr\}\{\$i\} = $2\}/g; + + $wcmd =~ s/\$TD\{(.*)?\}\{(.*)?\}.*(\".*\")/for my \$rowi ($1) \{for my \$coli ($2) \{\$hash->\{$table\}\{td\}\{\$rowi\}\{\$coli\} = $3\}\}/g; + $wcmd =~ s/\$TABLE/\$hash->{$table}{tablestyle}/; + + $wcmd =~ s/\$VAR/\$hash->{var}/g; + $wcmd =~ s/\$SELF/$d/g; + $wcmd =~ s/FUNC_/DOIF_FUNC_$d\_/g; + $wcmd =~ s/PUP[ \t]*\(/DOIF_tablePopUp(\"$d\",/g; + $wcmd =~ s/\$SHOWNOSTATE/\$hash->{$table}{shownostate}/; + $wcmd =~ s/\$SHOWNODEVICELINK/\$hash->{$table}{shownodevicelink}/; + $wcmd =~ s/\$SHOWNODEVICELINE/\$hash->{$table}{shownodeviceline}/; + + if ($wcmd=~ /^\s*\{/) { # perl block + my ($beginning,$currentBlock,$err,$tailBlock)=GetBlockDoIf($wcmd,'[\{\}]'); + if ($err) { + return ("error in $table: $err",""); + } elsif ($currentBlock ne "") { + $currentBlock ="no warnings 'redefine';".$currentBlock; + eval ($currentBlock); + if ($@) { + $err="$d: error: $@ in $table: $currentBlock"; + return ($err,""); + } + $wcmd=$tailBlock; + } + } + + $wcmd =~ s/^\s*//; + $wcmd =~ s/[ \t]*\n/\n/g; + $wcmd =~ s/,[ \t]*[\n]+/,/g; + $wcmd =~ s/\.[ \t]*[\n]+/\./g; + $wcmd =~ s/\|[ \t]*[\n]+/\|/g; + $wcmd =~ s/>[ \t]*[\n]+/>/g; + + my $tail=$wcmd; + my $beginning; + my $currentBlock; + + while($tail =~ /(?:^|\n)\s*DEF\s*(TPL_[^ ^\t^\(]*)[^\(]*\(/g) { + ($beginning,$currentBlock,$err,$tail)=GetBlockDoIf($tail,'[\(\)]'); + if ($err) { + return ("error in $table: $err",""); + } elsif ($currentBlock ne "") { + $hash->{$table}{tpl}{$1}=$currentBlock; + } + } + return ("",$tail); +} + +sub import_tpl +{ + my ($hash,$file,$table) = @_; + my $fh; + my $err; + if(!open($fh, $file)) { + return "Can't open $file: $!"; + } + my @tpl=<$fh>; + close $fh; + my $wcmd=join("",@tpl); + ($err,$wcmd)=parse_tpl($hash,$wcmd,$table); + return $err if ($err); + return ""; +} + +sub DOIF_uiTable_def +{ + my ($hash,$wcmd,$table) = @_; + return undef if (!$wcmd); + my $err=""; + delete ($hash->{Regex}{$table}); + delete ($hash->{$table}); + ($err,$wcmd)=parse_tpl($hash,$wcmd,$table); + return $err if ($err); + + my @rcmd = split(/\n/,$wcmd); + my $ii=0; + for (my $i=0; $i<@rcmd; $i++) { + next if ($rcmd[$i] =~ /^\s*$/); + my @ccmd = SplitDoIf('|',$rcmd[$i]); + for (my $k=0;$k<@ccmd;$k++) { + if ($ccmd[$k] =~ /^\s*(TPL_[^ ^\t^\(]*)[^\(]*\(/g) { + my $template=$1; + if (defined $hash->{$table}{tpl}{$template}) { + my $templ=$hash->{$table}{tpl}{$template}; + my ($beginning,$currentBlock,$err,$tail)=GetBlockDoIf($ccmd[$k],'[\(\)]'); + if ($err) { + return "error in $table: $err"; + } elsif ($currentBlock ne "") { + my @param = SplitDoIf(',',$currentBlock); + for (my $j=0;$j<@param;$j++) { + my $p=$j+1; + $templ =~ s/\$$p/$param[$j]/g; + } + $ccmd[$k]=$templ; + } + } else { + return ("no Template $template defined"); + } + } + my @cccmd = SplitDoIf(',',$ccmd[$k]); + for (my $l=0;$l<@cccmd;$l++) { + my @crcmd = SplitDoIf('.',$cccmd[$l]); + for (my $m=0;$m<@crcmd;$m++) { + $hash->{$table}{table}{$ii}{$k}{$l}{$m}= DOIF_RegisterCell($hash,$table,$crcmd[$m],$ii,$k,$l,$m); + + } + } + } + $ii++; + } + return undef; + ##$hash->{$table}{tabledef}=DOIF_RegisterEvalAll($hash); +} + +sub DOIF_RegisterEvalAll +{ + my ($hash,$d,$table) = @_; + my $ret = ""; + my $reg=1; + return undef if (!defined $hash->{$table}{table}); + #$ret =~ s/class\=\'block\'/$hash->{$table}{table}/ if($hash->{$table}{table}); + if ($table eq "uiTable") { + $ret .= "\n"; + #$ret .= "\n
"; + } else { + $ret .= "\n
"; + } + my $lasttr =scalar keys %{$hash->{$table}{table}}; + for (my $i=0;$i < $lasttr;$i++){ + my $class = ($i&1)?"class='odd'":"class='even'"; + $ret .="{$table}{tr}{$i}) ? $hash->{$table}{tr}{$i}:""); + $ret .=" ".(($i&1) ? $hash->{$table}{tr}{odd}:"") if (defined $hash->{$table}{tr}{odd}); + $ret .=" ".((!($i&1)) ? $hash->{$table}{tr}{even}:"") if (defined $hash->{$table}{tr}{even}); + $ret .=" ".(($i==$lasttr-1) ? $hash->{$table}{tr}{last}:"") if (defined $hash->{$table}{tr}{last}); + $ret .=" $class >"; + my $lastc =scalar keys %{$hash->{$table}{table}{$i}}; + for (my $k=0;$k < $lastc;$k++){ + $ret .=""; + } + $ret .= ""; + } + $ret .= "
{$table}{td}{$i}{$k}) ? $hash->{$table}{td}{$i}{$k}:""); + $ret .=" ".((defined $hash->{$table}{tc}{$k} )? $hash->{$table}{tc}{$k}:""); + $ret .=" ".(($k&1)?$hash->{$table}{tc}{odd}:"") if (defined $hash->{$table}{tc}{odd}); + $ret .=" ".((!($k&1))?$hash->{$table}{tc}{even}:"") if (defined $hash->{$table}{tc}{even}); + $ret .=" ".(($k==$lastc-1)?$hash->{$table}{tc}{last}:"") if (defined $hash->{$table}{tc}{last}); + $ret .=">"; + my $lastcc =scalar keys %{$hash->{$table}{table}{$i}{$k}}; + for (my $l=0;$l < $lastcc;$l++){ + for (my $m=0;$m < scalar keys %{$hash->{$table}{table}{$i}{$k}{$l}};$m++) { + if (defined $hash->{$table}{table}{$i}{$k}{$l}{$m}){ + my $value= eval ($hash->{$table}{table}{$i}{$k}{$l}{$m}); + if (defined $hash->{$table}{shownodevicelink} and !$hash->{$table}{shownodevicelink} and defined $defs{$value}) { + $ret.="$value"; + } else { + $ret.=$value; + } + } + } + $ret.="
" if ($l+1 != $lastcc); + } + $ret.="
\n"; # if ($table eq "uiTable"); + + # my $jsh = ""; + # $ret .= $jsh.$jsc.$jsf if ($jsc); + #$hash->{$table}{deftable}=$ret; + return $ret; +} + +# sub DOIF_summaryFn ($$$$) { + # my ($FW_wname, $d, $room, $pageHash) = @_; + # my $hash = $defs{$d}; + # return ($hash->{$table}{shownostate} ? "" : undef); +# } + +sub DOIF_tablePopUp { + my ($pn,$d,$icon,$table) = @_; + $table = $table ? $table : "uiTable"; + if ($defs{$d} && AttrVal($d,$table,"")) { + my $ret = "".FW_makeImage($icon).""; + } else { + return "no device $d or attribut $table"; + } +} + +sub DOIF_summaryFn ($$$$) { + my ($FW_wname, $d, $room, $pageHash) = @_; # pageHash is set for summaryFn. + my $hash = $defs{$d}; + my $ret = ""; + # if ($hash->{uiTable}{shownostate}) { + # return ""; + # } + #Log3 $d,1,"vor DOIF_RegisterEvalAll uiState d: $d"; + $ret=DOIF_RegisterEvalAll($hash,$d,"uiState"); + #Log3 $d,1,"nach DOIF_RegisterEvalAll"; + return $ret; +} + +sub DOIF_detailFn ($$$$) { + my ($FW_wname, $d, $room, $pageHash) = @_; # pageHash is set for summaryFn. + my $hash = $defs{$d}; + my $ret = ""; + #Log3 $d,1,"vor DOIF_RegisterEvalAll uiTable"; + $ret=DOIF_RegisterEvalAll($hash,$d,"uiTable"); + #Log3 $d,1,"nach DOIF_RegisterEvalAll"; + return $ret; +} + +sub GetBlockDoIf ($$) { my ($cmd,$match) = @_; my $count=0; @@ -114,8 +587,8 @@ GetBlockDoIf ($$) return ($cmd,"","",""); } } -sub -GetCommandDoIf ($$) + +sub GetCommandDoIf ($$) { my ($separator,$tailBlock) = @_; my $char; @@ -202,8 +675,7 @@ sub EvalCmdStateDoIf($$) return($state) } -sub -SplitDoIf($$) +sub SplitDoIf($$) { my ($separator,$tailBlock)=@_; my @commands; @@ -219,8 +691,7 @@ SplitDoIf($$) return(@commands); } -sub -EventCheckDoif($$$$) +sub EventCheckDoif($$$$) { my ($n,$dev,$eventa,$NotifyExp)=@_; my $found=0; @@ -243,8 +714,7 @@ EventCheckDoif($$$$) return 0; } -sub -AggrIntDoIf +sub AggrIntDoIf { my ($hash,$modeType,$device,$reading,$cond,$default)=@_; my $num=0; @@ -269,7 +739,7 @@ AggrIntDoIf my $place; my $number; -if ($modeType =~ /.(sum|average|max|min)?[:]?(?:(a|d)?(\d)?)?/) { + if ($modeType =~ /.(sum|average|max|min)?[:]?(?:(a|d)?(\d)?)?/) { $type = (defined $1)? $1 : ""; $format= (defined $2)? $2 : ""; $place= $3; @@ -387,15 +857,13 @@ if ($modeType =~ /.(sum|average|max|min)?[:]?(?:(a|d)?(\d)?)?/) { return 0; } -sub -AggrDoIf +sub AggrDoIf { my ($modeType,$device,$reading,$cond,$default)=@_; return (AggrIntDoIf(undef,$modeType,$device,$reading,$cond,$default)); } -sub -AggregateDoIf +sub AggregateDoIf { my ($hash,$modeType,$device,$reading,$cond,$default)=@_; my $mode=substr($modeType,0,1); @@ -412,8 +880,7 @@ AggregateDoIf return (""); } -sub -EventDoIf +sub EventDoIf { my ($n,$hash,$NotifyExp,$check,$filter,$output,$default)=@_; @@ -481,8 +948,7 @@ EventDoIf } } -sub -InternalDoIf +sub InternalDoIf { my ($hash,$name,$internal,$default,$regExp,$output)=@_; @@ -515,16 +981,14 @@ InternalDoIf return($element); } -sub -ReadingSecDoIf($$) +sub ReadingSecDoIf($$) { my ($name,$reading)=@_; my ($seconds, $microseconds) = gettimeofday(); return ($seconds - time_str2num(ReadingsTimestamp($name, $reading, "1970-01-01 01:00:00"))); } -sub -ReadingValDoIf +sub ReadingValDoIf { my ($hash,$name,$reading,$default,$regExp,$output)=@_; @@ -566,8 +1030,7 @@ ReadingValDoIf return($element); } -sub -EvalAllDoIf($$) +sub EvalAllDoIf($$) { my ($hash,$tailBlock)= @_; my $eval=""; @@ -602,7 +1065,7 @@ EvalAllDoIf($$) sub ReplaceAggregateDoIf($$$) { - my ($hash,$block,$condition) = @_; + my ($hash,$block,$eval) = @_; my $exp; my $nameExp; my $notifyExp; @@ -642,7 +1105,7 @@ sub ReplaceAggregateDoIf($$$) $block="AggregateDoIf(".'$hash'.",'$aggrType','$nameExp')"; } - if (!($condition >= 0)) { + if ($eval) { my $ret = eval $block; return($block." ",$@) if ($@); $block=$ret; @@ -650,7 +1113,6 @@ sub ReplaceAggregateDoIf($$$) return ($block,undef); } - sub ReplaceEventDoIf($) { my ($block) = @_; @@ -809,45 +1271,74 @@ sub AddItemDoIf($$) return $items; } -sub AddRegexpTriggerDoIf($$$) +sub AddRegexpTriggerDoIf { - my ($hash,$regexp,$condition)= @_; - my $max_regexp=keys %{$hash->{regexp}{$condition}}; - for (my $i=0; $i<$max_regexp;$i++) - { - if ($hash->{regexp}{$condition}{$i} eq $regexp) { - return; + my ($hash,$type,$regexp,$element,$dev,$reading)= @_; + + $dev="" if (!defined($dev)); + $reading="" if (!defined($reading)); + my $regexpid='"'.$regexp.'"'; + + if ($dev) { + if ($reading){ + $hash->{Regex}{$type}{$dev}{$element}{$reading}=(($reading =~ "^\&") ? "\^$dev\$":"\^$dev\$:\^$reading: "); + } elsif ($regexp) { + $hash->{Regex}{$type}{$dev}{$element}{$regexpid}="\^$dev\$:$regexp"; } + return; } - $hash->{regexp}{$condition}{$max_regexp}=$regexp; - $max_regexp=keys %{$hash->{regexp}{all}}; - for (my $i=0; $i<$max_regexp;$i++) - { - if ($hash->{regexp}{all}{$i} eq $regexp) { - return; - } - } - $hash->{regexp}{all}{$max_regexp}=$regexp; + $hash->{Regex}{$type}{$dev}{$element}{$regexpid}=$regexp; } -sub AddRegexpStateDoIf($$) +sub addDOIF_Readings($$) { - my ($hash,$regexp)= @_; - my $max_regexp=keys %{$hash->{state}{STATE}}; - for (my $i=0; $i<$max_regexp;$i++) + my ($hash,$DOIF_Readings) = @_; + delete $hash->{DOIF_Readings}; + delete $hash->{Regex}{DOIF_Readings}; + my @list=SplitDoIf(',',$DOIF_Readings); + my $reading; + my $readingdef; + + for (my $i=0;$i<@list;$i++) { - if ($hash->{state}{STATE}{$i} eq $regexp) { - return; + ($reading,$readingdef)=SplitDoIf(":",$list[$i]); + if (!$readingdef) { + return ($DOIF_Readings,"no reading definiton: $list[$i]"); + } + if ($reading =~ /^\s*([a-z0-9._-]*[a-z._-]+[a-z0-9._-]*)\s*$/i) { + my ($def,$err)=ReplaceAllReadingsDoIf($hash,$readingdef,-4,0,$1); + return ($def,$err) if ($err); + $hash->{DOIF_Readings}{$1}=$def; + } else { + return ($list [$i],"wrong reading specification for: $reading"); } } - $hash->{state}{STATE}{$max_regexp}=$regexp; + return ("",""); } - - -sub ReplaceAllReadingsDoIf($$$$) +sub setDOIF_Reading { - my ($hash,$tailBlock,$condition,$eval)= @_; + my ($hash,$DOIF_Reading,$reading) = @_; + $lastWarningMsg=""; + my $ret = eval $hash->{DOIF_Readings}{$DOIF_Reading}; + if ($@) { + $@ =~ s/^(.*) at \(eval.*\)(.*)$/$1,$2/; + $ret="error in DOIF_Readings: ".$@; + } + if ($lastWarningMsg) { + $lastWarningMsg =~ s/^(.*) at \(eval.*$/$1/; + Log3 ($hash->{NAME},3 , "$hash->{NAME}: warning in DOIF_Readings: $DOIF_Reading"); + } + $lastWarningMsg=""; + if ($ret ne ReadingsVal($hash->{NAME},$DOIF_Reading,"")){ + push (@{$hash->{helper}{DOIF_Readings_events}},"$DOIF_Reading: $ret"); + readingsSingleUpdate ($hash,$DOIF_Reading,$ret,0); + } +} + +sub ReplaceAllReadingsDoIf +{ + my ($hash,$tailBlock,$condition,$eval,$id)= @_; my $block=""; my $beginning; my $err; @@ -876,22 +1367,34 @@ sub ReplaceAllReadingsDoIf($$$$) $trigger=1; } if ($block =~ /^(?:(?:#|@)[^"]*)"([^"]*)"/) { - ($block,$err)=ReplaceAggregateDoIf($hash,$block,$condition); + ($block,$err)=ReplaceAggregateDoIf($hash,$block,$eval); return ($block,$err) if ($err); if ($trigger) { + $event=1; if ($condition >= 0) { - AddRegexpTriggerDoIf($hash,$1,$condition); - $event=1; + AddRegexpTriggerDoIf($hash,"cond",$1,$condition); } elsif ($condition == -2) { - AddRegexpStateDoIf($hash,$1); - } + AddRegexpTriggerDoIf($hash,"STATE",$1,"STATE"); + } elsif ($condition == -4) { + AddRegexpTriggerDoIf($hash,"DOIF_Readings",$1,$id); + } elsif ($condition == -5) { + AddRegexpTriggerDoIf($hash,"uiTable",$1,$id); + } elsif ($condition == -6) { + AddRegexpTriggerDoIf($hash,"uiState",$1,$id); + } } } elsif ($block =~ /^"([^"]*)"/) { - if ($condition>=0) { - ($block,$err)=ReplaceEventDoIf($block); - return ($block,$err) if ($err); - AddRegexpTriggerDoIf($hash,$1,$condition); - $event=1; + ($block,$err)=ReplaceEventDoIf($block); + return ($block,$err) if ($err); + if ($trigger) { + if ($condition>=0) { + AddRegexpTriggerDoIf($hash,"cond",$1,$condition); + $event=1; + } elsif ($condition == -4) { + AddRegexpTriggerDoIf($hash,"DOIF_Readings",$1,$id); + } else { + $block="[".$block."]"; + } } else { $block="[".$block."]"; } @@ -913,9 +1416,31 @@ sub ReplaceAllReadingsDoIf($$$$) $hash->{trigger}{all} = AddItemDoIf($hash->{trigger}{all},"$device") if (!defined ($internal) and !defined($reading)); } elsif ($condition == -2) { - $hash->{state}{device} = AddItemDoIf($hash->{state}{device},$device); #if ($device ne $hash->{NAME}); + if ($trigger) { + AddRegexpTriggerDoIf($hash,"STATE","","STATE",$device,((defined $reading) ? $reading : "&STATE")); + $event=1; + } } elsif ($condition == -3) { $hash->{itimer}{all} = AddItemDoIf($hash->{itimer}{all},$device); + } elsif ($condition == -4) { + if ($trigger) { + AddRegexpTriggerDoIf($hash,"DOIF_Readings","",$id,$device,((defined $reading) ? $reading :"&STATE")); + $event=1; + } + } elsif ($condition == -5) { + if ($trigger) { + AddRegexpTriggerDoIf($hash,"uiTable","",$id,$device,((defined $reading) ? $reading : "&STATE")); + $hash->{uiTable}{dev}=$device; + $hash->{uiTable}{reading}=((defined $reading) ? $reading : "&STATE"); + $event=1; + } + } elsif ($condition == -6) { + if ($trigger) { + AddRegexpTriggerDoIf($hash,"uiState","",$id,$device,((defined $reading) ? $reading : "&STATE")); + $hash->{uiState}{dev}=$device; + $hash->{uiState}{reading}=((defined $reading) ? $reading : "&STATE"); + $event=1; + } } } elsif ($condition >= 0) { ($timer,$err)=DOIF_CheckTimers($hash,$block,$condition,$trigger); @@ -932,7 +1457,7 @@ sub ReplaceAllReadingsDoIf($$$$) $cmd.=$beginning.$block; } #return ($definition,"no trigger in condition") if ($condition >=0 and $event == 0); - return ($cmd,""); + return ($cmd,"",$event); } sub @@ -1205,7 +1730,6 @@ DOIF_SetState($$$$$) my $state=AttrVal($hash->{NAME},"state",""); $state =~ s/\$SELF/$pn/g; my @cmdState=SplitDoIf('|',$attr); - return undef if (AttrVal($hash->{NAME},"disable","")); $nr=ReadingsVal($pn,"cmd_nr",0)-1 if (!$event); if ($nr!=-1) { $cmdNr=$nr+1; @@ -1229,16 +1753,21 @@ DOIF_SetState($$$$$) } readingsBeginUpdate ($hash); if ($event) { + push (@{$hash->{helper}{DOIF_eventas}},"cmd_nr: $cmdNr"); readingsBulkUpdate($hash,"cmd_nr",$cmdNr); if (defined $hash->{do}{$nr}{1}) { readingsBulkUpdate($hash,"cmd_seqnr",$subnr+1); + push (@{$hash->{helper}{DOIF_eventas}},("cmd_seqnr: ".($subnr+1))); readingsBulkUpdate($hash,"cmd",$cmdNr.".".($subnr+1)); } else { delete ($defs{$hash->{NAME}}{READINGS}{cmd_seqnr}); + push (@{$hash->{helper}{DOIF_eventas}},"cmd: $cmdNr"); readingsBulkUpdate($hash,"cmd",$cmdNr); } + push (@{$hash->{helper}{DOIF_eventas}},"cmd_event: $event"); readingsBulkUpdate($hash,"cmd_event",$event); if ($last_error) { + push (@{$hash->{helper}{DOIF_eventas}},"error: $last_error"); readingsBulkUpdate($hash,"error",$last_error); } else { delete ($defs{$hash->{NAME}}{READINGS}{error}); @@ -1253,9 +1782,13 @@ DOIF_SetState($$$$$) } else { $state=$cmd; } - - readingsBulkUpdate($hash, "state", $state); - readingsEndUpdate ($hash, 1); + push (@{$hash->{helper}{DOIF_eventas}},"state: $state"); + readingsBulkUpdate($hash, "state", $state); + if (defined $hash->{uiState}{table}) { + readingsEndUpdate ($hash, 0); + } else { + readingsEndUpdate ($hash, 1); + } } sub @@ -1420,7 +1953,6 @@ DOIF_cmd ($$$$) } if ($hash->{do}{$nr}{$subnr}) { $cmd=$hash->{do}{$nr}{$subnr}; - my $eventa=$hash->{helper}{triggerEvents}; my $events=""; if ($eventa) { @@ -1446,7 +1978,7 @@ DOIF_cmd ($$$$) DOIF_cmd ($hash,$nr,$subnr,$event); } } else { - if ($sleeptimer[$nr]) { + if (($sleeptimer[$nr])) { my $last_cond=ReadingsVal($pn,"cmd_nr",0)-1; if (DOIF_SetSleepTimer($hash,$last_cond,$nr,0,$event,-1,$sleeptimer[$nr])) { DOIF_cmd ($hash,$nr,$subnr,$event); @@ -1485,7 +2017,7 @@ sub CheckReadingDoIf($$) my $found=0; my $device; my $reading; - + if (!defined $readings) { return 1; } @@ -1505,65 +2037,77 @@ sub CheckReadingDoIf($$) return 0; } -sub CheckRegexpDoIf($$$$) +sub CheckRegexpDoIf { - my ($hash,$name,$eventa,$cond)=@_; - my $type; - if ($cond eq "STATE") { - $type="state"; - } else { - $type="regexp"; - } - my $max_regexp=keys %{$hash->{$type}{$cond}}; - my $c; + my ($hash,$type,$device,$id,$eventa,$readingupdate)=@_; my $nameExp; my $notifyExp; - - for (my $i=0; $i<$max_regexp;$i++) - { - if ($hash->{$type}{$cond}{$i} =~ /([^\:]*):(.*)/) { - $nameExp=$1; - $notifyExp=$2; - } else { - $nameExp=$hash->{$type}{$cond}{$i}; + my $event; + my @idlist; + my @devlist; + + return undef if (!defined $hash->{Regex}{$type}); + if ($id eq "") { + if (defined $hash->{Regex}{$type}{$device}) { + return 1; } - $nameExp="" if (!$nameExp); - $notifyExp="" if (!$notifyExp); - if ($nameExp eq "" or $name =~ /$nameExp/) { - #my $eventa = $hash->{helper}{triggerEvents}; - my $events=""; - if ($eventa) { - $events=join(",",@{$eventa}); - } - if ($notifyExp eq "") { - if ($cond ne "all" and $cond ne "STATE") { - $c=$cond+1; - readingsSingleUpdate ($hash, "matched_event_c".$c."_".($i+1),"$events",0); - } - return 1; - } - my $max = int(@{$eventa}); - my $s; - my $found; - for (my $j = 0; $j < $max; $j++) { - $s = $eventa->[$j]; - $s = "" if(!defined($s)); - $found = ($s =~ m/$notifyExp/); - if ($found) { - if ($cond ne "all" and $cond ne "STATE") { - $c=$cond+1; - readingsSingleUpdate ($hash, "matched_event_c".$c."_".($i+1),$s,0); + @devlist=(""); + } else { + @devlist=("$device",""); + } + + foreach my $dev (@devlist){ + if (defined $hash->{Regex}{$type}{$dev}) { + @idlist=($id eq "") ? (keys %{$hash->{Regex}{$type}{$dev}}):($id); + foreach my $id (@idlist) { + foreach my $i (keys %{$hash->{Regex}{$type}{$dev}{$id}}) { + #$event=($type eq "cond") ? "c".($id+1) : $id; + if ($hash->{Regex}{$type}{$dev}{$id}{$i} =~ /([^\:]*):(.*)/) { + $nameExp=$1; + $notifyExp=$2; + } else { + $nameExp=$hash->{Regex}{$type}{$dev}{$id}{$i}; + } + $nameExp="" if (!$nameExp); + $notifyExp="" if (!$notifyExp); + if ($nameExp eq "" or $device =~ /$nameExp/) { + my $events=""; + if ($eventa) { + $events=join(",",@{$eventa}); + } + if ($notifyExp eq "") { + if ($readingupdate==1) { + #readingsSingleUpdate ($hash, "matched_regex_$id",$events,0); + } elsif ($readingupdate==2) { + #readingsBulkUpdate ($hash, "matched_event_$event"."_".($i+1),$events); + } + return $i; + } + my $max = int(@{$eventa}); + my $s; + my $found; + for (my $j = 0; $j < $max; $j++) { + $s = $eventa->[$j]; + $s = "" if(!defined($s)); + $found = ($s =~ m/$notifyExp/); + if ($found) { + if ($readingupdate==1) { + #readingsSingleUpdate ($hash, "matched_regex_$id",$s,0); + } elsif ($readingupdate==2) { + #readingsBulkUpdate ($hash, "matched_event_$event"."_".($i+1),$s); + } + return $i; + } + } } - return 1 } } } } - return 0; + return undef; } -sub -DOIF_Trigger ($$) +sub DOIF_Trigger ($$) { my ($hash,$device)= @_; my $timerNr=-1; @@ -1603,7 +2147,7 @@ DOIF_Trigger ($$) $hash->{helper}{triggerDev}=""; $hash->{helper}{event}=$event; } else { #event - if (!CheckRegexpDoIf($hash, $device, $hash->{helper}{triggerEvents}, $i)) { + if (!defined CheckRegexpDoIf($hash,"cond", $device,$i,$hash->{helper}{triggerEvents},1)) { if (AttrVal($pn, "checkall", 0) !~ "1|all|event") { next if (!defined ($hash->{devices}{$i})); next if ($hash->{devices}{$i} !~ / $device /); @@ -1664,9 +2208,11 @@ DOIF_Notify($$) my $err; my $eventa; my $eventas; + $eventa = deviceEvents($dev, AttrVal($pn, "addStateEvent", 0)); $eventas = deviceEvents($dev, 1); - if ($dev->{NAME} eq "global" and (EventCheckDoif($dev->{NAME},"global",$eventa,"INITIALIZED") or EventCheckDoif($dev->{NAME},"global",$eventa,"REREADCFG"))) + + if ($dev->{NAME} eq "global" and (EventCheckDoif($dev->{NAME},"global",$eventa,'^INITIALIZED$') or EventCheckDoif($dev->{NAME},"global",$eventa,'^REREADCFG$'))) { $hash->{helper}{globalinit}=1; # delete old timer-readings @@ -1679,18 +2225,30 @@ DOIF_Notify($$) DOIF_SetTimer($hash,"DOIF_TimerTrigger",$j); } } - if (AttrVal($pn,"initialize",0) and !AttrVal($pn,"disable",0)) { - readingsBeginUpdate($hash); - readingsBulkUpdate ($hash,"state",AttrVal($pn,"initialize",0)); - readingsBulkUpdate ($hash,"cmd_nr","0"); - readingsBulkUpdate ($hash,"cmd",0); - readingsEndUpdate($hash, 0); + + my $uiTable=AttrVal($pn, "uiTable", 0); + if ($uiTable){ + my $err=DOIF_uiTable_def($hash,$uiTable,"uiTable"); + Log3 ($pn,3,"$pn: error in uiTable: $err") if ($err); + } + + my $uiState=AttrVal($pn, "uiState", 0); + if ($uiState){ + my $err=DOIF_uiTable_def($hash,$uiState,"uiState"); + Log3 ($pn,3,"$pn: error in uiState: $err") if ($err); + } + + if (AttrVal($pn,"initialize",0) and !AttrVal($pn,"disable",0)) { + readingsBeginUpdate($hash); + readingsBulkUpdate ($hash,"state",AttrVal($pn,"initialize",0)); + readingsBulkUpdate ($hash,"cmd_nr","0"); + readingsBulkUpdate ($hash,"cmd",0); + readingsEndUpdate($hash, 0); } } - return "" if (!$hash->{helper}{globalinit}); - return "" if (!$hash->{itimer}{all} and !$hash->{devices}{all} and !$hash->{state}{device} and !keys %{$hash->{state}{STATE}} and !keys %{$hash->{regexp}{all}}); + #return "" if (!$hash->{itimer}{all} and !$hash->{devices}{all} and !keys %{$hash->{Regex}}); if (($hash->{itimer}{all}) and $hash->{itimer}{all} =~ / $dev->{NAME} /) { for (my $j=0; $j<$hash->{helper}{last_timer};$j++) { @@ -1702,12 +2260,18 @@ DOIF_Notify($$) return "" if (defined $hash->{helper}{cur_cmd_nr}); return "" if (ReadingsVal($pn,"mode","") eq "disabled"); + + $ret=0; + $hash->{helper}{DOIF_eventas} = (); - if ((($hash->{devices}{all}) and $hash->{devices}{all} =~ / $dev->{NAME} /) or CheckRegexpDoIf($hash,$dev->{NAME},$eventa,"all") or CheckRegexpDoIf($hash,$dev->{NAME},$eventa,"STATE")){ + if ((($hash->{devices}{all}) and $hash->{devices}{all} =~ / $dev->{NAME} /) or defined CheckRegexpDoIf($hash,"cond",$dev->{NAME},"",$eventa,0)){ $hash->{helper}{cur_cmd_nr}="Trigger $dev->{NAME}" if (AttrVal($hash->{NAME},"selftrigger","") ne "all"); + $hash->{helper}{triggerEvents}=$eventa; + $hash->{helper}{triggerEventsState}=$eventas; + $hash->{helper}{triggerDev}=$dev->{NAME}; + $hash->{helper}{event}=join(",",@{$eventa}); + readingsSingleUpdate ($hash, "Device",$dev->{NAME},0); - #my $events = deviceEvents($dev, AttrVal($dev->{NAME}, "addStateEvent", 0)); - #readingsSingleUpdate ($hash, "Event","@{$events}",0); if ($hash->{readings}{all}) { foreach my $item (split(/ /,$hash->{readings}{all})) { ($device,$reading)=(split(":",$item)); @@ -1729,21 +2293,65 @@ DOIF_Notify($$) readingsSingleUpdate ($hash, "e_".$dev->{NAME}."_events",join(",",@{$eventa}),0); } } - $hash->{helper}{triggerEvents}=$eventa; - $hash->{helper}{triggerEventsState}=$eventas; - $hash->{helper}{triggerDev}=$dev->{NAME}; - $hash->{helper}{event}=join(",",@{$eventa}); $ret=DOIF_Trigger($hash,$dev->{NAME}); } - if ((($hash->{state}{device}) and $hash->{state}{device} =~ / $dev->{NAME} / or CheckRegexpDoIf($hash,$dev->{NAME},$eventa,"STATE")) and !$ret) { - $hash->{helper}{cur_cmd_nr}="Trigger $dev->{NAME}" if (AttrVal($hash->{NAME},"selftrigger","") ne "all"); + + if ((defined CheckRegexpDoIf($hash,"STATE",$dev->{NAME},"STATE",$eventa,1)) and !$ret) { $hash->{helper}{triggerEvents}=$eventa; $hash->{helper}{triggerEventsState}=$eventas; $hash->{helper}{triggerDev}=$dev->{NAME}; $hash->{helper}{event}=join(",",@{$eventa}); DOIF_SetState($hash,"",0,"",""); } + delete $hash->{helper}{cur_cmd_nr}; + + $hash->{helper}{DOIF_Readings_events}= (); + if (defined $hash->{Regex}{"DOIF_Readings"}) { + foreach $device ("$dev->{NAME}","") { + if (defined $hash->{Regex}{"DOIF_Readings"}{$device}) { + #readingsBeginUpdate($hash); + foreach my $reading (keys %{$hash->{Regex}{"DOIF_Readings"}{$device}}) { + my $readingregex=CheckRegexpDoIf($hash,"DOIF_Readings",$dev->{NAME},$reading,$eventas,0); + setDOIF_Reading($hash,$reading,$readingregex) if (defined($readingregex)); + } + #readingsEndUpdate($hash, 1); + } + } + if (defined ($hash->{helper}{DOIF_eventas})) { #$SELF events + foreach my $reading (keys %{$hash->{Regex}{"DOIF_Readings"}{$hash->{NAME}}}) { + my $readingregex=CheckRegexpDoIf($hash,"DOIF_Readings",$hash->{NAME},$reading,$hash->{helper}{DOIF_eventas},0); + setDOIF_Reading($hash,$reading,$readingregex) if (defined($readingregex)); + } + } + } + + foreach my $table ("uiTable","uiState") { + if (defined $hash->{Regex}{$table}) { + foreach $device ("$dev->{NAME}","") { + if (defined $hash->{Regex}{$table}{$device}) { + foreach my $doifId (keys %{$hash->{Regex}{$table}{$device}}) { + my $readingregex=CheckRegexpDoIf($hash,$table,$dev->{NAME},$doifId,$eventas,0); + DOIF_UpdateCell($hash,$doifId,$hash->{NAME},$readingregex) if (defined($readingregex)); + } + } + } + if (defined ($hash->{helper}{DOIF_eventas})) { #$SELF events + foreach my $doifId (keys %{$hash->{Regex}{$table}{$hash->{NAME}}}) { + my $readingregex=CheckRegexpDoIf($hash,$table,$hash->{NAME},$doifId,$hash->{helper}{DOIF_eventas},0); + DOIF_UpdateCell($hash,$doifId,$hash->{NAME},$readingregex) if (defined($readingregex)); + } + } + } + } + + if (defined $hash->{helper}{DOIF_Readings_events}) { + if ($dev->{NAME} ne $hash->{NAME}) { + @{$hash->{CHANGED}}=@{$hash->{helper}{DOIF_Readings_events}}; + @{$hash->{CHANGEDWITHSTATE}}=@{$hash->{helper}{DOIF_Readings_events}}; + DOIF_Notify($hash,$hash); + } + } return undef; } @@ -2031,7 +2639,6 @@ DOIF_SetSleepTimer($$$$$$$) if ($timerNr >= 0 and !AttrVal($pn,"timerWithWait","")) {#Timer if ($last_cond != $nr or AttrVal($pn,"do","") eq "always" or AttrVal($pn,"do","") eq "resetwait" or AttrVal($pn,"repeatsame","")) { - return 1; } else { return 0; @@ -2089,8 +2696,6 @@ DOIF_SleepTrigger ($) my ($hash)=@_; my $sleeptimer=$hash->{helper}{sleeptimer}; my $sleepsubtimer=$hash->{helper}{sleepsubtimer}; - $hash->{helper}{sleeptimer}=-1; - $hash->{helper}{sleepsubtimer}=-1; my $pn = $hash->{NAME}; $hash->{helper}{cur_cmd_nr}="wait_timer" if (!AttrVal($hash->{NAME},"selftrigger","")); $hash->{helper}{triggerEvents}=$hash->{helper}{timerevents}; @@ -2098,7 +2703,8 @@ DOIF_SleepTrigger ($) $hash->{helper}{event}=$hash->{helper}{timerevent}; $hash->{helper}{triggerDev}=$hash->{helper}{timerdev}; readingsSingleUpdate ($hash, "wait_timer", "no timer",1); -# if (!AttrVal($hash->{NAME},"disable","")) { + $hash->{helper}{sleeptimer}=-1; + $hash->{helper}{sleepsubtimer}=-1; if (ReadingsVal($pn,"mode","") ne "disabled") { DOIF_cmd ($hash,$sleeptimer,$sleepsubtimer,$hash->{helper}{sleepdevice}); } @@ -2249,11 +2855,11 @@ DOIF_Attr(@) DOIF_delAll ($hash); readingsSingleUpdate ($hash,"state","deactivated",1); } elsif($a[0] eq "set" && $a[2] eq "state") { - delete $hash->{state}; + delete $hash->{Regex}{"STATE"}; my ($block,$err)=ReplaceAllReadingsDoIf($hash,$a[3],-2,0); return $err if ($err); } elsif($a[0] eq "del" && $a[2] eq "state") { - delete $hash->{state}; + delete $hash->{Regex}{"STATE"}; } elsif($a[0] eq "set" && $a[2] eq "wait") { RemoveInternalTimer($hash); #delete ($defs{$hash->{NAME}}{READINGS}{wait_timer}); @@ -2263,6 +2869,25 @@ DOIF_Attr(@) delete ($defs{$hash->{NAME}}{READINGS}{cmd_count}); } elsif($a[0] eq "del" && $a[2] eq "waitsame") { delete ($defs{$hash->{NAME}}{READINGS}{waitsame}); + } elsif($a[0] eq "set" && $a[2] eq "DOIF_Readings") { + my ($def,$err)=addDOIF_Readings($hash,$a[3]); + if ($err) { + return ("error in DOIF_Readings $def, $err"); + } + } elsif($a[0] eq "del" && ($a[2] eq "DOIF_Readings")) { + delete ($hash->{DOIF_Readings}); + delete $hash->{Regex}{"DOIF_Readings"} + } elsif($a[0] eq "set" && ($a[2] eq "uiTable" || $a[2] eq "uiState")) { + if ($init_done) { + my $err=DOIF_uiTable_def($hash,$a[3],$a[2]); + return $err if ($err); + DOIF_reloadFW; + # InternalTimer(gettimeofday()+2,"DOIF_reloadFW",$hash) if($a[3]=~/\$ATTRIBUTESFIRST *= *2/); + } + } elsif($a[0] eq "del" && ($a[2] eq "uiTable" || $a[2] eq "uiState")) { + #my $table=$a[2]; + delete ($hash->{Regex}{$a[2]}); + delete ($hash->{$a[2]}); } return undef; } @@ -2423,7 +3048,7 @@ Many examples with english identifiers - see

DOIF

+ +Perl-Funktionen +