76_SolarForecast: contrib V1.57.0

git-svn-id: https://svn.fhem.de/fhem/trunk@30184 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
DS_Starter
2025-08-07 20:55:38 +00:00
parent a21b6b6f23
commit 66ad3b17da

View File

@@ -160,6 +160,7 @@ BEGIN {
# Versions History intern
my %vNotesIntern = (
"1.57.0" => "08.08.2025 new option attr graphicControl->scaleMode=X:staple ",
"1.56.0" => "07.08.2025 set MAXINVERTER to 5 ",
"1.55.0" => "06.08.2025 DWD-Weather and DWD-Radiation device new minimum value of attr 'forecastDays' is 2 ".
"checkPlantConfig: check forecastDays of new minimum value ".
@@ -6500,18 +6501,18 @@ sub _attrgraphicControl { ## no critic "not used"
my $cmd = $paref->{cmd};
my $valid = {
beamPaddingBottom => { comp => '\d+', act => 0 },
beamPaddingTop => { comp => '\d+', act => 0 },
beamWidth => { comp => '([2-9][0-9]|100)', act => 0 },
energyUnit => { comp => '(Wh|kWh)', act => 0 },
beamHeightlevel => { comp => '(?:[1-3]:(?:[1-9][0-9]*))(?:,(?:[1-3]:(?:[1-9][0-9]*)))*', act => 0 },
headerDetail => { comp => '.*', act => 1 },
hourCount => { comp => '([4-9]|1[0-9]|2[0-4])', act => 0 },
hourStyle => { comp => ':(0{1,2})', act => 0 },
layoutType => { comp => '(single|double|diff)', act => 0 },
scaleMode => { comp => '(?:[1-3]:(?:log|lin))(?:,(?:[1-3]:(?:log|lin)))*', act => 0 },
showDiff => { comp => '(?:[1-3]:(?:top|bottom))(?:,(?:[1-3]:(?:top|bottom)))*', act => 0 },
spaceSize => { comp => '\d+', act => 0 },
beamPaddingBottom => { comp => '\d+', act => 0 },
beamPaddingTop => { comp => '\d+', act => 0 },
beamWidth => { comp => '([2-9][0-9]|100)', act => 0 },
energyUnit => { comp => '(Wh|kWh)', act => 0 },
beamHeightlevel => { comp => '(?:[1-3]:(?:[1-9][0-9]*))(?:,(?:[1-3]:(?:[1-9][0-9]*)))*', act => 0 },
headerDetail => { comp => '.*', act => 1 },
hourCount => { comp => '([4-9]|1[0-9]|2[0-4])', act => 0 },
hourStyle => { comp => ':(0{1,2})', act => 0 },
layoutType => { comp => '(single|double|diff)', act => 0 },
scaleMode => { comp => '(?:[1-3]:(?:log|lin|staple))(?:,(?:[1-3]:(?:log|lin|staple)))*', act => 0 },
showDiff => { comp => '(?:[1-3]:(?:top|bottom))(?:,(?:[1-3]:(?:top|bottom)))*', act => 0 },
spaceSize => { comp => '\d+', act => 0 },
};
my ($a, $h) = parseParams ($aVal);
@@ -17228,14 +17229,15 @@ sub _beamGraphic {
# lässt sich durch einbetten in eine zusätzliche Table roomoverview eindämmen
# Die Tabelle ist recht schmal angelegt, aber nur so lassen sich Umbrüche erzwingen
my ($val, $z2, $z3, $z4, $he, $titz2, $titz3);
my ($val, $z2, $z3, $z4, $z1, $titz2, $titz3);
$paref->{beampos} = 'top'; # Lagedefinition "über den Balken"
my $ret = q{};
my $colspan = $maxhours + 2;
my $m = $paref->{modulo} % 2;
$maxVal = 1.1 if(!int $maxVal); # maxVal devision by zero & log(x) Problem
$maxVal = 1.1 if(!int $maxVal); # devision by zero & log(x) Problem
$maxStVal = 1.1 if(!int $maxStVal); # devision by zero Problem
## zusätzlicher Abstand vor der ersten Reihe
##############################################
@@ -17283,7 +17285,8 @@ sub _beamGraphic {
$ret .= "<tr class='$htr{$m}{cl}'><td class='solarfc'></td>"; # Neue Zeile mit freiem Platz am Anfang
my $ii = 0;
my $ii = 0;
my $mbdf = 0;
for my $i (0..($maxhours * 2) - 1) { # gleiche Bedingung wie oben
next if(__dontNightshowSkipSync ($name, $paref, $i));
@@ -17296,8 +17299,9 @@ sub _beamGraphic {
# Berechnung der Zonen
########################
if ($lotype eq 'single') {
$he = __normBeamHeight ( { val => $maxVal - $hfcg->{$i}{beam1},
$z1 = __normBeamHeight ( { val => $maxVal - $hfcg->{$i}{beam1},
maxVal => $maxVal,
maxStVal => $maxStVal,
height => $height,
ground => 0,
scalemode => 'lin'
@@ -17312,25 +17316,36 @@ sub _beamGraphic {
# he - freier der Raum über den Balken. spacesz wird nicht verwendet, da bei diesem Typ keine Zahlen über den Balken stehen
# z2 - primärer Balkenwert ggf. mit Icon
# z3 - sekundärer Balkenwert, bei zu kleinem Wert wird der Platz komplett Zone 2 zugeschlagen und nicht angezeigt
# z2 und z3 nach Bedarf tauschen, wenn sekundärer Balkenwert > primärer Balkenwert
# z2 und z3 nach Bedarf tauschen, wenn sekundärer Balkenwert > primärer Balkenwert (außer bei 'staple')
if ($hfcg->{$i}{beam1} > $hfcg->{$i}{beam2}) {
if ($scm eq 'staple') {
$z2 = $hfcg->{$i}{beam1};
$z3 = $hfcg->{$i}{beam2};
$titz2 = qq/title="$hfcg->{0}{beam1txt}"/;
$titz3 = qq/title="$hfcg->{0}{beam2txt}"/;
$mbdf = $maxStVal - ($z2 + $z3); # Wertedifferenz abs. Maxwert und größerem Balkenwert
}
else { # tauschen, Betrag Beam1 < Betrag Beam2
$z2 = $hfcg->{$i}{beam2};
$z3 = $hfcg->{$i}{beam1};
$titz2 = qq/title="$hfcg->{0}{beam2txt}"/;
$titz3 = qq/title="$hfcg->{0}{beam1txt}"/;
else {
if ($hfcg->{$i}{beam1} >= $hfcg->{$i}{beam2}) {
$z2 = $hfcg->{$i}{beam1};
$z3 = $hfcg->{$i}{beam2};
$titz2 = qq/title="$hfcg->{0}{beam1txt}"/;
$titz3 = qq/title="$hfcg->{0}{beam2txt}"/;
}
else { # tauschen, Betrag Beam1 < Betrag Beam2
$z2 = $hfcg->{$i}{beam2};
$z3 = $hfcg->{$i}{beam1};
$titz2 = qq/title="$hfcg->{0}{beam2txt}"/;
$titz3 = qq/title="$hfcg->{0}{beam1txt}"/;
}
$mbdf = $maxVal - $z2; # Wertedifferenz abs. Maxwert und größerem Balkenwert
}
$he = __normBeamHeight ( { val => $maxVal - $z2, maxVal => $maxVal, height => $height, ground => 0, scalemode => 'lin' } );
$z2 = __normBeamHeight ( { val => $z2, maxVal => $maxVal, height => $height, ground => 0, scalemode => $scm } );
$z3 = __normBeamHeight ( { val => $z3, maxVal => $maxVal, height => $height, ground => 0, scalemode => $scm } );
$z2 -= $z3 if($scm eq 'lin'); # effektive Stapelhöhe, da $z2 + $z3 übereinander dargestellt wird
$z1 = __normBeamHeight ( { val => $mbdf, maxVal => $maxVal, height => $height, ground => 0, scalemode => 'lin' } );
$z2 = __normBeamHeight ( { val => $z2, maxVal => $maxVal, height => $height, ground => 0, scalemode => $scm } );
$z3 = __normBeamHeight ( { val => $z3, maxVal => $maxVal, height => $height, ground => 0, scalemode => $scm } );
$z2 -= $z3 if($scm eq 'lin'); # effektive Stapelhöhe, da $z2 + $z3 übereinander dargestellt wird
if ($scm eq 'log' && $z2) {
my $z3perc = int (100 / $z2 * $z3);
@@ -17382,13 +17397,13 @@ sub _beamGraphic {
$titz2 = qq/title="$hfcg->{0}{beam1txt}"/;
$titz3 = qq/title="$hfcg->{0}{beam2txt}"/;
# Alle vorbesetzen Werte umrechnen auf echte Ausgabe px
$he = (!$px_pos || !$maxDif) ? 0 : int(($maxDif-$z2) / $maxDif * $px_pos); # Teilung durch 0 vermeiden
$z2 = ($px_pos - $he) ;
$z1 = (!$px_pos || !$maxDif) ? 0 : int(($maxDif-$z2) / $maxDif * $px_pos); # Teilung durch 0 vermeiden
$z2 = ($px_pos - $z1) ;
$z4 = (!$px_neg || !$minDif) ? 0 : int((abs($minDif)-$z3) / abs($minDif) * $px_neg); # Teilung durch 0 unbedingt vermeiden
$z3 = ($px_neg - $z4);
# Beiden Zonen die Werte ausgeben könnten muß spacesz als zusätzlicher Raum zugeschlagen werden !
$he += $spacesz;
$z1 += $spacesz;
$z4 += $spacesz if($z3); # komplette Grafik ohne negativ Balken, keine Ausgabe von z3 & z4
}
@@ -17400,14 +17415,14 @@ sub _beamGraphic {
$ret .="<td style='text-align: center; padding-left:1px; padding-right:1px; margin:0px; vertical-align:bottom; padding-top:0px'>\n";
$he /= 10; # freier der Raum über den Balken
$he = $he < 20 ? 20 : $he;
$z1 /= 10; # freier der Raum über den Balken
$z1 = $z1 < 20 ? 20 : $z1;
if ($lotype eq 'single') {
$val = normBeamWidth ($paref, 'beam1', $i, 'beam1');
$ret .="<table width='100%' height='100%'>"; # mit width=100% etwas bessere Füllung der Balken
$ret .="<tr class='$htr{$m}{cl}' style='height:".$he."px'>";
$ret .="<tr class='$htr{$m}{cl}' style='height:".$z1."px'>";
$ret .="<td class='solarfc' style='vertical-align:bottom; color:#$fcolor1;' $titz3>".$val;
$ret .="</td></tr>";
@@ -17431,15 +17446,15 @@ sub _beamGraphic {
my $style = "style='padding-bottom:0px; padding-top:1px; vertical-align:top; margin-left:auto; margin-right:auto;";
$ret .="<table width='100%' height='100%'>\n"; # mit width=100% etwas bessere Füllung der Balken
$ret .="<tr class='$htr{$m}{cl}' style='height:".$he."px'><td class='solarfc'></td></tr>"; # Freiraum über den Balken einfügen
$ret .="<table width='100%' height='100%'>\n"; # mit width=100% etwas bessere Füllung der Balken
$ret .="<tr class='$htr{$m}{cl}' style='height:".$z1."px'><td class='solarfc'></td></tr>"; # Freiraum über den Balken einfügen
if ($hfcg->{$i}{beam1} > $hfcg->{$i}{beam2}) { # wer ist oben, Beam2 oder Beam1 ? Wert und Farbe für Zone 2 & 3 vorbesetzen
if ($hfcg->{$i}{beam1} > $hfcg->{$i}{beam2} || $scm eq 'staple') { # wer ist oben, Beam2 oder Beam1 ? Wert und Farbe für Zone 2 & 3 vorbesetzen
$val = normBeamWidth ($paref, 'beam1', $i, 'beam1');
$color1 = $colorb1;
$style1 = $style." background-color:#$color1; color:#$fcolor1;'";
if ($z3) { # die Zuweisung können wir uns sparen wenn Zone 3 nachher eh nicht ausgegeben wird
if ($z3) { # die Zuweisung können wir uns sparen wenn Zone 3 nachher eh nicht ausgegeben wird
$v = normBeamWidth ($paref, 'beam2', $i, 'beam2');
$color2 = $colorb2;
$style2 = $style." background-color:#$color2; color:#$fcolor2;'";
@@ -17481,7 +17496,7 @@ sub _beamGraphic {
$val = '&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;' if($hfcg->{$i}{diff} == 0); # Sonderfall , hier wird die 0 gebraucht !
if ($val) {
$ret .= "<tr class='$htr{$m}{cl}' style='height:".$he."px'>";
$ret .= "<tr class='$htr{$m}{cl}' style='height:".$z1."px'>";
$ret .= "<td class='solarfc' style='vertical-align:bottom; color:#$fcolor1;'>".$val;
$ret .= "</td></tr>";
}
@@ -17622,14 +17637,17 @@ sub __normBeamHeight {
my $maxVal = $paref->{maxVal};
my $height = $paref->{height};
my $ground = $paref->{ground} // 0; # eine minimale Balkenhöhe die immer eingehalten werden soll
my $scalemode = $paref->{scalemode} // 'lin'; # lin / log
my $scalemode = $paref->{scalemode} // 'lin'; # lin / log / staple
my $px = 0;
if ($scalemode eq 'lin') {
$px = $ground + (($val / $maxVal) * ($height - $ground));
}
elsif ($val * 1 > 0) { # logarithmische Anzeige wenn Mode log, kein Logarithmus für negative Zahlen
elsif ($scalemode eq 'staple') {
$px = $ground + (($val / $maxVal) * ($height - $ground));
}
elsif ($scalemode eq 'log' && $val * 1 > 0) { # logarithmische Anzeige wenn Mode log, kein Logarithmus für negative Zahlen
$px = $ground + ((log ($val) / log ($maxVal)) * ($height - $ground));
}
@@ -26943,7 +26961,8 @@ to ensure that the system configuration is correct.
<tr><td> </td><td>The strings for each level are separated by commas (see example). </td></tr>
<tr><td> </td><td><b>&lt;Level&gt;:lin</b> - linear scaling (default) </td></tr>
<tr><td> </td><td><b>&lt;Level&gt;:log</b> - logarithmic scaling </td></tr>
<tr><td> </td><td> </td></tr>
<tr><td> </td><td><b>&lt;Ebene&gt;:staple</b> - The bars are stacked, with the secondary bar displayed above the primary bar. </td></tr>
<tr><td> </td><td> </td></tr>
<tr><td> <b>showDiff</b> </td><td>Additional numerical display of the difference '&lt;primary bar content&gt; - &lt;secondary bar content&gt;'. </td></tr>
<tr><td> </td><td>The specification for each level consists of the level number (1..X), a ':' followed by the position 'top' or 'bottom'. </td></tr>
<tr><td> </td><td>The strings for each level are separated by commas (see example). </td></tr>
@@ -29599,7 +29618,8 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<tr><td> </td><td>Die Strings für jede Ebene werden durch Komma getrennt (siehe Beispiel). </td></tr>
<tr><td> </td><td><b>&lt;Ebene&gt;:lin</b> - lineare Skalierung (default) </td></tr>
<tr><td> </td><td><b>&lt;Ebene&gt;:log</b> - logarithmische Skalierung </td></tr>
<tr><td> </td><td> </td></tr>
<tr><td> </td><td><b>&lt;Ebene&gt;:staple</b> - die Balken werden 'gestapelt', der sekundäre Balken wird über dem primären Balken dargestellt </td></tr>
<tr><td> </td><td> </td></tr>
<tr><td> <b>showDiff</b> </td><td>Zusätzliche numerische Anzeige der Differenz '&lt;primärer Balkeninhalt&gt; - &lt;sekundärer Balkeninhalt&gt;'. </td></tr>
<tr><td> </td><td>Die Angabe für jede Ebene besteht aus der Ebenen-Nummer (1..X), einem ':' gefolgt von der Position 'top' oder 'bottom'. </td></tr>
<tr><td> </td><td>Die Strings für jede Ebene werden durch Komma getrennt (siehe Beispiel). </td></tr>