diff --git a/fhem/contrib/DS_Starter/76_SolarForecast.pm b/fhem/contrib/DS_Starter/76_SolarForecast.pm index be29d29bc..ab8f49c27 100644 --- a/fhem/contrib/DS_Starter/76_SolarForecast.pm +++ b/fhem/contrib/DS_Starter/76_SolarForecast.pm @@ -144,6 +144,8 @@ BEGIN { # Versions History intern my %vNotesIntern = ( + "1.0.10" => "31.10.2023 fix warnings, edit comref ", + "1.0.9" => "29.10.2023 _aiGetSpread: set spread from 50 to 20 ", "1.0.8" => "22.10.2023 codechange: add central readings store array, new function storeReading, writeCacheToFile ". "solcastapi in sub __delObsoleteAPIData, save freespace if flowGraphicShowConsumer=0 is set ". "pay attention to attr graphicEnergyUnit in __createOwnSpec ", @@ -3588,7 +3590,7 @@ sub __VictronVRM_ApiRequestForecast { my $idsite = $paref->{idsite}; my $tstart = time; - my $tend = time + 259200; # 172800 = 2 Tage + my $tend = time + 259200; # 172800 = 2 Tage my $url = "https://vrmapi.victronenergy.com/v2/installations/$idsite/stats?type=forecast&interval=hours&start=$tstart&end=$tend"; @@ -3694,7 +3696,7 @@ sub __VictronVRM_ApiResponseForecast { my $k = 0; while ($jdata->{'records'}{'solar_yield_forecast'}[$k]) { next if(ref $jdata->{'records'}{'solar_yield_forecast'}[$k] ne "ARRAY"); # Forum: https://forum.fhem.de/index.php?msg=1288637 - + my $starttmstr = $jdata->{'records'}{'solar_yield_forecast'}[$k][0]; # Millisekunden geliefert my $val = $jdata->{'records'}{'solar_yield_forecast'}[$k][1]; $starttmstr = (timestampToTimestring ($starttmstr, $lang))[3]; @@ -3715,7 +3717,7 @@ sub __VictronVRM_ApiResponseForecast { $k = 0; while ($jdata->{'records'}{'vrm_consumption_fc'}[$k]) { next if(ref $jdata->{'records'}{'vrm_consumption_fc'}[$k] ne "ARRAY"); # Forum: https://forum.fhem.de/index.php?msg=1288637 - + my $starttmstr = $jdata->{'records'}{'vrm_consumption_fc'}[$k][0]; # Millisekunden geliefert my $val = $jdata->{'records'}{'vrm_consumption_fc'}[$k][1]; $starttmstr = (timestampToTimestring ($starttmstr, $lang))[3]; @@ -4008,7 +4010,7 @@ sub Attr { my $name = shift; my $aName = shift; my $aVal = shift; - + my $hash = $defs{$name}; my ($do,$val); @@ -4034,7 +4036,7 @@ sub Attr { if($aName eq 'ctrlNextDayForecastReadings') { deleteReadingspec ($hash, "Tomorrow_Hour.*"); } - + if($aName eq 'ctrlGenPVdeviation' && $aVal eq 'daily') { my $type = $hash->{TYPE}; deleteReadingspec ($hash, 'Today_PVdeviation'); @@ -4752,9 +4754,9 @@ sub centralTask { saveEnergyConsumption ($centpars); # Energie Hausverbrauch speichern genStatisticReadings ($centpars); # optionale Statistikreadings erstellen - userExit ($centpars); # User spezifische Funktionen ausführen + userExit ($centpars); # User spezifische Funktionen ausführen setTimeTracking ($hash, $cst, 'runTimeCentralTask'); # Zyklus-Laufzeit ermitteln - + createReadingsFromArray ($hash, $evt); # Readings erzeugen if ($evt) { @@ -5013,7 +5015,7 @@ sub _specialActivities { $pvfc = ReadingsNum ($name, "Today_Hour24_PVforecast", 0); storeReading ('LastHourPVforecast', "$pvfc Wh", $ts); - + $pvrl = ReadingsNum ($name, "Today_Hour24_PVreal", 0); storeReading ('LastHourPVreal', "$pvrl Wh", $ts); @@ -5142,7 +5144,7 @@ sub __delObsoleteAPIData { delete $data{$type}{$name}{solcastapi}{$idx}{$scd} if ($ds && $ds < $refts); } } - + writeCacheToFile ($hash, "solcastapi", $scpicache.$name); # Cache File SolCast API Werte schreiben my @as = split ",", ReadingsVal($name, 'inverterStrings', ''); @@ -5380,7 +5382,7 @@ sub _transferAPIRadiationValues { delete $paref->{histname}; } } - + storeReading ('.lastupdateForecastValues', $t); # Statusreading letzter update return; @@ -6168,7 +6170,7 @@ sub _createSummaries { $todaySumFc->{PV} += ReadingsNum ($name, "Today_Hour".sprintf("%02d",$th)."_PVforecast", 0); $todaySumRe->{PV} += ReadingsNum ($name, "Today_Hour".sprintf("%02d",$th)."_PVreal", 0); } - + my $pvre = int $todaySumRe->{PV}; push @{$data{$type}{$name}{current}{h4fcslidereg}}, int $next4HoursSum->{PV}; # Schieberegister 4h Summe Forecast @@ -6208,7 +6210,7 @@ sub _createSummaries { storeReading ('Current_AutarkyRate', $autarkyrate. ' %'); storeReading ('Today_PVreal', $pvre. ' Wh') if($pvre > ReadingsNum ($name, 'Today_PVreal', 0)); storeReading ('Tomorrow_ConsumptionForecast', $tconsum. ' Wh') if(defined $tconsum); - + storeReading ('NextHours_Sum01_PVforecast', (int $next1HoursSum->{PV}). ' Wh'); storeReading ('NextHours_Sum02_PVforecast', (int $next2HoursSum->{PV}). ' Wh'); storeReading ('NextHours_Sum03_PVforecast', (int $next3HoursSum->{PV}). ' Wh'); @@ -6402,9 +6404,9 @@ sub _manageConsumerData { my ($iilt,$rlt) = isInLocktime ($paref); # Sperrzeit Status ermitteln my $constate = "name='$alias' state='$costate' planningstate='$pstate'"; $constate .= " remainLockTime='$rlt'" if($rlt); - - storeReading ("consumer${c}", $constate); # Consumer Infos - storeReading ("consumer${c}_planned_start", $starttime) if($starttime); # Consumer Start geplant + + storeReading ("consumer${c}", $constate); # Consumer Infos + storeReading ("consumer${c}_planned_start", $starttime) if($starttime); # Consumer Start geplant storeReading ("consumer${c}_planned_stop", $stoptime) if($stoptime); # Consumer Stop geplant } @@ -7745,15 +7747,15 @@ sub _calcTodayPVdeviation { my $pvfc = ReadingsNum ($name, 'Today_PVforecast', 0); my $pvre = ReadingsNum ($name, 'Today_PVreal', 0); - + return if(!$pvre); - + my $dp; - + if (AttrVal($name, 'ctrlGenPVdeviation', 'daily') eq 'daily') { my $sstime = timestringToTimestamp ($date.' '.ReadingsVal ($name, "Today_SunSet", '22:00').':00'); return if($t < $sstime); - + my $diff = $pvfc - $pvre; $dp = sprintf "%.2f" , (100 * $diff / $pvre); } @@ -7762,7 +7764,7 @@ sub _calcTodayPVdeviation { my $dayfc = $pvre + $rodfc; # laufende Tagesprognose aus PVreal + Prognose Resttag $dp = sprintf "%.2f", (100 * ($pvfc - $dayfc) / $dayfc); } - + $data{$type}{$name}{circular}{99}{tdayDvtn} = $dp; storeReading ('Today_PVdeviation', $dp.' %'); @@ -8009,14 +8011,14 @@ sub genStatisticReadings { $dono = $don; } - + my $sttmp = timestringToTimestamp ($sttm) // return; - $sttmp += 3600; # Beginnzeitstempel auf volle Stunde ergänzen + $sttmp += 3600; # Beginnzeitstempel auf volle Stunde ergänzen my $mhrs = $hrs * 60; # berücksichtigte volle Minuten my $mtsr = ($sttmp - $t) / 60; # Minuten bis nächsten Sonnenaufgang (gerundet) $confc = $confc / $mhrs * $mtsr; - + storeReading ('statistic_'.$kpi, ($confc ? (sprintf "%.0f", $confc).$hcsr{$kpi}{unit} : '-')); } } @@ -8085,7 +8087,7 @@ sub collectAllRegConsumers { if(exists $hc->{asynchron}) { $asynchron = $hc->{asynchron}; } - + my $noshow; if(exists $hc->{noshow}) { # Consumer ausblenden in Grafik $noshow = $hc->{noshow}; @@ -8596,7 +8598,7 @@ sub _graphicHeader { my $hdrDetail = $paref->{hdrDetail}; # ermöglicht den Inhalt zu begrenzen, um bspw. passgenau in ftui einzubetten my $ftui = $paref->{ftui}; my $lang = $paref->{lang}; - my $name = $paref->{name}; + my $name = $paref->{name}; my $hash = $paref->{hash}; my $kw = $paref->{kw}; my $dstyle = $paref->{dstyle}; # TD-Style @@ -8671,8 +8673,8 @@ sub _graphicHeader { my $chktitle = $htitles{plchk}{$lang}; ## Update-Icon - ################ - my $upicon = __createUpdateIcon ($paref); + ################ + my $upicon = __createUpdateIcon ($paref); ## Sonnenauf- und untergang ############################ @@ -8818,11 +8820,11 @@ sub _graphicHeader { $tdayDvtn =~ s/\,0//; $ydayDvtn =~ s/\./,/; $ydayDvtn =~ s/,0//; - + my $genpvdva = $paref->{genpvdva}; my $dvtntxt = $hqtxt{dvtn}{$lang}.' '; - my $tdaytxt = ($genpvdva eq 'daily' ? $hqtxt{tday}{$lang} : $hqtxt{ctnsly}{$lang}).': '."".$tdayDvtn.""; + my $tdaytxt = ($genpvdva eq 'daily' ? $hqtxt{tday}{$lang} : $hqtxt{ctnsly}{$lang}).': '."".$tdayDvtn.""; my $ydaytxt = $hqtxt{yday}{$lang}.': '."".$ydayDvtn.""; my $text_tdayDvtn = $tdayDvtn =~ /^-[1-9]/? $hqtxt{pmtp}{$lang} : @@ -8895,7 +8897,7 @@ sub _graphicHeader { $header .= qq{