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:
parent
3e419d9e14
commit
2e8d960718
@ -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};
|
||||||
@ -14278,11 +14283,14 @@ sub _flowGraphic {
|
|||||||
#####################################
|
#####################################
|
||||||
my ($togrid, $tonode, $tobat) = __sortProducer ($pdcr); # lfn Producer sortiert nach ptyp und feed
|
my ($togrid, $tonode, $tobat) = __sortProducer ($pdcr); # lfn Producer sortiert nach ptyp und feed
|
||||||
|
|
||||||
my $psorted = {
|
my $psorted = {
|
||||||
'1togrid' => { xicon => -100, xchain => 350, ychain => 420, step => 70, count => scalar @{$togrid}, sorted => $togrid }, # Producer/PV nur zu Grid
|
'1togrid' => { xicon => -100, xchain => 350, ychain => 420, step => 70, count => scalar @{$togrid}, sorted => $togrid }, # Producer/PV nur zu Grid
|
||||||
'2tonode' => { xicon => 350, xchain => 700, ychain => 200, step => $pdist, count => scalar @{$tonode}, sorted => $tonode }, # Producer/PV zum Knoten
|
'2tonode' => { xicon => 350, xchain => 700, ychain => 200, step => $pdist, count => scalar @{$tonode}, sorted => $tonode }, # Producer/PV zum Knoten
|
||||||
'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
|
||||||
#####################################
|
#####################################
|
||||||
@ -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 (!$doproducerrow) {
|
||||||
|
$paref->{y_coord} = 165;
|
||||||
|
$ret .= __addProducerIcon ($paref); # Producer Icons row einfügen
|
||||||
|
}
|
||||||
|
else { # mehr als ein Producer vorhanden
|
||||||
|
$paref->{y_coord} = 0;
|
||||||
|
$ret .= __addProducerIcon ($paref); # Producer Icons row einfügen
|
||||||
|
|
||||||
if ($count % 2) {
|
$paref->{x_coord} = 360;
|
||||||
$xicon = $xicon - ($pdist * ($count - 1) / 2);
|
$paref->{y_coord} = 165;
|
||||||
}
|
$ret .= __addNodeIcon ($paref); # Knoten Icon
|
||||||
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,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;
|
my $producer_style;
|
||||||
|
|
||||||
for my $lfn (@sorted) {
|
for my $lfn (@sorted) {
|
||||||
my $pn = $pdcr->{$lfn}{pn};
|
my $pn = $pdcr->{$lfn}{pn};
|
||||||
my $p = $pdcr->{$lfn}{p};
|
my $p = $pdcr->{$lfn}{p};
|
||||||
$producer_style = $p > 0 ? "$stna active_normal" : "$stna inactive";
|
$producer_style = $p > 0 ? "$stna active_normal" : "$stna inactive";
|
||||||
my $chain_color = ''; # Farbe der Laufkette des Producers
|
my $chain_color = ''; # Farbe der Laufkette des Producers
|
||||||
|
|
||||||
if ($p) {
|
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).';"';
|
#$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;
|
||||||
}
|
}
|
||||||
|
|
||||||
$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}) {
|
###############################################################################
|
||||||
my $left = $psorted->{$st}{start} * 2 - 70; # Übertrag aus Producer Icon Abschnitt, -XX -> Start Lage Producer Beschriftung
|
if ($doproducerrow) {
|
||||||
my @sorted = @{$psorted->{$st}{sorted}};
|
for my $st (sort keys %{$psorted}) {
|
||||||
|
my $left = $psorted->{$st}{start} * 2 - 70; # Übertrag aus Producer Icon Abschnitt, -XX -> Start Lage Producer Beschriftung
|
||||||
for my $lfn (@sorted) {
|
my @sorted = @{$psorted->{$st}{sorted}};
|
||||||
my $pn = $pdcr->{$lfn}{pn};
|
|
||||||
$currentPower = $pdcr->{$lfn}{p};
|
|
||||||
$lcp = length $currentPower;
|
|
||||||
|
|
||||||
# Leistungszahl abhängig von der Größe entsprechend auf der x-Achse verschieben
|
|
||||||
###############################################################################
|
|
||||||
if ($lcp >= 5) {$left -= 10}
|
|
||||||
elsif ($lcp == 4) {$left += 10}
|
|
||||||
elsif ($lcp == 3) {$left += 15}
|
|
||||||
elsif ($lcp == 2) {$left += 20}
|
|
||||||
elsif ($lcp == 1) {$left += 40}
|
|
||||||
|
|
||||||
$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
|
|
||||||
####################################################
|
|
||||||
if ($lcp >= 5) {$left += 10}
|
|
||||||
elsif ($lcp == 4) {$left -= 10}
|
|
||||||
elsif ($lcp == 3) {$left -= 15}
|
|
||||||
elsif ($lcp == 2) {$left -= 20}
|
|
||||||
elsif ($lcp == 1) {$left -= 40}
|
|
||||||
|
|
||||||
$left += ($pdist * 2);
|
for my $lfn (@sorted) {
|
||||||
|
my $pn = $pdcr->{$lfn}{pn};
|
||||||
|
$currentPower = $pdcr->{$lfn}{p};
|
||||||
|
$lcp = length $currentPower;
|
||||||
|
|
||||||
|
# Leistungszahl abhängig von der Größe entsprechend auf der x-Achse verschieben
|
||||||
|
###############################################################################
|
||||||
|
if ($lcp >= 5) {$left -= 10}
|
||||||
|
elsif ($lcp == 4) {$left += 10}
|
||||||
|
elsif ($lcp == 3) {$left += 15}
|
||||||
|
elsif ($lcp == 2) {$left += 20}
|
||||||
|
elsif ($lcp == 1) {$left += 40}
|
||||||
|
|
||||||
|
$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
|
||||||
|
####################################################
|
||||||
|
if ($lcp >= 5) {$left += 10}
|
||||||
|
elsif ($lcp == 4) {$left -= 10}
|
||||||
|
elsif ($lcp == 3) {$left -= 15}
|
||||||
|
elsif ($lcp == 2) {$left -= 20}
|
||||||
|
elsif ($lcp == 1) {$left -= 40}
|
||||||
|
|
||||||
|
$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
|
||||||
|
Loading…
Reference in New Issue
Block a user