From bd64672cbc977db2d22a57a3d43433c425a80095 Mon Sep 17 00:00:00 2001 From: nasseeder1 Date: Wed, 2 Jun 2021 21:26:06 +0000 Subject: [PATCH] 76_SolarForecast.pm: contrib 0.50.2 git-svn-id: https://svn.fhem.de/fhem/trunk@24569 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/contrib/DS_Starter/76_SolarForecast.pm | 318 ++++++++++++-------- 1 file changed, 192 insertions(+), 126 deletions(-) diff --git a/fhem/contrib/DS_Starter/76_SolarForecast.pm b/fhem/contrib/DS_Starter/76_SolarForecast.pm index 124778328..8e0833c63 100644 --- a/fhem/contrib/DS_Starter/76_SolarForecast.pm +++ b/fhem/contrib/DS_Starter/76_SolarForecast.pm @@ -117,6 +117,8 @@ BEGIN { # Versions History intern my %vNotesIntern = ( + "0.50.2" => "01.06.2021 more refactoring, delete attr headerAlignment, consumerlegend as table ", + "0.50.1" => "01.06.2021 switch to mathematical rounding of cloudiness range ", "0.50.0" => "01.06.2021 real switch off time in consumerXX_planned_stop when finished, change key 'ready' to 'auto' ". "consider switch on Time limits (consumer keys notbefore/notafter) ", "0.49.5" => "01.06.2021 change pv correction factor to 1 if no historical factors found (only with automatic correction) ", @@ -284,14 +286,14 @@ my %hqtxt = ( ); my %htitles = ( # Hash Hilfetexte - iaaf => { EN => qq{Off (automatic mode off) -> Enable automatic mode}, - DE => qq{Aus (Automatikmodus aus) -> Automatik freigeben} }, - iave => { EN => qq{Off (automatic mode) -> Switch on consumer}, - DE => qq{Aus (Automatikmodus) -> Verbraucher einschalten} }, - ieas => { EN => qq{On (automatic mode) -> Lock automatic mode}, - DE => qq{Ein (Automatikmodus) -> Automatik sperren} }, - ieva => { EN => qq{On (automatic mode off) -> Switch off consumer}, - DE => qq{Ein (Automatikmodus aus) -> Verbraucher ausschalten} }, + iaaf => { EN => qq{Automatic mode off -> Enable automatic mode}, + DE => qq{Automatikmodus aus -> Automatik freigeben} }, + ieas => { EN => qq{Automatic mode on -> Lock automatic mode}, + DE => qq{Automatikmodus ein -> Automatik sperren} }, + iave => { EN => qq{Off -> Switch on consumer}, + DE => qq{Aus -> Verbraucher einschalten} }, + ieva => { EN => qq{On -> Switch off consumer}, + DE => qq{Ein -> Verbraucher ausschalten} }, upd => { EN => qq{Update}, DE => qq{Update} }, on => { EN => qq{switched on}, @@ -302,6 +304,12 @@ my %htitles = ( DE => qq{undefiniert} }, dela => { EN => qq{delayed}, DE => qq{verzoegert} }, + cnsm => { EN => qq{Consumer}, + DE => qq{Verbraucher} }, + eiau => { EN => qq{On/Off}, + DE => qq{Ein/Aus} }, + auto => { EN => qq{Automatic}, + DE => qq{Automatik} }, ); my %weather_ids = ( @@ -510,8 +518,7 @@ sub Initialize { "flowGraphicAnimate:1,0 ". "follow70percentRule:1,dynamic,0 ". "forcePageRefresh:1,0 ". - "graphicSelect:both,flow,forecast ". - "headerAlignment:center,left,right ". + "graphicSelect:both,flow,forecast ". "headerDetail:all,co,pv,pvco,statusLink ". "historyHour:slider,-23,-1,0 ". "hourCount:slider,4,1,24 ". @@ -3484,6 +3491,7 @@ sub entryGraphic { name => $name, ftui => $ftui, maxhours => $maxhours, + dstyle => qq{style='padding-left: 10px; padding-right: 10px; padding-top: 3px; padding-bottom: 3px;'}, # TD-Style offset => AttrNum ($name, 'historyHour', 0), hourstyle => AttrVal ($name, 'hourStyle', ''), colorfc => AttrVal ($name, 'beam1Color', '000000'), @@ -3509,7 +3517,6 @@ sub entryGraphic { colorwn => AttrVal ($name, 'weatherColorNight', $colorw), # Wetter Icon Farbe Nacht wlalias => AttrVal ($name, 'alias', $name), header => AttrNum ($name, 'showHeader', 1), - hdrAlign => AttrVal ($name, 'headerAlignment', 'center'), # ermöglicht per attr die Ausrichtung der Tabelle zu setzen hdrDetail => AttrVal ($name, 'headerDetail', 'all'), # ermöglicht den Inhalt zu begrenzen, um bspw. passgenau in ftui einzubetten lang => AttrVal ("global", 'language', 'EN'), flowgh => AttrVal ($name, 'flowGraphicSize', $defflowGSize), # Größe Energieflußgrafik @@ -3608,9 +3615,9 @@ sub forecastGraphic { ## no critic 'complexity' my $hash = $paref->{hash}; my $name = $paref->{name}; my $ftui = $paref->{ftui}; - - my $hfcg = $data{$hash->{TYPE}}{$name}{html}; #(hfcg = hash forecast graphic) + my $type = $hash->{TYPE}; + my $hfcg = {}; #(hfcg = hash forecast graphic) # Verbraucherlegende und Steuerung ################################### @@ -3620,10 +3627,8 @@ sub forecastGraphic { ## no critic 'complexity' $paref->{consumersref} = \@consumers; $paref->{clegend} = $clegend; $paref->{clegendstyle} = $clegendstyle; - my $legendtxt = _forecastGraphicConsumerLegend ($paref); - # Parameter f. Anzeige extrahieren ################################### my $maxhours = $paref->{maxhours}; @@ -3666,62 +3671,16 @@ sub forecastGraphic { ## no critic 'complexity' $header = _forecastGraphicHeader ($paref); # Werte aktuelle Stunde - ########################## - my $day; + ########################## + $paref->{hfcg} = $hfcg; + my $back = _forecastGraphicFirstHour ($paref); + my $val1 = $back->{val1}; + my $val2 = $back->{val2}; + my $val3 = $back->{val3}; + my $val4 = $back->{val4}; + my $thishour = $back->{thishour}; + $hfcg = $back->{hfcg}; - my $t = NexthoursVal ($hash, "NextHour00", "starttime", '0000-00-00 24'); - my ($year,$month,$day_str,$thishour) = $t =~ m/(\d{4})-(\d{2})-(\d{2})\s(\d{2})/x; - - $thishour++; - - $hfcg->{0}{time_str} = $thishour; - $thishour = int($thishour); # keine führende Null - - $hfcg->{0}{time} = $thishour; - $hfcg->{0}{day_str} = $day_str; - $day = int($day_str); - $hfcg->{0}{day} = $day; - $hfcg->{0}{mktime} = fhemTimeLocal(0,0,$thishour,$day,int($month)-1,$year-1900); # gleich die Unix Zeit dazu holen - - my $val1 = 0; - my $val2 = 0; - my $val3 = 0; - my $val4 = 0; - - if ($offset) { - $hfcg->{0}{time} += $offset; - - if ($hfcg->{0}{time} < 0) { - $hfcg->{0}{time} += 24; - my $n_day = strftime "%d", localtime($hfcg->{0}{mktime} - (3600 * abs($offset))); # Achtung : Tageswechsel - day muss jetzt neu berechnet werden ! - $hfcg->{0}{day} = int($n_day); - $hfcg->{0}{day_str} = $n_day; - } - - $hfcg->{0}{time_str} = sprintf('%02d', $hfcg->{0}{time}); - - $val1 = HistoryVal ($hash, $hfcg->{0}{day_str}, $hfcg->{0}{time_str}, "pvfc", 0); - $val2 = HistoryVal ($hash, $hfcg->{0}{day_str}, $hfcg->{0}{time_str}, "pvrl", 0); - $val3 = HistoryVal ($hash, $hfcg->{0}{day_str}, $hfcg->{0}{time_str}, "gcons", 0); - $val4 = HistoryVal ($hash, $hfcg->{0}{day_str}, $hfcg->{0}{time_str}, "confc", 0); - - # $hfcg->{0}{weather} = CircularVal ($hash, $hfcg->{0}{time_str}, "weatherid", undef); - $hfcg->{0}{weather} = HistoryVal ($hash, $hfcg->{0}{day_str}, $hfcg->{0}{time_str}, "weatherid", undef); - } - else { - $val1 = CircularVal ($hash, $hfcg->{0}{time_str}, "pvfc", 0); - $val2 = CircularVal ($hash, $hfcg->{0}{time_str}, "pvrl", 0); - $val3 = CircularVal ($hash, $hfcg->{0}{time_str}, "gcons", 0); - $val4 = CircularVal ($hash, $hfcg->{0}{time_str}, "confc", 0); - - $hfcg->{0}{weather} = CircularVal ($hash, $hfcg->{0}{time_str}, "weatherid", undef); - #$val4 = (ReadingsVal($name,"ThisHour_IsConsumptionRecommended",'no') eq 'yes' ) ? $icon : undef; - } - - $hfcg->{0}{time_str} = sprintf('%02d', $hfcg->{0}{time}-1).$hourstyle; - $hfcg->{0}{beam1} = ($beam1cont eq 'pvForecast') ? $val1 : ($beam1cont eq 'pvReal') ? $val2 : ($beam1cont eq 'gridconsumption') ? $val3 : $val4; - $hfcg->{0}{beam2} = ($beam2cont eq 'pvForecast') ? $val1 : ($beam2cont eq 'pvReal') ? $val2 : ($beam2cont eq 'gridconsumption') ? $val3 : $val4; - $hfcg->{0}{diff} = $hfcg->{0}{beam1} - $hfcg->{0}{beam2}; # get consumer list and display it in Graphics ################################################ @@ -4187,9 +4146,16 @@ sub _forecastGraphicConsumerLegend { my $ftui = $paref->{ftui}; my $clegendstyle = $paref->{clegendstyle}; my $lang = $paref->{lang}; + my $dstyle = $paref->{dstyle}; # TD-Style - my ($legendtxt,$staticon); - my @clegends; + my ($staticon); + + ## Tabelle Start + ################# + my $ctable = qq{}; + $ctable .= qq{}; + $ctable .= qq{}; + $ctable .= qq{}; for my $c (@{$consumersref}) { my $cname = ConsumerVal ($hash, $c, "name", ""); # Name des Consumerdevices @@ -4218,38 +4184,47 @@ sub _forecastGraphicConsumerLegend { $cmdautooff = q{} if(!$autord); my $swstate = ConsumerVal ($hash, $c, "state", "undef"); # Schaltzustand des Consumerdevices - my $swicon = ""; + my $swicon = q{}; + my $auicon = q{}; - if($cmdautoon && $swstate eq "off" && !$auto) { + $ctable .= qq{}; + + if(!$auto) { $staticon = FW_makeImage('ios_off_fill@red', $htitles{iaaf}{$lang}); - $swicon = " $staticon"; + $auicon = " $staticon"; } - elsif ($cmdon && $swstate eq "off") { - $staticon = FW_makeImage('ios_off_till_fill@orange', $htitles{iave}{$lang}); + + if ($auto) { + $staticon = FW_makeImage('ios_on_till_fill@orange', $htitles{ieas}{$lang}); + $auicon = " $staticon"; + } + + if ($cmdon && $swstate eq "off") { + $staticon = FW_makeImage('ios_off_fill@red', $htitles{iave}{$lang}); $swicon = " $staticon"; } - elsif ($cmdautooff && $swstate eq "on" && $auto) { - $staticon = FW_makeImage('ios_on_till_fill@green', $htitles{ieas}{$lang}); - $swicon = " $staticon"; - } - elsif ($cmdoff && $swstate eq "on") { + + if ($cmdoff && $swstate eq "on") { $staticon = FW_makeImage('ios_on_fill@green', $htitles{ieva}{$lang}); $swicon = " $staticon"; } - if ($clegendstyle eq 'icon') { # mögliche Umbruchstellen mit normalen Blanks vorsehen ! - push @clegends, $calias.' '.FW_makeImage($cicon).' '.$swicon; + if ($clegendstyle eq 'icon') { + $cicon = FW_makeImage($cicon); + $ctable .= ""; } else { my (undef,$co) = split('\@',$cicon); - $co = '#cccccc' if (!$co); # Farbe per default - push @clegends, ''.$calias.' '.$swicon; + $co = '#cccccc' if (!$co); + $ctable .= ""; } + + $ctable .= qq{}; } - $legendtxt = join("  |  ", @clegends); + $ctable .= qq{
$htitles{cnsm}{$lang}$htitles{eiau}{$lang}$htitles{auto}{$lang}
$calias$cicon$swicon$auicon$calias $swicon$auicon
}; -return $legendtxt; +return $ctable; } ################################################################ @@ -4261,13 +4236,13 @@ sub _forecastGraphicHeader { return if(!$header); - my $hdrAlign = $paref->{hdrAlign}; # ermöglicht per attr die Ausrichtung der Tabelle zu setzen 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 $hash = $paref->{hash}; my $kw = $paref->{kw}; + my $dstyle = $paref->{dstyle}; # TD-Style my $lup = ReadingsTimestamp ($name, ".lastupdateForecastValues", "0000-00-00 00:00:00"); # letzter Forecast Update @@ -4314,7 +4289,7 @@ sub _forecastGraphicHeader { my $lblPv4h = "next 4h:"; my $lblPvRe = "remain today:"; my $lblPvTo = "tomorrow:"; - my $lblPvCu = "actual"; + my $lblPvCu = "actual:"; if($lang eq "DE") { # Header globales Sprachschema Deutsch $lupt = "Stand:"; @@ -4323,10 +4298,12 @@ sub _forecastGraphicHeader { $lblPv4h = encode("utf8", "nächste 4h:"); $lblPvRe = "Rest heute:"; $lblPvTo = "morgen:"; - $lblPvCu = "aktuell"; + $lblPvCu = "aktuell:"; } - - $header = ""; + + ## Header Start + ################# + $header = qq{
}; # Header Link + Status + Update Button ######################################### @@ -4338,10 +4315,10 @@ sub _forecastGraphicHeader { $lup = "$day.$month.$year $time"; } - my $cmdupdate = "\"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=get $name data')\""; # Update Button generieren + my $cmdupdate = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=get $name data')"}; # Update Button generieren if ($ftui eq "ftui") { - $cmdupdate = "\"ftui.setFhemStatus('get $name data')\""; + $cmdupdate = qq{"ftui.setFhemStatus('get $name data')"}; } my $upstate = ReadingsVal($name, "state", ""); @@ -4398,19 +4375,20 @@ sub _forecastGraphicHeader { ####################### my $alias = AttrVal ($name, "alias", $name ); # Linktext als Aliasname my $dlink = qq{$alias}; - $header .= ""; - $header .= ""; + + $header .= ""; + $header .= ""; } # Header Information pv ######################## if($hdrDetail eq "all" || $hdrDetail eq "pv" || $hdrDetail eq "pvco") { $header .= ""; - $header .= ""; - $header .= ""; - $header .= ""; - $header .= ""; - $header .= ""; + $header .= ""; + $header .= ""; + $header .= ""; + $header .= ""; + $header .= ""; $header .= ""; } @@ -4419,11 +4397,11 @@ sub _forecastGraphicHeader { ######################## if($hdrDetail eq "all" || $hdrDetail eq "co" || $hdrDetail eq "pvco") { $header .= ""; - $header .= ""; - $header .= ""; - $header .= ""; - $header .= ""; - $header .= ""; + $header .= ""; + $header .= ""; + $header .= ""; + $header .= ""; + $header .= ""; $header .= ""; } @@ -4432,6 +4410,82 @@ sub _forecastGraphicHeader { return $header; } +################################################################ +# Werte aktuelle Stunde für forecastGraphic +################################################################ +sub _forecastGraphicFirstHour { + my $paref = shift; + my $hash = $paref->{hash}; + my $hfcg = $paref->{hfcg}; + my $offset = $paref->{offset}; + my $hourstyle = $paref->{hourstyle}; + my $beam1cont = $paref->{beam1cont}; + my $beam2cont = $paref->{beam2cont}; + + my $day; + + my $t = NexthoursVal ($hash, "NextHour00", "starttime", '0000-00-00 24'); + my ($year,$month,$day_str,$thishour) = $t =~ m/(\d{4})-(\d{2})-(\d{2})\s(\d{2})/x; + my ($val1,$val2,$val3,$val4) = (0,0,0,0); + + $thishour++; + + $hfcg->{0}{time_str} = $thishour; + $thishour = int($thishour); # keine führende Null + + $hfcg->{0}{time} = $thishour; + $hfcg->{0}{day_str} = $day_str; + $day = int($day_str); + $hfcg->{0}{day} = $day; + $hfcg->{0}{mktime} = fhemTimeLocal(0,0,$thishour,$day,int($month)-1,$year-1900); # gleich die Unix Zeit dazu holen + + if ($offset) { + $hfcg->{0}{time} += $offset; + + if ($hfcg->{0}{time} < 0) { + $hfcg->{0}{time} += 24; + my $n_day = strftime "%d", localtime($hfcg->{0}{mktime} - (3600 * abs($offset))); # Achtung : Tageswechsel - day muss jetzt neu berechnet werden ! + $hfcg->{0}{day} = int($n_day); + $hfcg->{0}{day_str} = $n_day; + } + + $hfcg->{0}{time_str} = sprintf('%02d', $hfcg->{0}{time}); + + $val1 = HistoryVal ($hash, $hfcg->{0}{day_str}, $hfcg->{0}{time_str}, "pvfc", 0); + $val2 = HistoryVal ($hash, $hfcg->{0}{day_str}, $hfcg->{0}{time_str}, "pvrl", 0); + $val3 = HistoryVal ($hash, $hfcg->{0}{day_str}, $hfcg->{0}{time_str}, "gcons", 0); + $val4 = HistoryVal ($hash, $hfcg->{0}{day_str}, $hfcg->{0}{time_str}, "confc", 0); + + # $hfcg->{0}{weather} = CircularVal ($hash, $hfcg->{0}{time_str}, "weatherid", undef); + $hfcg->{0}{weather} = HistoryVal ($hash, $hfcg->{0}{day_str}, $hfcg->{0}{time_str}, "weatherid", undef); + } + else { + $val1 = CircularVal ($hash, $hfcg->{0}{time_str}, "pvfc", 0); + $val2 = CircularVal ($hash, $hfcg->{0}{time_str}, "pvrl", 0); + $val3 = CircularVal ($hash, $hfcg->{0}{time_str}, "gcons", 0); + $val4 = CircularVal ($hash, $hfcg->{0}{time_str}, "confc", 0); + + $hfcg->{0}{weather} = CircularVal ($hash, $hfcg->{0}{time_str}, "weatherid", undef); + #$val4 = (ReadingsVal($name,"ThisHour_IsConsumptionRecommended",'no') eq 'yes' ) ? $icon : undef; + } + + $hfcg->{0}{time_str} = sprintf('%02d', $hfcg->{0}{time}-1).$hourstyle; + $hfcg->{0}{beam1} = ($beam1cont eq 'pvForecast') ? $val1 : ($beam1cont eq 'pvReal') ? $val2 : ($beam1cont eq 'gridconsumption') ? $val3 : $val4; + $hfcg->{0}{beam2} = ($beam2cont eq 'pvForecast') ? $val1 : ($beam2cont eq 'pvReal') ? $val2 : ($beam2cont eq 'gridconsumption') ? $val3 : $val4; + $hfcg->{0}{diff} = $hfcg->{0}{beam1} - $hfcg->{0}{beam2}; + + my $back = { + val1 => $val1, + val2 => $val2, + val3 => $val3, + val4 => $val4, + thishour => $thishour, + hfcg => $hfcg, + }; + +return ($back); +} + ################################################################ # Energieflußgrafik ################################################################ @@ -4777,7 +4831,7 @@ sub calcPVforecast { my $cloudcover = NexthoursVal ($hash, "NextHour".sprintf("%02d",$num), "cloudcover", 0); # effektive Wolkendecke nächste Stunde X my $ccf = 1 - ((($cloudcover - $cloud_base)/100) * $clouddamp/100); # Cloud Correction Faktor mit Steilheit und Fußpunkt - my $range = int ($cloudcover/10); # Range errechnen + my $range = calcCloudRange ($cloudcover); # V 0.50.1 # Range errechnen ## Ermitteln des relevanten Autokorrekturfaktors if ($uac eq "on") { # Autokorrektur soll genutzt werden @@ -4793,7 +4847,8 @@ sub calcPVforecast { $hc = sprintf "%.2f", $hc; - $data{$type}{$name}{nexthours}{"NextHour".sprintf("%02d",$num)}{pvcorrf} = $hc."/".$hq; + $data{$type}{$name}{nexthours}{"NextHour".sprintf("%02d",$num)}{pvcorrf} = $hc."/".$hq; + $data{$type}{$name}{nexthours}{"NextHour".sprintf("%02d",$num)}{cloudrange} = $range; if($fd == 0 && $fh1) { $paref->{pvcorrf} = $hc."/".$hq; @@ -5031,19 +5086,19 @@ sub calcAvgFromHistory { if(scalar(@efa)) { Log3 ($name, 4, "$name - PV History -> Raw Days ($calcmaxd) for average check: ".join " ",@efa); } - else { # vermeide Fehler: Illegal division by zero + else { # vermeide Fehler: Illegal division by zero Log3 ($name, 4, "$name - PV History -> Day $day has index $idx. Use only current day for average calc"); return; } - my $chwcc = HistoryVal ($hash, $day, $hour, "wcc", undef); # Wolkenbedeckung Heute & abgefragte Stunde + my $chwcc = HistoryVal ($hash, $day, $hour, "wcc", undef); # Wolkenbedeckung Heute & abgefragte Stunde if(!defined $chwcc) { Log3 ($name, 4, "$name - Day $day has no cloudiness value set for hour $hour, no past averages can be calculated."); return; } - my $range = int ($chwcc/10); + my $range = calcCloudRange ($chwcc); # V 0.50.1 Log3 ($name, 4, "$name - cloudiness range of day/hour $day/$hour is: $range"); @@ -5057,8 +5112,8 @@ sub calcAvgFromHistory { Log3 ($name, 4, "$name - PV History -> Day $dayfa has no cloudiness value set for hour $hour, this history dataset is ignored."); next; } - - $histwcc = int ($histwcc/10); + + $histwcc = calcCloudRange ($histwcc); # V 0.50.1 if($range == $histwcc) { $pvrl += HistoryVal ($hash, $dayfa, $hour, "pvrl", 0); @@ -5086,6 +5141,17 @@ sub calcAvgFromHistory { return; } +################################################################ +# Bewölkungsrange berechnen +################################################################ +sub calcCloudRange { + my $range = shift; + + $range = sprintf("%.0f", $range/10); + +return $range; +} + ################################################################ # PV und PV Forecast in History-Hash speichern zur # Berechnung des Korrekturfaktors über mehrere Tage @@ -5466,13 +5532,17 @@ sub listDataPool { my $pvfc = NexthoursVal ($hash, $idx, "pvforecast", "-"); my $wid = NexthoursVal ($hash, $idx, "weatherid", "-"); my $neff = NexthoursVal ($hash, $idx, "cloudcover", "-"); + my $crange = NexthoursVal ($hash, $idx, "cloudrange", "-"); my $r101 = NexthoursVal ($hash, $idx, "rainprob", "-"); my $rad1h = NexthoursVal ($hash, $idx, "Rad1h", "-"); my $pvcorrf = NexthoursVal ($hash, $idx, "pvcorrf", "-"); my $temp = NexthoursVal ($hash, $idx, "temp", "-"); my $confc = NexthoursVal ($hash, $idx, "confc", "-"); $sq .= "\n" if($sq); - $sq .= $idx." => starttime: $nhts, today: $today, pvfc: $pvfc, confc: $confc, wid: $wid, wcc: $neff, wrp: $r101, correff: $pvcorrf, Rad1h: $rad1h, temp=$temp"; + $sq .= $idx." => starttime: $nhts, today: $today\n"; + $sq .= " pvfc: $pvfc, confc: $confc, Rad1h: $rad1h\n"; + $sq .= " wid: $wid, wcc: $neff, wrp: $r101, temp=$temp\n"; + $sq .= " crange: $crange, correff: $pvcorrf"; } } @@ -5485,11 +5555,12 @@ sub listDataPool { my $nhfc = NexthoursVal ($hash, $idx, "pvforecast", undef); next if(!$nhfc); my $nhts = NexthoursVal ($hash, $idx, "starttime", undef); - my $pvcorrf = NexthoursVal ($hash, $idx, "pvcorrf", undef); - $pvcorrf //= "-/-"; + my $neff = NexthoursVal ($hash, $idx, "cloudcover", "-"); + my $crange = NexthoursVal ($hash, $idx, "cloudrange", "-"); + my $pvcorrf = NexthoursVal ($hash, $idx, "pvcorrf", "-/-"); my ($f,$q) = split "/", $pvcorrf; $sq .= "\n" if($sq); - $sq .= "starttime: $nhts, quality: $q, used factor: $f"; + $sq .= "starttime: $nhts, wcc: $neff, crange: $crange, quality: $q, used factor: $f"; } } @@ -5889,6 +5960,7 @@ return ($pvcorrf, $quality); # pvforecast - PV Vorhersage # weatherid - DWD Wetter id # cloudcover - DWD Wolkendichte +# cloudrange - berechnete Bewölkungsrange # rainprob - DWD Regenwahrscheinlichkeit # Rad1h - Globalstrahlung (kJ/m2) # confc - Vorhersage Hausverbrauch (Wh) @@ -6456,13 +6528,14 @@ Ein/Ausschaltzeiten sowie deren Ausführung vom SolarForecast Modul übernehmen + - +
".$dlink."".$lupt. " ".$lup." ".$upicon."
".$autoct." " .$acicon."".$lbpcq." " .$pcqicon. "
".$dlink."".$lupt. " ".$lup." ".$upicon."
".$autoct." " .$acicon."".$lbpcq." " .$pcqicon. "
PV =>$lblPvCu $pvCu$lblPv4h $pv4h$lblPvRe $pvRe$lblPvTo $pvToPV =>$lblPvCu $pvCu$lblPv4h $pv4h$lblPvRe $pvRe$lblPvTo $pvTo
CO =>$lblPvCu $coCu$lblPv4h $co4h$lblPvRe $coRe$lblPvTo $coToCO =>$lblPvCu$coCu$lblPv4h$co4h$lblPvRe$coRe$lblPvTo$coTo
confc erwarteter Energieverbrauch
wid ID des vorhergesagten Wetters
wcc vorhergesagter Grad der Bewölkung
crange berechneter Bewölkungsbereich
correff effektiv verwendeter Korrekturfaktor/Qualität
Faktor/m - manuell
Faktor/0 - Korrekturfaktor nicht in Store vorhanden (default wird verwendet)
Faktor/1...X - Korrekturfaktor aus Store genutzt (höhere Zahl = bessere Qualität)
wrp vorhergesagter Grad der Regenwahrscheinlichkeit
Rad1h vorhergesagte Globalstrahlung
temp vorhergesagte Außentemperatur
temp vorhergesagte Außentemperatur
@@ -6765,13 +6838,6 @@ Ein/Ausschaltzeiten sowie deren Ausführung vom SolarForecast Modul übernehmen
- -
  • headerAlignment <center | left | right>
    - Ausrichtung der Kopfzeilen.
    - (default: center) -
  • -
    -
  • hourCount <4...24>
    Anzahl der Balken/Stunden.