From ce65632a34aaa1bfc9335268caf7c835b6e72695 Mon Sep 17 00:00:00 2001 From: nasseeder1 Date: Mon, 18 Oct 2021 21:02:38 +0000 Subject: [PATCH] 76_SolarForecast.pm: contrib 0.56.7 git-svn-id: https://svn.fhem.de/fhem/trunk@25092 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/contrib/DS_Starter/76_SolarForecast.pm | 186 ++++++++++++-------- 1 file changed, 111 insertions(+), 75 deletions(-) diff --git a/fhem/contrib/DS_Starter/76_SolarForecast.pm b/fhem/contrib/DS_Starter/76_SolarForecast.pm index a8de22195..15aef8e9b 100644 --- a/fhem/contrib/DS_Starter/76_SolarForecast.pm +++ b/fhem/contrib/DS_Starter/76_SolarForecast.pm @@ -120,6 +120,7 @@ BEGIN { # Versions History intern my %vNotesIntern = ( + "0.56.7" => "18.10.2021 new attr flowGraphicShowConsumerDummy ", "0.56.6" => "19.09.2021 bug fix ", "0.56.5" => "16.09.2021 fix sub ___csmSpecificEpieces (rows 2924-2927) ", "0.56.4" => "16.09.2021 new sub ___csmSpecificEpieces ", @@ -518,19 +519,21 @@ my $defflowGSize = 300; my $defpopercent = 0.5; # Standard % aktuelle Leistung an nominaler Leistung gemäß Typenschild # Default CSS-Style -my $cssdef = qq{.flowg.text { stroke: none; fill: gray; font-size: 32px;} \n}. - qq{.flowg.sun_active { stroke: orange; fill: orange; } \n}. - qq{.flowg.sun_inactive { stroke: gray; fill: gray; } \n}. - qq{.flowg.bat25 { stroke: red; fill: red; } \n}. - qq{.flowg.bat50 { stroke: yellow; fill: yellow; } \n}. - qq{.flowg.bat75 { stroke: green; fill: green; } \n}. - qq{.flowg.grid_color1 { fill: green; } \n}. - qq{.flowg.grid_color2 { fill: red; } \n}. - qq{.flowg.grid_color3 { fill: gray; } \n}. - qq{.flowg.inactive_in { stroke: gray; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.2; } \n}. - qq{.flowg.inactive_out { stroke: gray; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.2; } \n}. - qq{.flowg.active_in { stroke: red; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.8; animation: dash 0.5s linear; animation-iteration-count: infinite; } \n}. - qq{.flowg.active_out { stroke: yellow; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.8; animation: dash 0.5s linear; animation-iteration-count: infinite; } \n} +my $cssdef = qq{.flowg.text { stroke: none; fill: gray; font-size: 32px;} \n}. + qq{.flowg.sun_active { stroke: orange; fill: orange; } \n}. + qq{.flowg.sun_inactive { stroke: gray; fill: gray; } \n}. + qq{.flowg.bat25 { stroke: red; fill: red; } \n}. + qq{.flowg.bat50 { stroke: yellow; fill: yellow; } \n}. + qq{.flowg.bat75 { stroke: green; fill: green; } \n}. + qq{.flowg.grid_color1 { fill: green; } \n}. + qq{.flowg.grid_color2 { fill: red; } \n}. + qq{.flowg.grid_color3 { fill: gray; } \n}. + qq{.flowg.inactive_in { stroke: gray; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.2; } \n}. + qq{.flowg.inactive_out { stroke: gray; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.2; } \n}. + qq{.flowg.active_in { stroke: red; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.8; animation: dash 0.5s linear; animation-iteration-count: infinite; } \n}. + qq{.flowg.active_out { stroke: yellow; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.8; animation: dash 0.5s linear; animation-iteration-count: infinite; } \n}. + qq{.flowg.active_bat_in { stroke: yellow; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.8; animation: dash 0.5s linear; animation-iteration-count: infinite; } \n}. + qq{.flowg.active_bat_out { stroke: green; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.8; animation: dash 0.5s linear; animation-iteration-count: infinite; } \n} ; my %hef = ( # Energiedaktoren für Verbrauchertypen @@ -593,6 +596,7 @@ sub Initialize { "flowGraphicSize ". "flowGraphicAnimate:1,0 ". "flowGraphicShowConsumer:1,0 ". + "flowGraphicShowConsumerDummy:1,0 ". "follow70percentRule:1,dynamic,0 ". "forcePageRefresh:1,0 ". "graphicSelect:both,flow,forecast,none ". @@ -1974,8 +1978,8 @@ sub centralTask { my $minute = strftime "%M", localtime($t); # aktuelle Minute my $day = strftime "%d", localtime($t); # aktueller Tag (range 01 to 31) my $dayname = strftime "%a", localtime($t); # aktueller Wochentagsname - - my $params = { + + my $centpars = { hash => $hash, name => $name, t => $t, @@ -1993,27 +1997,27 @@ sub centralTask { Log3 ($name, 4, "$name - ################################################################"); Log3 ($name, 4, "$name - current hour of day: ".($chour+1)); - collectAllRegConsumers ($params); # alle Verbraucher Infos laden + collectAllRegConsumers ($centpars); # alle Verbraucher Infos laden - _specialActivities ($params); # zusätzliche Events generieren + Sonderaufgaben - _transferWeatherValues ($params); # Wetterwerte übertragen - _transferDWDForecastValues ($params); # Forecast Werte übertragen - _transferInverterValues ($params); # WR Werte übertragen - _transferMeterValues ($params); # Energy Meter auswerten - _transferBatteryValues ($params); # Batteriewerte einsammeln - _manageConsumerData ($params); # Consumerdaten sammeln und planen - _estConsumptionForecast ($params); # erwarteten Verbrauch berechnen - _evaluateThresholds ($params); # Schwellenwerte bewerten und signalisieren - _calcSummaries ($params); # Zusammenfassungen erstellen + _specialActivities ($centpars); # zusätzliche Events generieren + Sonderaufgaben + _transferWeatherValues ($centpars); # Wetterwerte übertragen + _transferDWDForecastValues ($centpars); # Forecast Werte übertragen + _transferInverterValues ($centpars); # WR Werte übertragen + _transferMeterValues ($centpars); # Energy Meter auswerten + _transferBatteryValues ($centpars); # Batteriewerte einsammeln + _manageConsumerData ($centpars); # Consumerdaten sammeln und planen + _estConsumptionForecast ($centpars); # erwarteten Verbrauch berechnen + _evaluateThresholds ($centpars); # Schwellenwerte bewerten und signalisieren + _calcSummaries ($centpars); # Zusammenfassungen erstellen if(@da) { createReadingsFromArray ($hash, \@da, 1); } - calcVariance ($params); # Autokorrektur berechnen - saveEnergyConsumption ($params); # Energie Hausverbrauch speichern + calcVariance ($centpars); # Autokorrektur berechnen + saveEnergyConsumption ($centpars); # Energie Hausverbrauch speichern - readingsSingleUpdate($hash, "state", $params->{state}, 1); # Abschluß state + readingsSingleUpdate($hash, "state", $centpars->{state}, 1); # Abschluß state } else { InternalTimer(gettimeofday()+5, "FHEM::SolarForecast::centralTask", $hash, 0); @@ -4055,6 +4059,7 @@ sub entryGraphic { flowgh => AttrVal ($name, 'flowGraphicSize', $defflowGSize), # Größe Energieflußgrafik flowgani => AttrVal ($name, 'flowGraphicAnimate', 0), # Animation Energieflußgrafik flowgcons => AttrVal ($name, 'flowGraphicShowConsumer', 1), # Verbraucher in der Energieflußgrafik anzeigen + flowgconX => AttrVal ($name, 'flowGraphicShowConsumerDummy',1), # Dummyverbraucher in der Energieflußgrafik anzeigen css => AttrVal ($name, 'Css', $cssdef), # Css Styles }; @@ -5234,10 +5239,10 @@ sub _flowGraphic { my $flowgh = $paref->{flowgh}; my $flowgani = $paref->{flowgani}; my $flowgcons = $paref->{flowgcons}; + my $flowgconX = $paref->{flowgconX}; my $css = $paref->{css}; my $style = 'width:'.$flowgh.'px; height:'.$flowgh.'px;'; - # my $fs = $flowgh < 300 ? '48px' : '32px'; my $animation = $flowgani ? '@keyframes dash { to { stroke-dashoffset: 0; } }' : ''; # Animation Ja/Nein my $cpv = ReadingsNum($name, 'Current_PV', 0); @@ -5253,7 +5258,8 @@ sub _flowGraphic { my $csc_style = $csc ? 'flowg active_out' : 'flowg inactive_out'; my $cc = ReadingsNum($name, 'Current_Consumption', 0); - + my $cc_dummy = $cc; + my $batin = ReadingsNum($name, 'Current_PowerBatIn', undef); my $batout = ReadingsNum($name, 'Current_PowerBatOut', undef); my $soc = ReadingsNum($name, 'Current_BatCharge', 100); @@ -5276,9 +5282,9 @@ sub _flowGraphic { $csc_style = $csc ? 'flowg active_out' : 'flowg inactive_out'; } - my $batin_style = $batin ? 'flowg active_out' : 'flowg inactive_out'; - my $batout_style = $batout ? 'flowg active_in' : 'flowg inactive_in'; - my $grid_color = $cgfi ? 'flowg grid_color1' : 'flowg grid_color2'; + my $batin_style = $batin ? 'flowg active_in active_bat_in' : 'flowg inactive_out'; + my $batout_style = $batout ? 'flowg active_out active_bat_out' : 'flowg inactive_in'; + my $grid_color = $cgfi ? 'flowg grid_color1' : 'flowg grid_color2'; $grid_color = 'flowg grid_color3' if (!$cgfi && !$cgc && $batout); # dritte Farbe my $ret = << "END0"; @@ -5287,9 +5293,9 @@ sub _flowGraphic { $animation - + - + @@ -5317,11 +5323,11 @@ sub _flowGraphic { - + - + END0 @@ -5331,9 +5337,9 @@ END0 my $pos_left = 0; my $consumercount = 0; my $consumer_start = 0; - my $consumer_distance = 100; - my @consumers; + my $consumer_distance = 80; my $currentPower = 0; + my @consumers; if ($flowgcons) { my $type = $hash->{TYPE}; @@ -5341,10 +5347,10 @@ END0 $consumercount = scalar @consumers; if ($consumercount % 2) { - $consumer_start = 250 - ($consumer_distance * (($consumercount -1) / 2)); + $consumer_start = 350 - ($consumer_distance * (($consumercount -1) / 2)); } else { - $consumer_start = 250 - ((($consumer_distance ) / 2) * ($consumercount-1)); + $consumer_start = 350 - ((($consumer_distance ) / 2) * ($consumercount-1)); } $consumer_start = 0 if $consumer_start < 0; @@ -5354,7 +5360,8 @@ END0 my $calias = ConsumerVal ($hash, $c0, "alias", ""); # Name des Consumerdevices $currentPower = ReadingsNum ($name, "consumer${c0}_currentPower", 0); my $cicon = substConsumerIcon ($hash, $c0); # Icon des Consumerdevices - + $cc_dummy -= $currentPower; + $ret .= ''; $ret .= "$calias".FW_makeImage($cicon, ''); $ret .= ' '; @@ -5365,7 +5372,7 @@ END0 if ($hasbat) { $ret .= << "END1"; - + END1 @@ -5376,21 +5383,37 @@ END1 $ret .= '' if ($soc > 88); $ret .= ''; } - + + if ($flowgconX) { # Dummy Consumer + $ret .= ''; + $ret .= "consumer_X".FW_makeImage('light_light_dim_100', ''); + $ret .= ' '; + } + $ret .= << "END2"; - - - + + + END2 if ($hasbat) { $ret .= << "END3"; - - + + END3 } + if ($flowgconX) { # Dummy Consumer + my $consumer_style = 'flowg inactive_out'; + $consumer_style = 'flowg active_out' if($cc_dummy > 1); + + my $consumer_color = ""; + $consumer_color = 'style="stroke: #'.substr(Color::pahColor(0,500,1000,$cc_dummy,[0,255,0, 127,255,0, 255,255,0, 255,127,0, 255,0,0]),0,6).';"' if($cc_dummy > 0.5); + + $ret .= qq{}; + } + ## get consumer list and display it in Graphics ################################################ if ($flowgcons) { @@ -5399,10 +5422,10 @@ END3 my $distance = 25; if ($consumercount % 2) { - $pos_left_start = 500 - ($distance * (($consumercount -1) / 2)); + $pos_left_start = 700 - ($distance * (($consumercount -1) / 2)); } else { - $pos_left_start = 500 - ((($distance ) / 2) * ($consumercount-1)); + $pos_left_start = 700 - ((($distance ) / 2) * ($consumercount-1)); } for my $c1 (@consumers) { @@ -5430,16 +5453,19 @@ END3 $pos_left_start += $distance; } } + + $cc_dummy = sprintf("%.0f",$cc_dummy); - $ret .= qq{$cpv} if ($cpv); - $ret .= qq{$soc %} if ($hasbat); - $ret .= qq{$csc} if ($csc && $cpv); - $ret .= qq{$cgfi} if ($cgfi); - $ret .= qq{$cgc} if ($cgc); - $ret .= qq{$batout} if ($batout && $hasbat); - $ret .= qq{$batin} if ($batin && $hasbat); - $ret .= qq{$cc}; # Current_Consumption Anlage - + $ret .= qq{$cpv} if ($cpv); + $ret .= qq{$soc %} if ($hasbat); + $ret .= qq{$csc} if ($csc && $cpv); + $ret .= qq{$cgfi} if ($cgfi); + $ret .= qq{$cgc} if ($cgc); + $ret .= qq{$batout} if ($batout && $hasbat); + $ret .= qq{$batin} if ($batin && $hasbat); + $ret .= qq{$cc}; # Current_Consumption Anlage + $ret .= qq{$cc_dummy} if ($flowgconX); # Current_Consumption Dummy + ## get consumer list and display it in Graphics ################################################ if ($flowgcons) { @@ -5454,7 +5480,7 @@ END3 $currentPower = $swstate eq "on" ? 'on' : 'off'; } - $ret .= qq{$currentPower}; # Current_Consumption Consumer + $ret .= qq{$currentPower}; # Current_Consumption Consumer $pos_left += ($consumer_distance * 2); } } @@ -7812,19 +7838,21 @@ Ein/Ausschaltzeiten sowie deren Ausführung vom SolarForecast Modul übernehmen Zum Ändern des Css-Attributes bitte den Default übernehmen und anpassen:

@@ -7857,6 +7885,14 @@ Ein/Ausschaltzeiten sowie deren Ausführung vom SolarForecast Modul übernehmen
+ +
  • flowGraphicShowConsumerDummy
    + Zeigt bzw. unterdrückt den Dummy-Verbraucher in der Energieflußgrafik.
    + Dem Dummy-Verbraucher stellt den Energieverbrauch dar der anderen Verbrauchern nicht zugeordnet werden konnte.
    + (default: 1) +
  • +
    +
  • flowGraphicSize <Pixel>
    Größe der Energieflußgrafik sofern angezeigt.