mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-02-25 03:44:52 +00:00
76_SolarForecast: remove graphicBeam1MaxVal,ctrlAreaFactorUsage
git-svn-id: https://svn.fhem.de/fhem/trunk@29581 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
a221850f21
commit
f93176ff22
@ -1,5 +1,6 @@
|
|||||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||||
# Do not insert empty lines here, update check depends on it
|
# Do not insert empty lines here, update check depends on it
|
||||||
|
- change: 76_SolarForecast: remove graphicBeam1MaxVal,ctrlAreaFactorUsage
|
||||||
- feature: 76_SolarForecast: new special readings todayBatInSum,todayBatOutSum
|
- feature: 76_SolarForecast: new special readings todayBatInSum,todayBatOutSum
|
||||||
- change: 73_AutoShuttersControl: Change version
|
- change: 73_AutoShuttersControl: Change version
|
||||||
- feature: 76_SolarForecast: show historical battery SoC when displaying the
|
- feature: 76_SolarForecast: show historical battery SoC when displaying the
|
||||||
|
@ -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,8 @@ 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, fix bug in hrepl Hash ".
|
||||||
|
"remove Attr graphicBeam1MaxVal,ctrlAreaFactorUsage ",
|
||||||
"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 +177,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 ",
|
||||||
@ -707,17 +710,17 @@ my %hmoon = (
|
|||||||
);
|
);
|
||||||
|
|
||||||
my %hrepl = ( # Zeichenersetzungen
|
my %hrepl = ( # Zeichenersetzungen
|
||||||
'0' => 'a',
|
'0' => 'a',
|
||||||
'1' => 'b',
|
'1' => 'b',
|
||||||
'2' => 'c',
|
'2' => 'c',
|
||||||
'3' => 'd',
|
'3' => 'd',
|
||||||
'4' => 'e',
|
'4' => 'e',
|
||||||
'5' => 'f',
|
'5' => 'f',
|
||||||
'6' => 'g',
|
'6' => 'g',
|
||||||
'7' => 'h',
|
'7' => 'h',
|
||||||
'8' => 'i',
|
'8' => 'i',
|
||||||
'9' => 'j',
|
'9' => 'j',
|
||||||
'.' => 'k',
|
'\.' => 'k',
|
||||||
);
|
);
|
||||||
|
|
||||||
my %hqtxt = ( # Hash (Setup) Texte
|
my %hqtxt = ( # Hash (Setup) Texte
|
||||||
@ -1448,12 +1451,11 @@ sub Initialize {
|
|||||||
$readingFnAttributes;
|
$readingFnAttributes;
|
||||||
|
|
||||||
## Hinweis: graphicBeamXContent wird in _addDynAttr hinzugefügt
|
## Hinweis: graphicBeamXContent wird in _addDynAttr hinzugefügt
|
||||||
|
|
||||||
|
|
||||||
### nicht mehr benötigte Daten verarbeiten - Bereich kann später wieder raus !!
|
### nicht mehr benötigte Daten verarbeiten - Bereich kann später wieder raus !!
|
||||||
##########################################################################################################################
|
##########################################################################################################################
|
||||||
my $av1 = "obsolete#-#the#attribute#will#be#deleted#soon"; # 12.01.25
|
# my $av1 = "obsolete#-#the#attribute#will#be#deleted#soon";
|
||||||
$hash->{AttrList} .= " graphicBeam1MaxVal:$av1 ctrlAreaFactorUsage:$av1 ";
|
# $hash->{AttrList} .= " graphicBeam1MaxVal:$av1 ctrlAreaFactorUsage:$av1 ";
|
||||||
##########################################################################################################################
|
##########################################################################################################################
|
||||||
|
|
||||||
$hash->{FW_hideDisplayName} = 1; # Forum 88667
|
$hash->{FW_hideDisplayName} = 1; # Forum 88667
|
||||||
@ -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, 5);
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
@ -5536,16 +5538,16 @@ sub Attr {
|
|||||||
|
|
||||||
### nicht mehr benötigte Daten verarbeiten - Bereich kann später wieder raus !!
|
### nicht mehr benötigte Daten verarbeiten - Bereich kann später wieder raus !!
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
if ($cmd eq 'set' && $aName =~ /^graphicBeam1MaxVal|ctrlAreaFactorUsage$/) { # 12.01.25
|
#if ($cmd eq 'set' && $aName =~ /^graphicBeam1MaxVal|ctrlAreaFactorUsage$/) {
|
||||||
my $msg = "The attribute $aName is obsolete and will be deleted soon. Please save your Configuration.";
|
# my $msg = "The attribute $aName is obsolete and will be deleted soon. Please save your Configuration.";
|
||||||
if (!$init_done) {
|
# if (!$init_done) {
|
||||||
Log3 ($name, 1, "$name - $msg");
|
# Log3 ($name, 1, "$name - $msg");
|
||||||
return qq{Device "$name" -> $msg};
|
# return qq{Device "$name" -> $msg};
|
||||||
}
|
# }
|
||||||
else {
|
# else {
|
||||||
return $msg;
|
# return $msg;
|
||||||
}
|
# }
|
||||||
}
|
#}
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
|
|
||||||
if ($aName eq 'disable') {
|
if ($aName eq 'disable') {
|
||||||
@ -8289,14 +8291,6 @@ sub __delObsoleteAPIData {
|
|||||||
delete $data{$name}{solcastapi}{$idx}{$scd} if($ds && $ds < $refts);
|
delete $data{$name}{solcastapi}{$idx}{$scd} if($ds && $ds < $refts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
### nicht mehr benötigte Daten verarbeiten - Bereich kann später wieder raus !!
|
|
||||||
##########################################################################################################################
|
|
||||||
# 01.12.2024
|
|
||||||
for my $idx (keys %{$data{$name}{solcastapi}{'?All'}}) { # Wetterindexe löschen (kann später raus)
|
|
||||||
delete $data{$name}{solcastapi}{'?All'}{$idx} if($idx =~ /^fc?([0-9]{1,2})_?([0-9]{1,2})$/xs);
|
|
||||||
}
|
|
||||||
#####################################################################################################################
|
|
||||||
}
|
}
|
||||||
|
|
||||||
## veraltete Strings aus Strings-Hash löschen
|
## veraltete Strings aus Strings-Hash löschen
|
||||||
@ -14848,7 +14842,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 +15246,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};
|
||||||
@ -15369,15 +15363,14 @@ sub __batRcmdOnBeam {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
$title .= defined $currsoc ? "\n".$htitles{socbacur}{$lang}.": ".$currsoc." %" : '';
|
$title .= defined $currsoc ? "\n".$htitles{socbacur}{$lang}.": ".$currsoc." %" : '';
|
||||||
|
|
||||||
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').
|
|
||||||
", SoC: ".(defined $hfcg->{$i}{'soc'.$bn} ? $hfcg->{$i}{'soc'.$bn} : 'undef')." %");
|
|
||||||
|
|
||||||
my $image = defined $hfcg->{$i}{'rcdchargebat'.$bn} ? FW_makeImage ($bicon) : '';
|
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>";
|
$ret .= "<td title='$title' class='solarfc' width='$width' style='margin:1px; vertical-align:middle align:center; padding-bottom:1px;'>$image</td>";
|
||||||
|
|
||||||
|
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').
|
||||||
|
", SoC: ".(defined $hfcg->{$i}{'soc'.$bn} ? $hfcg->{$i}{'soc'.$bn} : 'undef')." %");
|
||||||
}
|
}
|
||||||
|
|
||||||
$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
|
||||||
@ -17631,7 +17624,70 @@ 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);
|
||||||
|
|
||||||
|
if ($htol eq "pvhist") {
|
||||||
|
$sq = _listDataPoolPvHist ($hash, $par);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($htol =~ /consumers|inverters|producers|strings|batteries/xs) {
|
||||||
|
$sq = _listDataPoolVarious ($hash, $htol, $par);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($htol eq "circular") {
|
||||||
|
$sq = _listDataPoolCircular ($hash, $par);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($htol eq "nexthours") {
|
||||||
|
$sq = _listDataPoolNextHours ($name, $par);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($htol eq "qualities") {
|
||||||
|
$sq = _listDataPoolQualities ($name, $par);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($htol eq "current") {
|
||||||
|
$sq = _listDataPoolCurrent ($name, $par);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($htol =~ /radiationApiData|weatherApiData|statusApiData/xs) {
|
||||||
|
$sq = _listDataPoolApiData ($name, $htol, $par);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($htol eq "aiRawData") {
|
||||||
|
$h = $data{$name}{aidectree}{airaw};
|
||||||
|
my $maxcnt = keys %{$h};
|
||||||
|
if (!$maxcnt) {
|
||||||
|
return qq{aiRawData values cache is empty.};
|
||||||
|
}
|
||||||
|
|
||||||
|
$sq = "<b>Number of datasets:</b> ".$maxcnt."\n";
|
||||||
|
|
||||||
|
for my $idx (sort keys %{$h}) {
|
||||||
|
my $hod = AiRawdataVal ($name, $idx, 'hod', '-');
|
||||||
|
my $sunalt = AiRawdataVal ($name, $idx, 'sunalt', '-');
|
||||||
|
my $sunaz = AiRawdataVal ($name, $idx, 'sunaz', '-');
|
||||||
|
my $rad1h = AiRawdataVal ($name, $idx, 'rad1h', '-');
|
||||||
|
my $wcc = AiRawdataVal ($name, $idx, 'wcc', '-');
|
||||||
|
my $rr1c = AiRawdataVal ($name, $idx, 'rr1c', '-');
|
||||||
|
my $pvrl = AiRawdataVal ($name, $idx, 'pvrl', '-');
|
||||||
|
my $temp = AiRawdataVal ($name, $idx, 'temp', '-');
|
||||||
|
$sq .= "\n";
|
||||||
|
$sq .= "$idx => hod: $hod, sunaz: $sunaz, sunalt: $sunalt, rad1h: $rad1h, wcc: $wcc, rr1c: $rr1c, pvrl: $pvrl, temp: $temp";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sq;
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# Listing des pvHistory Speichers
|
||||||
|
################################################################
|
||||||
|
sub _listDataPoolPvHist {
|
||||||
|
my $hash = shift;
|
||||||
|
my $par = shift // q{};
|
||||||
|
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
my ($sq, $h, $hexp);
|
my ($sq, $h, $hexp);
|
||||||
my $export = q{};
|
my $export = q{};
|
||||||
@ -17875,288 +17931,89 @@ sub listDataPool {
|
|||||||
return $ret;
|
return $ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
if ($htol eq "pvhist") {
|
$h = $data{$name}{pvhist};
|
||||||
$h = $data{$name}{pvhist};
|
|
||||||
|
|
||||||
if (!keys %{$h}) {
|
if (!keys %{$h}) {
|
||||||
return qq{PV cache is empty.};
|
return qq{PV cache is empty.};
|
||||||
}
|
}
|
||||||
|
|
||||||
for my $i (keys %{$h}) {
|
for my $i (keys %{$h}) {
|
||||||
if (!isNumeric ($i)) {
|
if (!isNumeric ($i)) {
|
||||||
delete $data{$name}{pvhist}{$i};
|
delete $data{$name}{pvhist}{$i};
|
||||||
Log3 ($name, 2, qq{$name - INFO - invalid key "$i" was deleted from pvHistory storage});
|
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) {
|
for my $idx (sort keys %{$h}) {
|
||||||
my $sub = $htol eq 'consumers' ? \&ConsumerVal :
|
next if($par && $idx ne $par);
|
||||||
$htol eq 'inverters' ? \&InverterVal :
|
$sq .= $idx." => ".$sub->($idx)."\n";
|
||||||
$htol eq 'producers' ? \&ProducerVal :
|
}
|
||||||
$htol eq 'strings' ? \&StringVal :
|
|
||||||
$htol eq 'batteries' ? \&BatteryVal :
|
|
||||||
'';
|
|
||||||
|
|
||||||
$h = $data{$name}{$htol};
|
|
||||||
|
|
||||||
if (!keys %{$h}) {
|
|
||||||
return ucfirst($htol).qq{ cache is empty.};
|
|
||||||
}
|
|
||||||
|
|
||||||
for my $i (keys %{$h}) {
|
if ($export eq 'csv') {
|
||||||
if ($i !~ /^[0-9]{2}$/ix && $htol ne 'strings') { # bereinigen ungültige Position, Forum: https://forum.fhem.de/index.php/topic,117864.msg1173219.html#msg1173219
|
return _writeAsCsv ($hash, $hexp, $pvhexprtcsv.$name.'.csv');
|
||||||
delete $data{$name}{$htol}{$i};
|
}
|
||||||
Log3 ($name, 2, qq{$name - INFO - invalid key "$i" was deleted from }.ucfirst($htol).qq{ storage});
|
|
||||||
|
return $sq;
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# Listing des verschiedene Speicher
|
||||||
|
################################################################
|
||||||
|
sub _listDataPoolVarious {
|
||||||
|
my $hash = shift;
|
||||||
|
my $htol = shift;
|
||||||
|
my $par = shift // q{};
|
||||||
|
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
|
my $func = $htol eq 'consumers' ? \&ConsumerVal :
|
||||||
|
$htol eq 'inverters' ? \&InverterVal :
|
||||||
|
$htol eq 'producers' ? \&ProducerVal :
|
||||||
|
$htol eq 'strings' ? \&StringVal :
|
||||||
|
$htol eq 'batteries' ? \&BatteryVal :
|
||||||
|
'';
|
||||||
|
|
||||||
|
my $h = $data{$name}{$htol};
|
||||||
|
|
||||||
|
if (!keys %{$h}) {
|
||||||
|
return ucfirst($htol).qq{ cache is empty.};
|
||||||
|
}
|
||||||
|
|
||||||
|
for my $i (keys %{$h}) {
|
||||||
|
if ($i !~ /^[0-9]{2}$/ix && $htol ne 'strings') { # bereinigen ungültige Position, Forum: https://forum.fhem.de/index.php/topic,117864.msg1173219.html#msg1173219
|
||||||
|
delete $data{$name}{$htol}{$i};
|
||||||
|
Log3 ($name, 2, qq{$name - INFO - invalid key "$i" was deleted from }.ucfirst($htol).qq{ storage});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
my $sq;
|
||||||
|
|
||||||
|
for my $idx (sort keys %{$h}) {
|
||||||
|
next if($par && $idx ne $par);
|
||||||
|
my ($cret, $s1);
|
||||||
|
my $sp1 = _ldpspaces ($idx, q{});
|
||||||
|
|
||||||
|
for my $ckey (sort keys %{$h->{$idx}}) {
|
||||||
|
if (ref $h->{$idx}{$ckey} eq 'ARRAY') {
|
||||||
|
my $aser = join " ", @{$h->{$idx}{$ckey}};
|
||||||
|
$cret .= ($s1 ? $sp1 : "").$ckey." => ".$aser."\n";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for my $idx (sort keys %{$h}) {
|
|
||||||
next if($par && $idx ne $par);
|
|
||||||
my ($cret, $s1);
|
|
||||||
my $sp1 = _ldpspaces ($idx, q{});
|
|
||||||
|
|
||||||
for my $ckey (sort keys %{$h->{$idx}}) {
|
if (ref $h->{$idx}{$ckey} eq 'HASH') {
|
||||||
if (ref $h->{$idx}{$ckey} eq 'ARRAY') {
|
my $hk = qq{};
|
||||||
my $aser = join " ", @{$h->{$idx}{$ckey}};
|
for my $f (sort {$a<=>$b} keys %{$h->{$idx}{$ckey}}) {
|
||||||
$cret .= ($s1 ? $sp1 : "").$ckey." => ".$aser."\n";
|
$hk .= " " if($hk);
|
||||||
}
|
$hk .= "$f=".$h->{$idx}{$ckey}{$f};
|
||||||
|
|
||||||
if (ref $h->{$idx}{$ckey} eq 'HASH') {
|
|
||||||
my $hk = qq{};
|
|
||||||
for my $f (sort {$a<=>$b} keys %{$h->{$idx}{$ckey}}) {
|
|
||||||
$hk .= " " if($hk);
|
|
||||||
$hk .= "$f=".$h->{$idx}{$ckey}{$f};
|
|
||||||
}
|
|
||||||
$cret .= ($s1 ? $sp1 : "").$ckey." => ".$hk."\n";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$cret .= ($s1 ? $sp1 : "").$ckey." => ". &{$sub} ($hash, $idx, $ckey, "")."\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
$s1 = 1;
|
|
||||||
}
|
|
||||||
$sq .= $idx." => ".$cret."\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($htol eq "circular") {
|
|
||||||
$sq = _listDataPoolCircular ($hash, $par);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($htol eq "nexthours") {
|
|
||||||
$h = $data{$name}{nexthours};
|
|
||||||
|
|
||||||
if (!keys %{$h}) {
|
|
||||||
return qq{NextHours cache is empty.};
|
|
||||||
}
|
|
||||||
|
|
||||||
for my $idx (sort keys %{$h}) {
|
|
||||||
my $nhts = NexthoursVal ($name, $idx, 'starttime', '-');
|
|
||||||
my $hod = NexthoursVal ($name, $idx, 'hourofday', '-');
|
|
||||||
my $today = NexthoursVal ($name, $idx, 'today', '-');
|
|
||||||
my $pvfc = NexthoursVal ($name, $idx, 'pvfc', '-');
|
|
||||||
my $pvapifc = NexthoursVal ($name, $idx, 'pvapifc', '-'); # PV Forecast der API
|
|
||||||
my $pvaifc = NexthoursVal ($name, $idx, 'pvaifc', '-'); # PV Forecast der KI
|
|
||||||
my $aihit = NexthoursVal ($name, $idx, 'aihit', '-'); # KI ForeCast Treffer Status
|
|
||||||
my $wid = NexthoursVal ($name, $idx, 'weatherid', '-');
|
|
||||||
my $wcc = NexthoursVal ($name, $idx, 'wcc', '-');
|
|
||||||
my $crang = NexthoursVal ($name, $idx, 'cloudrange', '-');
|
|
||||||
my $rr1c = NexthoursVal ($name, $idx, 'rr1c', '-');
|
|
||||||
my $rrange = NexthoursVal ($name, $idx, 'rainrange', '-');
|
|
||||||
my $rad1h = NexthoursVal ($name, $idx, 'rad1h', '-');
|
|
||||||
my $pvcorrf = NexthoursVal ($name, $idx, 'pvcorrf', '-');
|
|
||||||
my $temp = NexthoursVal ($name, $idx, 'temp', '-');
|
|
||||||
my $confc = NexthoursVal ($name, $idx, 'confc', '-');
|
|
||||||
my $confcex = NexthoursVal ($name, $idx, 'confcEx', '-');
|
|
||||||
my $don = NexthoursVal ($name, $idx, 'DoN', '-');
|
|
||||||
my $sunaz = NexthoursVal ($name, $idx, 'sunaz', '-');
|
|
||||||
my $sunalt = NexthoursVal ($name, $idx, 'sunalt', '-');
|
|
||||||
|
|
||||||
my ($rcdbat, $socs);
|
|
||||||
for my $bn (1..$maxbatteries) { # alle Batterien
|
|
||||||
$bn = sprintf "%02d", $bn;
|
|
||||||
my $rcdcharge = NexthoursVal ($name, $idx, 'rcdchargebat'.$bn, '-');
|
|
||||||
my $socxx = NexthoursVal ($name, $idx, 'soc'.$bn, '-');
|
|
||||||
$rcdbat .= ', ' if($rcdbat);
|
|
||||||
$rcdbat .= "rcdchargebat${bn}: $rcdcharge";
|
|
||||||
$socs .= ', ' if($socs);
|
|
||||||
$socs .= "soc${bn}: $socxx";
|
|
||||||
}
|
|
||||||
|
|
||||||
$sq .= "\n" if($sq);
|
|
||||||
$sq .= $idx." => ";
|
|
||||||
$sq .= "starttime: $nhts, hourofday: $hod, today: $today";
|
|
||||||
$sq .= "\n ";
|
|
||||||
$sq .= "pvapifc: $pvapifc, pvaifc: $pvaifc, pvfc: $pvfc, aihit: $aihit, confc: $confc";
|
|
||||||
$sq .= "\n ";
|
|
||||||
$sq .= "confcEx: $confcex, DoN: $don, weatherid: $wid, wcc: $wcc, rr1c: $rr1c, temp=$temp";
|
|
||||||
$sq .= "\n ";
|
|
||||||
$sq .= "rad1h: $rad1h, sunaz: $sunaz, sunalt: $sunalt";
|
|
||||||
$sq .= "\n ";
|
|
||||||
$sq .= "rrange: $rrange, crange: $crang, correff: $pvcorrf";
|
|
||||||
$sq .= "\n ";
|
|
||||||
$sq .= $socs;
|
|
||||||
$sq .= "\n ";
|
|
||||||
$sq .= $rcdbat;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($htol eq "qualities") {
|
|
||||||
$h = $data{$name}{nexthours};
|
|
||||||
if (!keys %{$h}) {
|
|
||||||
return qq{NextHours cache is empty.};
|
|
||||||
}
|
|
||||||
for my $idx (sort keys %{$h}) {
|
|
||||||
my $nhfc = NexthoursVal ($hash, $idx, 'pvfc', undef);
|
|
||||||
next if(!$nhfc);
|
|
||||||
|
|
||||||
my $nhts = NexthoursVal ($hash, $idx, 'starttime', '-');
|
|
||||||
my $pvcorrf = NexthoursVal ($hash, $idx, 'pvcorrf', '-/-');
|
|
||||||
my $aihit = NexthoursVal ($hash, $idx, 'aihit', '-');
|
|
||||||
my $pvfc = NexthoursVal ($hash, $idx, 'pvfc', '-');
|
|
||||||
my $wcc = NexthoursVal ($hash, $idx, 'wcc', '-');
|
|
||||||
my $sunalt = NexthoursVal ($hash, $idx, 'sunalt', '-');
|
|
||||||
|
|
||||||
my ($f,$q) = split "/", $pvcorrf;
|
|
||||||
$sq .= "\n" if($sq);
|
|
||||||
$sq .= "Start: $nhts, Quality: $q, Factor: $f, AI usage: $aihit, PV expect: $pvfc Wh, Sun Alt: $sunalt, Cloud: $wcc";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($htol eq "current") {
|
|
||||||
$h = $data{$name}{current};
|
|
||||||
|
|
||||||
if (!keys %{$h}) {
|
|
||||||
return qq{Current values cache is empty.};
|
|
||||||
}
|
|
||||||
|
|
||||||
for my $idx (sort keys %{$h}) {
|
|
||||||
if (ref $h->{$idx} eq 'ARRAY') {
|
|
||||||
my $aser = join " ",@{$h->{$idx}};
|
|
||||||
$sq .= $idx." => ".$aser."\n";
|
|
||||||
}
|
|
||||||
elsif (ref $h->{$idx} eq 'HASH') {
|
|
||||||
my $s1;
|
|
||||||
my $sp1 = _ldpspaces ($idx, q{});
|
|
||||||
$sq .= $idx." => ";
|
|
||||||
|
|
||||||
for my $idx1 (sort keys %{$h->{$idx}}) {
|
|
||||||
if (ref $h->{$idx}{$idx1} eq 'HASH') {
|
|
||||||
my $s2;
|
|
||||||
my $sp2 = _ldpspaces ($idx1, $sp1);
|
|
||||||
$sq .= ($s1 ? $sp1 : "").$idx1." => ";
|
|
||||||
|
|
||||||
for my $idx2 (sort keys %{$h->{$idx}{$idx1}}) {
|
|
||||||
my $s3;
|
|
||||||
my $sp3 = _ldpspaces ($idx2, $sp2);
|
|
||||||
$sq .= ($s2 ? $sp2 : "").$idx2." => ";
|
|
||||||
|
|
||||||
if (ref $h->{$idx}{$idx1}{$idx2} eq 'HASH') {
|
|
||||||
for my $idx3 (sort keys %{$h->{$idx}{$idx1}{$idx2}}) {
|
|
||||||
$sq .= ($s3 ? $sp3 : "").$idx3." => ".(defined $h->{$idx}{$idx1}{$idx2}{$idx3} ? $h->{$idx}{$idx1}{$idx2}{$idx3} : '')."\n";
|
|
||||||
$s3 = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$sq .= (defined $h->{$idx}{$idx1}{$idx2} ? $h->{$idx}{$idx1}{$idx2} : '')."\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
$s1 = 1;
|
|
||||||
$s2 = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$sq .= (defined $h->{$idx}{$idx1} ? $h->{$idx}{$idx1} : '')."\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
$cret .= ($s1 ? $sp1 : "").$ckey." => ".$hk."\n";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$sq .= $idx." => ".(defined $h->{$idx} ? $h->{$idx} : '')."\n";
|
$cret .= ($s1 ? $sp1 : "").$ckey." => ". &{$func} ($hash, $idx, $ckey, "")."\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$s1 = 1;
|
||||||
}
|
}
|
||||||
}
|
$sq .= $idx." => ".$cret."\n";
|
||||||
|
|
||||||
my $git = sub {
|
|
||||||
my $it = shift;
|
|
||||||
my @sorted = sort { $a cmp $b } keys %$it;
|
|
||||||
my $key = shift @sorted;
|
|
||||||
|
|
||||||
my $ret = {};
|
|
||||||
$ret = { $key => $it->{$key} } if($key);
|
|
||||||
|
|
||||||
return $ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
if ($htol =~ /radiationApiData|weatherApiData|statusApiData/xs) {
|
|
||||||
$h = $data{$name}{solcastapi};
|
|
||||||
$h = $data{$name}{weatherapi} if($htol eq 'weatherApiData');
|
|
||||||
$h = $data{$name}{statusapi} if($htol eq 'statusApiData');
|
|
||||||
|
|
||||||
if (!keys %{$h}) {
|
|
||||||
return qq{The API values cache is empty.};
|
|
||||||
}
|
|
||||||
|
|
||||||
my $pve = q{};
|
|
||||||
my $itref = dclone $h; # Deep Copy von $h
|
|
||||||
|
|
||||||
for my $idx (sort keys %{$itref}) {
|
|
||||||
my $s1;
|
|
||||||
my $sp1 = _ldpspaces ($idx, q{});
|
|
||||||
$sq .= $idx." => ";
|
|
||||||
|
|
||||||
while (my ($tag, $item) = each %{$git->($itref->{$idx})}) {
|
|
||||||
$sq .= ($s1 ? $sp1 : "").$tag." => ";
|
|
||||||
|
|
||||||
if (ref $item eq 'HASH') {
|
|
||||||
my $s2;
|
|
||||||
my $sp2 = _ldpspaces ($tag, $sp1);
|
|
||||||
|
|
||||||
while (my ($tag1, $item1) = each %{$git->($itref->{$idx}{$tag})}) {
|
|
||||||
$sq .= ($s2 ? $sp2 : "")."$tag1: ".$item1."\n";
|
|
||||||
$s2 = 1;
|
|
||||||
delete $itref->{$idx}{$tag}{$tag1};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$s1 = 1;
|
|
||||||
$sq .= "\n" if($sq !~ /\n$/xs);
|
|
||||||
|
|
||||||
delete $itref->{$idx}{$tag};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($htol eq "aiRawData") {
|
|
||||||
$h = $data{$name}{aidectree}{airaw};
|
|
||||||
my $maxcnt = keys %{$h};
|
|
||||||
if (!$maxcnt) {
|
|
||||||
return qq{aiRawData values cache is empty.};
|
|
||||||
}
|
|
||||||
|
|
||||||
$sq = "<b>Number of datasets:</b> ".$maxcnt."\n";
|
|
||||||
|
|
||||||
for my $idx (sort keys %{$h}) {
|
|
||||||
my $hod = AiRawdataVal ($hash, $idx, 'hod', '-');
|
|
||||||
my $sunalt = AiRawdataVal ($hash, $idx, 'sunalt', '-');
|
|
||||||
my $sunaz = AiRawdataVal ($hash, $idx, 'sunaz', '-');
|
|
||||||
my $rad1h = AiRawdataVal ($hash, $idx, 'rad1h', '-');
|
|
||||||
my $wcc = AiRawdataVal ($hash, $idx, 'wcc', '-');
|
|
||||||
my $rr1c = AiRawdataVal ($hash, $idx, 'rr1c', '-');
|
|
||||||
my $pvrl = AiRawdataVal ($hash, $idx, 'pvrl', '-');
|
|
||||||
my $temp = AiRawdataVal ($hash, $idx, 'temp', '-');
|
|
||||||
$sq .= "\n";
|
|
||||||
$sq .= "$idx => hod: $hod, sunaz: $sunaz, sunalt: $sunalt, rad1h: $rad1h, wcc: $wcc, rr1c: $rr1c, pvrl: $pvrl, temp: $temp";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sq;
|
return $sq;
|
||||||
@ -18178,35 +18035,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);
|
||||||
|
|
||||||
@ -18348,6 +18176,228 @@ sub _listDataPoolCircular {
|
|||||||
return $sq;
|
return $sq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# Listing des NextHours Speicher
|
||||||
|
################################################################
|
||||||
|
sub _listDataPoolNextHours {
|
||||||
|
my $name = shift;
|
||||||
|
my $par = shift // q{};
|
||||||
|
|
||||||
|
my $h = $data{$name}{nexthours};
|
||||||
|
my $sq;
|
||||||
|
|
||||||
|
if (!keys %{$h}) {
|
||||||
|
return qq{NextHours cache is empty.};
|
||||||
|
}
|
||||||
|
|
||||||
|
for my $idx (sort keys %{$h}) {
|
||||||
|
my $nhts = NexthoursVal ($name, $idx, 'starttime', '-');
|
||||||
|
my $hod = NexthoursVal ($name, $idx, 'hourofday', '-');
|
||||||
|
my $today = NexthoursVal ($name, $idx, 'today', '-');
|
||||||
|
my $pvfc = NexthoursVal ($name, $idx, 'pvfc', '-');
|
||||||
|
my $pvapifc = NexthoursVal ($name, $idx, 'pvapifc', '-'); # PV Forecast der API
|
||||||
|
my $pvaifc = NexthoursVal ($name, $idx, 'pvaifc', '-'); # PV Forecast der KI
|
||||||
|
my $aihit = NexthoursVal ($name, $idx, 'aihit', '-'); # KI ForeCast Treffer Status
|
||||||
|
my $wid = NexthoursVal ($name, $idx, 'weatherid', '-');
|
||||||
|
my $wcc = NexthoursVal ($name, $idx, 'wcc', '-');
|
||||||
|
my $crang = NexthoursVal ($name, $idx, 'cloudrange', '-');
|
||||||
|
my $rr1c = NexthoursVal ($name, $idx, 'rr1c', '-');
|
||||||
|
my $rrange = NexthoursVal ($name, $idx, 'rainrange', '-');
|
||||||
|
my $rad1h = NexthoursVal ($name, $idx, 'rad1h', '-');
|
||||||
|
my $pvcorrf = NexthoursVal ($name, $idx, 'pvcorrf', '-');
|
||||||
|
my $temp = NexthoursVal ($name, $idx, 'temp', '-');
|
||||||
|
my $confc = NexthoursVal ($name, $idx, 'confc', '-');
|
||||||
|
my $confcex = NexthoursVal ($name, $idx, 'confcEx', '-');
|
||||||
|
my $don = NexthoursVal ($name, $idx, 'DoN', '-');
|
||||||
|
my $sunaz = NexthoursVal ($name, $idx, 'sunaz', '-');
|
||||||
|
my $sunalt = NexthoursVal ($name, $idx, 'sunalt', '-');
|
||||||
|
|
||||||
|
my ($rcdbat, $socs);
|
||||||
|
for my $bn (1..$maxbatteries) { # alle Batterien
|
||||||
|
$bn = sprintf "%02d", $bn;
|
||||||
|
my $rcdcharge = NexthoursVal ($name, $idx, 'rcdchargebat'.$bn, '-');
|
||||||
|
my $socxx = NexthoursVal ($name, $idx, 'soc'.$bn, '-');
|
||||||
|
$rcdbat .= ', ' if($rcdbat);
|
||||||
|
$rcdbat .= "rcdchargebat${bn}: $rcdcharge";
|
||||||
|
$socs .= ', ' if($socs);
|
||||||
|
$socs .= "soc${bn}: $socxx";
|
||||||
|
}
|
||||||
|
|
||||||
|
$sq .= "\n" if($sq);
|
||||||
|
$sq .= $idx." => ";
|
||||||
|
$sq .= "starttime: $nhts, hourofday: $hod, today: $today";
|
||||||
|
$sq .= "\n ";
|
||||||
|
$sq .= "pvapifc: $pvapifc, pvaifc: $pvaifc, pvfc: $pvfc, aihit: $aihit, confc: $confc";
|
||||||
|
$sq .= "\n ";
|
||||||
|
$sq .= "confcEx: $confcex, DoN: $don, weatherid: $wid, wcc: $wcc, rr1c: $rr1c, temp=$temp";
|
||||||
|
$sq .= "\n ";
|
||||||
|
$sq .= "rad1h: $rad1h, sunaz: $sunaz, sunalt: $sunalt";
|
||||||
|
$sq .= "\n ";
|
||||||
|
$sq .= "rrange: $rrange, crange: $crang, correff: $pvcorrf";
|
||||||
|
$sq .= "\n ";
|
||||||
|
$sq .= $socs;
|
||||||
|
$sq .= "\n ";
|
||||||
|
$sq .= $rcdbat;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sq;
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# Listing des Qualities Speicher
|
||||||
|
################################################################
|
||||||
|
sub _listDataPoolQualities {
|
||||||
|
my $name = shift;
|
||||||
|
my $par = shift // q{};
|
||||||
|
|
||||||
|
my $h = $data{$name}{nexthours};
|
||||||
|
my $sq;
|
||||||
|
|
||||||
|
if (!keys %{$h}) {
|
||||||
|
return qq{NextHours cache is empty.};
|
||||||
|
}
|
||||||
|
|
||||||
|
for my $idx (sort keys %{$h}) {
|
||||||
|
my $nhfc = NexthoursVal ($name, $idx, 'pvfc', undef);
|
||||||
|
next if(!$nhfc);
|
||||||
|
|
||||||
|
my $nhts = NexthoursVal ($name, $idx, 'starttime', '-');
|
||||||
|
my $pvcorrf = NexthoursVal ($name, $idx, 'pvcorrf', '-/-');
|
||||||
|
my $aihit = NexthoursVal ($name, $idx, 'aihit', '-');
|
||||||
|
my $pvfc = NexthoursVal ($name, $idx, 'pvfc', '-');
|
||||||
|
my $wcc = NexthoursVal ($name, $idx, 'wcc', '-');
|
||||||
|
my $sunalt = NexthoursVal ($name, $idx, 'sunalt', '-');
|
||||||
|
|
||||||
|
my ($f,$q) = split "/", $pvcorrf;
|
||||||
|
$sq .= "\n" if($sq);
|
||||||
|
$sq .= "Start: $nhts, Quality: $q, Factor: $f, AI usage: $aihit, PV expect: $pvfc Wh, Sun Alt: $sunalt, Cloud: $wcc";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sq;
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# Listing des Current Speicher
|
||||||
|
################################################################
|
||||||
|
sub _listDataPoolCurrent {
|
||||||
|
my $name = shift;
|
||||||
|
my $par = shift // q{};
|
||||||
|
|
||||||
|
my $h = $data{$name}{current};
|
||||||
|
my $sq;
|
||||||
|
|
||||||
|
if (!keys %{$h}) {
|
||||||
|
return qq{Current values cache is empty.};
|
||||||
|
}
|
||||||
|
|
||||||
|
for my $idx (sort keys %{$h}) {
|
||||||
|
if (ref $h->{$idx} eq 'ARRAY') {
|
||||||
|
my $aser = join " ",@{$h->{$idx}};
|
||||||
|
$sq .= $idx." => ".$aser."\n";
|
||||||
|
}
|
||||||
|
elsif (ref $h->{$idx} eq 'HASH') {
|
||||||
|
my $s1;
|
||||||
|
my $sp1 = _ldpspaces ($idx, q{});
|
||||||
|
$sq .= $idx." => ";
|
||||||
|
|
||||||
|
for my $idx1 (sort keys %{$h->{$idx}}) {
|
||||||
|
if (ref $h->{$idx}{$idx1} eq 'HASH') {
|
||||||
|
my $s2;
|
||||||
|
my $sp2 = _ldpspaces ($idx1, $sp1);
|
||||||
|
$sq .= ($s1 ? $sp1 : "").$idx1." => ";
|
||||||
|
|
||||||
|
for my $idx2 (sort keys %{$h->{$idx}{$idx1}}) {
|
||||||
|
my $s3;
|
||||||
|
my $sp3 = _ldpspaces ($idx2, $sp2);
|
||||||
|
$sq .= ($s2 ? $sp2 : "").$idx2." => ";
|
||||||
|
|
||||||
|
if (ref $h->{$idx}{$idx1}{$idx2} eq 'HASH') {
|
||||||
|
for my $idx3 (sort keys %{$h->{$idx}{$idx1}{$idx2}}) {
|
||||||
|
$sq .= ($s3 ? $sp3 : "").$idx3." => ".(defined $h->{$idx}{$idx1}{$idx2}{$idx3} ? $h->{$idx}{$idx1}{$idx2}{$idx3} : '')."\n";
|
||||||
|
$s3 = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$sq .= (defined $h->{$idx}{$idx1}{$idx2} ? $h->{$idx}{$idx1}{$idx2} : '')."\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$s1 = 1;
|
||||||
|
$s2 = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$sq .= (defined $h->{$idx}{$idx1} ? $h->{$idx}{$idx1} : '')."\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$sq .= $idx." => ".(defined $h->{$idx} ? $h->{$idx} : '')."\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sq;
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# Listing der APiData Speicher
|
||||||
|
################################################################
|
||||||
|
sub _listDataPoolApiData {
|
||||||
|
my $name = shift;
|
||||||
|
my $htol = shift;
|
||||||
|
my $par = shift // q{};
|
||||||
|
|
||||||
|
my $h = $data{$name}{solcastapi};
|
||||||
|
$h = $data{$name}{weatherapi} if($htol eq 'weatherApiData');
|
||||||
|
$h = $data{$name}{statusapi} if($htol eq 'statusApiData');
|
||||||
|
|
||||||
|
if (!keys %{$h}) {
|
||||||
|
return qq{The API values cache is empty.};
|
||||||
|
}
|
||||||
|
|
||||||
|
my $git = sub {
|
||||||
|
my $it = shift;
|
||||||
|
my @sorted = sort { $a cmp $b } keys %$it;
|
||||||
|
my $key = shift @sorted;
|
||||||
|
|
||||||
|
my $ret = {};
|
||||||
|
$ret = { $key => $it->{$key} } if($key);
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
my $sq;
|
||||||
|
my $pve = q{};
|
||||||
|
my $itref = dclone $h; # Deep Copy von $h
|
||||||
|
|
||||||
|
for my $idx (sort keys %{$itref}) {
|
||||||
|
my $s1;
|
||||||
|
my $sp1 = _ldpspaces ($idx, q{});
|
||||||
|
$sq .= $idx." => ";
|
||||||
|
|
||||||
|
while (my ($tag, $item) = each %{$git->($itref->{$idx})}) {
|
||||||
|
$sq .= ($s1 ? $sp1 : "").$tag." => ";
|
||||||
|
|
||||||
|
if (ref $item eq 'HASH') {
|
||||||
|
my $s2;
|
||||||
|
my $sp2 = _ldpspaces ($tag, $sp1);
|
||||||
|
|
||||||
|
while (my ($tag1, $item1) = each %{$git->($itref->{$idx}{$tag})}) {
|
||||||
|
$sq .= ($s2 ? $sp2 : "")."$tag1: ".$item1."\n";
|
||||||
|
$s2 = 1;
|
||||||
|
delete $itref->{$idx}{$tag}{$tag1};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$s1 = 1;
|
||||||
|
$sq .= "\n" if($sq !~ /\n$/xs);
|
||||||
|
|
||||||
|
delete $itref->{$idx}{$tag};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sq;
|
||||||
|
}
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
# Hashwert aus CircularVal in formatierten String umwandeln
|
# Hashwert aus CircularVal in formatierten String umwandeln
|
||||||
################################################################
|
################################################################
|
||||||
|
Loading…
x
Reference in New Issue
Block a user