mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-07 12:58:13 +00:00
98_RandomTimer: add recomputeTimes; #138532
git-svn-id: https://svn.fhem.de/fhem/trunk@28989 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
ae637a8c82
commit
9a6d53eb19
@ -1,5 +1,6 @@
|
|||||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||||
# Do not insert empty lines here, update check depends on it
|
# Do not insert empty lines here, update check depends on it
|
||||||
|
- feature: 98_RandomTimer: add recomputeTimes setter
|
||||||
- change: 38_netatmo: new token refresh handling and fallback reading
|
- change: 38_netatmo: new token refresh handling and fallback reading
|
||||||
- bugfix: 76_SolarForecast: fix Warnings
|
- bugfix: 76_SolarForecast: fix Warnings
|
||||||
- change: 76_SolarForecast: set moduleAzimuth to attr setupStringAzimuth
|
- change: 76_SolarForecast: set moduleAzimuth to attr setupStringAzimuth
|
||||||
|
@ -43,6 +43,7 @@ BEGIN {
|
|||||||
qw(
|
qw(
|
||||||
defs
|
defs
|
||||||
modules
|
modules
|
||||||
|
init_done
|
||||||
attr
|
attr
|
||||||
featurelevel
|
featurelevel
|
||||||
readingFnAttributes
|
readingFnAttributes
|
||||||
@ -105,11 +106,11 @@ sub Define {
|
|||||||
$tspec = $3;
|
$tspec = $3;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return qq{ "Wrong timespec_start <$timespec_start>, use "[+][*]<time or func>" };
|
return qq{ "Wrong timespec_start <$timespec_start>, use "[+][*]<time or func>" } if $init_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
my ( $err, $hr, $min, $sec, $fn ) = GetTimeSpec($tspec);
|
my ( $err, $hr, $min, $sec, $fn ) = GetTimeSpec($tspec);
|
||||||
return $err if ($err);
|
return $err if $err && $init_done;
|
||||||
|
|
||||||
$rel = $rel // q{};
|
$rel = $rel // q{};
|
||||||
$rep = $rep // q{};
|
$rep = $rep // q{};
|
||||||
@ -120,13 +121,12 @@ sub Define {
|
|||||||
$srep = $2;
|
$srep = $2;
|
||||||
$stspec = $3;
|
$stspec = $3;
|
||||||
}
|
}
|
||||||
else {
|
elsif ($init_done) {
|
||||||
return
|
return qq{Wrong timespec_stop <$timespec_stop>, use "[+][*]<time or func>"};
|
||||||
qq{"Wrong timespec_stop <$timespec_stop>, use "[+][*]<time or func>"};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
my ( $e, $h, $m, $s, $f ) = GetTimeSpec($stspec);
|
my ( $e, $h, $m, $s, $f ) = GetTimeSpec($stspec);
|
||||||
return $e if $e;
|
return $e if $e && $init_done;
|
||||||
|
|
||||||
return "invalid timeToSwitch <$timeToSwitch>, use 9999"
|
return "invalid timeToSwitch <$timeToSwitch>, use 9999"
|
||||||
if ( !( $timeToSwitch =~ m{^[0-9]{2,4}$}ixms ) );
|
if ( !( $timeToSwitch =~ m{^[0-9]{2,4}$}ixms ) );
|
||||||
@ -207,7 +207,7 @@ sub Set {
|
|||||||
my ( $hash, @arr ) = @_;
|
my ( $hash, @arr ) = @_;
|
||||||
|
|
||||||
return "no set value specified" if int(@arr) < 2 ;
|
return "no set value specified" if int(@arr) < 2 ;
|
||||||
return "Unknown argument, choose one of execNow:noArg active:noArg inactive:noArg"
|
return "Unknown argument, choose one of execNow:noArg active:noArg inactive:noArg recomputeTimes:noArg"
|
||||||
if $arr[1] eq '?';
|
if $arr[1] eq '?';
|
||||||
|
|
||||||
my $name = shift @arr;
|
my $name = shift @arr;
|
||||||
@ -235,6 +235,18 @@ sub Set {
|
|||||||
InternalTimer(time + 1,\&RT_Exec,$hash);
|
InternalTimer(time + 1,\&RT_Exec,$hash);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if ( $v eq 'recomputeTimes' ) {
|
||||||
|
Log3( $hash, 3, "[$name] set $name $v" );
|
||||||
|
if ( AttrVal( $name, 'disable', 0 ) ) {
|
||||||
|
Log3( $hash, 3, "[$name] is disabled, set recomputeTimes not possible" );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
RemoveInternalTimer($hash,\&RT_Exec);
|
||||||
|
InternalTimer(time + 1,\&RT_SetTimer,$hash);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -761,6 +773,12 @@ __END__
|
|||||||
<br>
|
<br>
|
||||||
Temporarily disable the RandomTimer w/o setting disable attribute. When set the next switch will be immediately executed.
|
Temporarily disable the RandomTimer w/o setting disable attribute. When set the next switch will be immediately executed.
|
||||||
</ul><br>
|
</ul><br>
|
||||||
|
<ul><a id="RandomTimer-set-recomputeTimes"></a>
|
||||||
|
<code>set <name> recomputeTimes</code>
|
||||||
|
<br>
|
||||||
|
Recalculate timespec_start and timespec_stop values. Might be helpfull in case you set timer limits in external devices (e.g. dummy).<br>
|
||||||
|
Note: recomputing times will never issue any command towards <device>; esp.when shorting the time slot, make sure, your <device> is finally switched off.
|
||||||
|
</ul><br>
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
<id name="RandomTimer-attr"></a>
|
<id name="RandomTimer-attr"></a>
|
||||||
|
@ -60,7 +60,7 @@ sub z2t_send_weekprofile {
|
|||||||
my $model = shift // ReadingsVal($name,'week','5+2');
|
my $model = shift // ReadingsVal($name,'week','5+2');
|
||||||
my $topic = shift // AttrVal($name,'devicetopic','') . '/set';
|
my $topic = shift // AttrVal($name,'devicetopic','') . '/set';
|
||||||
|
|
||||||
my $hash = $defs{$name};
|
my $hash = $defs{$name} // return;
|
||||||
$topic .= ' ';
|
$topic .= ' ';
|
||||||
|
|
||||||
my $wp_profile_data = CommandGet(undef,"$wp_name profile_data $wp_profile 0");
|
my $wp_profile_data = CommandGet(undef,"$wp_name profile_data $wp_profile 0");
|
||||||
@ -114,7 +114,7 @@ sub z2t_send_Beca_weekprofile {
|
|||||||
my $wp_profile = shift // AttrVal($name, 'weekprofile', undef) // carp q[No weekprofile profile name provided!] && return;
|
my $wp_profile = shift // AttrVal($name, 'weekprofile', undef) // carp q[No weekprofile profile name provided!] && return;
|
||||||
my $topic = shift // carp q[No topic to send to provided!] && return;
|
my $topic = shift // carp q[No topic to send to provided!] && return;
|
||||||
|
|
||||||
my $hash = $defs{$name};
|
my $hash = $defs{$name} // return;
|
||||||
|
|
||||||
my $wp_profile_data = CommandGet(undef,"$wp_name profile_data $wp_profile 0");
|
my $wp_profile_data = CommandGet(undef,"$wp_name profile_data $wp_profile 0");
|
||||||
if ($wp_profile_data =~ m{(profile.*not.found|usage..profile_data..name)}xms ) {
|
if ($wp_profile_data =~ m{(profile.*not.found|usage..profile_data..name)}xms ) {
|
||||||
@ -144,7 +144,7 @@ sub z2t_send_Beca_weekprofile {
|
|||||||
$payload .= qq("${sd}${k}h":"$time","${sd}${k}t":$tmp);
|
$payload .= qq("${sd}${k}h":"$time","${sd}${k}t":$tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log3($hash,3,"$payload");
|
#Log3($hash,3,"$payload");
|
||||||
return if !defined $payload;
|
return if !defined $payload;
|
||||||
$payload .='}';
|
$payload .='}';
|
||||||
readingsSingleUpdate( $hash, 'weekprofile', "$wp_name $wp_profile",1);
|
readingsSingleUpdate( $hash, 'weekprofile', "$wp_name $wp_profile",1);
|
||||||
@ -158,8 +158,9 @@ sub z2t_send_BHT {
|
|||||||
my $wp_profile = shift // AttrVal($name, 'weekprofile', undef) // carp q[No weekprofile profile name provided!] && return;
|
my $wp_profile = shift // AttrVal($name, 'weekprofile', undef) // carp q[No weekprofile profile name provided!] && return;
|
||||||
my $topic = shift // AttrVal($name,'devicetopic','') . '/set';
|
my $topic = shift // AttrVal($name,'devicetopic','') . '/set';
|
||||||
|
|
||||||
my $hash = $defs{$name};
|
my $hash = $defs{$name} // return;
|
||||||
|
|
||||||
|
#Log3($hash, 3, "Fetching weekprofile for ${name} day ${today} / $D[${today}] from ${wp_name}/${wp_profile}");
|
||||||
my $wp_profile_data = CommandGet(undef,"$wp_name profile_data $wp_profile 0");
|
my $wp_profile_data = CommandGet(undef,"$wp_name profile_data $wp_profile 0");
|
||||||
if ($wp_profile_data =~ m{(profile.*not.found|usage..profile_data..name)}xms ) {
|
if ($wp_profile_data =~ m{(profile.*not.found|usage..profile_data..name)}xms ) {
|
||||||
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" );
|
||||||
@ -170,7 +171,6 @@ sub z2t_send_BHT {
|
|||||||
my $today = (localtime(time))[6];
|
my $today = (localtime(time))[6];
|
||||||
# if ( !($today ~~ [1..5]) ) {$today = 1};
|
# if ( !($today ~~ [1..5]) ) {$today = 1};
|
||||||
if ( !(0 < $today < 6) ) {$today = 1};
|
if ( !(0 < $today < 6) ) {$today = 1};
|
||||||
Log3($hash, 3, "Fetching weekprofile for ${name} day ${today} / $D[${today}] from ${wp_name}/${wp_profile}");
|
|
||||||
my @days = ($today,6,0);
|
my @days = ($today,6,0);
|
||||||
my $payload;
|
my $payload;
|
||||||
my $decoded;
|
my $decoded;
|
||||||
@ -203,6 +203,115 @@ sub z2t_send_BHT {
|
|||||||
return qq{$topic $payload};
|
return qq{$topic $payload};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub z2t_send_TRV {
|
||||||
|
my $name = shift // carp q[No device name provided!] && return;
|
||||||
|
my $wp_name = shift // carp q[No weekprofile device name provided!] && return;
|
||||||
|
my $wp_profile = shift // AttrVal($name, 'weekprofile', undef) // carp q[No weekprofile profile name provided!] && return;
|
||||||
|
my $topic = shift // AttrVal($name,'devicetopic','') . '/set';
|
||||||
|
|
||||||
|
my $hash = $defs{$name} // return;
|
||||||
|
|
||||||
|
my $wp_profile_data = CommandGet(undef,"$wp_name profile_data $wp_profile 0");
|
||||||
|
if ($wp_profile_data =~ m{(profile.*not.found|usage..profile_data..name)}xms ) {
|
||||||
|
Log3( $hash, 3, "[$name] weekprofile $wp_name: no profile named \"$wp_profile\" available" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
my @D = qw(Sun Mon Tue Wed Thu Fri Sat); # eqals to my @D = ("Sun","Mon","Tue","Wed","Thu","Fri","Sat");
|
||||||
|
my $today = (localtime(time))[6];
|
||||||
|
# if ( !($today ~~ [1..5]) ) {$today = 1};
|
||||||
|
if ( !(0 < $today < 6) ) {$today = 1};
|
||||||
|
#Log3($hash, 3, "Fetching weekprofile for ${name} day ${today} / $D[${today}] from ${wp_name}/${wp_profile}");
|
||||||
|
my @days = ($today,6,0);
|
||||||
|
my $payload;
|
||||||
|
my $decoded;
|
||||||
|
if ( !eval { $decoded = decode_json($wp_profile_data) ; 1 } ) {
|
||||||
|
Log3($name, 1, "JSON decoding error in $wp_profile provided by $wp_name: $@");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for my $i (@days) {
|
||||||
|
|
||||||
|
for my $j (0..3) {
|
||||||
|
my $time = $decoded->{$D[$i]}{'time'}[$j];
|
||||||
|
my ($hour,$minute) = split m{:}xms, $time;
|
||||||
|
$hour += 0;
|
||||||
|
$minute += 0;
|
||||||
|
last if !defined $time;
|
||||||
|
my $tmp = $decoded->{$D[$i]}{'temp'}[$j]+0;
|
||||||
|
my $k = $j+1;
|
||||||
|
next if !looks_like_number($tmp);
|
||||||
|
$payload .= defined $payload ? ' ' : '"';
|
||||||
|
$payload .= sprintf("%02d:%02d/%d", $hour, $minute, $tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# Log3($hash,3,"$payload");
|
||||||
|
return if !defined $payload;
|
||||||
|
$payload = '{"programming_mode":'.$payload;
|
||||||
|
$payload .='"}';
|
||||||
|
#Log3($hash,3,"Setting ${name} to new weekprofile: ${payload}");
|
||||||
|
readingsSingleUpdate( $hash, 'weekprofile', "$wp_name $wp_profile",1);
|
||||||
|
return qq{$topic $payload};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub z2t_send_ME168 {
|
||||||
|
my $name = shift // carp q[No device name provided!] && return;
|
||||||
|
my $wp_name = shift // carp q[No weekprofile device name provided!] && return;
|
||||||
|
my $wp_profile = shift // AttrVal($name, 'weekprofile', undef) // carp q[No weekprofile profile name provided!] && return;
|
||||||
|
my $topic = shift // AttrVal($name,'devicetopic','') . '/set';
|
||||||
|
|
||||||
|
my $hash = $defs{$name} // return;
|
||||||
|
|
||||||
|
my $wp_profile_data = CommandGet(undef,"$wp_name profile_data $wp_profile 0");
|
||||||
|
if ($wp_profile_data =~ m{(profile.*not.found|usage..profile_data..name)}xms ) {
|
||||||
|
Log3( $hash, 3, "[$name] weekprofile $wp_name: no profile named \"$wp_profile\" available" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
my @D = qw(Sun Mon Tue Wed Thu Fri Sat); # eqals to my @D = ("Sun","Mon","Tue","Wed","Thu","Fri","Sat");
|
||||||
|
my @DD = qw(sunday monday tuesday wednesday thursday friday saturday); # eqals to my @D = ("Sun","Mon","Tue","Wed","Thu","Fri","Sat");
|
||||||
|
my $today = (localtime(time))[6];
|
||||||
|
# if ( !($today ~~ [1..5]) ) {$today = 1};
|
||||||
|
# if ( !(0 < $today < 6) ) {$today = 1};
|
||||||
|
# Log3($hash, 3, "Fetching weekprofile for ${name} day ${today} / $D[${today}] from ${wp_name}/${wp_profile}");
|
||||||
|
# real dyrty hack, s it seems only the first 6 days are transmitted....
|
||||||
|
my @days = ($today, ($today+1)%7, ($today+2)%7, ($today+3)%7, ($today+4)%7 ,($today+5)%7 ,($today+6)%7);
|
||||||
|
#my @days = (0..6);
|
||||||
|
my $payload;
|
||||||
|
my $decoded;
|
||||||
|
if ( !eval { $decoded = decode_json($wp_profile_data) ; 1 } ) {
|
||||||
|
Log3($name, 1, "JSON decoding error in $wp_profile provided by $wp_name: $@");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for my $i (@days) {
|
||||||
|
$payload .= defined $payload ? ', ' : '';
|
||||||
|
$payload .= '"schedule_' . $DD[$i].'":';
|
||||||
|
my $schedule;
|
||||||
|
for my $j (0..3) {
|
||||||
|
my $time = $decoded->{$D[$i]}{'time'}[$j];
|
||||||
|
my ($hour,$minute) = split m{:}xms, $time;
|
||||||
|
$hour += 0;
|
||||||
|
$minute += 0;
|
||||||
|
last if !defined $time;
|
||||||
|
my $tmp = $decoded->{$D[$i]}{'temp'}[$j]+0;
|
||||||
|
my $k = $j+1;
|
||||||
|
next if !looks_like_number($tmp);
|
||||||
|
$schedule .= defined $schedule ? ' ' : '"';
|
||||||
|
$schedule .= sprintf("%02d:%02d/%d", $hour, $minute, $tmp);
|
||||||
|
}
|
||||||
|
$payload .= $schedule . '"';
|
||||||
|
}
|
||||||
|
# Log3($hash,3,"$payload");
|
||||||
|
return if !defined $payload;
|
||||||
|
$payload = '{'.$payload;
|
||||||
|
$payload .='}';
|
||||||
|
|
||||||
|
#Log3($hash,3,"Setting ${name} to new weekprofile: ${payload}");
|
||||||
|
readingsSingleUpdate( $hash, 'weekprofile', "$wp_name $wp_profile",1);
|
||||||
|
return qq{$topic $payload};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user