2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-22 08:11:44 +00:00

98_WeekdayTimer.pm: first steps towards better PBP conformity

git-svn-id: https://svn.fhem.de/fhem/trunk@21883 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
Beta-User 2020-05-06 20:21:38 +00:00
parent 16bff57965
commit 4af95c98ba

View File

@ -34,8 +34,8 @@ use Data::Dumper;
$Data::Dumper::Sortkeys = 1; $Data::Dumper::Sortkeys = 1;
################################################################################ ################################################################################
sub WeekdayTimer_Initialize($){ sub WeekdayTimer_Initialize {
my ($hash) = @_; my $hash = shift // return;
# Consumer # Consumer
$hash->{SetFn} = "WeekdayTimer_Set"; $hash->{SetFn} = "WeekdayTimer_Set";
@ -46,71 +46,75 @@ sub WeekdayTimer_Initialize($){
$hash->{UpdFn} = "WeekdayTimer_Update"; $hash->{UpdFn} = "WeekdayTimer_Update";
$hash->{AttrList}= "disable:0,1 delayedExecutionCond WDT_delayedExecutionDevices WDT_Group switchInThePast:0,1 commandTemplate ". $hash->{AttrList}= "disable:0,1 delayedExecutionCond WDT_delayedExecutionDevices WDT_Group switchInThePast:0,1 commandTemplate ".
$readingFnAttributes; $readingFnAttributes;
return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_Define($$) { sub WeekdayTimer_Define {
my ($hash, $def) = @_; my $hash = shift;
my $def = shift // return;
WeekdayTimer_InitHelper($hash); WeekdayTimer_InitHelper($hash);
my @a = split("[ \t\\\n]+", $def); my @arr = my @args = split m{\s+}xms, $def;
return "Usage: define <name> $hash->{TYPE} <device> <language> <switching times> <condition|command>" return "Usage: define <name> $hash->{TYPE} <device> <language> <switching times> <condition|command>"
if(@a < 4); if(@arr < 4);
#fuer den modify Altlasten bereinigen #fuer den modify Altlasten bereinigen
delete($hash->{helper}); delete($hash->{helper});
my $name = shift @a; my $name = shift @arr;
my $type = shift @a; my $type = shift @arr;
my $device = shift @a; my $device = shift @arr;
WeekdayTimer_DeleteTimer($hash); WeekdayTimer_DeleteTimer($hash);
my $delVariables = "(CONDITION|COMMAND|profile|Profil)"; my $delVariables = "(CONDITION|COMMAND|profile|Profil)";
map { delete $hash->{$_} if($_=~ m/^$delVariables.*/g) } keys %{$hash}; map { delete $hash->{$_} if($_=~ m{^$delVariables.*}gxms) } keys %{$hash};
$hash->{NAME} = $name; $hash->{NAME} = $name;
$hash->{DEVICE} = $device; $hash->{DEVICE} = $device;
my $language = WeekdayTimer_Language ($hash, \@a); my $language = WeekdayTimer_Language ($hash, \@arr);
if ($def =~ /weekprofile/gm) { if ($def =~ /weekprofile/gm) {
addToDevAttrList($name, "weekprofile"); addToDevAttrList($name, "weekprofile");
} }
InternalTimer(time(), "WeekdayTimer_Start",$hash,0); InternalTimer(time(), "WeekdayTimer_Start",$hash,0);
return undef; return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_Undef($$) { sub WeekdayTimer_Undef {
my ($hash, $arg) = @_; my ($hash, $arg) = @_;
foreach my $idx (keys %{$hash->{profil}}) { for my $idx (keys %{$hash->{profil}}) {
WeekdayTimer_RemoveInternalTimer($idx, $hash); WeekdayTimer_RemoveInternalTimer($idx, $hash);
} }
WeekdayTimer_RemoveInternalTimer("SetTimerOfDay", $hash); WeekdayTimer_RemoveInternalTimer("SetTimerOfDay", $hash);
delete $modules{$hash->{TYPE}}{defptr}{$hash->{NAME}}; delete $modules{$hash->{TYPE}}{defptr}{$hash->{NAME}};
return undef; return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_Start($) { sub WeekdayTimer_Start {
my ($hash) = @_; my $hash = shift;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my @a = split("[ \t\\\n]+", $hash->{DEF}); my $def = $hash->{DEF};
my $device = shift @a;
my $language = WeekdayTimer_Language ($hash, \@a); my @arr = split m{\s+}xms, $def;
my $device = shift @arr;
my $language = WeekdayTimer_Language ($hash, \@arr);
my $idx = 0; my $idx = 0;
$hash->{dayNumber} = {map {$_ => $idx++} @{$hash->{shortDays}{$language}}}; $hash->{dayNumber} = {map {$_ => $idx++} @{$hash->{shortDays}{$language}}};
$hash->{helper}{daysRegExp} = '(' . join ("|", @{$hash->{shortDays}{$language}}) . ")"; $hash->{helper}{daysRegExp} = '(' . join ("|", @{$hash->{shortDays}{$language}}) . ")";
$hash->{helper}{daysRegExpMessage} = $hash->{helper}{daysRegExp}; $hash->{helper}{daysRegExpMessage} = $hash->{helper}{daysRegExp};
$hash->{helper}{daysRegExp} =~ s/\$/\\\$/g; $hash->{helper}{daysRegExp} =~ s/\$/\\\$/gx;
$hash->{helper}{daysRegExp} =~ s/\!/\\\!/g; $hash->{helper}{daysRegExp} =~ s/\!/\\\!/gx;
WeekdayTimer_GlobalDaylistSpec ($hash, \@a); WeekdayTimer_GlobalDaylistSpec ($hash, \@arr);
my @switchingtimes = WeekdayTimer_gatherSwitchingTimes ($hash, \@a); my @switchingtimes = WeekdayTimer_gatherSwitchingTimes ($hash, \@arr);
my $conditionOrCommand = join (" ", @a); my $conditionOrCommand = join (" ", @arr);
# test if device is defined # test if device is defined
Log3 ($hash, 3, "[$name] device <$device> in fhem not defined, but accepted") if(!$defs{$device}); Log3 ($hash, 3, "[$name] device <$device> in fhem not defined, but accepted") if(!$defs{$device});
@ -120,13 +124,13 @@ sub WeekdayTimer_Start($) {
$hash->{STILLDONETIME} = 0; $hash->{STILLDONETIME} = 0;
$hash->{SWITCHINGTIMES} = \@switchingtimes; $hash->{SWITCHINGTIMES} = \@switchingtimes;
$attr{$name}{verbose} = 5 if (!defined $attr{$name}{verbose} && $name =~ m/^tst.*/ ); $attr{$name}{verbose} = 5 if (!defined $attr{$name}{verbose} && $name =~ m/^tst.*/x );
$defs{$device}{STILLDONETIME} = 0 if($defs{$device}); $defs{$device}{STILLDONETIME} = 0 if($defs{$device});
$modules{$hash->{TYPE}}{defptr}{$hash->{NAME}} = $hash; $modules{$hash->{TYPE}}{defptr}{$hash->{NAME}} = $hash;
$hash->{CONDITION} = ""; $hash->{COMMAND} = ""; $hash->{CONDITION} = ""; $hash->{COMMAND} = "";
if($conditionOrCommand =~ m/^\(.*\)$/g) { #condition (*) if($conditionOrCommand =~ m/^\(.*\)$/gx) { #condition (*)
$hash->{CONDITION} = $conditionOrCommand; $hash->{CONDITION} = $conditionOrCommand;
} elsif(length($conditionOrCommand) > 0 ) { } elsif(length($conditionOrCommand) > 0 ) {
$hash->{COMMAND} = $conditionOrCommand; $hash->{COMMAND} = $conditionOrCommand;
@ -141,17 +145,17 @@ sub WeekdayTimer_Start($) {
WeekdayTimer_SetTimerOfDay({ HASH => $hash}); WeekdayTimer_SetTimerOfDay({ HASH => $hash});
return undef; return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_Set($@) { sub WeekdayTimer_Set {
my ($hash, @a) = @_; my ($hash,@arr) = @_;
return "no set value specified" if(int(@a) < 2); return "no set value specified" if(int(@arr) < 2);
return "Unknown argument $a[1], choose one of enable:noArg disable:noArg WDT_Params:single,WDT_Group,all weekprofile" if($a[1] eq "?"); return "Unknown argument $arr[1], choose one of enable:noArg disable:noArg WDT_Params:single,WDT_Group,all weekprofile" if($arr[1] eq "?");
my $name = shift @a; my $name = shift @arr;
my $v = join(" ", @a); my $v = join(" ", @arr);
if ($v eq "enable") { if ($v eq "enable") {
Log3 ($hash, 3, "[$name] set $name $v"); Log3 ($hash, 3, "[$name] set $name $v");
@ -178,22 +182,22 @@ sub WeekdayTimer_Set($@) {
WeekdayTimer_SetAllParms("all"); WeekdayTimer_SetAllParms("all");
Log3 $hash,3, "[$name] set $name $v called; params in all WeekdayTimer instances will be set!"; Log3 $hash,3, "[$name] set $name $v called; params in all WeekdayTimer instances will be set!";
} }
} elsif ($v =~ /weekprofile ([^: ]+):([^:]+):([^: ]+)\b/) { } elsif ($v =~ /weekprofile ([^: ]+):([^:]+):([^: ]+)\b/x) {
Log3 $hash, 3, "[$name] set $name $v"; Log3 $hash, 3, "[$name] set $name $v";
return unless WeekdayTimer_UpdateWeekprofileReading($hash, $1, $2, $3); return unless WeekdayTimer_UpdateWeekprofileReading($hash, $1, $2, $3);
WeekdayTimer_DeleteTimer($hash); WeekdayTimer_DeleteTimer($hash);
WeekdayTimer_Start($hash); WeekdayTimer_Start($hash);
} }
return undef; return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_Get($@) { sub WeekdayTimer_Get {
my ($hash, @a) = @_; my ($hash, @arr) = @_;
return "argument is missing" if(int(@a) != 2); return "argument is missing" if(int(@arr) != 2);
$hash->{LOCAL} = 1; $hash->{LOCAL} = 1;
delete $hash->{LOCAL}; delete $hash->{LOCAL};
my $reading= $a[1]; my $reading= $arr[1];
my $value; my $value;
if(defined($hash->{READINGS}{$reading})) { if(defined($hash->{READINGS}{$reading})) {
@ -201,20 +205,20 @@ sub WeekdayTimer_Get($@) {
} else { } else {
return "no such reading: $reading"; return "no such reading: $reading";
} }
return "$a[0] $reading => $value"; return "$arr[0] $reading => $value";
} }
################################################################################ ################################################################################
sub WeekdayTimer_GetHashIndirekt ($$) { sub WeekdayTimer_GetHashIndirekt {
my ($myHash, $function) = @_; my ($myHash, $function) = @_;
if (!defined($myHash->{HASH})) { if (!defined($myHash->{HASH})) {
Log3 $myHash, 3, "[$function] myHash not valid"; Log3 $myHash, 3, "[$function] myHash not valid";
return undef; return;
}; };
return $myHash->{HASH}; return $myHash->{HASH};
} }
################################################################################ ################################################################################
sub WeekdayTimer_InternalTimer($$$$$) { sub WeekdayTimer_InternalTimer {
my ($modifier, $tim, $callback, $hash, $waitIfInitNotDone) = @_; my ($modifier, $tim, $callback, $hash, $waitIfInitNotDone) = @_;
my $timerName = "$hash->{NAME}_$modifier"; my $timerName = "$hash->{NAME}_$modifier";
@ -231,7 +235,7 @@ sub WeekdayTimer_InternalTimer($$$$$) {
return $mHash; return $mHash;
} }
################################################################################ ################################################################################
sub WeekdayTimer_RemoveInternalTimer($$) { sub WeekdayTimer_RemoveInternalTimer {
my ($modifier, $hash) = @_; my ($modifier, $hash) = @_;
my $timerName = "$hash->{NAME}_$modifier"; my $timerName = "$hash->{NAME}_$modifier";
@ -241,10 +245,11 @@ sub WeekdayTimer_RemoveInternalTimer($$) {
Log3 $hash, 5, "[$hash->{NAME}] removing Timer: $timerName"; Log3 $hash, 5, "[$hash->{NAME}] removing Timer: $timerName";
RemoveInternalTimer($myHash); RemoveInternalTimer($myHash);
} }
return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_InitHelper($) { sub WeekdayTimer_InitHelper {
my ($hash) = @_; my $hash = shift;
$hash->{longDays} = { "de" => ["Sonntag", "Montag","Dienstag","Mittwoch", "Donnerstag","Freitag", "Samstag", "Wochenende", "Werktags" ], $hash->{longDays} = { "de" => ["Sonntag", "Montag","Dienstag","Mittwoch", "Donnerstag","Freitag", "Samstag", "Wochenende", "Werktags" ],
"en" => ["Sunday", "Monday","Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "weekend", "weekdays" ], "en" => ["Sunday", "Monday","Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "weekend", "weekdays" ],
@ -254,9 +259,12 @@ sub WeekdayTimer_InitHelper($) {
"en" => ["su","mo","tu","we","th","fr","sa",'$we','!$we'], "en" => ["su","mo","tu","we","th","fr","sa",'$we','!$we'],
"fr" => ["di","lu","ma","me","je","ve","sa",'$we','!$we'], "fr" => ["di","lu","ma","me","je","ve","sa",'$we','!$we'],
"nl" => ["zo","ma","di","wo","do","vr","za",'$we','!$we']}; "nl" => ["zo","ma","di","wo","do","vr","za",'$we','!$we']};
return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_Profile($) { sub WeekdayTimer_Profile {
my $hash = shift; my $hash = shift;
my $language = $hash->{LANGUAGE}; my $language = $hash->{LANGUAGE};
@ -268,12 +276,12 @@ sub WeekdayTimer_Profile($) {
# ---- Zeitpunkte den Tagen zuordnen ----------------------------------- # ---- Zeitpunkte den Tagen zuordnen -----------------------------------
my $idx = 0; my $idx = 0;
foreach my $st (@{$hash->{SWITCHINGTIMES}}) { for my $st (@{$hash->{SWITCHINGTIMES}}) {
my ($tage,$time,$parameter,$overrulewday) = WeekdayTimer_SwitchingTime ($hash, $st); my ($tage,$time,$parameter,$overrulewday) = WeekdayTimer_SwitchingTime ($hash, $st);
$idx++; $idx++;
foreach my $d (@{$tage}) { for my $d (@{$tage}) {
my @listeDerTage = ($d); my @listeDerTage = ($d);
push (@listeDerTage, WeekdayTimer_getListeDerTage($hash, $d, $time)) if ($d>=7); push (@listeDerTage, WeekdayTimer_getListeDerTage($hash, $d, $time)) if ($d>=7);
@ -297,7 +305,7 @@ sub WeekdayTimer_Profile($) {
} }
# ---- Zeitpunkte des aktuellen Tages mit EPOCH ermitteln -------------- # ---- Zeitpunkte des aktuellen Tages mit EPOCH ermitteln --------------
$idx = 0; $idx = 0;
foreach my $st (@{$hash->{SWITCHINGTIMES}}) { for my $st (@{$hash->{SWITCHINGTIMES}}) {
my ($tage,$time,$parameter,$overrulewday) = WeekdayTimer_SwitchingTime ($hash, $st); my ($tage,$time,$parameter,$overrulewday) = WeekdayTimer_SwitchingTime ($hash, $st);
my $echtZeit = WeekdayTimer_EchteZeit ($hash, $wday, $time); my $echtZeit = WeekdayTimer_EchteZeit ($hash, $wday, $time);
my ($stunde, $minute, $sekunde) = split (":",$echtZeit); my ($stunde, $minute, $sekunde) = split (":",$echtZeit);
@ -311,13 +319,13 @@ sub WeekdayTimer_Profile($) {
} }
# ---- Texte Readings aufbauen ----------------------------------------- # ---- Texte Readings aufbauen -----------------------------------------
Log3 $hash, 4, "[$hash->{NAME}] " . sunrise_abs() . " " . sunset_abs() . " " . $longDays{$language}[$wday]; Log3 $hash, 4, "[$hash->{NAME}] " . sunrise_abs() . " " . sunset_abs() . " " . $longDays{$language}[$wday];
foreach my $d (sort keys %{$hash->{profile}}) { for my $d (sort keys %{$hash->{profile}}) {
my $profiltext = ""; my $profiltext = "";
foreach my $t (sort keys %{$hash->{profile}{$d}}) { for my $t (sort keys %{$hash->{profile}{$d}}) {
$profiltext .= "$t " . $hash->{profile}{$d}{$t} . ", "; $profiltext .= "$t " . $hash->{profile}{$d}{$t} . ", ";
} }
my $profilKey = "Profil $d: $longDays{$language}[$d]"; my $profilKey = "Profil $d: $longDays{$language}[$d]";
$profiltext =~ s/, $//; $profiltext =~ s/, $//x;
$hash->{$profilKey} = $profiltext; $hash->{$profilKey} = $profiltext;
Log3 $hash, 4, "[$hash->{NAME}] $profiltext ($profilKey)"; Log3 $hash, 4, "[$hash->{NAME}] $profiltext ($profilKey)";
} }
@ -325,12 +333,13 @@ sub WeekdayTimer_Profile($) {
# für logProxy umhaengen # für logProxy umhaengen
$hash->{helper}{SWITCHINGTIME} = $hash->{profile}; $hash->{helper}{SWITCHINGTIME} = $hash->{profile};
delete $hash->{profile}; delete $hash->{profile};
return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_getListeDerTage($$$) { sub WeekdayTimer_getListeDerTage {
my ($hash, $d, $time) = @_; my ($hash, $d, $time) = @_;
my %hdays=(); my %hdays=();
unless (AttrVal('global', 'holiday2we', '') =~ m,\bweekEnd\b,) { unless (AttrVal('global', 'holiday2we', '') =~ m,\bweekEnd\b,x) {
@hdays{(0, 6)} = undef if ($d==7); # sa,so ( $we) @hdays{(0, 6)} = undef if ($d==7); # sa,so ( $we)
@hdays{(1..5)} = undef if ($d==8); # mo-fr (!$we) @hdays{(1..5)} = undef if ($d==8); # mo-fr (!$we)
} else { } else {
@ -350,7 +359,7 @@ sub WeekdayTimer_getListeDerTage($$$) {
return keys %hdays; return keys %hdays;
} }
################################################################################ ################################################################################
sub WeekdayTimer_SwitchingTime($$) { sub WeekdayTimer_SwitchingTime {
my ($hash, $switchingtime) = @_; my ($hash, $switchingtime) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
@ -358,7 +367,7 @@ sub WeekdayTimer_SwitchingTime($$) {
my @tageGlobal = @{WeekdayTimer_daylistAsArray($hash, $globalDaylistSpec)}; my @tageGlobal = @{WeekdayTimer_daylistAsArray($hash, $globalDaylistSpec)};
my (@st, $daylist, $time, $timeString, $para); my (@st, $daylist, $time, $timeString, $para);
@st = split(/\|/, $switchingtime); @st = split(/\|/mx, $switchingtime);
my $overrulewday = 0; my $overrulewday = 0;
if ( @st == 2 || @st == 3 && $st[2] eq "w") { if ( @st == 2 || @st == 3 && $st[2] eq "w") {
$daylist = ($globalDaylistSpec gt "") ? $globalDaylistSpec : "0123456"; $daylist = ($globalDaylistSpec gt "") ? $globalDaylistSpec : "0123456";
@ -387,7 +396,7 @@ sub WeekdayTimer_SwitchingTime($$) {
return (\@tage,$time,$para,$overrulewday); return (\@tage,$time,$para,$overrulewday);
} }
################################################################################ ################################################################################
sub WeekdayTimer_daylistAsArray($$){ sub WeekdayTimer_daylistAsArray {
my ($hash, $daylist) = @_; my ($hash, $daylist) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
@ -398,7 +407,7 @@ sub WeekdayTimer_daylistAsArray($$){
$daylist = lc($daylist); $daylist = lc($daylist);
# Angaben der Tage verarbeiten # Angaben der Tage verarbeiten
# Aufzaehlung 1234 ... # Aufzaehlung 1234 ...
if ( $daylist =~ m/^[0-8]{0,9}$/g) { if ( $daylist =~ m/^[0-8]{0,9}$/gx) {
#Log3 ($hash, 3, "[$name] " . '"7" in daylist now means $we(weekend) - see dokumentation!!!' ) if (index($daylist, '7') != -1); #Log3 ($hash, 3, "[$name] " . '"7" in daylist now means $we(weekend) - see dokumentation!!!' ) if (index($daylist, '7') != -1);
@ -406,10 +415,10 @@ sub WeekdayTimer_daylistAsArray($$){
@hdays{@days} = undef; @hdays{@days} = undef;
# Aufzaehlung Sa,So,... | Mo-Di,Do,Fr-Mo # Aufzaehlung Sa,So,... | Mo-Di,Do,Fr-Mo
} elsif ($daylist =~ m/^($hash->{helper}{daysRegExp}(,|-|$)){0,7}$/g ) { } elsif ($daylist =~ m/^($hash->{helper}{daysRegExp}(,|-|$)){0,7}$/gx ) {
my @subDays; my @subDays;
my @aufzaehlungen = split (",", $daylist); my @aufzaehlungen = split (",", $daylist);
foreach my $einzelAufzaehlung (@aufzaehlungen) { for my $einzelAufzaehlung (@aufzaehlungen) {
my @days = split ("-", $einzelAufzaehlung); my @days = split ("-", $einzelAufzaehlung);
my $days = @days; my $days = @days;
if ($days == 1) { if ($days == 1) {
@ -423,7 +432,9 @@ sub WeekdayTimer_daylistAsArray($$){
@subDays = ($von .. $bis); @subDays = ($von .. $bis);
} else { } else {
#@subDays = ($dayNumber{so} .. $bis, $von .. $dayNumber{sa}); #@subDays = ($dayNumber{so} .. $bis, $von .. $dayNumber{sa});
@subDays = ( 00 .. $bis, $von .. 06); # was until percritic: @subDays = ( 00 .. $bis, $von .. 06);
@subDays = ( 0 .. $bis, $von .. 6);
} }
@hdays{@subDays}=undef; @hdays{@subDays}=undef;
} }
@ -436,7 +447,7 @@ sub WeekdayTimer_daylistAsArray($$){
return \@tage; return \@tage;
} }
################################################################################ ################################################################################
sub WeekdayTimer_EchteZeit($$$) { sub WeekdayTimer_EchteZeit {
my ($hash, $d, $time) = @_; my ($hash, $d, $time) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
@ -447,19 +458,19 @@ sub WeekdayTimer_EchteZeit($$$) {
my $listOfDays = ""; my $listOfDays = "";
# Zeitangabe verarbeiten. # Zeitangabe verarbeiten.
$time = '"' . "$time" . '"' if($time !~ m/^\{.*\}$/g); $time = '"' . "$time" . '"' if($time !~ m/^\{.*\}$/gx);
my $date = $now+($d-$wday)*86400; my $date = $now+($d-$wday)*86400;
my $timeString = '{ my $date='."$date;" .$time."}"; my $timeString = '{ my $date='."$date;" .$time."}";
my $eTimeString = eval( $timeString ); # must deliver HH:MM[:SS] my $eTimeString = eval( $timeString ); # must deliver HH:MM[:SS]
if ($@) { if ($@) {
$@ =~ s/\n/ /g; $@ =~ s/\n/ /gx;
Log3 ($hash, 3, "[$name] " . $@ . ">>>$timeString<<<"); Log3 ($hash, 3, "[$name] " . $@ . ">>>$timeString<<<");
$eTimeString = "00:00:00"; $eTimeString = "00:00:00";
} }
if ($eTimeString =~ m/^[0-2][0-9]:[0-5][0-9]$/g) { # HH:MM if ($eTimeString =~ m/^[0-2][0-9]:[0-5][0-9]$/gx) { # HH:MM
$eTimeString .= ":00"; # HH:MM:SS erzeugen $eTimeString .= ":00"; # HH:MM:SS erzeugen
} elsif ($eTimeString =~ m/^[0-2][0-9](:[0-5][0-9]){2,2}$/g) { # HH:MM:SS } elsif ($eTimeString =~ m/^[0-2][0-9](:[0-5][0-9]){2,2}$/gx) { # HH:MM:SS
; # ok. ; # ok.
} else { } else {
Log3 ($hash, 1, "[$name] invalid time <$eTimeString> HH:MM[:SS]"); Log3 ($hash, 1, "[$name] invalid time <$eTimeString> HH:MM[:SS]");
@ -468,7 +479,7 @@ sub WeekdayTimer_EchteZeit($$$) {
return $eTimeString; return $eTimeString;
} }
################################################################################ ################################################################################
sub WeekdayTimer_zeitErmitteln ($$$$$) { sub WeekdayTimer_zeitErmitteln {
my ($now, $hour, $min, $sec, $days) = @_; my ($now, $hour, $min, $sec, $days) = @_;
my @jetzt_arr = localtime($now); my @jetzt_arr = localtime($now);
@ -502,7 +513,7 @@ E: while (@$a > 0) {
# prüfen ob Anführungszeichen paarig sind # prüfen ob Anführungszeichen paarig sind
my @quotes = ('"', "'" ); my @quotes = ('"', "'" );
foreach my $quote (@quotes){ for my $quote (@quotes){
my $balancedSign = eval "((\$element =~ tr/$quote//))"; my $balancedSign = eval "((\$element =~ tr/$quote//))";
if ($balancedSign % 2) { # ungerade Anzahl quotes, dann verlängern if ($balancedSign % 2) { # ungerade Anzahl quotes, dann verlängern
Log3 $hash, 5, "[$name] $element - unbalanced quotes: $balancedSign $quote found"; Log3 $hash, 5, "[$name] $element - unbalanced quotes: $balancedSign $quote found";
@ -512,7 +523,7 @@ E: while (@$a > 0) {
# prüfen ob öffnende/schliessende Klammern paarig sind # prüfen ob öffnende/schliessende Klammern paarig sind
my %signs = ('('=>')', '{'=>'}'); my %signs = ('('=>')', '{'=>'}');
foreach my $signOpened (keys(%signs)) { for my $signOpened (keys(%signs)) {
my $signClosed = $signs{$signOpened}; my $signClosed = $signs{$signOpened};
my $balancedSign = eval "((\$element =~ tr/$signOpened//) - (\$element =~ tr/$signClosed//))"; my $balancedSign = eval "((\$element =~ tr/$signOpened//) - (\$element =~ tr/$signClosed//))";
if ($balancedSign) { # öffnende/schließende Klammern nicht gleich, dann verlängern if ($balancedSign) { # öffnende/schließende Klammern nicht gleich, dann verlängern
@ -525,7 +536,7 @@ E: while (@$a > 0) {
# ein space am Ende wieder abschneiden # ein space am Ende wieder abschneiden
$element = substr ($element, 0, length($element)-1); $element = substr ($element, 0, length($element)-1);
my @t = split(/\|/, $element); my @t = split(/\|/x, $element);
my $anzahl = @t; my $anzahl = @t;
if ( ($anzahl > 1 && $anzahl < 5) && $t[0] gt "" && $t[1] gt "" ) { if ( ($anzahl > 1 && $anzahl < 5) && $t[0] gt "" && $t[1] gt "" ) {
@ -533,13 +544,13 @@ E: while (@$a > 0) {
#$element = "0-6|".$element if $t[0] =~ m/\d:\d/; #$element = "0-6|".$element if $t[0] =~ m/\d:\d/;
push(@switchingtimes, $element); push(@switchingtimes, $element);
} elsif ($element =~ /weekprofile/ ) { } elsif ($element =~ /weekprofile/ ) {
my @wprof = split(/:/, $element); my @wprof = split(/:/x, $element);
my $wp_name = $wprof[1]; my $wp_name = $wprof[1];
my ($unused,$wp_profile) = split(":", WeekdayTimer_GetWeekprofileReadingTriplett($hash, $wp_name),2); my ($unused,$wp_profile) = split(":", WeekdayTimer_GetWeekprofileReadingTriplett($hash, $wp_name),2);
return unless $wp_profile; return unless $wp_profile;
my $wp_sunaswe = $wprof[2]//0; my $wp_sunaswe = $wprof[2]//0;
my $wp_profile_data = CommandGet(undef,$wp_name . " profile_data ". $wp_profile); my $wp_profile_data = CommandGet(undef,$wp_name . " profile_data ". $wp_profile);
if ($wp_profile_data =~ /(profile.*not.found|usage..profile_data..name)/ ) { if ($wp_profile_data =~ /(profile.*not.found|usage..profile_data..name)/x ) {
Log3 $hash, 3, "[$name] weekprofile $wp_name: no profile named \"$wp_profile\" available"; Log3 $hash, 3, "[$name] weekprofile $wp_name: no profile named \"$wp_profile\" available";
return; return;
} }
@ -548,7 +559,7 @@ E: while (@$a > 0) {
eval { $wp_profile_unpacked = $json->decode($wp_profile_data); }; eval { $wp_profile_unpacked = $json->decode($wp_profile_data); };
$hash->{weekprofiles}{$wp_name} = {'PROFILE'=>$wp_profile,'PROFILE_JSON'=>$wp_profile_data,'SunAsWE'=>$wp_sunaswe,'PROFILE_DATA'=>$wp_profile_unpacked }; $hash->{weekprofiles}{$wp_name} = {'PROFILE'=>$wp_profile,'PROFILE_JSON'=>$wp_profile_data,'SunAsWE'=>$wp_sunaswe,'PROFILE_DATA'=>$wp_profile_unpacked };
my %wp_shortDays = ("Mon"=>1,"Tue"=>2,"Wed"=>3,"Thu"=>4,"Fri"=>5,"Sat"=>6,"Sun"=>0); my %wp_shortDays = ("Mon"=>1,"Tue"=>2,"Wed"=>3,"Thu"=>4,"Fri"=>5,"Sat"=>6,"Sun"=>0);
foreach my $wp_days (sort keys %{$hash->{weekprofiles}{$wp_name}{PROFILE_DATA}}) { for my $wp_days (sort keys %{$hash->{weekprofiles}{$wp_name}{PROFILE_DATA}}) {
my $wp_times = $hash->{weekprofiles}{$wp_name}{PROFILE_DATA}{$wp_days}{time}; my $wp_times = $hash->{weekprofiles}{$wp_name}{PROFILE_DATA}{$wp_days}{time};
my $wp_temps = $hash->{weekprofiles}{$wp_name}{PROFILE_DATA}{$wp_days}{temp}; my $wp_temps = $hash->{weekprofiles}{$wp_name}{PROFILE_DATA}{$wp_days}{temp};
my $wp_shortDay = $wp_shortDays{$wp_days}; my $wp_shortDay = $wp_shortDays{$wp_days};
@ -583,11 +594,11 @@ sub WeekdayTimer_Language {
my $langRegExp = "(" . join ("|", keys(%{$hash->{shortDays}})) . ")"; my $langRegExp = "(" . join ("|", keys(%{$hash->{shortDays}})) . ")";
my $language = shift @$a; my $language = shift @$a;
unless ($language =~ m/^$langRegExp$/g) { unless ($language =~ m/^$langRegExp$/gx) {
Log3 ($hash, 3, "[$name] language: $language not recognized, use one of $langRegExp") if (length($language) == 2); Log3 ($hash, 3, "[$name] language: $language not recognized, use one of $langRegExp") if (length($language) == 2);
unshift @$a, $language; unshift @$a, $language;
$language = lc(AttrVal("global","language","en")); $language = lc(AttrVal("global","language","en"));
$language = $language =~ m/^$langRegExp$/g ? $language : "en"; $language = $language =~ m/^$langRegExp$/gx ? $language : "en";
} }
$hash->{LANGUAGE} = $language; $hash->{LANGUAGE} = $language;
@ -609,10 +620,11 @@ sub WeekdayTimer_GlobalDaylistSpec {
} }
$hash->{GlobalDaylistSpec} = $daylist; $hash->{GlobalDaylistSpec} = $daylist;
return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_SetTimerForMidnightUpdate($) { sub WeekdayTimer_SetTimerForMidnightUpdate {
my ($myHash) = @_; my $myHash = shift;
my $hash = WeekdayTimer_GetHashIndirekt($myHash, (caller(0))[3]); my $hash = WeekdayTimer_GetHashIndirekt($myHash, (caller(0))[3]);
return if (!defined($hash)); return if (!defined($hash));
@ -624,11 +636,12 @@ sub WeekdayTimer_SetTimerForMidnightUpdate($) {
WeekdayTimer_RemoveInternalTimer("SetTimerOfDay", $hash); WeekdayTimer_RemoveInternalTimer("SetTimerOfDay", $hash);
my $newMyHash = WeekdayTimer_InternalTimer ("SetTimerOfDay", $midnightPlus5Seconds, "$hash->{TYPE}_SetTimerOfDay", $hash, 0); my $newMyHash = WeekdayTimer_InternalTimer ("SetTimerOfDay", $midnightPlus5Seconds, "$hash->{TYPE}_SetTimerOfDay", $hash, 0);
$newMyHash->{SETTIMERATMIDNIGHT} = 1; $newMyHash->{SETTIMERATMIDNIGHT} = 1;
return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_SetTimerOfDay($) { sub WeekdayTimer_SetTimerOfDay {
my ($myHash) = @_; my $myHash = shift;
my $hash = WeekdayTimer_GetHashIndirekt($myHash, (caller(0))[3]); my $hash = WeekdayTimer_GetHashIndirekt($myHash, (caller(0))[3]);
return if (!defined($hash)); return if (!defined($hash));
@ -648,7 +661,7 @@ sub WeekdayTimer_SetTimerOfDay($) {
my $izeit = time() + DAYSECONDS * $i; my $izeit = time() + DAYSECONDS * $i;
my ($isec,$imin,$ihour,$imday,$imon,$iyear,$iwday,$iyday,$iisdst) = localtime($izeit); my ($isec,$imin,$ihour,$imday,$imon,$iyear,$iwday,$iyday,$iisdst) = localtime($izeit);
foreach my $h2we (split(',', AttrVal('global', 'holiday2we', ''))) { for my $h2we (split(',', AttrVal('global', 'holiday2we', ''))) {
if($h2we && ( $ergebnis eq 'none' || $h2we eq "noWeekEnd" ) && InternalVal($h2we, 'TYPE', '') eq "holiday" && !$noWeekEnd) { if($h2we && ( $ergebnis eq 'none' || $h2we eq "noWeekEnd" ) && InternalVal($h2we, 'TYPE', '') eq "holiday" && !$noWeekEnd) {
$ergebnis = CommandGet(undef,$h2we . ' ' . sprintf("%02d-%02d",$imon+1,$imday)); $ergebnis = CommandGet(undef,$h2we . ' ' . sprintf("%02d-%02d",$imon+1,$imday));
if ($ergebnis ne 'none' && $h2we eq "noWeekEnd") { if ($ergebnis ne 'none' && $h2we eq "noWeekEnd") {
@ -660,7 +673,7 @@ sub WeekdayTimer_SetTimerOfDay($) {
if ($ergebnis ne 'none') { if ($ergebnis ne 'none') {
$wedays{$i} = $ergebnis ; $wedays{$i} = $ergebnis ;
} else { } else {
if (AttrVal('global', 'holiday2we', '') =~ m,\bweekEnd\b, && ($iwday == 0 || $iwday == 6)) { if (AttrVal('global', 'holiday2we', '') =~ m,\bweekEnd\b,x && ($iwday == 0 || $iwday == 6)) {
delete $wedays{$i}; delete $wedays{$i};
} elsif ( $iwday == 0 || $iwday == 6) { } elsif ( $iwday == 0 || $iwday == 6) {
$wedays{$i} = 1 ; $wedays{$i} = 1 ;
@ -676,9 +689,10 @@ sub WeekdayTimer_SetTimerOfDay($) {
WeekdayTimer_SetTimer ($hash); WeekdayTimer_SetTimer ($hash);
delete $hash->{SETTIMERATMIDNIGHT}; delete $hash->{SETTIMERATMIDNIGHT};
WeekdayTimer_SetTimerForMidnightUpdate( { HASH => $hash} ); WeekdayTimer_SetTimerForMidnightUpdate( { HASH => $hash} );
return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_SetTimer($) { sub WeekdayTimer_SetTimer {
my $hash = shift; my $hash = shift;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
@ -769,10 +783,11 @@ sub WeekdayTimer_SetTimer($) {
WeekdayTimer_InternalTimer ("delayed", time()+5, "WeekdayTimer_delayedTimerInPast", $tipHash, 0); WeekdayTimer_InternalTimer ("delayed", time()+5, "WeekdayTimer_delayedTimerInPast", $tipHash, 0);
} }
return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_delayedTimerInPast($) { sub WeekdayTimer_delayedTimerInPast {
my ($myHash) = @_; my $myHash = shift;
my $hash = WeekdayTimer_GetHashIndirekt($myHash, (caller(0))[3]); my $hash = WeekdayTimer_GetHashIndirekt($myHash, (caller(0))[3]);
return if (!defined($hash)); return if (!defined($hash));
@ -780,11 +795,11 @@ sub WeekdayTimer_delayedTimerInPast($) {
my $tipIpHash = $modules{WeekdayTimer}{timerInThePast}; my $tipIpHash = $modules{WeekdayTimer}{timerInThePast};
foreach my $device ( keys %$tipIpHash ) { for my $device ( keys %$tipIpHash ) {
foreach my $time ( sort keys %{$tipIpHash->{$device}} ) { for my $time ( sort keys %{$tipIpHash->{$device}} ) {
Log3 $hash, 4, "[$hash->{NAME}] $device ".FmtDateTime($time)." ".($tim-$time)."s "; Log3 $hash, 4, "[$hash->{NAME}] $device ".FmtDateTime($time)." ".($tim-$time)."s ";
foreach my $para ( @{$tipIpHash->{$device}{$time}} ) { for my $para ( @{$tipIpHash->{$device}{$time}} ) {
WeekdayTimer_RemoveInternalTimer(@$para[0], @$para[3]); WeekdayTimer_RemoveInternalTimer(@$para[0], @$para[3]);
my $mHash =WeekdayTimer_InternalTimer (@$para[0],@$para[1],@$para[2],@$para[3],@$para[4]); my $mHash =WeekdayTimer_InternalTimer (@$para[0],@$para[1],@$para[2],@$para[3],@$para[4]);
$mHash->{forceSwitch} = 1; $mHash->{forceSwitch} = 1;
@ -792,10 +807,11 @@ sub WeekdayTimer_delayedTimerInPast($) {
} }
} }
delete $modules{WeekdayTimer}{timerInThePast}; delete $modules{WeekdayTimer}{timerInThePast};
delete $modules{WeekdayTimer}{timerInThePastHash} delete $modules{WeekdayTimer}{timerInThePastHash};
return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_searchAktNext($$) { sub WeekdayTimer_searchAktNext {
my ($hash, $now) = @_; my ($hash, $now) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
@ -814,7 +830,7 @@ sub WeekdayTimer_searchAktNext($$) {
my $relativeDay = $i-7; my $relativeDay = $i-7;
my $relWday = $realativeWdays[$i]; my $relWday = $realativeWdays[$i];
foreach my $time (sort keys %{$hash->{helper}{SWITCHINGTIME}{$relWday}}) { for my $time (sort keys %{$hash->{helper}{SWITCHINGTIME}{$relWday}}) {
my ($stunde, $minute, $sekunde) = split (":",$time); my ($stunde, $minute, $sekunde) = split (":",$time);
$oldTime = $nextTime; $oldTime = $nextTime;
@ -847,13 +863,14 @@ sub WeekdayTimer_searchAktNext($$) {
return (undef,undef,undef,undef); return (undef,undef,undef,undef);
} }
################################################################################ ################################################################################
sub WeekdayTimer_DeleteTimer($) { sub WeekdayTimer_DeleteTimer {
my $hash = shift; my $hash = shift;
map {WeekdayTimer_RemoveInternalTimer ($_, $hash)} keys %{$hash->{profil}}; map {WeekdayTimer_RemoveInternalTimer ($_, $hash)} keys %{$hash->{profil}};
return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_Update($) { sub WeekdayTimer_Update {
my ($myHash) = @_; my $myHash = shift;
my $hash = WeekdayTimer_GetHashIndirekt($myHash, (caller(0))[3]); my $hash = WeekdayTimer_GetHashIndirekt($myHash, (caller(0))[3]);
return if (!defined($hash)); return if (!defined($hash));
@ -918,7 +935,7 @@ sub WeekdayTimer_Update($) {
} }
################################################################################ ################################################################################
sub WeekdayTimer_isAnActiveTimer ($$$$) { sub WeekdayTimer_isAnActiveTimer {
my ($hash, $tage, $newParam, $overrulewday) = @_; my ($hash, $tage, $newParam, $overrulewday) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
@ -935,8 +952,8 @@ sub WeekdayTimer_isAnActiveTimer ($$$$) {
return $ret; return $ret;
} }
################################################################################ ################################################################################
sub WeekdayTimer_isHeizung($) { sub WeekdayTimer_isHeizung {
my ($hash) = @_; my $hash = shift;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
@ -951,16 +968,16 @@ sub WeekdayTimer_isHeizung($) {
my @tempSet = ("desired-temp", "desiredTemperature", "desired", "thermostatSetpointSet"); my @tempSet = ("desired-temp", "desiredTemperature", "desired", "thermostatSetpointSet");
my $allSets = getAllSets($dName); my $allSets = getAllSets($dName);
foreach my $ts (@tempSet) { for my $ts (@tempSet) {
if ($allSets =~ m/$ts/) { if ($allSets =~ m/$ts/x) {
Log3 $hash, 4, "[$name] device type heating recognized, setModifier:$ts"; Log3 $hash, 4, "[$name] device type heating recognized, setModifier:$ts";
return $ts return $ts
} }
} }
return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_FensterOffen ($$$) { sub WeekdayTimer_FensterOffen {
my ($hash, $event, $time) = @_; my ($hash, $event, $time) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
@ -992,9 +1009,9 @@ sub WeekdayTimer_FensterOffen ($$$) {
$nextRetry = $epoch + $nextDelay; $nextRetry = $epoch + $nextDelay;
Log3 $hash, 4, "[$name] time=".$hash->{profil}{$time}{TIME}."/$epoch delay=$delay, nextDelay=$nextDelay, nextRetry=$nextRetry"; Log3 $hash, 4, "[$name] time=".$hash->{profil}{$time}{TIME}."/$epoch delay=$delay, nextDelay=$nextDelay, nextRetry=$nextRetry";
map { my $key = $_; $key =~ s/\$/\\\$/g; map { my $key = $_; $key =~ s/\$/\\\$/gx;
my $val = $specials{$_}; my $val = $specials{$_};
$verzoegerteAusfuehrungCond =~ s/$key/$val/g $verzoegerteAusfuehrungCond =~ s/$key/$val/gx
} keys %specials; } keys %specials;
Log3 $hash, 4, "[$name] delayedExecutionCond:$verzoegerteAusfuehrungCond"; Log3 $hash, 4, "[$name] delayedExecutionCond:$verzoegerteAusfuehrungCond";
@ -1034,13 +1051,13 @@ sub WeekdayTimer_FensterOffen ($$$) {
my $fensterKontakte = $hash->{NAME} ." ". AttrVal($hash->{NAME}, "WDT_delayedExecutionDevices", ""); my $fensterKontakte = $hash->{NAME} ." ". AttrVal($hash->{NAME}, "WDT_delayedExecutionDevices", "");
my $HC_fensterKontakte = AttrVal($hash->{NAME}, "windowSensor", undef); my $HC_fensterKontakte = AttrVal($hash->{NAME}, "windowSensor", undef);
$fensterKontakte .= " ".$HC_fensterKontakte if defined $HC_fensterKontakte; $fensterKontakte .= " ".$HC_fensterKontakte if defined $HC_fensterKontakte;
$fensterKontakte =~ s/^\s+//; $fensterKontakte =~ s/^\s+//x;
$fensterKontakte =~ s/\s+$//; $fensterKontakte =~ s/\s+$//x;
Log3 $hash, 4, "[$name] list of window sensors found: '$fensterKontakte'"; Log3 $hash, 4, "[$name] list of window sensors found: '$fensterKontakte'";
if ($fensterKontakte ne "" ) { if ($fensterKontakte ne "" ) {
my @kontakte = split("[ \t]+", $fensterKontakte); my @kontakte = split("[ \t]+", $fensterKontakte);
foreach my $fk (@kontakte) { for my $fk (@kontakte) {
#hier flexible eigene Angaben ermöglichen?, Schreibweise: Device[:Reading[:ValueToCompare[:Comparator]]]; defaults: Reading=state, ValueToCompare=0/undef/false, all other true, Comparator=eq (options: eq, ne, lt, gt, ==, <,>,<>) #hier flexible eigene Angaben ermöglichen?, Schreibweise: Device[:Reading[:ValueToCompare[:Comparator]]]; defaults: Reading=state, ValueToCompare=0/undef/false, all other true, Comparator=eq (options: eq, ne, lt, gt, ==, <,>,<>)
my $fk_hash = $defs{$fk}; my $fk_hash = $defs{$fk};
unless($fk_hash) { unless($fk_hash) {
@ -1067,7 +1084,7 @@ sub WeekdayTimer_FensterOffen ($$$) {
} else { } else {
Log3 $hash, 5, "[$name] sensor '$fk' Reading/Attribute '$reading' is '$windowStatus'"; Log3 $hash, 5, "[$name] sensor '$fk' Reading/Attribute '$reading' is '$windowStatus'";
if ($windowStatus =~ m/^$statusReg$/g) { if ($windowStatus =~ m/^$statusReg$/gx) {
if (!defined($hash->{VERZOEGRUNG})) { if (!defined($hash->{VERZOEGRUNG})) {
Log3 $hash, 3, "[$name] switch of $hash->{DEVICE} delayed - sensor '$fk' Reading/Attribute '$reading' is '$windowStatus'"; Log3 $hash, 3, "[$name] switch of $hash->{DEVICE} delayed - sensor '$fk' Reading/Attribute '$reading' is '$windowStatus'";
} }
@ -1094,7 +1111,7 @@ sub WeekdayTimer_FensterOffen ($$$) {
return 0; return 0;
} }
################################################################################ ################################################################################
sub WeekdayTimer_Switch_Device($$$) { sub WeekdayTimer_Switch_Device {
my ($hash, $newParam, $tage) = @_; my ($hash, $newParam, $tage) = @_;
my ($command, $condition, $tageAsHash) = ""; my ($command, $condition, $tageAsHash) = "";
@ -1115,8 +1132,8 @@ sub WeekdayTimer_Switch_Device($$$) {
my $isHeating = $setModifier gt ""; my $isHeating = $setModifier gt "";
my $aktParam = ReadingsVal($hash->{DEVICE}, $setModifier, ""); my $aktParam = ReadingsVal($hash->{DEVICE}, $setModifier, "");
$aktParam = sprintf("%.1f", $aktParam) if ($isHeating && $aktParam =~ m/^[0-9]{1,3}$/i); $aktParam = sprintf("%.1f", $aktParam) if ($isHeating && $aktParam =~ m/^[0-9]{1,3}$/ix);
$newParam = sprintf("%.1f", $newParam) if ($isHeating && $newParam =~ m/^[0-9]{1,3}$/i); $newParam = sprintf("%.1f", $newParam) if ($isHeating && $newParam =~ m/^[0-9]{1,3}$/ix);
my $disabled = AttrVal($hash->{NAME}, "disable", 0); my $disabled = AttrVal($hash->{NAME}, "disable", 0);
my $disabled_txt = $disabled ? "" : " not"; my $disabled_txt = $disabled ? "" : " not";
@ -1127,8 +1144,8 @@ sub WeekdayTimer_Switch_Device($$$) {
&& $aktParam ne $newParam && $aktParam ne $newParam
) { ) {
$newParam =~ s/\\:/|/g; $newParam =~ s/\\:/|/g;
$newParam =~ s/:/ /g; $newParam =~ s/:/ /gx;
$newParam =~ s/\|/:/g; $newParam =~ s/\|/:/gx;
my %specials = ( "%NAME" => $hash->{DEVICE}, "%EVENT" => $newParam); my %specials = ( "%NAME" => $hash->{DEVICE}, "%EVENT" => $newParam);
$command= EvalSpecials($command, %specials); $command= EvalSpecials($command, %specials);
@ -1137,9 +1154,10 @@ sub WeekdayTimer_Switch_Device($$$) {
my $ret = AnalyzeCommandChain(undef, $command); my $ret = AnalyzeCommandChain(undef, $command);
Log3 ($hash, 3, $ret) if($ret); Log3 ($hash, 3, $ret) if($ret);
} }
return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_tageAsHash($$) { sub WeekdayTimer_tageAsHash {
my ($hash, $tage) = @_; my ($hash, $tage) = @_;
my %days = map {$_ => 1} @$tage; my %days = map {$_ => 1} @$tage;
@ -1148,7 +1166,7 @@ sub WeekdayTimer_tageAsHash($$) {
return 'my $days={};map{$days->{$_}=1}'.'('.join (",", sort keys %days).')'; return 'my $days={};map{$days->{$_}=1}'.'('.join (",", sort keys %days).')';
} }
################################################################################ ################################################################################
sub WeekdayTimer_Condition($$$) { sub WeekdayTimer_Condition {
my ($hash, $tage, $overrulewday) = @_; my ($hash, $tage, $overrulewday) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
@ -1162,7 +1180,7 @@ sub WeekdayTimer_Condition($$$) {
return $condition; return $condition;
} }
################################################################################ ################################################################################
sub WeekdayTimer_TageAsCondition ($$) { sub WeekdayTimer_TageAsCondition {
my ($tage, $overrulewday) = @_; my ($tage, $overrulewday) = @_;
my %days = map {$_ => 1} @$tage; my %days = map {$_ => 1} @$tage;
@ -1179,7 +1197,7 @@ sub WeekdayTimer_TageAsCondition ($$) {
return $tageExp; return $tageExp;
} }
################################################################################ ################################################################################
sub WeekdayTimer_Attr($$$$) { sub WeekdayTimer_Attr {
my ($cmd, $name, $attrName, $attrVal) = @_; my ($cmd, $name, $attrName, $attrVal) = @_;
return if (!$init_done); return if (!$init_done);
$attrVal = 0 if(!defined $attrVal); $attrVal = 0 if(!defined $attrVal);
@ -1197,76 +1215,79 @@ sub WeekdayTimer_Attr($$$$) {
$attr{$name}{$attrName} = $attrVal; $attr{$name}{$attrName} = $attrVal;
WeekdayTimer_SetTimerOfDay({ HASH => $hash}); WeekdayTimer_SetTimerOfDay({ HASH => $hash});
} }
return undef; return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_SetParm($) { sub WeekdayTimer_SetParm {
my ($name) = @_; my $name = shift;
my $hash = $defs{$name}; my $hash = $defs{$name};
if(defined $hash) { if(defined $hash) {
WeekdayTimer_DeleteTimer($hash); WeekdayTimer_DeleteTimer($hash);
WeekdayTimer_SetTimer($hash); WeekdayTimer_SetTimer($hash);
} }
return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_SetAllParms(;$) { # {WeekdayTimer_SetAllParms()} sub WeekdayTimer_SetAllParms { # {WeekdayTimer_SetAllParms()}
my ($group) = @_; my $group = shift//"all";
my @wdtNames; my @wdtNames;
if (!defined $group or $group eq "all") { if ($group eq "all") {
@wdtNames = devspec2array('TYPE=WeekdayTimer'); @wdtNames = devspec2array('TYPE=WeekdayTimer');
} else { } else {
@wdtNames = devspec2array("TYPE=WeekdayTimer:FILTER=WDT_Group=$group"); @wdtNames = devspec2array("TYPE=WeekdayTimer:FILTER=WDT_Group=$group");
} }
foreach my $wdName ( @wdtNames ) { for my $wdName ( @wdtNames ) {
WeekdayTimer_SetParm($wdName); WeekdayTimer_SetParm($wdName);
} }
Log3 undef, 3, "WeekdayTimer_SetAllParms() done on: ".join(" ",@wdtNames ); Log3 undef, 3, "WeekdayTimer_SetAllParms() done on: ".join(" ",@wdtNames );
return;
} }
################################################################################ ################################################################################
sub WeekdayTimer_UpdateWeekprofileReading($$$$) { sub WeekdayTimer_UpdateWeekprofileReading {
my ($hash,$wp_name,$wp_topic,$wp_profile) = @_; my ($hash,$wp_name,$wp_topic,$wp_profile) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
unless (defined $defs{$wp_name} && InternalVal($wp_name,"TYPE","false") eq "weekprofile") { unless (defined $defs{$wp_name} && InternalVal($wp_name,"TYPE","false") eq "weekprofile") {
Log3 $hash, 3, "[$name] weekprofile $wp_name not accepted, device seems not to exist or not to be of TYPE weekprofile"; Log3 $hash, 3, "[$name] weekprofile $wp_name not accepted, device seems not to exist or not to be of TYPE weekprofile";
return undef; return;
} }
unless ($hash->{DEF} =~ m/weekprofile:$wp_name\b/) { unless ($hash->{DEF} =~ m{weekprofile:$wp_name\b}xms) {
Log3 $hash, 3, "[$name] weekprofile $wp_name not accepted, device is not correctly listed as weekprofile in the WeekdayTimer definition"; Log3 $hash, 3, "[$name] weekprofile $wp_name not accepted, device is not correctly listed as weekprofile in the WeekdayTimer definition";
return undef; return;
} }
my $actual_wp_reading = ReadingsVal($name,"weekprofiles",undef); my $actual_wp_reading = ReadingsVal($name,"weekprofiles",undef);
my @newt = (); my @newt = ();
my @t = split(" ", $actual_wp_reading); my @t = split(" ", $actual_wp_reading);
my $newtriplett = $wp_name.":".$wp_topic.":".$wp_profile; my $newtriplett = qq($wp_name:$wp_topic:$wp_profile);
push @newt ,$newtriplett; push @newt ,$newtriplett;
foreach my $triplett (@t){ for my $triplett (@t){
push @newt ,$triplett unless $triplett =~ m/$wp_name\b/; push @newt ,$triplett unless $triplett =~ m{$wp_name\b}xms;
} }
readingsSingleUpdate ($hash, "weekprofiles", join(" ",@newt), 1); readingsSingleUpdate ($hash, "weekprofiles", join(" ",@newt), 1);
return 1; return 1;
} }
################################################################################ ################################################################################
sub WeekdayTimer_GetWeekprofileReadingTriplett($$) { sub WeekdayTimer_GetWeekprofileReadingTriplett {
my ($hash,$wp_name) = @_; my $hash = shift;
my $wp_name = shift // return;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $wp_topic = "default"; my $wp_topic = "default";
my $wp_profile = "default"; my $wp_profile = "default";
unless (defined $defs{$wp_name} && InternalVal($wp_name,"TYPE","false") eq "weekprofile") { unless (defined $defs{$wp_name} && InternalVal($wp_name,"TYPE","false") eq "weekprofile") {
Log3 $hash, 3, "[$name] weekprofile $wp_name not accepted, device seems not to exist or not to be of TYPE weekprofile"; Log3 $hash, 3, "[$name] weekprofile $wp_name not accepted, device seems not to exist or not to be of TYPE weekprofile";
return undef; return;
} }
my $newtriplett = $wp_name.":".$wp_topic.":".$wp_profile; my $newtriplett = qq($wp_name:$wp_topic:$wp_profile);
my $actual_wp_reading = ReadingsVal($name,"weekprofiles",0); my $actual_wp_reading = ReadingsVal($name,"weekprofiles",0);
unless ($actual_wp_reading) { unless ($actual_wp_reading) {
readingsSingleUpdate ($hash, "weekprofiles", $newtriplett, 0); readingsSingleUpdate ($hash, "weekprofiles", $newtriplett, 0);
$actual_wp_reading = $newtriplett; $actual_wp_reading = $newtriplett;
} }
my @t = split(" ", $actual_wp_reading); my @t = split(" ", $actual_wp_reading);
foreach my $triplett (@t){ for my $triplett (@t){
return $triplett if $triplett =~ m/$wp_name\b/; return $triplett if $triplett =~ m{$wp_name\b}xms;
} }
return undef; return;
} }
################################################################################ ################################################################################
1; 1;
@ -1320,8 +1341,10 @@ sub WeekdayTimer_GetWeekprofileReadingTriplett($$) {
<ul><b>[&lt;weekdays&gt;|]&lt;time&gt;|&lt;parameter&gt;</b></ul><br> <ul><b>[&lt;weekdays&gt;|]&lt;time&gt;|&lt;parameter&gt;</b></ul><br>
<u>weekdays:</u> optional, if not set every day of the week is used.<br> <u>weekdays:</u> <b>optional</b>, if not set every day of the week is used.</><br>
Otherwise you can define a day with its number or its shortname.<br> NOTE: It's highly recommended to not set weekdays if you just want your WeekdayTimer to switch all week long. Especially notations like "78" or "$we!$we" <b>are contraproductive!</b><br>
<br>
<b>Otherwise</b> you can define a day with its number or its shortname.<br>
<ul> <ul>
<li>0,su sunday</li> <li>0,su sunday</li>
<li>1,mo monday</li> <li>1,mo monday</li>