2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-05-04 20:17:45 +00:00

95_Alarm.pm: Neue Version mit erweiterten Möglichkeiten

95_YAAHM.pm: Neue Version mit verbesserten Timer-Funktionen

git-svn-id: https://svn.fhem.de/fhem/trunk@17344 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
phenning 2018-09-14 14:05:23 +00:00
parent 5a7ac8672e
commit 30694f05c0
3 changed files with 270 additions and 180 deletions

View File

@ -43,13 +43,15 @@ my $alarmlinkname = "Alarms"; # link text
my $alarmhiddenroom = "AlarmRoom"; # hidden room my $alarmhiddenroom = "AlarmRoom"; # hidden room
my $alarmpublicroom = "Alarm"; # public room my $alarmpublicroom = "Alarm"; # public room
my $alarmno = 8; my $alarmno = 8;
my $alarmversion = "4.05"; my $alarmversion = "5.0";
my %alarm_transtable_EN = ( my %alarm_transtable_EN = (
"ok" => "OK", "ok" => "OK",
"notok" => "Not OK", "notok" => "Not OK",
"cond" => "Condition",
"start" => "Start", "start" => "Start",
"end" => "End", "end" => "End",
"autocan" => "AutoCancel",
"status" => "Status", "status" => "Status",
"notstarted" => "Not started", "notstarted" => "Not started",
"next" => "Next", "next" => "Next",
@ -101,9 +103,11 @@ my %alarm_transtable_EN = (
my %alarm_transtable_DE = ( my %alarm_transtable_DE = (
"ok" => "OK", "ok" => "OK",
"notok" => "Nicht OK", "notok" => "Nicht OK",
"cond" => "Bedingung",
"start" => "Start", "start" => "Start",
"end" => "Ende", "end" => "Ende",
"autocan" => "AutoWiderruf",
"status" => "Status", "status" => "Status",
"notstarted" => "Nicht gestartet", "notstarted" => "Nicht gestartet",
"next" => "Nächste", "next" => "Nächste",
@ -174,7 +178,7 @@ sub Alarm_Initialize ($) {
my $attst = "lockstate:locked,unlocked testbutton:0,1 statedisplay:simple,color,table,none noicons iconmap disarmcolor ". my $attst = "lockstate:locked,unlocked testbutton:0,1 statedisplay:simple,color,table,none noicons iconmap disarmcolor ".
"armwaitcolor armcolor alarmcolor armdelay armwait armact disarmact cancelact"; "armwaitcolor armcolor alarmcolor armdelay armwait armact disarmact cancelact";
for( my $level=0;$level<$alarmno;$level++ ){ for( my $level=0;$level<$alarmno;$level++ ){
$attst .=" level".$level."start level".$level."end level".$level."msg level".$level."xec level".$level."onact level".$level."offact "; $attst .=" level".$level."cond level".$level."start level".$level."end level".$level."autocan level".$level."msg level".$level."onact level".$level."offact ";
} }
$hash->{AttrList} = $attst; $hash->{AttrList} = $attst;
@ -198,6 +202,7 @@ sub Alarm_Initialize ($) {
return undef; return undef;
} }
######################################################################################### #########################################################################################
# #
# Alarm_Define - Implements DefFn function # Alarm_Define - Implements DefFn function
@ -253,23 +258,6 @@ sub Alarm_Define ($$) {
return; return;
} }
sub Alarm_transform($){
my ($hash) = @_;
Log 1,"[Alarm] transforming old data format into new one";
my $md = 0;
for( my $i=0;$i<$alarmno;$i++){
if( defined(AttrVal($hash->{NAME},"level".$i."xec",undef)) ){
$md = 1;
$hash->{DATA}{"armstate"}{"level".$i} = AttrVal($hash->{NAME},"level".$i."xec","");
fhem("deleteattr ".$hash->{NAME}." level".$i."xec");
}
}
Alarm_save($hash)
if( $md==1 );
}
######################################################################################### #########################################################################################
# #
# Alarm_Undef - Implements Undef function # Alarm_Undef - Implements Undef function
@ -451,6 +439,11 @@ sub Alarm_getsettings($$$){
if( $aval[0] eq "" || $aval[1] eq "" ){ if( $aval[0] eq "" || $aval[1] eq "" ){
Log3 $hash, 1, "[Alarm] Settings $avl incomplete for alarmActor $dev"; Log3 $hash, 1, "[Alarm] Settings $avl incomplete for alarmActor $dev";
} }
#-- check if empty unset action
if( !defined($aval[3]) ){
$aval[3] = $aval[2];
$aval[2] = "";
}
#-- check delay time #-- check delay time
if( $aval[3] =~ /^\d+$/ ){ if( $aval[3] =~ /^\d+$/ ){
if( $aval[3] > 3559 ){ if( $aval[3] > 3559 ){
@ -608,29 +601,51 @@ sub Alarm_Exec($$$$$){
if( $act eq "on" ){ if( $act eq "on" ){
#-- only if this level is armed and not yet active #-- only if this level is armed and not yet active
if( ($xec eq "armed") && ($xac eq "armed") ){ if( ($xec eq "armed") && ($xac eq "armed") ){
#-- check for condition
my $cond = AttrVal($name, "level".$level."cond", 1);
$cond =~ s/\$NAME/$dev/g;
if( eval($cond) ne "1" ){
Log3 $hash,1,"[Alarm $level] Cannot be executed due to condition {$cond} not equal to 1 for level".$level."cond";
return;
}
#-- check for time #-- check for time
my $start = AttrVal($name, "level".$level."start", 0); my $start = AttrVal($name, "level".$level."start", "0:00");
if( index($start, '{') != -1){ if( index($start, '{') != -1){
$start = eval($start); $start = eval($start);
} }
my @st = split(':',$start); my @st = split(':',$start);
if( (int(@st)>3) || (int(@st)<2) || ($st[0] > 23) || ($st[0] < 0) || ($st[1] > 59) || ($st[1] < 0) ){ if( (int(@st)>3) || (int(@st)<2) || ($st[0] > 23) || ($st[0] < 0) || ($st[1] > 59) || ($st[1] < 0) ){
Log3 $hash,1,"[Alarm $level] Cannot be executed due to wrong time spec $start for level".$level."start"; Log3 $hash,1,"[Alarm $level] Cannot be executed due to wrong time spec $start for level".$level."start";
return; return;
} }
my $end = AttrVal($name, "level".$level."end", 0); my $end = AttrVal($name, "level".$level."end", "23:59");
if( index($end, '{') != -1){ if( index($end, '{') != -1){
$end = eval($end); $end = eval($end);
} }
my @et = split(':',$end); my @et = split(':',$end);
if( (int(@et)>3) || (int(@et)<2) || ($et[0] > 23) || ($et[0] < 0) || ($et[1] > 59) || ($et[1] < 0) ){ if( (int(@et)>3) || (int(@et)<2) || ($et[0] > 23) || ($et[0] < 0) || ($et[1] > 59) || ($et[1] < 0) ){
Log3 $hash,1,"[Alarm $level] Cannot be executed due to wrong time spec $end for level".$level."end"; Log3 $hash,1,"[Alarm $level] Cannot be executed due to wrong time spec $end for level".$level."end";
return; return;
} }
my $dur = AttrVal($name, "level".$level."autocan", "0:00");
if( index($dur, '{') != -1){
$dur = eval($dur);
}
my @dt = split(':',$dur);
if( (int(@dt)>3) || (int(@dt)<2) || ($dt[0] > 23) || ($dt[0] < 0) || ($dt[1] > 59) || ($dt[1] < 0) ){
Log3 $hash,1,"[Alarm $level] Cannot be executed due to wrong time spec $dur for level".$level."autocan";
return;
}
my $stp = $st[0]*60+$st[1]; my $stp = $st[0]*60+$st[1];
my $etp = $et[0]*60+$et[1]; my $etp = $et[0]*60+$et[1];
my $dtp = $dt[0]*60+$dt[1];
my ($sec, $min, $hour, $day, $month, $year, $wday, $yday, $isdst) = localtime(time); my ($sec, $min, $hour, $day, $month, $year, $wday, $yday, $isdst) = localtime(time);
my $ntp = $hour*60+$min; my $ntp = $hour*60+$min;
@ -659,6 +674,15 @@ sub Alarm_Exec($$$$$){
$msg = Alarm_getstate($hash)." ".$mga; $msg = Alarm_getstate($hash)." ".$mga;
readingsSingleUpdate( $hash, "state", $msg, 1 ); readingsSingleUpdate( $hash, "state", $msg, 1 );
$msg = "[Alarm $level] raised from device $dev with event $evt"; $msg = "[Alarm $level] raised from device $dev with event $evt";
#-- set up timer for auto cancel
if( $dur ne "0:00" ){
my $cmd = "alarm".$level.".autocancel at +$dur {Alarm_Exec('$name',$level,'".$alarm_tt->{"autocan"}."','dummy','off')}";
CommandDefine(undef,$cmd);
CommandAttr (undef,'alarm'.$level.'.autocancel room '.$alarmpublicroom);
CommandAttr (undef,'alarm'.$level.'.autocancel group alarmHelper');
}
#-- calling actors AFTER state update #-- calling actors AFTER state update
$cmd = AttrVal($name, "level".$level."onact", 0); $cmd = AttrVal($name, "level".$level."onact", 0);
$cmd =~ s/\$NAME/$dev/g; $cmd =~ s/\$NAME/$dev/g;
@ -686,6 +710,7 @@ sub Alarm_Exec($$$$$){
if( ($xac ne "armed")&&($xac ne "disarmed") ){ if( ($xac ne "armed")&&($xac ne "disarmed") ){
#-- TODO: ohne intAt auskommen #-- TODO: ohne intAt auskommen
#-- deleting all running ats #-- deleting all running ats
CommandDelete(undef,'alarm'.$level.'.autocancel');
$dly = sprintf("alarm%1ddly",$level); $dly = sprintf("alarm%1ddly",$level);
foreach my $d ( devspec2array("NAME=alarm.dly.*")) { foreach my $d ( devspec2array("NAME=alarm.dly.*")) {
Log3 $hash,1,"[Alarm] Killing delayed action $d"; Log3 $hash,1,"[Alarm] Killing delayed action $d";
@ -834,9 +859,6 @@ sub Alarm_CreateNotifiers($){
return "State locked, cannot create new notifiers"; return "State locked, cannot create new notifiers";
} }
#-- temporary code: transferm from attributes to hash
#Alarm_transform($hash);
for( my $level=0;$level<$alarmno;$level++ ){ for( my $level=0;$level<$alarmno;$level++ ){
#-- delete old defs in any case #-- delete old defs in any case
@ -1198,6 +1220,7 @@ sub Alarm_widget($){
} }
} }
######################################################################################### #########################################################################################
# #
# Alarm_Html - returns HTML code for the Alarm page # Alarm_Html - returns HTML code for the Alarm page
@ -1206,8 +1229,7 @@ sub Alarm_widget($){
# #
######################################################################################### #########################################################################################
sub Alarm_Html($) sub Alarm_Html($){
{
my ($name) = @_; my ($name) = @_;
my $ret = ""; my $ret = "";
@ -1333,28 +1355,38 @@ sub Alarm_Html($)
$ret .= "</td><td></td></tr><tr class=\"odd\"><td class=\"col1\" style=\"text-align:right\">".$alarm_tt->{"cancelbutton"}."&nbsp;&#8608;</td><td class=\"col2\" style=\"text-align:right\"> ".$alarm_tt->{"cancelaction"}." "; $ret .= "</td><td></td></tr><tr class=\"odd\"><td class=\"col1\" style=\"text-align:right\">".$alarm_tt->{"cancelbutton"}."&nbsp;&#8608;</td><td class=\"col2\" style=\"text-align:right\"> ".$alarm_tt->{"cancelaction"}." ";
$ret .= sprintf("<input type=\"text\" id=\"cancelaction\" size=\"50\" maxlength=\"512\" value=\"%s\"/>",(AttrVal($name, "cancelact","") eq "1")?"":AttrVal($name, "cancelact","")); $ret .= sprintf("<input type=\"text\" id=\"cancelaction\" size=\"50\" maxlength=\"512\" value=\"%s\"/>",(AttrVal($name, "cancelact","") eq "1")?"":AttrVal($name, "cancelact",""));
$ret .= "</td><td></td></tr></table></td></tr>"; $ret .= "</td><td></td></tr></table></td></tr>";
$ret .= "<tr class=\"odd\"><td class=\"col1\">".$alarm_tt->{"level"}."</td><td class=\"col2\">".$alarm_tt->{"time"}." [hh:mm]<br/>". $ret .= "<tr class=\"odd\"><td colspan=\"3\"style=\"padding:20px 0 20px 0;\"><table><tr><td></td><td></td><td class=\"col2\" colspan=\"3\">".$alarm_tt->{"time"}." [hh:mm]<td/></tr>".
$alarm_tt->{"start"}."&nbsp;&nbsp;&nbsp;&nbsp;".$alarm_tt->{"end"}."&nbsp;</td><td class=\"col3\">".$alarm_tt->{"messagepart"}." II</td>". "<tr><td class=\"col1\" style=\"padding:0 10px 0 10px;\">".$alarm_tt->{"level"}."</td><td class=\"col2\" style=\"padding:0 10px 0 10px;\">".$alarm_tt->{"cond"}.
"<td class=\"col4\">".$alarm_tt->{"arm"}."/".$alarm_tt->{"cancel"}."</td></tr>\n"; "</td><td class=\"col2\" style=\"padding:0 10px 0 10px;\">".$alarm_tt->{"start"}."</td><td class=\"col2\" style=\"padding:0 10px 0 10px;\">".$alarm_tt->{"end"}.
"</td><td class=\"col2\" style=\"padding:0 10px 0 15px;\">".$alarm_tt->{"autocan"}.
"</td><td class=\"col3\" style=\"padding:0 10px 0 10px;\">".$alarm_tt->{"messagepart"}." II</td>".
"<td class=\"col4\"style=\"padding:0 10px 0 10px;\">".$alarm_tt->{"arm"}."</td><td class=\"col4\">".$alarm_tt->{"cancel"}."</td></tr>\n";
#-- foreach level
for( my $k=0;$k<$alarmno;$k++ ){ for( my $k=0;$k<$alarmno;$k++ ){
$row++; $row++;
my $sval = AttrVal($name, "level".$k."start", 0); my $cval = AttrVal($name, "level".$k."cond", 1);
my $sval = AttrVal($name, "level".$k."start", "0:00");
$sval = "" $sval = ""
if( $sval eq "1"); if( $sval eq "1");
my $eval = AttrVal($name, "level".$k."end", 0); my $eval = AttrVal($name, "level".$k."end", "23:59");
$eval = "" $eval = ""
if( $eval eq "1"); if( $eval eq "1");
my $mval = AttrVal($name, "level".$k."msg", 0); my $oval = AttrVal($name, "level".$k."autocan", "0:00");
$oval = ""
if( $oval eq "1");
my $mval = AttrVal($name, "level".$k."msg", "--");
$mval = "" $mval = ""
if( $mval eq "1"); if( $mval eq "1");
my $xval = $hash->{DATA}{"armstate"}{"level".$k}; my $xval = $hash->{DATA}{"armstate"}{"level".$k};
$ret .= sprintf("<tr class=\"%s\"><td class=\"col1\">".$alarm_tt->{"alarm"}." $k</td>\n", ($row&1)?"odd":"even"); $ret .= sprintf("<tr class=\"%s\"><td class=\"col1\">".$alarm_tt->{"alarm"}." $k</td>\n", ($row&1)?"odd":"even");
$ret .= "<td class=\"col2\"><input type=\"text\" id=\"l".$k."s\" size=\"4\" maxlength=\"120\" value=\"$sval\"/>&nbsp;&nbsp;&nbsp;". $ret .= "<td class=\"col2\" style=\"padding:0 10px 0 10px;\"><input type=\"text\" id=\"l".$k."c\" size=\"15\" maxlength=\"512\" value=\"$cval\"/></td><td class=\"col2\">".
"<input type=\"text\" id=\"l".$k."e\" size=\"4\" maxlength=\"120\" value=\"$eval\"/></td>". "<input type=\"text\" id=\"l".$k."s\" size=\"4\" maxlength=\"120\" value=\"$sval\"/></td><td class=\"col2\">".
"<input type=\"text\" id=\"l".$k."e\" size=\"4\" maxlength=\"120\" value=\"$eval\"/></td><td class=\"col2\">".
"<input type=\"text\" id=\"l".$k."o\" size=\"4\" maxlength=\"120\" value=\"$oval\"/></td>".
"<td class=\"col3\"><input type=\"text\" id=\"l".$k."m\" size=\"25\" maxlength=\"256\" value=\"$mval\"/></td>"; "<td class=\"col3\"><input type=\"text\" id=\"l".$k."m\" size=\"25\" maxlength=\"256\" value=\"$mval\"/></td>";
$ret .= sprintf("<td class=\"col4\"><input type=\"checkbox\" id=\"l".$k."x\" %s onclick=\"javascript:alarm_arm('$name','$k')\"/>",($xval eq "armed")?"checked=\"checked\"":""). $ret .= sprintf("<td class=\"col4\" width=\"30px\" align=\"center\"><input type=\"checkbox\" id=\"l".$k."x\" %s onclick=\"javascript:alarm_arm('$name','$k')\"/>",($xval eq "armed")?"checked=\"checked\"":"").
"<input type=\"button\" value=\"".$alarm_tt->{"cancel"}."\" onclick=\"javascript:alarm_cancel('$name','$k')\"/></td></tr>\n"; "</td><td class=\"col4\"><input type=\"button\" value=\"".$alarm_tt->{"cancel"}."\" onclick=\"javascript:alarm_cancel('$name','$k')\"/></td></tr>\n";
} }
$ret .= "</table></td></tr>"; $ret .= "</table></td></tr>";
@ -1428,7 +1460,7 @@ sub Alarm_Html($)
if( AttrVal($name,"testbutton",0) == 1); if( AttrVal($name,"testbutton",0) == 1);
$ret .= "</td><td class=\"col4\"><input type=\"text\" name=\"delay\" size=\"5\" maxlength=\"8\" value=\"$aval[3]\"/></td></tr>\n"; $ret .= "</td><td class=\"col4\"><input type=\"text\" name=\"delay\" size=\"5\" maxlength=\"8\" value=\"$aval[3]\"/></td></tr>\n";
} }
} }
$ret .= "</table></td></tr>\n"; $ret .= "</table></td></tr>\n";
$ret .= "</table>"; $ret .= "</table>";
@ -1516,8 +1548,7 @@ sub Alarm_Html($)
<li> simple = OXOOOOO</li> <li> simple = OXOOOOO</li>
<li> color = <span style="color:lightgray"> 0 </span><span style="font-weight:bold;color:#53f3c7">1 <span style="font-weight:bold;color:#fd5777" <li> color = <span style="color:lightgray"> 0 </span><span style="font-weight:bold;color:#53f3c7">1 <span style="font-weight:bold;color:#fd5777"
>2</span> 3 4 5 6 7</span></li> >2</span> 3 4 5 6 7</span></li>
<li> table = HTML mini table with colored fields for alarms <li> table = HTML mini table with colored fields for alarms</li>
</li>
<li> none = no state display</li> <li> none = no state display</li>
</ul> </ul>
</li> </li>
@ -1535,14 +1566,14 @@ sub Alarm_Html($)
<li><a name="alarm_armwait"><code>attr &lt;name&gt; armwait <i>action</i></code></a> <li><a name="alarm_armwait"><code>attr &lt;name&gt; armwait <i>action</i></code></a>
<br />FHEM action to be carried out immediately after the arm event</li> <br />FHEM action to be carried out immediately after the arm event</li>
<li><a name="alarm_armact"><code>attr &lt;name&gt; armact <i>action</i></code></a> <li><a name="alarm_armact"><code>attr &lt;name&gt; armact <i>action</i></code></a>
<br />FHEM action to be carried out at the arme event after the delay time </li> <br />FHEM action to be carried out at the arm event after the delay time </li>
<li><a name="alarm_disarmact"><code>attr &lt;name&gt; disarmact <i>action</i></code></a> <li><a name="alarm_disarmact"><code>attr &lt;name&gt; disarmact <i>action</i></code></a>
<br />FHEM action to be carried out on the disarming of an alarm</li> <br />FHEM action to be carried out on the disarming of an alarm</li>
<li><a name="alarm_cancelact"><code>attr &lt;name&gt; cancelact <i>action</i></code></a> <li><a name="alarm_cancelact"><code>attr &lt;name&gt; cancelact <i>action</i></code></a>
<br />FHEM action to be carried out on the canceling of an alarm</li> <br />FHEM action to be carried out on the canceling of an alarm</li>
<li><a name="alarm_internals"></a>For each of the 8 alarm levels, several attributes <li><a name="alarm_internals"></a>For each of the 8 alarm levels, several attributes
hold the alarm setup. They should not be changed by hand, but through the web hold the alarm setup. They should not be changed by hand, but through the web
interface to avoid confusion: <code>level&lt;level&gt;start, level&lt;level&gt;end, interface to avoid confusion: <code>level&lt;level&gt;cond, level&lt;level&gt;start, level&lt;level&gt;end, level&lt;level&gt;autocan,
level&lt;level&gt;msg, level&lt;level&gt;onact, level&lt;level&gt;msg, level&lt;level&gt;onact,
level&lt;level&gt;offact</code></li> level&lt;level&gt;offact</code></li>
<li>Standard attributes <a href="#alias">alias</a>, <a href="#comment">comment</a>, <a <li>Standard attributes <a href="#alias">alias</a>, <a href="#comment">comment</a>, <a

View File

@ -47,7 +47,7 @@ my $yaahmname;
my $yaahmlinkname = "Profile"; # link text my $yaahmlinkname = "Profile"; # link text
my $yaahmhiddenroom = "ProfileRoom"; # hidden room my $yaahmhiddenroom = "ProfileRoom"; # hidden room
my $yaahmpublicroom = "Unsorted"; # public room my $yaahmpublicroom = "Unsorted"; # public room
my $yaahmversion = "1.54"; my $yaahmversion = "2.0";
my $firstcall = 1; my $firstcall = 1;
my %yaahm_transtable_EN = ( my %yaahm_transtable_EN = (
@ -353,7 +353,7 @@ sub YAAHM_Initialize ($) {
$hash->{GetFn} = "YAAHM_Get"; $hash->{GetFn} = "YAAHM_Get";
$hash->{UndefFn} = "YAAHM_Undef"; $hash->{UndefFn} = "YAAHM_Undef";
$hash->{AttrFn} = "YAAHM_Attr"; $hash->{AttrFn} = "YAAHM_Attr";
my $attst = "linkname publicroom hiddenroom lockstate:locked,unlocked simulation:0,1 ". my $attst = "linkname publicroom hiddenroom lockstate:locked,unlocked simulation:0,1 norepeat:0,1 ".
"modecolor0 modecolor1 modecolor2 modecolor3 statecolor0 statecolor1 statecolor2 statecolor3 ". "modecolor0 modecolor1 modecolor2 modecolor3 statecolor0 statecolor1 statecolor2 statecolor3 ".
"timeHelper modeHelper modeAuto:0,1 stateDevices:textField-long stateInterval noicons:0,1 stateWarning stateHelper stateAuto:0,1 ". "timeHelper modeHelper modeAuto:0,1 stateDevices:textField-long stateInterval noicons:0,1 stateWarning stateHelper stateAuto:0,1 ".
"holidayDevices:textField-long vacationDevices:textField-long specialDevices:textField-long"; "holidayDevices:textField-long vacationDevices:textField-long specialDevices:textField-long";
@ -450,6 +450,10 @@ sub YAAHM_Define ($$) {
$hash->{DATA}{"DD"} = (); $hash->{DATA}{"DD"} = ();
push(@{$hash->{DATA}{"DD"}},{%defaultdayproperties}); push(@{$hash->{DATA}{"DD"}},{%defaultdayproperties});
push(@{$hash->{DATA}{"DD"}},{%defaultdayproperties}); push(@{$hash->{DATA}{"DD"}},{%defaultdayproperties});
#-- initial mode and state
$hash->{DATA}{"HSM"}{"state"}="unsecured";
$hash->{DATA}{"HSM"}{"mode"}="normal";
} }
#-- determine Astro device #-- determine Astro device
@ -1123,73 +1127,90 @@ sub YAAHM_time {
my $lval = sprintf("%02d%02d",$hour,$min); my $lval = sprintf("%02d%02d",$hour,$min);
my $mval = $dailytable{"morning"}[0]; my $mval = $dailytable{"morning"}[0];
my $nval = $dailytable{"night"}[0]; my $nval = $dailytable{"night"}[0];
my $tval = $dailytable{$targettime}[0];
$mval =~ s/://;
$nval =~ s/://;
$tval =~ s/://;
#-- targetphase always according to real time, not to command time
my $targetphase = ( ($lval >= $mval) && ( $nval > $lval ) ) ? "daytime" : "nighttime";
#-- iterate through table to find next event
my $nexttime;
my $sval;
my $oval="0000";
foreach my $key (sort YAAHM_dsort keys %dailytable){
$nexttime = $key;
$sval = $dailytable{$key}[0];
next
if (!defined($sval));
$sval =~ s/://;
last
if ( ($lval <= $sval) && ( $lval > $oval ) );
$oval = $sval;
}
my $ma = defined($attr{$name}{"modeAuto"}) && ($attr{$name}{"modeAuto"} == 1);
my $sa = defined($attr{$name}{"stateAuto"}) && ($attr{$name}{"stateAuto"} == 1);
#Log 1,"===================> YAAHM Fehlersuche ma,sa = $ma,$sa exec=$exec";
#-- automatically leave party mode at morning time or when going to bed
# TODO
# TODO Fehler ! Wird nach party um Mitternacht aufgerufen und sichert das Haus, aber in jeder Zeile ein fehler undefined
if( $currmode eq "party" && $targettime =~ /(morning)|(sleep)/ && $ma ){
$msg = YAAHM_mode($name,"normal",$exec)."\n";
$msg .= YAAHM_state($name,"secured",$exec)."\n"
if( $currstate eq "unsecured" && $targettime eq "sleep" && $sa );
#-- automatically leave absence mode at wakeup time
# Ist das wirklich clever ? Was passiert, wenn der Wecker nicht ausgestellt wurde
}elsif( $currmode eq "absence" && $targettime =~ /(wakeup)/ && $ma ){
$msg = YAAHM_mode($name,"normal",$exec)."\n";
#-- automatically leave donotdisturb mode at any time event
}elsif( $currmode eq "donotdisturb" && $ma ){
$msg = YAAHM_mode($name,"normal",$exec)."\n";
#-- automatically secure the house at night time or when going to bed (if not absence, and if not party)
}elsif( $currmode eq "normal" && $currstate eq "unsecured" && $targettime =~ /(night)|(sleep)/ && $sa ){
$msg = YAAHM_state($name,"secured",$exec)."\n";
}
$hash->{DATA}{"HSM"}{"time"} = $targettime;
YAAHM_checkMonthly($hash,'event',$targettime);
readingsBeginUpdate($hash); readingsBeginUpdate($hash);
readingsBulkUpdate($hash,"prev_housetime",$prevtime); #-- is this a daily timer event ?
readingsBulkUpdate($hash,"next_housetime",$nexttime); my $regex = "((".join(")|(",@times)."))";
readingsBulkUpdate($hash,"housetime",$targettime); my $isdaily = ( $targettime =~ /$regex/ )?1:0;
readingsBulkUpdate($hash,"tr_housetime",$yaahm_tt->{$targettime}); if( $isdaily ){
readingsBulkUpdate($hash,"housephase",$targetphase); my $tval = $dailytable{$targettime}[0];
readingsBulkUpdate($hash,"tr_housephase",$yaahm_tt->{$targetphase});
$mval =~ s/://;
$nval =~ s/://;
$tval =~ s/://;
#-- targetphase always according to real time, not to command time
my $targetphase = ( ($lval >= $mval) && ( $nval > $lval ) ) ? "daytime" : "nighttime";
#-- iterate through table to find next event
my $nexttime;
my $sval;
my $oval="0000";
foreach my $key (sort YAAHM_dsort keys %dailytable){
$nexttime = $key;
$sval = $dailytable{$key}[0];
next
if (!defined($sval));
$sval =~ s/://;
last
if ( ($lval <= $sval) && ( $lval > $oval ) );
$oval = $sval;
}
my $ma = defined($attr{$name}{"modeAuto"}) && ($attr{$name}{"modeAuto"} == 1);
my $sa = defined($attr{$name}{"stateAuto"}) && ($attr{$name}{"stateAuto"} == 1);
#-- automatically leave party mode at morning time or when going to bed
# TODO
# TODO Fehler ! Wird nach party um Mitternacht aufgerufen und sichert das Haus, aber in jeder Zeile ein fehler undefined
if( $currmode eq "party" && $targettime =~ /(morning)|(sleep)/ && $ma ){
Log3 $name, 1,"[YAAHM_time] Leaving party mode because modeAuto=1";
$msg = YAAHM_mode($name,"normal",$exec)."\n";
if( $currstate eq "unsecured" && $targettime eq "sleep" && $sa ){
Log3 $name, 1,"[YAAHM_time] Securing the house because stateAuto=1";
$msg .= YAAHM_state($name,"secured",$exec)."\n"
};
#-- automatically leave absence mode at wakeup time
# Ist das wirklich clever ? Was passiert, wenn der Wecker nicht ausgestellt wurde
}elsif( $currmode eq "absence" && $targettime =~ /(wakeup)/ && $ma ){
Log3 $name, 1,"[YAAHM_time] Leaving absence mode because modeAuto=1";
$msg = YAAHM_mode($name,"normal",$exec)."\n";
#-- automatically leave donotdisturb mode at any time event
}elsif( $currmode eq "donotdisturb" && $ma ){
Log3 $name, 1,"[YAAHM_time] Leaving donotdisturb mode because modeAuto=1";
$msg = YAAHM_mode($name,"normal",$exec)."\n";
#-- automatically secure the house at night time or when going to bed (if not absence, and if not party)
}elsif( $currmode eq "normal" && $currstate eq "unsecured" && $targettime =~ /(night)|(sleep)/ && $sa ){
Log3 $name, 1,"[YAAHM_time] Securing the house because stateAuto=1";
$msg = YAAHM_state($name,"secured",$exec)."\n";
}
$hash->{DATA}{"HSM"}{"time"} = $targettime;
YAAHM_checkMonthly($hash,'event',$targettime);
readingsBulkUpdate($hash,"prev_housetime",$prevtime);
readingsBulkUpdate($hash,"next_housetime",$nexttime);
readingsBulkUpdate($hash,"housetime",$targettime);
readingsBulkUpdate($hash,"tr_housetime",$yaahm_tt->{$targettime});
readingsBulkUpdate($hash,"housephase",$targetphase);
readingsBulkUpdate($hash,"tr_housephase",$yaahm_tt->{$targetphase});
}
#-- before fixing new times
# if manual wake/sleep/timer, the time for the current day needs to be set to empty,
# but second execution on the same day is blocked if attribute norepeat is set.
if( $targettime eq "wakeup" ){ if( $targettime eq "wakeup" ){
$hash->{DATA}{"WT"}[0]{"next"} = ""; $hash->{DATA}{"WT"}[0]{"next"} = "";
readingsBulkUpdate($hash,"next_0",""); readingsBulkUpdate($hash,"next_0","");
}elsif( $targettime eq "sleep" ){ }elsif( $targettime eq "sleep" ){
$hash->{DATA}{"WT"}[1]{"next"} = ""; $hash->{DATA}{"WT"}[1]{"next"} = "";
readingsBulkUpdate($hash,"next_1",""); readingsBulkUpdate($hash,"next_1","");
}elsif( $targettime =~ /timer_(\d+)/ ){
my $i = $1;
$hash->{DATA}{"WT"}[$i]{"next"} = "";
readingsBulkUpdate($hash,"next_".$i,"");
} }
readingsEndUpdate($hash,1); readingsEndUpdate($hash,1);
YAAHM_setWeeklyTime($hash); YAAHM_setWeeklyTime($hash);
@ -1203,31 +1224,52 @@ sub YAAHM_time {
my $ival; my $ival;
my $wupn; my $wupn;
#-- todo here: what should we do, if the timer is NOT enabled and we get up or go to bed anyhow ??? #-- after fixing new time
if( $targettime eq "wakeup" ){ #-- TODO here: what should we do, if the timer is NOT enabled and we get up or go to bed anyhow ???
$wupn = $hash->{DATA}{"WT"}[0]{"name"}; if( $targettime =~ /((wakeup)|(sleep)|(timer_(\d+)))/ ){
$ival = (ReadingsVal($name.".wtimer_0.IF","mode","") ne "disabled"); my $timerno="";
$xval = $ival ? $hash->{DATA}{"WT"}[0]{"action"} : ""; if( $targettime eq "wakeup" ){
$msg .= "Simulation ".$xval." from weekly profile ".$wupn; $timerno=0;
$msg .= " (disabled)" }elsif( $targettime eq "sleep" ){
if !$ival; $timerno=1;
}elsif( $targettime eq "sleep" ){ }elsif( $targettime =~ /timer_(\d+)/ ){
$wupn = $hash->{DATA}{"WT"}[1]{"name"}; $timerno = $1;
$ival = (ReadingsVal($name.".wtimer_1.IF","mode","") ne "disabled"); }
$xval = $ival ? $hash->{DATA}{"WT"}[1]{"action"} : ""; $wupn = $hash->{DATA}{"WT"}[$timerno]{"name"};
$msg .= "Simulation ".$xval." from weekly profile ".$wupn; $ival = (ReadingsVal($name.".wtimer_".$timerno.".IF","mode","") ne "disabled");
$msg .= " (disabled)" $xval = $ival ? $hash->{DATA}{"WT"}[$timerno]{"action"} : "";
if !$ival; my $norep = AttrVal($name,"norepeat",0);
if( $exec==1 ){
if( $hash->{DATA}{"WT"}[$timerno]{"done"} && $norep ){
$msg = "Not executing action for timer $targettime, already done";
Log3 $name,3,"[YAAHM_time] ".$msg;
return $msg;
}else{
Log3 $name,1,"[YAAHM_time] executing action $xval for timer $targettime";
fhem($xval);
$hash->{DATA}{"WT"}[$timerno]{"done"} = 1;
return;
}
}elsif( $exec==0 ){
$msg .= "Simulation ".$xval." from timer ".$targettime;
$msg .= " (disabled)"
if !$ival;
Log3 $name,1,"[YAAHM_time] ".$msg;
return $msg;
}
#-- any other
}else{ }else{
$xval = $dailytable{$targettime}[2]; $xval = $dailytable{$targettime}[2];
$msg .= "Simulation ".$xval; $msg = "Simulation ".$xval;
} if( $exec==1 ){
if( $exec==1 ){ Log3 $name,1,"[YAAHM_time] ecxecuting $xval";
Log3 $name,1,"[YAAHM_time] ecxecuting $xval"; fhem($xval);
fhem($xval); return
}elsif( $exec==0 ){ }elsif( $exec==0 ){
Log3 $name,1,"[YAAHM_time] ".$msg; Log3 $name,1,"[YAAHM_time] ".$msg;
return $msg; return $msg;
}
} }
} }
@ -1281,6 +1323,7 @@ sub YAAHM_nextWeeklyTime {
#-- all logic in setweeklytime #-- all logic in setweeklytime
$hash->{DATA}{"WT"}[$i]{"next"} = $time; $hash->{DATA}{"WT"}[$i]{"next"} = $time;
$hash->{DATA}{"WT"}[$i]{"done"} = 0;
YAAHM_setWeeklyTime($hash); YAAHM_setWeeklyTime($hash);
} }
@ -1654,8 +1697,7 @@ sub YAAHM_startDayTimer($) {
my $f2 = defined($defaultdailytable{$key}[1]); my $f2 = defined($defaultdailytable{$key}[1]);
my $f3 = defined($hash->{DATA}{"DT"}{$key}[2]) && $hash->{DATA}{"DT"}{$key}[2] ne ""; my $f3 = defined($hash->{DATA}{"DT"}{$key}[2]) && $hash->{DATA}{"DT"}{$key}[2] ne "";
#-- uh oh, double execution of functions !!! Do this in YAAHM_time, NOT in timer #-- to prevent double execution of functions do this in YAAHM_time, NOT in timer
#my $xval = "{YAAHM_time('".$name."','".$key."')},".$hash->{DATA}{"DT"}{$key}[2];
my $xval = "{YAAHM_time('".$name."','".$key."',1)}"; my $xval = "{YAAHM_time('".$name."','".$key."',1)}";
#-- entries in the default table with no entry are single-timers #-- entries in the default table with no entry are single-timers
@ -1731,16 +1773,15 @@ sub YAAHM_startWeeklyTimer($) {
$res .= "\nand ([" .$name. ":housemode] =~ \"".$v4a."\")"; $res .= "\nand ([" .$name. ":housemode] =~ \"".$v4a."\")";
$res .= "\nand ([" .$name. ":todayType] =~ \"".$v4b."\")"; $res .= "\nand ([" .$name. ":todayType] =~ \"".$v4b."\")";
#-- action - explicitly in timer, not in YAAHM_time #-- to prevent double execution of functions do this in YAAHM_time, NOT in timer
my $xval = ""; my $xval;
if( $i==0 ){ if( $i==0 ){
$xval = "{YAAHM_time('".$name."','wakeup',0)},".$hash->{DATA}{"WT"}[$i]{"action"}; $xval = "{YAAHM_time('".$name."','wakeup',1)}";
}elsif( $i==1 ){ }elsif( $i==1 ){
$xval = "{YAAHM_time('".$name."','sleep',0)},".$hash->{DATA}{"WT"}[$i]{"action"}; $xval = "{YAAHM_time('".$name."','sleep',1)}";
}else{ }else{
$xval = $hash->{DATA}{"WT"}[$i]{"action"}; $xval = "{YAAHM_time('".$name."','timer_".$i."',1)}";
} }
#-- action #-- action
$res .= ")\n(".$xval.")"; $res .= ")\n(".$xval.")";
@ -1770,7 +1811,7 @@ sub YAAHM_setWeeklyTime($) {
my $name = $hash->{NAME}; my $name = $hash->{NAME};
#-- weekly profile times #-- weekly profile times
my ($sg0,$sg1,$sg0mod,$sg1mod,$sg0en,$sg1en,$ring_0,$ring_1,$ng); my ($sg0,$sg1,$ring_0x,$ring_1x,$ring_0e,$ring_1e,$ring_0,$ring_1,$ng);
#-- iterate over timers #-- iterate over timers
for( my $i=0;$i<int( @{$hash->{DATA}{"WT"}} );$i++){ for( my $i=0;$i<int( @{$hash->{DATA}{"WT"}} );$i++){
@ -1780,45 +1821,45 @@ sub YAAHM_setWeeklyTime($) {
if( ReadingsVal($name.".wtimer_".$i.".IF","mode","") eq "disabled" ){ if( ReadingsVal($name.".wtimer_".$i.".IF","mode","") eq "disabled" ){
$sg0 = "off"; $sg0 = "off";
$sg1 = "off"; $sg1 = "off";
$sg0en = "disabled (timer)"; $ring_0e = "disabled (timer)";
$sg1en = "disabled (timer)"; $ring_1e = "disabled (timer)";
#-- if the timer is enabled, we'll use its timing values #-- if the timer is enabled, we'll use its timing values
}else{ }else{
$sg0 = $hash->{DATA}{"WT"}[$i]{ $weeklytable[$hash->{DATA}{"DD"}[0]{"weekday"}] } ; $sg0 = $hash->{DATA}{"WT"}[$i]{ $weeklytable[$hash->{DATA}{"DD"}[0]{"weekday"}] } ;
$sg1 = $hash->{DATA}{"WT"}[$i]{ $weeklytable[$hash->{DATA}{"DD"}[1]{"weekday"}] }; $sg1 = $hash->{DATA}{"WT"}[$i]{ $weeklytable[$hash->{DATA}{"DD"}[1]{"weekday"}] };
$sg0en = "enabled"; $ring_0e = "enabled";
$sg1en = "enabled"; $ring_1e = "enabled";
#-- next higher priority for "off" is daytype #-- next higher priority for "off" is daytype
my $wupad = $hash->{DATA}{"WT"}[$i]{"acti_d"}.",workday,weekend"; my $wupad = $hash->{DATA}{"WT"}[$i]{"acti_d"}.",workday,weekend";
#-- start with tomorrow #-- start with tomorrow
if( index($wupad, $hash->{DATA}{"DD"}[1]{"daytype"}) == -1 ){ if( index($wupad, $hash->{DATA}{"DD"}[1]{"daytype"}) == -1 ){
$sg1mod = "off (".substr(ReadingsVal($name,"tr_tomorrowType",""),0,3).")"; $ring_1x = "off (".substr(ReadingsVal($name,"tr_tomorrowType",""),0,3).")";
$sg1en = "disabled (".ReadingsVal($name,"tomorrowType","").")"; $ring_1e = "disabled (".ReadingsVal($name,"tomorrowType","").")";
}elsif( ($hash->{DATA}{"DD"}[1]{"vacflag"} == 1 ) && index($wupad,"vacation") == -1 ){ }elsif( ($hash->{DATA}{"DD"}[1]{"vacflag"} == 1 ) && index($wupad,"vacation") == -1 ){
$sg1mod = "off (".substr($yaahm_tt->{"vacation"},0,3).")"; $ring_1x = "off (".substr($yaahm_tt->{"vacation"},0,3).")";
$sg1en = "disabled (vacation)"; $ring_1e = "disabled (vacation)";
}else{ }else{
$sg1mod = $sg1; $ring_1x = $sg1;
} }
#-- because today we might also have an influence of housemode #-- because today we might also have an influence of housemode
if( index($wupad, $hash->{DATA}{"DD"}[0]{"daytype"}) == -1 ){ if( index($wupad, $hash->{DATA}{"DD"}[0]{"daytype"}) == -1 ){
$sg0mod = "off (".substr(ReadingsVal($name,"tr_todayType",""),0,3).")"; $ring_0x = "off (".substr(ReadingsVal($name,"tr_todayType",""),0,3).")";
$sg0en = "disabled (".ReadingsVal($name,"todayType","").")"; $ring_0e = "disabled (".ReadingsVal($name,"todayType","").")";
}elsif( ($hash->{DATA}{"DD"}[0]{"vacflag"} == 1 ) && index($wupad,"vacation") == -1 ){ }elsif( ($hash->{DATA}{"DD"}[0]{"vacflag"} == 1 ) && index($wupad,"vacation") == -1 ){
$sg0mod = "off (".substr($yaahm_tt->{"vacation"},0,3).")"; $ring_0x = "off (".substr($yaahm_tt->{"vacation"},0,3).")";
$sg0en = "disabled (vacation)"; $ring_0e = "disabled (vacation)";
}else{ }else{
#-- next higher priority for "off" (only today !) is housemode #-- next higher priority for "off" (only today !) is housemode
my $wupam = $hash->{DATA}{"WT"}[$i]{"acti_m"}.",normal"; my $wupam = $hash->{DATA}{"WT"}[$i]{"acti_m"}.",normal";
if( index($wupam, ReadingsVal($name,"housemode","")) == -1 ){ if( index($wupam, ReadingsVal($name,"housemode","")) == -1 ){
$sg0mod = "off (".substr(ReadingsVal($name,"tr_housemode",""),0,3).")"; $ring_0x = "off (".substr(ReadingsVal($name,"tr_housemode",""),0,3).")";
$sg0en = "disabled (".ReadingsVal($name,"housemode","").")"; $ring_0e = "disabled (".ReadingsVal($name,"housemode","").")";
}else{ }else{
$sg0mod = $sg0; $ring_0x = $sg0;
} }
} }
} }
#Log 1,"====> AFTER INITIAL CHECK TIMER $i sg0=$sg0 sg0mod=$sg0mod sg1=$sg1 sg1mod=$sg1mod ng=$ng";
#-- no "next" time specification #-- no "next" time specification
if( !defined($ng) || $ng eq "" ){ if( !defined($ng) || $ng eq "" ){
$ring_0 = $sg0; $ring_0 = $sg0;
@ -1853,15 +1894,15 @@ sub YAAHM_setWeeklyTime($) {
}elsif( $nga eq "off" ){ }elsif( $nga eq "off" ){
#-- today's waketime not over => we mean today #-- today's waketime not over => we mean today
if( $tga ne "off" && ($tga > $lga)){ if( $tga ne "off" && ($tga > $lga)){
if( $sg0mod !~ /^off/ ){ if( $ring_0x !~ /^off/ ){
$sg0mod = "off (man)"; $ring_0x = "off (man)";
$ring_0 = "off"; $ring_0 = "off";
$ring_1 = $sg1; $ring_1 = $sg1;
} }
#-- today's waketime over => we mean tomorrow #-- today's waketime over => we mean tomorrow
}else{ }else{
if( $sg1mod !~ /^off/ ){ if( $ring_1x !~ /^off/ ){
$sg1mod = "off (man)"; $ring_1x = "off (man)";
$ring_0 = $sg0; $ring_0 = $sg0;
$ring_1 = "$sg1 (off)"; $ring_1 = "$sg1 (off)";
} }
@ -1872,39 +1913,39 @@ sub YAAHM_setWeeklyTime($) {
if( $nga > $lga ){ if( $nga > $lga ){
#-- the same as original waketime => restore ! (do we come here at all ?) #-- the same as original waketime => restore ! (do we come here at all ?)
#if( $ng eq $sg0 ){ #if( $ng eq $sg0 ){
# $sg0mod = $sg0; # $ring_0x = $sg0;
# $ring_0 = $sg0; # $ring_0 = $sg0;
# $ng = ""; # $ng = "";
# $hash->{DATA}{"WT"}[$i]{ "next" } = ""; # $hash->{DATA}{"WT"}[$i]{ "next" } = "";
#-- new manual waketime tomorrow #-- new manual waketime tomorrow
#}else{ #}else{
$sg0mod = "$ng (man)"; $ring_0x = "$ng (man)";
$ring_0 = $ng; $ring_0 = $ng;
#} #}
$ring_1 = $sg1; $ring_1 = $sg1;
#-- "next" before current time => we mean tomorrow #-- "next" before current time => we mean tomorrow
}else{ }else{
#-- the same as original waketime => restore ! (do we come here at all ?) #-- the same as original waketime => restore ! (do we come here at all ?)
#if( $ng eq $sg1 ){ #if( $ng eq $sg1 ){
# $sg0mod = $sg1; # $ring_0x = $sg1;
# $ring_1 = $sg1; # $ring_1 = $sg1;
# $ng = ""; # $ng = "";
# $hash->{DATA}{"WT"}[$i]{ "next" } = ""; # $hash->{DATA}{"WT"}[$i]{ "next" } = "";
#}else{ #}else{
$sg1mod = "$ng (man)"; $ring_1x = "$ng (man)";
$ring_1 = "$sg1 ($ng)"; $ring_1 = "$sg1 ($ng)";
#} #}
$ring_0 = $sg0; $ring_0 = $sg0;
} }
} }
} }
$hash->{DATA}{"WT"}[$i]{"ring_0"} = $ring_0; $hash->{DATA}{"WT"}[$i]{"ring_0"} = $ring_0;
$hash->{DATA}{"WT"}[$i]{"ring_1"} = $ring_1; $hash->{DATA}{"WT"}[$i]{"ring_1"} = $ring_1;
$hash->{DATA}{"WT"}[$i]{"ring_0x"} = $sg0mod; $hash->{DATA}{"WT"}[$i]{"ring_0x"} = $ring_0x;
$hash->{DATA}{"WT"}[$i]{"ring_1x"} = $sg1mod; $hash->{DATA}{"WT"}[$i]{"ring_1x"} = $ring_1x;
$hash->{DATA}{"WT"}[$i]{"ring_0e"} = $sg0en; $hash->{DATA}{"WT"}[$i]{"ring_0e"} = $ring_0e;
$hash->{DATA}{"WT"}[$i]{"ring_1e"} = $sg1en; $hash->{DATA}{"WT"}[$i]{"ring_1e"} = $ring_1e;
#Log 1,"====> AFTER FINAL CHECK TIMER $i sg0=$sg0 sg0mod=$sg0mod sg1=$sg1 sg1mod=$sg1mod ng=$ng"; #Log 1,"====> AFTER FINAL CHECK TIMER $i sg0=$sg0 ring_0x=$ring_0x sg1=$sg1 ring_1x=$ring_1x ng=$ng";
#Log 1," ".$hash->{DATA}{"WT"}[$i]{"ring_0x"}." ".$hash->{DATA}{"WT"}[$i]{"ring_1x"}; #Log 1," ".$hash->{DATA}{"WT"}[$i]{"ring_0x"}." ".$hash->{DATA}{"WT"}[$i]{"ring_1x"};
#-- notation: #-- notation:
# today_i is today's waketime of timer i # today_i is today's waketime of timer i
@ -1920,12 +1961,12 @@ sub YAAHM_setWeeklyTime($) {
readingsBeginUpdate($hash); readingsBeginUpdate($hash);
readingsBulkUpdate( $hash, "today_".$i,$sg0 ); readingsBulkUpdate( $hash, "today_".$i,$sg0 );
readingsBulkUpdate( $hash, "tomorrow_".$i,$sg1 ); readingsBulkUpdate( $hash, "tomorrow_".$i,$sg1 );
readingsBulkUpdate( $hash, "today_".$i."_e",$sg0en ); readingsBulkUpdate( $hash, "today_".$i."_e",$ring_0e );
readingsBulkUpdate( $hash, "tomorrow_".$i."_e",$sg1en ); readingsBulkUpdate( $hash, "tomorrow_".$i."_e",$ring_1e );
readingsBulkUpdate( $hash, "ring_".$i,$ring_0 ); readingsBulkUpdate( $hash, "ring_".$i,$ring_0 );
readingsBulkUpdate( $hash, "ring_".$i."_1",$ring_1 ); readingsBulkUpdate( $hash, "ring_".$i."_1",$ring_1 );
readingsBulkUpdate( $hash, "ring_".$i."x",$sg0mod ); readingsBulkUpdate( $hash, "ring_".$i."x",$ring_0x );
readingsBulkUpdate( $hash, "ring_".$i."_1x",$sg1mod ); readingsBulkUpdate( $hash, "ring_".$i."_1x",$ring_1x );
readingsBulkUpdate( $hash, "next_".$i,$ng ); readingsBulkUpdate( $hash, "next_".$i,$ng );
readingsEndUpdate($hash,1); readingsEndUpdate($hash,1);
@ -1937,7 +1978,9 @@ sub YAAHM_setWeeklyTime($) {
# #
# YAAHM_sayWeeklyTime - say the next weekly time # YAAHM_sayWeeklyTime - say the next weekly time
# #
# Parameter name = name of device addressed # Parameter hash = hash of YAAHM dvice
# timer = number of timer
# sp = 1 => output for speech device
# #
######################################################################################### #########################################################################################
@ -1945,13 +1988,13 @@ sub YAAHM_sayWeeklyTime($$$) {
my ($hash,$timer,$sp) = @_; my ($hash,$timer,$sp) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my ($tod,$tom,$ton,$hl,$ml,$tl,$ht,$mt,$tt,$tsay,$chg,$msg,$hw,$mw,$pt,$rea); my ($tod,$tom,$ton,$hl,$ml,$tl,$ht,$mt,$tt,$tsay,$chg,$msg,$hw,$mw,$pt,$rea,$done,$norep);
#--determine which timer (duplicate check when coming from set) #--determine which timer (duplicate check when coming from set)
if( $timer >= int( @{$hash->{DATA}{"WT"}}) ){ if( $timer >= int( @{$hash->{DATA}{"WT"}}) ){
$msg = "Error, timer number $timer does not exist, number musst be smaller than ".int( @{$hash->{DATA}{"WT"}}); $msg = "Error, timer number $timer does not exist, number musst be smaller than ".int( @{$hash->{DATA}{"WT"}});
Log3 $name,1,"[YAAHM_sayNextTime] ".$msg; Log3 $name,1,"[YAAHM_sayWeeklyTime] ".$msg;
return $msg; return $msg;
} }
@ -1961,6 +2004,8 @@ sub YAAHM_sayWeeklyTime($$$) {
#-- get timer values from readings, because these include vacation settings and special time #-- get timer values from readings, because these include vacation settings and special time
$tod = $hash->{DATA}{"WT"}[$timer]{"ring_0x"}; $tod = $hash->{DATA}{"WT"}[$timer]{"ring_0x"};
$tom = $hash->{DATA}{"WT"}[$timer]{"ring_1x"}; $tom = $hash->{DATA}{"WT"}[$timer]{"ring_1x"};
$done = $hash->{DATA}{"WT"}[$timer]{"done"};
$norep = AttrVal($name,"norepeat",0);
#-- current local time #-- current local time
($hl,$ml) = split(':',strftime('%H:%M', localtime(time))); ($hl,$ml) = split(':',strftime('%H:%M', localtime(time)));
@ -1968,11 +2013,13 @@ sub YAAHM_sayWeeklyTime($$$) {
#-- today off AND tomorrow any time or off => compare this time with current time #-- today off AND tomorrow any time or off => compare this time with current time
if( $tod =~ /^off.*/ ){ if( $tod =~ /^off.*/ ){
#-- tomorrow any time #-- tomorrow any time
if( $tom =~ /(\d?\d):(\d\d)(:(\d\d))?/ && $tom !~ /.*\(off\)$/ ){ if( $tom =~ /(\d?\d):(\d\d)(:(\d\d))?/ && $tom !~ /.*\(off\)$/ ){
#Log 1,"===========> |$1|$2|$3|$4"; #Log 1,"===========> |$1|$2|$3|$4";
($ht,$mt) = split('[\s:]',$tom); ($ht,$mt) = split('[\s:]',$tom);
$tt=60*$ht+$mt; $tt=60*$ht+$mt;
#-- wakeup tomorrow later than now #-- wakeup tomorrow later than now
if( $tt < $tl ){ if( $tt < $tl ){
$hw = $1*1; $hw = $1*1;
@ -1992,13 +2039,15 @@ sub YAAHM_sayWeeklyTime($$$) {
$pt = $yaahm_tt->{"undecid"}; $pt = $yaahm_tt->{"undecid"};
$msg .= " ".$yaahm_tt->{"undecid"}; $msg .= " ".$yaahm_tt->{"undecid"};
} }
#-- today nontrivial => compare this time with current time #-- today nontrivial => compare this time with current time
}elsif( $tod =~ /(\d?\d):(\d\d)(:(\d\d))?/ ){ }elsif( $tod =~ /(\d?\d):(\d\d)(:(\d\d))?/ ){
#Log 1,"===========> |$1|$2|$3|$4"; #Log 1,"===========> |$1|$2|$3|$4";
($ht,$mt) = split('[\s:]',$tod); ($ht,$mt) = split('[\s:]',$tod);
$tt=60*$ht+$mt; $tt=60*$ht+$mt;
#-- wakeup later today
if( $tt >= $tl ){ #-- wakeup later today, and ( not yet done - or done, but repeat possible)
if( ($tt >= $tl) && (($done == 0) | (($done == 1)&&($norep == 0))) ){
$hw = $1*1; $hw = $1*1;
$mw = $2*1; $mw = $2*1;
$pt = sprintf("%d:%02d",$hw,$mw)." ".lc($yaahm_tt->{"today"}); $pt = sprintf("%d:%02d",$hw,$mw)." ".lc($yaahm_tt->{"today"});
@ -2338,6 +2387,11 @@ sub YAAHM_GetDayStatus($) {
$yaahm_tt = \%yaahm_transtable_EN; $yaahm_tt = \%yaahm_transtable_EN;
} }
#-- iterate over timers to reset the "done" flag
for( my $i=0;$i<int( @{$hash->{DATA}{"WT"}} );$i++){
$hash->{DATA}{"WT"}[$i]{"done"} = 0;
}
my ($ret,$line,$fline,$date); my ($ret,$line,$fline,$date);
my (@lines,@chunks,@tday,@eday,@sday,@tmor,@ttwo); my (@lines,@chunks,@tday,@eday,@sday,@tmor,@ttwo);
my ($todaydesc,$todaytype,$tomdesc,$tomtype,$twodesc,$twotype); my ($todaydesc,$todaytype,$tomdesc,$tomtype,$twodesc,$twotype);
@ -2650,6 +2704,7 @@ sub YAAHM_GetDayStatus($) {
YAAHM_setWeeklyTime($hash); YAAHM_setWeeklyTime($hash);
readingsEndUpdate($hash,1); readingsEndUpdate($hash,1);
return undef; return undef;
} }
@ -3924,7 +3979,9 @@ sub YAAHM_Longtable($){
<li>On time (event) <i>wakeup</i>, <i>absence</i> mode will be reset to <i>normal</i> mode.</li> <li>On time (event) <i>wakeup</i>, <i>absence</i> mode will be reset to <i>normal</i> mode.</li>
<li>On <i>any</i> time (event), <i>donotdisturb</i> mode will be reset to <i>normal</i> mode.</li> <li>On <i>any</i> time (event), <i>donotdisturb</i> mode will be reset to <i>normal</i> mode.</li>
</ul> </ul>
</li> </li>
<li><<a name="yaahm_norepeat"><code>attr &lt;name&gt; norepeat 0|1</code></a>
<br/> if set to 1, repeated executions of wakeup, sleep and other timer events from the weekly programme will be suppressed.</li>
<li><a name="yaahm_statedevices"><code>attr &lt;name&gt; stateDevices (&lt;device&gt;:&lt;state-unsecured&gt;:&lt;state-secured&gt;:&lt;state-protected&gt;:&lt;state-guarded&gt;,)*</code></a> <li><a name="yaahm_statedevices"><code>attr &lt;name&gt; stateDevices (&lt;device&gt;:&lt;state-unsecured&gt;:&lt;state-secured&gt;:&lt;state-protected&gt;:&lt;state-guarded&gt;,)*</code></a>
<br />comma separated list of devices and their state in each of the house (security) states. Each of the listed devices will be checked in the interval given by the <i>stateInterval</i> attribute <br />comma separated list of devices and their state in each of the house (security) states. Each of the listed devices will be checked in the interval given by the <i>stateInterval</i> attribute
for its proper state, and a <i>stateWarning</i> function will be called if it is not in the proper state.</li> for its proper state, and a <i>stateWarning</i> function will be called if it is not in the proper state.</li>

View File

@ -1,6 +1,6 @@
//######################################################################################## //########################################################################################
// alarm.js // alarm.js
// Version 4.03 // Version 5.0
// See 95_Alarm for licensing // See 95_Alarm for licensing
//######################################################################################## //########################################################################################
//# Prof. Dr. Peter A. Henning //# Prof. Dr. Peter A. Henning
@ -258,8 +258,10 @@ function alarm_set(name) {
for (var i = 0; for (var i = 0;
i < alarmno; i < alarmno;
i++) { i++) {
FW_cmd(url + '?XHR=1&fwcsrf=' + csrfToken + '&cmd.' + name + '=attr%20' + name + '%20level' + i + 'cond%20' + document.getElementById('l' + i + 'c').value);
FW_cmd(url + '?XHR=1&fwcsrf=' + csrfToken + '&cmd.' + name + '=attr%20' + name + '%20level' + i + 'start%20' + document.getElementById('l' + i + 's').value); FW_cmd(url + '?XHR=1&fwcsrf=' + csrfToken + '&cmd.' + name + '=attr%20' + name + '%20level' + i + 'start%20' + document.getElementById('l' + i + 's').value);
FW_cmd(url + '?XHR=1&fwcsrf=' + csrfToken + '&cmd.' + name + '=attr%20' + name + '%20level' + i + 'end%20' + document.getElementById('l' + i + 'e').value); FW_cmd(url + '?XHR=1&fwcsrf=' + csrfToken + '&cmd.' + name + '=attr%20' + name + '%20level' + i + 'end%20' + document.getElementById('l' + i + 'e').value);
FW_cmd(url + '?XHR=1&fwcsrf=' + csrfToken + '&cmd.' + name + '=attr%20' + name + '%20level' + i + 'autocan%20' + document.getElementById('l' + i + 'o').value);
FW_cmd(url + '?XHR=1&fwcsrf=' + csrfToken + '&cmd.' + name + '=attr%20' + name + '%20level' + i + 'msg%20' + document.getElementById('l' + i + 'm').value); FW_cmd(url + '?XHR=1&fwcsrf=' + csrfToken + '&cmd.' + name + '=attr%20' + name + '%20level' + i + 'msg%20' + document.getElementById('l' + i + 'm').value);
if (document.getElementById('l' + i + 'x').checked == true) { if (document.getElementById('l' + i + 'x').checked == true) {
val = "armed"; val = "armed";