From e11b15d9eba9bfb57cd530a16520052b983ccfb2 Mon Sep 17 00:00:00 2001 From: nasseeder1 Date: Sun, 12 May 2024 21:18:27 +0000 Subject: [PATCH] 76_SolarForecast: contrib 1.20.0 git-svn-id: https://svn.fhem.de/fhem/trunk@28868 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/contrib/DS_Starter/76_SolarForecast.pm | 266 ++++++++++++-------- 1 file changed, 157 insertions(+), 109 deletions(-) diff --git a/fhem/contrib/DS_Starter/76_SolarForecast.pm b/fhem/contrib/DS_Starter/76_SolarForecast.pm index fd5f07cf7..8cc93152f 100644 --- a/fhem/contrib/DS_Starter/76_SolarForecast.pm +++ b/fhem/contrib/DS_Starter/76_SolarForecast.pm @@ -158,6 +158,7 @@ BEGIN { # Versions History intern my %vNotesIntern = ( + "1.20.0" => "12.05.2024 graphicBeamXContent: gridfeedin available, beamGraphic: Mouse-Over shows beamcontent text ", "1.19.0" => "11.05.2024 conprice, feedprice saved in pvHistory, graphicBeamXContent: energycosts, feedincome available ", "1.18.0" => "08.05.2024 add secondary level of the bar chart, new attr graphicBeam3Content, graphicBeam4Content ". "graphicBeam3Color, graphicBeam4Color, graphicBeam3FontColor, graphicBeam4FontColor ". @@ -815,6 +816,22 @@ my %htitles = ( DE => qq{Höhe} }, sunpos => { EN => qq{Sun position (decimal degrees)}, DE => qq{Sonnenstand (Dezimalgrad)} }, + enconsrl => { EN => qq{real Energy consumption}, + DE => qq{realer Energieverbrauch} }, + enconsfc => { EN => qq{forecasted energy consumption}, + DE => qq{prognostizierter Energieverbrauch} }, + enpchcst => { EN => qq{Energy purchase costs}, + DE => qq{Kosten Energiebezug} }, + rengfeed => { EN => qq{Remuneration for the grid feed-in}, + DE => qq{Vergütung Netzeinspeisung} }, + enppubgd => { EN => qq{Energy purchase from the public grid}, + DE => qq{Energiebezug aus dem öffentlichen Netz} }, + enfeedgd => { EN => qq{Feed-in}, + DE => qq{Einspeisung} }, + pvgenerl => { EN => qq{real PV generation}, + DE => qq{reale PV-Erzeugung} }, + pvgenefc => { EN => qq{forecasted PV generation}, + DE => qq{prognostizierte PV-Erzeugung} }, conrec => { EN => qq{Current time is within the consumption planning}, DE => qq{Aktuelle Zeit liegt innerhalb der Verbrauchsplanung} }, conrecba => { EN => qq{Current time is within the consumption planning, Priority charging Battery is active}, @@ -1080,9 +1097,10 @@ my %hfspvh = ( sub Initialize { my $hash = shift; - my $fwd = join ",", devspec2array("TYPE=FHEMWEB:FILTER=STATE=Initialized"); - my $hod = join ",", map { sprintf "%02d", $_} (1..24); - my $srd = join ",", sort keys (%hcsr); + my $fwd = join ",", devspec2array("TYPE=FHEMWEB:FILTER=STATE=Initialized"); + my $hod = join ",", map { sprintf "%02d", $_} (1..24); + my $srd = join ",", sort keys (%hcsr); + my $gbc = 'pvReal,pvForecast,consumption,consumptionForecast,gridconsumption,energycosts,gridfeedin,feedincome'; my ($consumer,@allc); for my $c (1..$maxconsumer) { @@ -1150,10 +1168,10 @@ sub Initialize { "graphicBeam2Color:colorpicker,RGB ". "graphicBeam3Color:colorpicker,RGB ". "graphicBeam4Color:colorpicker,RGB ". - "graphicBeam1Content:pvReal,pvForecast,consumption,consumptionForecast,gridconsumption,energycosts,feedincome ". - "graphicBeam2Content:pvReal,pvForecast,consumption,consumptionForecast,gridconsumption,energycosts,feedincome ". - "graphicBeam3Content:pvReal,pvForecast,consumption,consumptionForecast,gridconsumption,energycosts,feedincome ". - "graphicBeam4Content:pvReal,pvForecast,consumption,consumptionForecast,gridconsumption,energycosts,feedincome ". + "graphicBeam1Content:$gbc ". + "graphicBeam2Content:$gbc ". + "graphicBeam3Content:$gbc ". + "graphicBeam4Content:$gbc ". "graphicBeam1FontColor:colorpicker,RGB ". "graphicBeam2FontColor:colorpicker,RGB ". "graphicBeam3FontColor:colorpicker,RGB ". @@ -5659,6 +5677,33 @@ sub _attrWeatherDev { ## no critic "not used" return; } +################################################################ +# Attr graphicBeamXContent +################################################################ +sub _attrgraphicBeamXContent { ## no critic "not used" + my $paref = shift; + my $name = $paref->{name}; + my $aVal = $paref->{aVal}; + my $cmd = $paref->{cmd}; + + return if(!$init_done); + + my $medev = ReadingsVal ($name, "currentMeterDev", ""); # aktuelles Meter device + my ($a,$h) = parseParams ($medev); + + if ($cmd eq "set") { + if ($aVal eq 'energycosts') { + return "Define key 'conprice' in the currentMeterDev first before setting $aVal" if(!defined $h->{conprice}); + } + + if ($aVal eq 'feedincome') { + return "Define key 'feedprice' in the currentMeterDev first before setting $aVal" if(!defined $h->{feedprice}); + } + } + +return; +} + ################################################################ # currentRadiationAPI verzögert aus Attr setzen ################################################################ @@ -7770,7 +7815,7 @@ sub _transferMeterValues { my $t = $paref->{t}; my $chour = $paref->{chour}; - my $medev = ReadingsVal($name, "currentMeterDev", ""); # aktuelles Meter device + my $medev = ReadingsVal ($name, "currentMeterDev", ""); # aktuelles Meter device my ($a,$h) = parseParams ($medev); $medev = $a->[0] // ""; return if(!$medev || !$defs{$medev}); @@ -7991,16 +8036,16 @@ sub _transferBatteryValues { $boutunit //= $binunit; $binunit //= $boutunit; - my $piuf = $piunit =~ /^kW$/xi ? 1000 : 1; - my $pouf = $pounit =~ /^kW$/xi ? 1000 : 1; - my $binuf = $binunit =~ /^kWh$/xi ? 1000 : 1; - my $boutuf = $boutunit =~ /^kWh$/xi ? 1000 : 1; + my $piuf = $piunit =~ /^kW$/xi ? 1000 : 1; + my $pouf = $pounit =~ /^kW$/xi ? 1000 : 1; + my $binuf = $binunit =~ /^kWh$/xi ? 1000 : 1; + my $boutuf = $boutunit =~ /^kWh$/xi ? 1000 : 1; - my $pbo = ReadingsNum ($badev, $pou, 0) * $pouf; # aktuelle Batterieentladung (W) - my $pbi = ReadingsNum ($badev, $pin, 0) * $piuf; # aktueller Batterieladung (W) - my $btotout = ReadingsNum ($badev, $bout, 0) * $boutuf; # totale Batterieentladung (Wh) - my $btotin = ReadingsNum ($badev, $bin, 0) * $binuf; # totale Batterieladung (Wh) - my $soc = ReadingsNum ($badev, $batchr, 0); + my $pbo = ReadingsNum ($badev, $pou, 0) * $pouf; # aktuelle Batterieentladung (W) + my $pbi = ReadingsNum ($badev, $pin, 0) * $piuf; # aktueller Batterieladung (W) + my $btotout = ReadingsNum ($badev, $bout, 0) * $boutuf; # totale Batterieentladung (Wh) + my $btotin = ReadingsNum ($badev, $bin, 0) * $binuf; # totale Batterieladung (Wh) + my $soc = ReadingsNum ($badev, $batchr, 0); if ($instcap && !isNumeric ($instcap)) { # wenn $instcap Reading Wert abfragen my ($bcapr,$bcapunit) = split ':', $instcap; @@ -8057,17 +8102,7 @@ sub _transferBatteryValues { my $histbatintot = HistoryVal ($hash, $day, sprintf("%02d",$nhour), "batintotal", undef); # totale Batterieladung zu Beginn einer Stunde my $batinthishour; - if (!defined $histbatintot) { # totale Batterieladung der aktuelle Stunde gesetzt ? - #$paref->{val} = $btotin; - #$paref->{nhour} = sprintf "%02d", $nhour; - #$paref->{histname} = 'batintotal'; - - #setPVhistory ($paref); - - #delete $paref->{histname}; - #delete $paref->{nhour}; - #delete $paref->{val}; - + if (!defined $histbatintot) { # totale Batterieladung der aktuelle Stunde gesetzt? writeToHistory ( { paref => $paref, key => 'batintotal', val => $btotin, hour => $nhour } ); my $bitot = CurrentVal ($hash, "batintotal", $btotin); @@ -8079,18 +8114,7 @@ sub _transferBatteryValues { $batinthishour = 0 if($batinthishour < 0); - $data{$type}{$name}{circular}{sprintf("%02d",$nhour)}{batin} = $batinthishour; # Ringspeicher Battery In Forum: https://forum.fhem.de/index.php/topic,117864.msg1133350.html#msg1133350 - - #$paref->{val} = $batinthishour; - #$paref->{nhour} = sprintf "%02d", $nhour; - #$paref->{histname} = 'batinthishour'; - - #setPVhistory ($paref); - - #delete $paref->{histname}; - #delete $paref->{nhour}; - #delete $paref->{val}; - + $data{$type}{$name}{circular}{sprintf("%02d",$nhour)}{batin} = $batinthishour; # Ringspeicher Battery In Forum: https://forum.fhem.de/index.php/topic,117864.msg1133350.html#msg1133350 writeToHistory ( { paref => $paref, key => 'batinthishour', val => $batinthishour, hour => $nhour } ); # Batterieentladung aktuelle Stunde in pvHistory speichern @@ -8098,17 +8122,7 @@ sub _transferBatteryValues { my $histbatouttot = HistoryVal ($hash, $day, sprintf("%02d",$nhour), 'batouttotal', undef); # totale Betterieladung zu Beginn einer Stunde my $batoutthishour; - if (!defined $histbatouttot) { # totale Betterieladung der aktuelle Stunde gesetzt ? - #$paref->{val} = $btotout; - #$paref->{nhour} = sprintf "%02d", $nhour; - #$paref->{histname} = 'batouttotal'; - - #setPVhistory ($paref); - - #delete $paref->{histname}; - #delete $paref->{nhour}; - #delete $paref->{val}; - + if (!defined $histbatouttot) { # totale Betterieladung der aktuelle Stunde gesetzt? writeToHistory ( { paref => $paref, key => 'batouttotal', val => $btotout, hour => $nhour } ); my $botot = CurrentVal ($hash, 'batouttotal', $btotout); @@ -8120,35 +8134,14 @@ sub _transferBatteryValues { $batoutthishour = 0 if($batoutthishour < 0); - $data{$type}{$name}{circular}{sprintf("%02d",$nhour)}{batout} = $batoutthishour; # Ringspeicher Battery In Forum: https://forum.fhem.de/index.php/topic,117864.msg1133350.html#msg1133350 - - #$paref->{val} = $batoutthishour; - #$paref->{nhour} = sprintf "%02d", $nhour; - #$paref->{histname} = 'batoutthishour'; - - #setPVhistory ($paref); - - #delete $paref->{histname}; - #delete $paref->{nhour}; - #delete $paref->{val}; - + $data{$type}{$name}{circular}{sprintf("%02d",$nhour)}{batout} = $batoutthishour; # Ringspeicher Battery In Forum: https://forum.fhem.de/index.php/topic,117864.msg1133350.html#msg1133350 writeToHistory ( { paref => $paref, key => 'batoutthishour', val => $batoutthishour, hour => $nhour } ); # täglichen max. SOC in pvHistory speichern ############################################# my $batmaxsoc = HistoryVal ($hash, $day, 99, 'batmaxsoc', 0); # gespeicherter max. SOC des Tages - if ($soc >= $batmaxsoc) { - #$paref->{val} = $soc; - #$paref->{nhour} = 99; - #$paref->{histname} = 'batmaxsoc'; - - #setPVhistory ($paref); - - #delete $paref->{histname}; - #delete $paref->{nhour}; - #delete $paref->{val}; - + if ($soc >= $batmaxsoc) { writeToHistory ( { paref => $paref, key => 'batmaxsoc', val => $soc, hour => 99 } ); } @@ -11126,7 +11119,7 @@ sub entryGraphic { flowgconsDist => AttrVal ($name, 'flowGraphicConsumerDistance', $fgCDdef), # Abstand Verbrauchericons zueinander css => AttrVal ($name, 'flowGraphicCss', $cssdef), # flowGraphicCss Styles genpvdva => AttrVal ($name, 'ctrlGenPVdeviation', 'daily'), # Methode der Abweichungsberechnung - lang => AttrVal ($name, 'ctrlLanguage', AttrVal ('global', 'language', $deflang)), + lang => getLang ($hash), debug => getDebug ($hash), # Debug Module }; @@ -12553,13 +12546,14 @@ sub _beamGraphicFirstHour { my $hourstyle = $paref->{hourstyle}; my $beam1cont = $paref->{beam1cont}; my $beam2cont = $paref->{beam2cont}; + my $lang = $paref->{lang}; my $day; my $stt = NexthoursVal ($hash, "NextHour00", "starttime", '0000-00-00 24'); my ($year,$month,$day_str,$thishour) = $stt =~ m/(\d{4})-(\d{2})-(\d{2})\s(\d{2})/x; - my ($val1,$val2,$val3,$val4,$val5,$val6,$val7); + my ($val1,$val2,$val3,$val4,$val5,$val6,$val7,$val8); $thishour++; @@ -12589,9 +12583,10 @@ sub _beamGraphicFirstHour { $val5 = HistoryVal ($hash, $hfcg->{0}{day_str}, $hfcg->{0}{time_str}, 'con', 0); $val6 = sprintf "%.2f", (HistoryVal ($hash, $hfcg->{0}{day_str}, $hfcg->{0}{time_str}, 'conprice', 0) * $val3 / 1000); # Energiekosten der Stunde - $val7 = sprintf "%.2f", (HistoryVal ($hash, $hfcg->{0}{day_str}, $hfcg->{0}{time_str}, 'feedprice', 0) * - HistoryVal ($hash, $hfcg->{0}{day_str}, $hfcg->{0}{time_str}, 'gfeedin', 0) / 1000); # Einspeisevergütung der Stunde - + $val7 = HistoryVal ($hash, $hfcg->{0}{day_str}, $hfcg->{0}{time_str}, 'gfeedin', 0); + $val8 = sprintf "%.2f", (HistoryVal ($hash, $hfcg->{0}{day_str}, $hfcg->{0}{time_str}, 'feedprice', 0) * + $val7 / 1000); # Einspeisevergütung der Stunde + $hfcg->{0}{weather} = HistoryVal ($hash, $hfcg->{0}{day_str}, $hfcg->{0}{time_str}, 'weatherid', 999); $hfcg->{0}{wcc} = HistoryVal ($hash, $hfcg->{0}{day_str}, $hfcg->{0}{time_str}, 'wcc', '-'); $hfcg->{0}{sunalt} = HistoryVal ($hash, $hfcg->{0}{day_str}, $hfcg->{0}{time_str}, 'sunalt', '-'); @@ -12604,7 +12599,8 @@ sub _beamGraphicFirstHour { ($beam1cont eq 'consumptionForecast') ? $val4 : ($beam1cont eq 'consumption') ? $val5 : ($beam1cont eq 'energycosts') ? $val6 : - ($beam1cont eq 'feedincome') ? $val7 : + ($beam1cont eq 'gridfeedin') ? $val7 : + ($beam1cont eq 'feedincome') ? $val8 : undef; $hfcg->{0}{beam2} = ($beam2cont eq 'pvForecast') ? $val1 : ($beam2cont eq 'pvReal') ? $val2 : @@ -12612,12 +12608,35 @@ sub _beamGraphicFirstHour { ($beam2cont eq 'consumptionForecast') ? $val4 : ($beam2cont eq 'consumption') ? $val5 : ($beam2cont eq 'energycosts') ? $val6 : - ($beam2cont eq 'feedincome') ? $val7 : + ($beam2cont eq 'gridfeedin') ? $val7 : + ($beam2cont eq 'feedincome') ? $val8 : undef; $hfcg->{0}{beam1} //= 0; $hfcg->{0}{beam2} //= 0; $hfcg->{0}{diff} = $hfcg->{0}{beam1} - $hfcg->{0}{beam2}; + + my $epc = '('.CurrentVal ($hash, 'ePurchasePriceCcy', 0).')'; + my $efc = '('.CurrentVal ($hash, 'eFeedInTariffCcy', 0).')'; + + $hfcg->{0}{beam1txt} = ($beam1cont eq 'pvForecast') ? $htitles{pvgenefc}{$lang} : + ($beam1cont eq 'pvReal') ? $htitles{pvgenerl}{$lang} : + ($beam1cont eq 'gridconsumption') ? $htitles{enppubgd}{$lang} : + ($beam1cont eq 'consumptionForecast') ? $htitles{enconsfc}{$lang} : + ($beam1cont eq 'consumption') ? $htitles{enconsrl}{$lang} : + ($beam1cont eq 'energycosts') ? $htitles{enpchcst}{$lang}." $epc" : + ($beam1cont eq 'gridfeedin') ? $htitles{enfeedgd}{$lang} : + ($beam1cont eq 'feedincome') ? $htitles{rengfeed}{$lang}." $efc" : + ''; + $hfcg->{0}{beam2txt} = ($beam2cont eq 'pvForecast') ? $htitles{pvgenefc}{$lang} : + ($beam2cont eq 'pvReal') ? $htitles{pvgenerl}{$lang} : + ($beam2cont eq 'gridconsumption') ? $htitles{enppubgd}{$lang} : + ($beam2cont eq 'consumptionForecast') ? $htitles{enconsfc}{$lang} : + ($beam2cont eq 'consumption') ? $htitles{enconsrl}{$lang} : + ($beam2cont eq 'energycosts') ? $htitles{enpchcst}{$lang}." $epc" : + ($beam2cont eq 'gridfeedin') ? $htitles{enfeedgd}{$lang} : + ($beam2cont eq 'feedincome') ? $htitles{rengfeed}{$lang}." $efc" : + ''; return $thishour; } @@ -12638,15 +12657,15 @@ sub _beamGraphicRemainingHours { $maxVal //= $hfcg->{0}{beam1}; # Startwert wenn kein Wert bereits via attr vorgegeben ist - my ($val1,$val2,$val3,$val4,$val5,$val6,$val7); + my ($val1,$val2,$val3,$val4,$val5,$val6,$val7,$val8); my $maxCon = $hfcg->{0}{beam1}; my $maxDif = $hfcg->{0}{diff}; # für Typ diff my $minDif = $hfcg->{0}{diff}; # für Typ diff for my $i (1..($maxhours*2)-1) { # doppelte Anzahl berechnen my $val1 = 0; - ($val1,$val2,$val3,$val4,$val5,$val6,$val7) = (0,0,0,0,0,0,0); - $hfcg->{$i}{time} = $hfcg->{0}{time} + $i; + ($val1,$val2,$val3,$val4,$val5,$val6,$val7,$val8) = (0,0,0,0,0,0,0,0); + $hfcg->{$i}{time} = $hfcg->{0}{time} + $i; while ($hfcg->{$i}{time} > 24) { $hfcg->{$i}{time} -= 24; # wird bis zu 2x durchlaufen @@ -12669,8 +12688,8 @@ sub _beamGraphicRemainingHours { $val4 = HistoryVal ($hash, $ds, $hfcg->{$i}{time_str}, 'confc', 0); $val5 = HistoryVal ($hash, $ds, $hfcg->{$i}{time_str}, 'con', 0); $val6 = sprintf "%.2f", (HistoryVal ($hash, $ds, $hfcg->{$i}{time_str}, 'conprice', 0) * $val3 / 1000); # Energiekosten der Stunde - $val7 = sprintf "%.2f", (HistoryVal ($hash, $ds, $hfcg->{$i}{time_str}, 'feedprice', 0) * - HistoryVal ($hash, $ds, $hfcg->{$i}{time_str}, 'gfeedin', 0) / 1000); # Einspeisevergütung der Stunde + $val7 = HistoryVal ($hash, $ds, $hfcg->{$i}{time_str}, 'gfeedin', 0); + $val8 = sprintf "%.2f", (HistoryVal ($hash, $ds, $hfcg->{$i}{time_str}, 'feedprice', 0) * $val7 / 1000); # Einspeisevergütung der Stunde $hfcg->{$i}{weather} = HistoryVal ($hash, $ds, $hfcg->{$i}{time_str}, 'weatherid', 999); @@ -12703,7 +12722,8 @@ sub _beamGraphicRemainingHours { ($beam1cont eq 'consumptionForecast') ? $val4 : ($beam1cont eq 'consumption') ? $val5 : ($beam1cont eq 'energycosts') ? $val6 : - ($beam1cont eq 'feedincome') ? $val7 : + ($beam1cont eq 'gridfeedin') ? $val7 : + ($beam1cont eq 'feedincome') ? $val8 : undef; $hfcg->{$i}{beam2} = ($beam2cont eq 'pvForecast') ? $val1 : ($beam2cont eq 'pvReal') ? $val2 : @@ -12711,7 +12731,8 @@ sub _beamGraphicRemainingHours { ($beam2cont eq 'consumptionForecast') ? $val4 : ($beam2cont eq 'consumption') ? $val5 : ($beam2cont eq 'energycosts') ? $val6 : - ($beam2cont eq 'feedincome') ? $val7 : + ($beam2cont eq 'gridfeedin') ? $val7 : + ($beam2cont eq 'feedincome') ? $val8 : undef; $hfcg->{$i}{beam1} //= 0; @@ -12769,7 +12790,7 @@ 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); + my ($val, $z2, $z3, $z4, $he, $titz2, $titz3); my $ret .= __weatherOnBeam ($paref); my $m = $paref->{modulo} % 2; @@ -12803,7 +12824,7 @@ sub _beamGraphic { $ret .= ""; # Neue Zeile mit freiem Platz am Anfang my $ii = 0; - + for my $i (0..($maxhours * 2) - 1) { # gleiche Bedingung wie oben next if(!$show_night && $hfcg->{$i}{weather} > 99 && !$hfcg->{$i}{beam1} @@ -12817,10 +12838,10 @@ sub _beamGraphic { # Berechnung der Zonen ######################## - if ($lotype eq 'single') { - $he = int(($maxVal - $hfcg->{$i}{beam1}) / $maxVal * $height) + $fsize; # Der zusätzliche Offset durch $fsize verhindert bei den meisten Skins dass die Grundlinie der Balken nach unten durchbrochen wird - $z3 = int($height + $fsize - $he); + $he = int(($maxVal - $hfcg->{$i}{beam1}) / $maxVal * $height) + $fsize; # Der zusätzliche Offset durch $fsize verhindert bei den meisten Skins dass die Grundlinie der Balken nach unten durchbrochen wird + $z3 = int($height + $fsize - $he); + $titz3 = qq/title="$hfcg->{0}{beam1txt}"/; } if ($lotype eq 'double') { @@ -12834,10 +12855,14 @@ sub _beamGraphic { if ($hfcg->{$i}{beam1} > $hfcg->{$i}{beam2}) { # Beam1 oben , Beam2 unten $z2 = $hfcg->{$i}{beam1}; $z3 = $hfcg->{$i}{beam2}; + $titz2 = qq/title="$hfcg->{0}{beam1txt}"/; + $titz3 = qq/title="$hfcg->{0}{beam2txt}"/; } else { # tauschen, Verbrauch ist größer als Ertrag $z3 = $hfcg->{$i}{beam1}; $z2 = $hfcg->{$i}{beam2}; + $titz2 = qq/title="$hfcg->{0}{beam2txt}"/; + $titz3 = qq/title="$hfcg->{0}{beam1txt}"/; } $he = int(($maxVal-$z2) / $maxVal * $height); @@ -12916,14 +12941,15 @@ sub _beamGraphic { $ret .=""; # mit width=100% etwas bessere Füllung der Balken $ret .=""; - $ret .="'; + $ret .=""; if ($hfcg->{$i}{beam1} || $show_night) { # Balken nur einfärben wenn der User via Attr eine Farbe vorgibt, sonst bestimmt class odd von TR alleine die Farbe my $style = "style=\"padding-bottom:0px; vertical-align:top; margin-left:auto; margin-right:auto;"; $style .= defined $colorb1 ? " background-color:#$colorb1\"" : '"'; # Syntaxhilight $ret .= ""; - $ret .= " + + @@ -21974,10 +22017,15 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden. +
".$val.'
".$val; + $ret .="
"; + $ret .= ""; my $sicon = 1; @@ -12937,6 +12963,7 @@ sub _beamGraphic { if ($lotype eq 'double') { my ($color1, $color2, $style1, $style2, $v); + my $style = "style='padding-bottom:0px; padding-top:1px; vertical-align:top; margin-left:auto; margin-right:auto;"; $ret .="\n"; # mit width=100% etwas bessere Füllung der Balken @@ -12966,7 +12993,7 @@ sub _beamGraphic { } $ret .= ""; - $ret .= ""; - $ret .= ""; + $ret .= ""; } } if ($lotype eq 'diff') { # Type diff my $style = "style='padding-bottom:0px; padding-top:1px; vertical-align:top; margin-left:auto; margin-right:auto;"; - $ret .= "
$val"; + $ret .= "".$val; # inject the new icon if defined ################################## @@ -12976,58 +13003,65 @@ sub _beamGraphic { if ($z3) { # die Zone 3 lassen wir bei zu kleinen Werten auch ganz weg $ret .= "
$v
".$v; + $ret .= "
\n"; # Tipp : das nachfolgende border=0 auf 1 setzen hilft sehr Ausgabefehler zu endecken + $ret .= "
\n"; # Tipp : das nachfolgende border=0 auf 1 setzen hilft sehr Ausgabefehler zu endecken $val = ($hfcg->{$i}{diff} > 0) ? formatVal6 ($hfcg->{$i}{diff}, $kw, $hfcg->{$i}{weather}) : ''; $val = '   0  ' if($hfcg->{$i}{diff} == 0); # Sonderfall , hier wird die 0 gebraucht ! if ($val) { $ret .= ""; - $ret .= ""; + $ret .= ""; } if ($hfcg->{$i}{diff} >= 0) { # mit Farbe 1 colorb1 füllen $style .= " background-color:#$colorb1'"; $z2 = 1 if ($hfcg->{$i}{diff} == 0); # Sonderfall , 1px dünnen Strich ausgeben $ret .= ""; - $ret .= ""; } else { # ohne Farbe - $z2 = 2 if ($hfcg->{$i}{diff} == 0); # Sonderfall, hier wird die 0 gebraucht ! + $z2 = 2 if($hfcg->{$i}{diff} == 0); # Sonderfall, hier wird die 0 gebraucht ! if ($z2 && $val) { # z2 weglassen wenn nicht unbedigt nötig bzw. wenn zuvor he mit val keinen Wert hatte $ret .= ""; - $ret .= ""; + $ret .= ""; } } if ($hfcg->{$i}{diff} < 0) { # Negativ Balken anzeigen ? $style .= " background-color:#$colorb2'"; # mit Farbe 2 colorb2 füllen $ret .= ""; - $ret .= ""; + $ret .= ""; } elsif ($z3) { # ohne Farbe $ret .= ""; - $ret .= ""; + $ret .= ""; } - if($z4) { # kann entfallen wenn auch z3 0 ist - $val = ($hfcg->{$i}{diff} < 0) ? formatVal6 ($hfcg->{$i}{diff}, $kw, $hfcg->{$i}{weather}) : ' '; + if ($z4) { # kann entfallen wenn auch z3 0 ist + $val = $hfcg->{$i}{diff} < 0 ? formatVal6 ($hfcg->{$i}{diff}, $kw, $hfcg->{$i}{weather}) : ' '; $ret .= ""; - $ret .= ""; + $ret .= ""; } } if ($show_diff eq 'bottom') { # zusätzliche diff Anzeige $val = formatVal6 ($hfcg->{$i}{diff}, $kw, $hfcg->{$i}{weather}); $val = ($hfcg->{$i}{diff} < 0) ? ''.$val.'' : ($val > 0 ) ? '+'.$val : $val if ($val ne ' '); # negative Zahlen in Fettschrift, 0 aber ohne + - $ret .= ""; + $ret .= ""; } $ret .= " + + @@ -19701,10 +19737,15 @@ to ensure that the system configuration is correct. +
".$val."
".$val; + $ret .= "
"; + $ret .= ""; $ret .= "
"; + $ret .= "
"; + $ret .= "
"; + $ret .= "
".$val."
".$val; + $ret .= "
$val
$val"; + $ret .= "
"; @@ -13035,7 +13069,7 @@ sub _beamGraphic { ''.$hfcg->{$i}{time_str}.'' : $hfcg->{$i}{time_str}; - if($hfcg->{$i}{time} == $thishour) { + if ($hfcg->{$i}{time} == $thishour) { $thishour = 99; # nur einmal verwenden ! } @@ -17990,6 +18024,8 @@ to ensure that the system configuration is correct.
pv Reading which provides the current PV generation
etotal Reading which provides the total PV energy generated (a steadily increasing counter).
If the reading violates the specification of a continuously rising counter,
SolarForecast handles this error and reports the situation by means of a log message.
Einheit the respective unit (W,kW,Wh,kWh)
capacity Rated power of the inverter according to data sheet, i.e. max. possible output in Watts
(The entry is optional, but is strongly recommended)
energycosts Cost of energy purchased from the grid. The currency is defined in the currentMeterDev, key conprice.
feedincome Remuneration for feeding into the grid. The currency is defined in the currentMeterDev, key feedprice.
gridconsumption Energy purchase from the public grid
gridfeedin Feed into the public grid
pvReal real PV generation (default for graphicBeam1Content)
pvForecast predicted PV generation (default for graphicBeam2Content)
+
+ + Hinweis: The selection of the parameters energycosts and feedincome only makes sense if the optional keys + conprice and feedprice are set in currentMeterDev.
@@ -20252,6 +20293,8 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
pv Reading welches die aktuelle PV-Erzeugung liefert
etotal Reading welches die gesamte erzeugte PV-Energie liefert (ein stetig aufsteigender Zähler)
Sollte des Reading die Vorgabe eines stetig aufsteigenden Zählers verletzen, behandelt
SolarForecast diesen Fehler und meldet die aufgetretene Situation durch eine Logmeldung.
Einheit die jeweilige Einheit (W,kW,Wh,kWh)
capacity Bemessungsleistung des Wechselrichters gemäß Datenblatt, d.h. max. möglicher Output in Watt
(Die Angabe ist optional, wird aber dringend empfohlen zu setzen)
energycosts Kosten des Energiebezuges aus dem Netz. Die Währung ist im currentMeterDev, Schlüssel conprice, definiert.
feedincome Vergütung für die Netzeinspeisung. Die Währung ist im currentMeterDev, Schlüssel feedprice, definiert.
gridconsumption Energiebezug aus dem öffentlichen Netz
gridfeedin Einspeisung in das öffentliche Netz
pvReal reale PV-Erzeugung (default für graphicBeam1Content)
pvForecast prognostizierte PV-Erzeugung (default für graphicBeam2Content)
+
+ + Hinweis: Die Auswahl der Parameter energycosts und feedincome ist nur sinnvoll wenn in currentMeterDev die + optionalen Schlüssel conprice und feedprice gesetzt sind.