From 24c0dc9d53ac9082b74e4fc5ce9e3c823dc7fff5 Mon Sep 17 00:00:00 2001 From: phenning <> Date: Thu, 28 Feb 2019 10:11:26 +0000 Subject: [PATCH] 95_YAAHM.pm: neue Version git-svn-id: https://svn.fhem.de/fhem/trunk@18759 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/95_YAAHM.pm | 997 +++++++++++++++++++++++++++++------------ fhem/www/pgm2/yaahm.js | 79 +++- 2 files changed, 775 insertions(+), 301 deletions(-) diff --git a/fhem/FHEM/95_YAAHM.pm b/fhem/FHEM/95_YAAHM.pm index 2b95242b5..d2f76abf3 100644 --- a/fhem/FHEM/95_YAAHM.pm +++ b/fhem/FHEM/95_YAAHM.pm @@ -3,9 +3,6 @@ # YAAHM.pm # # Yet Another Auto Home Module for FHEM -# -# Problem: Wenn man trotz Feiertag geweckt werden möchte, wird zwar die Weckzeit richtig gesetzt - -# aber da "Wakeup" voM Timer ausgelöst wird und der nach den Zusatzbedingungen daytype etc fragt, gehen die rollläden eben nicht auf # # Prof. Dr. Peter A. Henning # @@ -50,7 +47,7 @@ my $yaahmname; my $yaahmlinkname = "Profile"; # link text my $yaahmhiddenroom = "ProfileRoom"; # hidden room my $yaahmpublicroom = "Unsorted"; # public room -my $yaahmversion = "2.02"; +my $yaahmversion = "3.0"; my $firstcall = 1; my %yaahm_transtable_EN = ( @@ -67,6 +64,10 @@ my %yaahm_transtable_EN = ( "swoff" => "switched off", "and" => "and", "clock" => "", + "device" => "Device", + "devices" => "Devices ", + "deviceaction" => "Device Action ", + "deviceactions" => "Device Actions ", "active" => "Active", "inactive" => "Inactive", "overview" => "Summary", @@ -74,6 +75,8 @@ my %yaahm_transtable_EN = ( "event" => "Event", "time" => "Time", "timer" => "Timer", + "earliest" => "Earliest", + "latest" => "Latest", "action" => "Action", "weekly" => "Weekly ", "day" => "Day", @@ -109,10 +112,6 @@ my %yaahm_transtable_EN = ( "date" => "Date", "today" => "Today", "tomorrow" => "Tomorrow", - "workday" => "Workday", - "weekend" => "Weekend", - "vacation" => "Vacation", - "holiday" => "Holiday", "weekday" => "Day of Week", #-- "mode" => "Mode", @@ -137,6 +136,10 @@ my %yaahm_transtable_EN = ( "friday" => ["Friday","Fri"], "saturday" => ["Saturday","Sat"], "sunday" => ["Sunday","Sun"], + "weekend" => ["Weekend","We"], + "holiday" => ["Holiday","Hol"], + "vacation" => ["Vacation","Vac"], + "workday" => ["Workday","Wor"], #-- "spring" => "Spring", "summer" => "Summer", @@ -153,6 +156,10 @@ my %yaahm_transtable_EN = ( "next" => "Nächste", "manual" => "Manuelle Zeit", "clock" => "Uhr", + "device" => "Gerät", + "devices" => "Geräte-", + "deviceaction" => "Geräte-Aktions-", + "deviceactions" => "Geräte-Aktionen", "exceptly" => "ausnahmsweise", "undecid" => "nicht bestimmbar", "off" => "Aus", @@ -165,6 +172,8 @@ my %yaahm_transtable_EN = ( "event" => "Event", "time" => "Zeit", "timer" => "Timer", + "earliest" => "Frühestens", + "latest" => "Spätestens", "action" => "Aktion", "weekly" => "Wochen-", "day" => "Tag", @@ -200,10 +209,6 @@ my %yaahm_transtable_EN = ( "date" => "Termin", "today" => "Heute", "tomorrow" => "Morgen", - "workday" => "Arbeitstag", - "weekend" => "Wochenende", - "vacation" => "Ferientag", - "holiday" => "Feiertag", "weekday" => "Wochentag", #-- "mode" => "Modus", @@ -228,6 +233,10 @@ my %yaahm_transtable_EN = ( "friday" => ["Freitag","Fr"], "saturday" => ["Samstag","Sa"], "sunday" => ["Sonntag","So"], + "weekend" => ["Wochenende","We"], + "holiday" => ["Feiertag","Fei"], + "vacation" => ["Urlaubstag","Url"], + "workday" => ["Arbeitstag","Arb"], #-- "spring" => "Frühling", "summer" => "Sommer", @@ -262,6 +271,8 @@ my %defaultdailytable = ( "sleep" => ["22:30",undef,undef,undef], "night" => ["22:00",undef,undef,undef], "beforemidnight" => [undef,"00:05",undef,undef]); + +my $defaultdailykeys = "(".join(")|(",keys %defaultdailytable).")"; my %dailytable = (); @@ -276,7 +287,9 @@ my @weeklytable = ( "thursday", "friday", "saturday", - "sunday"); + "sunday", + "holiday", + "vacation"); my %defaultwakeuptable = ( "name" => "", @@ -327,7 +340,7 @@ my @seasons = ( #-- modes or day types that affect the profile my @profmode = ("party","absence","donotdisturb"); -my @profday = ("vacation","holiday"); +my @profday = ("holiday","vacation"); #-- color schemes my @csmode; @@ -359,6 +372,9 @@ sub YAAHM_Initialize ($) { my $attst = "linkname publicroom hiddenroom lockstate:locked,unlocked simulation:0,1 norepeat: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 ". + "deviceActions:textField-long ". + "sunrise:SunRise,AstroTwilightMorning,NauticTwilightMorning,CivilTwilightMorning,CustomTwilightMorning ". + "sunset:SunSet,AstroTwilightEvening,NauticTwilightEvening,CivilTwilightEvening,CustomTwilightEvening ". "holidayDevices:textField-long vacationDevices:textField-long specialDevices:textField-long"; $hash->{AttrList} = $attst; @@ -432,13 +448,20 @@ sub YAAHM_Define ($$) { $attr{$name}{"room"} = $yaahmhiddenroom; my $date = YAAHM_restore($hash,0); + #-- data seems to be ok, restore if( defined($date) ){ YAAHM_restore($hash,1); Log3 $name,1,"[YAAHM_Define] data hash restored from save file with date $date"; + if( !defined($hash->{DATA}{"XT"}) ){ + $hash->{DATA}{"XT"} = {}; + } #-- intialization }else{ Log3 $name,1,"[YAAHM_Define] data hash is initialized"; + #-- ZERO device action entries profile + $hash->{DATA}{"XT"} = {}; + #-- clone daily default profile $hash->{DATA}{"DT"} = {%defaultdailytable}; @@ -446,9 +469,10 @@ sub YAAHM_Define ($$) { $hash->{DATA}{"WT"} = (); push(@{$hash->{DATA}{"WT"}},{%defaultwakeuptable}); $hash->{DATA}{"WT"}[0]{"name"} = $yaahm_tt->{"wakeup"}; - push(@{$hash->{DATA}{"WT"}},{%defaultsleeptable}); + push(@{$hash->{DATA}{"WT"}},{%defaultsleeptable}); $hash->{DATA}{"WT"}[1]{"name"} = $yaahm_tt->{"sleep"}; - + + #-- clone days for today and tomorrow $hash->{DATA}{"DD"} = (); push(@{$hash->{DATA}{"DD"}},{%defaultdayproperties}); @@ -834,6 +858,8 @@ sub YAAHM_Set($@) { } fhem("deletereading ".$name." ring_".($imax-1)); fhem("deletereading ".$name." ring_".($imax-1)."_1"); + fhem("deletereading ".$name." ring_".($imax-1)."x"); + fhem("deletereading ".$name." ring_".($imax-1)."_1x"); fhem("deletereading ".$name." next_".($imax-1)); fhem("deletereading ".$name." today_".($imax-1)); fhem("deletereading ".$name." today_".($imax-1)."_e"); @@ -904,7 +930,42 @@ sub YAAHM_Get($@) { return YAAHM_sayWeeklyTime($hash,$if,1); } }elsif ($arg eq "template") { - $res = "sub HouseTimeHelper(\@){\n". + $res = "################## subroutine for housestate transitions ###########\n"; + $res .= "sub HouseStateHelper(\@){\n". + " my (\$event,\$param1,\$param2) = \@_;\n\n". + " Log 1,\"[HouseStateHelper] event=\$event\";\n\n". + " my \$time = ReadingsVal(\"".$name."\",\"housetime\",\"\");\n". + " my \$phase = ReadingsVal(\"".$name."\",\"housephase\",\"\");\n". + " my \$state = ReadingsVal(\"".$name."\",\"housestate\",\"\");\n". + " my \$party = (ReadingsVal(\"".$name."\",\"housemode\",\"\") eq \"party\") ? 1 : 0;\n". + " my \$absence = (ReadingsVal(\"".$name."\",\"housemode\",\"\") eq \"absence\") ? 1 : 0;\n". + " my \$dndist = (ReadingsVal(\"".$name."\",\"housemode\",\"\") eq \"donotdisturb\") ? 1 : 0;\n"; + #-- iterate through table + for( my $i=0;$i{DATA}); my $error = FileWrite("YAAHMFILE",$jhash0); - #Log 1,"[YAAHM_save] error=$error"; return; } @@ -1015,24 +1060,44 @@ sub YAAHM_setParm($@) { my $cmd = $a[0]; my $key = $a[1]; + my $dea = $a[2]; my $msg = ""; my $val; + #-- device action profile + # start, end/offset, execution, active in mode / daytype + if ($cmd eq "xt") { + for( my $i=1;$i<6;$i++){ + $val = $a[$i+1]; + if( ($val eq "undef")||($val eq "") ){ + $val = undef; + }elsif( ($i>3) && ($i<5) && ($val !~ /\d?\d:\d\d/)){ + $msg = "wrong time specification $val in device action profile for device no. $key, must be hh:mm"; + Log 1,"[YAAHM_setParm] ".$msg; + } + } + $hash->{DATA}{"XT"}{$dea}{"name"} = $a[2]; + #-- check ?? + $hash->{DATA}{"XT"}{$dea}{"event"} = $a[3]; + $hash->{DATA}{"XT"}{$dea}{"earliest"} = $a[4]; + $hash->{DATA}{"XT"}{$dea}{"latest"} = $a[5]; + $hash->{DATA}{"XT"}{$dea}{"cmd"} = $a[6]; + return $msg; #-- daily profile # start, end/offset, execution, active in mode / daytype - if ($cmd eq "dt") { + }elsif ($cmd eq "dt") { for( my $i=1;$i<5;$i++){ $val = $a[$i+1]; if( ($val eq "undef")||($val eq "") ){ $val = undef; }elsif( ($i<3) && ($val !~ /\d?\d:\d\d/)){ - $msg = "wrong time specification $val for key $key, must be hh:mm"; + $msg = "wrong time specification $val in daily profile for timer no. $key, must be hh:mm"; Log 1,"[YAAHM_setParm] ".$msg; $val = "00:00"; }elsif( $i<3 ){ my ($hour,$min) = split(':',$val); if( $hour>23 || $min>59 ){ - $msg = "wrong time specification $val for key $key > 23:59"; + $msg = "wrong time specification $val in daily profile for timer no. $key > 23:59"; Log 1,"[YAAHM_setParm] ".$msg; $val = "00:00"; } @@ -1054,12 +1119,12 @@ sub YAAHM_setParm($@) { #-- ok my ($hour,$min) = split(':',$val); if( $hour>23 || $min>59 ){ - $msg = "wrong time specification next=$val for weekly timer > 23:59".$a[1]; + $msg = "wrong time specification next=$val for weekly timer ".$hash->{DATA}{"WT"}[$a[1]]{"name"}." > 23:59"; Log 1,"[YAAHM_setParm] ".$msg; $val = "off"; } }else{ - $msg = "wrong time specification next=$val for weekly timer ".$a[1].", must be hh:mm of 'off'"; + $msg = "wrong time specification next=$val for weekly timer ".$hash->{DATA}{"WT"}[$a[1]]{"name"}.", must be hh:mm of 'off'"; Log 1,"[YAAHM_setParm] ".$msg; $val = "off"; } @@ -1070,7 +1135,7 @@ sub YAAHM_setParm($@) { #-- activity vacation/holiday $hash->{DATA}{"WT"}[$a[1]]{"acti_d"} = $a[5]; #-- weekdays - for( my $i=0;$i<7;$i++){ + for( my $i=0;$i<9;$i++){ $val = $a[$i+6]; if( ($val eq "undef")||($val eq "") ){ $val = undef; @@ -1080,12 +1145,12 @@ sub YAAHM_setParm($@) { #-- ok my ($hour,$min) = split(':',$val); if( $hour>23 || $min>59 ){ - $msg = "wrong time specification $val for weekly timer > 23:59 ".$a[1]; + $msg = "wrong time specification $val for weekly timer ".$hash->{DATA}{"WT"}[$a[1]]{"name"}." > 23:59 "; Log 1,"[YAAHM_setParm] ".$msg; $val = "off"; } }else{ - $msg = "wrong time specification $val for weekly timer ".$a[1].", must be hh:mm or 'off'"; + $msg = "wrong time specification $val for weekly timer ".$hash->{DATA}{"WT"}[$a[1]]{"name"}.", must be hh:mm or 'off'"; Log 1,"[YAAHM_setParm] ".$msg; $val = "off"; } @@ -1200,10 +1265,12 @@ sub YAAHM_time { readingsBulkUpdate($hash,"tr_housetime",$yaahm_tt->{$targettime}); readingsBulkUpdate($hash,"housephase",$targetphase); readingsBulkUpdate($hash,"tr_housephase",$yaahm_tt->{$targetphase}); + readingsEndUpdate($hash,1); } #-- before fixing new times # if manual wake/sleep/timer, the time for the current day needs to be set to empty, # but second execution on the same day is blocked if attribute norepeat is set. + readingsBeginUpdate($hash); if( $targettime eq "wakeup" ){ $hash->{DATA}{"WT"}[0]{"next"} = ""; readingsBulkUpdate($hash,"next_0",""); @@ -1216,7 +1283,6 @@ sub YAAHM_time { readingsBulkUpdate($hash,"next_".$i,""); } readingsEndUpdate($hash,1); - YAAHM_setWeeklyTime($hash); #-- helper function not executed, e.g. by call from external timer return @@ -1327,8 +1393,7 @@ sub YAAHM_nextWeeklyTime { #-- all logic in setweeklytime $hash->{DATA}{"WT"}[$i]{"next"} = $time; $hash->{DATA}{"WT"}[$i]{"done"} = 0; - YAAHM_setWeeklyTime($hash); - + YAAHM_setWeeklyTime($hash); } ######################################################################################### @@ -1612,6 +1677,139 @@ sub YAAHM_informer($) { $me->{NTFY_ORDER} = $FW_cname; # else notifyfn won't be called %ntfyHash = (); } + +######################################################################################### +# +# YAAHM_startDeviceActions- start the device action function +# +# Parameter name = name of the YAAHM device +# +######################################################################################### + +sub YAAHM_startDeviceActions($) { + my ($name) = @_; + return + if(!defined($name)); + + my $hash = $defs{$name}; + return + if(!defined($hash)); + + my $res; + my $avl = AttrVal($name,"deviceActions",undef); + return + if( !$avl ); + + my ($dea,$dev,$evt,$eval,$lval,$xval,$tsw,$tfinal); + + #-- number of action devices + my $devactno; + my @actdevlist = split(',',$avl); + $devactno=int(@actdevlist); + + #-- check for obsolete keys and remove from hash + my %devacthash = %{$hash->{DATA}{"XT"}}; + my %actdevattr = map {$_ => 1} @actdevlist; + foreach my $key (keys %devacthash){ + if($actdevattr{$key} != 1){ + delete($hash->{DATA}{"XT"}{$key}); + } + } + + readingsBeginUpdate($hash); + + #-- start timer + for( my $i=0;$i < $devactno ;$i++){ + $dea = $actdevlist[$i]; + $dev = $hash->{DATA}{"XT"}{$dea}{"name"}; + if( $dea ne $dev){ + Log3 $name,1,"[YAAHM_startDeviceActions] key $dea not equal to name $dev, no action timer started"; + next; + } + $evt = $hash->{DATA}{"XT"}{$dea}{"event"}; + $eval = $hash->{DATA}{"XT"}{$dea}{"earliest"}; + $lval = $hash->{DATA}{"XT"}{$dea}{"latest"}; + $xval = $hash->{DATA}{"XT"}{$dea}{"cmd"}; + + #-- precise time + if( $evt =~ /$defaultdailykeys/ ){ + $tsw = ReadingsVal($name,"s_".$evt,"?"); + }else{ + my $jnd = undef; + for( my $j=0;$j < int( @{$hash->{DATA}{"WT"}} );$j++){ + $jnd = $j + if( ($hash->{DATA}{"WT"}[$j]{"name"} eq $evt) && ($evt !~ /(wakeup)|(sleep)/) ); + } + if( defined($jnd) ){ + $tsw = ReadingsVal($name,"ring_".$jnd,"?"); + }else{ + $tsw = "?"; + } + } + + #-- TODO: only if timer is enabled !!! + my $early = $hash->{DATA}{"XT"}{$dea}{"earliest"}; + my $late = $hash->{DATA}{"XT"}{$dea}{"latest"}; + if( $tsw =~ /(^off)|(\d?\d:\d\d(:\d\d)?)/ ){ + my $early = $hash->{DATA}{"XT"}{$dea}{"earliest"}; + my $late = $hash->{DATA}{"XT"}{$dea}{"latest"}; + + #-- no direct time, use latest + if( $tsw =~ /^off/ ){ + if( defined($late) && $late =~ /\d?\d:\d\d(:\d\d)?/ ){ + $tfinal = $late; + }else{ + $tfinal = "?"; + } + }elsif( $tsw =~ /\d?\d:\d\d(:\d\d)?/ ){ + #-- direct switching time + $tfinal = $tsw; + my ($hc,$mc) = split(':',$tsw); + #--early time defined + if( defined($early) && $early =~ /\d?\d:\d\d(:\d\d)?/ ){ + my ($he,$me) = split(':',$early); + my $de=60*($he-$hc)+($me-$mc); + #-- too early, action at early + if( $de>0 ){ + $tfinal = $early; + } + } + #-- late time defined + if( defined($late) && $late =~ /\d?\d:\d\d(:\d\d)?/ ){ + my ($hl,$ml) = split(':',$late); + my $dl=60*($hl-$hc)+($ml-$mc); + #-- too late, action at late + if( $dl<0 ){ + $tfinal = $late; + } + } + }else{ + $tfinal = "?"; + } + } + if( $tfinal =~ /\d?\d:\d\d(:\d\d)?/ ){ + Log3 $name,5,"[YAAHM_startDeviceActions] final switching time found for device action timer $dea is ".$tfinal; + my $xval = $hash->{DATA}{"XT"}{$dea}{"cmd"}; + $hash->{DATA}{"XT"}{$dea}{"time"} = $tfinal; + $res = "defmod ".$name.".xtimer_".$i.".IF DOIF ([$tfinal]) (".$xval.")"; + fhem($res); + fhem("attr ".$name.".xtimer_".$i.".IF comment ".$dev); + fhem("attr ".$name.".xtimer_".$i.".IF do always"); + fhem("attr ".$name.".xtimer_".$i.".IF room ".(defined($attr{$name}{"publicroom"}) ? $attr{$name}{"publicroom"} : $yaahmpublicroom)); + fhem("set ".$name.".xtimer_".$i.".IF enable"); + readingsBulkUpdate( $hash, "xdevice_".$i,$tfinal ); + }else{ + Log3 $name, 1,"[YAAHM_startDeviceActions] no switching time found for device action timer $dev with evt $evt"; + } + } + + #-- save everything + readingsEndUpdate($hash,1); + YAAHM_save($hash); + fhem("save"); + + return "Device actions started"; +} ######################################################################################### # @@ -1657,7 +1855,7 @@ sub YAAHM_startDayTimer($) { #-- Internal timer for night time my ($sec, $min, $hour, $day, $month, $year, $wday,$yday,$isdst) = localtime(time); my $nval = $hash->{DATA}{"DT"}{"night"}[0]; - if( $nval !~ /\d\d:\d\d/ ){ + if( $nval !~ /\d?\d:\d\d/ ){ $msg = "Error in night time specification"; Log3 1,$name,"[YAAHM_startDayTimer] ".$msg; return $msg; @@ -1672,7 +1870,7 @@ sub YAAHM_startDayTimer($) { #-- Internal timer for daytime my $mval = $hash->{DATA}{"DT"}{"morning"}[0]; - if( $mval !~ /\d\d:\d\d/ ){ + if( $mval !~ /\d?\d:\d\d/ ){ $msg = "Error in morning time specification"; Log3 1,$name,"[YAAHM_startDayTimer] ".$msg; return $msg; @@ -1736,6 +1934,7 @@ sub YAAHM_startDayTimer($) { $res =~ s/\nDOELSEIF$//; fhem($res); fhem("attr $name.dtimer.IF do always"); + fhem("attr $name.dtimer.IF room ".(defined($attr{$name}{"publicroom"}) ? $attr{$name}{"publicroom"} : $yaahmpublicroom)); fhem("set $name.dtimer.IF enable"); #-- save everything @@ -1767,10 +1966,12 @@ sub YAAHM_startWeeklyTimer($) { $wupn = $hash->{DATA}{"WT"}[$i]{"name"}; $res = "defmod ".$name.".wtimer_".$i.".IF DOIF ([".$name.":ring_".$i."] eq \"off\")\n()\nDOELSEIF\n(([[".$name.":ring_".$i."]])"; - #-- check for activity description + #-- check for mode activation my $g4a = defined($hash->{DATA}{"WT"}[$i]{"acti_m"}) ? $hash->{DATA}{"WT"}[$i]{"acti_m"} : ""; - my $g4b = defined($hash->{DATA}{"WT"}[$i]{"acti_d"}) ? $hash->{DATA}{"WT"}[$i]{"acti_d"} : ""; my $v4a = ($g4a ne "") ? "(normal)|(".join(')|(',split(',',$g4a)).")" : "(normal)"; + + #-- check for daytype activation + my $g4b = defined($hash->{DATA}{"WT"}[$i]{"acti_d"}) ? $hash->{DATA}{"WT"}[$i]{"acti_d"} : ""; my $v4b = ($g4b ne "") ? "(workday)|(weekend)|(".join(')|(',split(',',$g4b)).")" : "(workday)|(weekend)"; $res .= "\nand ((([" .$name. ":housemode] =~ \"".$v4a."\")"; @@ -1791,7 +1992,9 @@ sub YAAHM_startWeeklyTimer($) { #-- doit fhem($res); + fhem("attr ".$name.".wtimer_".$i.".IF comment $g4b"); fhem("attr ".$name.".wtimer_".$i.".IF do always"); + fhem("attr ".$name.".wtimer_".$i.".IF room ".(defined($attr{$name}{"publicroom"}) ? $attr{$name}{"publicroom"} : $yaahmpublicroom)); fhem("set ".$name.".wtimer_".$i.".IF enable"); } @@ -1815,84 +2018,127 @@ sub YAAHM_setWeeklyTime($) { my $name = $hash->{NAME}; #-- weekly profile times - my ($sg0,$sg1,$ring_0x,$ring_1x,$ring_0e,$ring_1e,$ring_0,$ring_1,$ng); + my ($daytype_0,$daytype_1,$weektime_0,$weektime_1,$ring_0x,$ring_1x,$ring_0e,$ring_1e,$ring_0,$ring_1,$nexttime,$wupad,$wupam); #-- iterate over timers for( my $i=0;$i{DATA}{"WT"}} );$i++){ #-- obtain next time spec => will override all - $ng = $hash->{DATA}{"WT"}[$i]{ "next" }; + $nexttime = $hash->{DATA}{"WT"}[$i]{ "next" }; #-- highest priority is a disabled timer - no wakeup at all if( ReadingsVal($name.".wtimer_".$i.".IF","mode","") eq "disabled" ){ - $sg0 = "off"; - $sg1 = "off"; + $ring_0 = "off"; + $ring_0x = "off"; $ring_0e = "disabled (timer)"; + $ring_1 = "off"; + $ring_1x = "off"; $ring_1e = "disabled (timer)"; #-- if the timer is enabled, we'll use its timing values }else{ - $sg0 = $hash->{DATA}{"WT"}[$i]{ $weeklytable[$hash->{DATA}{"DD"}[0]{"weekday"}] } ; - $sg1 = $hash->{DATA}{"WT"}[$i]{ $weeklytable[$hash->{DATA}{"DD"}[1]{"weekday"}] }; - $ring_0e = "enabled"; - $ring_1e = "enabled"; - #-- next higher priority for "off" is daytype - my $wupad = $hash->{DATA}{"WT"}[$i]{"acti_d"}.",workday,weekend"; + #-- timer active for the following daytypes + $wupad = $hash->{DATA}{"WT"}[$i]{"acti_d"}.",workday,weekend"; + #-- start with tomorrow - if( index($wupad, $hash->{DATA}{"DD"}[1]{"daytype"}) == -1 ){ - $ring_1x = "off (".substr(ReadingsVal($name,"tr_tomorrowType",""),0,3).")"; - $ring_1e = "disabled (".ReadingsVal($name,"tomorrowType","").")"; - }elsif( ($hash->{DATA}{"DD"}[1]{"vacflag"} == 1 ) && index($wupad,"vacation") == -1 ){ - $ring_1x = "off (".substr($yaahm_tt->{"vacation"},0,3).")"; - $ring_1e = "disabled (vacation)"; - }else{ - $ring_1x = $sg1; - } #-- because today we might also have an influence of housemode - if( index($wupad, $hash->{DATA}{"DD"}[0]{"daytype"}) == -1 ){ - $ring_0x = "off (".substr(ReadingsVal($name,"tr_todayType",""),0,3).")"; - $ring_0e = "disabled (".ReadingsVal($name,"todayType","").")"; - }elsif( ($hash->{DATA}{"DD"}[0]{"vacflag"} == 1 ) && index($wupad,"vacation") == -1 ){ - $ring_0x = "off (".substr($yaahm_tt->{"vacation"},0,3).")"; - $ring_0e = "disabled (vacation)"; - }else{ - #-- next higher priority for "off" (only today !) is housemode - my $wupam = $hash->{DATA}{"WT"}[$i]{"acti_m"}.",normal"; - if( index($wupam, ReadingsVal($name,"housemode","")) == -1 ){ - $ring_0x = "off (".substr(ReadingsVal($name,"tr_housemode",""),0,3).")"; - $ring_0e = "disabled (".ReadingsVal($name,"housemode","").")"; + $daytype_1 = $hash->{DATA}{"DD"}[1]{"daytype"}; + $ring_1 = $hash->{DATA}{"WT"}[$i]{ $weeklytable[$hash->{DATA}{"DD"}[1]{"weekday"}] } ; + $ring_1x = $ring_1; + $ring_1e = "enabled"; + + #-- holiday/vacation have higher priority, check for corresponding time + if( $daytype_1 eq "holiday" ){ + #-- holiday special time + $weektime_1 = $hash->{DATA}{"WT"}[$i]{ "holiday" } ; + if( defined($weektime_1) && ($weektime_1 =~ /\d?\d:\d\d(:\d\d)?/) ){ + $ring_1 = $weektime_1; + $ring_1x = $weektime_1; + }elsif( index($wupad, "holiday") != -1 ){ + #-- no change }else{ - $ring_0x = $sg0; - } - } - } - - #-- no "next" time specification - if( !defined($ng) || $ng eq "" ){ - $ring_0 = $sg0; - $ring_1 = $sg1; + $ring_1 = "off (".$yaahm_tt->{"holiday"}[1].")"; + $ring_1x = "off (".$yaahm_tt->{"holiday"}[1].")"; + $ring_1e = "disabled (holiday)"; + } + }elsif( $daytype_1 eq "vacation" ){ + #-- vacation special time + $weektime_1 = $hash->{DATA}{"WT"}[$i]{ "vacation" } ; + if( defined($weektime_1) && ($weektime_1 =~ /\d?\d:\d\d(:\d\d)?/) ){ + $ring_1 = $weektime_1; + $ring_1x = $weektime_1; + }elsif( index($wupad, "vacation") != -1 ){ + #--no change + }else{ + $ring_1 = "off (".$yaahm_tt->{"vacation"}[1].")"; + $ring_1x = "off (".$yaahm_tt->{"vacation"}[1].")"; + $ring_1e = "disabled (vacation)"; + } + } + + #-- now today + #-- because today we might also have an influence of housemode + $daytype_0 = $hash->{DATA}{"DD"}[0]{"daytype"}; + $ring_0 = $hash->{DATA}{"WT"}[$i]{ $weeklytable[$hash->{DATA}{"DD"}[0]{"weekday"}] } ; + $ring_0x = $ring_0; + $ring_0e = "enabled"; + + #-- holiday/vacation have higher priority, check for corresponding time + if( $daytype_0 eq "holiday" ){ + #-- holiday special time + $weektime_0 = $hash->{DATA}{"WT"}[$i]{ "holiday" } ; + if( defined($weektime_0) && ($weektime_0 =~ /\d?\d:\d\d(:\d\d)?/) ){ + $ring_0 = $weektime_0; + $ring_0x = $weektime_0; + }elsif( index($wupad, "holiday") != -1 ){ + #-- no change + }else{ + $ring_0 = "off (".$yaahm_tt->{"holiday"}[1].")"; + $ring_0x = "off (".$yaahm_tt->{"holiday"}[1].")"; + $ring_0e = "disabled (holiday)"; + } + }elsif( $daytype_0 eq "vacation" ){ + #-- vacation special time + $weektime_0 = $hash->{DATA}{"WT"}[$i]{ "vacation" } ; + if( defined($weektime_0) && ($weektime_0 =~ /\d?\d:\d\d(:\d\d)?/) ){ + $ring_0 = $weektime_0; + $ring_0x = $weektime_0; + }elsif( index($wupad, "vacation") != -1 ){ + #--no change + }else{ + $ring_0 = "off (".$yaahm_tt->{"vacation"}[1].")"; + $ring_0x = "off (".$yaahm_tt->{"vacation"}[1].")"; + $ring_0e = "disabled (vacation)"; + } + } + #-- next higher priority for "off" (only today !) is housemode + my $wupam = $hash->{DATA}{"WT"}[$i]{"acti_m"}.",normal"; + if( index($wupam, ReadingsVal($name,"housemode","")) == -1 ){ + $ring_0x = "off (".substr(ReadingsVal($name,"tr_housemode",""),0,3).")"; + $ring_0e = "disabled (".ReadingsVal($name,"housemode","").")"; + }else{ + $ring_0x = $ring_0; + } + } + #-- highest priority is a "next" time specification - }else{ + if( defined($nexttime) && ($nexttime =~ /(\d?\d:\d\d(:\d\d)?)|(off)/) ){ #-- current time my ($sec, $min, $hour, $day, $month, $year, $wday,$yday,$isdst) = localtime(time); my $lga = sprintf("%02d%02d",$hour,$min); #-- today's waketime - my $tga = $sg0; + my $tga = $ring_0; $tga =~ s/://; #-- tomorrow's waketime - my $tgm = $sg1; + my $tgm = $ring_1; $tgm =~ s/://; #-- "next" input - my $nga = (defined $ng)?$ng:""; + my $nga = (defined $nexttime)?$nexttime:""; $nga =~ s/://; #-- "next" is the same as todays waketime and todays waketime not over => restore ! if( ($nga eq $tga) && ($tga > $lga)){ - $ring_0 = $sg0; - $ring_1 = $sg1; - $ng = ""; + $nexttime = ""; $hash->{DATA}{"WT"}[$i]{ "next" }=""; #-- "next" is the same as tomorrows waketime and todays waketime over => restore ! }elsif( ($nga eq $tgm) && ($tga < $lga)){ - $ring_0 = $sg0; - $ring_1 = $sg1; - $ng = ""; + $nexttime = ""; $hash->{DATA}{"WT"}[$i]{ "next" }=""; #-- "next" is off }elsif( $nga eq "off" ){ @@ -1901,81 +2147,50 @@ sub YAAHM_setWeeklyTime($) { if( $ring_0x !~ /^off/ ){ $ring_0x = "off (man)"; $ring_0 = "off"; - $ring_1 = $sg1; } #-- today's waketime over => we mean tomorrow }else{ if( $ring_1x !~ /^off/ ){ - $ring_1x = "off (man)"; - $ring_0 = $sg0; - $ring_1 = "$sg1 (off)"; + $ring_1x = "off (man)"; + $ring_1 .= " (off)"; } } #-- "next" is nontrivial timespec }else{ #-- "next" after current time => we mean today if( $nga > $lga ){ - #-- the same as original waketime => restore ! (do we come here at all ?) - #if( $ng eq $sg0 ){ - # $ring_0x = $sg0; - # $ring_0 = $sg0; - # $ng = ""; - # $hash->{DATA}{"WT"}[$i]{ "next" } = ""; - #-- new manual waketime tomorrow - #}else{ - $ring_0x = "$ng (man)"; - $ring_0 = $ng; - #} - $ring_1 = $sg1; + $ring_0x = "$nexttime (man)"; + $ring_0 = $nexttime; #-- "next" before current time => we mean tomorrow }else{ - #-- the same as original waketime => restore ! (do we come here at all ?) - #if( $ng eq $sg1 ){ - # $ring_0x = $sg1; - # $ring_1 = $sg1; - # $ng = ""; - # $hash->{DATA}{"WT"}[$i]{ "next" } = ""; - #}else{ - $ring_1x = "$ng (man)"; - $ring_1 = "$sg1 ($ng)"; - #} - $ring_0 = $sg0; + $ring_1x = "$nexttime (man)"; + $ring_1 .= " ($nexttime)"; } } } + $hash->{DATA}{"WT"}[$i]{"ring_0"} = $ring_0; $hash->{DATA}{"WT"}[$i]{"ring_1"} = $ring_1; $hash->{DATA}{"WT"}[$i]{"ring_0x"} = $ring_0x; $hash->{DATA}{"WT"}[$i]{"ring_1x"} = $ring_1x; $hash->{DATA}{"WT"}[$i]{"ring_0e"} = $ring_0e; $hash->{DATA}{"WT"}[$i]{"ring_1e"} = $ring_1e; - #Log 1,"====> AFTER FINAL CHECK TIMER $i sg0=$sg0 ring_0x=$ring_0x sg1=$sg1 ring_1x=$ring_1x ng=$ng"; - #Log 1," ".$hash->{DATA}{"WT"}[$i]{"ring_0x"}." ".$hash->{DATA}{"WT"}[$i]{"ring_1x"}; - #-- notation: - # today_i is today's waketime of timer i - # tomorrow_i is tomorrow's waketime of timer i - # timers have additional conditions for activation according - # to housemode and daytype, these conditions are checked in the timer device - # devices and are not part of the table. But we have a reading: - # today_i_e is a copy of the condition checked in the timer device - # (housemode and daytype) - # tomorrow_i_e is not a complete copy of the condition checked in the timer device, - # (daytype only, because housemode of tomorrow is not known) - # ring_[i]_1 is tomorrow's ring time of timer i + readingsBeginUpdate($hash); - readingsBulkUpdate( $hash, "today_".$i,$sg0 ); - readingsBulkUpdate( $hash, "tomorrow_".$i,$sg1 ); + readingsBulkUpdate( $hash, "today_".$i,$ring_0 ); + readingsBulkUpdate( $hash, "tomorrow_".$i,$ring_1 ); readingsBulkUpdate( $hash, "today_".$i."_e",$ring_0e ); readingsBulkUpdate( $hash, "tomorrow_".$i."_e",$ring_1e ); readingsBulkUpdate( $hash, "ring_".$i,$ring_0 ); readingsBulkUpdate( $hash, "ring_".$i."_1",$ring_1 ); readingsBulkUpdate( $hash, "ring_".$i."x",$ring_0x ); readingsBulkUpdate( $hash, "ring_".$i."_1x",$ring_1x ); - readingsBulkUpdate( $hash, "next_".$i,$ng ); - + readingsBulkUpdate( $hash, "next_".$i,$nexttime ); readingsEndUpdate($hash,1); + YAAHM_sayWeeklyTime($hash,$i,0); } + YAAHM_startDeviceActions($name); } ######################################################################################### @@ -2006,21 +2221,20 @@ sub YAAHM_sayWeeklyTime($$$) { $msg = $hash->{DATA}{"WT"}[$timer]{"name"}; #-- get timer values from readings, because these include vacation settings and special time - $tod = $hash->{DATA}{"WT"}[$timer]{"ring_0x"}; - $tom = $hash->{DATA}{"WT"}[$timer]{"ring_1x"}; - $done = $hash->{DATA}{"WT"}[$timer]{"done"}; + $tod = $hash->{DATA}{"WT"}[$timer]{"ring_0x"}; + $tom = $hash->{DATA}{"WT"}[$timer]{"ring_1x"}; + $done = $hash->{DATA}{"WT"}[$timer]{"done"}; $norep = AttrVal($name,"norepeat",0); #-- current local time ($hl,$ml) = split(':',strftime('%H:%M', localtime(time))); - $tl = 60*$hl+$ml; + $tl = 60*$hl+$ml; #-- today off AND tomorrow any time or off => compare this time with current time if( $tod =~ /^off.*/ ){ #-- tomorrow any time if( $tom =~ /(\d?\d):(\d\d)(:(\d\d))?/ && $tom !~ /.*\(off\)$/ ){ - #Log 1,"===========> |$1|$2|$3|$4"; ($ht,$mt) = split('[\s:]',$tom); $tt=60*$ht+$mt; @@ -2046,7 +2260,6 @@ sub YAAHM_sayWeeklyTime($$$) { #-- today nontrivial => compare this time with current time }elsif( $tod =~ /(\d?\d):(\d\d)(:(\d\d))?/ ){ - #Log 1,"===========> |$1|$2|$3|$4"; ($ht,$mt) = split('[\s:]',$tod); $tt=60*$ht+$mt; @@ -2063,7 +2276,6 @@ sub YAAHM_sayWeeklyTime($$$) { $pt = "off ".lc($yaahm_tt->{"tomorrow"}); $msg .= " ".lc($yaahm_tt->{"tomorrow"})." ".$yaahm_tt->{"swoff"}; }elsif( $tom =~ /(\d?\d):(\d\d)(:(\d\d))?( \((\d?\d):(\d\d)(:(\d\d))?\))?/ ){ - #Log 1,"===========> |$1|$2|$3|$4|$5|$6"; if( defined($5) && $5 ne ""){ $hw = $6*1; $mw = $7*1; @@ -2150,9 +2362,13 @@ sub YAAHM_checkMonthly($$$) { @tmor = split('\.',$stom); @two = split('\.',$stwom); - $fline=Calendar_Get($defs{$specialDev},"get","full","mode=alarm|start|upcoming"); + $fline=Calendar_Get($defs{$specialDev},,"get","events","format:full filter:mode=~'alarm|start|upcoming'"); #-- more complicated to check here, # format is ' upcoming [ ] - [] + + #-- more complicated to check here, + # format is ' start/upcoming - [] + # d30479...5e6 start/upcoming 03.10.2018 00:00- Tag der Deutschen Einheit my ($cstart,$cdesc); if($fline){ @@ -2288,6 +2504,7 @@ sub YAAHM_updater($) { my ($timerHash) = @_; my $hash; my $next; + my $name = $hash->{NAME}; #-- start timer for updates - when device is reloaded if( defined($firstcall) && ($firstcall==1) ){ @@ -2306,7 +2523,6 @@ sub YAAHM_updater($) { #-- safeguard if hash is not properly indirected if( defined($hash->{HASH}) ){ - #Log 1,"WARNING ! HASH indirection not ok. firstcall=$firstcall"; $hash = $hash->{HASH}; } YAAHM_RemoveInternalTimer("aftermidnight",$hash); @@ -2314,7 +2530,7 @@ sub YAAHM_updater($) { Log 1,"[YAAHM_updater] on device ".$hash->{NAME}." called for this day"; YAAHM_GetDayStatus($hash); - + YAAHM_startDeviceActions($name); return undef; } @@ -2409,24 +2625,24 @@ sub YAAHM_GetDayStatus($) { $hash->{DATA}{"DD"}[0]{"date"} = $stoday; $hash->{DATA}{"DD"}[0]{"weekday"} = (strftime('%w', localtime(time))+6)%7; $hash->{DATA}{"DD"}[0]{"daytype"} = "workday"; - $hash->{DATA}{"DD"}[0]{"desc"} = $yaahm_tt->{"workday"}; + $hash->{DATA}{"DD"}[0]{"desc"} = $yaahm_tt->{"workday"}[0]; $hash->{DATA}{"DD"}[0]{"vacflag"} = 0; $tomtype = "workday"; $hash->{DATA}{"DD"}[1]{"date"} = $stom; $hash->{DATA}{"DD"}[1]{"weekday"} = (strftime('%w', localtime(time+86400))+6)%7; $hash->{DATA}{"DD"}[1]{"daytype"} = "workday"; - $hash->{DATA}{"DD"}[1]{"desc"} = $yaahm_tt->{"workday"}; + $hash->{DATA}{"DD"}[1]{"desc"} = $yaahm_tt->{"workday"}[0]; $hash->{DATA}{"DD"}[1]{"vacflag"} = 0; $twotype = "workday"; $hash->{DATA}{"DD"}[2]{"date"} = $stwo; $hash->{DATA}{"DD"}[2]{"weekday"} = (strftime('%w', localtime(time+2*86400))+6)%7; $hash->{DATA}{"DD"}[2]{"daytype"} = "workday"; - $hash->{DATA}{"DD"}[2]{"desc"} = $yaahm_tt->{"workday"}; + $hash->{DATA}{"DD"}[2]{"desc"} = $yaahm_tt->{"workday"}[0]; $hash->{DATA}{"DD"}[2]{"vacflag"} = 0; - #-- vacation = vacdays has higher priority + #-- vacation has higher priority my $vacdayDevs = AttrVal( $name, "vacationDevices", "" ); foreach my $vacdayDev ( split( /,/, $vacdayDevs ) ) { #-- device of type holiday @@ -2437,31 +2653,34 @@ sub YAAHM_GetDayStatus($) { my $tod = holiday_refresh( $vacdayDev, $stoday ); if ( $tod ne "none" ) { $todaydesc = $tod; - $todaytype = "vacday"; + $todaytype = "vacation"; Log3 $name, 5,"[YAAHM] found today=vacation \"$todaydesc\" in holiday $vacdayDev"; } $tod = holiday_refresh( $vacdayDev, $stom ); if ( $tod ne "none" ) { $tomdesc = $tod; - $tomtype = "vacday"; + $tomtype = "vacation"; Log3 $name, 5,"[YAAHM] found tomorrow=vacation \"$tomdesc\" in holiday $vacdayDev"; } $tod = holiday_refresh( $vacdayDev, $stwo ); if ( $tod ne "none" ) { $twodesc = $tod; - $twotype = "vacday"; + $twotype = "vacation"; Log3 $name, 5,"[YAAHM] found twodays=vacation \"$twodesc\" in holiday $vacdayDev"; } #-- device of type calendar }elsif( IsDevice($vacdayDev, "Calendar" )){ - $stoday = strftime('%d.%m.%y', localtime(time)); - $stom = strftime('%d.%m.%y', localtime(time+86400)); - $stwo = strftime('%d.%m.%y', localtime(time+2*86400)); + $stoday = strftime('%d.%m.%Y', localtime(time)); + $stom = strftime('%d.%m.%Y', localtime(time+86400)); + $stwo = strftime('%d.%m.%Y', localtime(time+2*86400)); @tday = split('\.',$stoday); @tmor = split('\.',$stom); @ttwo = split('\.',$stwo); #-- more complicated to check here - $fline=Calendar_Get($defs{$vacdayDev},"get","full","mode=alarm|start|upcoming"); + $fline=Calendar_Get($defs{$vacdayDev},"get","events","format:full filter:mode=~'alarm|start|upcoming'"); + #-- more complicated to check here, + # format is ' start/end - [] + # 58b54d...4b end 22.05.2018 00:00-03.06.2018 00:00 Pfingstferien if($fline){ #chomp($fline); @lines = split('\n',$fline); @@ -2469,28 +2688,29 @@ sub YAAHM_GetDayStatus($) { chomp($fline); @chunks = split(' ',$fline); @sday = split('\.',$chunks[2]); - @eday = split('\.',substr($chunks[3],9,10)); + @eday = split('\.',substr($chunks[3],6,10)); + #-- today my $rets = ($sday[2]-$tday[2])*365+($sday[1]-$tday[1])*31+($sday[0]-$tday[0]); my $rete = ($eday[2]-$tday[2])*365+($eday[1]-$tday[1])*31+($eday[0]-$tday[0]); if( ($rete>=0) && ($rets<=0) ){ $todaydesc = $chunks[5]; $todaytype = "vacation"; - Log3 $name, 5,"[YAAHM] found today=vacation \"$todaydesc\" in calendar $vacdayDev"; + Log3 $name, 1,"[YAAHM] found today=vacation \"$todaydesc\" in calendar $vacdayDev"; } $rets = ($sday[2]-$tmor[2])*365+($sday[1]-$tmor[1])*31+($sday[0]-$tmor[0]); $rete = ($eday[2]-$tmor[2])*365+($eday[1]-$tmor[1])*31+($eday[0]-$tmor[0]); if( ($rete>=0) && ($rets<=0) ){ $tomdesc = $chunks[5]; $tomtype = "vacation"; - Log3 $name, 5,"[YAAHM] found tomorrow=vacation \"$tomdesc\" in calendar $vacdayDev"; + Log3 $name, 1,"[YAAHM] found tomorrow=vacation \"$tomdesc\" in calendar $vacdayDev"; } $rets = ($sday[2]-$ttwo[2])*365+($sday[1]-$ttwo[1])*31+($sday[0]-$ttwo[0]); $rete = ($eday[2]-$ttwo[2])*365+($eday[1]-$ttwo[1])*31+($eday[0]-$ttwo[0]); if( ($rete>=0) && ($rets<=0) ){ $twodesc = $chunks[5]; $twotype = "vacation"; - Log3 $name, 5,"[YAAHM] found twodays=vacation \"$twodesc\" in calendar $vacdayDev"; + Log3 $name, 1,"[YAAHM] found twodays=vacation \"$twodesc\" in calendar $vacdayDev"; } } } @@ -2519,9 +2739,9 @@ sub YAAHM_GetDayStatus($) { if( strftime('%u', localtime(time)) > 5){ $todaytype = "weekend"; if( $hash->{DATA}{"DD"}[0]{"daytype"} ne "workday" ){ - $hash->{DATA}{"DD"}[0]{"desc"} = $yaahm_tt->{"weekend"}.", ".$hash->{DATA}{"DD"}[0]{"desc"}; + $hash->{DATA}{"DD"}[0]{"desc"} = $yaahm_tt->{"weekend"}[0].", ".$hash->{DATA}{"DD"}[0]{"desc"}; }else{ - $hash->{DATA}{"DD"}[0]{"desc"} = $yaahm_tt->{"weekend"}; + $hash->{DATA}{"DD"}[0]{"desc"} = $yaahm_tt->{"weekend"}[0]; } $hash->{DATA}{"DD"}[0]{"daytype"} = "weekend"; } @@ -2529,9 +2749,9 @@ sub YAAHM_GetDayStatus($) { if( strftime('%u', localtime(time+86400)) > 5){ $tomtype = "weekend"; if( $hash->{DATA}{"DD"}[1]{"daytype"} ne "workday" ){ - $hash->{DATA}{"DD"}[1]{"desc"} = $yaahm_tt->{"weekend"}.", ".$hash->{DATA}{"DD"}[1]{"desc"}; + $hash->{DATA}{"DD"}[1]{"desc"} = $yaahm_tt->{"weekend"}[0].", ".$hash->{DATA}{"DD"}[1]{"desc"}; }else{ - $hash->{DATA}{"DD"}[1]{"desc"} = $yaahm_tt->{"weekend"}; + $hash->{DATA}{"DD"}[1]{"desc"} = $yaahm_tt->{"weekend"}[0]; } $hash->{DATA}{"DD"}[1]{"daytype"} = "weekend"; } @@ -2539,9 +2759,9 @@ sub YAAHM_GetDayStatus($) { if( strftime('%u', localtime(time+2*86400)) > 5){ $twotype = "weekend"; if( $hash->{DATA}{"DD"}[2]{"daytype"} ne "workday" ){ - $hash->{DATA}{"DD"}[2]{"desc"} = $yaahm_tt->{"weekend"}.", ".$hash->{DATA}{"DD"}[2]{"desc"}; + $hash->{DATA}{"DD"}[2]{"desc"} = $yaahm_tt->{"weekend"}[0].", ".$hash->{DATA}{"DD"}[2]{"desc"}; }else{ - $hash->{DATA}{"DD"}[2]{"desc"} = $yaahm_tt->{"weekend"}; + $hash->{DATA}{"DD"}[2]{"desc"} = $yaahm_tt->{"weekend"}[0]; } $hash->{DATA}{"DD"}[2]{"daytype"} = "weekend"; } @@ -2576,30 +2796,33 @@ sub YAAHM_GetDayStatus($) { #-- device of type calendar }elsif( IsDevice($holidayDev, "Calendar" )){ - $stoday = strftime('%d.%m.%y', localtime(time)); - $stom = strftime('%d.%m.%y', localtime(time+86400)); - $stwo = strftime('%d.%m.%y', localtime(time+2*86400)); - $line=Calendar_Get($defs{$holidayDev},"get","text","mode=alarm|start|upcoming"); + $stoday = strftime('%d.%m.%Y', localtime(time)); + $stom = strftime('%d.%m.%Y', localtime(time+86400)); + $stwo = strftime('%d.%m.%Y', localtime(time+2*86400)); + $line=Calendar_Get($defs{$holidayDev},"get","events","format:text filter:mode=~'alarm|start|upcoming'"); + #-- more complicated to check here, + # format is - [] + # 03.10.2018 00:00- Tag der Deutschen Einheit if($line){ chomp($line); @lines = split('\n',$line); foreach $line (@lines){ chomp($line); - $date = substr($line,0,8); + $date = substr($line,0,10); if( $date eq $stoday ){ - $todaydesc = substr($line,15); + $todaydesc = substr($line,17); $todaytype = "holiday"; - Log3 $name, 5,"[YAAHM] found today=holiday \"$todaydesc\" in calendar $holidayDev"; + Log3 $name, 1,"[YAAHM] found today=holiday $date \"$todaydesc\" in calendar $holidayDev"; } if( $date eq $stom ){ - $tomdesc = substr($line,15); + $tomdesc = substr($line,17); $tomtype = "holiday"; - Log3 $name, 5,"[YAAHM] found tomorrow=holiday \"$tomdesc\" in calendar $holidayDev"; + Log3 $name, 1,"[YAAHM] found tomorrow=holiday $date \"$tomdesc\" in calendar $holidayDev"; } if( $date eq $stwo ){ - $twodesc = substr($line,15); + $twodesc = substr($line,17); $twotype = "holiday"; - Log3 $name, 5,"[YAAHM] found twodays=holiday \"$twodesc\" in calendar $holidayDev"; + Log3 $name, 1,"[YAAHM] found twodays=holiday $date \"$twodesc\" in calendar $holidayDev"; } } } @@ -2670,7 +2893,7 @@ sub YAAHM_GetDayStatus($) { } readingsBulkUpdateIfChanged( $hash, "todayType",$todaytype ); - readingsBulkUpdateIfChanged( $hash, "tr_todayType",$yaahm_tt->{$hash->{DATA}{"DD"}[0]{"daytype"}} ); + readingsBulkUpdateIfChanged( $hash, "tr_todayType",$yaahm_tt->{$hash->{DATA}{"DD"}[0]{"daytype"}}[0] ); if( $todaytype eq "workday"){ readingsBulkUpdateIfChanged( $hash, "todayDesc","--" ) }elsif( $todaytype eq "vacation"){ @@ -2682,7 +2905,7 @@ sub YAAHM_GetDayStatus($) { } readingsBulkUpdateIfChanged( $hash, "tomorrowType",$tomtype ); - readingsBulkUpdateIfChanged( $hash, "tr_tomorrowType",$yaahm_tt->{$hash->{DATA}{"DD"}[1]{"daytype"}} ); + readingsBulkUpdateIfChanged( $hash, "tr_tomorrowType",$yaahm_tt->{$hash->{DATA}{"DD"}[1]{"daytype"}}[0] ); if( $tomtype eq "workday"){ readingsBulkUpdateIfChanged( $hash, "tomorrowDesc","--" ) }elsif( $tomtype eq "vacation"){ @@ -2694,7 +2917,7 @@ sub YAAHM_GetDayStatus($) { } readingsBulkUpdateIfChanged( $hash, "twodaysType",$tomtype ); - readingsBulkUpdateIfChanged( $hash, "tr_twodaysType",$yaahm_tt->{$hash->{DATA}{"DD"}[2]{"daytype"}} ); + readingsBulkUpdateIfChanged( $hash, "tr_twodaysType",$yaahm_tt->{$hash->{DATA}{"DD"}[2]{"daytype"}}[0] ); if( $tomtype eq "workday"){ readingsBulkUpdateIfChanged( $hash, "twodaysDesc","--" ) }elsif( $tomtype eq "vacation"){ @@ -2733,11 +2956,14 @@ sub YAAHM_sun($) { my $strise2 = ""; my ($msg,$stset0,$stseas0,$stset1,$stseas1,$stset2,$stseas2); + my $sunsetf = AttrVal($name,"sunset","SunSet"); + my $sunrisef = AttrVal($name,"sunrise","SunRise"); + $sttoday = strftime('%Y-%m-%d', localtime(time)); #-- since the Astro module sometimes gives us strange results, we need to do this more than once while( $strise0 !~ /^\d\d:\d\d:\d\d/ && $count < 5){ - $strise0 = Astro_Get($hash,"dummy","text", "SunRise",$sttoday).":00"; + $strise0 = Astro_Get($hash,"dummy","text", $sunrisef,$sttoday).":00"; $count++; select(undef,undef,undef,0.01); } @@ -2748,8 +2974,9 @@ sub YAAHM_sun($) { } my ($hour,$min) = split(":",$strise0); $hash->{DATA}{"DD"}[0]{"sunrise"} = sprintf("%02d:%02d",$hour,$min); + - $stset0 = Astro_Get($hash,"dummy","text", "SunSet",$sttoday).":00"; + $stset0 = Astro_Get($hash,"dummy","text", $sunsetf,$sttoday).":00"; ($hour,$min) = split(":",$stset0); $hash->{DATA}{"DD"}[0]{"sunset"} = sprintf("%02d:%02d",$hour,$min); @@ -2761,7 +2988,7 @@ sub YAAHM_sun($) { $msg = ""; #-- since the Astro module sometimes gives us strange results, we need to do this more than once while( $strise1 !~ /^\d\d:\d\d:\d\d/ && $count < 5){ - $strise1 = Astro_Get($hash,"dummy","text", "SunRise",$sttom).":00"; + $strise1 = Astro_Get($hash,"dummy","text", $sunrisef,$sttom).":00"; $count++; select(undef,undef,undef,0.01); } @@ -2773,7 +3000,7 @@ sub YAAHM_sun($) { ($hour,$min) = split(":",$strise1); $hash->{DATA}{"DD"}[1]{"sunrise"} = sprintf("%02d:%02d",$hour,$min); - $stset1 = Astro_Get($hash,"dummy","text", "SunSet",$sttom).":00"; + $stset1 = Astro_Get($hash,"dummy","text", $sunsetf,$sttom).":00"; ($hour,$min) = split(":",$stset1); $hash->{DATA}{"DD"}[1]{"sunset"} = sprintf("%02d:%02d",$hour,$min); @@ -2785,7 +3012,7 @@ sub YAAHM_sun($) { $msg = ""; #-- since the Astro module sometimes gives us strange results, we need to do this more than once while( $strise2 !~ /^\d\d:\d\d:\d\d/ && $count < 5){ - $strise2 = Astro_Get($hash,"dummy","text", "SunRise",$sttwo).":00"; + $strise2 = Astro_Get($hash,"dummy","text", $sunrisef,$sttwo).":00"; $count++; select(undef,undef,undef,0.01); } @@ -2797,7 +3024,7 @@ sub YAAHM_sun($) { ($hour,$min) = split(":",$strise2); $hash->{DATA}{"DD"}[2]{"sunrise"} = sprintf("%02d:%02d",$hour,$min); - $stset2 = Astro_Get($hash,"dummy","text", "SunSet",$sttom).":00"; + $stset2 = Astro_Get($hash,"dummy","text", $sunsetf,$sttom).":00"; ($hour,$min) = split(":",$stset2); $hash->{DATA}{"DD"}[2]{"sunset"} = sprintf("%02d:%02d",$hour,$min); @@ -3344,12 +3571,39 @@ sub YAAHM_toptable($){ my $ts; my ($styl,$stym,$styr); my $ret = ""; - YAAHM_GetDayStatus($hash); + ###YAAHM_GetDayStatus($hash); #-- my $lockstate = ($hash->{READINGS}{lockstate}{VAL}) ? $hash->{READINGS}{lockstate}{VAL} : "unlocked"; my $showhelper = ($lockstate eq "unlocked") ? 1 : 0; %dailytable = %{$hash->{DATA}{"DT"}}; + + #-- number of action devices + my $devactno; + my @actdevlist; + my $avl = AttrVal($name,"deviceActions",undef); + if( !$avl){ + $devactno = 0; + }else{ + @actdevlist = split(',',$avl); + $devactno=int(@actdevlist); + } + + #-- temporary code to rewrite deviceactions array into a hash + my $xt = $hash->{DATA}{"XT"}; + if( ref $xt eq ref {}){ + }else{ + Log 1,"[Temporary code] changing XT array into hash"; + my %xtn={}; + for(my $i=0;$i<$devactno;$i++){ + my $dea=$actdevlist[$i]; + my %deb=%{$hash->{DATA}{"XT"}[$i]}; + #Log 1,"++++> Transferring key $dea"; + $xtn{$dea}=\%deb; + } + $hash->{DATA}{"XT"}=\%xtn; + } + my $dailyno = scalar keys %dailytable; my $weeklyno = int( @{$hash->{DATA}{"WT"}} ); @@ -3362,6 +3616,8 @@ sub YAAHM_toptable($){ $ret .= "var blinking = 0;\n"; $ret .= "var hscolor = \"".$csstate[0]."\";\n"; + $ret .= "var devactno = ".$devactno.";\n"; + $ret .= "var dailyno = ".$dailyno.";\n"; $ret .= "var dailykeys = [\"".join("\",\"",(sort YAAHM_dsort keys %dailytable))."\"];\n"; @@ -3374,6 +3630,7 @@ sub YAAHM_toptable($){ $ret .= "\"".$hash->{DATA}{"WT"}[$i]{"name"}."\""; } $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"; @@ -3382,12 +3639,29 @@ sub YAAHM_toptable($){ $ret .= "
".ReadingsVal($name,"housestate",undef)."
". "
".ReadingsVal($name,"housemode",undef)."
"; + + #-- formats for table borders + my ($stopleft,$stopmid,$stopright,$sbotleft,$sbotmid,$sbotright,$smidleft,$smidmid,$smidright,$saround); + $stopleft = "border-left:1px solid gray;border-top:1px solid gray;border-top-left-radius:10px;border-top-right-radius:0px;border-bottom-left-radius:0px;"; + $stopmid = "border-top:1px solid gray;border-radius:0px;"; + $stopright= "border-right:1px solid gray;border-top:1px solid gray;border-top-right-radius:10px;border-top-left-radius:0px;border-bottom-right-radius:0px;"; + $sbotleft = "border-left:1px solid gray;border-bottom:1px solid gray;border-bottom-left-radius:10px;border-bottom-right-radius:0px;border-top-left-radius:0px;"; + $sbotmid = "border-bottom:1px solid gray;border-radius:0px;"; + $sbotright= "border-right:1px solid gray;border-bottom:1px solid gray;border-bottom-right-radius:10px;border-top-right-radius:0px;border-bottom-left-radius:0px;"; + $smidleft = "border-left:1px solid gray;border-radius:0px;"; + $smidmid = "border:none"; + $smidright= "border-right:1px solid gray;border-radius:0px;"; + $saround = "padding:5px;vertical-align:top;border:1px solid gray;border-radius:10px;"; + + ### main table ############################################################################################ $ret .= "\n"; + + ### action ################################################################################################ + # spanning 3 cols of main table $ret .= "\n"; - ### action ################################################################################################ - #-- determine columns + #-- mode/state table, spanning 3 cols of main table my $cols = max(max(int(@modes),int(@states)),$weeklyno); $ret .= ""; - - $ret .= "\n"; ### daily overview ################################################################################################ - $styl="border-left:1px solid gray;border-top:1px solid gray;border-top-left-radius:10px;border-top-right-radius:0px;border-bottom-left-radius:0px;"; - $stym="border-top:1px solid gray;border-radius:0px;"; - $styr="border-right:1px solid gray;border-top:1px solid gray;border-top-right-radius:10px;border-top-left-radius:0px;border-bottom-right-radius:0px;"; - $ret .= "
".$yaahm_tt->{"action"}. "
".ReadingsVal($name,"tr_errmsg",undef)."
". "". @@ -3416,9 +3690,10 @@ sub YAAHM_toptable($){ } #style=\"height:20px;border-bottom: 10px solid #333333;background-image: linear-gradient(#e5e5e5,#ababab);\" $ret .= ""; - $ret .= "
".YAAHM_modewidget($hash)."

