2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 06:39:11 +00:00

76_SolarForecast: attr setupInverterDevXX: new key 'limit', the key 'capacity' is now mandatory! Attr affect70percentRule, ctrlAutoRefresh, ctrlAutoRefreshFW are deleted

git-svn-id: https://svn.fhem.de/fhem/trunk@29321 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2024-10-31 20:25:29 +00:00
parent d242102fc1
commit e325f514e6
2 changed files with 146 additions and 176 deletions

View File

@ -1,5 +1,8 @@
# 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
- change: 76_SolarForecast: attr setupInverterDevXX: new key 'limit',
the key 'capacity' is now mandatory! Attr affect70percentRule,
ctrlAutoRefresh, ctrlAutoRefreshFW are deleted
- feature: 36_Shelly: add Shelly Plug S MTR Gen3 - feature: 36_Shelly: add Shelly Plug S MTR Gen3
- change: 76_SolarForecast: Attr graphicStartHtml, graphicEndHtml removed - change: 76_SolarForecast: Attr graphicStartHtml, graphicEndHtml removed
- feature: 49_SSCam: Compatibility (Snapshot API) to SVS version >= 9.2.1 - feature: 49_SSCam: Compatibility (Snapshot API) to SVS version >= 9.2.1

View File

@ -156,6 +156,8 @@ BEGIN {
# Versions History intern # Versions History intern
my %vNotesIntern = ( my %vNotesIntern = (
"1.37.5" => "31.10.2024 attr setupInverterDevXX: new key 'limit', the key 'capacity' is now mandatory ".
"Attr affect70percentRule, ctrlAutoRefresh, ctrlAutoRefreshFW deleted ",
"1.37.4" => "29.10.2024 both attr graphicStartHtml, graphicEndHtml removed, fix flowGraphic when device name contains '.' ", "1.37.4" => "29.10.2024 both attr graphicStartHtml, graphicEndHtml removed, fix flowGraphic when device name contains '.' ",
"1.37.3" => "25.10.2024 _flowGraphic: grid, dummy and battery displacement by kask ". "1.37.3" => "25.10.2024 _flowGraphic: grid, dummy and battery displacement by kask ".
"Attr flowGraphicControl: new key h2consumerdist, animate=1 is default now ", "Attr flowGraphicControl: new key h2consumerdist, animate=1 is default now ",
@ -493,10 +495,10 @@ my @rconfigs = qw( pvCorrectionFactor_Auto
energyH4Trigger energyH4Trigger
); );
# Anlagenkonfiguration: maßgebliche Attribute # Anlagenkonfiguration: maßgebliche Attribute
my @aconfigs = qw( affect70percentRule affectBatteryPreferredCharge affectConsForecastIdentWeekdays my @aconfigs = qw( affectBatteryPreferredCharge affectConsForecastIdentWeekdays
affectConsForecastInPlanning affectSolCastPercentile affectConsForecastInPlanning affectSolCastPercentile
consumerLegend consumerAdviceIcon consumerLink consumerLegend consumerAdviceIcon consumerLink
ctrlAIdataStorageDuration ctrlAutoRefresh ctrlAutoRefreshFW ctrlBackupFilesKeep ctrlAIdataStorageDuration ctrlBackupFilesKeep
ctrlBatSocManagement ctrlConsRecommendReadings ctrlGenPVdeviation ctrlInterval ctrlBatSocManagement ctrlConsRecommendReadings ctrlGenPVdeviation ctrlInterval
ctrlLanguage ctrlNextDayForecastReadings ctrlShowLink ctrlSolCastAPImaxReq ctrlLanguage ctrlNextDayForecastReadings ctrlShowLink ctrlSolCastAPImaxReq
ctrlSolCastAPIoptimizeReq ctrlStatisticReadings ctrlUserExitFn ctrlSolCastAPIoptimizeReq ctrlStatisticReadings ctrlUserExitFn
@ -1164,7 +1166,6 @@ my %hfspvh = (
sub Initialize { sub Initialize {
my $hash = shift; my $hash = shift;
my $fwd = join ",", devspec2array("TYPE=FHEMWEB:FILTER=STATE=Initialized");
my $hod = join ",", map { sprintf "%02d", $_} (1..24); my $hod = join ",", map { sprintf "%02d", $_} (1..24);
my $srd = join ",", sort keys (%hcsr); my $srd = join ",", sort keys (%hcsr);
my $gbc = 'pvReal,pvForecast,consumption,consumptionForecast,gridconsumption,energycosts,gridfeedin,feedincome'; my $gbc = 'pvReal,pvForecast,consumption,consumptionForecast,gridconsumption,energycosts,gridfeedin,feedincome';
@ -1202,8 +1203,7 @@ sub Initialize {
$hash->{AttrFn} = \&Attr; $hash->{AttrFn} = \&Attr;
$hash->{NotifyFn} = \&Notify; $hash->{NotifyFn} = \&Notify;
$hash->{ReadyFn} = \&runTask; $hash->{ReadyFn} = \&runTask;
$hash->{AttrList} = "affect70percentRule:1,dynamic,0 ". $hash->{AttrList} = "affectBatteryPreferredCharge:slider,0,1,100 ".
"affectBatteryPreferredCharge:slider,0,1,100 ".
"affectConsForecastIdentWeekdays:1,0 ". "affectConsForecastIdentWeekdays:1,0 ".
"affectConsForecastInPlanning:1,0 ". "affectConsForecastInPlanning:1,0 ".
"affectConsForecastLastDays:slider,1,1,31 ". "affectConsForecastLastDays:slider,1,1,31 ".
@ -1213,12 +1213,10 @@ sub Initialize {
"consumerLink:0,1 ". "consumerLink:0,1 ".
"ctrlAIdataStorageDuration ". "ctrlAIdataStorageDuration ".
"ctrlAIshiftTrainStart:slider,1,1,23 ". "ctrlAIshiftTrainStart:slider,1,1,23 ".
"ctrlAutoRefresh:selectnumbers,120,0.2,1800,0,log10 ".
"ctrlAutoRefreshFW:$fwd ".
"ctrlBackupFilesKeep ". "ctrlBackupFilesKeep ".
"ctrlBatSocManagement:textField-long ". "ctrlBatSocManagement:textField-long ".
"ctrlConsRecommendReadings:multiple-strict,$allcs ". "ctrlConsRecommendReadings:multiple-strict,$allcs ".
"ctrlDebug:multiple-strict,$dm,#14 ". "ctrlDebug:multiple-strict,$dm,#10 ".
"ctrlAreaFactorUsage:fix,trackFull,trackShared,trackFlex ". "ctrlAreaFactorUsage:fix,trackFull,trackShared,trackFlex ".
"ctrlGenPVdeviation:daily,continuously ". "ctrlGenPVdeviation:daily,continuously ".
"ctrlInterval ". "ctrlInterval ".
@ -1282,6 +1280,8 @@ sub Initialize {
my $av = 'obsolete#-#use#attr#flowGraphicControl#instead'; my $av = 'obsolete#-#use#attr#flowGraphicControl#instead';
$hash->{AttrList} .= " flowGraphicCss:$av flowGraphicSize:$av flowGraphicAnimate:$av flowGraphicConsumerDistance:$av flowGraphicShowConsumer:$av flowGraphicShowConsumerDummy:$av flowGraphicShowConsumerPower:$av flowGraphicShowConsumerRemainTime:$av flowGraphicShift:$av "; $hash->{AttrList} .= " flowGraphicCss:$av flowGraphicSize:$av flowGraphicAnimate:$av flowGraphicConsumerDistance:$av flowGraphicShowConsumer:$av flowGraphicShowConsumerDummy:$av flowGraphicShowConsumerPower:$av flowGraphicShowConsumerRemainTime:$av flowGraphicShift:$av ";
my $av1 = "obsolete#-#the#attribute#will#be#deleted#soon";
$hash->{AttrList} .= " affect70percentRule:$av1 ctrlAutoRefresh:$av1 ctrlAutoRefreshFW:$av1 ";
########################################################################################################################## ##########################################################################################################################
$hash->{FW_hideDisplayName} = 1; # Forum 88667 $hash->{FW_hideDisplayName} = 1; # Forum 88667
@ -5329,13 +5329,16 @@ sub Attr {
return qq{The attribute '$aName' is obsolete and replaced by 'flowGraphicControl'.}; return qq{The attribute '$aName' is obsolete and replaced by 'flowGraphicControl'.};
} }
} }
# 29.10.2024 # 31.10.2024
if ($cmd eq 'set' && $aName =~ /^graphicStartHtml|graphicEndHtml$/) { if ($cmd eq 'set' && $aName =~ /^graphicStartHtml|affect70percentRule|graphicEndHtml|ctrlAutoRefresh|ctrlAutoRefreshFW$/) {
if (!$init_done) { if (!$init_done) {
my $msg = "The attribute $aName has been removed and is no longer valid."; my $msg = "The attribute $aName has been removed and is no longer valid.";
Log3 ($name, 1, "$name - $msg"); Log3 ($name, 1, "$name - $msg");
return qq{Device "$name" -> $msg}; return qq{Device "$name" -> $msg};
} }
else {
return qq{The attribute '$aName' is obsolete.};
}
} }
###################################################################################################################### ######################################################################################################################
@ -5348,11 +5351,6 @@ sub Attr {
singleUpdateState ( {hash => $hash, state => $val, evt => 1} ); singleUpdateState ( {hash => $hash, state => $val, evt => 1} );
} }
if ($aName eq 'ctrlAutoRefresh') {
delete $hash->{HELPER}{AREFRESH};
delete $hash->{AUTOREFRESH};
}
if ($aName eq 'ctrlNextDayForecastReadings') { if ($aName eq 'ctrlNextDayForecastReadings') {
deleteReadingspec ($hash, "Tomorrow_Hour.*"); deleteReadingspec ($hash, "Tomorrow_Hour.*");
} }
@ -5837,13 +5835,19 @@ sub _attrInverterDev { ## no critic "not used"
return qq{Set the first Inverter device with attribute 'setupInverterDev01'}; return qq{Set the first Inverter device with attribute 'setupInverterDev01'};
} }
if (!$h->{pv} || !$h->{etotal}) { if (!$h->{pv} || !$h->{etotal} || !$h->{capacity}) {
return qq{The syntax of '$aName' is not valid. Please consider the commandref.}; return qq{One or more of the keys 'pv, etotal, capacity' are missing . Please consider the commandref.};
} }
if ($h->{capacity} && !isNumeric($h->{capacity})) { if (!isNumeric($h->{capacity})) {
return qq{The syntax of key 'capacity' is not valid. Please consider the commandref.}; return qq{The value of key 'capacity' must be numeric. Please consider the commandref.};
} }
if ($h->{limit}) {
if (!isNumeric($h->{limit}) || $h->{limit} < 0 || $h->{limit} > 100) {
return qq{The value of key 'limit' is not valid. Please consider the commandref.};
}
}
if ($h->{feed} && $h->{feed} !~ /^grid|bat$/xs) { if ($h->{feed} && $h->{feed} !~ /^grid|bat$/xs) {
return qq{The value of key 'feed' is not valid. Please consider the commandref.}; return qq{The value of key 'feed' is not valid. Please consider the commandref.};
@ -5860,6 +5864,7 @@ sub _attrInverterDev { ## no critic "not used"
$data{$type}{$name}{circular}{99}{attrInvChangedTs} = int time; $data{$type}{$name}{circular}{99}{attrInvChangedTs} = int time;
delete $data{$type}{$name}{inverters}{$in}{invertercap}; delete $data{$type}{$name}{inverters}{$in}{invertercap};
delete $data{$type}{$name}{inverters}{$in}{ilimit};
delete $data{$type}{$name}{inverters}{$in}{iicon}; delete $data{$type}{$name}{inverters}{$in}{iicon};
delete $data{$type}{$name}{inverters}{$in}{istrings}; delete $data{$type}{$name}{inverters}{$in}{istrings};
delete $data{$type}{$name}{inverters}{$in}{ifeed}; delete $data{$type}{$name}{inverters}{$in}{ifeed};
@ -7023,6 +7028,7 @@ sub centralTask {
_transferMeterValues ($centpars); # Energy Meter auswerten _transferMeterValues ($centpars); # Energy Meter auswerten
_transferBatteryValues ($centpars); # Batteriewerte einsammeln _transferBatteryValues ($centpars); # Batteriewerte einsammeln
_batSocTarget ($centpars); # Batterie Optimum Ziel SOC berechnen _batSocTarget ($centpars); # Batterie Optimum Ziel SOC berechnen
_batChargeRecmd ($centpars); # Batterie Ladeempfehlung berechnen und erstellen
_manageConsumerData ($centpars); # Consumer Daten sammeln und Zeiten planen _manageConsumerData ($centpars); # Consumer Daten sammeln und Zeiten planen
_estConsumptionForecast ($centpars); # Verbrauchsprognose erstellen _estConsumptionForecast ($centpars); # Verbrauchsprognose erstellen
_evaluateThresholds ($centpars); # Schwellenwerte bewerten und signalisieren _evaluateThresholds ($centpars); # Schwellenwerte bewerten und signalisieren
@ -8387,16 +8393,8 @@ sub __calcPVestimates {
$data{$type}{$name}{current}{allstringspeak} = $peaksum; # temperaturbedingte Korrektur der installierten Peakleistung in W $data{$type}{$name}{current}{allstringspeak} = $peaksum; # temperaturbedingte Korrektur der installierten Peakleistung in W
$pvsum = $peaksum if($peaksum && $pvsum > $peaksum); # Vorhersage nicht größer als die Summe aller PV-Strings Peak $pvsum = $peaksum if($peaksum && $pvsum > $peaksum); # Vorhersage nicht größer als die Summe aller PV-Strings Peak
$pvsum = sprintf "%.0f", $pvsum;
my $logao = qq{};
$paref->{pvsum} = $pvsum;
$paref->{peaksum} = $peaksum;
($pvsum, $logao) = ___70percentRule ($paref);
delete $paref->{peaksum};
delete $paref->{pvsum};
if ($debug =~ /radiationProcess/xs) { if ($debug =~ /radiationProcess/xs) {
$lh = { # Log-Hash zur Ausgabe $lh = { # Log-Hash zur Ausgabe
"Starttime" => $wantdt, "Starttime" => $wantdt,
@ -8404,7 +8402,7 @@ sub __calcPVestimates {
"Cloudcover" => $wcc, "Cloudcover" => $wcc,
"Total Rain last hour" => $rr1c." kg/m2", "Total Rain last hour" => $rr1c." kg/m2",
"PV Correction mode" => ($acu ? $acu : 'no'), "PV Correction mode" => ($acu ? $acu : 'no'),
"PV generation forecast" => $pvsum." Wh ".$logao, "PV generation forecast" => $pvsum." Wh",
}; };
$sq = q{}; $sq = q{};
@ -8518,36 +8516,6 @@ sub ___calcPeaklossByTemp {
return ($peakloss, $modtemp); return ($peakloss, $modtemp);
} }
################################################################
# 70% Regel kalkulieren
################################################################
sub ___70percentRule {
my $paref = shift;
my $name = $paref->{name};
my $pvsum = $paref->{pvsum};
my $peaksum = $paref->{peaksum};
my $num = $paref->{num}; # Nexthour
my $hash = $defs{$name};
my $logao = qq{};
my $confc = NexthoursVal ($hash, "NextHour".sprintf("%02d",$num), "confc", 0);
my $max70 = $peaksum/100 * 70;
if (AttrVal ($name, "affect70percentRule", "0") eq "1" && $pvsum > $max70) {
$pvsum = $max70;
$logao = qq{(reduced by 70 percent rule)};
}
if (AttrVal ($name, "affect70percentRule", "0") eq "dynamic" && $pvsum > $max70 + $confc) {
$pvsum = $max70 + $confc;
$logao = qq{(reduced by 70 percent dynamic rule)};
}
$pvsum = int $pvsum;
return ($pvsum, $logao);
}
################################################################ ################################################################
# den Maximalwert PV Vorhersage für Heute ermitteln # den Maximalwert PV Vorhersage für Heute ermitteln
################################################################ ################################################################
@ -8651,14 +8619,15 @@ sub _transferInverterValues {
my $feed = $h->{feed} // 'default'; my $feed = $h->{feed} // 'default';
$data{$type}{$name}{inverters}{$in}{igeneration} = $pv; # Hilfshash Wert current generation, Forum: https://forum.fhem.de/index.php/topic,117864.msg1139251.html#msg1139251 $data{$type}{$name}{inverters}{$in}{igeneration} = $pv; # Hilfshash Wert current generation, Forum: https://forum.fhem.de/index.php/topic,117864.msg1139251.html#msg1139251
$data{$type}{$name}{inverters}{$in}{ietotal} = $etotal; # aktuellen etotal des WR speichern $data{$type}{$name}{inverters}{$in}{ietotal} = $etotal; # aktuellen etotal des WR speichern
$data{$type}{$name}{inverters}{$in}{iname} = $indev; # Name des Inverterdevices $data{$type}{$name}{inverters}{$in}{iname} = $indev; # Name des Inverterdevices
$data{$type}{$name}{inverters}{$in}{ialias} = AttrVal ($indev, 'alias', $indev); # Alias Inverter $data{$type}{$name}{inverters}{$in}{ialias} = AttrVal ($indev, 'alias', $indev); # Alias Inverter
$data{$type}{$name}{inverters}{$in}{invertercap} = $h->{capacity} if(defined $h->{capacity}); # optionale Angabe max. WR-Leistung $data{$type}{$name}{inverters}{$in}{invertercap} = $h->{capacity} if(defined $h->{capacity}); # optionale Angabe max. WR-Leistung
$data{$type}{$name}{inverters}{$in}{iicon} = $h->{icon} if($h->{icon}); # Icon des Inverters $data{$type}{$name}{inverters}{$in}{ilimit} = $h->{limit} // 100; # Wirkleistungsbegrenzung
$data{$type}{$name}{inverters}{$in}{istrings} = $h->{strings} if($h->{strings}); # dem Inverter zugeordnete Strings $data{$type}{$name}{inverters}{$in}{iicon} = $h->{icon} if($h->{icon}); # Icon des Inverters
$data{$type}{$name}{inverters}{$in}{ifeed} = $feed; # Eigenschaften der Energielieferung $data{$type}{$name}{inverters}{$in}{istrings} = $h->{strings} if($h->{strings}); # dem Inverter zugeordnete Strings
$data{$type}{$name}{inverters}{$in}{ifeed} = $feed; # Eigenschaften der Energielieferung
$pvsum += $pv; $pvsum += $pv;
$ethishoursum += $ethishour; $ethishoursum += $ethishour;
@ -9312,6 +9281,107 @@ sub __batSaveSocKeyFigures {
return; return;
} }
################################################################
# Erstellung Batterie Ladeempfehlung
################################################################
sub _batChargeRecmd {
my $paref = shift;
my $name = $paref->{name};
my $chour = $paref->{chour};
return if(!isBatteryUsed ($name));
my $hash = $defs{$name};
my $rodpvfc = ReadingsNum ($name, 'RestOfDayPVforecast', 0); # PV Prognose Rest des Tages
my $tompvfc = ReadingsNum ($name, 'Tomorrow_PVforecast', 0); # PV Prognose nächster Tag
my $confcss = CurrentVal ($hash, 'tdConFcTillSunset', 0); # Verbrauchsprognose bis Sonnenuntergang
my $tomconfc = ReadingsNum ($name, 'Tomorrow_ConsumptionForecast', 0);
my $pvCu = ReadingsNum ($name, 'Current_PV', 0); # aktuelle PV Erzeugung
my $batcap = CurrentVal ($hash, 'batinstcap', 0); # installierte Batteriekapazität Wh
my $soc = CurrentVal ($hash, 'batcharge', 0); # aktueller SOC (%)
my $inpmax = 0;
for my $in (1..$maxinverter) {
$in = sprintf "%02d", $in;
my $feed = InverterVal ($hash, $in, 'ifeed', '');
next if(!$feed || $feed eq 'grid'); # Inverter 'Grid' ausschließen
my $iname = InverterVal ($hash, $in, 'iname', '');
my $icap = InverterVal ($hash, $in, 'invertercap', 0);
my $limit = InverterVal ($hash, $in, 'ilimit', 100); # Wirkleistungsbegrenzung (default keine Begrenzung)
my $aplim = $icap * $limit / 100;
$inpmax += $aplim; # max. Leistung aller WR mit Berücksichtigung Wirkleistungsbegrenzung
debugLog ($paref, 'batteryManagement', "Inverter '$iname' capacity: $icap, Active power limit: $limit % -> Pmax limited: $aplim");
}
debugLog ($paref, 'batteryManagement', "Summary active power limit of all Inverter (except feed 'grid'): $inpmax");
return if(!$inpmax);
my $sfmargin = $inpmax * 0.5; # Sicherheitszuschlag 50% der installierten Leistung (Wh)
my $betEneed = sprintf "%.0f", ($batcap - ($batcap * $soc / 100)); # benötigte Energie bis 100% Batteriekapazität Wh
for my $num (0..47) {
my ($fd,$fh) = calcDayHourMove ($chour, $num);
next if($fd > 1);
my $today = NexthoursVal ($hash, 'NextHour'.sprintf("%02d",$num), 'today', 0);
my $confc = NexthoursVal ($hash, 'NextHour'.sprintf("%02d",$num), 'confc', 0);
my $pvfc = NexthoursVal ($hash, 'NextHour'.sprintf("%02d",$num), 'pvfc', 0);
my $stt = NexthoursVal ($hash, 'NextHour'.sprintf("%02d",$num), 'starttime', '');
$stt = (split '-', $stt)[2] if($stt);
my $dold = 0; # Ladeempfehlung 0 per Default
my $spday = 0;
if ($today) { # (Rest) heutiger Tag
$spday = $rodpvfc - $confcss;
}
else { # nächster Tag
$spday = $tompvfc - $tomconfc;
}
$spday = 0 if($spday < 0); # PV Überschuß Prognose bis Sonnenuntergang
if ( $betEneed + $sfmargin >= $spday ) {$dold = 1} # Ladeempfehlung wenn benötigte Ladeenergie >= Restüberschuß des Tages zzgl. Sicherheitsaufschlag
if ( !$num && $pvCu >= $inpmax ) {$dold = 1} # Ladeempfehlung wenn akt. PV Leistung >= WR-Leistungsbegrenzung
my $msg = "(Eneed: $betEneed -> Surplus Day: $spday, Curr PV: $pvCu -> Limit: $inpmax)";
if ($num) {
$msg = "(Eneed: $betEneed -> Surplus Day: $spday)";
}
else {
storeReading ('Battery_ChargeRecommended', $dold); # Reading nur für aktuelle Stunde
}
debugLog ($paref, 'batteryManagement', "Charge activation $stt -> $dold $msg");
if ($pvfc) {
if ($today) { # (Rest) heutiger Tag
$confcss -= $confc;
$confcss = 0 if($confcss < 0);
$rodpvfc -= $pvfc;
}
else { # nächster Tag
$tomconfc -= $confc;
$tomconfc = 0 if($tomconfc < 0);
$tompvfc -= $pvfc;
}
}
$betEneed -= sprintf "%.0f", ($pvfc - $confc);
$betEneed = $betEneed < 0 ? 0 : $betEneed;
}
return;
}
################################################################ ################################################################
# Zusammenfassungen erstellen # Zusammenfassungen erstellen
################################################################ ################################################################
@ -12022,48 +12092,9 @@ sub FwFn {
$ret .= entryGraphic ($name); $ret .= entryGraphic ($name);
$ret .= "</html>"; $ret .= "</html>";
# Autorefresh nur des aufrufenden FHEMWEB-Devices
my $al = AttrVal ($name, 'ctrlAutoRefresh', 0);
if ($al) {
pageRefresh ($hash);
}
return $ret; return $ret;
} }
###########################################################################
# Seitenrefresh festgelegt durch SolarForecast-Attribut "ctrlAutoRefresh"
# und "ctrlAutoRefreshFW"
###########################################################################
sub pageRefresh {
my $hash = shift;
my $name = $hash->{NAME};
my $al = AttrVal($name, 'ctrlAutoRefresh', 0);
if ($al) {
my $rftime = gettimeofday()+$al;
if (!$hash->{HELPER}{AREFRESH} || $hash->{HELPER}{AREFRESH} <= gettimeofday()) {
RemoveInternalTimer ($hash, \&pageRefresh);
InternalTimer($rftime, \&pageRefresh, $hash, 0);
my $rd = AttrVal ($name, 'ctrlAutoRefreshFW', $hash->{HELPER}{FW});
{ map { FW_directNotify("#FHEMWEB:$_", "location.reload('true')", "") } $rd } ## no critic 'Map blocks'
$hash->{HELPER}{AREFRESH} = $rftime;
$hash->{AUTOREFRESH} = FmtDateTime($rftime);
}
}
else {
delete $hash->{HELPER}{AREFRESH};
delete $hash->{AUTOREFRESH};
RemoveInternalTimer ($hash, \&pageRefresh);
}
return;
}
################################################################ ################################################################
# Grafik als HTML zurück liefern (z.B. für Widget) # Grafik als HTML zurück liefern (z.B. für Widget)
################################################################ ################################################################
@ -20537,22 +20568,6 @@ to ensure that the system configuration is correct.
<br><br> <br><br>
<ul> <ul>
<ul> <ul>
<a id="SolarForecast-attr-affect70percentRule"></a>
<li><b>affect70percentRule</b><br>
If set, the predicted power is limited according to the 70% rule. <br><br>
<ul>
<table>
<colgroup> <col width="15%"> <col width="85%"> </colgroup>
<tr><td> <b>0</b> </td><td>No limit on the forecast PV generation (default) </td></tr>
<tr><td> <b>1</b> </td><td>the predicted PV generation is limited to 70% of the installed string power(s) </td></tr>
<tr><td> <b>dynamic</b> </td><td>the predicted PV generation is limited when 70% of the installed </td></tr>
<tr><td> </td><td>string(s) power plus the predicted consumption is exceeded. </td></tr>
</table>
</ul>
</li>
<br>
<a id="SolarForecast-attr-affectBatteryPreferredCharge"></a> <a id="SolarForecast-attr-affectBatteryPreferredCharge"></a>
<li><b>affectBatteryPreferredCharge </b><br> <li><b>affectBatteryPreferredCharge </b><br>
Consumers with the <b>can</b> mode are only switched on when the specified battery charge (%) Consumers with the <b>can</b> mode are only switched on when the specified battery charge (%)
@ -20862,21 +20877,6 @@ to ensure that the system configuration is correct.
</li> </li>
<br> <br>
<a id="SolarForecast-attr-ctrlAutoRefresh"></a>
<li><b>ctrlAutoRefresh</b> <br>
If set, active browser pages of the FHEMWEB device that has called up the SolarForecast device are
reloaded after the set time (seconds). If browser pages of a certain FHEMWEB device are to be reloaded
instead, this device can be specified with the attribute "ctrlAutoRefreshFW".
</li>
<br>
<a id="SolarForecast-attr-ctrlAutoRefreshFW"></a>
<li><b>ctrlAutoRefreshFW</b><br>
If "ctrlAutoRefresh" is activated, this attribute can be used to determine the FHEMWEB device whose active browser pages
should be regularly reloaded.
</li>
<br>
<a id="SolarForecast-attr-ctrlBackupFilesKeep"></a> <a id="SolarForecast-attr-ctrlBackupFilesKeep"></a>
<li><b>ctrlBackupFilesKeep &lt;Integer&gt; </b><br> <li><b>ctrlBackupFilesKeep &lt;Integer&gt; </b><br>
Defines the number of generations of backup files Defines the number of generations of backup files
@ -21588,8 +21588,8 @@ to ensure that the system configuration is correct.
<a id="SolarForecast-attr-setupInverterDev" data-pattern="setupInverterDev.*"></a> <a id="SolarForecast-attr-setupInverterDev" data-pattern="setupInverterDev.*"></a>
<li><b>setupInverterDevXX &lt;Inverter Device Name&gt; pv=&lt;Readingname&gt;:&lt;Unit&gt; etotal=&lt;Readingname&gt;:&lt;Unit&gt; <li><b>setupInverterDevXX &lt;Inverter Device Name&gt; pv=&lt;Readingname&gt;:&lt;Unit&gt; etotal=&lt;Readingname&gt;:&lt;Unit&gt;
[capacity=&lt;max. WR-Leistung&gt;] [strings=&lt;String1&gt;,&lt;String2&gt;,...] capacity=&lt;max. WR-Leistung&gt; [strings=&lt;String1&gt;,&lt;String2&gt;,...]
[feed=&lt;Delivery type&gt;] [feed=&lt;Delivery type&gt;] [limit=&lt;0..100&gt;]
[icon=&lt;Day&gt;[@&lt;Color&gt;][:&lt;Night&gt;[@&lt;Color&gt;]]] </b> <br><br> [icon=&lt;Day&gt;[@&lt;Color&gt;][:&lt;Night&gt;[@&lt;Color&gt;]]] </b> <br><br>
Defines any inverter device or solar charger and its readings to supply the current PV generation values. <br> Defines any inverter device or solar charger and its readings to supply the current PV generation values. <br>
@ -21600,7 +21600,6 @@ to ensure that the system configuration is correct.
This can also be a dummy device with corresponding readings. <br> This can also be a dummy device with corresponding readings. <br>
The values of several inverters can be combined in a dummy device, for example, and this device can The values of several inverters can be combined in a dummy device, for example, and this device can
be specified with the corresponding readings. <br> be specified with the corresponding readings. <br>
Specifying <b>capacity</b> is optional, but strongly recommended to optimize prediction accuracy.
<br><br> <br><br>
<ul> <ul>
@ -21612,7 +21611,6 @@ to ensure that the system configuration is correct.
<tr><td> </td><td>SolarForecast handles this error and reports the situation by means of a log message. </td></tr> <tr><td> </td><td>SolarForecast handles this error and reports the situation by means of a log message. </td></tr>
<tr><td> <b>Einheit</b> </td><td>the respective unit (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>capacity</b> </td><td>Rated power of the inverter according to data sheet, i.e. max. possible output in Watts </td></tr> <tr><td> <b>capacity</b> </td><td>Rated power of the inverter according to data sheet, i.e. max. possible output in Watts </td></tr>
<tr><td> </td><td>(The entry is optional, but is strongly recommended) </td></tr>
<tr><td> <b>strings</b> </td><td>Comma-separated list of the strings assigned to the inverter (optional). The string names </td></tr> <tr><td> <b>strings</b> </td><td>Comma-separated list of the strings assigned to the inverter (optional). The string names </td></tr>
<tr><td> </td><td>are defined in the <a href=#SolarForecast-attr-setupInverterStrings”>setupInverterStrings</a> attribute. </td></tr> <tr><td> </td><td>are defined in the <a href=#SolarForecast-attr-setupInverterStrings”>setupInverterStrings</a> attribute. </td></tr>
<tr><td> </td><td>If 'strings' is not specified, all defined string names are assigned to the inverter. </td></tr> <tr><td> </td><td>If 'strings' is not specified, all defined string names are assigned to the inverter. </td></tr>
@ -21620,6 +21618,7 @@ to ensure that the system configuration is correct.
<tr><td> </td><td>If the key is not set, the device feeds the PV energy into the house's AC grid. </td></tr> <tr><td> </td><td>If the key is not set, the device feeds the PV energy into the house's AC grid. </td></tr>
<tr><td> </td><td><b>bat</b> - the device supplies energy exclusively to the battery </td></tr> <tr><td> </td><td><b>bat</b> - the device supplies energy exclusively to the battery </td></tr>
<tr><td> </td><td><b>grid</b> - the energy is fed exclusively into the public grid </td></tr> <tr><td> </td><td><b>grid</b> - the energy is fed exclusively into the public grid </td></tr>
<tr><td> <b>limit</b> </td><td>Defines any active power limitation in % (optional). </td></tr>
<tr><td> <b>icon</b> </td><td>Icon for displaying the inverter in the flow chart (optional) </td></tr> <tr><td> <b>icon</b> </td><td>Icon for displaying the inverter in the flow chart (optional) </td></tr>
<tr><td> </td><td><b>&lt;Day&gt;</b> - Icon and optional color for activity after sunrise </td></tr> <tr><td> </td><td><b>&lt;Day&gt;</b> - Icon and optional color for activity after sunrise </td></tr>
<tr><td> </td><td><b>&lt;Night&gt;</b> - Icon and optional color after sunset, otherwise the moon phase is displayed </td></tr> <tr><td> </td><td><b>&lt;Night&gt;</b> - Icon and optional color after sunset, otherwise the moon phase is displayed </td></tr>
@ -22930,22 +22929,6 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<br><br> <br><br>
<ul> <ul>
<ul> <ul>
<a id="SolarForecast-attr-affect70percentRule"></a>
<li><b>affect70percentRule</b><br>
Wenn gesetzt, wird die prognostizierte Leistung entsprechend der 70% Regel begrenzt. <br><br>
<ul>
<table>
<colgroup> <col width="15%"> <col width="85%"> </colgroup>
<tr><td> <b>0</b> </td><td>keine Begrenzung der prognostizierten PV-Erzeugung (default) </td></tr>
<tr><td> <b>1</b> </td><td>die prognostizierte PV-Erzeugung wird auf 70% der installierten Stringleistung(en) begrenzt </td></tr>
<tr><td> <b>dynamic</b> </td><td>die prognostizierte PV-Erzeugung wird begrenzt wenn 70% der installierten </td></tr>
<tr><td> </td><td>Stringleistung(en) zzgl. des prognostizierten Verbrauchs überschritten wird </td></tr>
</table>
</ul>
</li>
<br>
<a id="SolarForecast-attr-affectBatteryPreferredCharge"></a> <a id="SolarForecast-attr-affectBatteryPreferredCharge"></a>
<li><b>affectBatteryPreferredCharge </b><br> <li><b>affectBatteryPreferredCharge </b><br>
Es werden Verbraucher mit dem Mode <b>can</b> erst dann eingeschaltet, wenn die angegebene Batterieladung (%) Es werden Verbraucher mit dem Mode <b>can</b> erst dann eingeschaltet, wenn die angegebene Batterieladung (%)
@ -23255,21 +23238,6 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
</li> </li>
<br> <br>
<a id="SolarForecast-attr-ctrlAutoRefresh"></a>
<li><b>ctrlAutoRefresh</b> <br>
Wenn gesetzt, werden aktive Browserseiten des FHEMWEB-Devices welches das SolarForecast-Device aufgerufen hat, nach der
eingestellten Zeit (Sekunden) neu geladen. Sollen statt dessen Browserseiten eines bestimmten FHEMWEB-Devices neu
geladen werden, kann dieses Device mit dem Attribut "ctrlAutoRefreshFW" festgelegt werden.
</li>
<br>
<a id="SolarForecast-attr-ctrlAutoRefreshFW"></a>
<li><b>ctrlAutoRefreshFW</b><br>
Ist "ctrlAutoRefresh" aktiviert, kann mit diesem Attribut das FHEMWEB-Device bestimmt werden dessen aktive Browserseiten
regelmäßig neu geladen werden sollen.
</li>
<br>
<a id="SolarForecast-attr-ctrlBackupFilesKeep"></a> <a id="SolarForecast-attr-ctrlBackupFilesKeep"></a>
<li><b>ctrlBackupFilesKeep &lt;Ganzzahl&gt;</b><br> <li><b>ctrlBackupFilesKeep &lt;Ganzzahl&gt;</b><br>
Legt die Anzahl der Generationen von Sicherungsdateien Legt die Anzahl der Generationen von Sicherungsdateien
@ -23982,8 +23950,8 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<a id="SolarForecast-attr-setupInverterDev" data-pattern="setupInverterDev.*"></a> <a id="SolarForecast-attr-setupInverterDev" data-pattern="setupInverterDev.*"></a>
<li><b>setupInverterDevXX &lt;Inverter Device Name&gt; pv=&lt;Readingname&gt;:&lt;Einheit&gt; etotal=&lt;Readingname&gt;:&lt;Einheit&gt; <li><b>setupInverterDevXX &lt;Inverter Device Name&gt; pv=&lt;Readingname&gt;:&lt;Einheit&gt; etotal=&lt;Readingname&gt;:&lt;Einheit&gt;
[capacity=&lt;max. WR-Leistung&gt;] [strings=&lt;String1&gt;,&lt;String2&gt;,...] capacity=&lt;max. WR-Leistung&gt; [strings=&lt;String1&gt;,&lt;String2&gt;,...]
[feed=&lt;Liefertyp&gt;] [feed=&lt;Liefertyp&gt;] [limit=&lt;0..100&gt;]
[icon=&lt;Tag&gt;[@&lt;Farbe&gt;][:&lt;Nacht&gt;[@&lt;Farbe&gt;]]] </b> <br><br> [icon=&lt;Tag&gt;[@&lt;Farbe&gt;][:&lt;Nacht&gt;[@&lt;Farbe&gt;]]] </b> <br><br>
Legt ein beliebiges Wechselrichter-Gerät bzw. Solar-Ladegerät und dessen Readings zur Lieferung der aktuellen Legt ein beliebiges Wechselrichter-Gerät bzw. Solar-Ladegerät und dessen Readings zur Lieferung der aktuellen
@ -23995,7 +23963,6 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
Dabei kann es sich auch um ein Dummy Gerät mit entsprechenden Readings handeln. <br> Dabei kann es sich auch um ein Dummy Gerät mit entsprechenden Readings handeln. <br>
Die Werte mehrerer Wechselrichter kann man z.B. in einem Dummy Gerät zusammenführen und gibt dieses Gerät mit Die Werte mehrerer Wechselrichter kann man z.B. in einem Dummy Gerät zusammenführen und gibt dieses Gerät mit
den entsprechenden Readings an. <br> den entsprechenden Readings an. <br>
Die Angabe von <b>capacity</b> ist optional, wird aber zur Optimierung der Vorhersagegenauigkeit dringend empfohlen.
<br><br> <br><br>
<ul> <ul>
@ -24007,7 +23974,6 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<tr><td> </td><td>SolarForecast diesen Fehler und meldet die aufgetretene Situation durch einen Logeintrag. </td></tr> <tr><td> </td><td>SolarForecast diesen Fehler und meldet die aufgetretene Situation durch einen Logeintrag. </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>capacity</b> </td><td>Bemessungsleistung des Wechselrichters gemäß Datenblatt, d.h. max. möglicher Output in Watt </td></tr> <tr><td> <b>capacity</b> </td><td>Bemessungsleistung des Wechselrichters gemäß Datenblatt, d.h. max. möglicher Output in Watt </td></tr>
<tr><td> </td><td>(Die Angabe ist optional, wird aber dringend empfohlen zu setzen) </td></tr>
<tr><td> <b>strings</b> </td><td>Komma getrennte Liste der dem Wechselrichter zugeordneten Strings (optional). Die Stringnamen </td></tr> <tr><td> <b>strings</b> </td><td>Komma getrennte Liste der dem Wechselrichter zugeordneten Strings (optional). Die Stringnamen </td></tr>
<tr><td> </td><td>werden im Attribut <a href="#SolarForecast-attr-setupInverterStrings">setupInverterStrings</a> definiert. </td></tr> <tr><td> </td><td>werden im Attribut <a href="#SolarForecast-attr-setupInverterStrings">setupInverterStrings</a> definiert. </td></tr>
<tr><td> </td><td>Ist 'strings' nicht angegeben, werden alle definierten Stringnamen dem Wechselrichter zugeordnet. </td></tr> <tr><td> </td><td>Ist 'strings' nicht angegeben, werden alle definierten Stringnamen dem Wechselrichter zugeordnet. </td></tr>
@ -24015,6 +23981,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<tr><td> </td><td>Ist der Schlüssel nicht gesetzt, speist das Gerät die PV-Energie in das Wechselstromnetz des Hauses ein. </td></tr> <tr><td> </td><td>Ist der Schlüssel nicht gesetzt, speist das Gerät die PV-Energie in das Wechselstromnetz des Hauses ein. </td></tr>
<tr><td> </td><td><b>bat</b> - das Gerät liefert die Energie ausschließlich an die Batterie </td></tr> <tr><td> </td><td><b>bat</b> - das Gerät liefert die Energie ausschließlich an die Batterie </td></tr>
<tr><td> </td><td><b>grid</b> - die Energie wird ausschließlich in das öffentlich Netz eingespeist </td></tr> <tr><td> </td><td><b>grid</b> - die Energie wird ausschließlich in das öffentlich Netz eingespeist </td></tr>
<tr><td> <b>limit</b> </td><td>Definiert eine eventuelle Wirkleistungsbeschränkung in % (optional). </td></tr>
<tr><td> <b>icon</b> </td><td>Icon zur Darstellung des Inverters in der Flowgrafik (optional) </td></tr> <tr><td> <b>icon</b> </td><td>Icon zur Darstellung des Inverters in der Flowgrafik (optional) </td></tr>
<tr><td> </td><td><b>&lt;Tag&gt;</b> - Icon und ggf. Farbe bei Aktivität nach Sonnenaufgang </td></tr> <tr><td> </td><td><b>&lt;Tag&gt;</b> - Icon und ggf. Farbe bei Aktivität nach Sonnenaufgang </td></tr>
<tr><td> </td><td><b>&lt;Nacht&gt;</b> - Icon und ggf. Farbe nach Sonnenuntergang, sonst wird die Mondphase angezeigt </td></tr> <tr><td> </td><td><b>&lt;Nacht&gt;</b> - Icon und ggf. Farbe nach Sonnenuntergang, sonst wird die Mondphase angezeigt </td></tr>