2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 06:39:11 +00:00

76_SolarForecast: contrib 1.37.2

git-svn-id: https://svn.fhem.de/fhem/trunk@29287 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2024-10-24 20:35:48 +00:00
parent 3e419d9e14
commit 2e8d960718

View File

@ -156,6 +156,7 @@ BEGIN {
# Versions History intern # Versions History intern
my %vNotesIntern = ( my %vNotesIntern = (
"1.37.2" => "24.10.2024 _flowGraphic: show Producer Row only if more than one Producer is defined ",
"1.37.1" => "23.10.2024 state: 'The setup routine is still incomplete' if setup is incomplete ". "1.37.1" => "23.10.2024 state: 'The setup routine is still incomplete' if setup is incomplete ".
"change: 'trackFlex' && \$wcc >= 80 to \$wcc >= 70, implement Rename function ". "change: 'trackFlex' && \$wcc >= 80 to \$wcc >= 70, implement Rename function ".
"_flowGraphic: eliminate numbers in device name - Forum: https://forum.fhem.de/index.php?msg=1323229 ", "_flowGraphic: eliminate numbers in device name - Forum: https://forum.fhem.de/index.php?msg=1323229 ",
@ -6394,7 +6395,8 @@ sub Delete {
$csmcache.$name, $csmcache.$name,
$scpicache.$name, $scpicache.$name,
$airaw.$name, $airaw.$name,
$aitrained.$name $aitrained.$name,
$pvhexprtcsv.$name
); );
opendir (DIR, $cachedir); opendir (DIR, $cachedir);
@ -6414,6 +6416,9 @@ sub Delete {
if ($err) { if ($err) {
Log3 ($name, 1, qq{$name - Message while deleting file "$f": $err}); Log3 ($name, 1, qq{$name - Message while deleting file "$f": $err});
} }
else {
Log3 ($name, 3, qq{$name - INFO - File "$f" successfully deleted.});
}
} }
my $type = $hash->{TYPE}; my $type = $hash->{TYPE};
@ -14284,6 +14289,9 @@ sub _flowGraphic {
'3tobat' => { xicon => 750, xchain => 1100, ychain => 430, step => 40, count => scalar @{$tobat}, sorted => $tobat }, # Producer/PV nur zu Batterie '3tobat' => { xicon => 750, xchain => 1100, ychain => 430, step => 40, count => scalar @{$tobat}, sorted => $tobat }, # Producer/PV nur zu Batterie
}; };
my $doproducerrow = 1;
$doproducerrow = 0 if(!$psorted->{'1togrid'}{count} && !$psorted->{'3tobat'}{count} && $psorted->{'2tonode'}{count} == 1);
## definierte Verbraucher ermitteln ## definierte Verbraucher ermitteln
##################################### #####################################
my $cnsmr = {}; # Hashref Consumer current power my $cnsmr = {}; # Hashref Consumer current power
@ -14352,13 +14360,13 @@ sub _flowGraphic {
######################################### #########################################
my $vbwidth = 800; # width and height specify the viewBox size my $vbwidth = 800; # width and height specify the viewBox size
my $vbminx = -10 * $flowgshift; # min-x and min-y represent the smallest X and Y coordinates that the viewBox may have my $vbminx = -10 * $flowgshift; # min-x and min-y represent the smallest X and Y coordinates that the viewBox may have
my $vbminy = -25; my $vbminy = $doproducerrow ? -25 : 125; # Grafik höher positionieren wenn keine Poducerreihe angezeigt
my $vbhight = !$flowgcons ? 380 : my $vbhight = !$flowgcons ? 380 :
!$flowgconsTime ? 590 : !$flowgconsTime ? 590 :
610; 610;
$vbhight += 100; if ($doproducerrow) {$vbhight += 100}; # Höhe Box vergrößern wenn Poducerreihe angezeigt
my $vbox = "$vbminx $vbminy $vbwidth $vbhight"; my $vbox = "$vbminx $vbminy $vbwidth $vbhight";
my $svgstyle = 'width:98%; height:'.$flowgsize.'px;'; my $svgstyle = 'width:98%; height:'.$flowgsize.'px;';
@ -14398,61 +14406,32 @@ END0
## Producer Icon - in Reihenfolge: zum Grid - zum Knoten - zur Batterie ## Producer Icon - in Reihenfolge: zum Grid - zum Knoten - zur Batterie
######################################################################### #########################################################################
for my $st (sort keys %{$psorted}) { $paref->{stna} = $stna;
my $left = 0; $paref->{pnodesum} = $pnodesum;
my $xicon = $psorted->{$st}{xicon}; $paref->{psorted} = $psorted;
my $count = $psorted->{$st}{count}; $paref->{pdcr} = $pdcr;
my @sorted = @{$psorted->{$st}{sorted}}; $paref->{pdist} = $pdist;
if ($count % 2) { if (!$doproducerrow) {
$xicon = $xicon - ($pdist * ($count - 1) / 2); $paref->{y_coord} = 165;
} $ret .= __addProducerIcon ($paref); # Producer Icons row einfügen
else { }
$xicon = $xicon - ($pdist / 2 * ($count - 1)); else { # mehr als ein Producer vorhanden
} $paref->{y_coord} = 0;
$ret .= __addProducerIcon ($paref); # Producer Icons row einfügen
$psorted->{$st}{start} = $xicon; $paref->{x_coord} = 360;
$left = $xicon + 5; $paref->{y_coord} = 165;
$ret .= __addNodeIcon ($paref); # Knoten Icon
for my $lfn (@sorted) {
my $pn = $pdcr->{$lfn}{pn};
my ($picon, $ptxt) = __substituteIcon ( { hash => $hash, # Icon des Producerdevices
name => $name,
pn => $pn,
ptyp => $pdcr->{$lfn}{ptyp},
don => NexthoursVal ($hash, 'NextHour00', 'DoN', 0), # Tag oder Nacht
pcurr => $pdcr->{$lfn}{p},
lang => $lang
}
);
$picon = FW_makeImage ($picon, '');
($scale, $picon) = __normIconScale ($picon, $name);
$ret .= qq{<g id="producer_${pn}_$stna" fill="grey" transform="translate($left,0),scale($scale)">};
$ret .= "<title>$ptxt</title>".$picon;
$ret .= '</g> ';
$left += $pdist;
}
} }
## Knoten Icon delete $paref->{stna};
################ delete $paref->{pnodesum};
my ($nicon, $ntxt) = __substituteIcon ( { hash => $hash, delete $paref->{psorted};
name => $name, delete $paref->{pdcr};
ptyp => 'node', delete $paref->{pdist};
pcurr => $pnodesum, delete $paref->{x_coord};
lang => $lang delete $paref->{y_coord};
}
);
$nicon = FW_makeImage ($nicon, '');
($scale, $nicon) = __normIconScale ($nicon, $name);
$ret .= qq{<g id="node_$stna" transform="translate(360,165),scale($scale)">}; # translate(X-Koordinate,Y-Koordinate), scale(<Größe>)-> Koordinaten ändern sich bei Größenänderung
$ret .= "<title>$ntxt</title>".$nicon;
$ret .= '</g> ';
## Consumer Liste und Icons in Grafik anzeigen ## Consumer Liste und Icons in Grafik anzeigen
################################################ ################################################
@ -14574,37 +14553,40 @@ END3
} }
## Producer Laufketten - in Reihenfolge: zum Grid - zum Knoten - zur Batterie ## Producer Laufketten - in Reihenfolge: zum Grid - zum Knoten - zur Batterie
## Laufkette nur anzeigen wenn Producerzeile angezeigt werden soll
############################################################################### ###############################################################################
for my $st (sort keys %{$psorted}) { if ($doproducerrow) {
my $left = $psorted->{$st}{start} * 2; # Übertrag aus Producer Icon Abschnitt for my $st (sort keys %{$psorted}) {
my $count = $psorted->{$st}{count}; my $left = $psorted->{$st}{start} * 2; # Übertrag aus Producer Icon Abschnitt
my $xchain = $psorted->{$st}{xchain}; # X- Koordinate Kette am Ziel my $count = $psorted->{$st}{count};
my $ychain = $psorted->{$st}{ychain}; # Y- Koordinate Kette am Ziel my $xchain = $psorted->{$st}{xchain}; # X- Koordinate Kette am Ziel
my $step = $psorted->{$st}{step}; my $ychain = $psorted->{$st}{ychain}; # Y- Koordinate Kette am Ziel
my @sorted = @{$psorted->{$st}{sorted}}; my $step = $psorted->{$st}{step};
my @sorted = @{$psorted->{$st}{sorted}};
if ($count % 2) { if ($count % 2) {
$xchain = $xchain - ($pdist * ($count -1) / 2); $xchain = $xchain - ($pdist * ($count -1) / 2);
} }
else { else {
$xchain = $xchain - ($pdist / 2 * ($count - 1)); $xchain = $xchain - ($pdist / 2 * ($count - 1));
}
my $producer_style;
for my $lfn (@sorted) {
my $pn = $pdcr->{$lfn}{pn};
my $p = $pdcr->{$lfn}{p};
$producer_style = $p > 0 ? "$stna active_normal" : "$stna inactive";
my $chain_color = ''; # Farbe der Laufkette des Producers
if ($p) {
#$chain_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).';"';
} }
$ret .= qq{<path id="genproducer_${pn}_$stna" class="$producer_style" $chain_color d=" M$left,130 L$xchain,$ychain" />}; my $producer_style;
$left += ($pdist * 2);
$xchain += $step; for my $lfn (@sorted) {
my $pn = $pdcr->{$lfn}{pn};
my $p = $pdcr->{$lfn}{p};
$producer_style = $p > 0 ? "$stna active_normal" : "$stna inactive";
my $chain_color = ''; # Farbe der Laufkette des Producers
if ($p) {
#$chain_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).';"';
}
$ret .= qq{<path id="genproducer_${pn}_$stna" class="$producer_style" $chain_color d=" M$left,130 L$xchain,$ychain" />};
$left += ($pdist * 2);
$xchain += $step;
}
} }
} }
@ -14662,35 +14644,38 @@ END3
$ret .= qq{<text class="$stna text" id="dummytxt_$stna" x="1085" y="710" style="text-anchor: start;">$cc_dummy</text>} if ($flowgconX && $flowgconsPower); # Current_Consumption Dummy $ret .= qq{<text class="$stna text" id="dummytxt_$stna" x="1085" y="710" style="text-anchor: start;">$cc_dummy</text>} if ($flowgconX && $flowgconsPower); # Current_Consumption Dummy
## Textangabe Producer - in Reihenfolge: zum Grid - zum Knoten - zur Batterie ## Textangabe Producer - in Reihenfolge: zum Grid - zum Knoten - zur Batterie
## Textangabe nur anzeigen wenn Producerzeile angezeigt werden soll
############################################################################### ###############################################################################
for my $st (sort keys %{$psorted}) { if ($doproducerrow) {
my $left = $psorted->{$st}{start} * 2 - 70; # Übertrag aus Producer Icon Abschnitt, -XX -> Start Lage Producer Beschriftung for my $st (sort keys %{$psorted}) {
my @sorted = @{$psorted->{$st}{sorted}}; my $left = $psorted->{$st}{start} * 2 - 70; # Übertrag aus Producer Icon Abschnitt, -XX -> Start Lage Producer Beschriftung
my @sorted = @{$psorted->{$st}{sorted}};
for my $lfn (@sorted) { for my $lfn (@sorted) {
my $pn = $pdcr->{$lfn}{pn}; my $pn = $pdcr->{$lfn}{pn};
$currentPower = $pdcr->{$lfn}{p}; $currentPower = $pdcr->{$lfn}{p};
$lcp = length $currentPower; $lcp = length $currentPower;
# Leistungszahl abhängig von der Größe entsprechend auf der x-Achse verschieben # Leistungszahl abhängig von der Größe entsprechend auf der x-Achse verschieben
############################################################################### ###############################################################################
if ($lcp >= 5) {$left -= 10} if ($lcp >= 5) {$left -= 10}
elsif ($lcp == 4) {$left += 10} elsif ($lcp == 4) {$left += 10}
elsif ($lcp == 3) {$left += 15} elsif ($lcp == 3) {$left += 15}
elsif ($lcp == 2) {$left += 20} elsif ($lcp == 2) {$left += 20}
elsif ($lcp == 1) {$left += 40} elsif ($lcp == 1) {$left += 40}
$ret .= qq{<text class="$stna text" id="producertxt_${pn}_$stna" x="$left" y="100">$currentPower</text>} if($flowgPrdsPower); $ret .= qq{<text class="$stna text" id="producertxt_${pn}_$stna" x="$left" y="100">$currentPower</text>} if($flowgPrdsPower);
# Leistungszahl wieder zurück an den Ursprungspunkt # Leistungszahl wieder zurück an den Ursprungspunkt
#################################################### ####################################################
if ($lcp >= 5) {$left += 10} if ($lcp >= 5) {$left += 10}
elsif ($lcp == 4) {$left -= 10} elsif ($lcp == 4) {$left -= 10}
elsif ($lcp == 3) {$left -= 15} elsif ($lcp == 3) {$left -= 15}
elsif ($lcp == 2) {$left -= 20} elsif ($lcp == 2) {$left -= 20}
elsif ($lcp == 1) {$left -= 40} elsif ($lcp == 1) {$left -= 40}
$left += ($pdist * 2); $left += ($pdist * 2);
}
} }
} }
@ -14779,6 +14764,97 @@ sub __sortProducer {
return (\@togrid, \@tonode, \@tobat); return (\@togrid, \@tonode, \@tobat);
} }
################################################################
# Producer Icon einfügen
################################################################
sub __addProducerIcon {
my $paref = shift;
my $hash = $paref->{hash};
my $name = $paref->{name};
my $lang = $paref->{lang};
my $stna = $paref->{stna};
my $psorted = $paref->{psorted};
my $pdcr = $paref->{pdcr};
my $pdist = $paref->{pdist};
my $y_coord = $paref->{y_coord};
my ($scale, $ret);
for my $st (sort keys %{$psorted}) {
my $left = 0;
my $xicon = $psorted->{$st}{xicon};
my $count = $psorted->{$st}{count};
my @sorted = @{$psorted->{$st}{sorted}};
if ($count % 2) {
$xicon = $xicon - ($pdist * ($count - 1) / 2);
}
else {
$xicon = $xicon - ($pdist / 2 * ($count - 1));
}
$psorted->{$st}{start} = $xicon;
$left = $xicon + 5;
for my $lfn (@sorted) {
my $pn = $pdcr->{$lfn}{pn};
my ($picon, $ptxt) = __substituteIcon ( { hash => $hash, # Icon des Producerdevices
name => $name,
pn => $pn,
ptyp => $pdcr->{$lfn}{ptyp},
don => NexthoursVal ($hash, 'NextHour00', 'DoN', 0), # Tag oder Nacht
pcurr => $pdcr->{$lfn}{p},
lang => $lang
}
);
$picon = FW_makeImage ($picon, '');
($scale, $picon) = __normIconScale ($picon, $name);
$ret .= qq{<g id="producer_${pn}_$stna" fill="grey" transform="translate($left,$y_coord),scale($scale)">};
$ret .= "<title>$ptxt</title>".$picon;
$ret .= '</g> ';
$left += $pdist;
}
}
return $ret;
}
################################################################
# Knoten Icon einfügen
################################################################
sub __addNodeIcon {
my $paref = shift;
my $hash = $paref->{hash};
my $name = $paref->{name};
my $lang = $paref->{lang};
my $stna = $paref->{stna};
my $pnodesum = $paref->{pnodesum};
my $x_coord = $paref->{x_coord};
my $y_coord = $paref->{y_coord};
my $scale;
my ($nicon, $ntxt) = __substituteIcon ( { hash => $hash,
name => $name,
ptyp => 'node',
pcurr => $pnodesum,
lang => $lang
}
);
$nicon = FW_makeImage ($nicon, '');
($scale, $nicon) = __normIconScale ($nicon, $name);
my $ret = qq{<g id="node_$stna" transform="translate($x_coord,$y_coord),scale($scale)">}; # translate(X-Koordinate,Y-Koordinate), scale(<Größe>)-> Koordinaten ändern sich bei Größenänderung
$ret .= "<title>$ntxt</title>".$nicon;
$ret .= '</g> ';
return $ret;
}
################################################################ ################################################################
# prüfe ob Icon + Farbe angegeben ist # prüfe ob Icon + Farbe angegeben ist
# und setze ggf. Ersatzwerte # und setze ggf. Ersatzwerte