From ef03a0138ae6147415a2da7b2b8f1fc200c3c314 Mon Sep 17 00:00:00 2001 From: nasseeder1 Date: Mon, 21 Oct 2024 19:39:01 +0000 Subject: [PATCH] 76_SolarForecast: contrib 1.37.0 git-svn-id: https://svn.fhem.de/fhem/trunk@29276 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/contrib/DS_Starter/76_SolarForecast.pm | 203 ++++++++++++-------- 1 file changed, 120 insertions(+), 83 deletions(-) diff --git a/fhem/contrib/DS_Starter/76_SolarForecast.pm b/fhem/contrib/DS_Starter/76_SolarForecast.pm index e69309da3..f53ce99cf 100644 --- a/fhem/contrib/DS_Starter/76_SolarForecast.pm +++ b/fhem/contrib/DS_Starter/76_SolarForecast.pm @@ -156,10 +156,11 @@ BEGIN { # Versions History intern my %vNotesIntern = ( - "1.37.0" => "20.10.2024 attr setupInverterDevXX up to 03 inverters with accorded strings, setupInverterDevXX: keys strings and feed ". + "1.37.0" => "21.10.2024 attr setupInverterDevXX up to 03 inverters with accorded strings, setupInverterDevXX: keys strings and feed ". "_flowGraphic: controlhash for producer, new attr flowGraphicControl and replace the attributes: ". "flowGraphicAnimate flowGraphicConsumerDistance flowGraphicShowConsumer flowGraphicShowConsumerDummy ". - "flowGraphicShowConsumerPower flowGraphicShowConsumerRemainTime flowGraphicShift flowGraphicCss ", + "flowGraphicShowConsumerPower flowGraphicShowConsumerRemainTime flowGraphicShift flowGraphicCss ". + "flowGraphicControl: new keys strokecolina, strokecolsig, strokecolstd, strokewidth ", "1.36.1" => "14.10.2024 _flowGraphic: consumer distance modified by kask, Coloring of icons corrected when creating 0 ", "1.36.0" => "13.10.2024 new Getter valInverter, valStrings and valProducer, preparation for multiple inverters ". "rename setupInverterDev to setupInverterDev01, new attr affectConsForecastLastDays ". @@ -469,7 +470,11 @@ my $b4coldef = 'DBDBD0'; my $b4fontcoldef = '000000'; # default Schriftfarbe Beam 4 my $fgCDdef = 130; # Abstand Verbrauchericons zueinander -my $fgscaledef = 0.10; # Scale Normativ Icons in Flowgreafik +my $fgscaledef = 0.10; # Flußgrafik: Scale Normativ Icons +my $strokcolstddef = 'darkorange'; # Flußgrafik: Standardfarbe aktive normale Kette +my $strokcolsigdef = 'red'; # Flußgrafik: Standardfarbe aktive Signal-Kette +my $strokcolinadef = 'gray'; # Flußgrafik: Standardfarbe inaktive Kette +my $strokwidthdef = 25; # Flußgrafik: Standard Breite der Kette my $prodicondef = 'sani_garden_pump'; # default Producer-Icon my $cicondef = 'light_light_dim_100'; # default Consumer-Icon my $ciconcoldef = 'darkorange'; # default Consumer-Icon Färbung @@ -5677,6 +5682,10 @@ sub _attrflowGraphicControl { ## no critic "not used" size showconsumerdummy showconsumerpower + strokecolstd + strokecolsig + strokecolina + strokewidth ) ) { delete $data{$type}{$name}{current}{$av}; @@ -5692,6 +5701,10 @@ sub _attrflowGraphicControl { ## no critic "not used" showconsumerdummy => '0|1', showconsumerremaintime => '0|1', showconsumerpower => '0|1', + strokecolstd => '.*', + strokecolsig => '.*', + strokecolina => '.*', + strokewidth => '\d+', }; my ($a, $h) = parseParams ($aVal); @@ -9696,7 +9709,7 @@ sub __calcEnergyPieces { my $cotype = ConsumerVal ($hash, $c, "type", $defctype ); my $mintime = ConsumerVal ($hash, $c, "mintime", $defmintime); - if (isSunPath ($hash, $c)) { # SunPath ist in mintime gesetzt + if (isSunPath ($hash, $c)) { # SunPath ist in mintime gesetzt my ($riseshift, $setshift) = sunShift ($hash, $c); my $tdiff = (CurrentVal ($hash, 'sunsetTodayTs', 0) + $setshift) - (CurrentVal ($hash, 'sunriseTodayTs', 0) + $riseshift); @@ -9705,8 +9718,7 @@ sub __calcEnergyPieces { my $hours = ceil ($mintime / 60); # Einplanungsdauer in h my $ctote = ConsumerVal ($hash, $c, "avgenergy", undef); # gemessener durchschnittlicher Energieverbrauch pro Stunde (Wh) - $ctote = $ctote ? - $ctote : + $ctote = $ctote ? $ctote : ConsumerVal ($hash, $c, "power", 0); # alternativer nominaler Energieverbrauch in W (bzw. Wh bezogen auf 1 h) if (int($hef{$cotype}{f}) == 1) { # bei linearen Verbrauchertypen die nominale Leistungsangabe verwenden statt Durchschnitt @@ -14207,7 +14219,7 @@ sub _flowGraphic { my $lang = $paref->{lang}; my $cgc = ReadingsNum ($name, 'Current_GridConsumption', 0); - my $node2grid = ReadingsNum ($name, 'Current_GridFeedIn', 0); # vom Knoten zum Grid + my $node2grid = ReadingsNum ($name, 'Current_GridFeedIn', 0); # vom Knoten zum Grid my $cself = ReadingsNum ($name, 'Current_SelfConsumption', 0); my $cc = CurrentVal ($hash, 'consumption', 0); my $batin = ReadingsNum ($name, 'Current_PowerBatIn', undef); @@ -14216,15 +14228,15 @@ sub _flowGraphic { my $cc_dummy = $cc; my $scale = $fgscaledef; - my $pdist = 130; # Abstand Producer zueinander - my $hasbat = 1; # initial Batterie vorhanden + my $pdist = 130; # Abstand Producer zueinander + my $hasbat = 1; # initial Batterie vorhanden my $lcp; ## definierte Producer + Inverter ermitteln und zusammenfassen ################################################################ - my $pdcr = {}; # Hashref Producer - my $ppall = 0; # Summe Erzeugung alle nicht PV-Producer - my $pv2node = 0; # Summe PV-Erzeugung alle Inverter + my $pdcr = {}; # Hashref Producer + my $ppall = 0; # Summe Erzeugung alle nicht PV-Producer + my $pv2node = 0; # Summe PV-Erzeugung alle Inverter my $pv2grid = 0; my $pv2bat = 0; my $lfn = 0; @@ -14236,11 +14248,11 @@ sub _flowGraphic { if (defined $p) { $p = __normDecPlaces ($p); - $pdcr->{$lfn}{p} = $p; # aktuelle Erzeugung nicht PV-Producer - $pdcr->{$lfn}{pn} = $pn; # Producernummer - $pdcr->{$lfn}{feed} = $feed; # Eigenschaft der Energielieferung - $pdcr->{$lfn}{ptyp} = 'producer'; # Typ des Producers - $ppall += $p; # aktuelle Erzeuguung aller nicht PV-Producer + $pdcr->{$lfn}{p} = $p; # aktuelle Erzeugung nicht PV-Producer + $pdcr->{$lfn}{pn} = $pn; # Producernummer + $pdcr->{$lfn}{feed} = $feed; # Eigenschaft der Energielieferung + $pdcr->{$lfn}{ptyp} = 'producer'; # Typ des Producers + $ppall += $p; # aktuelle Erzeuguung aller nicht PV-Producer $lfn++; } @@ -14290,9 +14302,9 @@ sub _flowGraphic { ## Batterie + Werte festlegen ############################### - my $bat_color = $soc < 26 ? 'flowg bat25' : - $soc < 76 ? 'flowg bat50' : - 'flowg bat75'; + my $bat_color = $soc < 26 ? "$name bat25" : + $soc < 76 ? "$name bat50" : + "$name bat75"; if (!defined $batin && !defined $bat2home) { $hasbat = 0; @@ -14301,22 +14313,22 @@ sub _flowGraphic { $soc = 0; } - my $grid2home_style = $cgc ? 'flowg active_red' : 'flowg inactive'; # cgc current GridConsumption - my $bat2home_style = $bat2home ? 'flowg active_orange' : 'flowg inactive'; - my $cgc_direction = 'M490,515 L670,590'; + my $grid2home_style = $cgc ? "$name active_sig" : "$name inactive"; # cgc current GridConsumption + my $bat2home_style = $bat2home ? "$name active_normal" : "$name inactive"; + my $cgc_direction = "M490,515 L670,590"; if ($bat2home) { # Batterie wird ins Haus entladen my $cgfo = $node2grid - $pv2node; if ($cgfo > 1) { - $grid2home_style = 'flowg active_orange'; - $cgc_direction = 'M670,590 L490,515'; + $grid2home_style = "$name active_normal"; + $cgc_direction = "M670,590 L490,515"; $node2grid -= $cgfo; $cgc = $cgfo; } } - my $bat2home_direction = 'M902,515 L730,590'; + my $bat2home_direction = "M902,515 L730,590"; my $node2bat = $batin; if ($batin) { # Batterie wird geladen @@ -14324,8 +14336,8 @@ sub _flowGraphic { if ($home2bat > 1) { # Batterieladung wird anteilig aus Hausnetz geladen $node2bat -= $home2bat; - $bat2home_style = 'flowg active_red'; - $bat2home_direction = 'M730,590 L902,515'; + $bat2home_style = "$name active_sig"; + $bat2home_direction = "M730,590 L902,515"; $bat2home = $home2bat; } } @@ -14355,31 +14367,34 @@ sub _flowGraphic { my $svgstyle = 'width:98%; height:'.$flowgsize.'px;'; my $animation = $flowgani ? '@keyframes dash { to { stroke-dashoffset: 0; } }' : ''; # Animation Ja/Nein - my $grid_color = $node2grid ? 'flowg grid_green' : - !$node2grid && !$cgc && $bat2home ? 'flowg grid_gray' : - 'flowg grid_red'; + my $grid_color = $node2grid ? "$name grid_green" : + !$node2grid && !$cgc && $bat2home ? "$name grid_gray" : + "$name grid_red"; - # $grid_color = 'flowg grid_gray' if(!$node2grid && !$cgc && $bat2home); + my $strokecolstd = CurrentVal ($hash, 'strokecolstd', $strokcolstddef); + my $strokecolsig = CurrentVal ($hash, 'strokecolsig', $strokcolsigdef); + my $strokecolina = CurrentVal ($hash, 'strokecolina', $strokcolinadef); + my $strokewidth = CurrentVal ($hash, 'strokewidth', $strokwidthdef); my $ret = << "END0"; - + - + END0 @@ -14417,7 +14432,7 @@ END0 $picon = FW_makeImage ($picon, ''); ($scale, $picon) = __normIconScale ($picon, $name); - $ret .= qq{}; + $ret .= qq{}; $ret .= "$ptxt".$picon; $ret .= ' '; @@ -14438,7 +14453,7 @@ END0 $nicon = FW_makeImage ($nicon, ''); ($scale, $nicon) = __normIconScale ($nicon, $name); - $ret .= qq{}; # translate(X-Koordinate,Y-Koordinate), scale()-> Koordinaten ändern sich bei Größenänderung + $ret .= qq{}; # translate(X-Koordinate,Y-Koordinate), scale()-> Koordinaten ändern sich bei Größenänderung $ret .= "$ntxt".$nicon; $ret .= ' '; @@ -14475,7 +14490,7 @@ END0 $cicon = FW_makeImage ($cicon, ''); ($scale, $cicon) = __normIconScale ($cicon, $name); - $ret .= qq{}; + $ret .= qq{}; $ret .= "$calias".$cicon; $ret .= ' '; @@ -14504,7 +14519,7 @@ END1 my $hicon = FW_makeImage ($homeicondef, ''); ($scale, $hicon) = __normIconScale ($hicon, $name); - $ret .= qq{}; # translate(X-Koordinate,Y-Koordinate), scale()-> Koordinaten ändern sich bei Größenänderung + $ret .= qq{}; # translate(X-Koordinate,Y-Koordinate), scale()-> Koordinaten ändern sich bei Größenänderung $ret .= "Home".$hicon; $ret .= ' '; @@ -14516,41 +14531,41 @@ END1 my $dicon = FW_makeImage ($cicondef.$dumcol, ''); ($scale, $dicon) = __normIconScale ($dicon, $name); - $ret .= qq{}; + $ret .= qq{}; $ret .= "$dumtxt".$dicon; $ret .= ' '; } ## Laufketten Node->Home, Node->Grid, Bat->Home ################################################# - my $node2home_style = $node2home ? 'flowg active_orange' : 'flowg inactive'; - my $node2grid_style = $node2grid ? 'flowg active_orange' : 'flowg inactive'; + my $node2home_style = $node2home ? "$name active_normal" : "$name inactive"; + my $node2grid_style = $node2grid ? "$name active_normal" : "$name inactive"; $ret .= << "END2"; - - - + + + END2 ## Laufketten PV->Batterie, Batterie->Home ############################################## if ($hasbat) { - my $node2bat_style = $node2bat ? 'flowg active_orange' : 'flowg inactive'; - my $batin_direction = $node2bat < 0 ? 'M910,480 L730,400' : 'M730,400 L910,480'; + my $node2bat_style = $node2bat ? "$name active_normal" : "$name inactive"; + my $batin_direction = $node2bat < 0 ? "M910,480 L730,400" : "M730,400 L910,480"; $node2bat = abs $node2bat; $ret .= << "END3"; - - + + END3 } ## Dummy Consumer Laufketten ############################## if ($flowgconX) { - my $consumer_style = 'flowg inactive'; - $consumer_style = 'flowg active_red' if($cc_dummy > 1); + my $consumer_style = "$name inactive"; + $consumer_style = "$name active_sig" if($cc_dummy > 1); my $chain_color = ""; # Farbe der Laufkette Consumer-Dummy if ($cc_dummy > 0.5) { @@ -14558,7 +14573,7 @@ END3 #$chain_color = 'style="stroke: #DF0101;"'; } - $ret .= qq{}; + $ret .= qq{}; } ## Producer Laufketten - in Reihenfolge: zum Grid - zum Knoten - zur Batterie @@ -14581,8 +14596,8 @@ END3 for my $lfn (@sorted) { my $pn = $pdcr->{$lfn}{pn}; my $p = $pdcr->{$lfn}{p}; - my $consumer_style = 'flowg inactive'; - $consumer_style = 'flowg active_orange' if($p > 0); + my $consumer_style = "$name inactive"; + $consumer_style = "$name active_normal" if($p > 0); my $chain_color = ''; # Farbe der Laufkette des Producers if ($p) { @@ -14590,7 +14605,7 @@ END3 $chain_color = 'style="stroke: darkorange;"'; } - $ret .= qq{}; + $ret .= qq{}; $left += ($pdist * 2); $xchain += $step; } @@ -14621,8 +14636,8 @@ END3 my $p = $currentPower; $p = (($currentPower / $power) * 100) if ($power > 0); - my $consumer_style = 'flowg inactive'; - $consumer_style = 'flowg active_orange' if($p > $defpopercent); + my $consumer_style = "$name inactive"; + $consumer_style = "$name active_normal" if($p > $defpopercent); my $chain_color = ""; # Farbe der Laufkette des Consumers if ($p > 0.5) { @@ -14630,7 +14645,7 @@ END3 #$chain_color = 'style="stroke: #DF0101;"'; } - $ret .= qq{}; + $ret .= qq{}; $cons_left += ($cdist * 2); $cons_left_start += $distance_con; } @@ -14639,15 +14654,15 @@ END3 ## Textangaben an Grafikelementen ################################### $cc_dummy = sprintf("%.0f", $cc_dummy); # Verbrauch Dummy-Consumer - $ret .= qq{$pnodesum} if ($pnodesum > 0); - $ret .= qq{$soc %} if ($hasbat); # Lage Text Batterieladungszustand - $ret .= qq{$node2home} if ($node2home); - $ret .= qq{$node2grid} if ($node2grid); - $ret .= qq{$cgc} if ($cgc); - $ret .= qq{$bat2home} if ($bat2home && $hasbat); - $ret .= qq{$node2bat} if ($node2bat && $hasbat); - $ret .= qq{$cc}; # Current_Consumption Anlage - $ret .= qq{$cc_dummy} if ($flowgconX && $flowgconsPower); # Current_Consumption Dummy + $ret .= qq{$pnodesum} if ($pnodesum > 0); + $ret .= qq{$soc %} if ($hasbat); # Lage Text Batterieladungszustand + $ret .= qq{$node2home} if ($node2home); + $ret .= qq{$node2grid} if ($node2grid); + $ret .= qq{$cgc} if ($cgc); + $ret .= qq{$bat2home} if ($bat2home && $hasbat); + $ret .= qq{$node2bat} if ($node2bat && $hasbat); + $ret .= qq{$cc}; # Current_Consumption Anlage + $ret .= qq{$cc_dummy} if ($flowgconX && $flowgconsPower); # Current_Consumption Dummy ## Textangabe Producer - in Reihenfolge: zum Grid - zum Knoten - zur Batterie ############################################################################### @@ -14668,7 +14683,7 @@ END3 elsif ($lcp == 2) {$left += 20} elsif ($lcp == 1) {$left += 40} - $ret .= qq{$currentPower} if($flowgPrdsPower); + $ret .= qq{$currentPower} if($flowgPrdsPower); # Leistungszahl wieder zurück an den Ursprungspunkt #################################################### @@ -14699,8 +14714,8 @@ END3 $lcp = length $currentPower; - #$ret .= qq{$currentPower} if ($flowgconsPower); # Lage Consumer Consumption - #$ret .= qq{$consumerTime} if ($flowgconsTime); # Lage Consumer Restlaufzeit + #$ret .= qq{$currentPower} if ($flowgconsPower); # Lage Consumer Consumption + #$ret .= qq{$consumerTime} if ($flowgconsTime); # Lage Consumer Restlaufzeit # Verbrauchszahl abhängig von der Größe entsprechend auf der x-Achse verschieben ################################################################################## @@ -14710,8 +14725,8 @@ END3 elsif ($lcp == 2) {$cons_left += 7 } elsif ($lcp == 1) {$cons_left += 25} - $ret .= qq{$currentPower} if ($flowgconsPower); # Lage Consumer Consumption - $ret .= qq{$consumerTime} if ($flowgconsTime); # Lage Consumer Restlaufzeit + $ret .= qq{$currentPower} if ($flowgconsPower); # Lage Consumer Consumption + $ret .= qq{$consumerTime} if ($flowgconsTime); # Lage Consumer Restlaufzeit # Verbrauchszahl wieder zurück an den Ursprungspunkt ###################################################### @@ -21047,12 +21062,23 @@ to ensure that the system configuration is correct.
size Size of the energy flow graphic in pixels if displayed. (graphicSelect) Value: Integer, default: 400 + strokecolina Color of an inactive line + Value: Hex (e.g. #cc3300) or designation (e.g. red, blue), default: gray + + strokecolsig Color of an active signal line + Value: Hex (e.g. #cc3300) or designation (e.g. red, blue), default: red + + strokecolstd Color of an active standard line + Value: Hex (e.g. #cc3300) or designation (e.g. red, blue), default: darkorange + + strokewidth Width of the lines + Value: Integer, default: 25 @@ -23440,12 +23466,23 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden. size Größe der Energieflußgrafik in Pixel sofern angezeigt. (graphicSelect) Wert: Ganzzahl, default: 400 + strokecolina Farbe einer inaktiven Linie + Wert: Hex (z.B. #cc3300) oder Bezeichnung (z.B. red, blue), default: gray + + strokecolsig Farbe einer aktiven Signallinie + Wert: Hex (z.B. #cc3300) oder Bezeichnung (z.B. red, blue), default: red + + strokecolstd Farbe einer aktiven Standardlinie + Wert: Hex (z.B. #cc3300) oder Bezeichnung (z.B. red, blue), default: darkorange + + strokewidth Breite der Linien + Wert: Ganzzahl, default: 25