diff --git a/fhem/contrib/Alarm/95_Alarm.pm b/fhem/contrib/Alarm/95_Alarm.pm
index 6c3887f67..ea771f34a 100644
--- a/fhem/contrib/Alarm/95_Alarm.pm
+++ b/fhem/contrib/Alarm/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 = "1.2";
+my $alarmversion = "1.3";
#########################################################################################
#
@@ -58,7 +58,7 @@ sub Alarm_Initialize ($) {
$hash->{GetFn} = "Alarm_Get";
$hash->{UndefFn} = "Alarm_Undef";
#$hash->{AttrFn} = "Alarm_Attr";
- my $attst = "lockstate:lock,unlock";
+ my $attst = "lockstate:lock,unlock statedisplay:simple,color,table,graphics,none";
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";
}
@@ -151,6 +151,8 @@ sub Alarm_CreateEntry($) {
}
}
}
+ my $mga = Alarm_getstate($hash)." Keine Störung";
+ readingsSingleUpdate( $hash, "state", $mga, 0 );
}
#########################################################################################
@@ -209,6 +211,54 @@ sub Alarm_Get($@) {
}
}
+#########################################################################################
+#
+# Alarm_getstate - Helper function to assemble a state display
+#
+# Parameter hash = hash of device addressed
+#
+#########################################################################################
+
+sub Alarm_getstate($) {
+ my ($hash) = @_;
+ my $res = '';
+ my $type = AttrVal($hash->{NAME},"statedisplay",0);
+ #--------------------------
+ if( $type eq "simple" ){
+ for( my $level=0;$level<$alarmno;$level++ ){
+ if( $hash->{READINGS}{"level".$level}{VAL} eq "off" ){
+ $res.='O';
+ }else{
+ $res.='X';
+ }
+ }
+ #--------------------------
+ }elsif( $type eq "color" ){
+ $res = '';
+ for( my $level=0;$level<$alarmno;$level++ ){
+ if( $hash->{READINGS}{"level".$level}{VAL} eq "off" ){
+ $res.=' '.$level;
+ }else{
+ $res.=' '.$level.'';
+ }
+ }
+ $res.='';
+ #--------------------------
+ }elsif( $type eq "table" ){
+ $res = '
';
+ for( my $level=0;$level<$alarmno;$level++ ){
+ if( $hash->{READINGS}{"level".$level}{VAL} eq "off" ){
+ $res.=' | ';
+ }else{
+ $res.=' | ';
+ }
+ }
+ $res.='
';
+ #--------------------------
+ }
+ return $res;
+}
+
#########################################################################################
#
# Alarm_Exec - Execute the Alarm
@@ -228,6 +278,8 @@ sub Alarm_Exec($$$$$){
my $msg = '';
my $cmd;
my $mga;
+ my $dly;
+ my @sta;
#-- raising the alarm
if( $act eq "on" ){
@@ -243,11 +295,13 @@ sub Alarm_Exec($$$$$){
my ($sec, $min, $hour, $day, $month, $year, $wday, $yday, $isdst) = localtime(time);
my $ntp = $hour*60+$min;
- if( ($ntp <= $etp) && ($ntp >= $stp) ){
- my $str1 = "$day.$month $hour:$min";
+ if( ($ntp <= $etp) && ($ntp >= $stp) ){
+ #-- calling actors
+ $cmd = AttrVal($name, "level".$level."onact", 0);
+ fhem($cmd);
#-- raised by sensor (attribute values have been controlled in CreateNotifiers)
- my @sta = split('\|', AttrVal($dev, "alarmSettings", 0));
- my $mga = $sta[2]." ".AttrVal($name, "level".$level."msg", 0);
+ @sta = split('\|', AttrVal($dev, "alarmSettings", 0));
+ $mga = $sta[2]." ".AttrVal($name, "level".$level."msg", 0);
#-- replace some parts
my @evtpart = split(" ",$evt);
$mga =~ s/\$NAME/$dev/g;
@@ -255,19 +309,13 @@ sub Alarm_Exec($$$$$){
for( my $i=1;$i<= int(@evtpart);$i++){
$mga =~ s/\$EVTPART$i/$evtpart[$i-1]/g;
}
- #-- only if level is higher than before
- if( ($aclvl eq "none") || ($level >= $aclvl) ){
- $msg = "[Alarm $level] raised from device $dev with event $evt";
- readingsSingleUpdate( $hash, "state", $mga, 0 );
- readingsSingleUpdate( $hash, "level", $level, 0 );
- #-- calling actors
- $cmd = AttrVal($name, "level".$level."onact", 0);
- fhem($cmd);
- Log3 $hash,3,$msg;
- }else{
- $msg = "[Alarm $level] not raised from device $dev, already higher level $aclvl running";
- Log3 $hash,3,$msg;
- }
+ #-- readings
+ readingsSingleUpdate( $hash, "level".$level,$dev,0 );
+ readingsSingleUpdate( $hash, "short", $mga, 0);
+ $mga = Alarm_getstate($hash)." ".$mga;
+ readingsSingleUpdate( $hash, "state", $mga, 0 );
+ $msg = "[Alarm $level] raised from device $dev with event $evt";
+ Log3 $hash,3,$msg;
}else{
$msg = "[Alarm $level] not raised, not in time slot";
Log3 $hash,5,$msg;
@@ -277,23 +325,29 @@ sub Alarm_Exec($$$$$){
Log3 $hash,5,$msg;
}
}elsif( $act eq "off" ){
- #-- deleting all running ats
- my $dly = sprintf("alarm%1ddly",$level);
- foreach my $d (sort keys %intAt ) {
- next if( $intAt{$d}{FN} ne "at_Exec" );
- $mga = $intAt{$d}{ARG}{NAME};
- next if( $mga !~ /$dly\d/);
- #Log3 $hash,1,"[Alarm] Killing delayed action $name";
- CommandDelete(undef,"$mga");
- }
- #-- calling actors
- $cmd = AttrVal($name, "level".$level."offact", 0);
- $msg = "[Alarm $level] canceled from device $dev";
- fhem($cmd);
- #-- todo: several levels may be active at one - unclear so far.
- readingsSingleUpdate( $hash, "state", "Canceled", 0 );
- readingsSingleUpdate( $hash, "level", "none", 0 );
- Log3 $hash,3,$msg;
+ #-- only if this level is active
+ if( $hash->{READINGS}{"level".$level}{VAL} ne "off"){
+ #-- deleting all running ats
+ $dly = sprintf("alarm%1ddly",$level);
+ foreach my $d (sort keys %intAt ) {
+ next if( $intAt{$d}{FN} ne "at_Exec" );
+ $mga = $intAt{$d}{ARG}{NAME};
+ next if( $mga !~ /$dly\d/);
+ #Log3 $hash,1,"[Alarm] Killing delayed action $name";
+ CommandDelete(undef,"$mga");
+ }
+ #-- calling actors
+ $cmd = AttrVal($name, "level".$level."offact", 0);
+ fhem($cmd);
+ #-- readings
+ 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;
+ }
}else{
Log3 $hash,3,"[Alarm $level] Exec called with act=$act";
}
@@ -317,6 +371,8 @@ sub Alarm_Sharp($$$$$){
my $hash = $defs{$name};
my $aclvl = $hash->{READINGS}{"level"}{VAL};
my $msg = '';
+ my $mga;
+ my $cmd;
#-- sharpening the alarm
if( $act eq "sharp" ){
@@ -331,18 +387,22 @@ sub Alarm_Sharp($$$$$){
# $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');
+ CommandAttr(undef,$name.' level'.$level.'xec sharp');
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');
- #-- unsharpening implies canceling as well
- readingsSingleUpdate( $hash, "state", "Canceled", 0 );
- readingsSingleUpdate( $hash, "level", "none", 0 );
#-- calling actors
- my $cmd = AttrVal($name, "level".$level."offact", 0);
+ $cmd = AttrVal($name, "level".$level."offact", 0);
fhem($cmd);
- Log3 $hash,3,$msg;
+ 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;
}
return $msg;
}
@@ -543,6 +603,9 @@ sub Alarm_Html($)
my $hash = $defs{$name};
my $id = $defs{$name}{NR};
+
+ #--
+ readingsSingleUpdate( $hash, "state", Alarm_getstate($hash)." ".$hash->{READINGS}{"short"}{VAL}, 0 );
#--
my $lockstate = ($hash->{READINGS}{lockstate}{VAL}) ? $hash->{READINGS}{lockstate}{VAL} : "unlock";
@@ -666,8 +729,72 @@ sub Alarm_Html($)
=begin html
-Alarm
-
+ 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
+
+ -
+
get <name> version
+
Display the version of the module
+
+
+
+ Attributes
+
+ attr <name> lockstate locked|unlocked
+
locked means that alarm setups may not be changed,
+ unlocked means that alarm setups may be changed>
+ attr <name> statedisplay simple,color,table,none
+
defines how the state of all eight alarm levels is shown. Example for the case when only alarm no. 2 is raised:
+
+ - simple=OOXOOOOO
+ - color= 0 1 2 3 4 5 6 7
+ - table=
+ - none=no state display
+
+
+ - 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:
+
level<level>start, level<level>end, level<level>msg, level<level>xec,
+ level<level>onact, level<level>offact
+ - Standard attributes alias, comment, event-on-update-reading, event-on-change-reading, room, eventMap, loglevel,
+ webCmd
+
=end html
=begin html_DE