mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-03 04:36:36 +00:00
76_SolarForecast: consumerXX: notbefore, notafter can be {<code>}
git-svn-id: https://svn.fhem.de/fhem/trunk@28421 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
444664e709
commit
9fd115c73d
@ -1,5 +1,6 @@
|
||||
# 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.
|
||||
- feature: 76_SolarForecast: consumerXX: notbefore, notafter can be {<code>}
|
||||
- feature: 76_SolarForecast: consumerXX: notbefore, notafter format hh[:mm]
|
||||
- feature: 76_SolarForecast: add operationMode: active/inactive
|
||||
- feature: 74_AutomowerConnect: New setter confirmError for Testing
|
||||
|
@ -157,7 +157,8 @@ BEGIN {
|
||||
|
||||
# Versions History intern
|
||||
my %vNotesIntern = (
|
||||
"1.10.0" => "24.01.2024 consumerXX: notbefore, notafter format extended to hh[:mm], new sub __checkcode, __checkhhmm ",
|
||||
"1.11.0" => "25.01.2024 consumerXX: notbefore, notafter format extended to possible perl code {...} ",
|
||||
"1.10.0" => "24.01.2024 consumerXX: notbefore, notafter format extended to hh[:mm], new sub __checkCode, __checkhhmm ",
|
||||
"1.9.0" => "23.01.2024 modify disable, add operationMode: active/inactive ",
|
||||
"1.8.0" => "22.01.2024 add 'noLearning' Option to Setter pvCorrectionFactor_Auto ",
|
||||
"1.7.1" => "20.01.2024 optimize battery management ",
|
||||
@ -4133,7 +4134,7 @@ sub Attr {
|
||||
my $hash = $defs{$name};
|
||||
my $type = $hash->{TYPE};
|
||||
|
||||
my ($do,$val);
|
||||
my ($do,$val, $err);
|
||||
|
||||
# $cmd can be "del" or "set"
|
||||
# $name is device name
|
||||
@ -4190,9 +4191,8 @@ sub Attr {
|
||||
return;
|
||||
}
|
||||
|
||||
my $err;
|
||||
my $code = $aVal;
|
||||
($err, $code) = __checkcode ($name, $code);
|
||||
($err, $code) = __checkCode ($name, $code);
|
||||
return $err if($err);
|
||||
|
||||
$data{$type}{$name}{func}{ghoValForm} = $code;
|
||||
@ -4223,14 +4223,9 @@ sub Attr {
|
||||
}
|
||||
}
|
||||
|
||||
if ($aName eq 'ctrlUserExitFn' && $init_done) {
|
||||
if(!$aVal || $aVal !~ m/^\s*(\{.*\})\s*$/xs) {
|
||||
return "Usage of $aName is wrong. The function has to be specified as \"{<your own code>}\" ";
|
||||
}
|
||||
|
||||
$aVal = $1;
|
||||
eval $aVal;
|
||||
return $@ if($@);
|
||||
if ($aName eq 'ctrlUserExitFn' && $init_done) {
|
||||
($err) = __checkCode ($name, $aVal, 'cc1');
|
||||
return $err if($err);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4268,7 +4263,7 @@ sub _attrconsumer { ## no critic "not used"
|
||||
|
||||
return if(!$init_done); # Forum: https://forum.fhem.de/index.php/topic,117864.msg1159959.html#msg1159959
|
||||
|
||||
my $err;
|
||||
my ($err, $valid);
|
||||
|
||||
if ($cmd eq "set") {
|
||||
my ($a,$h) = parseParams ($aVal);
|
||||
@ -4303,14 +4298,26 @@ sub _attrconsumer { ## no critic "not used"
|
||||
return qq{The mode "$h->{mode}" isn't allowed!};
|
||||
}
|
||||
|
||||
if (exists $h->{notbefore}) {
|
||||
my $valid = __checkhhmm ($h->{notbefore});
|
||||
return qq{The syntax "$h->{notbefore}" is wrong!} if(!$valid);
|
||||
if (exists $h->{notbefore}) {
|
||||
if ($h->{notbefore} =~ m/^\s*\{.*\}\s*$/xs) {
|
||||
($err) = __checkCode ($name, $h->{notbefore}, 'cc1');
|
||||
return $err if($err);
|
||||
}
|
||||
else {
|
||||
$valid = __checkhhmm ($h->{notbefore});
|
||||
return qq{The syntax "notbefore=$h->{notbefore}" is wrong!} if(!$valid);
|
||||
}
|
||||
}
|
||||
|
||||
if (exists $h->{notafter}) {
|
||||
my $valid = __checkhhmm ($h->{notafter});
|
||||
return qq{The syntax "$h->{notafter}" is wrong!} if(!$valid);
|
||||
if (exists $h->{notafter}) {
|
||||
if ($h->{notafter} =~ m/^\s*\{.*\}\s*$/xs) {
|
||||
($err) = __checkCode ($name, $h->{notafter}, 'cc1');
|
||||
return $err if($err);
|
||||
}
|
||||
else {
|
||||
$valid = __checkhhmm ($h->{notafter});
|
||||
return qq{The syntax "notafter=$h->{notafter}" is wrong!} if(!$valid);
|
||||
}
|
||||
}
|
||||
|
||||
if (exists $h->{interruptable}) { # Check Regex/Hysterese
|
||||
@ -4400,13 +4407,21 @@ return $valid;
|
||||
################################################################
|
||||
# prüfen validen Code in $val
|
||||
################################################################
|
||||
sub __checkcode {
|
||||
sub __checkCode {
|
||||
my $name = shift;
|
||||
my $val = shift;
|
||||
my $cc1 = shift // 0; # wenn 1 __checkCode1 ausführen
|
||||
|
||||
my $err;
|
||||
|
||||
if (!$val || $val !~ m/^\s*\{.*\}\s*$/xs) {
|
||||
return qq{Usage of $name is wrong. The function has to be specified as "{<your own code>}"};
|
||||
}
|
||||
|
||||
if ($cc1) {
|
||||
($err, $val) = ___checkCode1 ($name, $val);
|
||||
return ($err, $val);
|
||||
}
|
||||
|
||||
my %specials = ( "%DEVICE" => $name,
|
||||
"%READING" => $name,
|
||||
@ -4414,7 +4429,7 @@ sub __checkcode {
|
||||
"%UNIT" => 'kW',
|
||||
);
|
||||
|
||||
my $err = perlSyntaxCheck ($val, %specials);
|
||||
$err = perlSyntaxCheck ($val, %specials);
|
||||
return $err if($err);
|
||||
|
||||
if ($val =~ m/^\{.*\}$/xs && $val =~ m/=>/ && $val !~ m/\$/ ) { # Attr wurde als Hash definiert
|
||||
@ -4429,6 +4444,23 @@ sub __checkcode {
|
||||
return ('', $val);
|
||||
}
|
||||
|
||||
################################################################
|
||||
# prüfen validen Code in $val
|
||||
################################################################
|
||||
sub ___checkCode1 {
|
||||
my $name = shift;
|
||||
my $val = shift;
|
||||
|
||||
my $hash = $defs{$name};
|
||||
|
||||
$val =~ m/^\s*(\{.*\})\s*$/xs;
|
||||
$val = $1;
|
||||
$val = eval $val;
|
||||
return $@ if($@);
|
||||
|
||||
return ('', $val);
|
||||
}
|
||||
|
||||
################################################################
|
||||
# Attr ctrlConsRecommendReadings
|
||||
################################################################
|
||||
@ -7629,15 +7661,49 @@ sub ___switchonTimelimits {
|
||||
}
|
||||
|
||||
my $origtime = $starttime;
|
||||
my $notbefore = ConsumerVal ($hash, $c, "notbefore", '00:00');
|
||||
my $notafter = ConsumerVal ($hash, $c, "notafter", '00:00');
|
||||
my $notbefore = ConsumerVal ($hash, $c, "notbefore", 0);
|
||||
my $notafter = ConsumerVal ($hash, $c, "notafter", 0);
|
||||
|
||||
my ($nbfhh, $nbfmm) = split ":", $notbefore;
|
||||
my ($nafhh, $nafmm) = split ":", $notafter;
|
||||
$nbfmm //= '00';
|
||||
$nafmm //= '00';
|
||||
$notbefore = (int $nbfhh) . $nbfmm;
|
||||
$notafter = (int $nafhh) . $nbfmm;
|
||||
my ($err, $val);
|
||||
|
||||
if ($notbefore =~ m/^\s*\{.*\}\s*$/xs) { # notbefore als Perl-Code definiert
|
||||
($err, $val) = __checkCode ($name, $notbefore, 'cc1');
|
||||
if (!$err && __checkhhmm ($val)) {
|
||||
$notbefore = $val;
|
||||
}
|
||||
else {
|
||||
Log3 ($name, 1, "$name - ERROR - the result of the Perl code in 'notbefore' is incorrect: $val");
|
||||
$notbefore = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ($notafter =~ m/^\s*(\{.*\})\s*$/xs) { # notafter als Perl-Code definiert
|
||||
($err, $val) = __checkCode ($name, $notafter, 'cc1');
|
||||
if (!$err && __checkhhmm ($val)) {
|
||||
$notafter = $val;
|
||||
}
|
||||
else {
|
||||
Log3 ($name, 1, "$name - ERROR - the result of the Perl code in the 'notafter' key is incorrect: $val");
|
||||
$notafter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
my ($nbfhh, $nbfmm, $nafhh, $nafmm);
|
||||
|
||||
if ($notbefore) {
|
||||
($nbfhh, $nbfmm) = split ":", $notbefore;
|
||||
$nbfmm //= '00';
|
||||
$notbefore = (int $nbfhh) . $nbfmm;
|
||||
}
|
||||
|
||||
if ($notafter) {
|
||||
($nafhh, $nafmm) = split ":", $notafter;
|
||||
$nafmm //= '00';
|
||||
$notafter = (int $nafhh) . $nbfmm;
|
||||
}
|
||||
|
||||
debugLog ($paref, "consumerPlanning", qq{consumer "$c" - used 'notbefore' term: }.(defined $notbefore ? $notbefore : ''));
|
||||
debugLog ($paref, "consumerPlanning", qq{consumer "$c" - used 'notafter' term: } .(defined $notafter ? $notafter : ''));
|
||||
|
||||
my $change = q{};
|
||||
|
||||
@ -16660,9 +16726,9 @@ to ensure that the system configuration is correct.
|
||||
|
||||
<a id="SolarForecast-attr-consumer" data-pattern="consumer.*"></a>
|
||||
<li><b>consumerXX <Device Name> type=<type> power=<power> [switchdev=<device>]<br>
|
||||
[mode=<mode>] [icon=<Icon>] [mintime=<minutes> | SunPath[:<Offset_Sunrise>:<Offset_Sunset>]] <br>
|
||||
[on=<command>] [off=<command>] [swstate=<Readingname>:<on-Regex>:<off-Regex>] [asynchron=<Option>] <br>
|
||||
[notbefore=<hour>[:<minute>]] [notafter=<hour>[:<minute>]] [locktime=<offlt>[:<onlt>]] <br>
|
||||
[mode=<mode>] [icon=<Icon>] [mintime=<minutes> | SunPath[:<Offset_Sunrise>:<Offset_Sunset>]] <br>
|
||||
[on=<command>] [off=<command>] [swstate=<Readingname>:<on-Regex>:<off-Regex>] [asynchron=<Option>] <br>
|
||||
[notbefore=<Expression>] [notafter=<Expression>] [locktime=<offlt>[:<onlt>]] <br>
|
||||
[auto=<Readingname>] [pcurr=<Readingname>:<Unit>[:<Threshold>]] [etotal=<Readingname>:<Einheit>[:<Threshold>]] <br>
|
||||
[swoncond=<Device>:<Reading>:<Regex>] [swoffcond=<Device>:<Reading>:<Regex>] [spignorecond=<Device>:<Reading>:<Regex>] <br>
|
||||
[interruptable=<Option>] [noshow=<Option>] </b><br>
|
||||
@ -16760,9 +16826,11 @@ to ensure that the system configuration is correct.
|
||||
<tr><td> </td><td><b>0</b> - only synchronous processing of switching states (default) </td></tr>
|
||||
<tr><td> </td><td><b>1</b> - additional asynchronous processing of switching states through event processing </td></tr>
|
||||
<tr><td> </td><td> </td></tr>
|
||||
<tr><td> <b>notbefore</b> </td><td>Schedule start time consumer not before specified time hh[:mm] (optional) </td></tr>
|
||||
<tr><td> <b>notbefore</b> </td><td>Schedule start time consumer not before specified time 'hour[:minute]' (optional) </td></tr>
|
||||
<tr><td> </td><td>The <Expression> has the format hh[:mm] or is Perl code enclosed in {...} that returns hh[:mm]. </td></tr>
|
||||
<tr><td> </td><td> </td></tr>
|
||||
<tr><td> <b>notafter</b> </td><td>Schedule start time consumer not after specified time hh[:mm] (optional) </td></tr>
|
||||
<tr><td> <b>notafter</b> </td><td>Schedule start time consumer not after specified time 'hour[:minute]' (optional) </td></tr>
|
||||
<tr><td> </td><td>The <Expression> has the format hh[:mm] or is Perl code enclosed in {...} that returns hh[:mm]. </td></tr>
|
||||
<tr><td> </td><td> </td></tr>
|
||||
<tr><td> <b>auto</b> </td><td>Reading in the consumer device which enables or blocks the switching of the consumer (optional) </td></tr>
|
||||
<tr><td> </td><td>If the key switchdev is given, the reading is set and evaluated in this device. </td></tr>
|
||||
@ -18718,10 +18786,10 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
|
||||
|
||||
<a id="SolarForecast-attr-consumer" data-pattern="consumer.*"></a>
|
||||
<li><b>consumerXX <Device Name> type=<type> power=<power> [switchdev=<device>]<br>
|
||||
[mode=<mode>] [icon=<Icon>] [mintime=<minutes> | SunPath[:<Offset_Sunrise>:<Offset_Sunset>]] <br>
|
||||
[on=<Kommando>] [off=<Kommando>] [swstate=<Readingname>:<on-Regex>:<off-Regex>] [asynchron=<Option>] <br>
|
||||
[notbefore=<Stunde>[:<Minute>]] [notafter=<Stunde>[:<Minute>]] [locktime=<offlt>[:<onlt>]] <br>
|
||||
[auto=<Readingname>] [pcurr=<Readingname>:<Einheit>[:<Schwellenwert>]] [etotal=<Readingname>:<Einheit>[:<Schwellenwert>]] <br>
|
||||
[mode=<mode>] [icon=<Icon>] [mintime=<minutes> | SunPath[:<Offset_Sunrise>:<Offset_Sunset>]] <br>
|
||||
[on=<Kommando>] [off=<Kommando>] [swstate=<Readingname>:<on-Regex>:<off-Regex>] [asynchron=<Option>] <br>
|
||||
[notbefore=<Ausdruck>] [notafter=<Ausdruck>] [locktime=<offlt>[:<onlt>]] <br>
|
||||
[auto=<Readingname>] [pcurr=<Readingname>:<Einheit>[:<Schwellenwert>]] [etotal=<Readingname>:<Einheit>[:<Schwellenwert>]] <br>
|
||||
[swoncond=<Device>:<Reading>:<Regex>] [swoffcond=<Device>:<Reading>:<Regex>] [spignorecond=<Device>:<Reading>:<Regex>] <br>
|
||||
[interruptable=<Option>] [noshow=<Option>] </b><br>
|
||||
<br>
|
||||
@ -18817,9 +18885,11 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
|
||||
<tr><td> </td><td><b>0</b> - ausschließlich synchrone Verarbeitung von Schaltzuständen (default) </td></tr>
|
||||
<tr><td> </td><td><b>1</b> - zusätzlich asynchrone Verarbeitung von Schaltzuständen durch Eventverarbeitung </td></tr>
|
||||
<tr><td> </td><td> </td></tr>
|
||||
<tr><td> <b>notbefore</b> </td><td>Startzeitpunkt Verbraucher nicht vor angegebener Zeit hh[:mm] einplanen (optional) </td></tr>
|
||||
<tr><td> <b>notbefore</b> </td><td>Startzeitpunkt Verbraucher nicht vor angegebener Zeit 'Stunde[:Minute]' einplanen (optional) </td></tr>
|
||||
<tr><td> </td><td>Der <Ausdruck> hat das Format hh[:mm] oder ist in {...} eingeschlossener Perl-Code der hh[:mm] zurückgibt. </td></tr>
|
||||
<tr><td> </td><td> </td></tr>
|
||||
<tr><td> <b>notafter</b> </td><td>Startzeitpunkt Verbraucher nicht nach angegebener Zeit hh[:mm] einplanen (optional) </td></tr>
|
||||
<tr><td> <b>notafter</b> </td><td>Startzeitpunkt Verbraucher nicht nach angegebener Zeit 'Stunde[:Minute]' einplanen (optional) </td></tr>
|
||||
<tr><td> </td><td>Der <Ausdruck> hat das Format hh[:mm] oder ist in {...} eingeschlossener Perl-Code der hh[:mm] zurückgibt. </td></tr>
|
||||
<tr><td> </td><td> </td></tr>
|
||||
<tr><td> <b>auto</b> </td><td>Reading im Verbraucherdevice welches das Schalten des Verbrauchers freigibt bzw. blockiert (optional) </td></tr>
|
||||
<tr><td> </td><td>Ist der Schlüssel switchdev angegeben, wird das Reading in diesem Device gesetzt und ausgewertet. </td></tr>
|
||||
|
Loading…
x
Reference in New Issue
Block a user