From 781b2f262fbda7d4f88d6e31aac31a50f5b75a46 Mon Sep 17 00:00:00 2001 From: pahenning <> Date: Sun, 2 Nov 2014 04:54:09 +0000 Subject: [PATCH] Alarm.pm: Moved into regular FHEM path alarm.js: Moved into regular www/pgm2 path git-svn-id: https://svn.fhem.de/fhem/trunk@6861 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/95_Alarm.pm | 814 +++++++++++++++++++++++++++++++++++++++++ fhem/www/pgm2/alarm.js | 131 +++++++ 2 files changed, 945 insertions(+) create mode 100644 fhem/FHEM/95_Alarm.pm create mode 100644 fhem/www/pgm2/alarm.js diff --git a/fhem/FHEM/95_Alarm.pm b/fhem/FHEM/95_Alarm.pm new file mode 100644 index 000000000..e809af892 --- /dev/null +++ b/fhem/FHEM/95_Alarm.pm @@ -0,0 +1,814 @@ +######################################################################################## +# +# Alarm.pm +# +# FHEM module for house alarm +# +# Prof. Dr. Peter A. Henning +# +# $Id: 95_Alarm.pm 2014-08 - pahenning $ +# +######################################################################################## +# +# This programm is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# The GNU General Public License can be found at +# http://www.gnu.org/copyleft/gpl.html. +# A copy is found in the textfile GPL.txt and important notices to the license +# from the author is found in LICENSE.txt distributed with these scripts. +# +# This script is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +######################################################################################## + +package main; + +use strict; +use warnings; +use vars qw(%defs); # FHEM device/button definitions +use vars qw(%intAt); # FHEM at definitions + +######################### +# Global variables +my $alarmname = "Alarms"; # link text +my $alarmhiddenroom = "AlarmRoom"; # hidden room +my $alarmpublicroom = "Alarm"; # public room +my $alarmno = 8; +my $alarmversion = "1.9"; + +######################################################################################### +# +# Alarm_Initialize +# +# Parameter hash = hash of device addressed +# +######################################################################################### + +sub Alarm_Initialize ($) { + my ($hash) = @_; + + $hash->{DefFn} = "Alarm_Define"; + $hash->{SetFn} = "Alarm_Set"; + $hash->{GetFn} = "Alarm_Get"; + $hash->{UndefFn} = "Alarm_Undef"; + #$hash->{AttrFn} = "Alarm_Attr"; + 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"; + } + $hash->{AttrList} = $attst; + + $data{FWEXT}{Alarmx}{LINK} = "?room=".$alarmhiddenroom; + $data{FWEXT}{Alarmx}{NAME} = $alarmname; + + return undef; +} + +######################################################################################### +# +# Alarm_Define - Implements DefFn function +# +# Parameter hash = hash of device addressed, def = definition string +# +######################################################################################### + +sub Alarm_Define ($$) { + my ($hash, $def) = @_; + my $now = time(); + my $name = $hash->{NAME}; + $hash->{VERSION} = $alarmversion; + readingsSingleUpdate( $hash, "state", "Initialized", 0 ); + + RemoveInternalTimer($hash); + InternalTimer ($now + 5, 'Alarm_CreateEntry', $hash, 0); + + return; +} + +######################################################################################### +# +# Alarm_Undef - Implements Undef function +# +# Parameter hash = hash of device addressed, def = definition string +# +######################################################################################### + +sub Alarm_Undef ($$) { + my ($hash,$arg) = @_; + + RemoveInternalTimer($hash); + + return undef; +} + +######################################################################################### +# +# Alarm_Attr - Implements Attr function +# +# Parameter hash = hash of device addressed, ??? +# +######################################################################################### + +sub Alarm_Attr($$$) { + my ($cmd, $name, $attrName, $attrVal) = @_; + return; +} + +######################################################################################### +# +# Alarm_CreateEntry - Puts the Alarm entry into the FHEM menu +# +# Parameter hash = hash of device addressed +# +######################################################################################### + +sub Alarm_CreateEntry($) { + my ($hash) = @_; + + my $name = $hash->{NAME}; + if (!defined $defs{$name."_weblink"}) { + FW_fC("define ".$name."_weblink weblink htmlCode {Alarm_Html(\"".$name."\")}"); + Log3 $hash, 3, "[".$name. " V".$alarmversion."]"." Weblink ".$name."_weblink created"; + } + FW_fC("attr ".$name."_weblink room ".$alarmhiddenroom); + + foreach my $dn (sort keys %defs) { + if ($defs{$dn}{TYPE} eq "FHEMWEB" && $defs{$dn}{NAME} !~ /FHEMWEB:/) { + my $hr = AttrVal($defs{$dn}{NAME}, "hiddenroom", ""); + if (index($hr,$alarmhiddenroom) == -1){ + if ($hr eq "") { + FW_fC("attr ".$defs{$dn}{NAME}." hiddenroom ".$alarmhiddenroom); + }else { + FW_fC("attr ".$defs{$dn}{NAME}." hiddenroom ".$hr.",".$alarmhiddenroom); + } + Log3 $hash, 3, "[".$name. " V".$alarmversion."]"." Added hidden room '".$alarmhiddenroom."' to ".$defs{$dn}{NAME}; + } + } + } + my $mga = Alarm_getstate($hash)." Keine Störung"; + readingsSingleUpdate( $hash, "state", $mga, 0 ); +} + +######################################################################################### +# +# Alarm_Set - Implements the Set function +# +# Parameter hash = hash of device addressed +# +######################################################################################### + +sub Alarm_Set($@) { + my ( $hash, $name, $cmd, @args ) = @_; + + if ( ($cmd eq "cancel") || ($cmd eq "sharp") || ($cmd eq "unsharp") ) { + 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"); + }else{ + Alarm_Sharp($name,$args[0],"web","button","unsharp"); + } + return; + } elsif ( $cmd eq "lock" ) { + readingsSingleUpdate( $hash, "lockstate", "locked", 0 ); + return; + } elsif ( $cmd eq "unlock" ) { + readingsSingleUpdate( $hash, "lockstate", "unlocked", 0 ); + 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"; + } +} + +######################################################################################### +# +# Alarm_Set - Implements the Get function +# +# Parameter hash = hash of device addressed +# +######################################################################################### + +sub Alarm_Get($@) { + my ($hash, @a) = @_; + my $res = ""; + + my $arg = (defined($a[1]) ? $a[1] : ""); + if ($arg eq "version") { + return "Alarm.version => $alarmversion"; + } else { + return "Unknown argument $arg choose one of version"; + } +} + +######################################################################################### +# +# 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 +# +# Parameter name = name of the Alarm definition +# level = Alarm level +# dev = name of the device calling the alarm +# evt = event calling the alarm +# act = action - "on" or "off" +# +######################################################################################### + +sub Alarm_Exec($$$$$){ + + my ($name,$level,$dev,$evt,$act) = @_; + my $hash = $defs{$name}; + my $aclvl = $hash->{READINGS}{'level'.$level}{VAL}; + my $msg = ''; + my $cmd; + my $mga; + my $dly; + my @sta; + + #Log3 $hash,1,"[Alarm $level] Exec called with dev $dev evt $evt act $act]"; + + #-- 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") ){ + #-- 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)); + my $stp = $st[0]*60+$st[1]; + my $etp = $et[0]*60+$et[1]; + + my ($sec, $min, $hour, $day, $month, $year, $wday, $yday, $isdst) = localtime(time); + my $ntp = $hour*60+$min; + + if( ($ntp <= $etp) && ($ntp >= $stp) ){ + #-- raised by sensor (attribute values have been controlled in CreateNotifiers) + @sta = split('\|', AttrVal($dev, "alarmSettings", 0)); + if( $sta[2] ){ + $mga = $sta[2]." ".AttrVal($name, "level".$level."msg", 0); + #-- replace some parts + my @evtpart = split(" ",$evt); + $mga =~ s/\$NAME/$dev/g; + $mga =~ s/\$EVENT/$evt/g; + for( my $i=1;$i<= int(@evtpart);$i++){ + $mga =~ s/\$EVTPART$i/$evtpart[$i-1]/g; + } + #-- 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"; + #-- calling actors AFTER state update + $cmd = AttrVal($name, "level".$level."onact", 0); + fhem($cmd); + Log3 $hash,3,$msg; + }else{ + $msg = "[Alarm $level] not raised, alarmSensor $dev has wrong settings"; + Log3 $hash,1,$msg; + } + }else{ + $msg = "[Alarm $level] not raised, not in time slot"; + Log3 $hash,5,$msg; + } + }else{ + $msg = "[Alarm $level] not raised, not sharp or already active"; + Log3 $hash,5,$msg; + } + }elsif( $act eq "off" ){ + #-- 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 BEFORE state update + $cmd = AttrVal($name, "level".$level."offact", 0); + fhem($cmd); + #-- readings + readingsSingleUpdate( $hash, "level".$level,"off",0 ); + $mga = " Level $level canceled"; + readingsSingleUpdate( $hash, "short", "", 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"; + } + #return $msg; +} + +######################################################################################### +# +# Alarm_Sharp - Sharpen 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" +# +######################################################################################### + +sub Alarm_Sharp($$$$$){ + + my ($name,$level,$dev,$evt,$act) = @_; + my $hash = $defs{$name}; + my $aclvl = $hash->{READINGS}{"level"}{VAL}; + my $msg = ''; + 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'); + 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'); + #-- 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; + } + return $msg; +} + +######################################################################################### +# +# Alarm_CreateNotifiers - Create the notifiers +# +# Parameter name = name of the Alarm definition +# +######################################################################################### + +sub Alarm_CreateNotifiers($){ + my ($name) = @_; + + my $ret = ""; + my $res; + + my $hash = $defs{$name}; + #-- don't do anything if locked + if( $hash->{READINGS}{"lockstate"}{VAL} ne "unlocked" ){ + Log3 $hash, 1, "[Alarm] State locked, cannot create new notifiers"; + return "State locked, cannot create new notifiers"; + } + + for( my $level=0;$level<$alarmno;$level++ ){ + + #-- delete old defs in any case + fhem('delete alarm'.$level.'.on.N' ) + 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'}); + + + my @st = split(':',(AttrVal($name, "level".$level."start", 0) ne '')?AttrVal($name, "level".$level."start", 0):'0:00'); + my @et = split(':',(AttrVal($name, "level".$level."end", 0) ne '')?AttrVal($name, "level".$level."end", 0):'23:59'); + + if( (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 ".AttrVal($name, "level".$level."start", 0)." for level".$level."start"; + next; + } + if( (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 ".AttrVal($name, "level".$level."end", 0)." for level".$level."end"; + next; + } + + #-- now set up the command for cancel alarm, and contained in this loop all other notifiers as well + my $cmd = ''; + foreach my $d (keys %defs ) { + next if(IsIgnored($d)); + if( AttrVal($d, "alarmDevice","") eq "Sensor" ) { + my @aval = split('\|',AttrVal($d, "alarmSettings","")); + if( int(@aval) != 4){ + # Log3 $hash, 1, "[Alarm $level] Settings incomplete for sensor $d"; + next; + } + if( (index($aval[0],"alarm".$level) != -1) && ($aval[3] eq "off") ){ + $cmd .= '('.$aval[1].')|'; + #Log3 $hash,1,"[Alarm $level] Adding sensor $d to cancel notifier"; + } + } + } + if( $cmd eq '' ){ + Log3 $hash,1,"[Alarm $level] No \"Cancel\" device defined, level will be ignored"; + } else { + $cmd = substr($cmd,0,length($cmd)-1); + $cmd = 'alarm'.$level.'.off.N notify '.$cmd; + $cmd .= ' {main::Alarm_Exec("'.$name.'",'.$level.',"$NAME","$EVENT","off")}'; + CommandDefine(undef,$cmd); + CommandAttr (undef,'alarm'.$level.'.off.N room '.$alarmpublicroom); + CommandAttr (undef,'alarm'.$level.'.off.N group alarmNotifier'); + Log3 $hash,5,"[Alarm $level] Created cancel notifier"; + + #-- now set up the command for raising alarm - only if cancel exists + $cmd = ''; + my $cmdsh = ""; + my $cmdunsh = ""; + foreach my $d (sort keys %defs ) { + next if(IsIgnored($d)); + if( AttrVal($d, "alarmDevice","") eq "Sensor" ) { + my @aval = split('\|',AttrVal($d, "alarmSettings","")); + if( int(@aval) != 4){ + # Log3 $hash, 1, "[Alarm $level] Settings incomplete for sensor $d"; + next; + } + if( index($aval[0],"alarm".$level) != -1){ + 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"; + } + } + } + } + #-- raise notifier + if( $cmd eq '' ){ + Log3 $hash,1,"[Alarm $level] No \"Raise\" device defined"; + } else { + $cmd = substr($cmd,0,length($cmd)-1); + $cmd = 'alarm'.$level.'.on.N notify '.$cmd; + $cmd .= ' {main::Alarm_Exec("'.$name.'",'.$level.',"$NAME","$EVENT","on")}'; + CommandDefine(undef,$cmd); + CommandAttr (undef,'alarm'.$level.'.on.N room '.$alarmpublicroom); + CommandAttr (undef,'alarm'.$level.'.on.N group alarmNotifier'); + Log3 $hash,5,"[Alarm $level] Created raise notifier"; + + #-- now set up the list of actors + $cmd = ''; + my $cmd2 = ''; + my $nonum = 0; + foreach my $d (sort keys %defs ) { + next if(IsIgnored($d)); + if( AttrVal($d, "alarmDevice","") eq "Actor" ) { + my @aval = split('\|',AttrVal($d, "alarmSettings","")); + if( int(@aval) != 4){ + Log3 $hash, 5, "[Alarm $level] Settings incomplete for actor $d"; + next; + } + if( index($aval[0],"alarm".$level) != -1 ){ + #-- activate without delay + if( $aval[3] eq "0" ){ + $cmd .= $aval[1].';'; + #-- activate with delay + } else { + $nonum++; + my @tarr = split(':',$aval[3]); + if( int(@tarr) == 1){ + if( $aval[3] > 59 ){ + Log3 $hash,3,"[Alarm $level] Invalid delay specification for actor $d: $aval[3] > 59"; + $cmd = ''; + } else { + $cmd .= sprintf('define alarm%1ddly%1d at +00:00:%02d %s;',$level,$nonum,$aval[3],$aval[1]); + } + }elsif( int(@tarr) == 2){ + $cmd .= sprintf('define alarm%1ddly%1d at +00:%02d:%02d %s;',$level,$nonum,$tarr[0],$tarr[1],$aval[1]); + } + } + $cmd2 .= $aval[2].';' + if( $aval[2] ne '' ); + Log3 $hash,5,"[Alarm $level] Adding actor $d to action list"; + } + } + } + if( $cmd ne '' ){ + CommandAttr(undef,$name.' level'.$level.'onact '.$cmd); + CommandAttr(undef,$name.' level'.$level.'offact '.$cmd2); + Log3 $hash,5,"[Alarm $level] Added on/off actors to $name"; + } 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"; + } + #-- 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"; + } + } + } + } + return "Created alarm notifiers"; +} + +######################################################################################### +# +# Alarm_Html - returns HTML code for the Alarm page +# +# Parameter name = name of the Alarm definition +# +######################################################################################### + +sub Alarm_Html($) +{ + my ($name) = @_; + + my $ret = ""; + + 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"; + my $showhelper = ($lockstate eq "unlock") ? 1 : 0; + + #-- + $ret .= "\n"; + + $ret .= "\n"; + $ret .= "". + "\n"; + + #-- settings table + my $row=1; + $ret .= ""; + $ret .= ""; + + #-- sensors table + $row=1; + $ret .= ""; + $ret .= ""; + + #-- actors table + $row=1; + $ret .= ""; + $ret .= "\n"; + + $ret .= "
Settings
\n"; + $ret .= "". + "\n"; + for( my $k=0;$k<$alarmno;$k++ ){ + $row++; + my $sval = AttrVal($name, "level".$k."start", 0); + $sval = "" + if( $sval eq "1"); + my $eval = AttrVal($name, "level".$k."end", 0); + $eval = "" + if( $eval eq "1"); + my $mval = AttrVal($name, "level".$k."msg", 0); + $mval = "" + if( $mval eq "1"); + + my $xval = AttrVal($name, "level".$k."xec", 0); + $ret .= sprintf("\n", ($row&1)?"odd":"even"); + $ret .= "". + ""; + $ret .= sprintf("\n"; + } + $ret .= "
LevelTime [hh:mm]Message Part IISharp/
 Cancel
