diff --git a/fhem/FHEM/95_Alarm.pm b/fhem/FHEM/95_Alarm.pm index c8934c6fd..4fc6d966c 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.0"; +my $alarmversion = "2.1"; ######################################################################################### # @@ -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 sharpact unsharpact cancelact"; + my $attst = "lockstate:lock,unlock statedisplay:simple,color,table,graphics,none armdelay 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 "; } @@ -166,17 +166,17 @@ sub Alarm_CreateEntry($) { sub Alarm_Set($@) { my ( $hash, $name, $cmd, @args ) = @_; - if ( ($cmd eq "cancel") || ($cmd eq "sharp") || ($cmd eq "unsharp") ) { + if ( ($cmd eq "cancel") || ($cmd eq "armed") || ($cmd eq "disarmed") ) { return "[Alarm] Invalid argument to set $cmd, must be numeric" if ( $args[0] !~ /\d+/ ); return "[Alarm] Invalid argument to set $cmd, must be 0 < arg < $alarmno" if ( ($args[0] >= $alarmno)||($args[0]<0) ); if( $cmd eq "cancel" ){ - Alarm_Exec($name,$args[0],"web","button","off"); - }elsif ( $cmd eq "sharp" ) { - Alarm_Sharp($name,$args[0],"web","button","sharp"); + Alarm_Exec($name,$args[0],"web","button","cancel"); + }elsif ( $cmd eq "arm" ) { + Alarm_Arm($name,$args[0],"web","button","arm"); }else{ - Alarm_Sharp($name,$args[0],"web","button","unsharp"); + Alarm_Arm($name,$args[0],"web","button","disarm"); } return; } elsif ( $cmd eq "lock" ) { @@ -187,7 +187,7 @@ sub Alarm_Set($@) { return; } else { my $str = join(",",(0..($alarmno-1))); - return "[Alarm] Unknown argument " . $cmd . ", choose one of cancel:$str sharp:$str unsharp:$str lock:noArg unlock:noArg"; + return "[Alarm] Unknown argument " . $cmd . ", choose one of cancel:$str arm:$str disarm:$str lock:noArg unlock:noArg"; } } @@ -283,12 +283,14 @@ sub Alarm_Exec($$$$$){ my @sta; #Log3 $hash,1,"[Alarm $level] Exec called with dev $dev evt $evt act $act]"; + return + if ($dev eq 'global'); #-- raising the alarm if( $act eq "on" ){ my $xec = AttrVal($name, "level".$level."xec", 0); - #-- only if this level is sharp and not yet active - if( ($xec eq "sharp") && ($hash->{READINGS}{"level".$level}{VAL} eq "off") ){ + #-- only if this level is armed and not yet active + if( ($xec eq "armed") && ($hash->{READINGS}{"level".$level}{VAL} 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)); @@ -329,10 +331,10 @@ sub Alarm_Exec($$$$$){ Log3 $hash,5,$msg; } }else{ - $msg = "[Alarm $level] not raised, not sharp or already active"; + $msg = "[Alarm $level] not raised, not armed or already active"; Log3 $hash,5,$msg; } - }elsif( $act eq "off" ){ + }elsif( ($act eq "off")||($act eq "cancel") ){ #-- only if this level is active if( $hash->{READINGS}{"level".$level}{VAL} ne "off"){ #-- deleting all running ats @@ -367,16 +369,16 @@ sub Alarm_Exec($$$$$){ ######################################################################################### # -# Alarm_Sharp - Sharpen the Alarm +# Alarm_Arm - Arm the Alarm # # Parameter name = name of the Alarm definition # level = Alarm level # dev = name of the device calling the alarm -# act = action - "sharp" or "unsharp" +# act = action - "armed" or "disarmed" # ######################################################################################### -sub Alarm_Sharp($$$$$){ +sub Alarm_Arm($$$$$){ my ($name,$level,$dev,$evt,$act) = @_; my $hash = $defs{$name}; @@ -385,41 +387,39 @@ sub Alarm_Sharp($$$$$){ my $mga; my $cmd; - #-- sharpening the alarm - if( $act eq "sharp" ){ - #-- sharpened by sensor (attribute values have been controlled in CreateNotifiers) - #my @sta = split('\|', AttrVal($dev, "alarmSettings", 0)); - #my $msg = $sta[2]." ".AttrVal($name, "level".$level."msg", 0); - #-- replace some parts - #my @evtpart = split(" ",$evt); - #$msg =~ s/\$NAME/$dev/g; - #$msg =~ s/\$EVENT/$evt/g; - #for( my $i=1;$i<= int(@evtpart);$i++){ - # $msg =~ s/\$EVTPART$i/$evtpart[$i-1]/g; - #} - $msg = "[Alarm $level] sharpened from device $dev with event $evt"; - CommandAttr(undef,$name.' level'.$level.'xec sharp'); - $cmd = AttrVal($name, "sharpact", 0); + #-- 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; + } + $msg = "[Alarm $level] armed from device $dev with event $evt, delay $dly[0] s"; + $cmd = sprintf("define alarm%1d.arm.dly at +00:00:%02d attr %s level%1dxec armed",$level,$dly[0],$name,$level); + }elsif( int(@dly) == 2){ + if( ($dly[0] > 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); + } + fhem($cmd); + $cmd = AttrVal($name, "armact", 0); fhem($cmd) - if( $cmd ); + if( $cmd ); Log3 $hash,3,$msg; - #-- unsharpening implies canceling as well - }elsif( $act eq "unsharp"){ - $msg = "[Alarm $level] unsharpened from device $dev with event $evt"; - CommandAttr (undef,$name.' level'.$level.'xec unsharp'); - $cmd = AttrVal($name, "unsharpact", 0); - fhem($cmd) - if( $cmd ); - #-- calling actors - $cmd = AttrVal($name, "level".$level."offact", 0); - fhem($cmd); - readingsSingleUpdate( $hash, "level".$level,"off",0 ); - $mga = " Level $level canceled"; - readingsSingleUpdate( $hash, "short", $mga, 0); - $mga = Alarm_getstate($hash)." ".$mga; - readingsSingleUpdate( $hash, "state", $mga, 0 ); - $msg = "[Alarm $level] canceled from device $dev"; - Log3 $hash,3,$msg; + #-- disarming implies canceling as well + }elsif( ($act eq "disarm") && (AttrVal($name, 'level'.$level.'xec', 0) eq "armed")) { + 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 ); } return $msg; } @@ -452,10 +452,10 @@ sub Alarm_CreateNotifiers($){ if( defined $defs{'alarm'.$level.'.on.N'}); fhem('delete alarm'.$level.'.off.N' ) if( defined $defs{'alarm'.$level.'.off.N'}); - fhem('delete alarm'.$level.'.sh.N' ) - if( defined $defs{'alarm'.$level.'.sh.N'}); - fhem('delete alarm'.$level.'.unsh.N' ) - if( defined $defs{'alarm'.$level.'.unsh.N'}); + fhem('delete alarm'.$level.'.arm.N' ) + if( defined $defs{'alarm'.$level.'.arm.N'}); + fhem('delete alarm'.$level.'.disarm.N' ) + if( defined $defs{'alarm'.$level.'.disarm.N'}); my @st = split(':',(AttrVal($name, "level".$level."start", 0) ne '')?AttrVal($name, "level".$level."start", 0):'0:00'); @@ -499,8 +499,8 @@ sub Alarm_CreateNotifiers($){ #-- now set up the command for raising alarm - only if cancel exists $cmd = ''; - my $cmdsh = ""; - my $cmdunsh = ""; + my $cmdarm = ""; + my $cmddisarm = ""; foreach my $d (sort keys %defs ) { next if(IsIgnored($d)); if( AttrVal($d, "alarmDevice","") eq "Sensor" ) { @@ -513,12 +513,12 @@ sub Alarm_CreateNotifiers($){ if( $aval[3] eq "on" ){ $cmd .= '('.$aval[1].')|'; # Log3 $hash,1,"[Alarm $level] Adding sensor $d to raise notifier"; - }elsif( $aval[3] eq "sh" ){ - $cmdsh .= '('.$aval[1].')|'; - #Log3 $hash,1,"[Alarm $level] Adding sensor $d to sharp notifier"; - }elsif( $aval[3] eq "unsh" ){ - $cmdunsh .= '('.$aval[1].')|'; - # Log3 $hash,1,"[Alarm $level] Adding sensor $d to sunharp notifier"; + }elsif( $aval[3] eq "arm" ){ + $cmdarm .= '('.$aval[1].')|'; + #Log3 $hash,1,"[Alarm $level] Adding sensor $d to arm notifier"; + }elsif( $aval[3] eq "disarm" ){ + $cmddisarm .= '('.$aval[1].')|'; + # Log3 $hash,1,"[Alarm $level] Adding sensor $d to disarm notifier"; } } } @@ -579,25 +579,25 @@ sub Alarm_CreateNotifiers($){ } else { Log3 $hash,5,"[Alarm $level] Adding on/off actors not possible"; } - #-- sharp notifier - optional, but only in case the alarm may be raised - if( $cmdsh ne '' ){ - $cmdsh = substr($cmdsh,0,length($cmdsh)-1); - $cmdsh = 'alarm'.$level.'.sh.N notify '.$cmdsh; - $cmdsh .= ' {main::Alarm_Sharp("'.$name.'",'.$level.',"$NAME","$EVENT","sharp")}'; - CommandDefine(undef,$cmdsh); - CommandAttr (undef,'alarm'.$level.'.sh.N room '.$alarmpublicroom); - CommandAttr (undef,'alarm'.$level.'.sh.N group alarmNotifier'); - Log3 $hash,3,"[Alarm $level] Created sharp notifier"; + #-- arm notifier - optional, but only in case the alarm may be raised + if( $cmdarm ne '' ){ + $cmdarm = substr($cmdarm,0,length($cmdarm)-1); + $cmdarm = 'alarm'.$level.'.arm.N notify '.$cmdarm; + $cmdarm .= ' {main::Alarm_Arm("'.$name.'",'.$level.',"$NAME","$EVENT","arm")}'; + CommandDefine(undef,$cmdarm); + CommandAttr (undef,'alarm'.$level.'.arm.N room '.$alarmpublicroom); + CommandAttr (undef,'alarm'.$level.'.arm.N group alarmNotifier'); + Log3 $hash,3,"[Alarm $level] Created arm notifier"; } - #-- unsharp notifier - optional, but only in case the alarm may be raised - if( $cmdunsh ne '' ){ - $cmdunsh = substr($cmdunsh,0,length($cmdunsh)-1); - $cmdunsh = 'alarm'.$level.'.unsh.N notify '.$cmdunsh; - $cmdunsh .= ' {main::Alarm_Sharp("'.$name.'",'.$level.',"$NAME","$EVENT","unsharp")}'; - CommandDefine(undef,$cmdunsh); - CommandAttr (undef,'alarm'.$level.'.unsh.N room '.$alarmpublicroom); - CommandAttr (undef,'alarm'.$level.'.unsh.N group alarmNotifier'); - Log3 $hash,3,"[Alarm $level] Created unsharp notifier"; + #-- disarm notifier - optional, but only in case the alarm may be raised + if( $cmddisarm ne '' ){ + $cmddisarm = substr($cmddisarm,0,length($cmddisarm)-1); + $cmddisarm = 'alarm'.$level.'.disarm.N notify '.$cmddisarm; + $cmddisarm .= ' {main::Alarm_Arm("'.$name.'",'.$level.',"$NAME","$EVENT","disarm")}'; + CommandDefine(undef,$cmddisarm); + CommandAttr (undef,'alarm'.$level.'.disarm.N room '.$alarmpublicroom); + CommandAttr (undef,'alarm'.$level.'.disarm.N group alarmNotifier'); + Log3 $hash,3,"[Alarm $level] Created disarm notifier"; } } } @@ -626,8 +626,8 @@ sub Alarm_Html($) readingsSingleUpdate( $hash, "state", Alarm_getstate($hash)." ".$hash->{READINGS}{"short"}{VAL}, 0 ); #-- - my $lockstate = ($hash->{READINGS}{lockstate}{VAL}) ? $hash->{READINGS}{lockstate}{VAL} : "unlock"; - my $showhelper = ($lockstate eq "unlock") ? 1 : 0; + my $lockstate = ($hash->{READINGS}{lockstate}{VAL}) ? $hash->{READINGS}{lockstate}{VAL} : "unlocked"; + my $showhelper = ($lockstate eq "unlocked") ? 1 : 0; #-- $ret .= "\n"; $ret .= "\n"; - $ret .= "". - "\n"; + $ret .= "\n"; #-- settings table my $row=1; $ret .= ""; - $ret .= "
Settings
\n"; + $ret .= ""; @@ -679,7 +687,7 @@ sub Alarm_Html($) #-- sensors table $row=1; $ret .= ""; - $ret .= "
\n"; + $ret .= ""; $ret .= "". - "\n"; + "\n"; for( my $k=0;$k<$alarmno;$k++ ){ $row++; my $sval = AttrVal($name, "level".$k."start", 0); @@ -671,7 +679,7 @@ sub Alarm_Html($) $ret .= "". ""; - $ret .= sprintf("\n"; } $ret .= "
Arm Delay"; + $ret .= sprintf("",AttrVal($name, "armdelay","")); + $ret .= " Arm Action"; + $ret .= sprintf("",AttrVal($name, "armact","")); + $ret .= "
Disarm Action"; + $ret .= sprintf("",AttrVal($name, "disarmact","")); + $ret .= "
Cancel Action"; + $ret .= sprintf("",AttrVal($name, "cancelact","")); + $ret .= "
LevelTime [hh:mm]Message Part IISharp/
 Cancel
Arm/Cancel
Start  ". "End ",($xval eq "sharp")?"checked=\"checked\"":""). + $ret .= sprintf("",($xval eq "armed")?"checked=\"checked\"":""). "
Sensors
\n"; + $ret .= ""; @@ -709,7 +717,7 @@ sub Alarm_Html($) #-- actors table $row=1; $ret .= ""; - $ret .= "
\n"; $ret .= "\n"; foreach my $d (sort keys %defs ) { @@ -700,8 +708,8 @@ sub Alarm_Html($) $ret .= "\n"; $ret .= sprintf("\n", - ($aval[3] eq "sh")?"selected=\"seleced\"":"",($aval[3] eq "unsh")?"selected=\"selected\"":""); + $ret .= sprintf("
Notify to Alarm Level
".join("     ",(0..($alarmno-1)))."
". "Notify on RegExp       Message Part IAction
Actors
\n"; + $ret .= "
\n"; $ret .= "\n"; @@ -739,8 +747,6 @@ sub Alarm_Html($) return $ret; } - - 1; =pod @@ -749,15 +755,12 @@ sub Alarm_Html($)

Alarm

FHEM module to set up a House Alarm System with 8 different alarm levels

-
-

Define

define <name> Alarm
Defines the Alarm system.

-

Set

-

Get

    @@ -787,7 +789,6 @@ sub Alarm_Html($) get <name> version
    Display the version of the module
-

Attributes

    @@ -803,11 +804,13 @@ sub Alarm_Html($)
  • none=no state display
-
  • attr <name> sharpact action -
    FHEM action to be carried out on the sharpening of an alarm
  • -
  • attr <name> unsharpact action -
    FHEM action to be carried out on the unsharpening of an alarm
  • -
  • attr <name> cancelpact action +
  • attr <name> armdelay seconds +
    seconds until the arming of an alarm becomes operative
  • +
  • attr <name> armact action +
    FHEM action to be carried out on the arming of an alarm
  • +
  • attr <name> disarmact action +
    FHEM action to be carried out on the disarming of an alarm
  • +
  • attr <name> cancelact action
    FHEM action to be carried out on the canceling of an alarm
  • For each of the 8 alarm levels, several attributes hold the alarm setup. They should not be changed by hand, but through the web interface to avoid confusion:
  • Set by Alarm Level
    ".join("     ",(0..($alarmno-1))). "
    Set Action". "                  Unset ActionDelay