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

76_SolarForecast: contrib Test

git-svn-id: https://svn.fhem.de/fhem/trunk@29578 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2025-01-26 10:54:17 +00:00
parent 82df18beac
commit 55ad97e71f

View File

@ -34,6 +34,7 @@ package FHEM::SolarForecast;
use strict; use strict;
use warnings; use warnings;
#use lib qw(/opt/fhem/FHEM /opt/fhem/lib); # für Syntaxcheck mit: perl -c /opt/fhem/FHEM/76_SolarForecast.pm
use POSIX; use POSIX;
use GPUtils qw(GP_Import GP_Export); # wird für den Import der FHEM Funktionen aus der fhem.pl benötigt use GPUtils qw(GP_Import GP_Export); # wird für den Import der FHEM Funktionen aus der fhem.pl benötigt
use Time::HiRes qw(gettimeofday tv_interval); use Time::HiRes qw(gettimeofday tv_interval);
@ -159,6 +160,7 @@ BEGIN {
# Versions History intern # Versions History intern
my %vNotesIntern = ( my %vNotesIntern = (
"1.44.4" => "26.01.2025 _getlistPVCircular: change width of output, new sub _listDataPoolPvHist ",
"1.44.3" => "25.01.2025 Notification System: minor changes, special Readings todayBatInSum todayBatOutSum ", "1.44.3" => "25.01.2025 Notification System: minor changes, special Readings todayBatInSum todayBatOutSum ",
"1.44.2" => "23.01.2025 _batChargeRecmd: user storeffdef, show historical battery SoC when displaying the battery in the bar graph ", "1.44.2" => "23.01.2025 _batChargeRecmd: user storeffdef, show historical battery SoC when displaying the battery in the bar graph ",
"1.44.1" => "20.01.2025 Notification system: minor fixes, integration of controls_solarforecast_messages_test/prod ". "1.44.1" => "20.01.2025 Notification system: minor fixes, integration of controls_solarforecast_messages_test/prod ".
@ -174,7 +176,7 @@ my %vNotesIntern = (
"trackFlex now default in DWD Model, replace title Charging recommendation by Charging release ". "trackFlex now default in DWD Model, replace title Charging recommendation by Charging release ".
"_saveEnergyConsumption: add dowrite flag, edit comref ", "_saveEnergyConsumption: add dowrite flag, edit comref ",
"1.43.1" => "11.01.2025 _batChargeRecmd: bugfix PV daily surplus update, _collectAllRegConsumers: fix interruptable hysteresis ". "1.43.1" => "11.01.2025 _batChargeRecmd: bugfix PV daily surplus update, _collectAllRegConsumers: fix interruptable hysteresis ".
"__batRcmdOnBeam: show soc forecast for hour 00 and fix english translation ". "__batteryOnBeam: show soc forecast for hour 00 and fix english translation ".
"_batChargeRecmd: consider battery capacity as part of total capacity ", "_batChargeRecmd: consider battery capacity as part of total capacity ",
"1.43.0" => "10.01.2025 graphicShowNight: add possible Time Sync of chart bar level 1 and the other ". "1.43.0" => "10.01.2025 graphicShowNight: add possible Time Sync of chart bar level 1 and the other ".
"_addDynAttr: minor fix for graphicBeamXContent, new attr ctrlNextHoursSoCForecastReadings ", "_addDynAttr: minor fix for graphicBeamXContent, new attr ctrlNextHoursSoCForecastReadings ",
@ -4743,7 +4745,7 @@ sub _getlistPVCircular {
my $hash = $defs{$name}; my $hash = $defs{$name};
my $ret = listDataPool ($hash, 'circular', $arg); my $ret = listDataPool ($hash, 'circular', $arg);
$ret .= lineFromSpaces ($ret, 20); $ret .= lineFromSpaces ($ret, -20);
return $ret; return $ret;
} }
@ -14848,7 +14850,7 @@ sub _beamGraphic {
my $ret = q{}; my $ret = q{};
$ret .= __weatherOnBeam ($paref) if($weather); $ret .= __weatherOnBeam ($paref) if($weather);
$ret .= __batRcmdOnBeam ($paref); $ret .= __batteryOnBeam ($paref);
my $m = $paref->{modulo} % 2; my $m = $paref->{modulo} % 2;
if ($show_diff eq 'top') { # Zusätzliche Zeile Ertrag - Verbrauch if ($show_diff eq 'top') { # Zusätzliche Zeile Ertrag - Verbrauch
@ -15252,7 +15254,7 @@ return $ret;
################################################################ ################################################################
# Batterieladeempfehlung in Balkengrafik # Batterieladeempfehlung in Balkengrafik
################################################################ ################################################################
sub __batRcmdOnBeam { sub __batteryOnBeam {
my $paref = shift; my $paref = shift;
my $name = $paref->{name}; my $name = $paref->{name};
my $maxhours = $paref->{maxhours}; my $maxhours = $paref->{maxhours};
@ -15327,6 +15329,7 @@ sub __batRcmdOnBeam {
$ret .= "<tr class='$htr{$m}{cl}'><td class='solarfc'></td>"; # freier Platz am Anfang $ret .= "<tr class='$htr{$m}{cl}'><td class='solarfc'></td>"; # freier Platz am Anfang
my $ii = 0; my $ii = 0;
my $m =0;
for my $i (0..($maxhours * 2) - 1) { for my $i (0..($maxhours * 2) - 1) {
my $skip = __dontNightshowSkipSync ($name, $paref, $i); my $skip = __dontNightshowSkipSync ($name, $paref, $i);
@ -15369,17 +15372,27 @@ sub __batRcmdOnBeam {
} }
); );
$title .= defined $currsoc ? "\n".$htitles{socbacur}{$lang}.": ".$currsoc." %" : ''; Log3 ($name, 4, "$name - Test title nach Subst $i: $title") if($m==0 || $m==1 || $m==2);
my $titleadd = defined $currsoc ? "\n".$htitles{socbacur}{$lang}.": ".$currsoc." %" : '';
Log3 ($name, 4, "$name - Test title Addon $i: $titleadd") if($m==0 || $m==1 || $m==2);
$title .= $titleadd;
Log3 ($name, 4, "$name - Test title Zusammengesetzt $i: $title") if($m==0 || $m==1 || $m==2);
my $image = defined $hfcg->{$i}{'rcdchargebat'.$bn} ? FW_makeImage ($bicon) : '';
$ret .= "<td title='$title' class='solarfc' width='$width' style='margin:1px; vertical-align:middle align:center; padding-bottom:1px;'>$image</td>";
Log3 ($name, 4, "$name - Test Return komplett $i: $ret\n") if($m==0 || $m==1 || $m==2);
debugLog ($paref, 'graphic', "Battery $bn pos >$i< day: $day_str, time: $time_str, Power ('-' = out): ".(defined $bpower ? $bpower : 'undef'). debugLog ($paref, 'graphic', "Battery $bn pos >$i< day: $day_str, time: $time_str, Power ('-' = out): ".(defined $bpower ? $bpower : 'undef').
" W, Rcmd: ".(defined $hfcg->{$i}{'rcdchargebat'.$bn} ? $hfcg->{$i}{'rcdchargebat'.$bn} : 'undef'). " W, Rcmd: ".(defined $hfcg->{$i}{'rcdchargebat'.$bn} ? $hfcg->{$i}{'rcdchargebat'.$bn} : 'undef').
", SoC: ".(defined $hfcg->{$i}{'soc'.$bn} ? $hfcg->{$i}{'soc'.$bn} : 'undef')." %"); ", SoC: ".(defined $hfcg->{$i}{'soc'.$bn} ? $hfcg->{$i}{'soc'.$bn} : 'undef')." %");
my $image = defined $hfcg->{$i}{'rcdchargebat'.$bn} ? FW_makeImage ($bicon) : ''; $m++;
Log3 ($name, 1, "$name - Test orig title: $title");
$ret .= "<td title='Ersatztitle' class='solarfc' width='$width' style='margin:1px; vertical-align:middle align:center; padding-bottom:1px;'>$image</td>";
} }
$ret .= "<td class='solarfc'></td></tr>" if($ret); # freier Platz am Ende der Icon Zeile $ret .= "<td class='solarfc'></td></tr>" if($ret); # freier Platz am Ende der Icon Zeile
@ -17633,272 +17646,10 @@ sub listDataPool {
my $par = shift // q{}; my $par = shift // q{};
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $type = $hash->{TYPE}; my ($sq, $h);
my ($sq, $h, $hexp);
my $export = q{};
if ($par eq 'exportToCsv') {
$export = 'csv';
$par = q{};
}
my $sub = sub {
my $day = shift;
my $ret;
for my $key (sort {$a<=>$b} keys %{$h->{$day}}) {
my $pvrl = HistoryVal ($name, $day, $key, 'pvrl', '-');
my $pvrlvd = HistoryVal ($name, $day, $key, 'pvrlvd', '-');
my $pvfc = HistoryVal ($name, $day, $key, 'pvfc', '-');
my $gcons = HistoryVal ($name, $day, $key, 'gcons', '-');
my $con = HistoryVal ($name, $day, $key, 'con', '-');
my $confc = HistoryVal ($name, $day, $key, 'confc', '-');
my $gfeedin = HistoryVal ($name, $day, $key, 'gfeedin', '-');
my $wid = HistoryVal ($name, $day, $key, 'weatherid', '-');
my $wcc = HistoryVal ($name, $day, $key, 'wcc', '-');
my $rr1c = HistoryVal ($name, $day, $key, 'rr1c', '-');
my $temp = HistoryVal ($name, $day, $key, 'temp', undef);
my $pvcorrf = HistoryVal ($name, $day, $key, 'pvcorrf', '-');
my $dayname = HistoryVal ($name, $day, $key, 'dayname', undef);
my $rad1h = HistoryVal ($name, $day, $key, 'rad1h', '-');
my $sunaz = HistoryVal ($name, $day, $key, 'sunaz', '-');
my $sunalt = HistoryVal ($name, $day, $key, 'sunalt', '-');
my $don = HistoryVal ($name, $day, $key, 'DoN', '-');
my $conprc = HistoryVal ($name, $day, $key, 'conprice', '-');
my $feedprc = HistoryVal ($name, $day, $key, 'feedprice', '-');
if ($export eq 'csv') {
$hexp->{$day}{$key}{PVreal} = $pvrl;
$hexp->{$day}{$key}{PVrealValid} = $pvrlvd;
$hexp->{$day}{$key}{PVforecast} = $pvfc;
$hexp->{$day}{$key}{GridConsumption} = $gcons;
$hexp->{$day}{$key}{Consumption} = $con;
$hexp->{$day}{$key}{confc} = $confc;
$hexp->{$day}{$key}{GridFeedIn} = $gfeedin;
$hexp->{$day}{$key}{WeatherId} = $wid;
$hexp->{$day}{$key}{CloudCover} = $wcc;
$hexp->{$day}{$key}{TotalPrecipitation} = $rr1c;
$hexp->{$day}{$key}{Temperature} = $temp // '';
$hexp->{$day}{$key}{PVCorrectionFactor} = $pvcorrf eq '-' ? '' : (split "/", $pvcorrf)[0];
$hexp->{$day}{$key}{Quality} = $pvcorrf eq '-' ? '' : (split "/", $pvcorrf)[1];
$hexp->{$day}{$key}{DayName} = $dayname // '';
$hexp->{$day}{$key}{GlobalRadiation } = $rad1h;
$hexp->{$day}{$key}{SunAzimuth} = $sunaz;
$hexp->{$day}{$key}{SunAltitude} = $sunalt;
$hexp->{$day}{$key}{DayOrNight} = $don;
$hexp->{$day}{$key}{PurchasePrice} = $conprc;
$hexp->{$day}{$key}{FeedInPrice} = $feedprc;
}
my ($inve, $invl);
for my $in (1..$maxinverter) { # + alle Inverter
$in = sprintf "%02d", $in;
my $etoti = HistoryVal ($name, $day, $key, 'etotali'.$in, '-');
my $pvrli = HistoryVal ($name, $day, $key, 'pvrl'.$in, '-');
if ($export eq 'csv') {
$hexp->{$day}{$key}{"Etotal${in}"} = $etoti;
$hexp->{$day}{$key}{"PVreal${in}"} = $pvrli;
}
$inve .= ', ' if($inve);
$inve .= "etotali${in}: $etoti";
$invl .= ', ' if($invl);
$invl .= "pvrl${in}: $pvrli";
}
my ($prde, $prdl);
for my $pn (1..$maxproducer) { # + alle Producer
$pn = sprintf "%02d", $pn;
my $etotp = HistoryVal ($name, $day, $key, 'etotalp'.$pn, '-');
my $pprl = HistoryVal ($name, $day, $key, 'pprl'.$pn, '-');
if ($export eq 'csv') {
$hexp->{$day}{$key}{"Etotal${pn}"} = $etotp;
$hexp->{$day}{$key}{"PPreal${pn}"} = $pprl;
}
$prde .= ', ' if($prde);
$prde .= "etotalp${pn}: $etotp";
$prdl .= ', ' if($prdl);
$prdl .= "pprl${pn}: $pprl";
}
my ($btotin, $batin, $btotout, $batout, $batmsoc, $batssoc, $batsoc);
for my $bn (1..$maxbatteries) { # + alle Batterien
$bn = sprintf "%02d", $bn;
my $hbtotin = HistoryVal ($name, $day, $key, 'batintotal'.$bn, '-');
my $hbtotout = HistoryVal ($name, $day, $key, 'batouttotal'.$bn, '-');
my $hbatin = HistoryVal ($name, $day, $key, 'batin'.$bn, '-');
my $hbatout = HistoryVal ($name, $day, $key, 'batout'.$bn, '-');
my $hbatmsoc = HistoryVal ($name, $day, $key, 'batmaxsoc'.$bn, '-');
my $hbatssoc = HistoryVal ($name, $day, $key, 'batsetsoc'.$bn, '-');
my $hbatsoc = HistoryVal ($name, $day, $key, 'batsoc'.$bn, '-');
if ($export eq 'csv') {
$hexp->{$day}{$key}{"BatteryInTotal${bn}"} = $hbtotin;
$hexp->{$day}{$key}{"BatteryOutTotal${bn}"} = $hbtotout;
$hexp->{$day}{$key}{"BatteryIn${bn}"} = $hbatin;
$hexp->{$day}{$key}{"BatteryOut${bn}"} = $hbatout;
$hexp->{$day}{$key}{"BatteryMaxSoc${bn}"} = $hbatmsoc;
$hexp->{$day}{$key}{"BatterySetSoc${bn}"} = $hbatssoc;
$hexp->{$day}{$key}{"BatterySoc${bn}"} = $hbatsoc;
}
$btotin .= ', ' if($btotin);
$btotin .= "batintotal${bn}: $hbtotin";
$btotout .= ', ' if($btotout);
$btotout .= "batouttotal${bn}: $hbtotout";
$batin .= ', ' if($batin);
$batin .= "batin${bn}: $hbatin";
$batout .= ', ' if($batout);
$batout .= "batout${bn}: $hbatout";
$batmsoc .= ', ' if($batmsoc);
$batmsoc .= "batmaxsoc${bn}: $hbatmsoc";
$batssoc .= ', ' if($batssoc);
$batssoc .= "batsetsoc${bn}: $hbatssoc";
$batsoc .= ', ' if($batsoc);
$batsoc .= "batsoc${bn}: $hbatsoc";
}
$ret .= "\n " if($ret);
$ret .= $key." => ";
$ret .= "pvfc: $pvfc, pvrl: $pvrl, pvrlvd: $pvrlvd, rad1h: $rad1h";
$ret .= "\n ";
$ret .= $inve if($inve && $key ne '99');
$ret .= "\n " if($inve && $key ne '99');
$ret .= $invl if($invl);
$ret .= "\n " if($invl);
$ret .= $prde if($prde && $key ne '99');
$ret .= "\n " if($prde && $key ne '99');
$ret .= $prdl if($prdl);
$ret .= "\n " if($prdl);
$ret .= "confc: $confc, con: $con, gcons: $gcons, conprice: $conprc";
$ret .= "\n ";
$ret .= "gfeedin: $gfeedin, feedprice: $feedprc";
$ret .= "\n ";
$ret .= "DoN: $don, sunaz: $sunaz, sunalt: $sunalt";
$ret .= "\n ";
$ret .= $btotin if($key ne '99');
$ret .= "\n " if($key ne '99');
$ret .= $btotout if($key ne '99');
$ret .= "\n " if($key ne '99');
$ret .= $batsoc if($key ne '99');
$ret .= "\n " if($key ne '99');
$ret .= $batin;
$ret .= "\n ";
$ret .= $batout;
$ret .= "\n ";
$ret .= $batmsoc if($key eq '99');
$ret .= "\n " if($key eq '99');
$ret .= $batssoc if($key eq '99');
$ret .= "\n " if($key eq '99');
if ($key ne '99') {
$ret .= "wid: $wid, ";
$ret .= "wcc: $wcc, ";
$ret .= "rr1c: $rr1c, ";
$ret .= "pvcorrf: $pvcorrf ";
}
$ret .= "temp: $temp, " if($temp);
$ret .= "dayname: $dayname, " if($dayname);
my $csm;
for my $c (1..$maxconsumer) { # + alle Consumer
$c = sprintf "%02d", $c;
my $nl = 0;
my $csmc = HistoryVal ($name, $day, $key, "cyclescsm${c}", undef);
my $csmt = HistoryVal ($name, $day, $key, "csmt${c}", undef);
my $csme = HistoryVal ($name, $day, $key, "csme${c}", undef);
my $csmm = HistoryVal ($name, $day, $key, "minutescsm${c}", undef);
my $csmh = HistoryVal ($name, $day, $key, "hourscsme${c}", undef);
my $csma = HistoryVal ($name, $day, $key, "avgcycmntscsm${c}", undef);
if ($export eq 'csv') {
$hexp->{$day}{$key}{"CyclesCsm${c}"} = $csmc if(defined $csmc);
$hexp->{$day}{$key}{"Csmt${c}"} = $csmt if(defined $csmt);
$hexp->{$day}{$key}{"Csme${c}"} = $csme if(defined $csme);
$hexp->{$day}{$key}{"MinutesCsm${c}"} = $csmm if(defined $csmm);
$hexp->{$day}{$key}{"HoursCsme${c}"} = $csmh if(defined $csmh);
$hexp->{$day}{$key}{"AvgCycleMinutesCsm${c}"} = $csma if(defined $csma);
}
if (defined $csmc) {
$csm .= "cyclescsm${c}: $csmc";
$nl = 1;
}
if (defined $csmt) {
$csm .= ", " if($nl);
$csm .= "csmt${c}: $csmt";
$nl = 1;
}
if (defined $csme) {
$csm .= ", " if($nl);
$csm .= "csme${c}: $csme";
$nl = 1;
}
if (defined $csmm) {
$csm .= ", " if($nl);
$csm .= "minutescsm${c}: $csmm";
$nl = 1;
}
if (defined $csmh) {
$csm .= ", " if($nl);
$csm .= "hourscsme${c}: $csmh";
$nl = 1;
}
if (defined $csma) {
$csm .= ", " if($nl);
$csm .= "avgcycmntscsm${c}: $csma";
$nl = 1;
}
$csm .= "\n " if($nl);
}
if ($csm) {
$ret .= "\n ";
$ret .= $csm;
}
else {
$ret .= "\n ";
}
}
return $ret;
};
if ($htol eq "pvhist") { if ($htol eq "pvhist") {
$h = $data{$name}{pvhist}; $sq = _listDataPoolPvHist ($hash, $par);
if (!keys %{$h}) {
return qq{PV cache is empty.};
}
for my $i (keys %{$h}) {
if (!isNumeric ($i)) {
delete $data{$name}{pvhist}{$i};
Log3 ($name, 2, qq{$name - INFO - invalid key "$i" was deleted from pvHistory storage});
}
}
for my $idx (sort keys %{$h}) {
next if($par && $idx ne $par);
$sq .= $idx." => ".$sub->($idx)."\n";
}
if ($export eq 'csv') {
return _writeAsCsv ($hash, $hexp, $pvhexprtcsv.$name.'.csv');
}
} }
if ($htol =~ /consumers|inverters|producers|strings|batteries/xs) { if ($htol =~ /consumers|inverters|producers|strings|batteries/xs) {
@ -18164,6 +17915,282 @@ sub listDataPool {
return $sq; return $sq;
} }
################################################################
# Listing des pvHistory Speichers
################################################################
sub _listDataPoolPvHist {
my $hash = shift;
my $par = shift // q{};
my $name = $hash->{NAME};
my ($sq, $h, $hexp);
my $export = q{};
if ($par eq 'exportToCsv') {
$export = 'csv';
$par = q{};
}
my $sub = sub {
my $day = shift;
my $ret;
for my $key (sort {$a<=>$b} keys %{$h->{$day}}) {
my $pvrl = HistoryVal ($name, $day, $key, 'pvrl', '-');
my $pvrlvd = HistoryVal ($name, $day, $key, 'pvrlvd', '-');
my $pvfc = HistoryVal ($name, $day, $key, 'pvfc', '-');
my $gcons = HistoryVal ($name, $day, $key, 'gcons', '-');
my $con = HistoryVal ($name, $day, $key, 'con', '-');
my $confc = HistoryVal ($name, $day, $key, 'confc', '-');
my $gfeedin = HistoryVal ($name, $day, $key, 'gfeedin', '-');
my $wid = HistoryVal ($name, $day, $key, 'weatherid', '-');
my $wcc = HistoryVal ($name, $day, $key, 'wcc', '-');
my $rr1c = HistoryVal ($name, $day, $key, 'rr1c', '-');
my $temp = HistoryVal ($name, $day, $key, 'temp', undef);
my $pvcorrf = HistoryVal ($name, $day, $key, 'pvcorrf', '-');
my $dayname = HistoryVal ($name, $day, $key, 'dayname', undef);
my $rad1h = HistoryVal ($name, $day, $key, 'rad1h', '-');
my $sunaz = HistoryVal ($name, $day, $key, 'sunaz', '-');
my $sunalt = HistoryVal ($name, $day, $key, 'sunalt', '-');
my $don = HistoryVal ($name, $day, $key, 'DoN', '-');
my $conprc = HistoryVal ($name, $day, $key, 'conprice', '-');
my $feedprc = HistoryVal ($name, $day, $key, 'feedprice', '-');
if ($export eq 'csv') {
$hexp->{$day}{$key}{PVreal} = $pvrl;
$hexp->{$day}{$key}{PVrealValid} = $pvrlvd;
$hexp->{$day}{$key}{PVforecast} = $pvfc;
$hexp->{$day}{$key}{GridConsumption} = $gcons;
$hexp->{$day}{$key}{Consumption} = $con;
$hexp->{$day}{$key}{confc} = $confc;
$hexp->{$day}{$key}{GridFeedIn} = $gfeedin;
$hexp->{$day}{$key}{WeatherId} = $wid;
$hexp->{$day}{$key}{CloudCover} = $wcc;
$hexp->{$day}{$key}{TotalPrecipitation} = $rr1c;
$hexp->{$day}{$key}{Temperature} = $temp // '';
$hexp->{$day}{$key}{PVCorrectionFactor} = $pvcorrf eq '-' ? '' : (split "/", $pvcorrf)[0];
$hexp->{$day}{$key}{Quality} = $pvcorrf eq '-' ? '' : (split "/", $pvcorrf)[1];
$hexp->{$day}{$key}{DayName} = $dayname // '';
$hexp->{$day}{$key}{GlobalRadiation } = $rad1h;
$hexp->{$day}{$key}{SunAzimuth} = $sunaz;
$hexp->{$day}{$key}{SunAltitude} = $sunalt;
$hexp->{$day}{$key}{DayOrNight} = $don;
$hexp->{$day}{$key}{PurchasePrice} = $conprc;
$hexp->{$day}{$key}{FeedInPrice} = $feedprc;
}
my ($inve, $invl);
for my $in (1..$maxinverter) { # + alle Inverter
$in = sprintf "%02d", $in;
my $etoti = HistoryVal ($name, $day, $key, 'etotali'.$in, '-');
my $pvrli = HistoryVal ($name, $day, $key, 'pvrl'.$in, '-');
if ($export eq 'csv') {
$hexp->{$day}{$key}{"Etotal${in}"} = $etoti;
$hexp->{$day}{$key}{"PVreal${in}"} = $pvrli;
}
$inve .= ', ' if($inve);
$inve .= "etotali${in}: $etoti";
$invl .= ', ' if($invl);
$invl .= "pvrl${in}: $pvrli";
}
my ($prde, $prdl);
for my $pn (1..$maxproducer) { # + alle Producer
$pn = sprintf "%02d", $pn;
my $etotp = HistoryVal ($name, $day, $key, 'etotalp'.$pn, '-');
my $pprl = HistoryVal ($name, $day, $key, 'pprl'.$pn, '-');
if ($export eq 'csv') {
$hexp->{$day}{$key}{"Etotal${pn}"} = $etotp;
$hexp->{$day}{$key}{"PPreal${pn}"} = $pprl;
}
$prde .= ', ' if($prde);
$prde .= "etotalp${pn}: $etotp";
$prdl .= ', ' if($prdl);
$prdl .= "pprl${pn}: $pprl";
}
my ($btotin, $batin, $btotout, $batout, $batmsoc, $batssoc, $batsoc);
for my $bn (1..$maxbatteries) { # + alle Batterien
$bn = sprintf "%02d", $bn;
my $hbtotin = HistoryVal ($name, $day, $key, 'batintotal'.$bn, '-');
my $hbtotout = HistoryVal ($name, $day, $key, 'batouttotal'.$bn, '-');
my $hbatin = HistoryVal ($name, $day, $key, 'batin'.$bn, '-');
my $hbatout = HistoryVal ($name, $day, $key, 'batout'.$bn, '-');
my $hbatmsoc = HistoryVal ($name, $day, $key, 'batmaxsoc'.$bn, '-');
my $hbatssoc = HistoryVal ($name, $day, $key, 'batsetsoc'.$bn, '-');
my $hbatsoc = HistoryVal ($name, $day, $key, 'batsoc'.$bn, '-');
if ($export eq 'csv') {
$hexp->{$day}{$key}{"BatteryInTotal${bn}"} = $hbtotin;
$hexp->{$day}{$key}{"BatteryOutTotal${bn}"} = $hbtotout;
$hexp->{$day}{$key}{"BatteryIn${bn}"} = $hbatin;
$hexp->{$day}{$key}{"BatteryOut${bn}"} = $hbatout;
$hexp->{$day}{$key}{"BatteryMaxSoc${bn}"} = $hbatmsoc;
$hexp->{$day}{$key}{"BatterySetSoc${bn}"} = $hbatssoc;
$hexp->{$day}{$key}{"BatterySoc${bn}"} = $hbatsoc;
}
$btotin .= ', ' if($btotin);
$btotin .= "batintotal${bn}: $hbtotin";
$btotout .= ', ' if($btotout);
$btotout .= "batouttotal${bn}: $hbtotout";
$batin .= ', ' if($batin);
$batin .= "batin${bn}: $hbatin";
$batout .= ', ' if($batout);
$batout .= "batout${bn}: $hbatout";
$batmsoc .= ', ' if($batmsoc);
$batmsoc .= "batmaxsoc${bn}: $hbatmsoc";
$batssoc .= ', ' if($batssoc);
$batssoc .= "batsetsoc${bn}: $hbatssoc";
$batsoc .= ', ' if($batsoc);
$batsoc .= "batsoc${bn}: $hbatsoc";
}
$ret .= "\n " if($ret);
$ret .= $key." => ";
$ret .= "pvfc: $pvfc, pvrl: $pvrl, pvrlvd: $pvrlvd, rad1h: $rad1h";
$ret .= "\n ";
$ret .= $inve if($inve && $key ne '99');
$ret .= "\n " if($inve && $key ne '99');
$ret .= $invl if($invl);
$ret .= "\n " if($invl);
$ret .= $prde if($prde && $key ne '99');
$ret .= "\n " if($prde && $key ne '99');
$ret .= $prdl if($prdl);
$ret .= "\n " if($prdl);
$ret .= "confc: $confc, con: $con, gcons: $gcons, conprice: $conprc";
$ret .= "\n ";
$ret .= "gfeedin: $gfeedin, feedprice: $feedprc";
$ret .= "\n ";
$ret .= "DoN: $don, sunaz: $sunaz, sunalt: $sunalt";
$ret .= "\n ";
$ret .= $btotin if($key ne '99');
$ret .= "\n " if($key ne '99');
$ret .= $btotout if($key ne '99');
$ret .= "\n " if($key ne '99');
$ret .= $batsoc if($key ne '99');
$ret .= "\n " if($key ne '99');
$ret .= $batin;
$ret .= "\n ";
$ret .= $batout;
$ret .= "\n ";
$ret .= $batmsoc if($key eq '99');
$ret .= "\n " if($key eq '99');
$ret .= $batssoc if($key eq '99');
$ret .= "\n " if($key eq '99');
if ($key ne '99') {
$ret .= "wid: $wid, ";
$ret .= "wcc: $wcc, ";
$ret .= "rr1c: $rr1c, ";
$ret .= "pvcorrf: $pvcorrf ";
}
$ret .= "temp: $temp, " if($temp);
$ret .= "dayname: $dayname, " if($dayname);
my $csm;
for my $c (1..$maxconsumer) { # + alle Consumer
$c = sprintf "%02d", $c;
my $nl = 0;
my $csmc = HistoryVal ($name, $day, $key, "cyclescsm${c}", undef);
my $csmt = HistoryVal ($name, $day, $key, "csmt${c}", undef);
my $csme = HistoryVal ($name, $day, $key, "csme${c}", undef);
my $csmm = HistoryVal ($name, $day, $key, "minutescsm${c}", undef);
my $csmh = HistoryVal ($name, $day, $key, "hourscsme${c}", undef);
my $csma = HistoryVal ($name, $day, $key, "avgcycmntscsm${c}", undef);
if ($export eq 'csv') {
$hexp->{$day}{$key}{"CyclesCsm${c}"} = $csmc if(defined $csmc);
$hexp->{$day}{$key}{"Csmt${c}"} = $csmt if(defined $csmt);
$hexp->{$day}{$key}{"Csme${c}"} = $csme if(defined $csme);
$hexp->{$day}{$key}{"MinutesCsm${c}"} = $csmm if(defined $csmm);
$hexp->{$day}{$key}{"HoursCsme${c}"} = $csmh if(defined $csmh);
$hexp->{$day}{$key}{"AvgCycleMinutesCsm${c}"} = $csma if(defined $csma);
}
if (defined $csmc) {
$csm .= "cyclescsm${c}: $csmc";
$nl = 1;
}
if (defined $csmt) {
$csm .= ", " if($nl);
$csm .= "csmt${c}: $csmt";
$nl = 1;
}
if (defined $csme) {
$csm .= ", " if($nl);
$csm .= "csme${c}: $csme";
$nl = 1;
}
if (defined $csmm) {
$csm .= ", " if($nl);
$csm .= "minutescsm${c}: $csmm";
$nl = 1;
}
if (defined $csmh) {
$csm .= ", " if($nl);
$csm .= "hourscsme${c}: $csmh";
$nl = 1;
}
if (defined $csma) {
$csm .= ", " if($nl);
$csm .= "avgcycmntscsm${c}: $csma";
$nl = 1;
}
$csm .= "\n " if($nl);
}
if ($csm) {
$ret .= "\n ";
$ret .= $csm;
}
else {
$ret .= "\n ";
}
}
return $ret;
};
$h = $data{$name}{pvhist};
if (!keys %{$h}) {
return qq{PV cache is empty.};
}
for my $i (keys %{$h}) {
if (!isNumeric ($i)) {
delete $data{$name}{pvhist}{$i};
Log3 ($name, 2, qq{$name - INFO - invalid key "$i" was deleted from pvHistory storage});
}
}
for my $idx (sort keys %{$h}) {
next if($par && $idx ne $par);
$sq .= $idx." => ".$sub->($idx)."\n";
}
if ($export eq 'csv') {
return _writeAsCsv ($hash, $hexp, $pvhexprtcsv.$name.'.csv');
}
return $sq;
}
################################################################ ################################################################
# Listing des Circular Speichers # Listing des Circular Speichers
################################################################ ################################################################
@ -18180,35 +18207,6 @@ sub _listDataPoolCircular {
my $sq; my $sq;
### nicht mehr benötigte Daten verarbeiten - Bereich kann später wieder raus !!
##########################################################################################################################
delete $data{$name}{circular}{'01'}{pvrl_5};
delete $data{$name}{circular}{'01'}{pvrl_10};
delete $data{$name}{circular}{'01'}{pvrl_25};
delete $data{$name}{circular}{'01'}{pvrl_60};
delete $data{$name}{circular}{'01'}{pvrl_65};
delete $data{$name}{circular}{'01'}{pvrl_90};
#push @{$data{$name}{circular}{'01'}{pvrl_65}{100}}, 4561;
#push @{$data{$name}{circular}{'01'}{pvrl_65}{100}}, 4562;
#push @{$data{$name}{circular}{'01'}{pvrl_65}{100}}, 4563;
#push @{$data{$name}{circular}{'01'}{pvrl_65}{100}}, 4564;
#push @{$data{$name}{circular}{'01'}{pvrl_65}{100}}, 4565;
#
#push @{$data{$name}{circular}{'01'}{pvrl_65}{60}}, 3561;
#push @{$data{$name}{circular}{'01'}{pvrl_65}{60}}, 3562;
#
#push @{$data{$name}{circular}{'01'}{pvrl_90}{100}}, 4561;
#push @{$data{$name}{circular}{'01'}{pvrl_90}{100}}, 4562;
#push @{$data{$name}{circular}{'01'}{pvrl_90}{100}}, 4563;
#push @{$data{$name}{circular}{'01'}{pvrl_90}{100}}, 4564;
#push @{$data{$name}{circular}{'01'}{pvrl_90}{100}}, 4565;
#push @{$data{$name}{circular}{'01'}{pvrl_90}{60}}, 3561;
#push @{$data{$name}{circular}{'01'}{pvrl_90}{60}}, 3562;
############################################################################################################
for my $idx (sort keys %{$h}) { for my $idx (sort keys %{$h}) {
next if($par && $idx ne $par); next if($par && $idx ne $par);