Alarm $kStart  ". + "End ",($xval eq "sharp")?"checked=\"checked\"":""). + "
Sensors
\n"; + $ret .= "\n"; + foreach my $d (sort keys %defs ) { + next if(IsIgnored($d)); + if( AttrVal($d, "alarmDevice","") eq "Sensor" ) { + my @aval = split('\|',AttrVal($d, "alarmSettings","")); + if( int(@aval) != 4){ + @aval=("","","",""); + } + $row++; + $ret .= sprintf("", ($row&1)?"odd":"even"); + $ret .= "\n"; + $ret .= "\n"; + $ret .= sprintf("\n", + ($aval[3] eq "sh")?"selected=\"seleced\"":"",($aval[3] eq "unsh")?"selected=\"selected\"":""); + } + } + $ret .= "
Notify to Alarm Level
".join("     ",(0..($alarmno-1)))."
". + "Notify on RegExp       Message Part IAction
$d\n"; + for( my $k=0;$k<$alarmno;$k++ ){ + $ret .= sprintf(" ",(index($aval[0],"alarm".$k) != -1)?"checked=\"checked\"":""); + } + $ret .= ""; + $ret .= "
Actors
\n"; + $ret .= "\n"; + foreach my $d (sort keys %defs ) { + next if(IsIgnored($d)); + if( AttrVal($d, "alarmDevice","") eq "Actor" ) { + my @aval = split('\|',AttrVal($d, "alarmSettings","")); + if( int(@aval) != 4){ + @aval=("","","",""); + } + $row++; + $ret .= sprintf("", ($row&1)?"odd":"even"); + $ret .= "\n"; + $ret .= ""; + $ret .= "\n"; + } + } + $ret .= "
Set by Alarm Level
".join("     ",(0..($alarmno-1))). + "
Set Action". + "                  Unset ActionDelay
$d\n"; + for( my $k=0;$k<$alarmno;$k++ ){ + $ret .= sprintf(" ",(index($aval[0],"alarm".$k) != -1)?"checked=\"checked\"":""); + } + $ret .= ""; + $ret .= "
"; + + return $ret; +} + + + +1; + +=pod +=begin 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

