IsWe() logic, namespace usage and holiday quirks
I'm in the second day of digging through (and understanding) the IsWe() subroutine.
In that effort, I started documenting/testing it:
sub IsWe {
my $when = shift;
my $wday = shift;
# if $when is true (probably meant defined) and a date of the form
# YYYY-MM-DD or MM-DD, then $date will be true
my $date = ($when && $when =~ m/^((\d{4})-)?([01]\d)-([0-3]\d)$/);
# that match - if it matches - leaves us with
# $1 - always undefined
# $2 - year (if defined, else undefined)
# $3 - month
# $4 - day
# if $when false or $when given as yesterday/tomorrow AND $date not true,
# define when as "state"
$when = "state" if (!$when || ($when !~ m/^(yesterday|tomorrow)$/ && !$date));
if (!defined($wday)) { # $wday probably means "week-day"
if ($date) { # if $wday is not defined and $date is
# let's compute weekday from the date given
my ($y,$m,$d) = ($2 ? $2-1900 : (localtime())[5], $3-1, $4);
$wday = (localtime(mktime(1,1,1,$d,$m,$y,0,0,-1)))[6];
}
else { # neither $wday nor $date is defined
$wday = (localtime(gettimeofday()))[6]; # get $wday from localtime (basically "now")
}
}
my ($we, $wf);
# for my $h2we (split(",", AttrVal("global", "holiday2we", ""))) {
# my $b = $date ? CommandGet(undef, "$h2we $when") : ReadingsVal($h2we, $when, 0);
# if ($b && $b ne "none") {
# return 0 if ($h2we eq "noWeekEnd");
# $we = 1 if ($b && $b ne "none");
# }
# $wf = 1 if ($h2we eq "weekEnd");
# }
if (!$wf && !$we) {
$we = ($when eq "yesterday" ? ($wday == 0 || $wday == 1) :
($when ne "tomorrow" ? ($wday == 6 || $wday == 0) :
($wday == 5 || $wday == 6))); # tomorrow
}
return $we ? 1 : 0;
}
Of course the usual FHEM-related problems of not distinguishing between true/defined still apply.
Descending into the pit of its usage (who uses it and how). In this quest, I found a good example in the 73_AutoShuttersControl.pm module. The module is ok in that it tries to detach it's namespace from main, by immediately defining it's own namespace as FHEM::AutoShuttersControl
and to fetch only that from main that is required.
sub IsWe() {
my $we = main::IsWe();
return $we;
}
sub IsWeTomorrow() {
my $we = main::IsWe('tomorrow');
return $we;
}
However, there is room for improvement. Use an argument pass-through:
sub IsWe {
return main::IsWe(@_);
}
and then of course removing the IsWeTomorrow facade: d582626b
Now for 95_holiday.pm
It seems to be a very baroque system of defining absolute and relative dates and I yet have to dig into that, but it's inevitable for a full unterstanding of - among others - IsWe.
For now, correcting some spelling errors, removing "return undef", prototypes and indentation has to be sufficient: a3bf87df