2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-10 09:16:53 +00:00

76_SolarForecast: currentMeterDev: opt. keys conprice, feedprice

git-svn-id: https://svn.fhem.de/fhem/trunk@28665 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2024-03-16 11:59:16 +00:00
parent 04797968c4
commit 55a796eea4
3 changed files with 232 additions and 179 deletions

View File

@ -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: 76_SolarForecast: currentMeterDev: opt. keys conprice, feedprice
- change: 93_DbRep: executeBefore/AfterProc output: set verbose level to 3 - change: 93_DbRep: executeBefore/AfterProc output: set verbose level to 3
- change: 76_SolarForecast: minor code changes ones more - change: 76_SolarForecast: minor code changes ones more
- bufgix: 72_FRITZBOX: Fehlerbehandlung verbessert - bufgix: 72_FRITZBOX: Fehlerbehandlung verbessert

View File

@ -158,6 +158,10 @@ BEGIN {
# Versions History intern # Versions History intern
my %vNotesIntern = ( my %vNotesIntern = (
"1.16.8" => "16.03.2024 plantConfigCheck: adjust pvCorrectionFactor_Auto check, settings of forecastRefresh ".
"rename reading nextSolCastCall to nextRadiationAPICall ".
"currentMeterDev: new optional keys conprice, feedprice ".
"destroy runtime data when delete device ",
"1.16.7" => "12.03.2024 prevent duplicates in NOTIFYDEV, Forum: https://forum.fhem.de/index.php?msg=1306875 ", "1.16.7" => "12.03.2024 prevent duplicates in NOTIFYDEV, Forum: https://forum.fhem.de/index.php?msg=1306875 ",
"1.16.6" => "11.03.2024 plantConfigCheck: join forecastProperties with ',' ", "1.16.6" => "11.03.2024 plantConfigCheck: join forecastProperties with ',' ",
"1.16.5" => "04.03.2024 setPVhistory: code changes, plantConfigCheck: check forecastRefresh ". "1.16.5" => "04.03.2024 setPVhistory: code changes, plantConfigCheck: check forecastRefresh ".
@ -1549,6 +1553,7 @@ sub _setcurrentRadiationAPI { ## no critic "not used"
createAssociatedWith ($hash); createAssociatedWith ($hash);
writeCacheToFile ($hash, "plantconfig", $plantcfg.$name); # Anlagenkonfiguration File schreiben writeCacheToFile ($hash, "plantconfig", $plantcfg.$name); # Anlagenkonfiguration File schreiben
setModel ($hash); # Model setzen setModel ($hash); # Model setzen
deleteReadingspec ($hash, 'nextRadiationAPICall');
return if(_checkSetupNotComplete ($hash)); # keine Stringkonfiguration wenn Setup noch nicht komplett return if(_checkSetupNotComplete ($hash)); # keine Stringkonfiguration wenn Setup noch nicht komplett
@ -1785,6 +1790,16 @@ sub _setmeterDevice { ## no critic "not used"
return qq{Incorrect input. It is not allowed that the keys gcon and gfeedin refer to each other.}; return qq{Incorrect input. It is not allowed that the keys gcon and gfeedin refer to each other.};
} }
if ($h->{conprice}) {
my ($gcp,$gcpcucy) = split ":", $h->{conprice};
return qq{Incorrect input for key 'conprice'. Please consider the commandref.} if(!$gcp || !$gcpcucy);
}
if ($h->{feedprice}) {
my ($gfr,$gfrcucy) = split ":", $h->{feedprice};
return qq{Incorrect input for key 'feedprice'. Please consider the commandref.} if(!$gfr || !$gfrcucy);
}
## alte Speicherwerte löschen ## alte Speicherwerte löschen
############################### ###############################
delete $data{$type}{$name}{circular}{'99'}{feedintotal}; delete $data{$type}{$name}{circular}{'99'}{feedintotal};
@ -2719,7 +2734,7 @@ sub __getSolCastData {
$etxt =~ s{<WT>}{($leadtime/60)}eg; $etxt =~ s{<WT>}{($leadtime/60)}eg;
if ($trc <= 0) { if ($trc <= 0) {
readingsSingleUpdate($hash, 'nextSolCastCall', $etxt, 1); readingsSingleUpdate($hash, 'nextRadiationAPICall', $etxt, 1);
return qq{SolCast free daily limit is used up}; return qq{SolCast free daily limit is used up};
} }
@ -2728,7 +2743,7 @@ sub __getSolCastData {
my $sstime = timestringToTimestamp ($date.' '.ReadingsVal($name, "Today_SunSet", '00:00').':00'); my $sstime = timestringToTimestamp ($date.' '.ReadingsVal($name, "Today_SunSet", '00:00').':00');
if ($t < $srtime - $leadtime || $t > $sstime + $lagtime) { if ($t < $srtime - $leadtime || $t > $sstime + $lagtime) {
readingsSingleUpdate($hash, 'nextSolCastCall', $etxt, 1); readingsSingleUpdate($hash, 'nextRadiationAPICall', $etxt, 1);
return "The current time is not between sunrise minus ".($leadtime/60)." minutes and sunset"; return "The current time is not between sunrise minus ".($leadtime/60)." minutes and sunset";
} }
@ -3115,7 +3130,7 @@ sub ___setSolCastAPIcallKeyData {
Log3 ($name, 1, "$name DEBUG> SolCast API Call - next API Call: ".(timestampToTimestring ($t + $apiitv, $lang))[0]); Log3 ($name, 1, "$name DEBUG> SolCast API Call - next API Call: ".(timestampToTimestring ($t + $apiitv, $lang))[0]);
} }
readingsSingleUpdate ($hash, 'nextSolCastCall', $hqtxt{after}{$lang}.' '.(timestampToTimestring ($t + $apiitv, $lang))[0], 1); readingsSingleUpdate ($hash, 'nextRadiationAPICall', $hqtxt{after}{$lang}.' '.(timestampToTimestring ($t + $apiitv, $lang))[0], 1);
return; return;
} }
@ -3140,7 +3155,7 @@ sub __getForecastSolarData {
my $sstime = timestringToTimestamp ($date.' '.ReadingsVal($name, "Today_SunSet", '00:00').':00'); my $sstime = timestringToTimestamp ($date.' '.ReadingsVal($name, "Today_SunSet", '00:00').':00');
if ($t < $srtime - $leadtime || $t > $sstime + $lagtime) { if ($t < $srtime - $leadtime || $t > $sstime + $lagtime) {
readingsSingleUpdate($hash, 'nextSolCastCall', $etxt, 1); readingsSingleUpdate($hash, 'nextRadiationAPICall', $etxt, 1);
return "The current time is not between sunrise minus ".($leadtime/60)." minutes and sunset"; return "The current time is not between sunrise minus ".($leadtime/60)." minutes and sunset";
} }
@ -3450,7 +3465,7 @@ sub ___setForeCastAPIcallKeyData {
$smt = '(forced waiting time)'; $smt = '(forced waiting time)';
} }
readingsSingleUpdate ($hash, 'nextSolCastCall', $hqtxt{after}{$lang}.' '.(timestampToTimestring ($t + $apiitv, $lang))[0].' '.$smt, 1); readingsSingleUpdate ($hash, 'nextRadiationAPICall', $hqtxt{after}{$lang}.' '.(timestampToTimestring ($t + $apiitv, $lang))[0].' '.$smt, 1);
return; return;
} }
@ -3549,7 +3564,7 @@ sub __getVictronSolarData {
} }
} }
readingsSingleUpdate ($hash, 'nextSolCastCall', $hqtxt{after}{$lang}.' '.(timestampToTimestring ($t + $apiitv, $lang))[0], 1); readingsSingleUpdate ($hash, 'nextRadiationAPICall', $hqtxt{after}{$lang}.' '.(timestampToTimestring ($t + $apiitv, $lang))[0], 1);
__VictronVRM_ApiRequestLogin ($paref); __VictronVRM_ApiRequestLogin ($paref);
@ -5247,6 +5262,10 @@ sub Delete {
} }
} }
my $type = $hash->{TYPE};
delete $data{$type}{$name};
return; return;
} }
@ -5641,30 +5660,6 @@ sub centralTask {
### nicht mehr benötigte Daten verarbeiten - Bereich kann später wieder raus !! ### nicht mehr benötigte Daten verarbeiten - Bereich kann später wieder raus !!
########################################################################################################################## ##########################################################################################################################
## percentile in simple umsetzen # 05.02.2024
for my $idx (sort keys %{$data{$type}{$name}{circular}}) {
if(defined $data{$type}{$name}{circular}{$idx}{pvcorrf}{percentile}) {
$data{$type}{$name}{circular}{$idx}{pvcorrf}{simple} = $data{$type}{$name}{circular}{$idx}{pvcorrf}{percentile};
delete $data{$type}{$name}{circular}{$idx}{pvcorrf}{percentile};
}
if(defined $data{$type}{$name}{circular}{$idx}{quality}{percentile}) {
$data{$type}{$name}{circular}{$idx}{quality}{simple} = $data{$type}{$name}{circular}{$idx}{quality}{percentile};
delete $data{$type}{$name}{circular}{$idx}{quality}{percentile};
}
if(defined $data{$type}{$name}{circular}{$idx}{pvrlsum}{percentile}) {
$data{$type}{$name}{circular}{$idx}{pvrlsum}{simple} = $data{$type}{$name}{circular}{$idx}{pvrlsum}{percentile};
delete $data{$type}{$name}{circular}{$idx}{pvrlsum}{percentile};
}
if(defined $data{$type}{$name}{circular}{$idx}{pvfcsum}{percentile}) {
$data{$type}{$name}{circular}{$idx}{pvfcsum}{simple} = $data{$type}{$name}{circular}{$idx}{pvfcsum}{percentile};
delete $data{$type}{$name}{circular}{$idx}{pvfcsum}{percentile};
}
if(defined $data{$type}{$name}{circular}{$idx}{dnumsum}{percentile}) {
$data{$type}{$name}{circular}{$idx}{dnumsum}{simple} = $data{$type}{$name}{circular}{$idx}{dnumsum}{percentile};
delete $data{$type}{$name}{circular}{$idx}{dnumsum}{percentile};
}
}
## nicht-Bin Werte löschen / wrp löschen ## nicht-Bin Werte löschen / wrp löschen
my $ra = '0|00|05|5|10|15|20|25|30|35|40|45|50|55|60|65|70|75|80|85|90|95|100|.*\..*|simple'; my $ra = '0|00|05|5|10|15|20|25|30|35|40|45|50|55|60|65|70|75|80|85|90|95|100|.*\..*|simple';
@ -5762,6 +5757,12 @@ sub centralTask {
} }
} }
my $nscc = ReadingsVal ($name, 'nextSolCastCall', ''); # 14.03.2024
if ($nscc) {
readingsSingleUpdate ($hash, 'nextRadiationAPICall', $nscc, 0);
deleteReadingspec ($hash, 'nextSolCastCall');
}
####################################################################################################################### #######################################################################################################################
return if(!$init_done); return if(!$init_done);
@ -7172,6 +7173,18 @@ sub _transferMeterValues {
return if(!$gc || !$gf || !$gt || !$ft); return if(!$gc || !$gf || !$gt || !$ft);
if ($h->{conprice}) {
my ($gcp,$gcpcucy) = split ":", $h->{conprice}; # Bezugspreis (Arbeitspreis) pro kWh
$data{$type}{$name}{current}{ePurchasePrice} = $gcp;
$data{$type}{$name}{current}{ePurchasePriceCcy} = $gcpcucy;
}
if ($h->{feedprice}) {
my ($gfr,$gfrcucy) = split ":", $h->{feedprice}; # Einspeisevergütung pro kWh
$data{$type}{$name}{current}{eFeedInTariff} = $gfr;
$data{$type}{$name}{current}{eFeedInTariffCcy} = $gfrcucy;
}
$gfunit //= $gcunit; $gfunit //= $gcunit;
$gcunit //= $gfunit; $gcunit //= $gfunit;
@ -8296,8 +8309,11 @@ sub __planInitialSwitchTime {
return; return;
} }
debugLog ($paref, "consumerPlanning", qq{Planning consumer "$c" - name: }.ConsumerVal ($hash, $c, 'name', ''). if ($debug =~ /consumerPlanning/x) {
Log3 ($name, 1, qq{$name DEBUG> ############### consumerPlanning consumer "$c" ############### });
Log3 ($name, 1, qq{$name DEBUG> Planning consumer "$c" - name: }.ConsumerVal ($hash, $c, 'name', '').
qq{ alias: }.ConsumerVal ($hash, $c, 'alias', '')); qq{ alias: }.ConsumerVal ($hash, $c, 'alias', ''));
}
if (ConsumerVal ($hash, $c, 'type', $defctype) eq 'noSchedule') { if (ConsumerVal ($hash, $c, 'type', $defctype) eq 'noSchedule') {
debugLog ($paref, "consumerPlanning", qq{consumer "$c" - }.$hqtxt{scnp}{EN}); debugLog ($paref, "consumerPlanning", qq{consumer "$c" - }.$hqtxt{scnp}{EN});
@ -8413,8 +8429,8 @@ sub ___doPlanning {
my %max; my %max;
my %mtimes; my %mtimes;
## max. Überschuß ermitteln ## max. PV-Forecast bzw. Überschuß (bei gesetzen affectConsForecastInPlanning) ermitteln
############################# ##########################################################################################
for my $idx (sort keys %{$nh}) { for my $idx (sort keys %{$nh}) {
my $pvfc = NexthoursVal ($hash, $idx, 'pvfc', 0); my $pvfc = NexthoursVal ($hash, $idx, 'pvfc', 0);
my $confcex = NexthoursVal ($hash, $idx, 'confcEx', 0); # prognostizierter Verbrauch ohne registrierte Consumer my $confcex = NexthoursVal ($hash, $idx, 'confcEx', 0); # prognostizierter Verbrauch ohne registrierte Consumer
@ -8952,7 +8968,7 @@ sub ___switchConsumerOn {
my $nompow = ConsumerVal ($hash, $c, 'power', '-'); my $nompow = ConsumerVal ($hash, $c, 'power', '-');
my $sp = CurrentVal ($hash, 'surplus', 0); my $sp = CurrentVal ($hash, 'surplus', 0);
Log3 ($name, 1, qq{$name DEBUG> ############### consumer "$c" ############### }); Log3 ($name, 1, qq{$name DEBUG> ############### consumerSwitching consumer "$c" ############### });
Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - general switching parameters => }. Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - general switching parameters => }.
qq{auto mode: $auto, current Consumption: $cons W, nompower: $nompow, surplus: $sp W, }. qq{auto mode: $auto, current Consumption: $cons W, nompower: $nompow, surplus: $sp W, }.
qq{planstate: $pstate, starttime: }.($startts ? (timestampToTimestring ($startts, $lang))[0] : "undef") qq{planstate: $pstate, starttime: }.($startts ? (timestampToTimestring ($startts, $lang))[0] : "undef")
@ -10851,7 +10867,7 @@ sub _graphicHeader {
isDWDUsed ($hash) ? '<a href="https://www.dwd.de/DE/leistungen/met_verfahren_mosmix/met_verfahren_mosmix.html" style="color: inherit !important;" target="_blank">DWD</a>:' : isDWDUsed ($hash) ? '<a href="https://www.dwd.de/DE/leistungen/met_verfahren_mosmix/met_verfahren_mosmix.html" style="color: inherit !important;" target="_blank">DWD</a>:' :
q{}; q{};
my $nscc = ReadingsVal ($name, 'nextSolCastCall', '?'); my $nscc = ReadingsVal ($name, 'nextRadiationAPICall', '?');
my $lrt = SolCastAPIVal ($hash, '?All', '?All', 'lastretrieval_time', '-'); my $lrt = SolCastAPIVal ($hash, '?All', '?All', 'lastretrieval_time', '-');
my $scrm = SolCastAPIVal ($hash, '?All', '?All', 'response_message', '-'); my $scrm = SolCastAPIVal ($hash, '?All', '?All', 'response_message', '-');
@ -14137,8 +14153,10 @@ sub checkPlantConfig {
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $type = $hash->{TYPE}; my $type = $hash->{TYPE};
setModel ($hash); # Model setzen
my $lang = AttrVal ($name, 'ctrlLanguage', AttrVal ('global', 'language', $deflang)); my $lang = AttrVal ($name, 'ctrlLanguage', AttrVal ('global', 'language', $deflang));
my $pcf = ReadingsVal ($name, 'pvCorrectionFactor_Auto', ''); my $pcf = ReadingsVal ($name, 'pvCorrectionFactor_Auto', 'off');
my $raname = ReadingsVal ($name, 'currentRadiationAPI', ''); my $raname = ReadingsVal ($name, 'currentRadiationAPI', '');
my ($acu, $aln) = isAutoCorrUsed ($name); my ($acu, $aln) = isAutoCorrUsed ($name);
@ -14239,7 +14257,7 @@ sub checkPlantConfig {
$result->{'DWD Weather Properties'}{fault} = 1; $result->{'DWD Weather Properties'}{fault} = 1;
} }
else { else {
$mosm = AttrVal ($fcname, 'forecastRefresh', 6) == 1 ? 'MOSMIX_S' : 'MOSMIX_L'; $mosm = AttrVal ($fcname, 'forecastRefresh', 6) == 6 ? 'MOSMIX_L' : 'MOSMIX_S';
if ($mosm eq 'MOSMIX_L') { if ($mosm eq 'MOSMIX_L') {
$result->{'DWD Weather Properties'}{state} = $info; $result->{'DWD Weather Properties'}{state} = $info;
@ -14252,7 +14270,7 @@ sub checkPlantConfig {
$result->{'DWD Weather Properties'}{note} .= qq{checked parameters and attributes of device "$fcname": <br>}; $result->{'DWD Weather Properties'}{note} .= qq{checked parameters and attributes of device "$fcname": <br>};
$result->{'DWD Weather Properties'}{note} .= 'forecastProperties -> '.join (',', @dweattrmust).'<br>'; $result->{'DWD Weather Properties'}{note} .= 'forecastProperties -> '.join (',', @dweattrmust).'<br>';
$result->{'DWD Weather Properties'}{note} .= 'forecastRefresh '.($mosm eq 'MOSMIX_L' ? '-> set attribute to "1" if possible' : '').'<br>'; $result->{'DWD Weather Properties'}{note} .= 'forecastRefresh '.($mosm eq 'MOSMIX_L' ? '-> set attribute to below "6" if possible' : '').'<br>';
} }
} }
@ -14295,7 +14313,7 @@ sub checkPlantConfig {
$result->{'DWD Radiation Properties'}{fault} = 1; $result->{'DWD Radiation Properties'}{fault} = 1;
} }
else { else {
$mosm = AttrVal ($raname, 'forecastRefresh', 6) == 1 ? 'MOSMIX_S' : 'MOSMIX_L'; $mosm = AttrVal ($raname, 'forecastRefresh', 6) == 6 ? 'MOSMIX_L' : 'MOSMIX_S';
if ($mosm eq 'MOSMIX_L') { if ($mosm eq 'MOSMIX_L') {
$result->{'DWD Radiation Properties'}{state} = $info; $result->{'DWD Radiation Properties'}{state} = $info;
@ -14326,7 +14344,7 @@ sub checkPlantConfig {
$result->{'DWD Radiation Properties'}{note} .= 'MOSMIX variant, Age of Radiation data. <br>'; $result->{'DWD Radiation Properties'}{note} .= 'MOSMIX variant, Age of Radiation data. <br>';
$result->{'DWD Radiation Properties'}{note} .= qq{<br>checked parameters and attributes device "$raname": <br>}; $result->{'DWD Radiation Properties'}{note} .= qq{<br>checked parameters and attributes device "$raname": <br>};
$result->{'DWD Radiation Properties'}{note} .= 'forecastProperties -> '.join (',', @draattrmust).'<br>'; $result->{'DWD Radiation Properties'}{note} .= 'forecastProperties -> '.join (',', @draattrmust).'<br>';
$result->{'DWD Radiation Properties'}{note} .= 'forecastRefresh '.($mosm eq 'MOSMIX_L' ? '-> set attribute to "1" if possible' : '').'<br>'; $result->{'DWD Radiation Properties'}{note} .= 'forecastRefresh '.($mosm eq 'MOSMIX_L' ? '-> set attribute to below "6" if possible' : '').'<br>';
} }
## Check Rooftop und Roof Ident Pair Settings (SolCast) ## Check Rooftop und Roof Ident Pair Settings (SolCast)
@ -14460,10 +14478,10 @@ sub checkPlantConfig {
} }
if (isForecastSolarUsed ($hash)) { # allg. Settings bei Nutzung Forecast.Solar API if (isForecastSolarUsed ($hash)) { # allg. Settings bei Nutzung Forecast.Solar API
if (!$pcf || $pcf !~ /on/xs) { if ($pcf !~ /on/xs) {
$result->{'Common Settings'}{state} = $info; $result->{'Common Settings'}{state} = $info;
$result->{'Common Settings'}{result} .= qq{pvCorrectionFactor_Auto is set to "$pcf" <br>}; $result->{'Common Settings'}{result} .= qq{pvCorrectionFactor_Auto is set to "$pcf" <br>};
$result->{'Common Settings'}{note} .= qq{Set pvCorrectionFactor_Auto to "on*" if an automatic adjustment of the prescaler data should be done.<br>}; $result->{'Common Settings'}{note} .= qq{Set pvCorrectionFactor_Auto to "on_complex" is recommended.<br>};
} }
if (!$lat) { if (!$lat) {
@ -14493,10 +14511,10 @@ sub checkPlantConfig {
my $lam = SolCastAPIVal ($hash, '?All', '?All', 'response_message', 'success'); my $lam = SolCastAPIVal ($hash, '?All', '?All', 'response_message', 'success');
if (!$pcf || $pcf !~ /on/xs) { if ($pcf !~ /on/xs) {
$result->{'Common Settings'}{state} = $info; $result->{'Common Settings'}{state} = $info;
$result->{'Common Settings'}{result} .= qq{pvCorrectionFactor_Auto is set to "$pcf" <br>}; $result->{'Common Settings'}{result} .= qq{pvCorrectionFactor_Auto is set to "$pcf" <br>};
$result->{'Common Settings'}{note} .= qq{set pvCorrectionFactor_Auto to "on*" is recommended if the SolCast efficiency factor is already adjusted.<br>}; $result->{'Common Settings'}{note} .= qq{set pvCorrectionFactor_Auto to "on_complex" is recommended if the SolCast efficiency factor is already adjusted.<br>};
} }
if (!$osi) { if (!$osi) {
@ -14543,10 +14561,10 @@ sub checkPlantConfig {
$result->{'Common Settings'}{info} = 1; $result->{'Common Settings'}{info} = 1;
} }
if (!$pcf || $pcf !~ /on/xs) { if ($pcf !~ /on/xs) {
$result->{'Common Settings'}{state} = $info; $result->{'Common Settings'}{state} = $info;
$result->{'Common Settings'}{result} .= qq{pvCorrectionFactor_Auto is set to "$pcf" <br>}; $result->{'Common Settings'}{result} .= qq{pvCorrectionFactor_Auto is set to "$pcf" <br>};
$result->{'Common Settings'}{note} .= qq{Set pvCorrectionFactor_Auto to "on*" if an automatic adjustment of the prescaler data should be done.<br>}; $result->{'Common Settings'}{note} .= qq{Set pvCorrectionFactor_Auto to "on_complex" or "on_complex_ai" is recommended.<br>};
} }
if ($lam ne 'success') { if ($lam ne 'success') {
@ -14571,10 +14589,10 @@ sub checkPlantConfig {
my $gdn = AttrVal ('global', 'dnsServer', ''); my $gdn = AttrVal ('global', 'dnsServer', '');
my $vrmcr = SolCastAPIVal ($hash, '?VRM', '?API', 'credentials', ''); my $vrmcr = SolCastAPIVal ($hash, '?VRM', '?API', 'credentials', '');
if ($pcf && $pcf !~ /off/xs) { if ($pcf !~ /on/xs) {
$result->{'Common Settings'}{state} = $warn; $result->{'Common Settings'}{state} = $warn;
$result->{'Common Settings'}{result} .= qq{pvCorrectionFactor_Auto is set to "$pcf" <br>}; $result->{'Common Settings'}{result} .= qq{pvCorrectionFactor_Auto is set to "$pcf" <br>};
$result->{'Common Settings'}{note} .= qq{set pvCorrectionFactor_Auto to "off" is recommended because of this API is KI based.<br>}; $result->{'Common Settings'}{note} .= qq{set pvCorrectionFactor_Auto to "on_complex" is recommended.<br>};
$result->{'Common Settings'}{warn} = 1; $result->{'Common Settings'}{warn} = 1;
} }
@ -14654,7 +14672,7 @@ sub checkPlantConfig {
## Ausgabe ## Ausgabe
############ ############
my $out = qq{<html>}; my $out = qq{<html>};
$out .= qq{<b>}.$hqtxt{plntck}{$lang}.qq{</b> <br><br>}; $out .= qq{<b>}.$hqtxt{plntck}{$lang}.qq{ - Model: $hash->{MODEL} </b> <br><br>};
$out .= qq{<table class="roomoverview" style="text-align:left; border:1px solid; padding:5px; border-spacing:5px; margin-left:auto; margin-right:auto;">}; $out .= qq{<table class="roomoverview" style="text-align:left; border:1px solid; padding:5px; border-spacing:5px; margin-left:auto; margin-right:auto;">};
$out .= qq{<tr style="font-weight:bold;">}; $out .= qq{<tr style="font-weight:bold;">};
@ -15051,7 +15069,6 @@ sub setModel {
} }
else { else {
$hash->{MODEL} = 'DWD'; $hash->{MODEL} = 'DWD';
deleteReadingspec ($hash, 'nextSolCastCall');
} }
return; return;
@ -15671,7 +15688,7 @@ sub isWeatherAgeExceeded {
} }
} }
$resh->{mosmix} = AttrVal ($resh->{agedv}, 'forecastRefresh', 6) == 1 ? 'MOSMIX_S' : 'MOSMIX_L'; $resh->{mosmix} = AttrVal ($resh->{agedv}, 'forecastRefresh', 6) == 6 ? 'MOSMIX_L' : 'MOSMIX_S';
my $th = $resh->{mosmix} eq 'MOSMIX_S' ? 7200 : 25200; my $th = $resh->{mosmix} eq 'MOSMIX_S' ? 7200 : 25200;
$resh->{exceed} = $currts - $agets > $th ? 1 : 0; $resh->{exceed} = $currts - $agets > $th ? 1 : 0;
@ -17016,7 +17033,9 @@ to ensure that the system configuration is correct.
<ul> <ul>
<a id="SolarForecast-set-currentMeterDev"></a> <a id="SolarForecast-set-currentMeterDev"></a>
<li><b>currentMeterDev &lt;Meter Device Name&gt; gcon=&lt;Readingname&gt;:&lt;Unit&gt; contotal=&lt;Readingname&gt;:&lt;Unit&gt; gfeedin=&lt;Readingname&gt;:&lt;Unit&gt; feedtotal=&lt;Readingname&gt;:&lt;Unit&gt; </b> <br><br> <li><b>currentMeterDev &lt;Meter Device Name&gt; gcon=&lt;Readingname&gt;:&lt;Einheit&gt; contotal=&lt;Readingname&gt;:&lt;Einheit&gt;
gfeedin=&lt;Readingname&gt;:&lt;Einheit&gt; feedtotal=&lt;Readingname&gt;:&lt;Einheit&gt;
[conprice=&lt;Wert&gt;:&lt;Currency&gt;] [feedprice=&lt;Wert&gt;:&lt;Currency&gt;] </b> <br><br>
Sets any device and its readings for energy measurement. Sets any device and its readings for energy measurement.
The module assumes that the numeric value of the readings is positive. The module assumes that the numeric value of the readings is positive.
@ -17026,11 +17045,13 @@ to ensure that the system configuration is correct.
<ul> <ul>
<table> <table>
<colgroup> <col width="15%"> <col width="85%"> </colgroup> <colgroup> <col width="15%"> <col width="85%"> </colgroup>
<tr><td> <b>gcon</b> </td><td>Reading welches die aktuell aus dem Netz bezogene Leistung liefert </td></tr> <tr><td> <b>gcon</b> </td><td>Reading which supplies the power currently drawn from the grid </td></tr>
<tr><td> <b>contotal</b> </td><td>Reading welches die Summe der aus dem Netz bezogenen Energie liefert (ein sich stetig erhöhender Zähler) </td></tr> <tr><td> <b>contotal</b> </td><td>Reading which provides the sum of the energy drawn from the grid (a constantly increasing meter) </td></tr>
<tr><td> <b>gfeedin</b> </td><td>Reading welches die aktuell in das Netz eingespeiste Leistung liefert </td></tr> <tr><td> <b>gfeedin</b> </td><td>Reading which supplies the power currently fed into the grid </td></tr>
<tr><td> <b>feedtotal</b> </td><td>Reading welches die Summe der in das Netz eingespeisten Energie liefert (ein sich stetig erhöhender Zähler) </td></tr> <tr><td> <b>feedtotal</b> </td><td>Reading which provides the sum of the energy fed into the grid (a constantly increasing meter) </td></tr>
<tr><td> <b>Einheit</b> </td><td>die jeweilige Einheit (W,kW,Wh,kWh) </td></tr> <tr><td> <b>Einheit</b> </td><td>the respective unit (W,kW,Wh,kWh) </td></tr>
<tr><td> <b>conprice</b> </td><td>Price and currency for the purchase of one kWh (optional) </td></tr>
<tr><td> <b>feedprice</b> </td><td>Price and currency for the feed-in of one kWh (optional) </td></tr>
</table> </table>
</ul> </ul>
<br> <br>
@ -17047,7 +17068,7 @@ to ensure that the system configuration is correct.
<ul> <ul>
<b>Example: </b> <br> <b>Example: </b> <br>
set &lt;name&gt; currentMeterDev Meter gcon=Wirkleistung:W contotal=BezWirkZaehler:kWh gfeedin=-gcon feedtotal=EinWirkZaehler:kWh <br> set &lt;name&gt; currentMeterDev Meter gcon=Wirkleistung:W contotal=BezWirkZaehler:kWh gfeedin=-gcon feedtotal=EinWirkZaehler:kWh conprice=0.2958: feedprice=0.1269: <br>
<br> <br>
# Device Meter provides the current grid reference in the reading "Wirkleistung" (W), # Device Meter provides the current grid reference in the reading "Wirkleistung" (W),
the sum of the grid reference in the reading "BezWirkZaehler" (kWh), the current feed in "Wirkleistung" if "Wirkleistung" is negative, the sum of the grid reference in the reading "BezWirkZaehler" (kWh), the current feed in "Wirkleistung" if "Wirkleistung" is negative,
@ -17369,7 +17390,7 @@ to ensure that the system configuration is correct.
<br><br> <br><br>
<b>Model SolCastAPI:</b> <br> <b>Model SolCastAPI:</b> <br>
The recommended autocorrection method is <b>on_simple</b>. <br> The recommended autocorrection method is <b>on_complex</b>. <br>
Before turning on autocorrection, optimise the forecast with the following steps: <br><br> Before turning on autocorrection, optimise the forecast with the following steps: <br><br>
<ul> <ul>
<li> <li>
@ -17914,7 +17935,8 @@ to ensure that the system configuration is correct.
<a id="SolarForecast-attr-affectMaxDayVariance"></a> <a id="SolarForecast-attr-affectMaxDayVariance"></a>
<li><b>affectMaxDayVariance &lt;Zahl&gt; </b><br> <li><b>affectMaxDayVariance &lt;Zahl&gt; </b><br>
Maximum change size of the PV prediction factor (Reading pvCorrectionFactor_XX) per day. <br> Maximum adjustment of the PV prediction factor (Reading pvCorrectionFactor_XX) that can be made
in relation to one hour per day. <br>
This setting has no influence on the learning and forecasting behavior of any AI support used This setting has no influence on the learning and forecasting behavior of any AI support used
(<a href="#SolarForecast-set-pvCorrectionFactor_Auto">pvCorrectionFactor_Auto</a>). <br> (<a href="#SolarForecast-set-pvCorrectionFactor_Auto">pvCorrectionFactor_Auto</a>). <br>
(default: 0.5) (default: 0.5)
@ -19141,7 +19163,9 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<ul> <ul>
<a id="SolarForecast-set-currentMeterDev"></a> <a id="SolarForecast-set-currentMeterDev"></a>
<li><b>currentMeterDev &lt;Meter Device Name&gt; gcon=&lt;Readingname&gt;:&lt;Einheit&gt; contotal=&lt;Readingname&gt;:&lt;Einheit&gt; gfeedin=&lt;Readingname&gt;:&lt;Einheit&gt; feedtotal=&lt;Readingname&gt;:&lt;Einheit&gt; </b> <br><br> <li><b>currentMeterDev &lt;Meter Device Name&gt; gcon=&lt;Readingname&gt;:&lt;Einheit&gt; contotal=&lt;Readingname&gt;:&lt;Einheit&gt;
gfeedin=&lt;Readingname&gt;:&lt;Einheit&gt; feedtotal=&lt;Readingname&gt;:&lt;Einheit&gt;
[conprice=&lt;Wert&gt;:&lt;Currency&gt;] [feedprice=&lt;Wert&gt;:&lt;Currency&gt;] </b> <br><br>
Legt ein beliebiges Device und seine Readings zur Energiemessung fest. Legt ein beliebiges Device und seine Readings zur Energiemessung fest.
Das Modul geht davon aus, dass der numerische Wert der Readings positiv ist. Das Modul geht davon aus, dass der numerische Wert der Readings positiv ist.
@ -19156,6 +19180,8 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<tr><td> <b>gfeedin</b> </td><td>Reading welches die aktuell in das Netz eingespeiste Leistung liefert </td></tr> <tr><td> <b>gfeedin</b> </td><td>Reading welches die aktuell in das Netz eingespeiste Leistung liefert </td></tr>
<tr><td> <b>feedtotal</b> </td><td>Reading welches die Summe der in das Netz eingespeisten Energie liefert (ein sich stetig erhöhender Zähler) </td></tr> <tr><td> <b>feedtotal</b> </td><td>Reading welches die Summe der in das Netz eingespeisten Energie liefert (ein sich stetig erhöhender Zähler) </td></tr>
<tr><td> <b>Einheit</b> </td><td>die jeweilige Einheit (W,kW,Wh,kWh) </td></tr> <tr><td> <b>Einheit</b> </td><td>die jeweilige Einheit (W,kW,Wh,kWh) </td></tr>
<tr><td> <b>conprice</b> </td><td>Preis und Währung für den Bezug einer kWh (optional) </td></tr>
<tr><td> <b>feedprice</b> </td><td>Preis und Währung für die Einspeisung einer kWh (optional) </td></tr>
</table> </table>
</ul> </ul>
<br> <br>
@ -19172,7 +19198,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<ul> <ul>
<b>Beispiel: </b> <br> <b>Beispiel: </b> <br>
set &lt;name&gt; currentMeterDev Meter gcon=Wirkleistung:W contotal=BezWirkZaehler:kWh gfeedin=-gcon feedtotal=EinWirkZaehler:kWh <br> set &lt;name&gt; currentMeterDev Meter gcon=Wirkleistung:W contotal=BezWirkZaehler:kWh gfeedin=-gcon feedtotal=EinWirkZaehler:kWh conprice=0.2958: feedprice=0.1269: <br>
<br> <br>
# Device Meter liefert den aktuellen Netzbezug im Reading "Wirkleistung" (W), # Device Meter liefert den aktuellen Netzbezug im Reading "Wirkleistung" (W),
die Summe des Netzbezugs im Reading "BezWirkZaehler" (kWh), die aktuelle Einspeisung in "Wirkleistung" wenn "Wirkleistung" negativ ist, die Summe des Netzbezugs im Reading "BezWirkZaehler" (kWh), die aktuelle Einspeisung in "Wirkleistung" wenn "Wirkleistung" negativ ist,
@ -19504,7 +19530,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<br><br> <br><br>
<b>Model SolCastAPI:</b> <br> <b>Model SolCastAPI:</b> <br>
Die empfohlene Autokorrekturmethode ist <b>on_simple</b>. <br> Die empfohlene Autokorrekturmethode ist <b>on_complex</b>. <br>
Bevor man die Autokorrektur eingeschaltet, ist die Prognose mit folgenden Schritten zu optimieren: <br><br> Bevor man die Autokorrektur eingeschaltet, ist die Prognose mit folgenden Schritten zu optimieren: <br><br>
<ul> <ul>
<li> <li>
@ -20049,7 +20075,8 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<a id="SolarForecast-attr-affectMaxDayVariance"></a> <a id="SolarForecast-attr-affectMaxDayVariance"></a>
<li><b>affectMaxDayVariance &lt;Zahl&gt; </b><br> <li><b>affectMaxDayVariance &lt;Zahl&gt; </b><br>
Maximale Änderungsgröße des PV Vorhersagefaktors (Reading pvCorrectionFactor_XX) pro Tag. <br> Maximale Anpassung des PV Vorhersagefaktors (Reading pvCorrectionFactor_XX) die bezogen auf eine
Stunde pro Tag vorgenommen werden kann. <br>
Auf das Lern- und Prognoseverhalten einer eventuell verwendeten KI-Unterstützung Auf das Lern- und Prognoseverhalten einer eventuell verwendeten KI-Unterstützung
(<a href="#SolarForecast-set-pvCorrectionFactor_Auto">pvCorrectionFactor_Auto</a>) hat diese Einstellung keinen (<a href="#SolarForecast-set-pvCorrectionFactor_Auto">pvCorrectionFactor_Auto</a>) hat diese Einstellung keinen
Einfluß. <br> Einfluß. <br>

View File

@ -158,6 +158,12 @@ BEGIN {
# Versions History intern # Versions History intern
my %vNotesIntern = ( my %vNotesIntern = (
"1.16.8" => "16.03.2024 plantConfigCheck: adjust pvCorrectionFactor_Auto check, settings of forecastRefresh ".
"rename reading nextSolCastCall to nextRadiationAPICall ".
"currentMeterDev: new optional keys conprice, feedprice ".
"destroy runtime data when delete device ",
"1.16.7" => "12.03.2024 prevent duplicates in NOTIFYDEV, Forum: https://forum.fhem.de/index.php?msg=1306875 ",
"1.16.6" => "11.03.2024 plantConfigCheck: join forecastProperties with ',' ",
"1.16.5" => "04.03.2024 setPVhistory: code changes, plantConfigCheck: check forecastRefresh ". "1.16.5" => "04.03.2024 setPVhistory: code changes, plantConfigCheck: check forecastRefresh ".
"check age of weather data according to used MOSMIX variant ", "check age of weather data according to used MOSMIX variant ",
"1.16.4" => "02.03.2024 __getDWDSolarData: change check reading to fcx_12_x, internal code changes ". "1.16.4" => "02.03.2024 __getDWDSolarData: change check reading to fcx_12_x, internal code changes ".
@ -1547,6 +1553,7 @@ sub _setcurrentRadiationAPI { ## no critic "not used"
createAssociatedWith ($hash); createAssociatedWith ($hash);
writeCacheToFile ($hash, "plantconfig", $plantcfg.$name); # Anlagenkonfiguration File schreiben writeCacheToFile ($hash, "plantconfig", $plantcfg.$name); # Anlagenkonfiguration File schreiben
setModel ($hash); # Model setzen setModel ($hash); # Model setzen
deleteReadingspec ($hash, 'nextRadiationAPICall');
return if(_checkSetupNotComplete ($hash)); # keine Stringkonfiguration wenn Setup noch nicht komplett return if(_checkSetupNotComplete ($hash)); # keine Stringkonfiguration wenn Setup noch nicht komplett
@ -1783,6 +1790,16 @@ sub _setmeterDevice { ## no critic "not used"
return qq{Incorrect input. It is not allowed that the keys gcon and gfeedin refer to each other.}; return qq{Incorrect input. It is not allowed that the keys gcon and gfeedin refer to each other.};
} }
if ($h->{conprice}) {
my ($gcp,$gcpcucy) = split ":", $h->{conprice};
return qq{Incorrect input for key 'conprice'. Please consider the commandref.} if(!$gcp || !$gcpcucy);
}
if ($h->{feedprice}) {
my ($gfr,$gfrcucy) = split ":", $h->{feedprice};
return qq{Incorrect input for key 'feedprice'. Please consider the commandref.} if(!$gfr || !$gfrcucy);
}
## alte Speicherwerte löschen ## alte Speicherwerte löschen
############################### ###############################
delete $data{$type}{$name}{circular}{'99'}{feedintotal}; delete $data{$type}{$name}{circular}{'99'}{feedintotal};
@ -2717,7 +2734,7 @@ sub __getSolCastData {
$etxt =~ s{<WT>}{($leadtime/60)}eg; $etxt =~ s{<WT>}{($leadtime/60)}eg;
if ($trc <= 0) { if ($trc <= 0) {
readingsSingleUpdate($hash, 'nextSolCastCall', $etxt, 1); readingsSingleUpdate($hash, 'nextRadiationAPICall', $etxt, 1);
return qq{SolCast free daily limit is used up}; return qq{SolCast free daily limit is used up};
} }
@ -2726,7 +2743,7 @@ sub __getSolCastData {
my $sstime = timestringToTimestamp ($date.' '.ReadingsVal($name, "Today_SunSet", '00:00').':00'); my $sstime = timestringToTimestamp ($date.' '.ReadingsVal($name, "Today_SunSet", '00:00').':00');
if ($t < $srtime - $leadtime || $t > $sstime + $lagtime) { if ($t < $srtime - $leadtime || $t > $sstime + $lagtime) {
readingsSingleUpdate($hash, 'nextSolCastCall', $etxt, 1); readingsSingleUpdate($hash, 'nextRadiationAPICall', $etxt, 1);
return "The current time is not between sunrise minus ".($leadtime/60)." minutes and sunset"; return "The current time is not between sunrise minus ".($leadtime/60)." minutes and sunset";
} }
@ -3113,7 +3130,7 @@ sub ___setSolCastAPIcallKeyData {
Log3 ($name, 1, "$name DEBUG> SolCast API Call - next API Call: ".(timestampToTimestring ($t + $apiitv, $lang))[0]); Log3 ($name, 1, "$name DEBUG> SolCast API Call - next API Call: ".(timestampToTimestring ($t + $apiitv, $lang))[0]);
} }
readingsSingleUpdate ($hash, 'nextSolCastCall', $hqtxt{after}{$lang}.' '.(timestampToTimestring ($t + $apiitv, $lang))[0], 1); readingsSingleUpdate ($hash, 'nextRadiationAPICall', $hqtxt{after}{$lang}.' '.(timestampToTimestring ($t + $apiitv, $lang))[0], 1);
return; return;
} }
@ -3138,7 +3155,7 @@ sub __getForecastSolarData {
my $sstime = timestringToTimestamp ($date.' '.ReadingsVal($name, "Today_SunSet", '00:00').':00'); my $sstime = timestringToTimestamp ($date.' '.ReadingsVal($name, "Today_SunSet", '00:00').':00');
if ($t < $srtime - $leadtime || $t > $sstime + $lagtime) { if ($t < $srtime - $leadtime || $t > $sstime + $lagtime) {
readingsSingleUpdate($hash, 'nextSolCastCall', $etxt, 1); readingsSingleUpdate($hash, 'nextRadiationAPICall', $etxt, 1);
return "The current time is not between sunrise minus ".($leadtime/60)." minutes and sunset"; return "The current time is not between sunrise minus ".($leadtime/60)." minutes and sunset";
} }
@ -3448,7 +3465,7 @@ sub ___setForeCastAPIcallKeyData {
$smt = '(forced waiting time)'; $smt = '(forced waiting time)';
} }
readingsSingleUpdate ($hash, 'nextSolCastCall', $hqtxt{after}{$lang}.' '.(timestampToTimestring ($t + $apiitv, $lang))[0].' '.$smt, 1); readingsSingleUpdate ($hash, 'nextRadiationAPICall', $hqtxt{after}{$lang}.' '.(timestampToTimestring ($t + $apiitv, $lang))[0].' '.$smt, 1);
return; return;
} }
@ -3547,7 +3564,7 @@ sub __getVictronSolarData {
} }
} }
readingsSingleUpdate ($hash, 'nextSolCastCall', $hqtxt{after}{$lang}.' '.(timestampToTimestring ($t + $apiitv, $lang))[0], 1); readingsSingleUpdate ($hash, 'nextRadiationAPICall', $hqtxt{after}{$lang}.' '.(timestampToTimestring ($t + $apiitv, $lang))[0], 1);
__VictronVRM_ApiRequestLogin ($paref); __VictronVRM_ApiRequestLogin ($paref);
@ -5245,6 +5262,10 @@ sub Delete {
} }
} }
my $type = $hash->{TYPE};
delete $data{$type}{$name};
return; return;
} }
@ -5639,40 +5660,6 @@ sub centralTask {
### nicht mehr benötigte Daten verarbeiten - Bereich kann später wieder raus !! ### nicht mehr benötigte Daten verarbeiten - Bereich kann später wieder raus !!
########################################################################################################################## ##########################################################################################################################
## AI Raw Daten formatieren # 09.02.2024
if (defined $data{$type}{$name}{aidectree}{airaw}) {
for my $idx (sort keys %{$data{$type}{$name}{aidectree}{airaw}}) {
delete $data{$type}{$name}{aidectree}{airaw}{$idx}{wrp};
$data{$type}{$name}{aidectree}{airaw}{$idx}{temp} = 0 if(AiRawdataVal ($hash, $idx, 'temp', 0) eq '00');
$data{$type}{$name}{aidectree}{airaw}{$idx}{temp} = 5 if(AiRawdataVal ($hash, $idx, 'temp', 0) eq '05');
$data{$type}{$name}{aidectree}{airaw}{$idx}{temp} = -5 if(AiRawdataVal ($hash, $idx, 'temp', 0) eq '-05');
}
}
## percentile in simple umsetzen # 05.02.2024
for my $idx (sort keys %{$data{$type}{$name}{circular}}) {
if(defined $data{$type}{$name}{circular}{$idx}{pvcorrf}{percentile}) {
$data{$type}{$name}{circular}{$idx}{pvcorrf}{simple} = $data{$type}{$name}{circular}{$idx}{pvcorrf}{percentile};
delete $data{$type}{$name}{circular}{$idx}{pvcorrf}{percentile};
}
if(defined $data{$type}{$name}{circular}{$idx}{quality}{percentile}) {
$data{$type}{$name}{circular}{$idx}{quality}{simple} = $data{$type}{$name}{circular}{$idx}{quality}{percentile};
delete $data{$type}{$name}{circular}{$idx}{quality}{percentile};
}
if(defined $data{$type}{$name}{circular}{$idx}{pvrlsum}{percentile}) {
$data{$type}{$name}{circular}{$idx}{pvrlsum}{simple} = $data{$type}{$name}{circular}{$idx}{pvrlsum}{percentile};
delete $data{$type}{$name}{circular}{$idx}{pvrlsum}{percentile};
}
if(defined $data{$type}{$name}{circular}{$idx}{pvfcsum}{percentile}) {
$data{$type}{$name}{circular}{$idx}{pvfcsum}{simple} = $data{$type}{$name}{circular}{$idx}{pvfcsum}{percentile};
delete $data{$type}{$name}{circular}{$idx}{pvfcsum}{percentile};
}
if(defined $data{$type}{$name}{circular}{$idx}{dnumsum}{percentile}) {
$data{$type}{$name}{circular}{$idx}{dnumsum}{simple} = $data{$type}{$name}{circular}{$idx}{dnumsum}{percentile};
delete $data{$type}{$name}{circular}{$idx}{dnumsum}{percentile};
}
}
## nicht-Bin Werte löschen / wrp löschen ## nicht-Bin Werte löschen / wrp löschen
my $ra = '0|00|05|5|10|15|20|25|30|35|40|45|50|55|60|65|70|75|80|85|90|95|100|.*\..*|simple'; my $ra = '0|00|05|5|10|15|20|25|30|35|40|45|50|55|60|65|70|75|80|85|90|95|100|.*\..*|simple';
@ -5770,6 +5757,12 @@ sub centralTask {
} }
} }
my $nscc = ReadingsVal ($name, 'nextSolCastCall', ''); # 14.03.2024
if ($nscc) {
readingsSingleUpdate ($hash, 'nextRadiationAPICall', $nscc, 0);
deleteReadingspec ($hash, 'nextSolCastCall');
}
####################################################################################################################### #######################################################################################################################
return if(!$init_done); return if(!$init_done);
@ -7180,6 +7173,18 @@ sub _transferMeterValues {
return if(!$gc || !$gf || !$gt || !$ft); return if(!$gc || !$gf || !$gt || !$ft);
if ($h->{conprice}) {
my ($gcp,$gcpcucy) = split ":", $h->{conprice}; # Bezugspreis (Arbeitspreis) pro kWh
$data{$type}{$name}{current}{ePurchasePrice} = $gcp;
$data{$type}{$name}{current}{ePurchasePriceCcy} = $gcpcucy;
}
if ($h->{feedprice}) {
my ($gfr,$gfrcucy) = split ":", $h->{feedprice}; # Einspeisevergütung pro kWh
$data{$type}{$name}{current}{eFeedInTariff} = $gfr;
$data{$type}{$name}{current}{eFeedInTariffCcy} = $gfrcucy;
}
$gfunit //= $gcunit; $gfunit //= $gcunit;
$gcunit //= $gfunit; $gcunit //= $gfunit;
@ -8304,8 +8309,11 @@ sub __planInitialSwitchTime {
return; return;
} }
debugLog ($paref, "consumerPlanning", qq{Planning consumer "$c" - name: }.ConsumerVal ($hash, $c, 'name', ''). if ($debug =~ /consumerPlanning/x) {
Log3 ($name, 1, qq{$name DEBUG> ############### consumerPlanning consumer "$c" ############### });
Log3 ($name, 1, qq{$name DEBUG> Planning consumer "$c" - name: }.ConsumerVal ($hash, $c, 'name', '').
qq{ alias: }.ConsumerVal ($hash, $c, 'alias', '')); qq{ alias: }.ConsumerVal ($hash, $c, 'alias', ''));
}
if (ConsumerVal ($hash, $c, 'type', $defctype) eq 'noSchedule') { if (ConsumerVal ($hash, $c, 'type', $defctype) eq 'noSchedule') {
debugLog ($paref, "consumerPlanning", qq{consumer "$c" - }.$hqtxt{scnp}{EN}); debugLog ($paref, "consumerPlanning", qq{consumer "$c" - }.$hqtxt{scnp}{EN});
@ -8421,8 +8429,8 @@ sub ___doPlanning {
my %max; my %max;
my %mtimes; my %mtimes;
## max. Überschuß ermitteln ## max. PV-Forecast bzw. Überschuß (bei gesetzen affectConsForecastInPlanning) ermitteln
############################# ##########################################################################################
for my $idx (sort keys %{$nh}) { for my $idx (sort keys %{$nh}) {
my $pvfc = NexthoursVal ($hash, $idx, 'pvfc', 0); my $pvfc = NexthoursVal ($hash, $idx, 'pvfc', 0);
my $confcex = NexthoursVal ($hash, $idx, 'confcEx', 0); # prognostizierter Verbrauch ohne registrierte Consumer my $confcex = NexthoursVal ($hash, $idx, 'confcEx', 0); # prognostizierter Verbrauch ohne registrierte Consumer
@ -8960,7 +8968,7 @@ sub ___switchConsumerOn {
my $nompow = ConsumerVal ($hash, $c, 'power', '-'); my $nompow = ConsumerVal ($hash, $c, 'power', '-');
my $sp = CurrentVal ($hash, 'surplus', 0); my $sp = CurrentVal ($hash, 'surplus', 0);
Log3 ($name, 1, qq{$name DEBUG> ############### consumer "$c" ############### }); Log3 ($name, 1, qq{$name DEBUG> ############### consumerSwitching consumer "$c" ############### });
Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - general switching parameters => }. Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - general switching parameters => }.
qq{auto mode: $auto, current Consumption: $cons W, nompower: $nompow, surplus: $sp W, }. qq{auto mode: $auto, current Consumption: $cons W, nompower: $nompow, surplus: $sp W, }.
qq{planstate: $pstate, starttime: }.($startts ? (timestampToTimestring ($startts, $lang))[0] : "undef") qq{planstate: $pstate, starttime: }.($startts ? (timestampToTimestring ($startts, $lang))[0] : "undef")
@ -10859,7 +10867,7 @@ sub _graphicHeader {
isDWDUsed ($hash) ? '<a href="https://www.dwd.de/DE/leistungen/met_verfahren_mosmix/met_verfahren_mosmix.html" style="color: inherit !important;" target="_blank">DWD</a>:' : isDWDUsed ($hash) ? '<a href="https://www.dwd.de/DE/leistungen/met_verfahren_mosmix/met_verfahren_mosmix.html" style="color: inherit !important;" target="_blank">DWD</a>:' :
q{}; q{};
my $nscc = ReadingsVal ($name, 'nextSolCastCall', '?'); my $nscc = ReadingsVal ($name, 'nextRadiationAPICall', '?');
my $lrt = SolCastAPIVal ($hash, '?All', '?All', 'lastretrieval_time', '-'); my $lrt = SolCastAPIVal ($hash, '?All', '?All', 'lastretrieval_time', '-');
my $scrm = SolCastAPIVal ($hash, '?All', '?All', 'response_message', '-'); my $scrm = SolCastAPIVal ($hash, '?All', '?All', 'response_message', '-');
@ -14145,8 +14153,10 @@ sub checkPlantConfig {
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $type = $hash->{TYPE}; my $type = $hash->{TYPE};
setModel ($hash); # Model setzen
my $lang = AttrVal ($name, 'ctrlLanguage', AttrVal ('global', 'language', $deflang)); my $lang = AttrVal ($name, 'ctrlLanguage', AttrVal ('global', 'language', $deflang));
my $pcf = ReadingsVal ($name, 'pvCorrectionFactor_Auto', ''); my $pcf = ReadingsVal ($name, 'pvCorrectionFactor_Auto', 'off');
my $raname = ReadingsVal ($name, 'currentRadiationAPI', ''); my $raname = ReadingsVal ($name, 'currentRadiationAPI', '');
my ($acu, $aln) = isAutoCorrUsed ($name); my ($acu, $aln) = isAutoCorrUsed ($name);
@ -14247,7 +14257,7 @@ sub checkPlantConfig {
$result->{'DWD Weather Properties'}{fault} = 1; $result->{'DWD Weather Properties'}{fault} = 1;
} }
else { else {
$mosm = AttrVal ($fcname, 'forecastRefresh', 6) == 1 ? 'MOSMIX_S' : 'MOSMIX_L'; $mosm = AttrVal ($fcname, 'forecastRefresh', 6) == 6 ? 'MOSMIX_L' : 'MOSMIX_S';
if ($mosm eq 'MOSMIX_L') { if ($mosm eq 'MOSMIX_L') {
$result->{'DWD Weather Properties'}{state} = $info; $result->{'DWD Weather Properties'}{state} = $info;
@ -14259,8 +14269,8 @@ sub checkPlantConfig {
} }
$result->{'DWD Weather Properties'}{note} .= qq{checked parameters and attributes of device "$fcname": <br>}; $result->{'DWD Weather Properties'}{note} .= qq{checked parameters and attributes of device "$fcname": <br>};
$result->{'DWD Weather Properties'}{note} .= 'forecastProperties -> '.join (' ', @dweattrmust).'<br>'; $result->{'DWD Weather Properties'}{note} .= 'forecastProperties -> '.join (',', @dweattrmust).'<br>';
$result->{'DWD Weather Properties'}{note} .= 'forecastRefresh '.($mosm eq 'MOSMIX_L' ? '-> set attribute to "1" if possible' : '').'<br>'; $result->{'DWD Weather Properties'}{note} .= 'forecastRefresh '.($mosm eq 'MOSMIX_L' ? '-> set attribute to below "6" if possible' : '').'<br>';
} }
} }
@ -14303,7 +14313,7 @@ sub checkPlantConfig {
$result->{'DWD Radiation Properties'}{fault} = 1; $result->{'DWD Radiation Properties'}{fault} = 1;
} }
else { else {
$mosm = AttrVal ($raname, 'forecastRefresh', 6) == 1 ? 'MOSMIX_S' : 'MOSMIX_L'; $mosm = AttrVal ($raname, 'forecastRefresh', 6) == 6 ? 'MOSMIX_L' : 'MOSMIX_S';
if ($mosm eq 'MOSMIX_L') { if ($mosm eq 'MOSMIX_L') {
$result->{'DWD Radiation Properties'}{state} = $info; $result->{'DWD Radiation Properties'}{state} = $info;
@ -14333,8 +14343,8 @@ sub checkPlantConfig {
$result->{'DWD Radiation Properties'}{note} .= qq{checked global Radiation parameters: <br>}; $result->{'DWD Radiation Properties'}{note} .= qq{checked global Radiation parameters: <br>};
$result->{'DWD Radiation Properties'}{note} .= 'MOSMIX variant, Age of Radiation data. <br>'; $result->{'DWD Radiation Properties'}{note} .= 'MOSMIX variant, Age of Radiation data. <br>';
$result->{'DWD Radiation Properties'}{note} .= qq{<br>checked parameters and attributes device "$raname": <br>}; $result->{'DWD Radiation Properties'}{note} .= qq{<br>checked parameters and attributes device "$raname": <br>};
$result->{'DWD Radiation Properties'}{note} .= 'forecastProperties -> '.join (' ', @draattrmust).'<br>'; $result->{'DWD Radiation Properties'}{note} .= 'forecastProperties -> '.join (',', @draattrmust).'<br>';
$result->{'DWD Radiation Properties'}{note} .= 'forecastRefresh '.($mosm eq 'MOSMIX_L' ? '-> set attribute to "1" if possible' : '').'<br>'; $result->{'DWD Radiation Properties'}{note} .= 'forecastRefresh '.($mosm eq 'MOSMIX_L' ? '-> set attribute to below "6" if possible' : '').'<br>';
} }
## Check Rooftop und Roof Ident Pair Settings (SolCast) ## Check Rooftop und Roof Ident Pair Settings (SolCast)
@ -14468,10 +14478,10 @@ sub checkPlantConfig {
} }
if (isForecastSolarUsed ($hash)) { # allg. Settings bei Nutzung Forecast.Solar API if (isForecastSolarUsed ($hash)) { # allg. Settings bei Nutzung Forecast.Solar API
if (!$pcf || $pcf !~ /on/xs) { if ($pcf !~ /on/xs) {
$result->{'Common Settings'}{state} = $info; $result->{'Common Settings'}{state} = $info;
$result->{'Common Settings'}{result} .= qq{pvCorrectionFactor_Auto is set to "$pcf" <br>}; $result->{'Common Settings'}{result} .= qq{pvCorrectionFactor_Auto is set to "$pcf" <br>};
$result->{'Common Settings'}{note} .= qq{Set pvCorrectionFactor_Auto to "on*" if an automatic adjustment of the prescaler data should be done.<br>}; $result->{'Common Settings'}{note} .= qq{Set pvCorrectionFactor_Auto to "on_complex" is recommended.<br>};
} }
if (!$lat) { if (!$lat) {
@ -14501,10 +14511,10 @@ sub checkPlantConfig {
my $lam = SolCastAPIVal ($hash, '?All', '?All', 'response_message', 'success'); my $lam = SolCastAPIVal ($hash, '?All', '?All', 'response_message', 'success');
if (!$pcf || $pcf !~ /on/xs) { if ($pcf !~ /on/xs) {
$result->{'Common Settings'}{state} = $info; $result->{'Common Settings'}{state} = $info;
$result->{'Common Settings'}{result} .= qq{pvCorrectionFactor_Auto is set to "$pcf" <br>}; $result->{'Common Settings'}{result} .= qq{pvCorrectionFactor_Auto is set to "$pcf" <br>};
$result->{'Common Settings'}{note} .= qq{set pvCorrectionFactor_Auto to "on*" is recommended if the SolCast efficiency factor is already adjusted.<br>}; $result->{'Common Settings'}{note} .= qq{set pvCorrectionFactor_Auto to "on_complex" is recommended if the SolCast efficiency factor is already adjusted.<br>};
} }
if (!$osi) { if (!$osi) {
@ -14551,10 +14561,10 @@ sub checkPlantConfig {
$result->{'Common Settings'}{info} = 1; $result->{'Common Settings'}{info} = 1;
} }
if (!$pcf || $pcf !~ /on/xs) { if ($pcf !~ /on/xs) {
$result->{'Common Settings'}{state} = $info; $result->{'Common Settings'}{state} = $info;
$result->{'Common Settings'}{result} .= qq{pvCorrectionFactor_Auto is set to "$pcf" <br>}; $result->{'Common Settings'}{result} .= qq{pvCorrectionFactor_Auto is set to "$pcf" <br>};
$result->{'Common Settings'}{note} .= qq{Set pvCorrectionFactor_Auto to "on*" if an automatic adjustment of the prescaler data should be done.<br>}; $result->{'Common Settings'}{note} .= qq{Set pvCorrectionFactor_Auto to "on_complex" or "on_complex_ai" is recommended.<br>};
} }
if ($lam ne 'success') { if ($lam ne 'success') {
@ -14579,10 +14589,10 @@ sub checkPlantConfig {
my $gdn = AttrVal ('global', 'dnsServer', ''); my $gdn = AttrVal ('global', 'dnsServer', '');
my $vrmcr = SolCastAPIVal ($hash, '?VRM', '?API', 'credentials', ''); my $vrmcr = SolCastAPIVal ($hash, '?VRM', '?API', 'credentials', '');
if ($pcf && $pcf !~ /off/xs) { if ($pcf !~ /on/xs) {
$result->{'Common Settings'}{state} = $warn; $result->{'Common Settings'}{state} = $warn;
$result->{'Common Settings'}{result} .= qq{pvCorrectionFactor_Auto is set to "$pcf" <br>}; $result->{'Common Settings'}{result} .= qq{pvCorrectionFactor_Auto is set to "$pcf" <br>};
$result->{'Common Settings'}{note} .= qq{set pvCorrectionFactor_Auto to "off" is recommended because of this API is KI based.<br>}; $result->{'Common Settings'}{note} .= qq{set pvCorrectionFactor_Auto to "on_complex" is recommended.<br>};
$result->{'Common Settings'}{warn} = 1; $result->{'Common Settings'}{warn} = 1;
} }
@ -14662,7 +14672,7 @@ sub checkPlantConfig {
## Ausgabe ## Ausgabe
############ ############
my $out = qq{<html>}; my $out = qq{<html>};
$out .= qq{<b>}.$hqtxt{plntck}{$lang}.qq{</b> <br><br>}; $out .= qq{<b>}.$hqtxt{plntck}{$lang}.qq{ - Model: $hash->{MODEL} </b> <br><br>};
$out .= qq{<table class="roomoverview" style="text-align:left; border:1px solid; padding:5px; border-spacing:5px; margin-left:auto; margin-right:auto;">}; $out .= qq{<table class="roomoverview" style="text-align:left; border:1px solid; padding:5px; border-spacing:5px; margin-left:auto; margin-right:auto;">};
$out .= qq{<tr style="font-weight:bold;">}; $out .= qq{<tr style="font-weight:bold;">};
@ -14973,11 +14983,8 @@ sub createAssociatedWith {
my $consumer = AttrVal($name, "consumer${c}", ""); my $consumer = AttrVal($name, "consumer${c}", "");
my ($ac,$hc) = parseParams ($consumer); my ($ac,$hc) = parseParams ($consumer);
my $codev = $ac->[0] // ''; my $codev = $ac->[0] // '';
push @cd, $codev if($codev);
my $dswitch = $hc->{switchdev} // ''; # alternatives Schaltdevice my $dswitch = $hc->{switchdev} // ''; # alternatives Schaltdevice
push @cd, $codev if($codev);
push @cd, $dswitch if($dswitch); push @cd, $dswitch if($dswitch);
} }
@ -14998,8 +15005,17 @@ sub createAssociatedWith {
push @ndn, $e; push @ndn, $e;
} }
$hash->{NOTIFYDEV} = join ",", @cd if(@cd); my %seen;
readingsSingleUpdate ($hash, ".associatedWith", join(" ",@ndn), 0) if(@ndn);
if (@cd) {
$hash->{NOTIFYDEV} = join ",", grep { !$seen{$_ }++ } @cd;
}
if (@nd) {
undef %seen;
my $asw = join " ", grep { !$seen{$_ }++ } @nd;
readingsSingleUpdate ($hash, ".associatedWith", $asw, 0);
}
} }
else { else {
InternalTimer(gettimeofday()+3, "FHEM::SolarForecast::createAssociatedWith", $hash, 0); InternalTimer(gettimeofday()+3, "FHEM::SolarForecast::createAssociatedWith", $hash, 0);
@ -15053,7 +15069,6 @@ sub setModel {
} }
else { else {
$hash->{MODEL} = 'DWD'; $hash->{MODEL} = 'DWD';
deleteReadingspec ($hash, 'nextSolCastCall');
} }
return; return;
@ -15673,7 +15688,7 @@ sub isWeatherAgeExceeded {
} }
} }
$resh->{mosmix} = AttrVal ($resh->{agedv}, 'forecastRefresh', 6) == 1 ? 'MOSMIX_S' : 'MOSMIX_L'; $resh->{mosmix} = AttrVal ($resh->{agedv}, 'forecastRefresh', 6) == 6 ? 'MOSMIX_L' : 'MOSMIX_S';
my $th = $resh->{mosmix} eq 'MOSMIX_S' ? 7200 : 25200; my $th = $resh->{mosmix} eq 'MOSMIX_S' ? 7200 : 25200;
$resh->{exceed} = $currts - $agets > $th ? 1 : 0; $resh->{exceed} = $currts - $agets > $th ? 1 : 0;
@ -17018,7 +17033,9 @@ to ensure that the system configuration is correct.
<ul> <ul>
<a id="SolarForecast-set-currentMeterDev"></a> <a id="SolarForecast-set-currentMeterDev"></a>
<li><b>currentMeterDev &lt;Meter Device Name&gt; gcon=&lt;Readingname&gt;:&lt;Unit&gt; contotal=&lt;Readingname&gt;:&lt;Unit&gt; gfeedin=&lt;Readingname&gt;:&lt;Unit&gt; feedtotal=&lt;Readingname&gt;:&lt;Unit&gt; </b> <br><br> <li><b>currentMeterDev &lt;Meter Device Name&gt; gcon=&lt;Readingname&gt;:&lt;Einheit&gt; contotal=&lt;Readingname&gt;:&lt;Einheit&gt;
gfeedin=&lt;Readingname&gt;:&lt;Einheit&gt; feedtotal=&lt;Readingname&gt;:&lt;Einheit&gt;
[conprice=&lt;Wert&gt;:&lt;Currency&gt;] [feedprice=&lt;Wert&gt;:&lt;Currency&gt;] </b> <br><br>
Sets any device and its readings for energy measurement. Sets any device and its readings for energy measurement.
The module assumes that the numeric value of the readings is positive. The module assumes that the numeric value of the readings is positive.
@ -17028,11 +17045,13 @@ to ensure that the system configuration is correct.
<ul> <ul>
<table> <table>
<colgroup> <col width="15%"> <col width="85%"> </colgroup> <colgroup> <col width="15%"> <col width="85%"> </colgroup>
<tr><td> <b>gcon</b> </td><td>Reading welches die aktuell aus dem Netz bezogene Leistung liefert </td></tr> <tr><td> <b>gcon</b> </td><td>Reading which supplies the power currently drawn from the grid </td></tr>
<tr><td> <b>contotal</b> </td><td>Reading welches die Summe der aus dem Netz bezogenen Energie liefert (ein sich stetig erhöhender Zähler) </td></tr> <tr><td> <b>contotal</b> </td><td>Reading which provides the sum of the energy drawn from the grid (a constantly increasing meter) </td></tr>
<tr><td> <b>gfeedin</b> </td><td>Reading welches die aktuell in das Netz eingespeiste Leistung liefert </td></tr> <tr><td> <b>gfeedin</b> </td><td>Reading which supplies the power currently fed into the grid </td></tr>
<tr><td> <b>feedtotal</b> </td><td>Reading welches die Summe der in das Netz eingespeisten Energie liefert (ein sich stetig erhöhender Zähler) </td></tr> <tr><td> <b>feedtotal</b> </td><td>Reading which provides the sum of the energy fed into the grid (a constantly increasing meter) </td></tr>
<tr><td> <b>Einheit</b> </td><td>die jeweilige Einheit (W,kW,Wh,kWh) </td></tr> <tr><td> <b>Einheit</b> </td><td>the respective unit (W,kW,Wh,kWh) </td></tr>
<tr><td> <b>conprice</b> </td><td>Price and currency for the purchase of one kWh (optional) </td></tr>
<tr><td> <b>feedprice</b> </td><td>Price and currency for the feed-in of one kWh (optional) </td></tr>
</table> </table>
</ul> </ul>
<br> <br>
@ -17049,7 +17068,7 @@ to ensure that the system configuration is correct.
<ul> <ul>
<b>Example: </b> <br> <b>Example: </b> <br>
set &lt;name&gt; currentMeterDev Meter gcon=Wirkleistung:W contotal=BezWirkZaehler:kWh gfeedin=-gcon feedtotal=EinWirkZaehler:kWh <br> set &lt;name&gt; currentMeterDev Meter gcon=Wirkleistung:W contotal=BezWirkZaehler:kWh gfeedin=-gcon feedtotal=EinWirkZaehler:kWh conprice=0.2958: feedprice=0.1269: <br>
<br> <br>
# Device Meter provides the current grid reference in the reading "Wirkleistung" (W), # Device Meter provides the current grid reference in the reading "Wirkleistung" (W),
the sum of the grid reference in the reading "BezWirkZaehler" (kWh), the current feed in "Wirkleistung" if "Wirkleistung" is negative, the sum of the grid reference in the reading "BezWirkZaehler" (kWh), the current feed in "Wirkleistung" if "Wirkleistung" is negative,
@ -17371,7 +17390,7 @@ to ensure that the system configuration is correct.
<br><br> <br><br>
<b>Model SolCastAPI:</b> <br> <b>Model SolCastAPI:</b> <br>
The recommended autocorrection method is <b>on_simple</b>. <br> The recommended autocorrection method is <b>on_complex</b>. <br>
Before turning on autocorrection, optimise the forecast with the following steps: <br><br> Before turning on autocorrection, optimise the forecast with the following steps: <br><br>
<ul> <ul>
<li> <li>
@ -17916,7 +17935,8 @@ to ensure that the system configuration is correct.
<a id="SolarForecast-attr-affectMaxDayVariance"></a> <a id="SolarForecast-attr-affectMaxDayVariance"></a>
<li><b>affectMaxDayVariance &lt;Zahl&gt; </b><br> <li><b>affectMaxDayVariance &lt;Zahl&gt; </b><br>
Maximum change size of the PV prediction factor (Reading pvCorrectionFactor_XX) per day. <br> Maximum adjustment of the PV prediction factor (Reading pvCorrectionFactor_XX) that can be made
in relation to one hour per day. <br>
This setting has no influence on the learning and forecasting behavior of any AI support used This setting has no influence on the learning and forecasting behavior of any AI support used
(<a href="#SolarForecast-set-pvCorrectionFactor_Auto">pvCorrectionFactor_Auto</a>). <br> (<a href="#SolarForecast-set-pvCorrectionFactor_Auto">pvCorrectionFactor_Auto</a>). <br>
(default: 0.5) (default: 0.5)
@ -19143,7 +19163,9 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<ul> <ul>
<a id="SolarForecast-set-currentMeterDev"></a> <a id="SolarForecast-set-currentMeterDev"></a>
<li><b>currentMeterDev &lt;Meter Device Name&gt; gcon=&lt;Readingname&gt;:&lt;Einheit&gt; contotal=&lt;Readingname&gt;:&lt;Einheit&gt; gfeedin=&lt;Readingname&gt;:&lt;Einheit&gt; feedtotal=&lt;Readingname&gt;:&lt;Einheit&gt; </b> <br><br> <li><b>currentMeterDev &lt;Meter Device Name&gt; gcon=&lt;Readingname&gt;:&lt;Einheit&gt; contotal=&lt;Readingname&gt;:&lt;Einheit&gt;
gfeedin=&lt;Readingname&gt;:&lt;Einheit&gt; feedtotal=&lt;Readingname&gt;:&lt;Einheit&gt;
[conprice=&lt;Wert&gt;:&lt;Currency&gt;] [feedprice=&lt;Wert&gt;:&lt;Currency&gt;] </b> <br><br>
Legt ein beliebiges Device und seine Readings zur Energiemessung fest. Legt ein beliebiges Device und seine Readings zur Energiemessung fest.
Das Modul geht davon aus, dass der numerische Wert der Readings positiv ist. Das Modul geht davon aus, dass der numerische Wert der Readings positiv ist.
@ -19158,6 +19180,8 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<tr><td> <b>gfeedin</b> </td><td>Reading welches die aktuell in das Netz eingespeiste Leistung liefert </td></tr> <tr><td> <b>gfeedin</b> </td><td>Reading welches die aktuell in das Netz eingespeiste Leistung liefert </td></tr>
<tr><td> <b>feedtotal</b> </td><td>Reading welches die Summe der in das Netz eingespeisten Energie liefert (ein sich stetig erhöhender Zähler) </td></tr> <tr><td> <b>feedtotal</b> </td><td>Reading welches die Summe der in das Netz eingespeisten Energie liefert (ein sich stetig erhöhender Zähler) </td></tr>
<tr><td> <b>Einheit</b> </td><td>die jeweilige Einheit (W,kW,Wh,kWh) </td></tr> <tr><td> <b>Einheit</b> </td><td>die jeweilige Einheit (W,kW,Wh,kWh) </td></tr>
<tr><td> <b>conprice</b> </td><td>Preis und Währung für den Bezug einer kWh (optional) </td></tr>
<tr><td> <b>feedprice</b> </td><td>Preis und Währung für die Einspeisung einer kWh (optional) </td></tr>
</table> </table>
</ul> </ul>
<br> <br>
@ -19174,7 +19198,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<ul> <ul>
<b>Beispiel: </b> <br> <b>Beispiel: </b> <br>
set &lt;name&gt; currentMeterDev Meter gcon=Wirkleistung:W contotal=BezWirkZaehler:kWh gfeedin=-gcon feedtotal=EinWirkZaehler:kWh <br> set &lt;name&gt; currentMeterDev Meter gcon=Wirkleistung:W contotal=BezWirkZaehler:kWh gfeedin=-gcon feedtotal=EinWirkZaehler:kWh conprice=0.2958: feedprice=0.1269: <br>
<br> <br>
# Device Meter liefert den aktuellen Netzbezug im Reading "Wirkleistung" (W), # Device Meter liefert den aktuellen Netzbezug im Reading "Wirkleistung" (W),
die Summe des Netzbezugs im Reading "BezWirkZaehler" (kWh), die aktuelle Einspeisung in "Wirkleistung" wenn "Wirkleistung" negativ ist, die Summe des Netzbezugs im Reading "BezWirkZaehler" (kWh), die aktuelle Einspeisung in "Wirkleistung" wenn "Wirkleistung" negativ ist,
@ -19506,7 +19530,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<br><br> <br><br>
<b>Model SolCastAPI:</b> <br> <b>Model SolCastAPI:</b> <br>
Die empfohlene Autokorrekturmethode ist <b>on_simple</b>. <br> Die empfohlene Autokorrekturmethode ist <b>on_complex</b>. <br>
Bevor man die Autokorrektur eingeschaltet, ist die Prognose mit folgenden Schritten zu optimieren: <br><br> Bevor man die Autokorrektur eingeschaltet, ist die Prognose mit folgenden Schritten zu optimieren: <br><br>
<ul> <ul>
<li> <li>
@ -20051,7 +20075,8 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<a id="SolarForecast-attr-affectMaxDayVariance"></a> <a id="SolarForecast-attr-affectMaxDayVariance"></a>
<li><b>affectMaxDayVariance &lt;Zahl&gt; </b><br> <li><b>affectMaxDayVariance &lt;Zahl&gt; </b><br>
Maximale Änderungsgröße des PV Vorhersagefaktors (Reading pvCorrectionFactor_XX) pro Tag. <br> Maximale Anpassung des PV Vorhersagefaktors (Reading pvCorrectionFactor_XX) die bezogen auf eine
Stunde pro Tag vorgenommen werden kann. <br>
Auf das Lern- und Prognoseverhalten einer eventuell verwendeten KI-Unterstützung Auf das Lern- und Prognoseverhalten einer eventuell verwendeten KI-Unterstützung
(<a href="#SolarForecast-set-pvCorrectionFactor_Auto">pvCorrectionFactor_Auto</a>) hat diese Einstellung keinen (<a href="#SolarForecast-set-pvCorrectionFactor_Auto">pvCorrectionFactor_Auto</a>) hat diese Einstellung keinen
Einfluß. <br> Einfluß. <br>