+ +
+ +

Attributes

+ +=end html +=begin html_DE + + +

Alarm

+ +=end html_DE +=cut diff --git a/fhem/www/pgm2/alarm.js b/fhem/www/pgm2/alarm.js new file mode 100644 index 000000000..3b427a750 --- /dev/null +++ b/fhem/www/pgm2/alarm.js @@ -0,0 +1,131 @@ +//######################################################################################## +// alarm.js +//######################################################################################## +//# Prof. Dr. Peter A. Henning + +function HashTable() { + this.length = 0; + this.items = new Array(); + for (var i = 0; i < arguments.length; i += 2) { + if (typeof(arguments[i + 1]) != 'undefined') { + this.items[arguments[i]] = arguments[i + 1]; + this.length++; + } + } + + this.removeItem = function(in_key) { + var tmp_value; + if (typeof(this.items[in_key]) != 'undefined') { + this.length--; + var tmp_value = this.items[in_key]; + delete this.items[in_key]; + } + return tmp_value; + } + + this.getItem = function(in_key) { + return this.items[in_key]; + } + + this.setItem = function(in_key, in_value) + { + if (typeof(in_value) != 'undefined') { + if (typeof(this.items[in_key]) == 'undefined') { + this.length++; + } + this.items[in_key] = in_value; + } + return in_value; + } + + this.hasItem = function(in_key) { + return typeof(this.items[in_key]) != 'undefined'; + } + } + +var ah = new HashTable('l0s','','l0e',''); + +//------------------------------------------------------------------------------------------------------ +// Write the Attribute Value +//------------------------------------------------------------------------------------------------------ +function alarm_setAttribute(name, attr, val) {//set Alarm Attribute + 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+'=attr '+name+' '+attr+' '+val); +} + +function alarm_cancel(name,level){ + var val; + var nam; + + 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_Exec("'+name+'",'+level+',"web","button","off")}'); + } + + +function alarm_set(name){ + var val; + var nam; + + 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; + + // saving start and end times + for (var i = 0; i < alarmno; i++){ + FW_cmd(url+'?XHR=1&cmd.'+name+'=attr '+name+' level'+i+'start '+document.getElementById('l'+i+'s').value); + FW_cmd(url+'?XHR=1&cmd.'+name+'=attr '+name+' level'+i+'end ' +document.getElementById('l'+i+'e').value); + FW_cmd(url+'?XHR=1&cmd.'+name+'=attr '+name+' level'+i+'msg ' +document.getElementById('l'+i+'m').value); + if (document.getElementById('l'+i+'x').checked == true ){ + val = "sharp"; + }else{ + val = "unsharp"; + } + FW_cmd(url+'?XHR=1&cmd.'+name+'=attr '+name+' level'+i+'xec ' + val); + } + for (var k in ah.items) { + ah.setItem(k,document.getElementById(k).value); + } + + // acquiring data for each sensor + var sarr = document.getElementsByName('sensor'); + for (var k = 0; k < sarr.length; k++){ + nam = sarr[k].getAttribute('informId'); + val = ""; + for (var i = 0; i < alarmno; i++){ + if (sarr[k].children[1].children[i].checked == true ){ + val += "alarm"+i+","; + } + } + val += "|"+sarr[k].children[2].children[0].value; + val += "|"+sarr[k].children[2].children[1].value; + val += "|"+sarr[k].children[3].children[0].options[sarr[k].children[3].children[0].selectedIndex].value; + FW_cmd(url+'?XHR=1&cmd.'+nam+'=attr '+nam+' alarmSettings ' + val); + } + + // acquiring data for each actor + var aarr = document.getElementsByName('actor'); + for (var k = 0; k < aarr.length; k++){ + nam = aarr[k].getAttribute('informId'); + val = ""; + for (var i = 0; i < alarmno; i++){ + //alert(" Checking "+k+" "+i) + if (aarr[k].children[1].children[i].checked == true ){ + val += "alarm"+i+","; + } + } + val += "|"+aarr[k].children[2].children[0].value; + val += "|"+aarr[k].children[2].children[1].value; + val += "|"+aarr[k].children[3].children[0].value; + FW_cmd(url+'?XHR=1&cmd.'+nam+'=attr '+nam+' alarmSettings ' + val); + } + + // creating notifiers + FW_cmd(url+'?XHR=1&cmd.' + name + ' ={main::Alarm_CreateNotifiers("' + name + '")}'); +} + +