2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-02-25 03:44:52 +00:00

76_SolarForecast: new Version 1.46.0, Forum https://forum.fhem.de/index.php?msg=1334203

git-svn-id: https://svn.fhem.de/fhem/trunk@29665 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2025-02-17 15:49:23 +00:00
parent 5e05db3f14
commit 3e954889d5
2 changed files with 422 additions and 268 deletions

View File

@ -1,5 +1,7 @@
# 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: new Version 1.46.0,
Forum https://forum.fhem.de/index.php?msg=1334203
- feature: 98_vitoconnect.pm: Mapped error codes stored in readings - feature: 98_vitoconnect.pm: Mapped error codes stored in readings
- bugfix: 98_vitoconnect.pm: DeleteKeyValue thanks to Schlimbo - bugfix: 98_vitoconnect.pm: DeleteKeyValue thanks to Schlimbo
- change: 76_SolarForecast: version 1.45.6 - change: 76_SolarForecast: version 1.45.6

View File

@ -159,8 +159,13 @@ BEGIN {
# Versions History intern # Versions History intern
my %vNotesIntern = ( my %vNotesIntern = (
"1.46.0" => "17.02.2025 Notification System: print out last/next file pull if no messages are present, improvements and activation of ".
"_calcConsForecast_circular, checkPlantConfig: add Data Memory check pvHistory 'con' ".
"sunalt2bin/cloud2bin: classification of values improved, affectConsForecastLastDays: max to 180 ".
"set reset consumption to reset consumptionHistory, improve Debug Info ".
"fix error: https://forum.fhem.de/index.php?msg=1334123 ",
"1.45.6" => "12.02.2025 Notification System: print out next planned file pull, timestringsFromOffset: allow +- offsets ". "1.45.6" => "12.02.2025 Notification System: print out next planned file pull, timestringsFromOffset: allow +- offsets ".
"new sub _calcConsumptionForecast_circular to prepare the evaluation of consumption days in pvCircular ", "new sub _calcConsForecast_circular to prepare the evaluation of consumption days in pvCircular ",
"1.45.5" => "09.02.2025 change constant GMFILEREPEAT, GMFILERANDOM, Pull Message File from GitHub Repo ", "1.45.5" => "09.02.2025 change constant GMFILEREPEAT, GMFILERANDOM, Pull Message File from GitHub Repo ",
"1.45.4" => "08.02.2025 change constant GMFILEREPEAT + new constant GMFILERANDOM ", "1.45.4" => "08.02.2025 change constant GMFILEREPEAT + new constant GMFILERANDOM ",
"1.45.3" => "06.02.2025 __readDataWeather: if no values of hour 01 (00:00+) use val of hour 24 of day before ". "1.45.3" => "06.02.2025 __readDataWeather: if no values of hour 01 (00:00+) use val of hour 24 of day before ".
@ -356,18 +361,6 @@ my %vNotesIntern = (
"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 ".
"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 ".
"plantConfiguration: save/restore relevant readings AND attributes ".
"visual LED display whether the weather data is current (age < 2h) ",
"1.16.3" => "24.02.2024 store pvcorrf, quality, pvrlsum, pvfcsum, dnumsum with value <sunalt2bin>.<cloud2bin> in pvCircular ".
"get pvcorrf / quality from neff in combination with sun altitude (CircularSunCloudkorrVal) ".
"delete CircularCloudkorrVal, show sun position in beamgrafic weather mouse over ".
"split pvCorrection into pvCorrectionRead and pvCorrectionWrite ".
"_checkSetupNotComplete: improve setup Wizzard for ForecastSolar-API ",
"1.16.2" => "22.02.2024 minor changes, R101 -> RR1c, rr1c instead of weatherrainprob, delete wrp r101 ".
"delete wrp from circular & airaw, remove rain2bin, __getDWDSolarData: change \$runh, ".
"fix Illegal division by zero Forum: https://forum.fhem.de/index.php?msg=1304009 ".
"DWD API: check age of Rad1h data, store pvcorrf of sunalt with value 200+x in pvCircular ",
"0.1.0" => "09.12.2020 initial Version " "0.1.0" => "09.12.2020 initial Version "
); );
@ -383,6 +376,7 @@ use constant {
DEFINTERVAL => 70, # Standard Abfrageintervall DEFINTERVAL => 70, # Standard Abfrageintervall
SLIDENUMMAX => 3, # max. Anzahl der Arrayelemente in Schieberegistern SLIDENUMMAX => 3, # max. Anzahl der Arrayelemente in Schieberegistern
SPLSLIDEMAX => 20, # max. Anzahl der Arrayelemente in Schieberegister PV Überschuß SPLSLIDEMAX => 20, # max. Anzahl der Arrayelemente in Schieberegister PV Überschuß
CONDAYSLIDEMAX => 30, # max. Anzahl der Arrayelemente im Register pvCircular -> con_all -> <Tag>
WHISTREPEAT => 851, # Wiederholungsintervall Cache File Daten schreiben WHISTREPEAT => 851, # Wiederholungsintervall Cache File Daten schreiben
EPIECMAXCYCLES => 10, # Anzahl Einschaltzyklen (Consumer) für verbraucherspezifische Energiestück Ermittlung EPIECMAXCYCLES => 10, # Anzahl Einschaltzyklen (Consumer) für verbraucherspezifische Energiestück Ermittlung
@ -428,6 +422,7 @@ use constant {
TEMPBASEDEF => 25, # Temperatur Module bei Nominalleistung TEMPBASEDEF => 25, # Temperatur Module bei Nominalleistung
DEFMINTIME => 60, # default Einplanungsdauer in Minuten DEFMINTIME => 60, # default Einplanungsdauer in Minuten
CONSFCLDAYS => 60, # die Stundenwerte der letzten CONSFCLDAYS Tage zur Kalkulation der Verbrauchvorhersage einbezogen
DEFCTYPE => 'other', # default Verbrauchertyp DEFCTYPE => 'other', # default Verbrauchertyp
DEFCMODE => 'can', # default Planungsmode der Verbraucher DEFCMODE => 'can', # default Planungsmode der Verbraucher
DEFPOPERCENT => 1.0, # Standard % aktuelle Leistung an nominaler Leistung gemäß Typenschild DEFPOPERCENT => 1.0, # Standard % aktuelle Leistung an nominaler Leistung gemäß Typenschild
@ -468,6 +463,7 @@ use constant {
MOONCOLDEF => 'lightblue', # default Mond Färbung MOONCOLDEF => 'lightblue', # default Mond Färbung
ACTCOLDEF => 'orange', # default Färbung Icon wenn aktiv ACTCOLDEF => 'orange', # default Färbung Icon wenn aktiv
INACTCOLDEF => 'grey', # default Färbung Icon wenn inaktiv INACTCOLDEF => 'grey', # default Färbung Icon wenn inaktiv
LOCALE_TIME => setlocale (POSIX::LC_TIME), # installierte locale abfragen
BPATH => 'https://svn.fhem.de/trac/browser/trunk/fhem/contrib/SolarForecast/', # Basispfad Abruf contrib SolarForecast Files BPATH => 'https://svn.fhem.de/trac/browser/trunk/fhem/contrib/SolarForecast/', # Basispfad Abruf contrib SolarForecast Files
PPATH => '?format=txt', # Download Format PPATH => '?format=txt', # Download Format
@ -706,6 +702,17 @@ my %hmoon = (
7 => { icon => 'weather_moon_phases_8', DE => 'abnehmende Sichel', EN => 'decreasing crescent' }, 7 => { icon => 'weather_moon_phases_8', DE => 'abnehmende Sichel', EN => 'decreasing crescent' },
); );
# gekürzte Wochentagsnamen nach locale
my %habwdn = (
'1' => { DE => 'Mo', EN => 'Mon' },
'2' => { DE => 'Di', EN => 'Tue' },
'3' => { DE => 'Mi', EN => 'Wed' },
'4' => { DE => 'Do', EN => 'Thu' },
'5' => { DE => 'Fr', EN => 'Fri' },
'6' => { DE => 'Sa', EN => 'Sat' },
'7' => { DE => 'So', EN => 'Sun' },
);
my %hrepl = ( # Zeichenersetzungen my %hrepl = ( # Zeichenersetzungen
'0' => 'a', '0' => 'a',
'1' => 'b', '1' => 'b',
@ -984,6 +991,10 @@ my %htitles = (
DE => qq{Mitteilungen sind vorhanden - dr&#252;cke die Taste um sie zu &#246;ffnen} }, DE => qq{Mitteilungen sind vorhanden - dr&#252;cke die Taste um sie zu &#246;ffnen} },
nomsgfo => { EN => qq{there are no new messages}, nomsgfo => { EN => qq{there are no new messages},
DE => qq{es sind keine neuen Mitteilungen vorhanden} }, DE => qq{es sind keine neuen Mitteilungen vorhanden} },
lstmsgc => { EN => qq{last message call},
DE => qq{letzter Mitteilungsabruf} },
nxtmsgc => { EN => qq{next message call},
DE => qq{n&auml;chster Mitteilungsabruf} },
scaresps => { EN => qq{API request successful}, scaresps => { EN => qq{API request successful},
DE => qq{API Abfrage erfolgreich} }, DE => qq{API Abfrage erfolgreich} },
dwfcrsu => { EN => qq{Weather data are up to date according to used DWD model}, dwfcrsu => { EN => qq{Weather data are up to date according to used DWD model},
@ -1458,7 +1469,7 @@ sub Initialize {
$hash->{AttrList} = "affectBatteryPreferredCharge:slider,0,1,100 ". $hash->{AttrList} = "affectBatteryPreferredCharge:slider,0,1,100 ".
"affectConsForecastIdentWeekdays:1,0 ". "affectConsForecastIdentWeekdays:1,0 ".
"affectConsForecastInPlanning:1,0 ". "affectConsForecastInPlanning:1,0 ".
"affectConsForecastLastDays:slider,1,1,31 ". "affectConsForecastLastDays:selectnumbers,1,1,180,0,lin ".
"affectSolCastPercentile:select,10,50,90 ". "affectSolCastPercentile:select,10,50,90 ".
"consumerLegend:none,icon_top,icon_bottom,text_top,text_bottom ". "consumerLegend:none,icon_top,icon_bottom,text_top,text_bottom ".
"consumerAdviceIcon ". "consumerAdviceIcon ".
@ -1612,7 +1623,7 @@ sub Set {
batteryTriggerSet batteryTriggerSet
consumerMaster consumerMaster
consumerPlanning consumerPlanning
consumption consumptionHistory
energyH4TriggerSet energyH4TriggerSet
powerTriggerSet powerTriggerSet
pvCorrection pvCorrection
@ -2224,7 +2235,7 @@ sub _setreset { ## no critic "not used"
return; return;
} }
if ($prop eq 'consumption') { if ($prop eq 'consumptionHistory') {
my $dday = $paref->{prop1} // ""; # ein bestimmter Tag der pvHistory angegeben ? my $dday = $paref->{prop1} // ""; # ein bestimmter Tag der pvHistory angegeben ?
my $dhour = $paref->{prop2} // ""; # eine bestimmte Stunde eines Tages der pvHistory angegeben ? my $dhour = $paref->{prop2} // ""; # eine bestimmte Stunde eines Tages der pvHistory angegeben ?
@ -5686,7 +5697,7 @@ sub _attrconsumer { ## no critic "not used"
return $err if($err); return $err if($err);
if (!$h->{type} || !exists $h->{power}) { if (!$h->{type} || !exists $h->{power}) {
return qq{The syntax of "$aName" is not correct. Please consider the commandref.}; return qq{The syntax of "$aName" is not correct. Please consider the command reference.};
} }
my $alowt = grep (/^$h->{type}$/, @ctypes) ? 1 : 0; my $alowt = grep (/^$h->{type}$/, @ctypes) ? 1 : 0;
@ -5703,6 +5714,10 @@ sub _attrconsumer { ## no critic "not used"
return qq{The key "power" must be specified only by numbers without decimal places}; return qq{The key "power" must be specified only by numbers without decimal places};
} }
if (defined $h->{exconfc} && $h->{exconfc} !~ /^[012]$/xs) {
return qq{The key "exconfc" is not set correct. Please consider the command reference.};
}
if (exists $h->{mode} && $h->{mode} !~ /^(?:can|must)$/xs) { if (exists $h->{mode} && $h->{mode} !~ /^(?:can|must)$/xs) {
if ($h->{mode} =~ /.*:.*/xs) { if ($h->{mode} =~ /.*:.*/xs) {
my ($dv, $rd) = split ':', $h->{mode}; my ($dv, $rd) = split ':', $h->{mode};
@ -7546,9 +7561,9 @@ 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 !!
########################################################################################################################## ##########################################################################################################################
delete $data{$name}{circular}{99}{days2care}; # 29.12.2024 delete $data{$name}{circular}{99}{days2care}; # 29.12.2024
delete $data{$name}{circular}{'00'}; # 04.02.2025 delete $data{$name}{circular}{'00'}; # 04.02.2025
# delete $data{$name}{circular}{1};
$data{$name}{circular}{99}{initdaybatintot01} = delete $data{$name}{circular}{99}{initdaybatintot} if(defined $data{$name}{circular}{99}{initdaybatintot}); # 29.12.2024 $data{$name}{circular}{99}{initdaybatintot01} = delete $data{$name}{circular}{99}{initdaybatintot} if(defined $data{$name}{circular}{99}{initdaybatintot}); # 29.12.2024
$data{$name}{circular}{99}{initdaybatouttot01} = delete $data{$name}{circular}{99}{initdaybatouttot} if(defined $data{$name}{circular}{99}{initdaybatouttot}); # 29.12.2024 $data{$name}{circular}{99}{initdaybatouttot01} = delete $data{$name}{circular}{99}{initdaybatouttot} if(defined $data{$name}{circular}{99}{initdaybatouttot}); # 29.12.2024
@ -7696,9 +7711,9 @@ sub centralTask {
_batSocTarget ($centpars); # Batterie Optimum Ziel SOC berechnen _batSocTarget ($centpars); # Batterie Optimum Ziel SOC berechnen
_batChargeRecmd ($centpars); # Batterie Ladefreigabe berechnen und erstellen _batChargeRecmd ($centpars); # Batterie Ladefreigabe berechnen und erstellen
_manageConsumerData ($centpars); # Consumer Daten sammeln und Zeiten planen _manageConsumerData ($centpars); # Consumer Daten sammeln und Zeiten planen
_calcConsumptionForecast ($centpars); # Verbrauchsprognose erstellen # _calcConsumptionForecast ($centpars); # Verbrauchsprognose erstellen
_calcConsumptionForecast_circular ($centpars); # Test neue Verbrauchsprognose _calcConsForecast_circular ($centpars); # neue Verbrauchsprognose über pvCircular
_evaluateThresholds ($centpars); # Schwellenwerte bewerten und signalisieren _evaluateThresholds ($centpars); # Schwellenwerte bewerten und signalisieren
_calcReadingsTomorrowPVFc ($centpars); # zusätzliche Readings Tomorrow_HourXX_PVforecast berechnen _calcReadingsTomorrowPVFc ($centpars); # zusätzliche Readings Tomorrow_HourXX_PVforecast berechnen
@ -9544,6 +9559,8 @@ sub _transferMeterValues {
$data{$name}{circular}{sprintf("%02d",$nhour)}{gcons} = $gctotthishour; # Hilfshash Wert Bezug (Wh) Forum: https://forum.fhem.de/index.php/topic,117864.msg1133350.html#msg1133350 $data{$name}{circular}{sprintf("%02d",$nhour)}{gcons} = $gctotthishour; # Hilfshash Wert Bezug (Wh) Forum: https://forum.fhem.de/index.php/topic,117864.msg1133350.html#msg1133350
writeToHistory ( { paref => $paref, key => 'gcons', val => $gctotthishour, hour => $nhour } ); writeToHistory ( { paref => $paref, key => 'gcons', val => $gctotthishour, hour => $nhour } );
debugLog ($paref, "saveData2Cache|collectData", "write to pvHistory - day: $paref->{day}, hod: $nhour, GridConsumption (gcons): $gctotthishour Wh");
} }
## Management der in das Netz eingespeister (nur vom Meter gemessene) Energie ## Management der in das Netz eingespeister (nur vom Meter gemessene) Energie
@ -10209,7 +10226,6 @@ return;
sub _createSummaries { sub _createSummaries {
my $paref = shift; my $paref = shift;
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $day = $paref->{day}; my $day = $paref->{day};
my $chour = $paref->{chour}; # aktuelle Stunde my $chour = $paref->{chour}; # aktuelle Stunde
my $minute = $paref->{minute}; # aktuelle Minute my $minute = $paref->{minute}; # aktuelle Minute
@ -10385,7 +10401,6 @@ return;
sub _manageConsumerData { sub _manageConsumerData {
my $paref = shift; my $paref = shift;
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $t = $paref->{t}; # aktuelle Zeit my $t = $paref->{t}; # aktuelle Zeit
my $chour = $paref->{chour}; my $chour = $paref->{chour};
my $day = $paref->{day}; my $day = $paref->{day};
@ -10588,7 +10603,6 @@ return;
sub __calcEnergyPieces { sub __calcEnergyPieces {
my $paref = shift; my $paref = shift;
my $name = $paref->{name}; my $name = $paref->{name};
my $type = $paref->{type};
my $c = $paref->{consumer}; my $c = $paref->{consumer};
my $hash = $defs{$name}; my $hash = $defs{$name};
@ -10923,7 +10937,7 @@ sub ___doPlanning {
########################################################################################## ##########################################################################################
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 mit gesetzten Schlüssel exconfc
my $spexp = $pvfc - ($cicfip ? $confcex : 0); # prognostizierter Energieüberschuß (kann negativ sein) my $spexp = $pvfc - ($cicfip ? $confcex : 0); # prognostizierter Energieüberschuß (kann negativ sein)
@ -11486,7 +11500,7 @@ sub ___switchConsumerOn {
qq{planstate: $pstate, starttime: }.($startts ? (timestampToTimestring ($startts, $lang))[0] : "undef") qq{planstate: $pstate, starttime: }.($startts ? (timestampToTimestring ($startts, $lang))[0] : "undef")
); );
Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - isInLocktime: $iilt}.($rlt ? ", remainLockTime: $rlt seconds" : '')); Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - isInLocktime: $iilt}.($rlt ? ", remainLockTime: $rlt seconds" : ''));
Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - in Context 'switch on' => }. Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - Check Context 'switch on' => }.
qq{swoncond: $swoncond, on-command: $oncom } qq{swoncond: $swoncond, on-command: $oncom }
); );
Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - isAddSwitchOnCond Info: $infon}) if($swoncond && $infon); Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - isAddSwitchOnCond Info: $infon}) if($swoncond && $infon);
@ -11499,6 +11513,11 @@ sub ___switchConsumerOn {
} }
my $isintable = isInterruptable ($hash, $c, 0, 1); # mit Ausgabe Interruptable Info im Debug my $isintable = isInterruptable ($hash, $c, 0, 1); # mit Ausgabe Interruptable Info im Debug
if ($debug =~ /consumerSwitching${c}/x) {
Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - Interrupt Characteristic value: $isintable});
}
my $isConsRcmd = isConsRcmd ($hash, $c); my $isConsRcmd = isConsRcmd ($hash, $c);
my $supplmnt = ConsumerVal ($hash, $c, 'planSupplement', ''); my $supplmnt = ConsumerVal ($hash, $c, 'planSupplement', '');
@ -11603,7 +11622,7 @@ sub ___switchConsumerOff {
my ($iilt,$rlt) = isInLocktime ($paref); # Sperrzeit Status ermitteln my ($iilt,$rlt) = isInLocktime ($paref); # Sperrzeit Status ermitteln
if ($debug =~ /consumerSwitching${c}/x) { # nur für Debugging if ($debug =~ /consumerSwitching${c}/x) { # nur für Debugging
Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - in Context 'switch off' => }. Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - Check Context 'switch off' => }.
qq{swoffcond: $swoffcond, off-command: $offcom} qq{swoffcond: $swoffcond, off-command: $offcom}
); );
@ -12152,7 +12171,7 @@ return;
################################################################ ################################################################
# Energieverbrauch Vorhersage kalkulieren (Median) # Energieverbrauch Vorhersage kalkulieren (Median)
################################################################ ################################################################
sub _calcConsumptionForecast_circular { sub _calcConsForecast_circular {
my $paref = shift; my $paref = shift;
my $name = $paref->{name}; my $name = $paref->{name};
my $chour = $paref->{chour}; my $chour = $paref->{chour};
@ -12163,83 +12182,107 @@ sub _calcConsumptionForecast_circular {
my $hash = $defs{$name}; my $hash = $defs{$name};
my $acref = $data{$name}{consumers}; my $acref = $data{$name}{consumers};
my $swdfcfc = AttrVal ($name, 'affectConsForecastIdentWeekdays', 0); # nutze nur gleiche Wochentage (Mo...So) für Verbrauchsvorhersage my $swdfcfc = AttrVal ($name, 'affectConsForecastIdentWeekdays', 0); # nutze nur gleiche Wochentage (Mo...So) für Verbrauchsvorhersage
my $acld = AttrVal ($name, 'affectConsForecastLastDays', CONSFCLDAYS); # Beachtung Stundenwerte der letzten X Tage falls gesetzt
## Beachtung der letzten X Tage falls gesetzt
###############################################
my $acld = AttrVal ($name, 'affectConsForecastLastDays', 0);
## Verbrauchsvorhersage für den kommenden Tag
##############################################
my $dt = timestringsFromOffset ($t, 86400); my $dt = timestringsFromOffset ($t, 86400);
my $tomdayname = $dt->{dayname}; # Wochentagsname kommender Tag my $tomdayname = $dt->{dayname}; # Wochentagsname kommender Tag
my $lct = LOCALE_TIME =~ /^de_/xs ? 'DE' : 'EN';
my (@cona, $exconfc, $csme, %usage); my (@cona, $exconfc, $csme, %usage);
$usage{tom}{con} = 0; $usage{tom}{con} = 0;
debugLog ($paref, 'consumption|consumption_long', "################### Consumption forecast for the next day (new median) ###################");
## Verbrauch der hod-Stunden 01..24 u. gesamten Tag ermitteln ## Verbrauch der hod-Stunden 01..24 u. gesamten Tag ermitteln
############################################################### ###############################################################
for my $h (1..24) { # Median für jede Stunde / Tag berechnen for my $h (1..24) { # Median für jede Stunde / Tag berechnen
my $dt = timestringsFromOffset ($t, $h * 3600);
my $dayname = $dt->{dayname};
my $hh = sprintf "%02d", $h; my $hh = sprintf "%02d", $h;
my @conh; my (@conh, @conhtom);
my $mix = 0;
if ($swdfcfc) { # nur gleiche Tage (Mo...So) einbeziehen der Stunde if ($swdfcfc) { # nur bestimmten Tag (Mo...So) einbeziehen der Stunde
push @conh, @{$data{$name}{circular}{$hh}{con_all}{"$tomdayname"}}; push @conh, @{$data{$name}{circular}{$hh}{con_all}{"$dayname"}} if(defined ${$data{$name}{circular}{$hh}{con_all}{"$dayname"}}[0]);
push @conhtom, @{$data{$name}{circular}{$hh}{con_all}{"$tomdayname"}} if(defined ${$data{$name}{circular}{$hh}{con_all}{"$tomdayname"}}[0]); # für den nächsten Tag
}
else { # alle aufgezeichneten Wochentage in der Stunde berücksichtigen
for my $dy (keys %{$data{$name}{circular}{$hh}{con_all}}) { # den max Index aller Tagesarrays ermitteln
my $ai = $#{$data{$name}{circular}{$hh}{con_all}{$dy}};
$mix = $ai if($ai > $mix);
}
for my $i (0..$mix) { # Werte sortiert nach Alter aufsteigend in Array einfügen
for my $dy (sort keys %habwdn) {
push @conh, ${$data{$name}{circular}{$hh}{con_all}{$habwdn{$dy}{$lct}}}[$i] if(defined ${$data{$name}{circular}{$hh}{con_all}{$habwdn{$dy}{$lct}}}[$i]);
push @conhtom, @conh;
} }
else {
for my $dy (keys %{$data{$name}{circular}{$hh}{con_all}}) { # alle aufgezeichneten Wochentage in der Stunde berücksichtigen
push @conh, @{$data{$name}{circular}{$hh}{con_all}{$dy}};
} }
} }
my $hnum = scalar @conh; my $hnum = scalar @conh;
my $hnumtom = scalar @conhtom;
if ($hnum) { if ($hnum) {
if ($hnum > $acld) {
@conh = splice (@conh, $acld * -1);
$hnum = scalar @conh;
}
my $hcon = sprintf "%.0f", medianArray (\@conh); my $hcon = sprintf "%.0f", medianArray (\@conh);
$usage{$hh}{con} = $hcon; # prognostizierter Verbrauch (Median) der Stunde hh (Hour of Day) $usage{$hh}{con} = $hcon; # prognostizierter Verbrauch (Median) der Stunde hh (Hour of Day)
$usage{$hh}{num} = $hnum; $usage{$hh}{num} = $hnum;
$usage{tom}{con} += $hcon; # Summe prognostizierter Verbrauch (Median) des Tages }
$usage{tom}{num} += $hnum;
if ($hnumtom) {
if ($hnumtom > $acld) {
@conhtom = splice (@conhtom, $acld * -1);
$hnumtom = scalar @conhtom;
}
my $hcontom = sprintf "%.0f", medianArray (\@conhtom);
$usage{tom}{con} += $hcontom; # Summe prognostizierter Verbrauch (Median) des Tages
$usage{tom}{num} += $hnumtom;
} }
} }
## historische Werte Verbraucher exkludieren / geplante inkludieren ## Excludes / Includes vorbereiten
##################################################################### ####################################
my $tomnum = $usage{tom}{num} // 0;
if ($tomnum) {
my $exnum = 0; my $exnum = 0;
my $ex = 0; my $ex = 0;
my $lap = 1;
for my $n (sort{$a<=>$b} keys %{$data{$name}{pvhist}}) { for my $n (sort{$a<=>$b} keys %{$data{$name}{pvhist}}) {
next if ($n eq $day); # aktuellen (unvollständigen) Tag nicht berücksichtigen next if ($n eq $day); # aktuellen (unvollständigen) Tag nicht berücksichtigen
if ($swdfcfc) { # nur gleiche Tage (Mo...So) einbeziehen
my $hdn = HistoryVal ($hash, $n, 99, 'dayname', undef);
next if(!$hdn || $hdn ne $tomdayname);
}
for my $c (sort{$a<=>$b} keys %{$acref}) { # historischer Verbrauch aller registrierten Verbraucher aufaddieren for my $c (sort{$a<=>$b} keys %{$acref}) { # historischer Verbrauch aller registrierten Verbraucher aufaddieren
$exconfc = ConsumerVal ($hash, $c, 'exconfc', 0); # 1 -> Consumer Verbrauch von Erstelleung der Verbrauchsprognose ausschließen $exconfc = ConsumerVal ($hash, $c, 'exconfc', 0);
if ($exconfc) { if ($exconfc) {
## Tageswert Excludes finden und summieren ## Tageswert Excludes finden und summieren
############################################ ############################################
if ($exconfc == 1) { # 1 -> Consumer Verbrauch von Erstelleung der Verbrauchsprognose ausschließen
my $do = 1;
if ($swdfcfc) { # nur gleiche Tage (Mo...So) einbeziehen
my $hdn = HistoryVal ($hash, $n, 99, 'dayname', undef);
$do = 0 if(!$hdn || $hdn ne $tomdayname);
}
if ($do) {
$csme = HistoryVal ($hash, $n, 99, "csme${c}", 0); $csme = HistoryVal ($hash, $n, 99, "csme${c}", 0);
if ($csme > 0) { if ($csme > 0) {
$ex += $csme; $ex += $csme;
$exnum++; $exnum++;
debugLog ($paref, 'consumption|consumption_long', "Consumer '$c' hist cons registered by 'exconfc' for excl. - day: $n, csme: $csme"); debugLog ($paref, 'consumption_long', "Consumer '$c' hist cons registered by 'exconfc' for excl. - day: $n, csme: $csme");
}
}
} }
## hist. On-Stunden aller Tage aufnehmen ## hist. On-Stunden aller Tage aufnehmen
########################################## ##########################################
for my $h (1..24) { for my $h (1..24) { # excludieren ob exconfc 1 oder 2
my $hh = sprintf "%02d", $h; my $hh = sprintf "%02d", $h;
$csme = HistoryVal ($hash, $n, $hh, "csme${c}", 0); $csme = HistoryVal ($hash, $n, $hh, "csme${c}", 0);
@ -12247,32 +12290,92 @@ sub _calcConsumptionForecast_circular {
$usage{$hh}{histcon} += $csme; $usage{$hh}{histcon} += $csme;
$usage{$hh}{histnum}++; $usage{$hh}{histnum}++;
} }
if ($exconfc == 2 && $lap == 1) { # Planungsdaten des Consumers inkludieren
my $ehp = $data{$name}{consumers}{$c}{ehodpieces}{$hh};
if (defined $ehp) {
$usage{$hh}{plancon} += $ehp;
$usage{$hh}{plannum}++;
} }
} }
} }
} }
}
$lap++;
}
## effektiven StundenForecast berechnen
#########################################
debugLog ($paref, 'consumption|consumption_long', "################### Consumption forecast for the next Hours (new median) ###################");
for my $h (1..24) { for my $h (1..24) {
my $hh = sprintf "%02d", $h; my $hh = sprintf "%02d", $h;
if (defined $usage{$hh}{histnum}) { if (defined $usage{$hh}{histnum}) { # historische Stundenverbräuche exkludieren
my $exhcon = sprintf "%.0f", ($usage{$hh}{histcon} / $usage{$hh}{histnum}); # durchschnittlichen Verbrauchswert my $exhcon = sprintf "%.0f", ($usage{$hh}{histcon} / $usage{$hh}{histnum}); # durchschnittlichen Verbrauchswert
$usage{$hh}{con} -= $exhcon; $usage{$hh}{con} -= $exhcon;
debugLog ($paref, 'consumption|consumption_long', "excl. $exhcon Wh for Hour $hh, Considered value numbers: ".$usage{$hh}{histnum}); debugLog ($paref, 'consumption_long', "excl. hist $exhcon Wh for Hour $hh, Considered value numbers: ".$usage{$hh}{histnum});
}
$usage{$hh}{conex} = $usage{$hh}{con};
if (defined $usage{$hh}{plannum}) { # geplante Stundenverbräuche inkludieren
my $inhcon = sprintf "%.0f", ($usage{$hh}{plancon} / $usage{$hh}{plannum});
$usage{$hh}{con} += $inhcon;
debugLog ($paref, 'consumption_long', "incl. planned $inhcon Wh for Hour $hh, Considered value numbers: ".$usage{$hh}{plannum});
} }
debugLog ($paref, 'consumption|consumption_long', "estimated cons of Hour $hh: ".$usage{$hh}{con}." Wh, Considered value numbers: ".$usage{$hh}{num}); debugLog ($paref, 'consumption|consumption_long', "estimated cons of Hour $hh: ".$usage{$hh}{con}." Wh, Considered value numbers: ".$usage{$hh}{num});
} }
$ex = sprintf "%.0f", ($ex / $exnum) if($exnum); # Ex Tageswert Durchschnitt bilden ## nächsten Tageswert Excludes berücksichtigen
$usage{tom}{con} -= $ex; ################################################
my $tomnum = $usage{tom}{num} // 0;
debugLog ($paref, 'consumption|consumption_long', "estimated cons Tomorrow: ".$usage{tom}{con}." Wh, Considered value numbers: $tomnum, exclude: $ex Wh (avg of $exnum)"); debugLog ($paref, 'consumption|consumption_long', "################### Consumption forecast for the next day (new median) ###################");
if ($tomnum) {
if ($exnum) {
$ex = sprintf "%.0f", ($ex / $exnum); # Ex Tageswert Durchschnitt bilden
$usage{tom}{con} -= $ex;
}
$data{$name}{current}{tomorrowconsumption} = $usage{tom}{con};
debugLog ($paref, 'consumption|consumption_long', "estimated cons Tomorrow: ".$usage{tom}{con}." Wh, Individual hourly values considered: $tomnum, exclude: $ex Wh (avg of $exnum entities)");
} }
else { else {
my $lang = $paref->{lang}; my $lang = $paref->{lang};
# $data{$name}{current}{tomorrowconsumption} = $hqtxt{wfmdcf}{$lang}; $data{$name}{current}{tomorrowconsumption} = $hqtxt{wfmdcf}{$lang};
debugLog ($paref, 'consumption|consumption_long', "no estimated cons for Tomorrow: ".$hqtxt{wfmdcf}{$lang});
}
## Ergebnisse speichern
########################
debugLog ($paref, 'saveData2Cache|consumption_long', "################### Store Consumption forecast values (new median) ###################");
for my $k (sort keys %{$data{$name}{nexthours}}) {
my $nhst = NexthoursVal ($hash, $k, "starttime", undef); # Startzeit
next if(!$nhst);
my $utime = timestringToTimestamp ($nhst);
my $nhday = strftime "%a", localtime($utime); # Wochentagsname des NextHours Key
my $nhhr = sprintf "%02d", int (strftime "%H", localtime($utime)) + 1; # Stunde des Tages vom NextHours Key (01,02,...24)
$data{$name}{nexthours}{$k}{confcEx} = $usage{$nhhr}{conex};
$data{$name}{nexthours}{$k}{confc} = $usage{$nhhr}{con}; # prognostizierter Verbrauch (Median)
debugLog ($paref, 'saveData2Cache|consumption_long', "store '$k' hod '$nhhr' confc: $usage{$nhhr}{con}, confcEx: $usage{$nhhr}{conex}");
if (NexthoursVal ($hash, $k, 'today', 0)) { # nur Werte des aktuellen Tags speichern
$data{$name}{circular}{$nhhr}{confc} = $usage{$nhhr}{con};
writeToHistory ( { paref => $paref, key => 'confc', val => $usage{$nhhr}{con}, hour => $nhhr } );
debugLog ($paref, 'saveData2Cache|consumption_long', "store circular/history hod '$nhhr' confc: $usage{$nhhr}{con}");
}
} }
return; return;
@ -12670,6 +12773,8 @@ sub _addCon2CircArray {
push @{$data{$name}{circular}{$hh}{con_all}{"$dayname"}}, $con if($con >= 0); # Wert zum Speicherarray hinzufügen push @{$data{$name}{circular}{$hh}{con_all}{"$dayname"}}, $con if($con >= 0); # Wert zum Speicherarray hinzufügen
limitArray ($data{$name}{circular}{$hh}{con_all}{"$dayname"}, CONDAYSLIDEMAX);
debugLog ($paref, 'saveData2Cache', "add consumption into Array (con_all) in Circular - day: $day, hod: $hh, con: $con"); debugLog ($paref, 'saveData2Cache', "add consumption into Array (con_all) in Circular - day: $day, hod: $hh, con: $con");
return; return;
@ -12846,6 +12951,9 @@ sub _saveEnergyConsumption {
if ($dowrite) { if ($dowrite) {
writeToHistory ( { paref => $paref, key => 'con', val => $con, hour => $hod } ); writeToHistory ( { paref => $paref, key => 'con', val => $con, hour => $hod } );
$data{$name}{circular}{99}{todayConsumption} = HistoryVal ($name, $day, '99', 'con', undef); $data{$name}{circular}{99}{todayConsumption} = HistoryVal ($name, $day, '99', 'con', undef);
debugLog ($paref, 'consumption', "consumption calculated - day: $day, hod: $hod, con: $con Wh");
debugLog ($paref, 'saveData2Cache|consumption', "write pvCircular consumption - hod: 99, todayConsumption: ".HistoryVal ($name, $day, '99', 'con', 'undef')." Wh");
} }
return; return;
@ -12946,7 +13054,7 @@ sub _genSpecialReadings {
my $dgcon = $cgcon - $idgcon; my $dgcon = $cgcon - $idgcon;
storeReading ($prpo.'_'.$kpi, (sprintf "%.1f", $dgcon).' Wh'); storeReading ($prpo.'_'.$kpi, (sprintf "%.0f", $dgcon).' Wh');
} }
if ($kpi eq 'todayBatInSum') { # Summe tägl. Ladeenergie (alle Batterien) if ($kpi eq 'todayBatInSum') { # Summe tägl. Ladeenergie (alle Batterien)
@ -13644,10 +13752,16 @@ sub _graphicHeader {
## Message-Icon ## Message-Icon
################# #################
my $tfl = $data{$name}{messages}{999000}{TS} ?
(timestampToTimestring ($data{$name}{messages}{999000}{TS}, $lang))[0] :
'n.a.';
my $tfn = $data{$name}{messages}{999000}{TSNEXT} ?
(timestampToTimestring ($data{$name}{messages}{999000}{TSNEXT}, $lang))[0] :
'n.a.';
my ($micon, $midx) = fillupMessageSystem ($paref); my ($micon, $midx) = fillupMessageSystem ($paref);
$img = FW_makeImage ($micon); $img = FW_makeImage ($micon);
my $msgicon = $midx ? "<a onClick=$cmdoutmsg>$img</a>" : $img; my $msgicon = $midx ? "<a onClick=$cmdoutmsg>$img</a>" : $img;
my $msgtitle = $midx ? $htitles{outpmsg}{$lang} : $htitles{nomsgfo}{$lang}; my $msgtitle = $midx ? $htitles{outpmsg}{$lang} : $htitles{nomsgfo}{$lang}."\n\n$htitles{lstmsgc}{$lang}: $tfl \n$htitles{nxtmsgc}{$lang}: $tfn";
## Update-Icon ## Update-Icon
################ ################
@ -18414,11 +18528,11 @@ sub _listDataPoolNextHours {
$sq .= $idx." => "; $sq .= $idx." => ";
$sq .= "starttime: $nhts, hourofday: $hod, today: $today"; $sq .= "starttime: $nhts, hourofday: $hod, today: $today";
$sq .= "\n "; $sq .= "\n ";
$sq .= "pvapifc: $pvapifc, pvaifc: $pvaifc, pvfc: $pvfc, aihit: $aihit, confc: $confc"; $sq .= "pvapifc: $pvapifc, pvaifc: $pvaifc, pvfc: $pvfc, aihit: $aihit";
$sq .= "\n "; $sq .= "\n ";
$sq .= "confcEx: $confcex, DoN: $don, weatherid: $wid, wcc: $wcc, rr1c: $rr1c, temp=$temp"; $sq .= "confc: $confc, confcEx: $confcex, weatherid: $wid, wcc: $wcc, rr1c: $rr1c, temp=$temp";
$sq .= "\n "; $sq .= "\n ";
$sq .= "rad1h: $rad1h, sunaz: $sunaz, sunalt: $sunalt"; $sq .= "rad1h: $rad1h, sunaz: $sunaz, sunalt: $sunalt, DoN: $don";
$sq .= "\n "; $sq .= "\n ";
$sq .= "rrange: $rrange, crange: $crang, correff: $pvcorrf"; $sq .= "rrange: $rrange, crange: $crang, correff: $pvcorrf";
$sq .= "\n "; $sq .= "\n ";
@ -18755,6 +18869,7 @@ sub checkPlantConfig {
'Common Settings' => { 'state' => $ok, 'result' => '', 'note' => '', 'info' => 0, 'warn' => 0, 'fault' => 0 }, 'Common Settings' => { 'state' => $ok, 'result' => '', 'note' => '', 'info' => 0, 'warn' => 0, 'fault' => 0 },
'FTUI Widget Files' => { 'state' => $ok, 'result' => '', 'note' => '', 'info' => 0, 'warn' => 0, 'fault' => 0 }, 'FTUI Widget Files' => { 'state' => $ok, 'result' => '', 'note' => '', 'info' => 0, 'warn' => 0, 'fault' => 0 },
'Perl Modules' => { 'state' => $ok, 'result' => '', 'note' => '', 'info' => 0, 'warn' => 0, 'fault' => 0 }, 'Perl Modules' => { 'state' => $ok, 'result' => '', 'note' => '', 'info' => 0, 'warn' => 0, 'fault' => 0 },
'Data Memory' => { 'state' => $ok, 'result' => '', 'note' => '', 'info' => 0, 'warn' => 0, 'fault' => 0 },
}; };
my $sub = sub { my $sub = sub {
@ -19238,7 +19353,33 @@ sub checkPlantConfig {
$result->{'Perl Modules'}{note} .= qq{AI::DecisionTree <br>}; $result->{'Perl Modules'}{note} .= qq{AI::DecisionTree <br>};
} }
## Datenspeicher Check
########################
my $confault = 0;
for my $dy (sort{$a<=>$b} keys %{$data{$name}{pvhist}}) {
for my $hh (sort{$a<=>$b} keys %{$data{$name}{pvhist}{$dy}}) {
my $hcon = HistoryVal ($hash, $dy, $hh, 'con', 0); # historische Verbrauchswerte
if ($hcon < 0) { # V1.45.7
$confault++;
Log3 ($name, 1, "$name - WARNING - The stored Energy consumption of day/hour $dy/$hh is negative. This appears to be an error. The incorrect value can be deleted with 'set $name reset consumption $dy $hh'.");
}
}
}
if ($confault) {
$result->{'Data Memory'}{state} = $warn;
$result->{'Data Memory'}{result} .= qq{There may be '$confault' incorrect value(s) in the 'con' key of the pvHistory Storage. <br>};
$result->{'Data Memory'}{note} .= qq{See Logfile for detailed information and how these value(s) could be corrected. <br>};
$result->{'Data Memory'}{warn} = 1;
}
if (!$result->{'Data Memory'}{info} && !$result->{'Data Memory'}{warn} && !$result->{'Data Memory'}{fault}) {
$result->{'Data Memory'}{result} .= $hqtxt{fulfd}{$lang}.'<br>';
$result->{'Data Memory'}{note} .= qq{<br>checked Data Memory: <br>};
$result->{'Data Memory'}{note} .= qq{pvHistory key 'con' <br>};
}
## FTUI Widget Support ## FTUI Widget Support
######################## ########################
@ -20268,7 +20409,7 @@ sub isAddSwitchOffCond {
if (defined $condval) { if (defined $condval) {
if ($condval =~ m/^$swoffcondregex$/x) { if ($condval =~ m/^$swoffcondregex$/x) {
$info = qq{value "$condval" matches the Regex "$swoffcondregex" \n}; $info = qq{value "$condval" matches the Regex "$swoffcondregex" \n};
$info .= "-> !Interrupt! "; $info .= "-> Check successful ";
$swoff = 1; $swoff = 1;
} }
else { else {
@ -20281,7 +20422,7 @@ sub isAddSwitchOffCond {
if ($condval =~ m/^$swoffcondregex$/x) { if ($condval =~ m/^$swoffcondregex$/x) {
$info = qq{value "$condval" (included hysteresis = $hyst) matches the Regex "$swoffcondregex" \n}; $info = qq{value "$condval" (included hysteresis = $hyst) matches the Regex "$swoffcondregex" \n};
$info .= "-> !Interrupt! "; $info .= "-> Check successful ";
$swoff = 1; $swoff = 1;
} }
else { else {
@ -20440,11 +20581,11 @@ sub isInterruptable {
return 1; return 1;
} }
my $debug = getDebug ($hash); # Debug Module
my ($swoffcond,$info,$err) = isAddSwitchOffCond ($hash, $c, $intable, $hyst); my ($swoffcond,$info,$err) = isAddSwitchOffCond ($hash, $c, $intable, $hyst);
Log3 ($name, 1, "$name - $err") if($err); Log3 ($name, 1, "$name - $err") if($err);
my $debug = getDebug ($hash); # Debug Module
if ($print && $debug =~ /consumerSwitching${c}/x) { if ($print && $debug =~ /consumerSwitching${c}/x) {
Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - Interrupt Info: $info}); Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - Interrupt Info: $info});
} }
@ -21108,43 +21249,43 @@ sub cloud2bin {
my $bin = $val == 100 ? '100' : my $bin = $val == 100 ? '100' :
$val > 97 ? '100' : $val > 97 ? '100' :
$val > 95 ? '95' : $val >= 95 ? '95' :
$val > 92 ? '95' : $val > 92 ? '95' :
$val > 90 ? '90' : $val >= 90 ? '90' :
$val > 87 ? '90' : $val > 87 ? '90' :
$val > 85 ? '85' : $val >= 85 ? '85' :
$val > 82 ? '85' : $val > 82 ? '85' :
$val > 80 ? '80' : $val >= 80 ? '80' :
$val > 77 ? '80' : $val > 77 ? '80' :
$val > 75 ? '75' : $val >= 75 ? '75' :
$val > 72 ? '75' : $val > 72 ? '75' :
$val > 70 ? '70' : $val >= 70 ? '70' :
$val > 67 ? '70' : $val > 67 ? '70' :
$val > 65 ? '65' : $val >= 65 ? '65' :
$val > 62 ? '65' : $val > 62 ? '65' :
$val > 60 ? '60' : $val >= 60 ? '60' :
$val > 57 ? '60' : $val > 57 ? '60' :
$val > 55 ? '55' : $val >= 55 ? '55' :
$val > 52 ? '55' : $val > 52 ? '55' :
$val > 50 ? '50' : $val >= 50 ? '50' :
$val > 47 ? '50' : $val > 47 ? '50' :
$val > 45 ? '45' : $val >= 45 ? '45' :
$val > 42 ? '45' : $val > 42 ? '45' :
$val > 40 ? '40' : $val >= 40 ? '40' :
$val > 37 ? '40' : $val > 37 ? '40' :
$val > 35 ? '35' : $val >= 35 ? '35' :
$val > 32 ? '35' : $val > 32 ? '35' :
$val > 30 ? '30' : $val >= 30 ? '30' :
$val > 27 ? '30' : $val > 27 ? '30' :
$val > 25 ? '25' : $val >= 25 ? '25' :
$val > 22 ? '25' : $val > 22 ? '25' :
$val > 20 ? '20' : $val >= 20 ? '20' :
$val > 17 ? '20' : $val > 17 ? '20' :
$val > 15 ? '15' : $val >= 15 ? '15' :
$val > 12 ? '15' : $val > 12 ? '15' :
$val > 10 ? '10' : $val >= 10 ? '10' :
$val > 7 ? '10' : $val > 7 ? '10' :
$val > 5 ? '05' : $val >= 5 ? '05' :
$val > 2 ? '05' : $val > 2 ? '05' :
'00'; '00';
@ -21159,39 +21300,39 @@ sub sunalt2bin {
my $bin = $val == 90 ? 90 : my $bin = $val == 90 ? 90 :
$val > 87 ? 90 : $val > 87 ? 90 :
$val > 85 ? 85 : $val >= 85 ? 85 :
$val > 82 ? 85 : $val > 82 ? 85 :
$val > 80 ? 80 : $val >= 80 ? 80 :
$val > 77 ? 80 : $val > 77 ? 80 :
$val > 75 ? 75 : $val >= 75 ? 75 :
$val > 72 ? 75 : $val > 72 ? 75 :
$val > 70 ? 70 : $val >= 70 ? 70 :
$val > 67 ? 70 : $val > 67 ? 70 :
$val > 65 ? 65 : $val >= 65 ? 65 :
$val > 62 ? 65 : $val > 62 ? 65 :
$val > 60 ? 60 : $val >= 60 ? 60 :
$val > 57 ? 60 : $val > 57 ? 60 :
$val > 55 ? 55 : $val >= 55 ? 55 :
$val > 52 ? 55 : $val > 52 ? 55 :
$val > 50 ? 50 : $val >= 50 ? 50 :
$val > 47 ? 50 : $val > 47 ? 50 :
$val > 45 ? 45 : $val >= 45 ? 45 :
$val > 42 ? 45 : $val > 42 ? 45 :
$val > 40 ? 40 : $val >= 40 ? 40 :
$val > 37 ? 40 : $val > 37 ? 40 :
$val > 35 ? 35 : $val >= 35 ? 35 :
$val > 32 ? 35 : $val > 32 ? 35 :
$val > 30 ? 30 : $val >= 30 ? 30 :
$val > 27 ? 30 : $val > 27 ? 30 :
$val > 25 ? 25 : $val >= 25 ? 25 :
$val > 22 ? 25 : $val > 22 ? 25 :
$val > 20 ? 20 : $val >= 20 ? 20 :
$val > 17 ? 20 : $val > 17 ? 20 :
$val > 15 ? 15 : $val >= 15 ? 15 :
$val > 12 ? 15 : $val > 12 ? 15 :
$val > 10 ? 10 : $val >= 10 ? 10 :
$val > 7 ? 10 : $val > 7 ? 10 :
$val > 5 ? 5 : $val >= 5 ? 5 :
$val > 2 ? 5 : $val > 2 ? 5 :
0; 0;
@ -22578,11 +22719,11 @@ to ensure that the system configuration is correct.
<tr><td> </td><td>The defined consumer attributes remain and the data is collected again. </td></tr> <tr><td> </td><td>The defined consumer attributes remain and the data is collected again. </td></tr>
<tr><td> </td><td>To delete the data of only one consumer use: </td></tr> <tr><td> </td><td>To delete the data of only one consumer use: </td></tr>
<tr><td> </td><td><ul>set &lt;name&gt; reset consumerMaster &lt;Consumer number&gt; </ul> </td></tr> <tr><td> </td><td><ul>set &lt;name&gt; reset consumerMaster &lt;Consumer number&gt; </ul> </td></tr>
<tr><td> <b>consumption</b> </td><td>deletes the stored consumption values of the house </td></tr> <tr><td> <b>consumptionHistory</b> </td><td>deletes the stored consumption values of the house from the pvHistory memory </td></tr>
<tr><td> </td><td>To delete the consumption values of a specific day: </td></tr> <tr><td> </td><td>To delete the consumption values of a specific day: </td></tr>
<tr><td> </td><td><ul>set &lt;name&gt; reset consumption &lt;Day&gt; (e.g. set &lt;name&gt; reset consumption 08) </ul> </td></tr> <tr><td> </td><td><ul>set &lt;name&gt; reset consumptionHistory &lt;Day&gt; (e.g. set &lt;name&gt; reset consumptionHistory 08) </ul> </td></tr>
<tr><td> </td><td>To delete the consumption values of a specific hour of a day: </td></tr> <tr><td> </td><td>To delete the consumption values of a specific hour of a day: </td></tr>
<tr><td> </td><td><ul>set &lt;name&gt; reset consumption &lt;Day&gt; &lt;Hour&gt; (e.g. set &lt;name&gt; reset consumption 08 10) </ul> </td></tr> <tr><td> </td><td><ul>set &lt;name&gt; reset consumptionHistory &lt;Day&gt; &lt;Hour&gt; (e.g. set &lt;name&gt; reset consumptionHistory 08 10) </ul> </td></tr>
<tr><td> <b>energyH4TriggerSet</b> </td><td>deletes the 4-hour energy trigger points </td></tr> <tr><td> <b>energyH4TriggerSet</b> </td><td>deletes the 4-hour energy trigger points </td></tr>
<tr><td> <b>powerTriggerSet</b> </td><td>deletes the trigger points for PV generation values </td></tr> <tr><td> <b>powerTriggerSet</b> </td><td>deletes the trigger points for PV generation values </td></tr>
<tr><td> <b>pvCorrection</b> </td><td>deletes the readings pvCorrectionFactor* </td></tr> <tr><td> <b>pvCorrection</b> </td><td>deletes the readings pvCorrectionFactor* </td></tr>
@ -23155,22 +23296,26 @@ to ensure that the system configuration is correct.
<a id="SolarForecast-attr-affectConsForecastIdentWeekdays"></a> <a id="SolarForecast-attr-affectConsForecastIdentWeekdays"></a>
<li><b>affectConsForecastIdentWeekdays </b><br> <li><b>affectConsForecastIdentWeekdays </b><br>
If set, only the same weekdays (Mon..Sun) are included in the calculation of the consumption forecast. <br> If set, only the same weekdays (Mon..Sun) are included in the calculation of the consumption forecast. <br>
Otherwise, all weekdays are used equally for calculation. <br> Otherwise, all weekdays are used equally for the calculation. <br>
Any additional attribute The number of weekdays included is determined by the attribute
<a href="#SolarForecast-attr-affectConsForecastLastDays">affectConsForecastLastDays</a> <a href="#SolarForecast-attr-affectConsForecastLastDays">affectConsForecastLastDays</a>. <br>
is also taken into account. <br>
(default: 0) (default: 0)
</li> </li>
<br> <br>
<a id="SolarForecast-attr-affectConsForecastLastDays"></a> <a id="SolarForecast-attr-affectConsForecastLastDays"></a>
<li><b>affectConsForecastLastDays </b><br> <li><b>affectConsForecastLastDays </b><br>
The specified past days (1..31) are included in the calculation of the consumption forecast. <br> The specified number of historical daily values is included in the calculation of the consumption forecast. <br>
For example, with the attribute value 1 only the previous day is taken into account, with the value 14 the previous 14 days. <br> For example, with the attribute value 1 only the previous day is taken into account, with the value 14 the previous 14 days. <br>
If an additional attribute The days actually taken into account may be less than specified if there are not enough values in the internal memory
are available. <br>
(default: 60) <br><br>
<b>Note:</b> With an additionally set attribute
<a href="#SolarForecast-attr-affectConsForecastIdentWeekdays">affectConsForecastIdentWeekdays</a> <a href="#SolarForecast-attr-affectConsForecastIdentWeekdays">affectConsForecastIdentWeekdays</a>
is set, the specified number of past weekdays of the same type (Mon .. Sun) is taken into account. <br> the specified number of past weekdays of the same type (Mon .. Sun) is taken into account. <br>
(default: all days available in pvHistory) In this case, if a value of 8 is set, the same weekdays of the past 8 weeks are taken into account.
are taken into account. <br>
</li> </li>
<br> <br>
@ -23395,9 +23540,10 @@ to ensure that the system configuration is correct.
<tr><td> </td><td>If the reading has the value 0 or is not present, the consumer is displayed. </td></tr> <tr><td> </td><td>If the reading has the value 0 or is not present, the consumer is displayed. </td></tr>
<tr><td> </td><td>The effect of the possible reading values 1, 2 and 3 is as described. </td></tr> <tr><td> </td><td>The effect of the possible reading values 1, 2 and 3 is as described. </td></tr>
<tr><td> </td><td> </td></tr> <tr><td> </td><td> </td></tr>
<tr><td> <b>exconfc</b> </td><td>Use of the consumer's recorded energy consumption to create the consumption forecast (optional). </td></tr> <tr><td> <b>exconfc</b> </td><td>Indicator for using the historical energy consumption of the consumer (optional). </td></tr>
<tr><td> </td><td><b>0</b> - the consumer's historical energy consumption is used to create the consumption forecast (default) </td></tr> <tr><td> </td><td><b>0</b> - the stored energy consumption shares are retained as part of the general consumption forecast (default) </td></tr>
<tr><td> </td><td><b>1</b> - the consumer's historical energy consumption is excluded from the consumption forecast. </td></tr> <tr><td> </td><td><b>1</b> - the general consumption forecast is reduced by the stored energy consumption shares. </td></tr>
<tr><td> </td><td><b>2</b> - as with '1', but the consumer's planning data is included in the forecast for the coming hours. </td></tr>
</table> </table>
</ul> </ul>
<br> <br>
@ -25066,11 +25212,11 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<tr><td> </td><td>Die definierten Consumer Attribute bleiben bestehen und die Daten werden neu gesammelt. </td></tr> <tr><td> </td><td>Die definierten Consumer Attribute bleiben bestehen und die Daten werden neu gesammelt. </td></tr>
<tr><td> </td><td>Um die Daten nur eines Verbrauchers zu löschen verwendet man: </td></tr> <tr><td> </td><td>Um die Daten nur eines Verbrauchers zu löschen verwendet man: </td></tr>
<tr><td> </td><td><ul>set &lt;name&gt; reset consumerMaster &lt;Verbrauchernummer&gt; </ul> </td></tr> <tr><td> </td><td><ul>set &lt;name&gt; reset consumerMaster &lt;Verbrauchernummer&gt; </ul> </td></tr>
<tr><td> <b>consumption</b> </td><td>löscht die gespeicherten Verbrauchswerte des Hauses </td></tr> <tr><td> <b>consumptionHistory</b> </td><td>löscht die gespeicherten Verbrauchswerte des Hauses aus dem pvHistory Speicher </td></tr>
<tr><td> </td><td>Um die Verbrauchswerte eines bestimmten Tages zu löschen: </td></tr> <tr><td> </td><td>Um die Verbrauchswerte eines bestimmten Tages zu löschen: </td></tr>
<tr><td> </td><td><ul>set &lt;name&gt; reset consumption &lt;Tag&gt; (z.B. set &lt;name&gt; reset consumption 08) </ul> </td></tr> <tr><td> </td><td><ul>set &lt;name&gt; reset consumptionHistory &lt;Tag&gt; (z.B. set &lt;name&gt; reset consumptionHistory 08) </ul> </td></tr>
<tr><td> </td><td>Um die Verbrauchswerte einer bestimmten Stunde eines Tages zu löschen: </td></tr> <tr><td> </td><td>Um die Verbrauchswerte einer bestimmten Stunde eines Tages zu löschen: </td></tr>
<tr><td> </td><td><ul>set &lt;name&gt; reset consumption &lt;Tag&gt; &lt;Stunde&gt; (z.B. set &lt;name&gt; reset consumption 08 10) </ul> </td></tr> <tr><td> </td><td><ul>set &lt;name&gt; reset consumptionHistory &lt;Tag&gt; &lt;Stunde&gt; (z.B. set &lt;name&gt; reset consumptionHistory 08 10) </ul> </td></tr>
<tr><td> <b>energyH4TriggerSet</b> </td><td>löscht die 4-Stunden Energie Triggerpunkte </td></tr> <tr><td> <b>energyH4TriggerSet</b> </td><td>löscht die 4-Stunden Energie Triggerpunkte </td></tr>
<tr><td> <b>powerTriggerSet</b> </td><td>löscht die Triggerpunkte für PV Erzeugungswerte </td></tr> <tr><td> <b>powerTriggerSet</b> </td><td>löscht die Triggerpunkte für PV Erzeugungswerte </td></tr>
<tr><td> <b>pvCorrection</b> </td><td>löscht die Readings pvCorrectionFactor* </td></tr> <tr><td> <b>pvCorrection</b> </td><td>löscht die Readings pvCorrectionFactor* </td></tr>
@ -25643,21 +25789,26 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<li><b>affectConsForecastIdentWeekdays </b><br> <li><b>affectConsForecastIdentWeekdays </b><br>
Wenn gesetzt, werden zur Berechnung der Verbrauchsprognose nur gleiche Wochentage (Mo..So) einbezogen. <br> Wenn gesetzt, werden zur Berechnung der Verbrauchsprognose nur gleiche Wochentage (Mo..So) einbezogen. <br>
Anderenfalls werden alle Wochentage gleichberechtigt zur Kalkulation verwendet. <br> Anderenfalls werden alle Wochentage gleichberechtigt zur Kalkulation verwendet. <br>
Ein eventuell zusätzlich gesetztes Attribut Die Anzahl der einbezogenen Wochentage wird durch das Attribut
<a href="#SolarForecast-attr-affectConsForecastLastDays">affectConsForecastLastDays</a> <a href="#SolarForecast-attr-affectConsForecastLastDays">affectConsForecastLastDays</a>
wird gleichfalls berücksichtigt. <br> bestimmt. <br>
(default: 0) (default: 0)
</li> </li>
<br> <br>
<a id="SolarForecast-attr-affectConsForecastLastDays"></a> <a id="SolarForecast-attr-affectConsForecastLastDays"></a>
<li><b>affectConsForecastLastDays </b><br> <li><b>affectConsForecastLastDays </b><br>
Es werden die angegebenen vergangenen Tage (1..31) bei der Berechnung der Verbrauchsprognose einbezogen. <br> Es wird die angegebene Anzahl historischer Tageswerte bei der Berechnung der Verbrauchsprognose einbezogen. <br>
So wird z.B. mit dem Attributwert "1" nur der vorangegangene Tag berücksichtigt, mit dem Wert "14" die vergangenen 14 Tage. <br> So wird z.B. mit dem Attributwert "1" nur der vorangegangene Tag berücksichtigt, mit dem Wert "14" die vergangenen 14 Tage. <br>
Bei einem zusätzlich gesetzten Attribut Die tatsächlich berücksichtigten Tage können geringer als angegeben sein wenn noch nicht genügend Werte im internen Speicher
vorhanden sind. <br>
(default: 60) <br><br>
<b>Hinweis:</b> Bei einem zusätzlich gesetzten Attribut
<a href="#SolarForecast-attr-affectConsForecastIdentWeekdays">affectConsForecastIdentWeekdays</a> <a href="#SolarForecast-attr-affectConsForecastIdentWeekdays">affectConsForecastIdentWeekdays</a>
wird die angegebene Anzahl vergangener gleicher Wochentage (Mo .. So) berücksichtigt. <br> wird die angegebene Anzahl vergangener gleicher Wochentage (Mo .. So) berücksichtigt. <br>
(default: alle in pvHistory vorhandenen Tage) In diesem Fall werden bei einem gesetzten Wert von "8" die gleichen Wochentage der vergangenen 8 Wochen
berücksichtigt. <br>
</li> </li>
<br> <br>
@ -25881,9 +26032,10 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<tr><td> </td><td>Hat das Reading den Wert 0 oder ist nicht vorhanden, wird der Verbraucher eingeblendet. </td></tr> <tr><td> </td><td>Hat das Reading den Wert 0 oder ist nicht vorhanden, wird der Verbraucher eingeblendet. </td></tr>
<tr><td> </td><td>Die Wirkung der möglichen Readingwerte 1, 2 und 3 ist wie beschrieben. </td></tr> <tr><td> </td><td>Die Wirkung der möglichen Readingwerte 1, 2 und 3 ist wie beschrieben. </td></tr>
<tr><td> </td><td> </td></tr> <tr><td> </td><td> </td></tr>
<tr><td> <b>exconfc</b> </td><td>Verwendung des aufgezeichneten Energieverbrauchs des Verbrauchers zur Erstellung der Verbrauchsprognose (optional). </td></tr> <tr><td> <b>exconfc</b> </td><td>Kennzeichen zur Verwendung des historischen Energieverbrauchs des Verbrauchers (optional). </td></tr>
<tr><td> </td><td><b>0</b> - der historische Energieverbrauch des Verbrauchers wird zur Erstellung der Verbrauchsprognose verwendet (default) </td></tr> <tr><td> </td><td><b>0</b> - die gespeicherten Energieverbrauchsanteile bleiben als Bestandteil der allgemeinen Verbrauchsprognose erhalten (default) </td></tr>
<tr><td> </td><td><b>1</b> - der historische Energieverbrauch des Verbrauchers wird von der Verbrauchsprognose ausgeschlossen. </td></tr> <tr><td> </td><td><b>1</b> - die allgemeine Verbrauchsprognose wird um die gespeicherten Energieverbrauchsanteile reduziert. </td></tr>
<tr><td> </td><td><b>2</b> - wie bei '1', jedoch gehen die Planungsdaten des Verbrauchers bei der Prognose der kommenden Stunden wieder mit ein. </td></tr>
</table> </table>
</ul> </ul>
<br> <br>