mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 12:49:34 +00:00
76_SolarForecast.pm: contrib 0.56.0
git-svn-id: https://svn.fhem.de/fhem/trunk@24950 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
0786cc0367
commit
8d20c83965
@ -120,6 +120,7 @@ BEGIN {
|
|||||||
|
|
||||||
# Versions History intern
|
# Versions History intern
|
||||||
my %vNotesIntern = (
|
my %vNotesIntern = (
|
||||||
|
"0.56.0" => "11.09.2021 new Attr flowGraphicShowConsumer, extend calc consumer power consumption ",
|
||||||
"0.55.3" => "08.09.2021 add powerthreshold to etotal key ",
|
"0.55.3" => "08.09.2021 add powerthreshold to etotal key ",
|
||||||
"0.55.2" => "08.09.2021 minor fixes, use Color ",
|
"0.55.2" => "08.09.2021 minor fixes, use Color ",
|
||||||
"0.55.1" => "05.09.2021 delete invalid consumer index, Forum: https://forum.fhem.de/index.php/topic,117864.msg1173219.html#msg1173219 ",
|
"0.55.1" => "05.09.2021 delete invalid consumer index, Forum: https://forum.fhem.de/index.php/topic,117864.msg1173219.html#msg1173219 ",
|
||||||
@ -507,9 +508,10 @@ my $defcmode = "can";
|
|||||||
my $caicondef = 'light_light_dim_100@gold'; # default consumerAdviceIcon
|
my $caicondef = 'light_light_dim_100@gold'; # default consumerAdviceIcon
|
||||||
|
|
||||||
my $defflowGSize = 300; # default flowGraphicSize
|
my $defflowGSize = 300; # default flowGraphicSize
|
||||||
|
my $defpopercent = 0.5; # Standard % aktuelle Leistung an nominaler Leistung gemäß Typenschild
|
||||||
|
|
||||||
# Default CSS-Style
|
# Default CSS-Style
|
||||||
my $cssdef = qq{.flowg.text { stroke: none; fill: gray; } \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_active { stroke: orange; fill: orange; } \n}.
|
||||||
qq{.flowg.sun_inactive { stroke: gray; fill: gray; } \n}.
|
qq{.flowg.sun_inactive { stroke: gray; fill: gray; } \n}.
|
||||||
qq{.flowg.bat25 { stroke: red; fill: red; } \n}.
|
qq{.flowg.bat25 { stroke: red; fill: red; } \n}.
|
||||||
@ -583,6 +585,7 @@ sub Initialize {
|
|||||||
"disable:1,0 ".
|
"disable:1,0 ".
|
||||||
"flowGraphicSize ".
|
"flowGraphicSize ".
|
||||||
"flowGraphicAnimate:1,0 ".
|
"flowGraphicAnimate:1,0 ".
|
||||||
|
"flowGraphicShowConsumer:1,0 ".
|
||||||
"follow70percentRule:1,dynamic,0 ".
|
"follow70percentRule:1,dynamic,0 ".
|
||||||
"forcePageRefresh:1,0 ".
|
"forcePageRefresh:1,0 ".
|
||||||
"graphicSelect:both,flow,forecast,none ".
|
"graphicSelect:both,flow,forecast,none ".
|
||||||
@ -2167,6 +2170,10 @@ sub _specialActivities {
|
|||||||
deleteConsumerPlanning ($hash, $c);
|
deleteConsumerPlanning ($hash, $c);
|
||||||
my $calias = ConsumerVal ($hash, $c, "alias", "");
|
my $calias = ConsumerVal ($hash, $c, "alias", "");
|
||||||
Log3 ($name, 3, qq{$name - Consumer planning of "$calias" deleted});
|
Log3 ($name, 3, qq{$name - Consumer planning of "$calias" deleted});
|
||||||
|
|
||||||
|
$data{$type}{$name}{consumers}{$c}{minutesOn} = 0;
|
||||||
|
$data{$type}{$name}{consumers}{$c}{numberDayStarts} = 0;
|
||||||
|
$data{$type}{$name}{consumers}{$c}{onoff} = "off";
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteReadingspec ($hash, "consumer.*_planned.*");
|
deleteReadingspec ($hash, "consumer.*_planned.*");
|
||||||
@ -2602,61 +2609,116 @@ sub _manageConsumerData {
|
|||||||
my $paref = shift;
|
my $paref = shift;
|
||||||
my $hash = $paref->{hash};
|
my $hash = $paref->{hash};
|
||||||
my $name = $paref->{name};
|
my $name = $paref->{name};
|
||||||
|
my $t = $paref->{t}; # aktuelle Zeit
|
||||||
my $chour = $paref->{chour};
|
my $chour = $paref->{chour};
|
||||||
my $day = $paref->{day};
|
my $day = $paref->{day};
|
||||||
my $daref = $paref->{daref};
|
my $daref = $paref->{daref};
|
||||||
|
|
||||||
my $nhour = $chour+1;
|
my $nhour = $chour+1;
|
||||||
my $type = $hash->{TYPE};
|
my $type = $hash->{TYPE};
|
||||||
|
|
||||||
my $acref = $data{$type}{$name}{consumers};
|
|
||||||
|
|
||||||
for my $c (sort{$a<=>$b} keys %{$acref}) {
|
for my $c (sort{$a<=>$b} keys %{$data{$type}{$name}{consumers}}) {
|
||||||
my $consumer = $acref->{$c}{name};
|
my $consumer = ConsumerVal ($hash, $c, "name", "");
|
||||||
my $alias = $acref->{$c}{alias};
|
my $alias = ConsumerVal ($hash, $c, "alias", "");
|
||||||
|
|
||||||
## aktuelle Leistung auslesen
|
## aktuelle Leistung auslesen
|
||||||
##############################
|
##############################
|
||||||
my $paread = $acref->{$c}{rpcurr};
|
my $paread = ConsumerVal ($hash, $c, "rpcurr", "");
|
||||||
my $up = $acref->{$c}{upcurr};
|
my $up = ConsumerVal ($hash, $c, "upcurr", "");
|
||||||
|
my $pcurr = 0;
|
||||||
|
|
||||||
if($paread) {
|
if($paread) {
|
||||||
my $eup = $up =~ /^kW$/xi ? 1000 : 1;
|
my $eup = $up =~ /^kW$/xi ? 1000 : 1;
|
||||||
my $pcurr = ReadingsNum ($consumer, $paread, 0) * $eup;
|
$pcurr = ReadingsNum ($consumer, $paread, 0) * $eup;
|
||||||
|
|
||||||
push @$daref, "consumer${c}_currentPower<>". $pcurr." W";
|
push @$daref, "consumer${c}_currentPower<>". $pcurr." W";
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
deleteReadingspec ($hash, "consumer${c}_currentPower");
|
|
||||||
}
|
|
||||||
|
|
||||||
## Verbrauch auslesen + speichern
|
## Verbrauch auslesen + speichern
|
||||||
##################################
|
##################################
|
||||||
my $enread = $acref->{$c}{retotal};
|
my $pthreshold = 0;
|
||||||
my $u = $acref->{$c}{uetotal};
|
my $enread = ConsumerVal ($hash, $c, "retotal", "");
|
||||||
|
my $u = ConsumerVal ($hash, $c, "uetotal", "");
|
||||||
|
|
||||||
if($enread) {
|
if($enread) {
|
||||||
my $eu = $u =~ /^kWh$/xi ? 1000 : 1;
|
my $eu = $u =~ /^kWh$/xi ? 1000 : 1;
|
||||||
my $etot = ReadingsNum ($consumer, $enread, 0) * $eu; # Summe Energieverbrauch des Verbrauchers
|
my $etot = ReadingsNum ($consumer, $enread, 0) * $eu; # Summe Energieverbrauch des Verbrauchers
|
||||||
my $ehist = HistoryVal ($hash, $day, sprintf("%02d",$nhour), "csmt${c}", undef); # gespeicherter Totalverbrauch
|
my $ehist = HistoryVal ($hash, $day, sprintf("%02d",$nhour), "csmt${c}", undef); # gespeicherter Totalverbrauch
|
||||||
my $pthreshold = ConsumerVal ($hash, $c, "powerthreshold", 0); # Schwellenwert (Wh pro Stunde) ab der ein Verbraucher als aktiv gewertet wird
|
$pthreshold = ConsumerVal ($hash, $c, "powerthreshold", 0); # Schwellenwert (Wh pro Stunde) ab der ein Verbraucher als aktiv gewertet wird
|
||||||
|
|
||||||
|
## aktuelle Leitung ermitteln wenn kein Reading d. aktuellen Leistung verfügbar
|
||||||
|
################################################################################
|
||||||
|
if(!$paread){
|
||||||
|
my $timespan = $t - ConsumerVal ($hash, $c, "old_etottime", $t);
|
||||||
|
my $delta = $etot - ConsumerVal ($hash, $c, "old_etotal", $etot);
|
||||||
|
$pcurr = sprintf("%.6f", $delta / (3600 * $timespan)) if($delta > 0); # Einheitenformel beachten !!: W = Wh / (3600 * s)
|
||||||
|
|
||||||
|
$data{$type}{$name}{consumers}{$c}{old_etotal} = $etot;
|
||||||
|
$data{$type}{$name}{consumers}{$c}{old_etottime} = $t;
|
||||||
|
|
||||||
|
push @$daref, "consumer${c}_currentPower<>". $pcurr." W";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
deleteReadingspec ($hash, "consumer${c}_currentPower");
|
||||||
|
}
|
||||||
|
|
||||||
if(defined $ehist && $etot >= $ehist && ($etot - $ehist) >= $pthreshold) {
|
if(defined $ehist && $etot >= $ehist && ($etot - $ehist) >= $pthreshold) {
|
||||||
my $consumerco = $etot - $ehist;
|
my $consumerco = $etot - $ehist;
|
||||||
$consumerco += HistoryVal ($hash, $day, sprintf("%02d",$nhour), "csme${c}", 0);
|
$consumerco += HistoryVal ($hash, $day, sprintf("%02d",$nhour), "csme${c}", 0);
|
||||||
|
|
||||||
$paref->{consumerco} = $consumerco;
|
$paref->{consumerco} = $consumerco;
|
||||||
$paref->{nhour} = sprintf("%02d",$nhour);
|
$paref->{nhour} = sprintf("%02d",$nhour); # Verbrauch des Consumers aktuelle Stunde
|
||||||
$paref->{histname} = "csme${c}";
|
$paref->{histname} = "csme${c}";
|
||||||
setPVhistory ($paref);
|
setPVhistory ($paref);
|
||||||
delete $paref->{histname};
|
delete $paref->{histname};
|
||||||
}
|
}
|
||||||
|
|
||||||
$paref->{consumerco} = $etot;
|
$paref->{consumerco} = $etot; # Totalverbrauch des Verbrauchers
|
||||||
$paref->{nhour} = sprintf("%02d",$nhour);
|
$paref->{nhour} = sprintf("%02d",$nhour);
|
||||||
$paref->{histname} = "csmt${c}";
|
$paref->{histname} = "csmt${c}";
|
||||||
setPVhistory ($paref);
|
setPVhistory ($paref);
|
||||||
delete $paref->{histname};
|
delete $paref->{histname};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
## Verbraucher - Laufzeit und Zyklen pro Tag ermitteln
|
||||||
|
## Laufzeit (in Minuten) wird pro Stunde erfasst
|
||||||
|
## bei Tageswechsel Rücksetzen in _specialActivities
|
||||||
|
#######################################################
|
||||||
|
my $nompower = ConsumerVal ($hash, $c, "power", 0); # nominale Leistung lt. Typenschild
|
||||||
|
my $rpcurr = ConsumerVal ($hash, $c, "rpcurr", ""); # Reading für akt. Verbrauch angegeben ?
|
||||||
|
my $swstate = ConsumerVal ($hash, $c, "state", "undef"); # Schaltzustand des Consumerdevices
|
||||||
|
|
||||||
|
if (!$rpcurr && $swstate eq "on") { # Workaround wenn Verbraucher ohne Leistungsmessung
|
||||||
|
$pcurr = $nompower;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $currpowerpercent = $pcurr;
|
||||||
|
$currpowerpercent = (($pcurr / $nompower) * 100) if($nompower > 0);
|
||||||
|
|
||||||
|
$data{$type}{$name}{consumers}{$c}{currpowerpercent} = $currpowerpercent;
|
||||||
|
|
||||||
|
if($pcurr > $pthreshold || $currpowerpercent > $defpopercent) {
|
||||||
|
if($data{$type}{$name}{consumers}{$c}{onoff} ne "on") {
|
||||||
|
$data{$type}{$name}{consumers}{$c}{startTime} = $t;
|
||||||
|
$data{$type}{$name}{consumers}{$c}{onoff} = "on";
|
||||||
|
my $stimes = ConsumerVal ($hash, $c, "numberDayStarts", 0); # Anzahl der On-Schaltungen am Tag
|
||||||
|
$data{$type}{$name}{consumers}{$c}{numberDayStarts} = $stimes+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $starthour = strftime "%H", localtime(ConsumerVal ($hash, $c, "startTime", $t));
|
||||||
|
|
||||||
|
if($chour eq $starthour) {
|
||||||
|
my $runtime = ($t - ConsumerVal ($hash, $c, "startTime", $t)) / 60 ; # in Minuten ! (gettimeofday sind ms !)
|
||||||
|
$data{$type}{$name}{consumers}{$c}{minutesOn} = ConsumerVal ($hash, $c, "minutesOn", 0) + $runtime;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$data{$type}{$name}{consumers}{$c}{minutesOn} = 0; # neue Stunde hat begonnen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$data{$type}{$name}{consumers}{$c}{onoff} = "off";
|
||||||
|
}
|
||||||
|
|
||||||
## Durchschnittsverbrauch / Betriebszeit ermitteln + speichern
|
## Durchschnittsverbrauch / Betriebszeit ermitteln + speichern
|
||||||
################################################################
|
################################################################
|
||||||
my $consumerco = 0;
|
my $consumerco = 0;
|
||||||
@ -3852,6 +3914,7 @@ sub entryGraphic {
|
|||||||
lang => AttrVal ("global", 'language', 'EN'),
|
lang => AttrVal ("global", 'language', 'EN'),
|
||||||
flowgh => AttrVal ($name, 'flowGraphicSize', $defflowGSize), # Größe Energieflußgrafik
|
flowgh => AttrVal ($name, 'flowGraphicSize', $defflowGSize), # Größe Energieflußgrafik
|
||||||
flowgani => AttrVal ($name, 'flowGraphicAnimate', 0), # Animation Energieflußgrafik
|
flowgani => AttrVal ($name, 'flowGraphicAnimate', 0), # Animation Energieflußgrafik
|
||||||
|
flowgcons => AttrVal ($name, 'flowGraphicShowConsumer', 1), # Verbraucher in der Energieflußgrafik anzeigen
|
||||||
css => AttrVal ($name, 'Css', $cssdef), # Css Styles
|
css => AttrVal ($name, 'Css', $cssdef), # Css Styles
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -5030,10 +5093,11 @@ sub _flowGraphic {
|
|||||||
my $name = $paref->{name};
|
my $name = $paref->{name};
|
||||||
my $flowgh = $paref->{flowgh};
|
my $flowgh = $paref->{flowgh};
|
||||||
my $flowgani = $paref->{flowgani};
|
my $flowgani = $paref->{flowgani};
|
||||||
|
my $flowgcons = $paref->{flowgcons};
|
||||||
my $css = $paref->{css};
|
my $css = $paref->{css};
|
||||||
|
|
||||||
my $style = 'width:'.$flowgh.'px; height:'.$flowgh.'px;';
|
my $style = 'width:'.$flowgh.'px; height:'.$flowgh.'px;';
|
||||||
my $fs = $flowgh < 300 ? '48px' : '32px';
|
# my $fs = $flowgh < 300 ? '48px' : '32px';
|
||||||
my $animation = $flowgani ? '@keyframes dash { to { stroke-dashoffset: 0; } }' : ''; # Animation Ja/Nein
|
my $animation = $flowgani ? '@keyframes dash { to { stroke-dashoffset: 0; } }' : ''; # Animation Ja/Nein
|
||||||
|
|
||||||
my $cpv = ReadingsNum($name, 'Current_PV', 0);
|
my $cpv = ReadingsNum($name, 'Current_PV', 0);
|
||||||
@ -5047,6 +5111,8 @@ sub _flowGraphic {
|
|||||||
|
|
||||||
my $csc = ReadingsNum($name, 'Current_SelfConsumption', 0);
|
my $csc = ReadingsNum($name, 'Current_SelfConsumption', 0);
|
||||||
my $csc_style = $csc ? 'flowg active_out' : 'flowg inactive_out';
|
my $csc_style = $csc ? 'flowg active_out' : 'flowg inactive_out';
|
||||||
|
|
||||||
|
my $cc = ReadingsNum($name, 'Current_Consumption', 0);
|
||||||
|
|
||||||
my $batin = ReadingsNum($name, 'Current_PowerBatIn', undef);
|
my $batin = ReadingsNum($name, 'Current_PowerBatIn', undef);
|
||||||
my $batout = ReadingsNum($name, 'Current_PowerBatOut', undef);
|
my $batout = ReadingsNum($name, 'Current_PowerBatOut', undef);
|
||||||
@ -5122,34 +5188,39 @@ END0
|
|||||||
|
|
||||||
## get consumer list and display it in Graphics
|
## get consumer list and display it in Graphics
|
||||||
################################################
|
################################################
|
||||||
my $type = $hash->{TYPE};
|
my $pos_left = 0;
|
||||||
my @consumers = sort{$a<=>$b} keys %{$data{$type}{$name}{consumers}}; # definierte Verbraucher ermitteln
|
my $consumercount = 0;
|
||||||
my $consumercount = scalar @consumers;
|
|
||||||
my $consumer_start = 0;
|
my $consumer_start = 0;
|
||||||
my $consumer_distance = 100;
|
my $consumer_distance = 100;
|
||||||
|
my @consumers;
|
||||||
|
my $currentPower = 0;
|
||||||
|
|
||||||
my $currentPower;
|
if ($flowgcons) {
|
||||||
|
my $type = $hash->{TYPE};
|
||||||
if ($consumercount % 2) {
|
@consumers = sort{$a<=>$b} keys %{$data{$type}{$name}{consumers}}; # definierte Verbraucher ermitteln
|
||||||
$consumer_start = 250 - ($consumer_distance * (($consumercount -1) / 2));
|
$consumercount = scalar @consumers;
|
||||||
}
|
|
||||||
else {
|
|
||||||
$consumer_start = 250 - ((($consumer_distance ) / 2) * ($consumercount-1));
|
|
||||||
}
|
|
||||||
|
|
||||||
$consumer_start = 0 if $consumer_start < 0;
|
|
||||||
my $pos_left = $consumer_start + 15;
|
|
||||||
|
|
||||||
for my $c0 (@consumers) {
|
|
||||||
my $calias = ConsumerVal ($hash, $c0, "alias", ""); # Name des Consumerdevices
|
|
||||||
$currentPower = ReadingsNum ($name, "consumer${c0}_currentPower", 0);
|
|
||||||
my $cicon = substConsumerIcon ($hash, $c0); # Icon des Consumerdevices
|
|
||||||
|
|
||||||
$ret .= '<g id="consumer_'.$c0.'" fill="grey" transform="translate('.$pos_left.',485),scale(0.1)">';
|
if ($consumercount % 2) {
|
||||||
$ret .= "<title>$calias</title>".FW_makeImage($cicon, '');
|
$consumer_start = 250 - ($consumer_distance * (($consumercount -1) / 2));
|
||||||
$ret .= '</g> ';
|
}
|
||||||
|
else {
|
||||||
$pos_left += $consumer_distance;
|
$consumer_start = 250 - ((($consumer_distance ) / 2) * ($consumercount-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
$consumer_start = 0 if $consumer_start < 0;
|
||||||
|
$pos_left = $consumer_start + 15;
|
||||||
|
|
||||||
|
for my $c0 (@consumers) {
|
||||||
|
my $calias = ConsumerVal ($hash, $c0, "alias", ""); # Name des Consumerdevices
|
||||||
|
$currentPower = ReadingsNum ($name, "consumer${c0}_currentPower", 0);
|
||||||
|
my $cicon = substConsumerIcon ($hash, $c0); # Icon des Consumerdevices
|
||||||
|
|
||||||
|
$ret .= '<g id="consumer_'.$c0.'" fill="grey" transform="translate('.$pos_left.',485),scale(0.1)">';
|
||||||
|
$ret .= "<title>$calias</title>".FW_makeImage($cicon, '');
|
||||||
|
$ret .= '</g> ';
|
||||||
|
|
||||||
|
$pos_left += $consumer_distance;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($hasbat) {
|
if ($hasbat) {
|
||||||
@ -5182,65 +5253,70 @@ END3
|
|||||||
|
|
||||||
## get consumer list and display it in Graphics
|
## get consumer list and display it in Graphics
|
||||||
################################################
|
################################################
|
||||||
$pos_left = $consumer_start * 2;
|
if ($flowgcons) {
|
||||||
my $pos_left_start = 0;
|
$pos_left = $consumer_start * 2;
|
||||||
my $distance = 25;
|
my $pos_left_start = 0;
|
||||||
|
my $distance = 25;
|
||||||
if ($consumercount % 2) {
|
|
||||||
$pos_left_start = 500 - ($distance * (($consumercount -1) / 2));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$pos_left_start = 500 - ((($distance ) / 2) * ($consumercount-1));
|
|
||||||
}
|
|
||||||
|
|
||||||
for my $c1 (@consumers) {
|
|
||||||
my $power = ConsumerVal ($hash, $c1, "power", 0);
|
|
||||||
my $rpcurr = ConsumerVal ($hash, $c1, "rpcurr", ""); # Reading für akt. Verbrauch angegeben ?
|
|
||||||
my $swstate = ConsumerVal ($hash, $c1, "state", "undef"); # Schaltzustand des Consumerdevices
|
|
||||||
$currentPower = ReadingsNum ($name, "consumer${c1}_currentPower", 0);
|
|
||||||
|
|
||||||
if (!$rpcurr && $swstate eq "on") { # Workaround wenn Verbraucher ohne Leistungsmessung
|
if ($consumercount % 2) {
|
||||||
$currentPower = $power;
|
$pos_left_start = 500 - ($distance * (($consumercount -1) / 2));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$pos_left_start = 500 - ((($distance ) / 2) * ($consumercount-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
my $p = $currentPower;
|
for my $c1 (@consumers) {
|
||||||
$p = (($currentPower / $power) * 100) if ($power > 0);
|
my $power = ConsumerVal ($hash, $c1, "power", 0);
|
||||||
|
my $rpcurr = ConsumerVal ($hash, $c1, "rpcurr", ""); # Reading für akt. Verbrauch angegeben ?
|
||||||
|
my $swstate = ConsumerVal ($hash, $c1, "state", "undef"); # Schaltzustand des Consumerdevices
|
||||||
|
$currentPower = ReadingsNum ($name, "consumer${c1}_currentPower", 0);
|
||||||
|
|
||||||
|
if (!$rpcurr && $swstate eq "on") { # Workaround wenn Verbraucher ohne Leistungsmessung
|
||||||
|
$currentPower = $power;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $p = $currentPower;
|
||||||
|
$p = (($currentPower / $power) * 100) if ($power > 0);
|
||||||
|
|
||||||
|
my $consumer_style = 'flowg inactive_out';
|
||||||
|
$consumer_style = 'flowg active_out' if($p > $defpopercent);
|
||||||
|
|
||||||
my $consumer_style = 'flowg inactive_out';
|
my $consumer_color = "";
|
||||||
$consumer_style = 'flowg active_out' if($p > 0.5);
|
$consumer_color = 'style="stroke: #'.substr(Color::pahColor(0,50,100,$p,[0,255,0, 127,255,0, 255,255,0, 255,127,0, 255,0,0]),0,6).';"' if($p > 0.5);
|
||||||
|
|
||||||
my $consumer_color = "";
|
$ret .= qq{<path id="home-consumer_$c1" class="$consumer_style" $consumer_color d="M$pos_left_start,700 L$pos_left,850" />};
|
||||||
$consumer_color = 'style="stroke: #'.substr(Color::pahColor(0,50,100,$p,[0,255,0, 127,255,0, 255,255,0, 255,127,0, 255,0,0]),0,6).';"' if($p > 0.5);
|
|
||||||
|
$pos_left += ($consumer_distance * 2);
|
||||||
$ret .= qq{<path id="home-consumer_$c1" class="$consumer_style" $consumer_color d="M$pos_left_start,700 L$pos_left,850" />};
|
$pos_left_start += $distance;
|
||||||
|
}
|
||||||
$pos_left += ($consumer_distance * 2);
|
}
|
||||||
$pos_left_start += $distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
$ret .= qq{<text class="flowg text" id="pv-txt" x="600" y="15" style="font-size: $fs; text-anchor: start;">$cpv</text>} if ($cpv);
|
$ret .= qq{<text class="flowg text" id="pv-txt" x="600" y="15" style="text-anchor: start;">$cpv</text>} if ($cpv);
|
||||||
$ret .= qq{<text class="flowg text" id="bat-txt" x="795" y="370" style="font-size: $fs; text-anchor: middle;">$soc %</text>} if ($hasbat);
|
$ret .= qq{<text class="flowg text" id="bat-txt" x="795" y="370" style="text-anchor: middle;">$soc %</text>} if ($hasbat);
|
||||||
$ret .= qq{<text class="flowg text" id="pv_home-txt" x="530" y="300" style="font-size: $fs; text-anchor: start;">$csc</text>} if ($csc && $cpv);
|
$ret .= qq{<text class="flowg text" id="pv_home-txt" x="530" y="300" style="text-anchor: start;">$csc</text>} if ($csc && $cpv);
|
||||||
$ret .= qq{<text class="flowg text" id="pv-grid-txt" x="325" y="200" style="font-size: $fs; text-anchor: end;">$cgfi</text>} if ($cgfi);
|
$ret .= qq{<text class="flowg text" id="pv-grid-txt" x="325" y="200" style="text-anchor: end;">$cgfi</text>} if ($cgfi);
|
||||||
$ret .= qq{<text class="flowg text" id="grid-home-txt" x="325" y="420" style="font-size: $fs; text-anchor: end;">$cgc</text>} if ($cgc);
|
$ret .= qq{<text class="flowg text" id="grid-home-txt" x="325" y="420" style="text-anchor: end;">$cgc</text>} if ($cgc);
|
||||||
$ret .= qq{<text class="flowg text" id="batout-txt" x="665" y="420" style="font-size: $fs; text-anchor: start;">$batout</text>} if ($batout && $hasbat);
|
$ret .= qq{<text class="flowg text" id="batout-txt" x="665" y="420" style="text-anchor: start;">$batout</text>} if ($batout && $hasbat);
|
||||||
$ret .= qq{<text class="flowg text" id="batin-txt" x="665" y="200" style="font-size: $fs; text-anchor: start;">$batin</text>} if ($batin && $hasbat);
|
$ret .= qq{<text class="flowg text" id="batin-txt" x="665" y="200" style="text-anchor: start;">$batin</text>} if ($batin && $hasbat);
|
||||||
|
# $ret .= qq{<text class="flowg text" id="home-txt" x="600" y="620" style="text-anchor: start;">$cc</text>}; # Current_Consumption Anlage
|
||||||
|
|
||||||
## get consumer list and display it in Graphics
|
## get consumer list and display it in Graphics
|
||||||
################################################
|
################################################
|
||||||
$pos_left = ($consumer_start * 2) - 50;
|
if ($flowgcons) {
|
||||||
|
$pos_left = ($consumer_start * 2) - 50;
|
||||||
for my $c2 (@consumers) {
|
|
||||||
$currentPower = sprintf("%.1f", ReadingsNum($name, "consumer${c2}_currentPower", 0));
|
|
||||||
my $swstate = ConsumerVal ($hash, $c2, "state", "undef"); # Schaltzustand des Consumerdevices
|
|
||||||
my $rpcurr = ConsumerVal ($hash, $c2, "rpcurr", ""); # Readingname f. current Power
|
|
||||||
|
|
||||||
if (!$rpcurr) { # Workaround wenn Verbraucher ohne Leistungsmessung
|
for my $c2 (@consumers) {
|
||||||
$currentPower = $swstate eq "on" ? 'on' : 'off';
|
$currentPower = sprintf("%.1f", ReadingsNum($name, "consumer${c2}_currentPower", 0));
|
||||||
|
my $swstate = ConsumerVal ($hash, $c2, "state", "undef"); # Schaltzustand des Consumerdevices
|
||||||
|
my $rpcurr = ConsumerVal ($hash, $c2, "rpcurr", ""); # Readingname f. current Power
|
||||||
|
|
||||||
|
if (!$rpcurr) { # Workaround wenn Verbraucher ohne Leistungsmessung
|
||||||
|
$currentPower = $swstate eq "on" ? 'on' : 'off';
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret .= qq{<text class="flowg text" id="consumer-txt_$c2" x="$pos_left" y="1070" style="text-anchor: start;">$currentPower</text>}; # Current_Consumption Consumer
|
||||||
|
$pos_left += ($consumer_distance * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
$ret .= qq{<text class="flowg text" id="consumer-txt_$c2" x="$pos_left" y="1070" style="font-size: $fs; text-anchor: start;">$currentPower</text>};
|
|
||||||
$pos_left += ($consumer_distance * 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$ret .= qq{</g></svg>};
|
$ret .= qq{</g></svg>};
|
||||||
@ -7551,15 +7627,15 @@ Ein/Ausschaltzeiten sowie deren Ausführung vom SolarForecast Modul übernehmen
|
|||||||
Zum Ändern des Css-Attributes bitte den Default übernehmen und anpassen: <br><br>
|
Zum Ändern des Css-Attributes bitte den Default übernehmen und anpassen: <br><br>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
.flowg.text { stroke: none; fill: gray; } <br>
|
.flowg.text { stroke: none; fill: gray; font-size: 32px; } <br>
|
||||||
.flowg.sun_active { stroke: orange; fill: orange; } <br>
|
.flowg.sun_active { stroke: orange; fill: orange; } <br>
|
||||||
.flowg.sun_inactive { stroke: gray; fill: gray; } <br>
|
.flowg.sun_inactive { stroke: gray; fill: gray; } <br>
|
||||||
.flowg.bat25 { stroke: red; fill: red; } <br>
|
.flowg.bat25 { stroke: red; fill: red; } <br>
|
||||||
.flowg.bat50 { stroke: yellow; fill: yellow; } <br>
|
.flowg.bat50 { stroke: yellow; fill: yellow; } <br>
|
||||||
.flowg.bat75 { stroke: green; fill: green; } <br>
|
.flowg.bat75 { stroke: green; fill: green; } <br>
|
||||||
.flowg.grid_color1 { fill: green; } <br>
|
.flowg.grid_color1 { fill: green; } <br>
|
||||||
.flowg.grid_color2 { fill: red; } <br>
|
.flowg.grid_color2 { fill: red; } <br>
|
||||||
.flowg.grid_color3 { fill: gray; } <br>
|
.flowg.grid_color3 { fill: gray; } <br>
|
||||||
.flowg.inactive_in { stroke: gray; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.2; } <br>
|
.flowg.inactive_in { stroke: gray; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.2; } <br>
|
||||||
.flowg.inactive_out { stroke: gray; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.2; } <br>
|
.flowg.inactive_out { stroke: gray; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.2; } <br>
|
||||||
.flowg.active_in { stroke: red; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.8; animation: dash 0.5s linear; animation-iteration-count: infinite; } <br>
|
.flowg.active_in { stroke: red; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.8; animation: dash 0.5s linear; animation-iteration-count: infinite; } <br>
|
||||||
@ -7589,6 +7665,13 @@ Ein/Ausschaltzeiten sowie deren Ausführung vom SolarForecast Modul übernehmen
|
|||||||
</li>
|
</li>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
<a id="SolarForecast-attr-flowGraphicShowConsumer"></a>
|
||||||
|
<li><b>flowGraphicShowConsumer </b><br>
|
||||||
|
Unterdrückt die Anzeige der Verbraucher in der Energieflußgrafik wenn auf "0" gesetzt. <br>
|
||||||
|
(default: 1)
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
<a id="SolarForecast-attr-flowGraphicSize"></a>
|
<a id="SolarForecast-attr-flowGraphicSize"></a>
|
||||||
<li><b>flowGraphicSize <Pixel> </b><br>
|
<li><b>flowGraphicSize <Pixel> </b><br>
|
||||||
Größe der Energieflußgrafik sofern angezeigt.
|
Größe der Energieflußgrafik sofern angezeigt.
|
||||||
|
Loading…
Reference in New Issue
Block a user