2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 12:49:34 +00:00

95_Alarm.pm: Neue Version mit diversen neuen Features

95_YAAHM.pm: Neue Version mit diversen neuen Features

git-svn-id: https://svn.fhem.de/fhem/trunk@15580 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
phenning 2017-12-09 18:16:42 +00:00
parent f4b5a1950f
commit 5996c2c0ce
4 changed files with 843 additions and 255 deletions

View File

@ -35,13 +35,15 @@ use vars qw(%defs); # FHEM device/button definitions
use vars qw(%intAt); # FHEM at definitions use vars qw(%intAt); # FHEM at definitions
use vars qw($FW_ME); use vars qw($FW_ME);
use JSON; # imports encode_json, decode_json, to_json and from_json.
######################### #########################
# Global variables # Global variables
my $alarmlinkname = "Alarms"; # link text 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 = "3.0"; my $alarmversion = "3.1";
my %alarm_transtable_EN = ( my %alarm_transtable_EN = (
"ok" => "OK", "ok" => "OK",
@ -82,8 +84,11 @@ my %alarm_transtable_EN = (
"disarmaction" => "Disarm Action", "disarmaction" => "Disarm Action",
"waitaction" => "Wait Action", "waitaction" => "Wait Action",
"cancelaction" => "Cancel Action", "cancelaction" => "Cancel Action",
"canceled" => "canceled by:",
"alarm" => "Alarm", "alarm" => "Alarm",
"raised" => "raised by:",
"alarms" => "Alarm System", "alarms" => "Alarm System",
"setparms" => "Set Parameters",
#-- #--
"state" => "Security", "state" => "Security",
"unlocked" => "Unlocked", "unlocked" => "Unlocked",
@ -133,8 +138,11 @@ my %alarm_transtable_EN = (
"disarmaction" => "Unscharf-Aktion", "disarmaction" => "Unscharf-Aktion",
"waitaction" => "Warte-Aktion", "waitaction" => "Warte-Aktion",
"cancelaction" => "Widerruf-Aktion", "cancelaction" => "Widerruf-Aktion",
"canceled" => "widerrufen durch:",
"alarm" => "Alarm", "alarm" => "Alarm",
"raised" => "ausgelöst durch:",
"alarms" => "Alarmanlage", "alarms" => "Alarmanlage",
"setparms" => "Parameter setzen",
#-- #--
"state" => "Sicherheit", "state" => "Sicherheit",
"unlocked" => "Unverschlossen", "unlocked" => "Unverschlossen",
@ -163,9 +171,10 @@ sub Alarm_Initialize ($) {
$hash->{GetFn} = "Alarm_Get"; $hash->{GetFn} = "Alarm_Get";
$hash->{UndefFn} = "Alarm_Undef"; $hash->{UndefFn} = "Alarm_Undef";
#$hash->{AttrFn} = "Alarm_Attr"; #$hash->{AttrFn} = "Alarm_Attr";
my $attst = "lockstate:locked,unlocked testbutton:0,1 statedisplay:simple,color,table,none armdelay armwait armact disarmact cancelact"; my $attst = "lockstate:locked,unlocked testbutton:0,1 statedisplay:simple,color,table,none noicons iconmap disarmcolor ".
"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:0,1 level".$level."onact level".$level."offact "; $attst .=" level".$level."start level".$level."end level".$level."msg level".$level."xec level".$level."onact level".$level."offact ";
} }
$hash->{AttrList} = $attst; $hash->{AttrList} = $attst;
@ -181,7 +190,10 @@ sub Alarm_Initialize ($) {
$alarmlinkname = $alarm_tt->{"alarms"}; $alarmlinkname = $alarm_tt->{"alarms"};
$data{FWEXT}{Alarmx}{LINK} = "?room=".$alarmhiddenroom; $data{FWEXT}{Alarmx}{LINK} = "?room=".$alarmhiddenroom;
$data{FWEXT}{Alarmx}{NAME} = $alarmlinkname; $data{FWEXT}{Alarmx}{NAME} = $alarmlinkname;
$data{FWEXT}{"/Alarm_widget"}{FUNC} = "Alarm_widget";
$data{FWEXT}{"/Alarm_widget"}{FORKABLE} = 0;
return undef; return undef;
} }
@ -215,6 +227,23 @@ sub Alarm_Define ($$) {
$data{FWEXT}{Alarmx}{LINK} = "?room=".$alarmhiddenroom; $data{FWEXT}{Alarmx}{LINK} = "?room=".$alarmhiddenroom;
$data{FWEXT}{Alarmx}{NAME} = $alarmlinkname; $data{FWEXT}{Alarmx}{NAME} = $alarmlinkname;
$attr{$name}{"room"} = $alarmhiddenroom; $attr{$name}{"room"} = $alarmhiddenroom;
#$data{FWEXT}{"/Alarm_widget"}{FUNC} = "Alarm_widget";
#$data{FWEXT}{"/Alarm_widget"}{FORKABLE} = 0;
my $date = Alarm_restore($hash,0);
#-- data seems to be ok, restore
if( defined($date) ){
Alarm_restore($hash,1);
Log3 $name,1,"[Alarm_Define] data hash restored from save file with date $date";
#-- intialization
}else{
for( my $i=0;$i<$alarmno;$i++){
$hash->{DATA}{"armstate"}{"level".$i} = "disarmed";
}
Alarm_save($hash);
Log3 $name,1,"[Alarm_Define] data hash is initialized";
}
$modules{Alarm}{defptr}{$name} = $hash; $modules{Alarm}{defptr}{$name} = $hash;
@ -224,6 +253,24 @@ 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
@ -302,19 +349,14 @@ sub Alarm_CreateEntry($) {
} }
#-- recover state from stored readings #-- recover state from stored readings
readingsBeginUpdate($hash);
for( my $level=0;$level<$alarmno;$level++ ){ for( my $level=0;$level<$alarmno;$level++ ){
my $val = ReadingsVal($name,"level".$level,""); my $val = $hash->{DATA}{"armstate"}{"level".$level};
if( $val eq "disarmed" ){# readingsBulkUpdate( $hash, "level".$level, $val);
CommandAttr (undef,$name.' level'.$level.'xec disarmed');
}elsif( $val eq "armed" ){
CommandAttr (undef,$name.' level'.$level.'xec armed');
}else{
Log3 $hash,1,"[Alarm $level] has undefined save data $val, disarming";
CommandAttr (undef,$name.' level'.$level.'xec disarmed');
}
} }
my $mga = Alarm_getstate($hash)." Keine Störung"; my $mga = Alarm_getstate($hash);
readingsSingleUpdate( $hash, "state", $mga, 1 ); readingsBulkUpdate( $hash, "state", $mga);
readingsEndUpdate( $hash,1 );
} }
@ -344,21 +386,31 @@ sub Alarm_Set($@) {
return "[Alarm] Invalid argument set $cmd"; return "[Alarm] Invalid argument set $cmd";
} }
return; return;
#-----------------------------------------------------------
} elsif ( $cmd =~ /^lock(ed)?$/ ) { } elsif ( $cmd =~ /^lock(ed)?$/ ) {
readingsSingleUpdate( $hash, "lockstate", "locked", 0 ); readingsSingleUpdate( $hash, "lockstate", "locked", 0 );
return; return;
#-----------------------------------------------------------
} elsif ( $cmd =~ /^unlock(ed)?$/ ) { } elsif ( $cmd =~ /^unlock(ed)?$/ ) {
readingsSingleUpdate( $hash, "lockstate", "unlocked", 0 ); readingsSingleUpdate( $hash, "lockstate", "unlocked", 0 );
return; return;
#-----------------------------------------------------------
} elsif ( $cmd =~ /^save/ ) {
return Alarm_save($hash);
#-----------------------------------------------------------
} elsif ( $cmd =~ /^restore/ ) {
return Alarm_restore($hash,1);
} else { } else {
my $str = join(",",(0..($alarmno-1))); my $str = join(",",(0..($alarmno-1)));
return "[Alarm] Unknown argument " . $cmd . ", choose one of canceled:$str armed:$str disarmed:$str locked:noArg unlocked:noArg"; return "[Alarm] Unknown argument " . $cmd . ", choose one of canceled:$str armed:$str disarmed:$str locked:noArg unlocked:noArg save:noArg restore:noArg";
} }
} }
######################################################################################### #########################################################################################
# #
# Alarm_Set - Implements the Get function # Alarm_Get - Implements the Get function
# #
# Parameter hash = hash of device addressed # Parameter hash = hash of device addressed
# #
@ -372,68 +424,10 @@ sub Alarm_Get($@) {
if ($arg eq "version") { if ($arg eq "version") {
return "Alarm.version => $alarmversion"; return "Alarm.version => $alarmversion";
} else { } else {
return "Unknown argument $arg choose one of version"; return "Unknown argument $arg choose one of version:noArg";
} }
} }
#########################################################################################
#
# 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);
my $val;
#--------------------------
if( $type eq "simple" ){
for( my $level=0;$level<$alarmno;$level++ ){
$val = $hash->{READINGS}{"level".$level}{VAL};
if( $val eq "disarmed" ){
$res .= '-';
}elsif( $val eq "armed" ){
$res .= 'O';
}else{
$res .= 'X';
}
}
#--------------------------
}elsif( $type eq "color" ){
$res = '<span style="color:lightgray">';
for( my $level=0;$level<$alarmno;$level++ ){
$val = $hash->{READINGS}{"level".$level}{VAL};
if( $val eq "disarmed" ){
$res .= ' '.$level;
}elsif( $val eq "armed" ){
$res .= ' <span style="width:1ex;font-weight:bold;color:green">'.$level.'</span>';
}else{
$res .= ' <span style="width:1ex;font-weight:bold;color:red">'.$level.'</span>';
}
}
$res.='</span>';
#--------------------------
}elsif( $type eq "table" ){
$res = '<table><tr style="height:1ex">';
for( my $level=0;$level<$alarmno;$level++ ){
$val = $hash->{READINGS}{"level".$level}{VAL};
if( $val eq "disarmed" ){
$res .= '<td style="width:1ex;background-color:lightgray"/>';
}elsif( $val eq "armed" ){
$res .= '<td style="width:1ex;background-color:green"/>';
}else{
$res .= '<td style="width:1ex;background-color:red"/>';
}
}
$res.='</tr></table>';
#--------------------------
}
return $res;
}
######################################################################################### #########################################################################################
# #
# Alarm_getsettings - Helper function to assemble the alarm settings for a device # Alarm_getsettings - Helper function to assemble the alarm settings for a device
@ -462,8 +456,11 @@ sub Alarm_getsettings($$$){
$aval[3] = ""; $aval[3] = "";
$chg = 1; $chg = 1;
} }
#-- #-- unset func may be missing
if( int(@aval) != 4){ $aval[2] = ""
if(!defined($aval[2]));
#-- position 0:set by, 1:set func, 2:unset func, 3:delay
if( int(@aval) != 4 || !defined($aval[0]) || !defined($aval[1]) ){
Log3 $hash, 1, "[Alarm] Settings incomplete for alarmActor $dev"; Log3 $hash, 1, "[Alarm] Settings incomplete for alarmActor $dev";
} }
} }
@ -474,6 +471,57 @@ sub Alarm_getsettings($$$){
return @aval; return @aval;
} }
#########################################################################################
#
# Alarm_save
#
# Parameter hash = hash of the Alarm device
#
#########################################################################################
sub Alarm_save($) {
my ($hash) = @_;
$hash->{DATA}{"savedate"} = localtime(time);
readingsSingleUpdate( $hash, "savedate", $hash->{DATA}{"savedate"}, 1 );
my $json = JSON->new->utf8;
my $jhash0 = eval{ $json->encode( $hash->{DATA} ) };
my $error = FileWrite("AlarmFILE",$jhash0);
#Log 1,"[Alarm_save] error=$error";
return;
}
#########################################################################################
#
# Alarm_restore
#
# Parameter hash = hash of the Alarm device
#
#########################################################################################
sub Alarm_restore($$) {
my ($hash,$doit) = @_;
my $name = $hash->{NAME};
my ($error,$jhash0) = FileRead("AlarmFILE");
if( defined($error) && $error ne "" ){
Log3 $name,1,"[Alarm_restore] read error=$error";
return undef;
}
my $json = JSON->new->utf8;
my $jhash1 = eval{ $json->decode( $jhash0 ) };
my $date = $jhash1->{"savedate"};
#-- just for the first time, reading an old savefile
$date = localtime(time)
if( !defined($date));
readingsSingleUpdate( $hash, "savedate", $date, 0 );
if( $doit==1 ){
$hash->{DATA} = {%{$jhash1}};
Log3 $name,5,"[Alarm_restore] Data hash restored from save file with date ".$date;
return 1;
}else{
return $date;
}
}
######################################################################################### #########################################################################################
# #
# Alarm_Test - Test an actor # Alarm_Test - Test an actor
@ -514,8 +562,8 @@ sub Alarm_Exec($$$$$){
my ($name,$level,$dev,$evt,$act) = @_; my ($name,$level,$dev,$evt,$act) = @_;
my $hash = $defs{$name}; my $hash = $defs{$name};
my $xec = AttrVal($name, "level".$level."xec", 0); my $xec = $hash->{DATA}{"armstate"}{"level".$level};
my $xac = $hash->{READINGS}{'level'.$level}{VAL}; my $xac = $hash->{READINGS}{"level".$level}{VAL};
my $msg = ''; my $msg = '';
my $cmd; my $cmd;
my $mga; my $mga;
@ -629,7 +677,7 @@ sub Alarm_Exec($$$$$){
readingsSingleUpdate( $hash, "level".$level,"canceled",1); readingsSingleUpdate( $hash, "level".$level,"canceled",1);
readingsSingleUpdate( $hash, "level".$level,"armed",1); readingsSingleUpdate( $hash, "level".$level,"armed",1);
readingsSingleUpdate( $hash, "short", "", 0); readingsSingleUpdate( $hash, "short", "", 0);
$mga = Alarm_getstate($hash)." ".$mga; $mga = Alarm_getstate($hash)." ".$alarm_tt->{"canceled"}." ".$dev;
readingsSingleUpdate( $hash, "state", $mga, 1 ); readingsSingleUpdate( $hash, "state", $mga, 1 );
$msg = "[Alarm $level] canceled from device $dev"; $msg = "[Alarm $level] canceled from device $dev";
Log3 $hash,3,$msg; Log3 $hash,3,$msg;
@ -647,6 +695,7 @@ sub Alarm_Exec($$$$$){
# Parameter name = name of the Alarm definition # Parameter name = name of the Alarm definition
# level = Alarm level # level = Alarm level
# dev = name of the device calling the alarm # dev = name of the device calling the alarm
# evt = Event of the device
# act = action - "armed" or "disarmed" # act = action - "armed" or "disarmed"
# #
######################################################################################### #########################################################################################
@ -655,20 +704,26 @@ sub Alarm_Arm($$$$$){
my ($name,$level,$dev,$evt,$act) = @_; my ($name,$level,$dev,$evt,$act) = @_;
my $hash = $defs{$name}; my $hash = $defs{$name};
my $xac = $hash->{READINGS}{"level"}{VAL}; my $xec = $hash->{DATA}{"armstate"}{"level".$level};
my $xec = AttrVal($name, 'level'.$level.'xec', 0); my $xac = $hash->{READINGS}{"level".$level}{VAL};
my $msg = ''; my $msg = '';
my $mga; my $mga;
my $cmd; my $cmd;
#-- arming the alarm #-- arming the alarm
if( ($act eq "arm") && ( $xec ne "armed") ){ if( ($act eq "arm") && ( $xac ne "armed") ){
my $xdl = AttrVal($name, "armdelay", 0); my $xdl = AttrVal($name, "armdelay", 0);
my $cmdwait = AttrVal($name, "armwait", 0); my $cmdwait = AttrVal($name, "armwait", 0);
my $cmdact = AttrVal($name, "armact", 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'); #-- immediate arming
if( ($xdl eq '')||($xdl eq '0:00')||($xdl eq '00:00')||($evt eq "delay") ){
#-- update state display
$hash->{DATA}{"armstate"}{"level".$level} = "armed";
readingsSingleUpdate( $hash, "level".$level,"armed",1 ); readingsSingleUpdate( $hash, "level".$level,"armed",1 );
readingsSingleUpdate( $hash, "state", Alarm_getstate($hash)." ".$hash->{READINGS}{"short"}{VAL}, 1 );
#-- save new state
Alarm_save($hash);
#--transform commands from fhem to perl level #--transform commands from fhem to perl level
my @cmdactarr = split(/;/,$cmdact); my @cmdactarr = split(/;/,$cmdact);
my $cmdactf; my $cmdactf;
@ -681,8 +736,14 @@ sub Alarm_Arm($$$$$){
} }
$msg = "[Alarm $level] armed from alarmSensor $dev with event $evt"; $msg = "[Alarm $level] armed from alarmSensor $dev with event $evt";
Log3 $hash,3,$msg; Log3 $hash,3,$msg;
} elsif( $xdl =~ /([0-9])?:([0-5][0-9])?/ ){ } elsif( $xdl =~ /([0-9])?:([0-5][0-9])?/ ){
CommandAttr(undef,$name.' level'.$level.'xec armwait'); #-- update state display
$hash->{DATA}{"armstate"}{"level".$level} = "armed";
readingsSingleUpdate( $hash, "level".$level,"armwait",1 );
readingsSingleUpdate( $hash, "state", Alarm_getstate($hash)." ".$hash->{READINGS}{"short"}{VAL}, 1 );
#-- save new state
Alarm_save($hash);
#--transform commands from fhem to perl level #--transform commands from fhem to perl level
my @cmdactarr = split(/;/,$cmdact); my @cmdactarr = split(/;/,$cmdact);
my $cmdactf; my $cmdactf;
@ -694,30 +755,31 @@ sub Alarm_Arm($$$$$){
$cmdactf.="fhem(\"".$cmdactarr[$i]."\");;"; $cmdactf.="fhem(\"".$cmdactarr[$i]."\");;";
} }
} }
#-- compose commands #-- compose commands TODO
$cmd = sprintf("define alarm%1d.arm.dly at +00:%02d:%02d {fhem(\"setreading %s level%1d armed\");;fhem(\"attr %s level%1dxec armed\");;%s}", $cmd = sprintf("defmod alarm%1d.arm.dly at +00:%02d:%02d {Alarm_Arm(\"%s\",%1d,\"%s\",\"delay\",\"arm\");;%s}",
$level,$1,$2,$name,$level,$name,$level,$cmdactf); $level,$1,$2,$name,$level,$dev,$cmdactf);
$msg = "[Alarm $level] will be armed from alarmSensor $dev with event $evt, delay $xdl"; $msg = "[Alarm $level] will be armed from alarmSensor $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 #-- define new delayed arm
fhem($cmd); fhem($cmd);
#-- execute armwait action #-- execute armwait action
fhem($cmdwait); fhem($cmdwait);
Log3 $hash,3,$msg; Log3 $hash,1,$msg;
}else{ }else{
$msg = "[Alarm $level] cannot be armed due to wrong delay timespec"; $msg = "[Alarm $level] cannot be armed due to wrong delay timespec";
Log3 $hash,1,$msg; Log3 $hash,1,$msg;
} }
#-- disarming implies canceling as well #-- disarming implies canceling as well
}elsif( ($act eq "disarm") && ($xec ne "disarmed")) { }elsif( ($act eq "disarm") && ($xec ne "disarmed")) {
#-- delete old delayed arm #-- delete stale delayed arm
fhem('delete alarm'.$level.'.arm.dly' ) fhem('delete alarm'.$level.'.arm.dly' )
if( defined $defs{'alarm'.$level.'.arm.dly'}); if( defined $defs{'alarm'.$level.'.arm.dly'});
CommandAttr (undef,$name.' level'.$level.'xec disarmed'); $hash->{DATA}{"armstate"}{"level".$level} = "disarmed";
Alarm_Exec($name,$level,"program","disarm","cancel"); Alarm_Exec($name,$level,"program","disarm","cancel");
#-- update state display
readingsSingleUpdate( $hash, "level".$level,"disarmed",1 ); readingsSingleUpdate( $hash, "level".$level,"disarmed",1 );
readingsSingleUpdate( $hash, "state", Alarm_getstate($hash)." ".$hash->{READINGS}{"short"}{VAL}, 1 );
#-- save new state
Alarm_save($hash);
#-- #--
$msg = "[Alarm $level] disarmed from alarmSensor $dev with event $evt"; $msg = "[Alarm $level] disarmed from alarmSensor $dev with event $evt";
$cmd = AttrVal($name, "disarmact", 0); $cmd = AttrVal($name, "disarmact", 0);
@ -748,6 +810,9 @@ 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
@ -870,9 +935,9 @@ sub Alarm_CreateNotifiers($){
$nonum++; $nonum++;
my @tarr = split(':',$aval[3]); my @tarr = split(':',$aval[3]);
if( int(@tarr) == 2){ if( int(@tarr) == 2){
$cmd .= sprintf('define alarm%1ddly%1d at +00:%02d:%02d %s;',$level,$nonum,$tarr[0],$tarr[1],$aval[1]); $cmd .= sprintf('defmod alarm%1ddly%1d at +00:%02d:%02d %s;',$level,$nonum,$tarr[0],$tarr[1],$aval[1]);
}elsif( int(@tarr) == 3){ }elsif( int(@tarr) == 3){
$cmd .= sprintf('define alarm%1ddly%1d at +%02d:%02d:%02d %s;',$level,$nonum,$tarr[0],$tarr[1],$tarr[2],$aval[1]); $cmd .= sprintf('defmod alarm%1ddly%1d at +%02d:%02d:%02d %s;',$level,$nonum,$tarr[0],$tarr[1],$tarr[2],$aval[1]);
}else{ }else{
Log3 $name,1,"[Alarm $level] Invalid delay specification for actor $d, skipped"; Log3 $name,1,"[Alarm $level] Invalid delay specification for actor $d, skipped";
$cmd .= $aval[1].';'; $cmd .= $aval[1].';';
@ -917,6 +982,183 @@ sub Alarm_CreateNotifiers($){
return "Created alarm notifiers"; return "Created alarm notifiers";
} }
#########################################################################################
#
# Alarm_getstate - Helper function to assemble a state display
#
# Parameter hash = hash of device addressed
#
#########################################################################################
sub Alarm_getstate($) {
my ($hash) = @_;
my $name = $hash->{NAME};
my $res = '';
my $type = AttrVal($hash->{NAME},"statedisplay",0);
my $val;
#--------------------------
if( $type eq "simple" ){
for( my $level=0;$level<$alarmno;$level++ ){
$val = $hash->{READINGS}{"level".$level}{VAL};
if( $val eq "disarmed" ){
$res .= '-';
}elsif( $val eq "armwait" ){
$res .= 'o';
}elsif( $val eq "armed" ){
$res .= 'O';
}else{
$res .= 'X';
}
}
#--------------------------
}else{
my $dac = AttrVal($name,"disarmcolor","lightgray");
my $ac = AttrVal($name,"armcolor","#53f3c7");
my $awc = AttrVal($name,"armwaitcolor","#ffe658");
my $alc = AttrVal($name,"alarmcolor","#fd5777");
if( $type eq "color" ){
$res = '<span style="color:'.$dac.'">';
for( my $level=0;$level<$alarmno;$level++ ){
$val = $hash->{READINGS}{"level".$level}{VAL};
if( $val eq "disarmed" ){
$res .= ' '.$level;
}elsif( $val eq "armwait" ){
$res .= ' <span style="width:1ex;font-weight:bold;color:'.$awc.'">'.$level.'</span>';
}elsif( $val eq "armed" ){
$res .= ' <span style="width:1ex;font-weight:bold;color:'.$ac.'">'.$level.'</span>';
}else{
$res .= ' <span style="width:1ex;font-weight:bold;color:'.$alc.'">'.$level.'</span>';
}
}
$res.='</span>';
#--------------------------
}elsif( $type eq "table" ){
$res = '<table><tr style="height:1ex">';
for( my $level=0;$level<$alarmno;$level++ ){
$val = $hash->{READINGS}{"level".$level}{VAL};
if( $val eq "disarmed" ){
$res .= '<td style="width:1ex;background-color:'.$dac.'"/>';
}elsif( $val eq "armwait" ){
$res .= '<td style="width:1ex;background-color:'.$awc.'"/>';
}elsif( $val eq "armed" ){
$res .= '<td style="width:1ex;background-color:'.$ac.'"/>';
}else{
$res .= '<td style="width:1ex;background-color:'.$alc.'"/>';
}
}
$res.='</tr></table>';
}
}
return $res;
}
#########################################################################################
#
# Alarm_widget - returns animated SVG-code for the Alarm page
#
# Parameter name = name of the Alarm definition
#
#########################################################################################
sub Alarm_widget($){
my ($arg) = @_;
my $name = $FW_webArgs{name};
my $sizep = $FW_webArgs{size};
my $gstate = ( $FW_webArgs{gstate} ? $FW_webArgs{gstate} : "disarmed");
my $dstate = ( $FW_webArgs{dstate} ? $FW_webArgs{dstate} : "--------");
my $inline = 0;
#-- no webarg, check direct parameter. TODO: order
if( !defined($name) || $name eq "" ){
if( $arg =~ /^name=(\w*)&gstate=(.+)&dstate=(.+)&size=(\d+x\d+)/ ){
$name = $1;
$gstate = $2;
$dstate = $3;
$sizep = $4;
$inline = 1;
}
}
Log 1,"[Alarm_widget] name=$name gstate=$gstate dstate=$dstate sizep=$sizep";
$name =~ s/'//g;
my @size=split('x',($sizep ? $sizep : '60x80'));
my ($fillcolor,$fillcolor2);
my $dac = AttrVal($name,"disarmcolor","lightgray");
my $ac = AttrVal($name,"armcolor","#53f3c7");
my $awc = AttrVal($name,"armwaitcolor","#ffe658");
my $alc = AttrVal($name,"alarmcolor","#fd5777");
if($gstate eq "disarmed"){
$fillcolor = AttrVal($name,"disarmcolor",$dac);
$fillcolor2 = "white";
}elsif($gstate eq "armed"){
$fillcolor = AttrVal($name,"armcolor",$ac);
$fillcolor2 = "white";
}elsif($gstate eq "mixed"){
$fillcolor = AttrVal($name,"armwaitcolor",$awc);
$fillcolor2 = "white";
}else{
$fillcolor = AttrVal($name,"alarmcolor",$alc);
$fillcolor2 = $fillcolor;
}
my $hash = $defs{$name};
my $id = $defs{$name}{NR};
my $ret="";
$ret = "<svg viewBox=\"0 0 60 80\" preserveAspectRatio=\"xMidYMin slice\" width=\"100%\" style=\"padding-bottom: 92%; height: 1px; overflow: visible\">";
$ret .= "<g id=\"alarmicon\" transform=\"translate(20,5) scale(1.5,1.5)\">".
"<path class=\"alarmst_b\" id=\"alarmst_ib\" d=\"M 25 6 C 23.354545 6 22 7.3545455 22 9 L 22 10.365234 C 17.172775 11.551105 14.001117 15.612755 14.001953 21.0625 ".
"L 14.001953 28.863281 C 14.001953 31.035281 12.718469 33.494563 11.980469 34.726562 L 10.167969 37.445312 C 9.9629687 37.751312 9.9431875 ".
"38.147656 10.117188 38.472656 C 10.291188 38.797656 10.631 39 11 39 L 39 39 C 39.369 39 39.708813 38.797656 39.882812 38.472656 C 40.056813 ".
"38.147656 40.037031 37.752313 39.832031 37.445312 L 38.044922 34.767578 C 36.668922 32.473578 36 30.587 36 29 L 36 21.199219 C 36 15.68167 ".
"32.827303 11.569596 28 10.369141 L 28 9 C 28 7.3545455 26.645455 6 25 6 z M 25 8 C 25.554545 8 26 8.4454545 26 9 L 26 10.044922 C 25.671339 ".
"10.019952 25.339787 10 25 10 C 24.660213 10 24.328661 10.020256 24 10.044922 L 24 9 C 24 8.4454545 24.445455 8 25 8 z \" fill=\"$fillcolor\" stroke=\"black\" style=\"stroke-width:1.5\"/>";
$ret .= "<path d=\"M 20.423828 41 C 21.197828 42.763 22.955 44 25 44 C 27.045 44 28.802172 42.763 29.576172 41 L 20.423828 41 z\" fill=\"black\"/>";
$ret .= "<path id=\"alarmst_isb\" class=\"alarmst_sb\" d=\"M 3.4804688 9.4765625 ".
"C 1.2493231 13.103089 -2.9605947e-16 17.418182 0 22 C 0 26.581818 1.2493231 30.896911 3.4804688 34.523438 L 5.1855469 33.476562 C 3.1506926 ".
"30.169089 2 26.218182 2 22 C 2 17.781818 3.1506926 13.830911 5.1855469 10.523438 L 3.4804688 9.4765625 z M 46.519531 9.4765625 L 44.814453 ".
"10.523438 C 46.849307 13.83091 48 17.781818 48 22 C 48 26.218182 46.849307 30.169089 44.814453 33.476562 L 46.519531 34.523438 C 48.750677 ".
"30.896911 50 26.581818 50 22 C 50 17.418182 48.750677 13.103089 46.519531 9.4765625 z M 7.8164062 12.140625 C 5.9949036 15.081921 5 ".
"18.353594 5 22 C 5 25.672173 6.1278502 29.047117 7.8085938 31.847656 L 9.5253906 30.818359 C 8.0061341 28.286898 7 25.261827 7 22 C 7 ".
"18.712406 7.8710809 15.852063 9.5175781 13.193359 L 7.8164062 12.140625 z M 42.183594 12.140625 L 40.482422 13.193359 C 42.128919 15.852063 ".
"43 18.712406 43 22 C 43 25.261827 41.993866 28.286898 40.474609 30.818359 L 42.191406 31.847656 C 43.87215 29.047117 45 25.672173 45 22 C 45 ".
"18.353594 44.005097 15.081921 42.183594 12.140625 z\" fill=\"$fillcolor2\" />";
$ret .= "<g id=\"alarmstate\" transform=\"translate(0,30) scale(0.6,0.6)\">";
for( my $level=0;$level<$alarmno;$level++ ){
my $val = $hash->{READINGS}{"level".$level}{VAL};
my $col;
if($val eq "disarmed"){
$col = $dac;
}elsif($val eq "armed"){
$col = $ac;
}elsif($val eq "armwait"){
$col = $awc;
}else{
$col = $alc;
}
$ret .= "<rect class=\"arec\" width=\"10\" height=\"10\" x=\"".(5+10*$level)."\" y=\"35\" fill=\"".$col."\" stroke=\"black\"/>";
}
$ret .= "</g></g></svg>";
return $ret;
if( $inline ){
return $ret;
}else{
$FW_RETTYPE = "image/svg+xml";
$FW_RET="";
FW_pO $ret;
return ($FW_RETTYPE, $FW_RET);
}
}
######################################################################################### #########################################################################################
# #
# Alarm_Html - returns HTML code for the Alarm page # Alarm_Html - returns HTML code for the Alarm page
@ -944,7 +1186,7 @@ sub Alarm_Html($)
} }
} }
#-- #-- update state display
readingsSingleUpdate( $hash, "state", Alarm_getstate($hash)." ".$hash->{READINGS}{"short"}{VAL}, 1 ); readingsSingleUpdate( $hash, "state", Alarm_getstate($hash)." ".$hash->{READINGS}{"short"}{VAL}, 1 );
#-- #--
@ -954,30 +1196,92 @@ sub Alarm_Html($)
#-- #--
$ret .= "<script type=\"text/javascript\" src=\"$FW_ME/pgm2/alarm.js\"></script><script type=\"text/javascript\">\n"; $ret .= "<script type=\"text/javascript\" src=\"$FW_ME/pgm2/alarm.js\"></script><script type=\"text/javascript\">\n";
$ret .= "var alarmno = ".$alarmno.";\n"; $ret .= "var alarmno = ".$alarmno.";\n";
#for( my $k=0;$k<$alarmno;$k++ ){ #-- colors
# $ret .= "ah.setItem('l".$k."s','".AttrVal($name, "level".$k."start", 0)."');\n" $ret .= "var disarmcolor = \"".AttrVal($name,"disarmcolor","lightgray")."\";\n";
# if( defined AttrVal($name, "level".$k."start", 0)); $ret .= "var armwaitcolor = \"".AttrVal($name,"armwaitcolor","#ffe658")."\";\n";
# $ret .= "ah.setItem('l".$k."e','".AttrVal($name, "level".$k."end", 0)."');\n" $ret .= "var armcolor = \"".AttrVal($name,"armcolor","#53f3c7")."\";\n";
# if( defined AttrVal($name, "level".$k."end", 0)); $ret .= "var alarmcolor = \"".AttrVal($name,"alarmcolor","#fd5777")."\";\n";
# $ret .= "ah.setItem('l".$k."m','".AttrVal($name, "level".$k."msg", 0)."');\n" #-- icon map
# if( defined AttrVal($name, "level".$k."msg", 0)); my $iconmap = AttrVal($name,"iconmap","");
# $ret .= "ah.setItem('l".$k."x','".AttrVal($name, "level".$k."xec", 0)."');\n" $ret .= "var iconmap = '".$iconmap."';\n";
# if( defined AttrVal($name, "level".$k."xec", 0));
#} #-- initial state of system
my ($s,$ad,$aa,$al,$at,$detailstate);
$ad = 1;
$aa = 1;
$al = "";
$at = "";
$detailstate = "";
$ret .= "var ast = ['";
for( my $i=0;$i<$alarmno;$i++){
$s = $hash->{READINGS}{"level".$i}{VAL};
if( index($iconmap,$i) > -1 ){
#-- simplify by using state ??
if( ($s eq "disarmed") || ($s eq "armwait") ){
$detailstate .= "-";
}elsif( $s eq "armed" ){
$detailstate .= "O";
}else{
$detailstate .= "X";
}
$ad = $ad & ( ($s eq "disarmed")||($s eq "armwait") );
$aa = $aa & ( $s eq "armed" );
if( $s ne "disarmed" && $s ne "armwait" && $s ne "armed" ){
$al .= $i.",";
$at .= $s.",";
}
}
$ret .= $s."'";
$ret .= ",'"
if( $i != $alarmno-1 );
}
$ret .= "];\n";
$ret .="var aa = ".(($aa == 1) ? "true;\n" : "false;\n");
$ret .="var ad = ".(($ad == 1) ? "true;\n" : "false;\n");
$ret .="var al = '".$al."';\n";
$ret .="var at = '".$at."';\n";
#-- initial state of alarm icon
my $iconstate;
if( $al ne "" ){
$iconstate = $al;
$ret .= "var blinking = 1;\n";
$ret .= "var blinker = setInterval('blinkbell()', 250);\n";
}else{
if( $aa == 1 && $ad == 0 ){
$iconstate = "armed";
}elsif( $aa == 0 && $ad == 1 ){
$iconstate = "disarmed";
}else{
$iconstate = "mixed";
}
$ret .= "var blinking = 0;\n";
$ret .= "var blinker;\n";
}
$ret .= "</script>\n"; $ret .= "</script>\n";
$ret .= "<table class=\"roomoverview\">\n"; $ret .= "<table class=\"roomoverview\">\n";
$ret .= "<tr><td><input type=\"button\" value=\"Set Alarms\" onclick=\"javascript:alarm_set('$name')\"/></td></tr>\n"; #--- here we insert the icon
$ret .= "<tr><td style=\"width:60px;height:80px\">";
$ret .= "<div>".Alarm_widget("name=".$name."&gstate=".$iconstate."&dstate=".$detailstate."&size=60x80")."</div>"
if( AttrVal($name,"noicons",0)==0 );
$ret .= "</td>";
$ret .= "<td style=\"width:150px;vertical-align:center\"><input type=\"button\" value=\"".$alarm_tt->{"setparms"}."\" onclick=\"javascript:alarm_set('$name')\"/></td><td>".
"<div id=\"hid_levels\">";
for( my $k=0;$k<$alarmno;$k++ ){
$ret .= "<div informId=\"$name-level".$k."\" class=\"hid_lx\" style=\"display:none\">".$hash->{READINGS}{"level".$k}{VAL}."</div>";
}
$ret .= "</div></td></tr>\n";
#-- settings table #-- settings table
my $row=1; my $row=1;
$ret .= "<tr><td><div class=\"devType\">".$alarm_tt->{"settings"}."</div></td></tr>"; $ret .= "<tr><td colspan=\"3\"><div class=\"devType\">".$alarm_tt->{"settings"}."</div></td></tr>";
$ret .= "<tr><td><table class=\"block wide\" id=\"settingstable\">\n"; $ret .= "<tr><td colspan=\"3\"><table class=\"block wide\" id=\"settingstable\">\n";
$ret .= "<tr class=\"odd\"><td class=\"col1\" colspan=\"4\"><table id=\"armtable\" border=\"0\">\n"; $ret .= "<tr class=\"odd\"><td class=\"col1\" colspan=\"4\"><table id=\"armtable\" border=\"0\">\n";
$ret .= "<tr class=\"odd\"><td class=\"col1\" style=\"text-align:right\">".$alarm_tt->{"armbutton"}."&nbsp;&#8608</td>"; $ret .= "<tr class=\"odd\"><td class=\"col1\" style=\"text-align:right\">".$alarm_tt->{"armbutton"}."&nbsp;&#8608;</td>";
$ret .= "<td class=\"col2\" style=\"text-align:right\"> ".$alarm_tt->{"waitaction"}." "; $ret .= "<td class=\"col2\" style=\"text-align:right\"> ".$alarm_tt->{"waitaction"}." ";
$ret .= sprintf("<input type=\"text\" id=\"armwait\" size=\"50\" maxlength=\"512\" value=\"%s\"/>",(AttrVal($name, "armwait","") eq "1")?"":AttrVal($name, "armwait","")); $ret .= sprintf("<input type=\"text\" id=\"armwait\" size=\"50\" maxlength=\"512\" value=\"%s\"/>",(AttrVal($name, "armwait","") eq "1")?"":AttrVal($name, "armwait",""));
$ret .= "</td><td class=\"col3\" rowspan=\"2\"> &#8628 ".$alarm_tt->{"delay"}."<br> &#8626"; $ret .= "</td><td class=\"col3\" rowspan=\"2\"> &#8628 ".$alarm_tt->{"delay"}."<br> &#8626;";
$ret .= sprintf("<input type=\"text\" id=\"armdelay\" size=\"4\" maxlength=\"5\" value=\"%s\"/>",(AttrVal($name, "armdelay","0:00") eq "1")?"":AttrVal($name, "armdelay","0:00")); $ret .= sprintf("<input type=\"text\" id=\"armdelay\" size=\"4\" maxlength=\"5\" value=\"%s\"/>",(AttrVal($name, "armdelay","0:00") eq "1")?"":AttrVal($name, "armdelay","0:00"));
$ret .= "</td></tr>\n"; $ret .= "</td></tr>\n";
$ret .= "<tr class=\"even\"><td class=\"col1\"></td><td class=\"col2\" style=\"text-align:right\">".$alarm_tt->{"armaction"}." "; $ret .= "<tr class=\"even\"><td class=\"col1\"></td><td class=\"col2\" style=\"text-align:right\">".$alarm_tt->{"armaction"}." ";
@ -985,7 +1289,7 @@ sub Alarm_Html($)
$ret .= "</td></tr>\n"; $ret .= "</td></tr>\n";
$ret .="<tr class=\"odd\"><td class=\"col1\" style=\"text-align:right\">".$alarm_tt->{"disarmbutton"}."&#8608</td><td class=\"col2\" style=\"text-align:right\">".$alarm_tt->{"disarmaction"}." "; $ret .="<tr class=\"odd\"><td class=\"col1\" style=\"text-align:right\">".$alarm_tt->{"disarmbutton"}."&#8608</td><td class=\"col2\" style=\"text-align:right\">".$alarm_tt->{"disarmaction"}." ";
$ret .= sprintf("<input type=\"text\" id=\"disarmaction\" size=\"50\" maxlength=\"512\" value=\"%s\"/>",(AttrVal($name, "disarmact","") eq "1")?"":AttrVal($name, "disarmact","")); $ret .= sprintf("<input type=\"text\" id=\"disarmaction\" size=\"50\" maxlength=\"512\" value=\"%s\"/>",(AttrVal($name, "disarmact","") eq "1")?"":AttrVal($name, "disarmact",""));
$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 class=\"col1\">".$alarm_tt->{"level"}."</td><td class=\"col2\">".$alarm_tt->{"time"}." [hh:mm]<br/>".
@ -1004,6 +1308,7 @@ sub Alarm_Html($)
if( $mval eq "1"); if( $mval eq "1");
my $xval = AttrVal($name, "level".$k."xec", 0); my $xval = AttrVal($name, "level".$k."xec", 0);
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\"><input type=\"text\" id=\"l".$k."s\" size=\"4\" maxlength=\"120\" value=\"$sval\"/>&nbsp;&nbsp;&nbsp;".
"<input type=\"text\" id=\"l".$k."e\" size=\"4\" maxlength=\"120\" value=\"$eval\"/></td>". "<input type=\"text\" id=\"l".$k."e\" size=\"4\" maxlength=\"120\" value=\"$eval\"/></td>".
@ -1011,12 +1316,12 @@ sub Alarm_Html($)
$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\"><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"; "<input type=\"button\" value=\"".$alarm_tt->{"cancel"}."\" onclick=\"javascript:alarm_cancel('$name','$k')\"/></td></tr>\n";
} }
$ret .= "</table></td></tr></tr>"; $ret .= "</table></td></tr>";
#-- sensors table #-- sensors table
$row=1; $row=1;
$ret .= "<tr><td><div class=\"devType\">".$alarm_tt->{"sensors"}."</div></td></tr>"; $ret .= "<tr><td colspan=\"3\"><div class=\"devType\">".$alarm_tt->{"sensors"}."</div></td></tr>";
$ret .= "<tr><td><table class=\"block wide\" id=\"sensorstable\">\n"; $ret .= "<tr><td colspan=\"3\"><table class=\"block wide\" id=\"sensorstable\">\n";
$ret .= "<tr class=\"odd\" style=\"min-width:100px\"><td/><td class=\"col2\" style=\"min-width:200px\">".$alarm_tt->{"notifyto"}." ".$alarm_tt->{"alarm"}." ".$alarm_tt->{"level"}."<br/>". $ret .= "<tr class=\"odd\" style=\"min-width:100px\"><td/><td class=\"col2\" style=\"min-width:200px\">".$alarm_tt->{"notifyto"}." ".$alarm_tt->{"alarm"}." ".$alarm_tt->{"level"}."<br/>".
join("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;",(0..($alarmno-1)))."</td><td class=\"col3\">". join("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;",(0..($alarmno-1)))."</td><td class=\"col3\">".
$alarm_tt->{"notifyby"}." ".$alarm_tt->{"regexp"}."</td><td class=\"col3\">".$alarm_tt->{"messagepart"}." I</td><td class=\"col4\">".$alarm_tt->{"action"}."</td></tr>\n"; $alarm_tt->{"notifyby"}." ".$alarm_tt->{"regexp"}."</td><td class=\"col3\">".$alarm_tt->{"messagepart"}." I</td><td class=\"col4\">".$alarm_tt->{"action"}."</td></tr>\n";
@ -1042,12 +1347,12 @@ sub Alarm_Html($)
($aval[3] eq "arm")?"selected=\"seleced\"":"",($aval[3] eq "disarm")?"selected=\"selected\"":""); ($aval[3] eq "arm")?"selected=\"seleced\"":"",($aval[3] eq "disarm")?"selected=\"selected\"":"");
} }
} }
$ret .= "</table></td></tr></tr>"; $ret .= "</table></td></tr>";
#-- actors table #-- actors table
$row=1; $row=1;
$ret .= "<tr><td><div class=\"devType\">".$alarm_tt->{"actors"}."</div></td></tr>"; $ret .= "<tr><td colspan=\"3\"><div class=\"devType\">".$alarm_tt->{"actors"}."</div></td></tr>";
$ret .= "<tr><td><table class=\"block wide\" id=\"actorstable\">\n"; $ret .= "<tr><td colspan=\"3\"><table class=\"block wide\" id=\"actorstable\">\n";
$ret .= "<tr class=\"odd\" style=\"min-width:100px\"><td/><td class=\"col2\" style=\"min-width:200px\">".$alarm_tt->{"setby"}." ".$alarm_tt->{"alarm"}." ".$alarm_tt->{"level"}."<br/>".join("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;",(0..($alarmno-1))). $ret .= "<tr class=\"odd\" style=\"min-width:100px\"><td/><td class=\"col2\" style=\"min-width:200px\">".$alarm_tt->{"setby"}." ".$alarm_tt->{"alarm"}." ".$alarm_tt->{"level"}."<br/>".join("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;",(0..($alarmno-1))).
"</td><td class=\"col3\">".$alarm_tt->{"setaction"}; "</td><td class=\"col3\">".$alarm_tt->{"setaction"};
$ret .= "&nbsp; (".$alarm_tt->{"testaction"}.")" $ret .= "&nbsp; (".$alarm_tt->{"testaction"}.")"
@ -1077,7 +1382,7 @@ sub Alarm_Html($)
$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></tr>\n"; $ret .= "</table></td></tr>\n";
$ret .= "</table>"; $ret .= "</table>";
@ -1093,6 +1398,7 @@ sub Alarm_Html($)
<a name="Alarm"></a> <a name="Alarm"></a>
<h3>Alarm</h3> <h3>Alarm</h3>
<ul>
<p> FHEM module to set up a house alarm system with 8 different alarm levels</p> <p> FHEM module to set up a house alarm system with 8 different alarm levels</p>
<a name="Alarmusage"></a> <a name="Alarmusage"></a>
<h4>Usage</h4> <h4>Usage</h4>
@ -1104,6 +1410,11 @@ sub Alarm_Html($)
<code>define &lt;name&gt; Alarm</code> <code>define &lt;name&gt; Alarm</code>
<br />Defines the Alarm system. </p> <br />Defines the Alarm system. </p>
<a name="Alarmset"></a> <a name="Alarmset"></a>
Notes: <ul>
<li>This module uses the global attribute <code>language</code> to determine its output data<br/>
(default: EN=english). For German output set <code>attr global language DE</code>.</li>
<li>This module needs the JSON package.</li>
</ul>
<h4>Set</h4> <h4>Set</h4>
<ul> <ul>
<li><a name="alarm_cancel"> <li><a name="alarm_cancel">
@ -1122,6 +1433,10 @@ sub Alarm_Html($)
</a> </a>
<br />sets the lockstate of the alarm module to <i>locked</i> (i.e., alarm setups <br />sets the lockstate of the alarm module to <i>locked</i> (i.e., alarm setups
may not be changed) resp. <i>unlocked</i> (i.e., alarm setups may be changed>)</li> may not be changed) resp. <i>unlocked</i> (i.e., alarm setups may be changed>)</li>
<li><a name="alarm_save">
<code>set &lt;name&gt; save|restore</code>
</a>
<br />Manually save/restore the arm states to/from the external file AlarmFILE (save done automatically at each state modification, restore at FHEM start)</li>
</ul> </ul>
<a name="Alarmget"></a> <a name="Alarmget"></a>
<h4>Get</h4> <h4>Get</h4>
@ -1145,20 +1460,29 @@ sub Alarm_Html($)
locked|unlocked</code></a> locked|unlocked</code></a>
<br /><i>locked</i> means that alarm setups may not be changed, <i>unlocked</i> <br /><i>locked</i> means that alarm setups may not be changed, <i>unlocked</i>
means that alarm setups may be changed></li> means that alarm setups may be changed></li>
<li><a name="alarm_testbutton"><code>attr &lt;name&gt; testbutton 0|1</code></a> <li><a name="alarm_testbutton"><code>attr &lt;name&gt; testbutton 0|1</code></a>
<br /><i>1</i> means that a test button is displayed for every actor field</li> <br /><i>1</i> means that a test button is displayed for every actor field</li>
<li><a name="alarm_statedisplay"><code>attr &lt;name&gt; statedisplay <li><a name="alarm_statedisplay"><code>attr &lt;name&gt; statedisplay
simple,color,table,none</code></a> simple,color,table,none</code></a>
<br />defines how the state of all eight alarm levels is shown. Example for the case <br />defines how the state of all eight alarm levels is shown. Example for the case
when alarm no. 0 is disarmed and only alarm no. 2 is raised: <ul> when alarm no. 0 is disarmed and only alarm no. 2 is raised: <ul>
<li> simple = -OXOOOOO</li> <li> simple = OXOOOOO</li>
<li> color = <span style="color:lightgray"> 0 </span><span style="font-weight:bold;color:green">1 <span style="font-weight:bold;color:red" <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 lightgray, green and red 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>
<li><a name="alarm_noicons"><code>attr &lt;name&gt; noicons
0|1</code></a>
<br />when set to 1, animated icons are suppressed</li>
<li><a name="alarm_iconmap"><code>attr &lt;name&gt; iconmap <i>list</i></code></a>
<br /> comma separated list of alarm levels for which the main icon/widget is set to disarmed/mixed/armed. No default=icon static</li>
<li><a name="alarm_color"><code>attr &lt;name&gt; disarmcolor|armwaitcolor|armcolor|alarmcolor <i>color</i></code></a>
<br />four color specifications to signal the states disarmed (default <span style="color:lightgray">lightgray</span>),
armwait (default <span style="color:#ffe658">#ffe658</span>),
armed (default <span style="color:#53f3c7">#53f3c7</span>) and alarmed (default <span style="color:#fd5777">#fd5777</span>)</li>
<li><a name="alarm_armdelay"><code>attr &lt;name&gt; armdelay <i>mm:ss</i></code></a> <li><a name="alarm_armdelay"><code>attr &lt;name&gt; armdelay <i>mm:ss</i></code></a>
<br />time until the arming of an alarm becomes operative (0:00 - 9:59 allowed)</li> <br />time until the arming of an alarm becomes operative (0:00 - 9:59 allowed)</li>
<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>
@ -1172,7 +1496,7 @@ sub Alarm_Html($)
<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;start, level&lt;level&gt;end,
level&lt;level&gt;msg, level&lt;level&gt;xec, 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
href="#event-on-update-reading">event-on-update-reading</a>, <a href="#event-on-update-reading">event-on-update-reading</a>, <a
@ -1180,12 +1504,14 @@ sub Alarm_Html($)
>room</a>, <a href="#eventMap">eventMap</a>, <a href="#loglevel">loglevel</a>, >room</a>, <a href="#eventMap">eventMap</a>, <a href="#loglevel">loglevel</a>,
<a href="#webCmd">webCmd</a></li> <a href="#webCmd">webCmd</a></li>
</ul> </ul>
</ul>
=end html =end html
=begin html_DE =begin html_DE
<a name="Alarm"></a> <a name="Alarm"></a>
<h3>Alarm</h3> <h3>Alarm</h3>
<ul>
<a href="https://wiki.fhem.de/wiki/Modul_Alarm">Deutsche Dokumentation im Wiki</a> vorhanden, die englische Version gibt es hier: <a href="/fhem/docs/commandref.html#Alarm">Alarm</a> <a href="https://wiki.fhem.de/wiki/Modul_Alarm">Deutsche Dokumentation im Wiki</a> vorhanden, die englische Version gibt es hier: <a href="/fhem/docs/commandref.html#Alarm">Alarm</a>
</ul>
=end html_DE =end html_DE
=cut =cut

View File

@ -6,8 +6,6 @@
# #
# Prof. Dr. Peter A. Henning # Prof. Dr. Peter A. Henning
# #
# TODO: Löschen readings, wenn timer gelöscht
#
# $Id$ # $Id$
# #
######################################################################################## ########################################################################################
@ -50,7 +48,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.30"; my $yaahmversion = "1.31";
my $firstcall = 1; my $firstcall = 1;
my %yaahm_transtable_EN = ( my %yaahm_transtable_EN = (
@ -328,14 +326,11 @@ my @profmode = ("party","absence","donotdisturb");
my @profday = ("vacation","holiday"); my @profday = ("vacation","holiday");
#-- color schemes #-- color schemes
my $csnum=2;
my @csmode; my @csmode;
my @csmode1 = ("#53f3c7","#8bfa56","#ff9458","#fd5777"); my @csmode1 = ("#53f3c7","#8bfa56","#ff9458","#fd5777");
my @csmode2 = ("#35ffc7","#77ff35","#ff7e35","#ff355e");
my @csstate; my @csstate;
my @csstate1 = ("#53f3c7","#ff9458","#f554e2","#fd5777"); my @csstate1 = ("#53f3c7","#ff9458","#f554e2","#fd5777");
my @csstate2 = ("#35ffc7","#ff7e35","#ff35e2","#ff355e");
#-- temporary fix for update purpose #-- temporary fix for update purpose
sub YAAHM_restore($$){}; sub YAAHM_restore($$){};
@ -358,7 +353,8 @@ sub YAAHM_Initialize ($) {
$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 ".
"timeHelper modeHelper modeAuto:0,1 stateDevices:textField-long stateInterval noicons:0,1 colorscheme:1,2 stateWarning stateHelper stateAuto:0,1 ". "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 ".
"holidayDevices:textField-long vacationDevices:textField-long specialDevices:textField-long"; "holidayDevices:textField-long vacationDevices:textField-long specialDevices:textField-long";
$hash->{AttrList} = $attst; $hash->{AttrList} = $attst;
@ -537,6 +533,32 @@ sub YAAHM_Attr($$$) {
} }
} }
#--------------------------------------- #---------------------------------------
}elsif ( ($cmd eq "set") && ($attrName =~ /modecolor(\d)/) ) {
my $ci = $1;
if( $ci >= 0 && $ci <= 3 ){
$csmode[$ci] = $attrVal;
}
#---------------------------------------
}elsif ( ($cmd eq "del") && ($attrName =~ /modecolor(\d)/) ) {
my $ci = $1;
if( $ci >= 0 && $ci <= 3 ){
$csmode[$ci] = $csmode1[$ci];
}
#---------------------------------------
}elsif ( ($cmd eq "set") && ($attrName =~ /statecolor(\d)/) ) {
my $ci = $1;
if( $ci >= 0 && $ci <= 3 ){
$csstate[$ci] = $attrVal;
}
#---------------------------------------
}elsif ( ($cmd eq "del") && ($attrName =~ /statecolor(\d)/) ) {
my $ci = $1;
if( $ci >= 0 && $ci <= 3 ){
$csstate[$ci] = $csstate1[$ci];
}
#---------------------------------------
}elsif ( ($cmd eq "set") && ($attrName eq "linkname") ) { }elsif ( ($cmd eq "set") && ($attrName eq "linkname") ) {
$yaahmlinkname = $attrVal; $yaahmlinkname = $attrVal;
@ -579,17 +601,7 @@ sub YAAHM_Attr($$$) {
} }
} }
} }
#---------------------------------------
}elsif ( ($cmd eq "set") && ($attrName eq "colorscheme") ) {
Log 1,"==================> colorscheme";
if( $attrVal == 2 ){
@csmode = @csmode2;
@csstate = @csstate2;
}else{
@csmode = @csmode2;
@csstate = @csstate2;
}
#--------------------------------------- #---------------------------------------
}elsif ( ($cmd eq "delete") && ($attrName eq "stateDevices") ) { }elsif ( ($cmd eq "delete") && ($attrName eq "stateDevices") ) {
fhem("deletereading $name sdev_housestate"); fhem("deletereading $name sdev_housestate");
@ -713,6 +725,10 @@ sub YAAHM_Set($@) {
$cmd = "next_".$if; $cmd = "next_".$if;
} }
return YAAHM_nextWeeklyTime($name,$cmd,$args[1],$exec); return YAAHM_nextWeeklyTime($name,$cmd,$args[1],$exec);
#-----------------------------------------------------------
}elsif ( $cmd =~ /^checkstate.*/ ) {
YAAHM_InternalTimer("check",time()+ $args[0], "YAAHM_checkstate", $hash, 0);
#----------------------------------------------------------- #-----------------------------------------------------------
}elsif ( $cmd =~ /^time.*/ ) { }elsif ( $cmd =~ /^time.*/ ) {
@ -749,6 +765,7 @@ sub YAAHM_Set($@) {
$firstcall = 1; $firstcall = 1;
YAAHM_updater($hash); YAAHM_updater($hash);
YAAHM_InternalTimer("check",time()+ 5, "YAAHM_checkstate", $hash, 0); YAAHM_InternalTimer("check",time()+ 5, "YAAHM_checkstate", $hash, 0);
#----------------------------------------------------------- #-----------------------------------------------------------
} elsif ( $cmd eq "createWeekly" ){ } elsif ( $cmd eq "createWeekly" ){
return "[YAAHM] missing name for new weekly profile" return "[YAAHM] missing name for new weekly profile"
@ -781,7 +798,7 @@ sub YAAHM_Set($@) {
#-- find index #-- find index
$imax = int(@{$hash->{DATA}{"WT"}}); $imax = int(@{$hash->{DATA}{"WT"}});
$if= undef; $if= undef;
for( my $j=0;$j<$imax;$j++){ for( my $j=2;$j<$imax;$j++){
if($hash->{DATA}{"WT"}[$j]{"name"} eq $args[0]){ if($hash->{DATA}{"WT"}[$j]{"name"} eq $args[0]){
$if = $j; $if = $j;
last; last;
@ -792,6 +809,25 @@ sub YAAHM_Set($@) {
splice(@{$hash->{DATA}{"WT"}},$if,1); splice(@{$hash->{DATA}{"WT"}},$if,1);
#-- delete timer #-- delete timer
fhem("delete ".$name.".wtimer_".$if.".IF"); fhem("delete ".$name.".wtimer_".$if.".IF");
#-- delete readings
for( my $j=$if;$j<$imax-1;$j++){
$hash->{READINGS}{"ring_".$j}{VAL} = $hash->{READINGS}{"ring_".($j+1)}{VAL};
$hash->{READINGS}{"ring_".$j."_1"}{VAL} = $hash->{READINGS}{"ring_".($j+1)."_1"}{VAL};
$hash->{READINGS}{"next_".$j}{VAL} = $hash->{READINGS}{"next_".($j+1)}{VAL};
$hash->{READINGS}{"today_".$j}{VAL} = $hash->{READINGS}{"today_".($j+1)}{VAL};
$hash->{READINGS}{"today_".$j."_e"}{VAL} = $hash->{READINGS}{"today_".($j+1)."_e"}{VAL};
$hash->{READINGS}{"tomorrow_".$j}{VAL} = $hash->{READINGS}{"tomorrow_".($j+1)}{VAL};
$hash->{READINGS}{"tomorrow_".$j."_e"}{VAL} = $hash->{READINGS}{"tomorrow_".($j+1)."_e"}{VAL};
$hash->{READINGS}{"tr_wake_".$j}{VAL} = $hash->{READINGS}{"tr_wake".($j+1)}{VAL};
}
fhem("deletereading ".$name." ring_".($imax-1));
fhem("deletereading ".$name." ring_".($imax-1)."_1");
fhem("deletereading ".$name." next_".($imax-1));
fhem("deletereading ".$name." today_".($imax-1));
fhem("deletereading ".$name." today_".($imax-1)."_e");
fhem("deletereading ".$name." tomorrow_".($imax-1));
fhem("deletereading ".$name." tomorrow_".($imax-1)."_e");
fhem("deletereading ".$name." tr_wake_".($imax-1));
#-- save everything #-- save everything
YAAHM_save($hash); YAAHM_save($hash);
fhem("save"); fhem("save");
@ -802,7 +838,7 @@ sub YAAHM_Set($@) {
my $str = ""; my $str = "";
return "[YAAHM] Unknown argument " . $cmd . ", choose one of". return "[YAAHM] Unknown argument " . $cmd . ", choose one of".
" manualnext time:".join(',',@times)." mode:".join(',',@modes). " manualnext time:".join(',',@times)." mode:".join(',',@modes).
" state:".join(',',@states)." locked:noArg unlocked:noArg save:noArg restore:noArg initialize:noArg createWeekly deleteWeekly"; " state:".join(',',@states)." locked:noArg unlocked:noArg save:noArg checkstate:0,5,10 restore:noArg initialize:noArg createWeekly deleteWeekly";
} }
} }
@ -1424,19 +1460,6 @@ sub YAAHM_checkstate($) {
return undef return undef
} }
#########################################################################################
#
# YAAHM_SM - State machine
#
# Parameter hash = hash of device addressed
#
#########################################################################################
sub YAAHM_SM($) {
my ($hash) = @_;
}
######################################################################################### #########################################################################################
# #
# YAAHM_informer - Tell FHEMWEB to inform this page # YAAHM_informer - Tell FHEMWEB to inform this page
@ -1721,6 +1744,9 @@ sub YAAHM_setWeeklyTime($) {
#-- today's waketime #-- today's waketime
my $tga = $sg0; my $tga = $sg0;
$tga =~ s/://; $tga =~ s/://;
#-- tomorrow's waketime
my $tgm = $sg1;
$tgm =~ s/://;
#-- "next" input #-- "next" input
my $nga = (defined $ng)?$ng:""; my $nga = (defined $ng)?$ng:"";
$nga =~ s/://; $nga =~ s/://;
@ -1729,6 +1755,20 @@ sub YAAHM_setWeeklyTime($) {
if( $nga eq "" ){ if( $nga eq "" ){
$ring_0 = $sg0; $ring_0 = $sg0;
$ring_1 = $sg1; $ring_1 = $sg1;
$ng = "";
$hash->{DATA}{"WT"}[$i]{ "next" }="";
#-- "next" is the same as today and today not over
}elsif( ($nga eq $tga) && ($tga > $lga)){
$ring_0 = $sg0;
$ring_1 = $sg1;
$ng = "";
$hash->{DATA}{"WT"}[$i]{ "next" }="";
#-- "next" is the same as tomorrow and today over
}elsif( ($nga eq $tgm) && ($tga < $lga)){
$ring_0 = $sg0;
$ring_1 = $sg1;
$ng = "";
$hash->{DATA}{"WT"}[$i]{ "next" }="";
#-- "next" is off #-- "next" is off
}elsif( $nga eq "off" ){ }elsif( $nga eq "off" ){
#-- today's waketime not over => we mean today #-- today's waketime not over => we mean today
@ -1750,10 +1790,11 @@ sub YAAHM_setWeeklyTime($) {
}else{ }else{
#-- "next" after current time => we mean today #-- "next" after current time => we mean today
if( $nga > $lga ){ if( $nga > $lga ){
#-- only restore standard setting #-- only restore standard setting (do we come here at all ?)
if( $ng eq $sg0 ){ if( $ng eq $sg0 ){
$sg0mod = $sg0; $sg0mod = $sg0;
$ring_0 = $sg0; $ring_0 = $sg0;
$ng = "";
$hash->{DATA}{"WT"}[$i]{ "next" } = ""; $hash->{DATA}{"WT"}[$i]{ "next" } = "";
}else{ }else{
$sg0mod = "$ng (man)"; $sg0mod = "$ng (man)";
@ -1762,10 +1803,11 @@ sub YAAHM_setWeeklyTime($) {
$ring_1 = $sg1; $ring_1 = $sg1;
#-- "next" before current time => we mean tomorrow #-- "next" before current time => we mean tomorrow
}else{ }else{
#-- only restore standard setting #-- only restore standard setting (do we come here at all ?)
if( $ng eq $sg1 ){ if( $ng eq $sg1 ){
$sg0mod = $sg1; $sg0mod = $sg1;
$ring_1 = $sg1; $ring_1 = $sg1;
$ng = "";
$hash->{DATA}{"WT"}[$i]{ "next" } = ""; $hash->{DATA}{"WT"}[$i]{ "next" } = "";
}else{ }else{
$sg1mod = "$ng (man)"; $sg1mod = "$ng (man)";
@ -2980,7 +3022,7 @@ sub YAAHM_timewidget($){
FW_pO '<path d="M 0 0 '.$x_morning.' '.$y_morning.' A '.$radius.' '.$radius.' 0 0 1 '.$x_evening.' '.$y_evening.' Z" fill="url(#grad1)"/>'; FW_pO '<path d="M 0 0 '.$x_morning.' '.$y_morning.' A '.$radius.' '.$radius.' 0 0 1 '.$x_evening.' '.$y_evening.' Z" fill="url(#grad1)"/>';
#-- evening to sunset sector #-- evening to sunset sector
$dir = ( $ss < $ev ) ? 1 : 0; $dir = ( $ss < $ev ) ? 0 : 1;
FW_pO '<path d="M 0 0 '.$x_evening.' '.$y_evening.' A '.$radius.' '.$radius.' 0 0 '.$dir.' '.$x_sunset.' '.$y_sunset.' Z" fill="url(#grad2)"/>'; FW_pO '<path d="M 0 0 '.$x_evening.' '.$y_evening.' A '.$radius.' '.$radius.' 0 0 '.$dir.' '.$x_sunset.' '.$y_sunset.' Z" fill="url(#grad2)"/>';
#-- midnight line #-- midnight line
@ -3070,6 +3112,9 @@ sub YAAHM_toptable($){
$ret .= "var csmode = [\"".$csmode[0]."\",\"".$csmode[1]."\",\"".$csmode[2]."\",\"".$csmode[3]."\"];"; $ret .= "var csmode = [\"".$csmode[0]."\",\"".$csmode[1]."\",\"".$csmode[2]."\",\"".$csmode[3]."\"];";
$ret .= "var csstate = [\"".$csstate[0]."\",\"".$csstate[1]."\",\"".$csstate[2]."\",\"".$csstate[3]."\"];"; $ret .= "var csstate = [\"".$csstate[0]."\",\"".$csstate[1]."\",\"".$csstate[2]."\",\"".$csstate[3]."\"];";
$ret .= "var blinking = 0;\n";
$ret .= "var hscolor = \"".$csstate[0]."\";\n";
$ret .= "var dailyno = ".$dailyno.";\n"; $ret .= "var dailyno = ".$dailyno.";\n";
$ret .= "var dailykeys = [\"".join("\",\"",(sort YAAHM_dsort keys %dailytable))."\"];\n"; $ret .= "var dailykeys = [\"".join("\",\"",(sort YAAHM_dsort keys %dailytable))."\"];\n";
@ -3080,9 +3125,14 @@ sub YAAHM_toptable($){
$ret .= "," $ret .= ","
if( $i!=0 ); if( $i!=0 );
$ret .= "\"".$hash->{DATA}{"WT"}[$i]{"name"}."\""; $ret .= "\"".$hash->{DATA}{"WT"}[$i]{"name"}."\"";
} }
$ret .= "];\n"; $ret .= "];\n";
#-- watcher for next hidden divisions
for( my $i=2;$i<$weeklyno;$i++){
$ret .= "$(\"body\").on('DOMSubtreeModified', \"#wt".$i."_o\",function () {nval = document.getElementById(\"wt".$i."_o\").innerHTML;document.getElementById(\"wt".$i."_n\").value = nval;})\n";
}
$ret .= "</script>\n"; $ret .= "</script>\n";
$ret .= "<div informId=\"$name-housestate\" style=\"display:none\" id=\"hid_hs\">".ReadingsVal($name,"housestate",undef)."</div>". $ret .= "<div informId=\"$name-housestate\" style=\"display:none\" id=\"hid_hs\">".ReadingsVal($name,"housestate",undef)."</div>".
"<div informId=\"$name-housemode\" style=\"display:none\" id=\"hid_hm\">".ReadingsVal($name,"housemode",undef)."</div>"; "<div informId=\"$name-housemode\" style=\"display:none\" id=\"hid_hm\">".ReadingsVal($name,"housemode",undef)."</div>";
$ret .= "<table class=\"roomoverview\">\n"; $ret .= "<table class=\"roomoverview\">\n";
@ -3108,7 +3158,7 @@ sub YAAHM_toptable($){
$ret .= "<tr class=\"even\"><td rowspan=\"2\" height=\"40\" id=\"wid_hs\">".YAAHM_statewidget($hash)."</td>". $ret .= "<tr class=\"even\"><td rowspan=\"2\" height=\"40\" id=\"wid_hs\">".YAAHM_statewidget($hash)."</td>".
"<td class=\"dname\" style=\"padding:5px;\">".$yaahm_tt->{"state"}."</td>". "<td class=\"dname\" style=\"padding:5px;\">".$yaahm_tt->{"state"}."</td>".
"<td><div informId=\"$name-tr_housestate\">".ReadingsVal($name,"tr_housestate",undef). "<td><div informId=\"$name-tr_housestate\">".ReadingsVal($name,"tr_housestate",undef).
"</div></td><td style=\"width:20px\"><div informId=\"$name-sym_housestate\" style=\"align:center\">".ReadingsVal($name,"sym_housestate",undef)."</div></td>"; "</div></td><td style=\"width:20px\"><div id=\"sym_hs\" informId=\"$name-sym_housestate\" style=\"align:center\">".ReadingsVal($name,"sym_housestate",undef)."</div></td>";
for( my $i=0; $i<$cols; $i++){ for( my $i=0; $i<$cols; $i++){
if( $i < int(@states)){ if( $i < int(@states)){
$ret .= "<td width=\"120px\"><input type=\"button\" id=\"b_".$states[$i]."\" value=\"".$yaahm_tt->{$states[$i]}. $ret .= "<td width=\"120px\"><input type=\"button\" id=\"b_".$states[$i]."\" value=\"".$yaahm_tt->{$states[$i]}.
@ -3124,7 +3174,7 @@ sub YAAHM_toptable($){
#-- repeat manual next for every weekly table #-- repeat manual next for every weekly table
my $nval = ""; my $nval = "";
my $wupn; my $wupn;
$ret .= "<tr class=\"odd\"><td class=\"col1\" style=\"padding:5px; border-left: 1px solid gray; border-top:1px solid gray; border-bottom:1px solid gray; border-bottom-left-radius:10px; border-top-left-radius:10px;\">".$yaahm_tt->{"manual"}."</td>"; $ret .= "<tr class=\"odd\"><td class=\"col1\" style=\"padding:5px; border-left: 1px solid gray; border-top:1px solid gray; border-bottom:1px solid gray; border-bottom-left-radius:10px; border-top-left-radius:10px;\">".$yaahm_tt->{"manual"}."</td>\n";
for (my $i=0;$i<$weeklyno;$i++){ for (my $i=0;$i<$weeklyno;$i++){
if($i<$weeklyno-1){ if($i<$weeklyno-1){
$styl= "border-bottom:1px solid gray;border-top:1px solid gray"; $styl= "border-bottom:1px solid gray;border-top:1px solid gray";
@ -3134,7 +3184,7 @@ sub YAAHM_toptable($){
$wupn = $hash->{DATA}{"WT"}[$i]{"name"}; $wupn = $hash->{DATA}{"WT"}[$i]{"name"};
$nval = ( defined($hash->{DATA}{"WT"}[$i]{"next"}) ) ? $hash->{DATA}{"WT"}[$i]{"next"} : ""; $nval = ( defined($hash->{DATA}{"WT"}[$i]{"next"}) ) ? $hash->{DATA}{"WT"}[$i]{"next"} : "";
$ret .= sprintf("<td class=\"col2\" style=\"text-align:left;padding:5px;padding-left:10px;padding-right:10px;$styl\">$wupn<br/>". $ret .= sprintf("<td class=\"col2\" style=\"text-align:left;padding:5px;padding-left:10px;padding-right:10px;$styl\">$wupn<br/>".
"<input type=\"text\" id=\"wt%d_n\" informId=\"$name-next_$i\" size=\"4\" maxlength=\"120\" value=\"$nval\" onchange=\"javascript:yaahm_setnext('$name',%d)\"/></td>",$i,$i); "<div style=\"display:none\" id=\"wt%d_o\" informId=\"$name-next_$i\">$nval</div><input type=\"text\" id=\"wt%d_n\" size=\"4\" maxlength=\"120\" value=\"$nval\" onchange=\"javascript:yaahm_setnext('$name',%d)\"/></td>\n",$i,$i,$i);
} }
$ret .= "</tr>\n"; $ret .= "</tr>\n";
$ret .= "</table><br/></td></tr>"; $ret .= "</table><br/></td></tr>";
@ -3546,6 +3596,7 @@ sub YAAHM_Longtable($){
Notes: <ul> Notes: <ul>
<li>This module uses the global attribute <code>language</code> to determine its output data<br/> <li>This module uses the global attribute <code>language</code> to determine its output data<br/>
(default: EN=english). For German output set <code>attr global language DE</code>.</li> (default: EN=english). For German output set <code>attr global language DE</code>.</li>
<li>This module needs the JSON package</li>
</ul> </ul>
<h4>Set</h4> <h4>Set</h4>
<ul> <ul>
@ -3619,7 +3670,7 @@ sub YAAHM_Longtable($){
<li><a name="yaahm_save"> <li><a name="yaahm_save">
<code>set &lt;name&gt; save|restore</code> <code>set &lt;name&gt; save|restore</code>
</a> </a>
<br />Manually save/restore the complete profile data to/from the external file YAAHMFILE (save done automatically at each timer starte, restore at FHEM start)</li> <br />Manually save/restore the complete profile data to/from the external file YAAHMFILE (save done automatically at each timer start, restore at FHEM start)</li>
</ul> </ul>
<a name="YAAHMget"></a> <a name="YAAHMget"></a>
<h4>Get</h4> <h4>Get</h4>
@ -3661,9 +3712,14 @@ sub YAAHM_Longtable($){
<li><a name="yaahm_noicons"><code>attr &lt;name&gt; noicons <li><a name="yaahm_noicons"><code>attr &lt;name&gt; noicons
0|1</code></a> 0|1</code></a>
<br />when set to 1, animated icons are suppressed</li> <br />when set to 1, animated icons are suppressed</li>
<li><a name="yaahm_colorscheme"><code>attr &lt;name&gt; colorscheme <li><a name="yaahm_modecolor"><code>attr &lt;name&gt; modecolor[0|1|2|3] <i>color</i></code></a>
1|2</code></a> <br />four color specifications to signal the modes normal (default <span style="color:#53f3c7">#53f3c7</span>),
<br />color scheme for the icons</li> party (default <span style="color:#8bfa56">#8bfa56</span>), absence (default <span style="color:#ff9458">#ff9458</span>),
donotodisturb (default <span style="color:#fd5777">#fd5777</span>), </li>
<li><a name="yaahm_statecolor"><code>attr &lt;name&gt; statecolor[0|1|2|3] <i>color</i></code></a>
<br />four color specifications to signal the states unsecured (default <span style="color:#53f3c7">#53f3c7</span>),
secured (default <span style="color:#ff9458">#ff9458</span>),
protected (default <span style="color:#f554e2">#f554e2</span>) and guarded (default <span style="color:#fd5777">#fd5777</span>)</li>
<li><a name="yaahm_timehelper"><code>attr &lt;name&gt; timeHelper &lt;name of perl program&gt;</code></a> <li><a name="yaahm_timehelper"><code>attr &lt;name&gt; timeHelper &lt;name of perl program&gt;</code></a>
<br />name of a perl function that is called at each time step of the daily profile and for the two default weekly profiles</li> <br />name of a perl function that is called at each time step of the daily profile and for the two default weekly profiles</li>
<li><a name="yaahm_modehelper"><code>attr &lt;name&gt; modeHelper &lt;name of perl program&gt;</code></a> <li><a name="yaahm_modehelper"><code>attr &lt;name&gt; modeHelper &lt;name of perl program&gt;</code></a>

View File

@ -1,10 +1,10 @@
//######################################################################################## //########################################################################################
// alarm.js // alarm.js
// Version 2.81 // Version 3.1
// See 95_Alarm for licensing // See 95_Alarm for licensing
//######################################################################################## //########################################################################################
//# Prof. Dr. Peter A. Henning //# Prof. Dr. Peter A. Henning
function encodeParm(oldval) { function encodeParm(oldval) {
var newval; var newval;
newval = oldval.replace(/\+/g, '%2B'); newval = oldval.replace(/\+/g, '%2B');
@ -13,134 +13,284 @@ function encodeParm(oldval) {
return newval; return newval;
} }
//var ah = new HashTable('l0s','','l0e',''); //------------------------------------------------------------------------------------------------------
// Animated Icon
//------------------------------------------------------------------------------------------------------
var bellfill;
function blinkbell() {
var w = document.getElementById("alarmicon");
if (w) {
if (bellfill == alarmcolor) {
bellfill = "white";
w.getElementsByClassName("alarmst_b")[0].setAttribute("fill", "white");
w.getElementsByClassName("alarmst_sb")[0].setAttribute("fill", "white");
} else {
bellfill = alarmcolor;
w.getElementsByClassName("alarmst_b")[0].setAttribute("fill", alarmcolor);
w.getElementsByClassName("alarmst_sb")[0].setAttribute("fill", alarmcolor);
}
}
}
function updateIcon(name, alarmst) {
var w = document.getElementById(name);
if (w) {
switch (alarmst) {
case "disarmed":
w.getElementsByClassName("alarmst_b")[0].setAttribute("fill", "white");
w.getElementsByClassName("alarmst_sb")[0].setAttribute("fill", "white");
if (blinking == 1) {
clearInterval(blinker);
blinking = 0;
}
break;
case "mixed":
w.getElementsByClassName("alarmst_b")[0].setAttribute("fill", armwaitcolor);
w.getElementsByClassName("alarmst_sb")[0].setAttribute("fill", "white");
if (blinking == 1) {
clearInterval(blinker);
blinking = 0;
}
break;
case "armed":
w.getElementsByClassName("alarmst_b")[0].setAttribute("fill", armcolor);
w.getElementsByClassName("alarmst_sb")[0].setAttribute("fill", "white");
if (blinking == 1) {
clearInterval(blinker);
blinking = 0;
}
break;
default:
if (blinking == 0) {
blinker = setInterval('blinkbell()', 250);
blinking = 1;
}
}
}
}
$("body").on('DOMSubtreeModified', "#hid_levels", function () {
var w = document.getElementById("hid_levels");
var v = document.getElementById("alarmicon");
var t = v.getElementsByClassName("arec");
var ifnd;
var sfnd;
var col;
for (i = 0; i < alarmno; i++) {
var s = w.getElementsByClassName("hid_lx")[i].innerHTML;
if (ast[i] != s) {
switch(s){
case "disarmed":
col = disarmcolor;
break;
case "armwait":
col = armwaitcolor;
break;
case "armed":
col = armcolor;
break;
default:
col = alarmcolor
}
t[i].setAttribute("fill",col);
ast[i] = s;
ifnd = i;
sfnd = s;
}
}
if (ifnd && (iconmap.includes(ifnd))) {
var aan = true;
var adn = true;
var aln = "";
var atn = "";
for (i = 0; i < alarmno; i++) {
if (iconmap.includes(i)) {
var s = ast[i];
if (s != "disarmed" && s != "armwait" && s != "armed") {
aln = aln + i + ",";
atn = atn + s + ",";
} else {
adn = adn && ((s == "disarmed")||(s == "armwait"));
aan = aan && (s == "armed");
}
}
}
if (adn != ad || aan != aa || aln != al) {
aa = aan;
ad = adn;
al = aln;
at = atn;
var iconstate;
if (al != "") {
iconstate = al;
} else {
if (aa && (! ad)) {
iconstate = "armed";
} else {
if ((! aa) && ad) {
iconstate = "disarmed";
} else {
iconstate = "mixed";
}
}
}
updateIcon('alarmicon', iconstate);
}
}
});
//------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------
// Write the Attribute Value // Write the Attribute Value
//------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------
function alarm_setAttribute(name, attr, val) {//set Alarm Attribute
var location = document.location.pathname; function alarm_setAttribute(name, attr, val) {
if (location.substr(location.length-1,1) == '/') {location = location.substr(0,location.length-1);} //set Alarm Attribute
var url = document.location.protocol+"//"+document.location.host+location; var location = document.location.pathname;
FW_cmd(url+'?XHR=1&cmd.'+name+'=attr '+name+' '+encodeParm(attr)+' '+ encodeParm(val)); 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 + ' ' + encodeParm(attr) + ' ' + encodeParm(val));
} }
function alarm_cancel(name,level){ function alarm_cancel(name, level) {
var val; var val;
var nam; var nam;
var location = document.location.pathname; var location = document.location.pathname;
if (location.substr(location.length-1,1) == '/') {location = location.substr(0,location.length-1);} if (location.substr(location.length -1, 1) == '/') {
var url = document.location.protocol+"//"+document.location.host+location; 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")}');
}
FW_cmd(url+'?XHR=1&cmd.'+name+'={Alarm_Exec("'+name+'",'+level+',"web","button","off")}'); function alarm_arm(name, level) {
}
function alarm_arm(name,level){
var val; var val;
var nam; var nam;
var command = document.getElementById('l'+level+'x').checked; var command = document.getElementById('l' + level + 'x').checked;
if (command == true){ if (command == true) {
command="arm"; command = "arm";
}else{ } else {
command="disarm"; command = "disarm";
} }
var location = document.location.pathname; var location = document.location.pathname;
if (location.substr(location.length-1,1) == '/') {location = location.substr(0,location.length-1);} if (location.substr(location.length -1, 1) == '/') {
var url = document.location.protocol+"//"+document.location.host+location; 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 + '")}');
}
FW_cmd(url+'?XHR=1&cmd.'+name+'={Alarm_Arm("'+name+'",'+level+',"web","button","'+command+'")}'); function alarm_testaction(name, dev, type) {
}
function alarm_testaction(name,dev,type){
var cmd; var cmd;
var nam; var nam;
if(type == 'set'){ if (type == 'set') {
cmd = document.getElementById(dev).parentElement.children[2].children[0].value; cmd = document.getElementById(dev).parentElement.children[2].children[0].value;
}else{ } else {
cmd = document.getElementById(dev).parentElement.children[3].children[0].value; cmd = document.getElementById(dev).parentElement.children[3].children[0].value;
} }
var cmds; var cmds;
cmds = cmd.replace(/\\/g, '\\'); cmds = cmd.replace(/\\/g, '\\');
cmds = cmds.replace(/\'/g, '\"'); cmds = cmds.replace(/\'/g, '\"');
cmds = cmds.replace(/\$/g, '\\$'); cmds = cmds.replace(/\$/g, '\\$');
alert( cmds ); alert(cmds);
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_Test("'+name+'","' + cmds + '")}');
}
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_Test("' + name + '","' + cmds + '")}');
}
function alarm_set(name){
function alarm_set(name) {
var val; var val;
var nam; var nam;
var location = document.location.pathname; var location = document.location.pathname;
if (location.substr(location.length-1,1) == '/') {location = location.substr(0,location.length-1);} if (location.substr(location.length -1, 1) == '/') {
var url = document.location.protocol+"//"+document.location.host+location; location = location.substr(0, location.length -1);
}
var url = document.location.protocol + "//" + document.location.host + location;
// saving arm data // 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 + ' armdelay ' + document.getElementById('armdelay').value);
FW_cmd(url+'?XHR=1&cmd.'+name+'=attr '+name+' armwait '+ encodeParm(document.getElementById('armwait').value)); FW_cmd(url + '?XHR=1&cmd.' + name + '=attr ' + name + ' armwait ' + encodeParm(document.getElementById('armwait').value));
FW_cmd(url+'?XHR=1&cmd.'+name+'=attr '+name+' armact '+ encodeParm(document.getElementById('armaction').value)); FW_cmd(url + '?XHR=1&cmd.' + name + '=attr ' + name + ' armact ' + encodeParm(document.getElementById('armaction').value));
FW_cmd(url+'?XHR=1&cmd.'+name+'=attr '+name+' disarmact '+ encodeParm(document.getElementById('disarmaction').value)); FW_cmd(url + '?XHR=1&cmd.' + name + '=attr ' + name + ' disarmact ' + encodeParm(document.getElementById('disarmaction').value));
FW_cmd(url+'?XHR=1&cmd.'+name+'=attr '+name+' cancelact '+ encodeParm(document.getElementById('cancelaction').value)); FW_cmd(url + '?XHR=1&cmd.' + name + '=attr ' + name + ' cancelact ' + encodeParm(document.getElementById('cancelaction').value));
// saving start and end times // saving start and end times
for (var i = 0; i < alarmno; i++){ for (var i = 0;
FW_cmd(url+'?XHR=1&cmd.'+name+'=attr '+name+' level'+i+'start '+document.getElementById('l'+i+'s').value); i < alarmno;
FW_cmd(url+'?XHR=1&cmd.'+name+'=attr '+name+' level'+i+'end ' +document.getElementById('l'+i+'e').value); i++) {
FW_cmd(url+'?XHR=1&cmd.'+name+'=attr '+name+' level'+i+'msg ' +document.getElementById('l'+i+'m').value); FW_cmd(url + '?XHR=1&cmd.' + name + '=attr ' + name + ' level' + i + 'start ' + document.getElementById('l' + i + 's').value);
if (document.getElementById('l'+i+'x').checked == true ){ 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 = "armed"; val = "armed";
}else{ } else {
val = "disarmed"; val = "disarmed";
} }
FW_cmd(url+'?XHR=1&cmd.'+name+'=attr '+name+' level'+i+'xec ' + val); FW_cmd(url + '?XHR=1&cmd.' + name + '=attr ' + name + ' level' + i + 'xec ' + val);
} }
//for (var k in ah.items) { //for (var k in ah.items) {
// ah.setItem(k,document.getElementById(k).value); // ah.setItem(k,document.getElementById(k).value);
//} //}
// acquiring data for each sensor // acquiring data for each sensor
var sarr = document.getElementsByName('sensor'); var sarr = document.getElementsByName('sensor');
for (var k = 0; k < sarr.length; k++){ for (var k = 0;
nam = sarr[k].getAttribute('informId'); k < sarr.length;
val = ""; k++) {
for (var i = 0; i < alarmno; i++){ nam = sarr[k].getAttribute('informId');
if (sarr[k].children[1].children[i].checked == true ){ val = "";
val += "alarm"+i+","; 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[0].value;
val += "|"+sarr[k].children[3].children[0].value; val += "|" + sarr[k].children[3].children[0].value;
val += "|"+sarr[k].children[4].children[0].options[sarr[k].children[4].children[0].selectedIndex].value; val += "|" + sarr[k].children[4].children[0].options[sarr[k].children[4].children[0].selectedIndex].value;
FW_cmd(url+'?XHR=1&cmd.'+nam+'=attr '+nam+' alarmSettings ' + encodeParm(val)); FW_cmd(url + '?XHR=1&cmd.' + nam + '=attr ' + nam + ' alarmSettings ' + encodeParm(val));
} }
// acquiring data for each actor // acquiring data for each actor
var aarr = document.getElementsByName('actor'); var aarr = document.getElementsByName('actor');
for (var k = 0; k < aarr.length; k++){ for (var k = 0;
nam = aarr[k].getAttribute('informId'); k < aarr.length;
val = ""; k++) {
for (var i = 0; i < alarmno; i++){ nam = aarr[k].getAttribute('informId');
val = "";
for (var i = 0;
i < alarmno;
i++) {
//alert(" Checking "+k+" "+i) //alert(" Checking "+k+" "+i)
if (aarr[k].children[1].children[i].checked == true ){ if (aarr[k].children[1].children[i].checked == true) {
val += "alarm"+i+","; val += "alarm" + i + ",";
} }
} }
val += "|"+aarr[k].children[2].children[0].value; val += "|" + aarr[k].children[2].children[0].value;
val += "|"+aarr[k].children[3].children[0].value; val += "|" + aarr[k].children[3].children[0].value;
val += "|"+aarr[k].children[4].children[0].value; val += "|" + aarr[k].children[4].children[0].value;
FW_cmd(url+'?XHR=1&cmd.'+nam+'=attr '+nam+' alarmSettings ' + encodeParm(val)); FW_cmd(url + '?XHR=1&cmd.' + nam + '=attr ' + nam + ' alarmSettings ' + encodeParm(val));
} }
// creating notifiers // creating notifiers
FW_cmd(url+'?XHR=1&cmd.' + name + ' ={main::Alarm_CreateNotifiers("' + name + '")}'); FW_cmd(url + '?XHR=1&cmd.' + name + ' ={main::Alarm_CreateNotifiers("' + name + '")}');
}
}

View File

@ -98,10 +98,62 @@ function yaahm_setnext(name, i) {
FW_cmd(url + '?XHR=1&cmd.' + name + '={main::YAAHM_nextWeeklyTime("' + name + '","next_' + i + '","' + nval + '")}'); FW_cmd(url + '?XHR=1&cmd.' + name + '={main::YAAHM_nextWeeklyTime("' + name + '","next_' + i + '","' + nval + '")}');
} }
//------------------------------------------------------------------------------------------------------
// Write field value for next - first two here, the others dynamically
//------------------------------------------------------------------------------------------------------
$("body").on('DOMSubtreeModified', "#wt0_o",
function () {
nval = document.getElementById("wt0_o").innerHTML;
document.getElementById("wt0_n").value = nval;
})
$("body").on('DOMSubtreeModified', "#wt1_o",
function () {
nval = document.getElementById("wt1_o").innerHTML;
document.getElementById("wt1_n").value = nval;
})
//------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------
// Animate housestate icon // Animate housestate icon
//------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------
var blinker;
var hsfill;
var hscolor;
function blinkhs() {
var w = document.getElementById("wid_hs");
if (w) {
if (hsfill == hscolor) {
hsfill = "white";
w.getElementsByClassName("hs_is")[0].setAttribute("fill", "white");
} else {
hsfill = hscolor;
w.getElementsByClassName("hs_is")[0].setAttribute("fill", hscolor);
}
}
}
$("body").on('DOMSubtreeModified', "#sym_hs",
function () {
var w = document.getElementById("wid_hs");
if (w) {
var symnew = document.getElementById("sym_hs").innerHTML;
if (blinking == 1 && symnew.includes("green")) {
clearInterval(blinker);
blinking = 0;
w.getElementsByClassName("hs_is")[0].setAttribute("fill", hscolor);
} else {
if (blinking == 0 && ! symnew.includes("green")) {
hscolor = w.getElementsByClassName("hs_is")[0].getAttribute("fill");
blinker = setInterval('blinkhs()', 1000);
blinking = 1;
}
}
}
})
$("body").on('DOMSubtreeModified', "#hid_hs", $("body").on('DOMSubtreeModified', "#hid_hs",
function () { function () {
var hsnew = document.getElementById("hid_hs").innerHTML; var hsnew = document.getElementById("hid_hs").innerHTML;
@ -111,6 +163,7 @@ function () {
if (w) { if (w) {
switch (hsnew) { switch (hsnew) {
case "unsecured": case "unsecured":
hscolor = csstate[0];
w.getElementsByClassName("hs_is")[0].setAttribute("fill", csstate[0]); w.getElementsByClassName("hs_is")[0].setAttribute("fill", csstate[0]);
w.getElementsByClassName("hs_smb")[0].setAttribute("visibility", "hidden"); w.getElementsByClassName("hs_smb")[0].setAttribute("visibility", "hidden");
w.getElementsByClassName("hs_unlocked")[0].setAttribute("visibility", "visible"); w.getElementsByClassName("hs_unlocked")[0].setAttribute("visibility", "visible");
@ -118,6 +171,7 @@ function () {
w.getElementsByClassName("hs_eye")[0].setAttribute("visibility", "hidden"); w.getElementsByClassName("hs_eye")[0].setAttribute("visibility", "hidden");
break; break;
case "secured": case "secured":
hscolor = csstate[1];
w.getElementsByClassName("hs_is")[0].setAttribute("fill", csstate[1]); w.getElementsByClassName("hs_is")[0].setAttribute("fill", csstate[1]);
w.getElementsByClassName("hs_smb")[0].setAttribute("visibility", "hidden"); w.getElementsByClassName("hs_smb")[0].setAttribute("visibility", "hidden");
w.getElementsByClassName("hs_unlocked")[0].setAttribute("visibility", "hidden"); w.getElementsByClassName("hs_unlocked")[0].setAttribute("visibility", "hidden");
@ -125,6 +179,7 @@ function () {
w.getElementsByClassName("hs_eye")[0].setAttribute("visibility", "hidden"); w.getElementsByClassName("hs_eye")[0].setAttribute("visibility", "hidden");
break; break;
case "protected": case "protected":
hscolor = csstate[2];
w.getElementsByClassName("hs_is")[0].setAttribute("fill", csstate[2]); w.getElementsByClassName("hs_is")[0].setAttribute("fill", csstate[2]);
w.getElementsByClassName("hs_smb")[0].setAttribute("visibility", "visible"); w.getElementsByClassName("hs_smb")[0].setAttribute("visibility", "visible");
w.getElementsByClassName("hs_unlocked")[0].setAttribute("visibility", "hidden"); w.getElementsByClassName("hs_unlocked")[0].setAttribute("visibility", "hidden");
@ -132,6 +187,7 @@ function () {
w.getElementsByClassName("hs_eye")[0].setAttribute("visibility", "hidden"); w.getElementsByClassName("hs_eye")[0].setAttribute("visibility", "hidden");
break; break;
case "guarded": case "guarded":
hscolor = csstate[3];
w.getElementsByClassName("hs_is")[0].setAttribute("fill", csstate[3]); w.getElementsByClassName("hs_is")[0].setAttribute("fill", csstate[3]);
w.getElementsByClassName("hs_smb")[0].setAttribute("visibility", "visible"); w.getElementsByClassName("hs_smb")[0].setAttribute("visibility", "visible");
w.getElementsByClassName("hs_unlocked")[0].setAttribute("visibility", "hidden"); w.getElementsByClassName("hs_unlocked")[0].setAttribute("visibility", "hidden");