"; - - #-- repeat manual next for every weekly table + $ret .= "

"; + + #-- manual next time table, just below mode/state table + $ret .= ""; my $nval = ""; my $wupn; $ret .= "\n"; @@ -3435,47 +3710,75 @@ sub YAAHM_toptable($){ } $ret .= "\n"; $ret .= "
".$yaahm_tt->{"manual"}."

".$yaahm_tt->{"overview"}."
"; + # spanning 3 cols of main table + $ret .= "\n"; + #-- widget/state table, spanning 2 cols of main table + $ret .= "
".$yaahm_tt->{"overview"}."
"; #-- time widget $ret .= ""; #-- continue summary with headers - $ret .= ""; + $ret .= ""; - #-- device states - $ret .= "\n"; - - $styl="border-left:1px solid gray;border-radius:0px;"; - $stym="border:none"; - $styr="border-right:1px solid gray;border-radius:0px;"; - $ret .= ""; + ### device states inserted as new td spanning 8 rows #################################################################################### + $ret .= ""; + + ### device action table inserted as new td spanning 10 rows ################################################################################################ + if( $avl ){ + my ($dea,$dev,$tim); + $ret .= sprintf(""; + } + $ret .= "\n"; + + ### next lines of state summary ######################################################## + $ret .= ""; #-- continue summary with entries - $ret .= "\n"; - $ret .= "\n"; - $ret .= "\n"; - $ret .= "\n"; - $ret .= "\n"; - $styl="border-left:1px solid gray;border-bottom:1px solid gray;border-bottom-left-radius:10px;border-bottom-right-radius:0px;border-top-left-radius:0px;"; - $stym="border-bottom:1px solid gray;border-radius:0px;"; - $styr="border-right:1px solid gray;border-bottom:1px solid gray;border-bottom-right-radius:10px;border-top-right-radius:0px;border-bottom-left-radius:0px;"; - $ret .= "\n"; + $ret .= "\n"; + $ret .= "\n"; + $ret .= "\n"; + $ret .= "\n"; + $ret .= "\n"; + $ret .= "\n"; #-- housetime/phase $ret .= "". @@ -3577,6 +3879,83 @@ sub YAAHM_Longtable($){ #-- $ret = YAAHM_toptable($name); + ### device action table ################################################################################################ + my $avl = AttrVal($name,"deviceActions",undef); + if( $avl){ + $ret .= "\n"; + $ret .= ""; + } + ### daily profile table ################################################################################################ my $row = 1; my $event = ""; @@ -3678,14 +4057,19 @@ sub YAAHM_Longtable($){ $row = 1; $event = ""; $sval = ""; - + my $asg = ""; + my $ast = ""; + my $ass; + my $acc; + + #--header my $wupn; my $wt = ( $weeklyno == 1) ? $yaahm_tt->{"profile"} :$yaahm_tt->{"profiles"}; $ret .= ""; - $ret .= "
".$yaahm_tt->{"today"}."".$yaahm_tt->{"tomorrow"}."".$yaahm_tt->{"today"}."".$yaahm_tt->{"tomorrow"}."". - "
".ReadingsVal($name,"tr_housestate",undef)."
→". - $yaahm_tt->{"secstate"}."
".ReadingsVal($name,"sdev_housestate","")."
".$yaahm_tt->{$weeklytable[$hash->{DATA}{"DD"}[0]{"weekday"}]}[0] . - "".$yaahm_tt->{$weeklytable[$hash->{DATA}{"DD"}[1]{"weekday"}]}[0]."
". + $yaahm_tt->{"state"}."
". + "
".ReadingsVal($name,"tr_housestate",undef)."
→". + $yaahm_tt->{"secstate"}."
".ReadingsVal($name,"sdev_housestate","")."
",$weeklyno+8); + $ret .= ""; + $ret .= ""; + $ret .= ""; + for( my $i=0;$i<$devactno;$i++){ + + #-- timer status + my $ts; + if( defined($defs{$name.".xtimer_".$i.".IF"})){ + if( ReadingsVal($name.".xtimer_".$i.".IF","state","") ne "inactive" ){ + $ts = "
"; + }else{ + $ts = "
"; + } + }else{ + $ts = ""; + } + $dea = $actdevlist[$i]; + $dev = $hash->{DATA}{"XT"}{$dea}{"name"}; + Log3 $name,1,"[YAAHM_toptable] key $dea not equal to name $dev" + if( $dea ne $dev); + $tim = $hash->{DATA}{"XT"}{$dea}{"time"}; + $ret .= ""; + $ret .= ""; + $ret .= sprintf("",$i); + } + + $ret .= "
".$yaahm_tt->{"deviceactions"}."
".$dev."$ts".$tim."
".$yaahm_tt->{$weeklytable[$hash->{DATA}{"DD"}[0]{"weekday"}]}[0] . + "".$yaahm_tt->{$weeklytable[$hash->{DATA}{"DD"}[1]{"weekday"}]}[0]."
".$hash->{DATA}{"DD"}[0]{"date"}. - "".$hash->{DATA}{"DD"}[1]{"date"}."
".$yaahm_tt->{"daylight"}."".$hash->{DATA}{"DD"}[0]{"sunrise"}."-".$hash->{DATA}{"DD"}[0]{"sunset"}. - "".$hash->{DATA}{"DD"}[1]{"sunrise"}."-".$hash->{DATA}{"DD"}[1]{"sunset"}."
".$yaahm_tt->{"daytime"}."".$hash->{DATA}{"DT"}{"morning"}[0]."-". - $hash->{DATA}{"DT"}{"night"}[0]."
".$yaahm_tt->{"daytype"}."".$yaahm_tt->{$hash->{DATA}{"DD"}[0]{"daytype"}}. - "".$yaahm_tt->{$hash->{DATA}{"DD"}[1]{"daytype"}}."
".$yaahm_tt->{"description"}."".$hash->{DATA}{"DD"}[0]{"desc"}. - "".$hash->{DATA}{"DD"}[1]{"desc"}."
".$yaahm_tt->{"date"}."".$hash->{DATA}{"DD"}[0]{"special"}. - "".$hash->{DATA}{"DD"}[1]{"special"}."
".$hash->{DATA}{"DD"}[0]{"date"}. + "".$hash->{DATA}{"DD"}[1]{"date"}."
".$yaahm_tt->{"daylight"}."".$hash->{DATA}{"DD"}[0]{"sunrise"}."-".$hash->{DATA}{"DD"}[0]{"sunset"}. + "".$hash->{DATA}{"DD"}[1]{"sunrise"}."-".$hash->{DATA}{"DD"}[1]{"sunset"}."
".$yaahm_tt->{"daytime"}."".$hash->{DATA}{"DT"}{"morning"}[0]."-". + $hash->{DATA}{"DT"}{"night"}[0]."
".$yaahm_tt->{"daytype"}."".$yaahm_tt->{$hash->{DATA}{"DD"}[0]{"daytype"}}[0]. + "".$yaahm_tt->{$hash->{DATA}{"DD"}[1]{"daytype"}}[0]."
".$yaahm_tt->{"description"}."".$hash->{DATA}{"DD"}[0]{"desc"}. + "".$hash->{DATA}{"DD"}[1]{"desc"}."
".$yaahm_tt->{"date"}."".$hash->{DATA}{"DD"}[0]{"special"}. + "".$hash->{DATA}{"DD"}[1]{"special"}."
". @@ -3498,24 +3801,23 @@ sub YAAHM_toptable($){ } #-- ring times - my $ring_0x = $hash->{DATA}{"WT"}[$i]{"ring_0x"}; + my $ring_0x = $hash->{DATA}{"WT"}[$i]{"ring_0x"}; my $ring_1x = $hash->{DATA}{"WT"}[$i]{"ring_1x"}; my $wake = $hash->{DATA}{"WT"}[$i]{"wake"}; #-- border styles - if( $i==0 ){ - $styl="border-left:1px solid gray;border-top:1px solid gray;border-top-left-radius:10px;border-top-right-radius:0px;border-bottom-left-radius:0px;"; - $stym="border-top:1px solid gray;border-radius:0px;"; - $styr="border-right:1px solid gray;border-top:1px solid gray;border-top-right-radius:10px;border-top-left-radius:0px;border-bottom-right-radius:0px;"; + $styl=$stopleft; + $stym=$stopmid; + $styr=$stopright; }elsif( $i == $weeklyno-1 ){ - $styl="border-left:1px solid gray;border-bottom:1px solid gray;border-bottom-left-radius:10px;border-bottom-right-radius:0px;border-top-left-radius:0px;"; - $stym="border-bottom:1px solid gray;border-radius:0px;"; - $styr="border-right:1px solid gray;border-bottom:1px solid gray;border-bottom-right-radius:10px;border-top-right-radius:0px;border-bottom-left-radius:0px;"; + $styl=$sbotleft; + $stym=$sbotmid; + $styr=$sbotright; }else{ - $styl="border-left:1px solid gray;border-radius:0px;"; - $stym="border:none"; - $styr="border-right:1px solid gray;border-radius:0px;"; + $styl=$smidleft; + $stym=$smidmid; + $styr=$smidright; } $ret.="".$wupn. "$ts
".$yaahm_tt->{"deviceaction"}.$yaahm_tt->{"profile"}; + $ret .= "  {"start"}." ".$yaahm_tt->{"deviceactions"}."\" onclick=\"javascript:yaahm_startDeviceAction('$name')\"/>
\n"; + + #-- number of action devices + my $devactno; + my @actdevlist = split(',',$avl); + $devactno=int(@actdevlist); + + my ($dea,$dev,$eval,$lval,$xval,$evt); + my ($styl,$stym,$styr); + $ret .= ""; + $ret .= ""; + for( my $i=0;$i<$devactno;$i++){ + $dea = $actdevlist[$i]; + $dev = $hash->{DATA}{"XT"}{$dea}{"name"}; + #-- Here we may have a new and therefore empty deviceaction + if( !defined($dev) || $dev eq "" ){ + $hash->{DATA}{"XT"}{$dea}{"name"}=$dea; + $dev = $dea; + } + $evt = $hash->{DATA}{"XT"}{$dea}{"event"}; + $eval = $hash->{DATA}{"XT"}{$dea}{"earliest"}; + $lval = $hash->{DATA}{"XT"}{$dea}{"latest"}; + $xval = $hash->{DATA}{"XT"}{$dea}{"cmd"}; + + $ret .= sprintf("",$i); + $ret .= ""; + #-- timer status + my $ts; + if( defined($defs{$name.".xtimer_".$i.".IF"})){ + if( ReadingsVal($name.".xtimer_".$i.".IF","state","") ne "inactive" ){ + $ts = "
"; + }else{ + $ts = "
"; + } + }else{ + $ts = ""; + } + $ret .= ""; + $ret .= sprintf(""; + $ret .= sprintf("",$i); + $ret .= sprintf("",$i); + $ret .= sprintf("",$i); + } + + $ret .= "
".$yaahm_tt->{"name"}."".$yaahm_tt->{"event"}."".$yaahm_tt->{"earliest"}."".$yaahm_tt->{"latest"}."".$yaahm_tt->{"action"}."
$name.xtimer_".$i.".IF$ts
".$yaahm_tt->{"weekly"}.$wt. "  {"start"}." ".$yaahm_tt->{"weekly"}.$yaahm_tt->{"timer"}."\" onclick=\"javascript:yaahm_startWeeklyTimer('$name')\"/>
\n"; + $ret .= "
\n"; #-- repeat name for every weekly table $ret .= ""; @@ -3698,63 +4082,26 @@ sub YAAHM_Longtable($){ #-- repeat link for every weekly table $ret .= ""; - #-- array with activity status - my @tss; - + #-- timer status + my $tss; for (my $i=0;$i<$weeklyno;$i++){ $wupn = $hash->{DATA}{"WT"}[$i]{"name"}; #-- timer status if( defined($defs{$name.".wtimer_".$i.".IF"})){ $tl = "".$name.".wtimer_".$i.".IF"; if( ReadingsVal($name.".wtimer_".$i.".IF","mode","") ne "disabled" ){ - push(@tss,"
"); + $tss="
"; }else{ - push(@tss,"
"); + $tss="
"; } }else{ $tl = $yaahm_tt->{"notstarted"}; - push(@tss,""); + $tss= ""; } - $ret .= sprintf("",$i,$tl); + $ret .= sprintf("",$i,$tl,$tss); } $ret .= "\n"; - #-- repeat active status for every weekly table - my $asg = ""; - my $ast = ""; - my $ass; - my $acc; - #--header - for(my $i=0;$i{$profmode[$i]},0,3)." "; - $ast .= $yaahm_tt->{$profmode[$i]}." "; - } - for(my $i=0;$i{$profday[$i]},0,3)." "; - $ast .= $yaahm_tt->{$profday[$i]}." "; - } - $ret .= ""; - for (my $i=0;$i<$weeklyno;$i++){ - $wupn = $hash->{DATA}{"WT"}[$i]{"name"}; - $ret .= ""; - } - $ret .= "\n"; - #-- repeat action for every weekly table $ret .= ""; for (my $i=0;$i<$weeklyno;$i++){ @@ -3774,21 +4121,70 @@ sub YAAHM_Longtable($){ $ret .= sprintf("",$i); } $ret .= "\n"; - - #-- repeat unit for every weekly table - $ret .= ""; + + #-- specialday header + $ret .= ""; for (my $i=0;$i<$weeklyno;$i++){ $ret .= ""; } $ret .= "\n"; + #-- repeat specialday entry every weekly table + for (my $j=7;$j<9;$j++){ + my $key = $weeklytable[$j]; + $row++; + $event = $yaahm_tt->{$key}[0]; + + $ret .= sprintf("\n", ($row&1)?"odd":"even"); + for (my $i=0;$i<$weeklyno;$i++){ + $sval = $hash->{DATA}{"WT"}[$i]{$key}; + #-- check if weekday profile active here or not + $ass = ( defined($hash->{DATA}{"WT"}[$i]{"acti_d"}) ) ? $hash->{DATA}{"WT"}[$i]{"acti_d"} : ""; + $acc = ( $ass =~ /.*$key.*/ ) ? "disabled=\"disabled\"" : ""; + $ret .= sprintf("",$key,$i); + } + $ret .= "\n"; + } + #-- weekday header $ret .= ""; for (my $i=0;$i<$weeklyno;$i++){ - $ret .= ""; + $ret .= ""; } $ret .= "\n"; - + + #-- checkboxes for every weekly table + for(my $i=0;$i{$profmode[$i]},0,3)." "; + $ast .= $yaahm_tt->{$profmode[$i]}." "; + } + for(my $i=0;$i{$profday[$i]}[1]." "; + $ast .= $yaahm_tt->{$profday[$i]}." "; + } + $ret .= ""; + for (my $i=0;$i<$weeklyno;$i++){ + $wupn = $hash->{DATA}{"WT"}[$i]{"name"}; + $ret .= ""; + } + $ret .= "\n"; + + #-- repeat weekday entry every weekly table for (my $j=0;$j<7;$j++){ my $key = $weeklytable[$j]; $row++; @@ -3984,7 +4380,10 @@ sub YAAHM_Longtable($){
  • On any time (event), donotdisturb mode will be reset to normal mode.
  • -
  • <attr <name> norepeat 0|1 +
  • attr <name> sunrise SunRise|AstroTwilightMorning|NauticTwilightMorning|CivilTwilightMorning|CustomTwilightMorning
    + attr <name> sunset SunSet|AstroTwilightEvening|NauticTwilightEvening|CivilTwilightEvening|CustomTwilightEvening
    + Use different definitions for sunset and sunrise, see Module Astro
  • +
  • attr <name> norepeat 0|1
    if set to 1, repeated executions of wakeup, sleep and other timer events from the weekly programme will be suppressed.
  • attr <name> stateDevices (<device>:<state-unsecured>:<state-secured>:<state-protected>:<state-guarded>,)*
    comma separated list of devices and their state in each of the house (security) states. Each of the listed devices will be checked in the interval given by the stateInterval attribute @@ -4002,13 +4401,15 @@ sub YAAHM_Longtable($){
  • If in normal mode and time event sleep or night, and currently in (security) state unsecured, the state will change to secured.
  • -
  • attr <name> <comma-separated list of devices> +
  • attr <name> deviceActions <comma-separated list of virtual device actions> +
    list of virtual device actions that yaahm is performing, e.g. roller_up, roller_down etc.
  • +
  • attr <name> holidayDevices <comma-separated list of devices>
    list of devices that provide holiday information. The devices may be holiday devices or Calendar devices
  • -
  • attr <comma-separated list of devices> +
  • attr <name> vacationDevices <comma-separated list of devices>
    list of devices that provide vacation information. The devices may be holiday devices or Calendar devices
  • -
  • attr <comma-separated list of devices> +
  • attr <name> specialDevices <comma-separated list of devices>
    list of devices that provide special date information (like e.g. garbage collection). The devices may be holiday devices or Calendar devices
  • @@ -4019,7 +4420,7 @@ sub YAAHM_Longtable($){

    YAAHM

    =end html_DE =cut diff --git a/fhem/www/pgm2/yaahm.js b/fhem/www/pgm2/yaahm.js index bc7f1ffcb..119af6132 100644 --- a/fhem/www/pgm2/yaahm.js +++ b/fhem/www/pgm2/yaahm.js @@ -1,6 +1,6 @@ //######################################################################################## // yaahm.js -// Version 1.45 +// Version 3.0beta4 // See 95_YAAHM for licensing //######################################################################################## //# Prof. Dr. Peter A. Henning @@ -265,6 +265,57 @@ function () { } }); +//------------------------------------------------------------------------------------------------------ +// Device Action +//------------------------------------------------------------------------------------------------------ + +function yaahm_startDeviceAction(name) { + + 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 event, earliest and latest + // iterate over different device actions + for (var i = 0; i < devactno; i++) { + var dev, evt; + var eval, lval, xval; + if (document.getElementById('xt' + i + '_n') !== null) { + dev = encodeParm(document.getElementById('xt' + i + '_n').innerHTML); + } else { + dev = "undef" + } + if (document.getElementById('xt' + i + '_v') !== null) { + evt = encodeParm(document.getElementById('xt' + i + '_v').value); + } else { + evt = "undef" + } + if (document.getElementById('xt' + i + '_e') !== null) { + eval = encodeParm(document.getElementById('xt' + i + '_e').value); + } else { + eval = "undef" + } + if (document.getElementById('xt' + i + '_l') !== null) { + lval = encodeParm(document.getElementById('xt' + i + '_l').value); + } else { + lval = "undef" + } + //action + if (document.getElementById('xt' + i + '_x') !== null) { + xval = encodeParm(document.getElementById('xt' + i + '_x').value); + } else { + xval = "undef" + } + + + FW_cmd(url + '?XHR=1&fwcsrf=' + csrfToken + '&cmd.' + name + '={main::YAAHM_setParm("' + name + '","xt","' + i + '","' + dev + '","' + evt + '","' + eval + '","' + lval + '","' + xval + '")}'); + } + // really start it now + FW_cmd(url + '?XHR=1&fwcsrf=' + csrfToken + '&cmd.' + name + ' ={main::YAAHM_startDeviceActions("' + name + '")}'); + +} //------------------------------------------------------------------------------------------------------ // Start the daily timer @@ -313,6 +364,28 @@ function yaahm_startDayTimer(name) { $('#dtlink').html('' + name + '.dtimer.IF'); } +//------------------------------------------------------------------------------------------------------ +// daytype logic +//------------------------------------------------------------------------------------------------------ + +function yaahm_dtlogic(i,dt) { + //i = timer number, j = daytype number + //has it been checked ? + //activity vacation/holiday + var aval; + //modify input field + var field = document.getElementById('wt' + dt + i + '_s'); + if (field !== null) { + var checkBox = document.getElementById('acti_' + dt + i + '_d'); + if (checkBox.checked == true){ + field.value = ''; + field.disabled = true; + }else{ + field.disabled = false; + } + } +} + //------------------------------------------------------------------------------------------------------ // Weekly profile //------------------------------------------------------------------------------------------------------ @@ -331,7 +404,7 @@ function yaahm_startWeeklyTimer(name) { var xval; var nval; var aval1, aval2; - var sval =[ "", "", "", "", "", "", ""]; + var sval =[ "", "", "", "", "", "", "", "", ""]; //action if (document.getElementById('wt' + i + '_x') !== null) { xval = encodeParm(document.getElementById('wt' + i + '_x').value); @@ -354,7 +427,7 @@ function yaahm_startWeeklyTimer(name) { }).get(); //iterate over days of week - for (var j = 0; j < 7; j++) { + for (var j = 0; j < 9; j++) { if (document.getElementById('wt' + weeklykeys[j] + i + '_s') !== null) { sval[j] = document.getElementById('wt' + weeklykeys[j] + i + '_s').value; } else {
    ".$yaahm_tt->{"name"}."
    ".$yaahm_tt->{"timer"}."
    %s
    %s%s
    ".$yaahm_tt->{"active"}."
    ".$asg."
    ".$tss[$i]."
    "; - - $asg = ""; - $ass = ( defined($hash->{DATA}{"WT"}[$i]{"acti_m"}) ) ? $hash->{DATA}{"WT"}[$i]{"acti_m"} : ""; - for( my $j=0;$j ",$i); - } - $ass = ( defined($hash->{DATA}{"WT"}[$i]{"acti_d"}) ) ? $hash->{DATA}{"WT"}[$i]{"acti_d"} : ""; - for( my $j=0;$j ",$i); - } - $ret .= "$asg
    ".$yaahm_tt->{"action"}."
    ".$yaahm_tt->{"daytype"}."".$yaahm_tt->{"time"}." [hh:mm]
    $event
    ".$yaahm_tt->{"weekday"}."".$yaahm_tt->{"time"}." [hh:mm]
    ".$yaahm_tt->{"active"}."
    ".$asg."
    "; + + $asg = ""; + $ass = ( defined($hash->{DATA}{"WT"}[$i]{"acti_m"}) ) ? $hash->{DATA}{"WT"}[$i]{"acti_m"} : ""; + for( my $j=0;$j ",$i); + } + $ass = ( defined($hash->{DATA}{"WT"}[$i]{"acti_d"}) ) ? $hash->{DATA}{"WT"}[$i]{"acti_d"} : ""; + for( my $j=0;$j ",$i,$profday[$j],$i,$i,$profday[$j]); + } + $ret .= "$asg