diff --git a/fhem/FHEM/95_Alarm.pm b/fhem/FHEM/95_Alarm.pm index 50d37ff5c..70349adf2 100644 --- a/fhem/FHEM/95_Alarm.pm +++ b/fhem/FHEM/95_Alarm.pm @@ -40,7 +40,7 @@ my $alarmname = "Alarms"; # link text my $alarmhiddenroom = "AlarmRoom"; # hidden room my $alarmpublicroom = "Alarm"; # public room my $alarmno = 8; -my $alarmversion = "2.3"; +my $alarmversion = "2.4"; ######################################################################################### # @@ -58,7 +58,7 @@ sub Alarm_Initialize ($) { $hash->{GetFn} = "Alarm_Get"; $hash->{UndefFn} = "Alarm_Undef"; #$hash->{AttrFn} = "Alarm_Attr"; - my $attst = "lockstate:lock,unlock statedisplay:simple,color,table,graphics,none armdelay armact disarmact cancelact"; + my $attst = "lockstate:lock,unlock statedisplay:simple,color,table,graphics,none armdelay armwait armact disarmact cancelact"; for( my $level=0;$level<$alarmno;$level++ ){ $attst .=" level".$level."start level".$level."end level".$level."msg level".$level."xec:0,1 level".$level."onact level".$level."offact "; } @@ -277,7 +277,8 @@ sub Alarm_Exec($$$$$){ my ($name,$level,$dev,$evt,$act) = @_; my $hash = $defs{$name}; - my $aclvl = $hash->{READINGS}{'level'.$level}{VAL}; + my $xec = AttrVal($name, "level".$level."xec", 0); + my $xac = $hash->{READINGS}{'level'.$level}{VAL}; my $msg = ''; my $cmd; my $mga; @@ -290,9 +291,8 @@ sub Alarm_Exec($$$$$){ #-- raising the alarm if( $act eq "on" ){ - my $xec = AttrVal($name, "level".$level."xec", 0); #-- only if this level is armed and not yet active - if( ($xec eq "armed") && ($hash->{READINGS}{"level".$level}{VAL} eq "off") ){ + if( ($xec eq "armed") && ($xac eq "off") ){ #-- check for time (attribute values have been controlled in CreateNotifiers) my @st = split(':',AttrVal($name, "level".$level."start", 0)); my @et = split(':',AttrVal($name, "level".$level."end", 0)); @@ -338,7 +338,7 @@ sub Alarm_Exec($$$$$){ } }elsif( ($act eq "off")||($act eq "cancel") ){ #-- only if this level is active - if( $hash->{READINGS}{"level".$level}{VAL} ne "off"){ + if( $xac ne "off"){ #-- deleting all running ats $dly = sprintf("alarm%1ddly",$level); foreach my $d (sort keys %intAt ) { @@ -384,44 +384,61 @@ sub Alarm_Arm($$$$$){ my ($name,$level,$dev,$evt,$act) = @_; my $hash = $defs{$name}; - my $aclvl = $hash->{READINGS}{"level"}{VAL}; + my $xac = $hash->{READINGS}{"level"}{VAL}; + my $xec = AttrVal($name, 'level'.$level.'xec', 0); my $msg = ''; my $mga; my $cmd; #-- arming the alarm - if( ($act eq "arm") && (AttrVal($name, 'level'.$level.'xec', 0) eq "disarmed") ){ - my @dly = split(':',(AttrVal($name, "armdelay", 0) ne '')?AttrVal($name, "armdelay", 0):'0:00'); - if( int(@dly) == 1){ - if( $dly[0] > 59 ){ - Log3 $hash,3,"[Alarm $level] Cannot be armed due to wrong time spec ".AttrVal($name, "armdelay", 0)." for armdelay"; - $dly[0] = 59; + if( ($act eq "arm") && ( $xec ne "armed") ){ + my $xdl = AttrVal($name, "armdelay", 0); + my $cmdwait = AttrVal($name, "armwait", 0); + my $cmdact = AttrVal($name, "armact", 0); + if( ($xdl eq '')|($xdl eq '0:00')|($xdl eq '00:00') ){ + CommandAttr(undef,$name.' level'.$level.'xec armed'); + $msg = "[Alarm $level] armed from device $dev with event $evt"; + Log3 $hash,3,$msg; + } elsif( $xdl =~ /([0-9])?:([0-5][0-9])?/ ){ + CommandAttr(undef,$name.' level'.$level.'xec armwait'); + #--transform commands from fhem to perl level + my @cmdactarr = split(/;/,$cmdact); + my $cmdactf; + if( int(@cmdactarr) == 1 ){ + $cmdactf = "fhem(\"".$cmdact."\");;"; + }else{ + $cmdactf = ''; + for(my $i=0;$i 10) || ($dly[0] < 0) || ($dly[1] > 59) || ($dly[1] < 0) ){ - Log3 $hash,1,"[Alarm $level] Cannot be armed due to wrong time spec ".AttrVal($name, "armdelay", 0)." for armdelay"; - $dly[0] = 9; - $dly[1] = 59; - } - $msg = "[Alarm $level] armed from device $dev with event $evt, delay $dly[0]:$dly[1]"; - $cmd = sprintf("define alarm%1d.arm.dly at +00:%02d:%02d attr %s level%1dxec armed",$level,$dly[0],$dly[1],$name,$level); + #-- compose commands + $cmd = sprintf("define alarm%1d.arm.dly at +00:%02d:%02d {fhem(\"attr %s level%1dxec armed\");;%s}",$level,$1,$2,$name,$level,$cmdactf); + $msg = "[Alarm $level] will be armed from device $dev with event $evt, delay $xdl"; + #-- delete old delayed arm + fhem('delete alarm'.$level.'.arm.dly' ) + if( defined $defs{'alarm'.$level.'.arm.dly'}); + #-- define new delayed arm + fhem($cmd); + #-- execute armwait action + fhem($cmdwait); + Log3 $hash,3,$msg; + }else{ + $msg = "[Alarm $level] cannot be armed due to wrong delay timespec"; + Log3 $hash,1,$msg; } - fhem($cmd); - $cmd = AttrVal($name, "armact", 0); - fhem($cmd) - if( $cmd ); - Log3 $hash,3,$msg; #-- disarming implies canceling as well - }elsif( ($act eq "disarm") && (AttrVal($name, 'level'.$level.'xec', 0) eq "armed")) { + }elsif( ($act eq "disarm") && ($xec ne "disarmed")) { + #-- delete old delayed arm + fhem('delete alarm'.$level.'.arm.dly' ) + if( defined $defs{'alarm'.$level.'.arm.dly'}); CommandAttr (undef,$name.' level'.$level.'xec disarmed'); Alarm_Exec($name,$level,"program","disarm","cancel"); #-- $msg = "[Alarm $level] disarmed from device $dev with event $evt"; $cmd = AttrVal($name, "disarmact", 0); - fhem("define alarm".$level.".disarm.T at +00:00:05 ".$cmd); - #if( $cmd ); + fhem("define alarm".$level.".disarm.T at +00:00:03 ".$cmd) + if( $cmd ); } return $msg; } @@ -653,15 +670,21 @@ sub Alarm_Html($) my $row=1; $ret .= "
Settings
"; $ret .= "\n"; - $ret .= ""; $ret .= "". "\n"; for( my $k=0;$k<$alarmno;$k++ ){ @@ -681,7 +704,7 @@ sub Alarm_Html($) $ret .= "". ""; - $ret .= sprintf("\n"; } $ret .= "
"; + $ret .= "
Arm Delay"; - $ret .= sprintf("",AttrVal($name, "armdelay","")); - $ret .= " Arm Action"; + $ret .= "
\n"; + $ret .= ""; + $ret .= "\n"; + $ret .= "\n"; + $ret .="
Arm Button ↠ Wait Action "; + $ret .= sprintf("",AttrVal($name, "armwait","")); + $ret .= " ↴ Delay
↲"; + $ret .= sprintf("",AttrVal($name, "armdelay","")); + $ret .= "
Arm Action "; $ret .= sprintf("",AttrVal($name, "armact","")); - $ret .= "
Disarm Action"; + $ret .= "
Disarm Button ↠Disarm Action "; $ret .= sprintf("",AttrVal($name, "disarmact","")); - $ret .= "
Cancel Action"; + $ret .= "
Cancel Button ↠ Cancel Action "; $ret .= sprintf("",AttrVal($name, "cancelact","")); - $ret .= "
LevelTime [hh:mm]Message Part IIArmed/Cancel
Start  ". "End ",($xval eq "armed")?"checked=\"checked\"":""). + $ret .= sprintf("",($xval eq "armed")?"checked=\"checked\"":""). "
"; @@ -769,13 +792,13 @@ sub Alarm_Html($)
  • set <name> canceled <level> -
    cancels an alarm of level <level>, where <level> = 1..7 +
    cancels an alarm of level <level>, where <level> = 0..7
  • set <name> armed <level>
    set <name> disarmed <level>
    -
    sets the alarm of level <level> to armed (i.e., active) or disarmed (i.e., inactive), where <level> = 1..7 +
    sets the alarm of level <level> to armed (i.e., active) or disarmed (i.e., inactive), where <level> = 0..7
  • set <name> locked
    @@ -806,10 +829,12 @@ sub Alarm_Html($)
  • none=no state display
  • -
  • attr <name> armdelay seconds -
    seconds until the arming of an alarm becomes operative
  • +
  • attr <name> armdelay mm:ss +
    time until the arming of an alarm becomes operative (0:00 - 9:59 allowed)
  • +
  • attr <name> armwait action +
    FHEM action to be carried out immediately after the arm event
  • attr <name> armact action -
    FHEM action to be carried out on the arming of an alarm
  • +
    FHEM action to be carried out at the arme event after the delay time
  • attr <name> disarmact action
    FHEM action to be carried out on the disarming of an alarm
  • attr <name> cancelact action diff --git a/fhem/www/pgm2/alarm.js b/fhem/www/pgm2/alarm.js index 9209bcc1c..d5d4c5087 100644 --- a/fhem/www/pgm2/alarm.js +++ b/fhem/www/pgm2/alarm.js @@ -65,6 +65,22 @@ function alarm_cancel(name,level){ FW_cmd(url+'?XHR=1&cmd.'+name+'={Alarm_Exec("'+name+'",'+level+',"web","button","off")}'); } + +function alarm_arm(name,level){ + var val; + var nam; + var command = document.getElementById('l'+level+'x').checked; + if (command == true){ + command="arm"; + }else{ + command="disarm"; + } + var location = document.location.pathname; + if (location.substr(location.length-1,1) == '/') {location = location.substr(0,location.length-1);} + var url = document.location.protocol+"//"+document.location.host+location; + + FW_cmd(url+'?XHR=1&cmd.'+name+'={Alarm_Arm("'+name+'",'+level+',"web","button","'+command+'")}'); + } function alarm_set(name){ @@ -77,6 +93,7 @@ function alarm_set(name){ // saving arm data FW_cmd(url+'?XHR=1&cmd.'+name+'=attr '+name+' armdelay '+document.getElementById('armdelay').value); + FW_cmd(url+'?XHR=1&cmd.'+name+'=attr '+name+' armwait '+document.getElementById('armwait').value); FW_cmd(url+'?XHR=1&cmd.'+name+'=attr '+name+' armact '+document.getElementById('armaction').value); FW_cmd(url+'?XHR=1&cmd.'+name+'=attr '+name+' disarmact '+document.getElementById('disarmaction').value); FW_cmd(url+'?XHR=1&cmd.'+name+'=attr '+name+' cancelact '+document.getElementById('cancelaction').value);