mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-10 09:16:53 +00:00
76_SolarForecast: new Attr graphicHeaderOwnspec, minor fixes
git-svn-id: https://svn.fhem.de/fhem/trunk@28033 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
a2c87a5659
commit
736864892e
@ -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.
|
||||||
|
- feature: 76_SolarForecast: new Attr graphicHeaderOwnspec, minor fixes
|
||||||
- change: 76_SMAInverter: add BAT_P_Charge/Discarge
|
- change: 76_SMAInverter: add BAT_P_Charge/Discarge
|
||||||
- change: 74_AutomowerConnect: Commandref update
|
- change: 74_AutomowerConnect: Commandref update
|
||||||
- bugfix: 76_SolarForecast: Victron API fix Forum:#1288637
|
- bugfix: 76_SolarForecast: Victron API fix Forum:#1288637
|
||||||
|
@ -144,6 +144,9 @@ BEGIN {
|
|||||||
|
|
||||||
# Versions History intern
|
# Versions History intern
|
||||||
my %vNotesIntern = (
|
my %vNotesIntern = (
|
||||||
|
"1.0.3" => "08.10.2023 change graphic header PV/CO detail, new attr graphicHeaderOwnspec, internal code changes ".
|
||||||
|
"fix isAddSwitchOffCond 0 Forum: https://forum.fhem.de/index.php?msg=1288877 ".
|
||||||
|
"change calcValueImproves and subroutines ",
|
||||||
"1.0.2" => "05.10.2023 replace calcRange by cloud2bin ",
|
"1.0.2" => "05.10.2023 replace calcRange by cloud2bin ",
|
||||||
"1.0.1" => "03.10.2023 fixes in comRef, bug fix Forum: https://forum.fhem.de/index.php?msg=1288637 ",
|
"1.0.1" => "03.10.2023 fixes in comRef, bug fix Forum: https://forum.fhem.de/index.php?msg=1288637 ",
|
||||||
"1.0.0" => "01.10.2023 preparation for check in ",
|
"1.0.0" => "01.10.2023 preparation for check in ",
|
||||||
@ -670,6 +673,10 @@ my %hqtxt = (
|
|||||||
DE => qq{ab <WT> Minuten vor dem kommenden Sonnenaufgang} },
|
DE => qq{ab <WT> Minuten vor dem kommenden Sonnenaufgang} },
|
||||||
dvtn => { EN => qq{Deviation},
|
dvtn => { EN => qq{Deviation},
|
||||||
DE => qq{Abweichung} },
|
DE => qq{Abweichung} },
|
||||||
|
pvgen => { EN => qq{Generation},
|
||||||
|
DE => qq{Erzeugung} },
|
||||||
|
conspt => { EN => qq{Consumption},
|
||||||
|
DE => qq{Verbrauch} },
|
||||||
tday => { EN => qq{today},
|
tday => { EN => qq{today},
|
||||||
DE => qq{heute} },
|
DE => qq{heute} },
|
||||||
yday => { EN => qq{yesterday},
|
yday => { EN => qq{yesterday},
|
||||||
@ -1028,7 +1035,8 @@ sub Initialize {
|
|||||||
"graphicBeam2FontColor:colorpicker,RGB ".
|
"graphicBeam2FontColor:colorpicker,RGB ".
|
||||||
"graphicBeam1MaxVal ".
|
"graphicBeam1MaxVal ".
|
||||||
"graphicEnergyUnit:Wh,kWh ".
|
"graphicEnergyUnit:Wh,kWh ".
|
||||||
"graphicHeaderDetail:all,co,pv,pvco,statusLink ".
|
"graphicHeaderOwnspec:textField-long ".
|
||||||
|
"graphicHeaderDetail:multiple-strict,all,co,pv,own,status ".
|
||||||
"graphicHeaderShow:1,0 ".
|
"graphicHeaderShow:1,0 ".
|
||||||
"graphicHistoryHour:slider,0,1,23 ".
|
"graphicHistoryHour:slider,0,1,23 ".
|
||||||
"graphicHourCount:slider,4,1,24 ".
|
"graphicHourCount:slider,4,1,24 ".
|
||||||
@ -7152,7 +7160,7 @@ sub ___switchConsumerOn {
|
|||||||
Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - current Context is switching "on" => }.
|
Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - current Context is switching "on" => }.
|
||||||
qq{swoncond: $swoncond, on-command: $oncom }
|
qq{swoncond: $swoncond, on-command: $oncom }
|
||||||
);
|
);
|
||||||
Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - isAddSwitchOnCond Info: $infon}) if($swoncond && $infon);
|
Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - isAddSwitchOnCond Info: $infon}) if($swoncond && $infon);
|
||||||
Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - isAddSwitchOffCond Info: $infoff}) if($swoffcond && $infoff);
|
Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - isAddSwitchOffCond Info: $infoff}) if($swoffcond && $infoff);
|
||||||
Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - device >$dswname< is used as switching device});
|
Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - device >$dswname< is used as switching device});
|
||||||
|
|
||||||
@ -8280,38 +8288,38 @@ sub entryGraphic {
|
|||||||
modulo => 1,
|
modulo => 1,
|
||||||
dstyle => qq{style='padding-left: 10px; padding-right: 10px; padding-top: 3px; padding-bottom: 3px; white-space:nowrap;'}, # TD-Style
|
dstyle => qq{style='padding-left: 10px; padding-right: 10px; padding-top: 3px; padding-bottom: 3px; white-space:nowrap;'}, # TD-Style
|
||||||
offset => $offset,
|
offset => $offset,
|
||||||
hourstyle => AttrVal ($name, 'graphicHourStyle', ''),
|
hourstyle => AttrVal ($name, 'graphicHourStyle', ''),
|
||||||
colorb1 => AttrVal ($name, 'graphicBeam1Color', $b1coldef),
|
colorb1 => AttrVal ($name, 'graphicBeam1Color', $b1coldef),
|
||||||
colorb2 => AttrVal ($name, 'graphicBeam2Color', $b2coldef),
|
colorb2 => AttrVal ($name, 'graphicBeam2Color', $b2coldef),
|
||||||
fcolor1 => AttrVal ($name, 'graphicBeam1FontColor', $b1fontcoldef),
|
fcolor1 => AttrVal ($name, 'graphicBeam1FontColor', $b1fontcoldef),
|
||||||
fcolor2 => AttrVal ($name, 'graphicBeam2FontColor', $b2fontcoldef),
|
fcolor2 => AttrVal ($name, 'graphicBeam2FontColor', $b2fontcoldef),
|
||||||
beam1cont => AttrVal ($name, 'graphicBeam1Content', 'pvReal'),
|
beam1cont => AttrVal ($name, 'graphicBeam1Content', 'pvReal'),
|
||||||
beam2cont => AttrVal ($name, 'graphicBeam2Content', 'pvForecast'),
|
beam2cont => AttrVal ($name, 'graphicBeam2Content', 'pvForecast'),
|
||||||
caicon => AttrVal ($name, 'consumerAdviceIcon', $caicondef), # Consumer AdviceIcon
|
caicon => AttrVal ($name, 'consumerAdviceIcon', $caicondef), # Consumer AdviceIcon
|
||||||
clegend => AttrVal ($name, 'consumerLegend', 'icon_top'), # Lage und Art Cunsumer Legende
|
clegend => AttrVal ($name, 'consumerLegend', 'icon_top'), # Lage und Art Cunsumer Legende
|
||||||
clink => AttrVal ($name, 'consumerLink' , 1), # Detail-Link zum Verbraucher
|
clink => AttrVal ($name, 'consumerLink' , 1), # Detail-Link zum Verbraucher
|
||||||
lotype => AttrVal ($name, 'graphicLayoutType', 'double'),
|
lotype => AttrVal ($name, 'graphicLayoutType', 'double'),
|
||||||
kw => AttrVal ($name, 'graphicEnergyUnit', 'Wh'),
|
kw => AttrVal ($name, 'graphicEnergyUnit', 'Wh'),
|
||||||
height => AttrNum ($name, 'graphicBeamHeight', 200),
|
height => AttrNum ($name, 'graphicBeamHeight', 200),
|
||||||
width => $width,
|
width => $width,
|
||||||
fsize => AttrNum ($name, 'graphicSpaceSize', 24),
|
fsize => AttrNum ($name, 'graphicSpaceSize', 24),
|
||||||
maxVal => AttrNum ($name, 'graphicBeam1MaxVal', 0), # dyn. Anpassung der Balkenhöhe oder statisch ?
|
maxVal => AttrNum ($name, 'graphicBeam1MaxVal', 0), # dyn. Anpassung der Balkenhöhe oder statisch ?
|
||||||
show_night => AttrNum ($name, 'graphicShowNight', 0), # alle Balken (Spalten) anzeigen ?
|
show_night => AttrNum ($name, 'graphicShowNight', 0), # alle Balken (Spalten) anzeigen ?
|
||||||
show_diff => AttrVal ($name, 'graphicShowDiff', 'no'), # zusätzliche Anzeige $di{} in allen Typen
|
show_diff => AttrVal ($name, 'graphicShowDiff', 'no'), # zusätzliche Anzeige $di{} in allen Typen
|
||||||
weather => AttrNum ($name, 'graphicShowWeather', 1),
|
weather => AttrNum ($name, 'graphicShowWeather', 1),
|
||||||
colorw => AttrVal ($name, 'graphicWeatherColor', $wthcolddef), # Wetter Icon Farbe Tag
|
colorw => AttrVal ($name, 'graphicWeatherColor', $wthcolddef), # Wetter Icon Farbe Tag
|
||||||
colorwn => AttrVal ($name, 'graphicWeatherColorNight', $wthcolndef), # Wetter Icon Farbe Nacht
|
colorwn => AttrVal ($name, 'graphicWeatherColorNight', $wthcolndef), # Wetter Icon Farbe Nacht
|
||||||
wlalias => AttrVal ($name, 'alias', $name),
|
wlalias => AttrVal ($name, 'alias', $name),
|
||||||
sheader => AttrNum ($name, 'graphicHeaderShow', 1), # Anzeigen des Grafik Headers
|
sheader => AttrNum ($name, 'graphicHeaderShow', 1), # Anzeigen des Grafik Headers
|
||||||
hdrDetail => AttrVal ($name, 'graphicHeaderDetail', 'all'), # ermöglicht den Inhalt zu begrenzen, um bspw. passgenau in ftui einzubetten
|
hdrDetail => AttrVal ($name, 'graphicHeaderDetail', 'all'), # ermöglicht den Inhalt zu begrenzen, um bspw. passgenau in ftui einzubetten
|
||||||
flowgsize => AttrVal ($name, 'flowGraphicSize', $flowGSizedef), # Größe Energieflußgrafik
|
flowgsize => AttrVal ($name, 'flowGraphicSize', $flowGSizedef), # Größe Energieflußgrafik
|
||||||
flowgani => AttrVal ($name, 'flowGraphicAnimate', 0), # Animation Energieflußgrafik
|
flowgani => AttrVal ($name, 'flowGraphicAnimate', 0), # Animation Energieflußgrafik
|
||||||
flowgcons => AttrVal ($name, 'flowGraphicShowConsumer', 1), # Verbraucher in der Energieflußgrafik anzeigen
|
flowgcons => AttrVal ($name, 'flowGraphicShowConsumer', 1), # Verbraucher in der Energieflußgrafik anzeigen
|
||||||
flowgconX => AttrVal ($name, 'flowGraphicShowConsumerDummy', 1), # Dummyverbraucher in der Energieflußgrafik anzeigen
|
flowgconX => AttrVal ($name, 'flowGraphicShowConsumerDummy', 1), # Dummyverbraucher in der Energieflußgrafik anzeigen
|
||||||
flowgconsPower => AttrVal ($name, 'flowGraphicShowConsumerPower' , 1), # Verbraucher Leistung in der Energieflußgrafik anzeigen
|
flowgconsPower => AttrVal ($name, 'flowGraphicShowConsumerPower' , 1), # Verbraucher Leistung in der Energieflußgrafik anzeigen
|
||||||
flowgconsTime => AttrVal ($name, 'flowGraphicShowConsumerRemainTime', 1), # Verbraucher Restlaufeit in der Energieflußgrafik anzeigen
|
flowgconsTime => AttrVal ($name, 'flowGraphicShowConsumerRemainTime', 1), # Verbraucher Restlaufeit in der Energieflußgrafik anzeigen
|
||||||
flowgconsDist => AttrVal ($name, 'flowGraphicConsumerDistance', $fgCDdef), # Abstand Verbrauchericons zueinander
|
flowgconsDist => AttrVal ($name, 'flowGraphicConsumerDistance', $fgCDdef), # Abstand Verbrauchericons zueinander
|
||||||
css => AttrVal ($name, 'flowGraphicCss', $cssdef), # flowGraphicCss Styles
|
css => AttrVal ($name, 'flowGraphicCss', $cssdef), # flowGraphicCss Styles
|
||||||
lang => AttrVal ($name, 'ctrlLanguage', AttrVal ('global', 'language', $deflang)),
|
lang => AttrVal ($name, 'ctrlLanguage', AttrVal ('global', 'language', $deflang)),
|
||||||
debug => getDebug ($hash), # Debug Module
|
debug => getDebug ($hash), # Debug Module
|
||||||
};
|
};
|
||||||
@ -8585,13 +8593,6 @@ sub _graphicHeader {
|
|||||||
my $pvTo = ReadingsNum ($name, "Tomorrow_PVforecast", 0);
|
my $pvTo = ReadingsNum ($name, "Tomorrow_PVforecast", 0);
|
||||||
my $pvCu = ReadingsNum ($name, "Current_PV", 0);
|
my $pvCu = ReadingsNum ($name, "Current_PV", 0);
|
||||||
|
|
||||||
my $pvcorrf00 = NexthoursVal($hash, "NextHour00", "pvcorrf", "-/-");
|
|
||||||
my ($pcf,$pcq) = split "/", $pvcorrf00;
|
|
||||||
my $pvcanz = qq{factor: $pcf / quality: $pcq};
|
|
||||||
|
|
||||||
my $pvfc00 = NexthoursVal ($hash, 'NextHour00', 'pvfc', undef);
|
|
||||||
my $acu = isAutoCorrUsed ($name);
|
|
||||||
|
|
||||||
if ($kw eq 'kWh') {
|
if ($kw eq 'kWh') {
|
||||||
$co4h = sprintf("%.1f" , $co4h/1000)." kWh";
|
$co4h = sprintf("%.1f" , $co4h/1000)." kWh";
|
||||||
$coRe = sprintf("%.1f" , $coRe/1000)." kWh";
|
$coRe = sprintf("%.1f" , $coRe/1000)." kWh";
|
||||||
@ -8628,8 +8629,8 @@ sub _graphicHeader {
|
|||||||
|
|
||||||
# Header Link + Status + Update Button
|
# Header Link + Status + Update Button
|
||||||
#########################################
|
#########################################
|
||||||
if($hdrDetail eq "all" || $hdrDetail eq "statusLink") {
|
if ($hdrDetail =~ /all|status/xs) {
|
||||||
my ($upicon,$scicon,$img);
|
my ($scicon,$img);
|
||||||
|
|
||||||
my ($year, $month, $day, $time) = $lup =~ /(\d{4})-(\d{2})-(\d{2})\s+(.*)/x;
|
my ($year, $month, $day, $time) = $lup =~ /(\d{4})-(\d{2})-(\d{2})\s+(.*)/x;
|
||||||
$lup = "$year-$month-$day $time";
|
$lup = "$year-$month-$day $time";
|
||||||
@ -8638,26 +8639,12 @@ sub _graphicHeader {
|
|||||||
$lup = "$day.$month.$year $time";
|
$lup = "$day.$month.$year $time";
|
||||||
}
|
}
|
||||||
|
|
||||||
my $cmdupdate = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction - 0 get $name data')"}; # Update Button generieren
|
|
||||||
|
|
||||||
if ($ftui eq 'ftui') {
|
|
||||||
$cmdupdate = qq{"ftui.setFhemStatus('set $name clientAction - 0 get $name data')"};
|
|
||||||
}
|
|
||||||
|
|
||||||
my $cmdplchk = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=get $name plantConfigCheck', function(data){FW_okDialog(data)})"}; # Plant Check Button generieren
|
my $cmdplchk = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=get $name plantConfigCheck', function(data){FW_okDialog(data)})"}; # Plant Check Button generieren
|
||||||
|
|
||||||
if ($ftui eq 'ftui') {
|
if ($ftui eq 'ftui') {
|
||||||
$cmdplchk = qq{"ftui.setFhemStatus('get $name plantConfigCheck')"};
|
$cmdplchk = qq{"ftui.setFhemStatus('get $name plantConfigCheck')"};
|
||||||
}
|
}
|
||||||
|
|
||||||
my $cmdfcqal = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=get $name forecastQualities imgget', function(data){FW_okDialog(data)})"};
|
|
||||||
|
|
||||||
if ($ftui eq 'ftui') {
|
|
||||||
$cmdfcqal = qq{"ftui.setFhemStatus('get $name forecastQualities imgget')"};
|
|
||||||
}
|
|
||||||
|
|
||||||
my $upstate = ReadingsVal($name, 'state', '');
|
|
||||||
|
|
||||||
## Anlagen Check-Icon
|
## Anlagen Check-Icon
|
||||||
#######################
|
#######################
|
||||||
$img = FW_makeImage('edit_settings@grey');
|
$img = FW_makeImage('edit_settings@grey');
|
||||||
@ -8666,23 +8653,7 @@ sub _graphicHeader {
|
|||||||
|
|
||||||
## Update-Icon
|
## Update-Icon
|
||||||
################
|
################
|
||||||
my $naup = ReadingsVal ($name, 'nextCycletime', '');
|
my $upicon = __createUpdateIcon ($paref);
|
||||||
if ($upstate =~ /updated|successfully|switched/ix) {
|
|
||||||
$img = FW_makeImage('10px-kreis-gruen.png', $htitles{upd}{$lang}.' '.$htitles{natc}{$lang}.' '.$naup.'');
|
|
||||||
$upicon = "<a onClick=$cmdupdate>$img</a>";
|
|
||||||
}
|
|
||||||
elsif ($upstate =~ /running/ix) {
|
|
||||||
$img = FW_makeImage('10px-kreis-gelb.png', 'running');
|
|
||||||
$upicon = "<a>$img</a>";
|
|
||||||
}
|
|
||||||
elsif ($upstate =~ /initialized/ix) {
|
|
||||||
$img = FW_makeImage('1px-spacer.png', 'initialized');
|
|
||||||
$upicon = "<a>$img</a>";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$img = FW_makeImage('10px-kreis-rot.png', $htitles{upd}{$lang}.' ('.$htitles{natc}{$lang}.' '.$naup.')');
|
|
||||||
$upicon = "<a onClick=$cmdupdate>$img</a>";
|
|
||||||
}
|
|
||||||
|
|
||||||
## Sonnenauf- und untergang
|
## Sonnenauf- und untergang
|
||||||
############################
|
############################
|
||||||
@ -8693,25 +8664,7 @@ sub _graphicHeader {
|
|||||||
|
|
||||||
## Autokorrektur-Icon
|
## Autokorrektur-Icon
|
||||||
######################
|
######################
|
||||||
my $aciimg;
|
my $acicon = __createAutokorrIcon ($paref);
|
||||||
my $acitit = q{};
|
|
||||||
|
|
||||||
if ($acu =~ /on/xs) {
|
|
||||||
$aciimg = FW_makeImage('10px-kreis-gruen.png', $htitles{on}{$lang}." ($acu)");
|
|
||||||
}
|
|
||||||
elsif ($acu =~ /standby/ixs) {
|
|
||||||
my $pcfa = ReadingsVal ($name, 'pvCorrectionFactor_Auto', 'off');
|
|
||||||
my ($rtime) = $pcfa =~ /for (.*?) hours/x;
|
|
||||||
$img = FW_makeImage('10px-kreis-gelb.png', $htitles{dela}{$lang});
|
|
||||||
$aciimg = "$img (Start in ".$rtime." h)";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$acitit = $htitles{akorron}{$lang};
|
|
||||||
$acitit =~ s/<NAME>/$name/xs;
|
|
||||||
$aciimg = '-';
|
|
||||||
}
|
|
||||||
|
|
||||||
my $acicon = qq{<a title="$acitit">$aciimg</a>};
|
|
||||||
|
|
||||||
## Solare API Sektion
|
## Solare API Sektion
|
||||||
########################
|
########################
|
||||||
@ -8830,40 +8783,11 @@ sub _graphicHeader {
|
|||||||
|
|
||||||
## Qualitäts-Icon
|
## Qualitäts-Icon
|
||||||
######################
|
######################
|
||||||
$pcq =~ s/-/-1/xs;
|
my $pcqicon = __createQuaIcon ($paref);
|
||||||
my $pcqimg = $pcq < 0.00 ? FW_makeImage ('15px-blank', $pvcanz) :
|
|
||||||
$pcq < 0.60 ? FW_makeImage ('10px-kreis-rot.png', $pvcanz) :
|
|
||||||
$pcq < 0.80 ? FW_makeImage ('10px-kreis-gelb.png', $pvcanz) :
|
|
||||||
FW_makeImage ('10px-kreis-gruen.png', $pvcanz);
|
|
||||||
|
|
||||||
my $pcqtit = q();
|
|
||||||
|
|
||||||
if(!$pvfc00 || $pcq == -1) {
|
|
||||||
$pcqimg = "-";
|
|
||||||
$pcqtit = $htitles{norate}{$lang};
|
|
||||||
}
|
|
||||||
|
|
||||||
my $pcqicon = qq{<a title="$pcqtit", onClick=$cmdfcqal>$pcqimg</a>};
|
|
||||||
|
|
||||||
## KI Status
|
## KI Status
|
||||||
##############
|
##############
|
||||||
my $aiprep = isPrepared4AI ($hash, 'full'); # isPrepared4AI full vor Abfrage 'aicanuse' ausführen !
|
my $aiicon = __createAIicon ($paref);
|
||||||
my $aicanuse = CurrentVal ($hash, 'aicanuse', '');
|
|
||||||
my $aitst = CurrentVal ($hash, 'aitrainstate', 'ok');
|
|
||||||
my $aihit = NexthoursVal ($hash, 'NextHour00', 'aihit', 0);
|
|
||||||
|
|
||||||
my $aitit = $aidtabs ? $htitles{aimstt}{$lang} :
|
|
||||||
$aicanuse ne 'ok' ? $htitles{ainuse}{$lang} :
|
|
||||||
q{};
|
|
||||||
$aitit =~ s/<NAME>/$name/xs;
|
|
||||||
|
|
||||||
my $aiimg = $aidtabs ? '--' :
|
|
||||||
$aicanuse ne 'ok' ? '-' :
|
|
||||||
$aitst ne 'ok' ? FW_makeImage ('10px-kreis-rot.png', $aitst) :
|
|
||||||
$aihit ? FW_makeImage ('10px-kreis-gruen.png', $hqtxt{aiwhit}{$lang}) :
|
|
||||||
FW_makeImage ('10px-kreis-gelb.png', $hqtxt{aiwook}{$lang});
|
|
||||||
|
|
||||||
my $aiicon = qq{<a title="$aitit">$aiimg</a>};
|
|
||||||
|
|
||||||
## Abweichung PV Prognose/Erzeugung
|
## Abweichung PV Prognose/Erzeugung
|
||||||
#####################################
|
#####################################
|
||||||
@ -8922,9 +8846,9 @@ sub _graphicHeader {
|
|||||||
|
|
||||||
# Header Information pv
|
# Header Information pv
|
||||||
########################
|
########################
|
||||||
if($hdrDetail eq "all" || $hdrDetail eq "pv" || $hdrDetail eq "pvco") {
|
if ($hdrDetail =~ /all|pv/xs) {
|
||||||
$header .= "<tr>";
|
$header .= "<tr>";
|
||||||
$header .= "<td $dstyle><b>PV =></b></td>";
|
$header .= "<td $dstyle><b>".$hqtxt{pvgen}{$lang}." </b></td>";
|
||||||
$header .= "<td $dstyle><b>$lblPvCu</b></td> <td align=right $dstyle>$pvCu</td>";
|
$header .= "<td $dstyle><b>$lblPvCu</b></td> <td align=right $dstyle>$pvCu</td>";
|
||||||
$header .= "<td $dstyle><b>$lblPv4h</b></td> <td align=right $dstyle>$pv4h</td>";
|
$header .= "<td $dstyle><b>$lblPv4h</b></td> <td align=right $dstyle>$pv4h</td>";
|
||||||
$header .= "<td $dstyle><b>$lblPvRe</b></td> <td align=right $dstyle>$pvRe</td>";
|
$header .= "<td $dstyle><b>$lblPvRe</b></td> <td align=right $dstyle>$pvRe</td>";
|
||||||
@ -8934,10 +8858,10 @@ sub _graphicHeader {
|
|||||||
|
|
||||||
|
|
||||||
# Header Information co
|
# Header Information co
|
||||||
########################
|
#########################
|
||||||
if($hdrDetail eq "all" || $hdrDetail eq "co" || $hdrDetail eq "pvco") {
|
if ($hdrDetail =~ /all|co/xs) {
|
||||||
$header .= "<tr>";
|
$header .= "<tr>";
|
||||||
$header .= "<td $dstyle><b>CO =></b></td>";
|
$header .= "<td $dstyle><b>".$hqtxt{conspt}{$lang}." </b></td>";
|
||||||
$header .= "<td $dstyle><b>$lblPvCu</b></td><td align=right $dstyle>$coCu</td>";
|
$header .= "<td $dstyle><b>$lblPvCu</b></td><td align=right $dstyle>$coCu</td>";
|
||||||
$header .= "<td $dstyle><b>$lblPv4h</b></td><td align=right $dstyle>$co4h</td>";
|
$header .= "<td $dstyle><b>$lblPv4h</b></td><td align=right $dstyle>$co4h</td>";
|
||||||
$header .= "<td $dstyle><b>$lblPvRe</b></td><td align=right $dstyle>$coRe</td>";
|
$header .= "<td $dstyle><b>$lblPvRe</b></td><td align=right $dstyle>$coRe</td>";
|
||||||
@ -8945,15 +8869,215 @@ sub _graphicHeader {
|
|||||||
$header .= "</tr>";
|
$header .= "</tr>";
|
||||||
}
|
}
|
||||||
|
|
||||||
$header .= qq{<tr>};
|
if ($hdrDetail =~ /all|pv|co/xs) {
|
||||||
$header .= qq{<td colspan="9" align="left" $dstyle><hr></td>};
|
$header .= qq{<tr>};
|
||||||
$header .= qq{</tr>};
|
$header .= qq{<td colspan="9" align="left" $dstyle><hr></td>};
|
||||||
|
$header .= qq{</tr>};
|
||||||
|
}
|
||||||
|
|
||||||
|
# Header User Spezifikation
|
||||||
|
#############################
|
||||||
|
my $ownv = __createOwnSpec ($paref);
|
||||||
|
$header .= $ownv if($ownv);
|
||||||
|
|
||||||
$header .= qq{</table>};
|
$header .= qq{</table>};
|
||||||
|
|
||||||
return $header;
|
return $header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# erstelle Update-Icon
|
||||||
|
################################################################
|
||||||
|
sub __createUpdateIcon {
|
||||||
|
my $paref = shift;
|
||||||
|
|
||||||
|
my $hash = $paref->{hash};
|
||||||
|
my $name = $paref->{name};
|
||||||
|
my $lang = $paref->{lang};
|
||||||
|
my $ftui = $paref->{ftui};
|
||||||
|
|
||||||
|
my $upstate = ReadingsVal ($name, 'state', '');
|
||||||
|
my $naup = ReadingsVal ($name, 'nextCycletime', '');
|
||||||
|
|
||||||
|
my $cmdupdate = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name clientAction - 0 get $name data')"}; # Update Button generieren
|
||||||
|
|
||||||
|
if ($ftui eq 'ftui') {
|
||||||
|
$cmdupdate = qq{"ftui.setFhemStatus('set $name clientAction - 0 get $name data')"};
|
||||||
|
}
|
||||||
|
|
||||||
|
my ($img, $upicon);
|
||||||
|
|
||||||
|
if ($upstate =~ /updated|successfully|switched/ix) {
|
||||||
|
$img = FW_makeImage('10px-kreis-gruen.png', $htitles{upd}{$lang}.' '.$htitles{natc}{$lang}.' '.$naup.'');
|
||||||
|
$upicon = "<a onClick=$cmdupdate>$img</a>";
|
||||||
|
}
|
||||||
|
elsif ($upstate =~ /running/ix) {
|
||||||
|
$img = FW_makeImage('10px-kreis-gelb.png', 'running');
|
||||||
|
$upicon = "<a>$img</a>";
|
||||||
|
}
|
||||||
|
elsif ($upstate =~ /initialized/ix) {
|
||||||
|
$img = FW_makeImage('1px-spacer.png', 'initialized');
|
||||||
|
$upicon = "<a>$img</a>";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$img = FW_makeImage('10px-kreis-rot.png', $htitles{upd}{$lang}.' ('.$htitles{natc}{$lang}.' '.$naup.')');
|
||||||
|
$upicon = "<a onClick=$cmdupdate>$img</a>";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $upicon;
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# erstelle Autokorrektur-Icon
|
||||||
|
################################################################
|
||||||
|
sub __createAutokorrIcon {
|
||||||
|
my $paref = shift;
|
||||||
|
|
||||||
|
my $hash = $paref->{hash};
|
||||||
|
my $name = $paref->{name};
|
||||||
|
my $lang = $paref->{lang};
|
||||||
|
|
||||||
|
my $aciimg;
|
||||||
|
my $acitit = q{};
|
||||||
|
my $acu = isAutoCorrUsed ($name);
|
||||||
|
|
||||||
|
if ($acu =~ /on/xs) {
|
||||||
|
$aciimg = FW_makeImage ('10px-kreis-gruen.png', $htitles{on}{$lang}." ($acu)");
|
||||||
|
}
|
||||||
|
elsif ($acu =~ /standby/ixs) {
|
||||||
|
my $pcfa = ReadingsVal ($name, 'pvCorrectionFactor_Auto', 'off');
|
||||||
|
my ($rtime) = $pcfa =~ /for (.*?) hours/x;
|
||||||
|
my $img = FW_makeImage ('10px-kreis-gelb.png', $htitles{dela}{$lang});
|
||||||
|
$aciimg = "$img (Start in ".$rtime." h)";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$acitit = $htitles{akorron}{$lang};
|
||||||
|
$acitit =~ s/<NAME>/$name/xs;
|
||||||
|
$aciimg = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
my $acicon = qq{<a title="$acitit">$aciimg</a>};
|
||||||
|
|
||||||
|
return $acicon;
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# erstelle Qualitäts-Icon
|
||||||
|
################################################################
|
||||||
|
sub __createQuaIcon {
|
||||||
|
my $paref = shift;
|
||||||
|
|
||||||
|
my $hash = $paref->{hash};
|
||||||
|
my $name = $paref->{name};
|
||||||
|
my $lang = $paref->{lang};
|
||||||
|
my $ftui = $paref->{ftui};
|
||||||
|
|
||||||
|
my $pvfc00 = NexthoursVal ($hash, 'NextHour00', 'pvfc', undef);
|
||||||
|
my $pvcorrf00 = NexthoursVal ($hash, "NextHour00", "pvcorrf", "-/-");
|
||||||
|
my ($pcf,$pcq) = split "/", $pvcorrf00;
|
||||||
|
my $pvcanz = qq{factor: $pcf / quality: $pcq};
|
||||||
|
|
||||||
|
my $cmdfcqal = qq{"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=get $name forecastQualities imgget', function(data){FW_okDialog(data)})"};
|
||||||
|
|
||||||
|
if ($ftui eq 'ftui') {
|
||||||
|
$cmdfcqal = qq{"ftui.setFhemStatus('get $name forecastQualities imgget')"};
|
||||||
|
}
|
||||||
|
|
||||||
|
$pcq =~ s/-/-1/xs;
|
||||||
|
my $pcqimg = $pcq < 0.00 ? FW_makeImage ('15px-blank', $pvcanz) :
|
||||||
|
$pcq < 0.60 ? FW_makeImage ('10px-kreis-rot.png', $pvcanz) :
|
||||||
|
$pcq < 0.80 ? FW_makeImage ('10px-kreis-gelb.png', $pvcanz) :
|
||||||
|
FW_makeImage ('10px-kreis-gruen.png', $pvcanz);
|
||||||
|
|
||||||
|
my $pcqtit = q();
|
||||||
|
|
||||||
|
if(!$pvfc00 || $pcq == -1) {
|
||||||
|
$pcqimg = "-";
|
||||||
|
$pcqtit = $htitles{norate}{$lang};
|
||||||
|
}
|
||||||
|
|
||||||
|
my $pcqicon = qq{<a title="$pcqtit", onClick=$cmdfcqal>$pcqimg</a>};
|
||||||
|
|
||||||
|
return $pcqicon;
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# erstelle KI Icon
|
||||||
|
################################################################
|
||||||
|
sub __createAIicon {
|
||||||
|
my $paref = shift;
|
||||||
|
|
||||||
|
my $hash = $paref->{hash};
|
||||||
|
my $name = $paref->{name};
|
||||||
|
my $lang = $paref->{lang};
|
||||||
|
|
||||||
|
my $aiprep = isPrepared4AI ($hash, 'full'); # isPrepared4AI full vor Abfrage 'aicanuse' ausführen !
|
||||||
|
my $aicanuse = CurrentVal ($hash, 'aicanuse', '');
|
||||||
|
my $aitst = CurrentVal ($hash, 'aitrainstate', 'ok');
|
||||||
|
my $aihit = NexthoursVal ($hash, 'NextHour00', 'aihit', 0);
|
||||||
|
|
||||||
|
my $aitit = $aidtabs ? $htitles{aimstt}{$lang} :
|
||||||
|
$aicanuse ne 'ok' ? $htitles{ainuse}{$lang} :
|
||||||
|
q{};
|
||||||
|
$aitit =~ s/<NAME>/$name/xs;
|
||||||
|
|
||||||
|
my $aiimg = $aidtabs ? '--' :
|
||||||
|
$aicanuse ne 'ok' ? '-' :
|
||||||
|
$aitst ne 'ok' ? FW_makeImage ('10px-kreis-rot.png', $aitst) :
|
||||||
|
$aihit ? FW_makeImage ('10px-kreis-gruen.png', $hqtxt{aiwhit}{$lang}) :
|
||||||
|
FW_makeImage ('10px-kreis-gelb.png', $hqtxt{aiwook}{$lang});
|
||||||
|
|
||||||
|
my $aiicon = qq{<a title="$aitit">$aiimg</a>};
|
||||||
|
|
||||||
|
return $aiicon;
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# erstelle Übersicht eigener Readings
|
||||||
|
################################################################
|
||||||
|
sub __createOwnSpec {
|
||||||
|
my $paref = shift;
|
||||||
|
|
||||||
|
my $hash = $paref->{hash};
|
||||||
|
my $name = $paref->{name};
|
||||||
|
my $dstyle = $paref->{dstyle}; # TD-Style
|
||||||
|
my $hdrDetail = $paref->{hdrDetail};
|
||||||
|
|
||||||
|
my $vinr = 4; # Spezifikationen in einer Zeile
|
||||||
|
my $spec = AttrVal ($name, 'graphicHeaderOwnspec', '');
|
||||||
|
my $show = $hdrDetail =~ /all|own/xs ? 1 : 0;
|
||||||
|
|
||||||
|
return if(!$spec || !$show);
|
||||||
|
|
||||||
|
my $ownv;
|
||||||
|
my @vals = split (/\s+/sx, $spec);
|
||||||
|
my $rows = ceil (scalar(@vals) / $vinr);
|
||||||
|
my $col = 0;
|
||||||
|
|
||||||
|
for (my $i = 1 ; $i <= $rows; $i++) {
|
||||||
|
my $h;
|
||||||
|
|
||||||
|
for (my $k = 0 ; $k < $vinr; $k++) {
|
||||||
|
($h->{$k}{label}, $h->{$k}{rdg}) = split ":", $vals[$col] if($vals[$col]);
|
||||||
|
$col++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ownv .= "<tr>";
|
||||||
|
$ownv .= "<td $dstyle></td>";
|
||||||
|
$ownv .= "<td $dstyle><b>".$h->{0}{label}.":</b></td> <td align=right $dstyle>".ReadingsVal ($name,$h->{0}{rdg},'')."</td>" if(exists $h->{0}{label});
|
||||||
|
$ownv .= "<td $dstyle><b>".$h->{1}{label}.":</b></td> <td align=right $dstyle>".ReadingsVal ($name,$h->{1}{rdg},'')."</td>" if(exists $h->{1}{label});
|
||||||
|
$ownv .= "<td $dstyle><b>".$h->{2}{label}.":</b></td> <td align=right $dstyle>".ReadingsVal ($name,$h->{2}{rdg},'')."</td>" if(exists $h->{2}{label});
|
||||||
|
$ownv .= "<td $dstyle><b>".$h->{3}{label}.":</b></td> <td align=right $dstyle>".ReadingsVal ($name,$h->{3}{rdg},'')."</td>" if(exists $h->{3}{label});
|
||||||
|
$ownv .= "</tr>";
|
||||||
|
}
|
||||||
|
|
||||||
|
$ownv .= qq{<tr>};
|
||||||
|
$ownv .= qq{<td colspan="9" align="left" $dstyle><hr></td>};
|
||||||
|
$ownv .= qq{</tr>};
|
||||||
|
|
||||||
|
return $ownv;
|
||||||
|
}
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
# Consumer in forecastGraphic (Balken) anzeigen
|
# Consumer in forecastGraphic (Balken) anzeigen
|
||||||
# (Hat zur Zeit keine Wirkung !)
|
# (Hat zur Zeit keine Wirkung !)
|
||||||
@ -9061,7 +9185,7 @@ sub _graphicConsumerLegend {
|
|||||||
$ctable .= qq{<td> </td>};
|
$ctable .= qq{<td> </td>};
|
||||||
|
|
||||||
my $cnum = @consumers;
|
my $cnum = @consumers;
|
||||||
if($cnum > 1) {
|
if ($cnum > 1) {
|
||||||
$ctable .= qq{<td style='text-align:left' $dstyle> $hqtxt{cnsm}{$lang} </td>};
|
$ctable .= qq{<td style='text-align:left' $dstyle> $hqtxt{cnsm}{$lang} </td>};
|
||||||
$ctable .= qq{<td> </td>};
|
$ctable .= qq{<td> </td>};
|
||||||
$ctable .= qq{<td> </td>};
|
$ctable .= qq{<td> </td>};
|
||||||
@ -10315,6 +10439,7 @@ sub calcValueImproves {
|
|||||||
my $paref = shift;
|
my $paref = shift;
|
||||||
my $hash = $paref->{hash};
|
my $hash = $paref->{hash};
|
||||||
my $name = $paref->{name};
|
my $name = $paref->{name};
|
||||||
|
my $chour = $paref->{chour};
|
||||||
my $t = $paref->{t}; # aktuelle Unix-Zeit
|
my $t = $paref->{t}; # aktuelle Unix-Zeit
|
||||||
|
|
||||||
my $idts = ReadingsTimestamp ($name, "currentInverterDev", ""); # Definitionstimestamp des Inverterdevice
|
my $idts = ReadingsTimestamp ($name, "currentInverterDev", ""); # Definitionstimestamp des Inverterdevice
|
||||||
@ -10347,9 +10472,16 @@ sub calcValueImproves {
|
|||||||
|
|
||||||
$paref->{acu} = $acu;
|
$paref->{acu} = $acu;
|
||||||
|
|
||||||
_calcCaQcomplex ($paref); # Korrekturberechnung mit Bewölkung duchführen/speichern
|
for my $h (1..23) {
|
||||||
_calcCaQsimple ($paref); # einfache Korrekturberechnung duchführen/speichern
|
next if(!$chour || $h > $chour);
|
||||||
_addHourAiRawdata ($paref); # AI Instanz hinzufügen
|
$paref->{h} = $h;
|
||||||
|
|
||||||
|
_calcCaQcomplex ($paref); # Korrekturberechnung mit Bewölkung duchführen/speichern
|
||||||
|
_calcCaQsimple ($paref); # einfache Korrekturberechnung duchführen/speichern
|
||||||
|
_addHourAiRawdata ($paref); # AI Instanz hinzufügen
|
||||||
|
|
||||||
|
delete $paref->{h};
|
||||||
|
}
|
||||||
|
|
||||||
delete $paref->{acu};
|
delete $paref->{acu};
|
||||||
|
|
||||||
@ -10364,78 +10496,77 @@ sub _calcCaQcomplex {
|
|||||||
my $paref = shift;
|
my $paref = shift;
|
||||||
my $hash = $paref->{hash};
|
my $hash = $paref->{hash};
|
||||||
my $name = $paref->{name};
|
my $name = $paref->{name};
|
||||||
my $chour = $paref->{chour};
|
|
||||||
my $daref = $paref->{daref};
|
my $daref = $paref->{daref};
|
||||||
my $debug = $paref->{debug};
|
my $debug = $paref->{debug};
|
||||||
my $acu = $paref->{acu};
|
my $acu = $paref->{acu};
|
||||||
|
my $h = $paref->{h};
|
||||||
|
|
||||||
my $maxvar = AttrVal ($name, 'affectMaxDayVariance', $defmaxvar); # max. Korrekturvarianz
|
my $maxvar = AttrVal ($name, 'affectMaxDayVariance', $defmaxvar); # max. Korrekturvarianz
|
||||||
|
my $sr = ReadingsVal ($name, ".pvCorrectionFactor_".sprintf("%02d",$h)."_cloudcover", "");
|
||||||
|
|
||||||
for my $h (1..23) {
|
if ($sr eq "done") {
|
||||||
next if(!$chour || $h > $chour);
|
# Log3 ($name, 1, "$name DEBUG> Complex Corrf -> factor Hour: ".sprintf("%02d",$h)." already calculated");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
my $sr = ReadingsVal ($name, ".pvCorrectionFactor_".sprintf("%02d",$h)."_cloudcover", "");
|
debugLog ($paref, 'pvCorrection', "start calculation complex correction factor for hour: $h");
|
||||||
|
|
||||||
if ($sr eq "done") {
|
my $pvre = CircularVal ($hash, sprintf("%02d",$h), 'pvrl', 0);
|
||||||
# Log3 ($name, 1, "$name DEBUG> Complex Corrf -> factor Hour: ".sprintf("%02d",$h)." already calculated");
|
my $pvfc = CircularVal ($hash, sprintf("%02d",$h), 'pvapifc', 0);
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
my $pvre = CircularVal ($hash, sprintf("%02d",$h), 'pvrl', 0);
|
if (!$pvre || !$pvfc) {
|
||||||
next if(!$pvre);
|
push @$daref, ".pvCorrectionFactor_".sprintf("%02d",$h)."_cloudcover<>done";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
my $pvfc = CircularVal ($hash, sprintf("%02d",$h), 'pvapifc', 0);
|
$paref->{hour} = $h;
|
||||||
next if(!$pvfc);
|
my ($pvhis,$fchis,$dnum,$range) = __Pv_Fc_Complex_Dnum_Hist ($paref); # historische PV / Forecast Vergleichswerte ermitteln
|
||||||
|
|
||||||
$paref->{hour} = $h;
|
my ($oldfac, $oldq) = CircularAutokorrVal ($hash, sprintf("%02d",$h), $range, 0); # bisher definierter Korrekturfaktor/KF-Qualität der Stunde des Tages der entsprechenden Bewölkungsrange
|
||||||
my ($pvhis,$fchis,$dnum,$range) = __Pv_Fc_Complex_Dnum_Hist ($paref); # historische PV / Forecast Vergleichswerte ermitteln
|
$oldfac = 1 if(1 * $oldfac == 0);
|
||||||
|
|
||||||
my ($oldfac, $oldq) = CircularAutokorrVal ($hash, sprintf("%02d",$h), $range, 0); # bisher definierter Korrekturfaktor/KF-Qualität der Stunde des Tages der entsprechenden Bewölkungsrange
|
(my $factor, $dnum) = __calcNewFactor ({ name => $name,
|
||||||
$oldfac = 1 if(1 * $oldfac == 0);
|
oldfac => $oldfac,
|
||||||
|
dnum => $dnum,
|
||||||
|
pvre => $pvre,
|
||||||
|
pvfc => $pvfc,
|
||||||
|
pvhis => $pvhis,
|
||||||
|
fchis => $fchis
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
(my $factor, $dnum) = __calcNewFactor ({ name => $name,
|
if (abs($factor - $oldfac) > $maxvar) {
|
||||||
oldfac => $oldfac,
|
$factor = sprintf "%.2f", ($factor > $oldfac ? $oldfac + $maxvar : $oldfac - $maxvar);
|
||||||
dnum => $dnum,
|
Log3 ($name, 3, "$name - new complex correction factor calculated (limited by affectMaxDayVariance): $factor (old: $oldfac) for hour: $h");
|
||||||
pvre => $pvre,
|
}
|
||||||
pvfc => $pvfc,
|
else {
|
||||||
pvhis => $pvhis,
|
Log3 ($name, 3, "$name - new complex correction factor for hour $h calculated: $factor (old: $oldfac)") if($factor != $oldfac);
|
||||||
fchis => $fchis
|
}
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (abs($factor - $oldfac) > $maxvar) {
|
$pvre = sprintf "%.0f", $pvre;
|
||||||
$factor = sprintf "%.2f", ($factor > $oldfac ? $oldfac + $maxvar : $oldfac - $maxvar);
|
$pvfc = sprintf "%.0f", $pvfc;
|
||||||
Log3 ($name, 3, "$name - new correction factor calculated (limited by affectMaxDayVariance): $factor (old: $oldfac) for hour: $h");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Log3 ($name, 3, "$name - new complex correction factor for hour $h calculated: $factor (old: $oldfac)") if($factor != $oldfac);
|
|
||||||
}
|
|
||||||
|
|
||||||
$pvre = sprintf "%.0f", $pvre;
|
debugLog ($paref, 'pvCorrection', "Complex Corrf -> determined values - hour: $h, cloudiness range: $range, average forecast: $pvfc, average real: $pvre, old corrf: $oldfac, new corrf: $factor, days: $dnum");
|
||||||
$pvfc = sprintf "%.0f", $pvfc;
|
|
||||||
|
|
||||||
debugLog ($paref, 'pvCorrection', "Complex Corrf -> determined values - hour: $h, cloudiness range: $range, average forecast: $pvfc, average real: $pvre, old corrf: $oldfac, new corrf: $factor, days: $dnum");
|
if (defined $range) {
|
||||||
|
my $type = $paref->{type};
|
||||||
|
|
||||||
if (defined $range) {
|
my $qual = __calcFcQuality ($pvfc, $pvre); # Qualität der Vorhersage für die vergangene Stunde
|
||||||
my $type = $paref->{type};
|
|
||||||
|
|
||||||
my $qual = __calcFcQuality ($pvfc, $pvre); # Qualität der Vorhersage für die vergangene Stunde
|
debugLog ($paref, 'pvCorrection|saveData2Cache', "Complex Corrf -> write range correction values into Circular: hour: $h, cloudiness range: $range, factor: $factor, quality: $qual");
|
||||||
|
|
||||||
debugLog ($paref, 'pvCorrection|saveData2Cache', "Complex Corrf -> write range correction values into Circular: hour: $h, cloudiness range: $range, factor: $factor, quality: $qual");
|
$data{$type}{$name}{circular}{sprintf("%02d",$h)}{pvcorrf}{$range} = $factor; # Korrekturfaktor für Bewölkung der jeweiligen Stunde als Datenquelle eintragen
|
||||||
|
$data{$type}{$name}{circular}{sprintf("%02d",$h)}{quality}{$range} = $qual;
|
||||||
|
|
||||||
$data{$type}{$name}{circular}{sprintf("%02d",$h)}{pvcorrf}{$range} = $factor; # Korrekturfaktor für Bewölkung der jeweiligen Stunde als Datenquelle eintragen
|
push @$daref, ".pvCorrectionFactor_".sprintf("%02d",$h)."_cloudcover<>done";
|
||||||
$data{$type}{$name}{circular}{sprintf("%02d",$h)}{quality}{$range} = $qual;
|
}
|
||||||
|
else {
|
||||||
|
$range = "";
|
||||||
|
}
|
||||||
|
|
||||||
push @$daref, ".pvCorrectionFactor_".sprintf("%02d",$h)."_cloudcover<>done";
|
if ($acu =~ /on_complex/xs) {
|
||||||
}
|
push @$daref, "pvCorrectionFactor_". sprintf("%02d",$h)."<>".$factor." (automatic - old factor: $oldfac, cloudiness range: $range, days in range: $dnum)";
|
||||||
else {
|
push @$daref, "pvCorrectionFactor_". sprintf("%02d",$h)."_autocalc<>done";
|
||||||
$range = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($acu =~ /on_complex/xs) {
|
|
||||||
push @$daref, "pvCorrectionFactor_". sprintf("%02d",$h)."<>".$factor." (automatic - old factor: $oldfac, cloudiness range: $range, days in range: $dnum)";
|
|
||||||
push @$daref, "pvCorrectionFactor_". sprintf("%02d",$h)."_autocalc<>done";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -10449,71 +10580,71 @@ sub _calcCaQsimple {
|
|||||||
my $paref = shift;
|
my $paref = shift;
|
||||||
my $hash = $paref->{hash};
|
my $hash = $paref->{hash};
|
||||||
my $name = $paref->{name};
|
my $name = $paref->{name};
|
||||||
my $chour = $paref->{chour}; # aktuelle Stunde
|
|
||||||
my $date = $paref->{date};
|
my $date = $paref->{date};
|
||||||
my $daref = $paref->{daref};
|
my $daref = $paref->{daref};
|
||||||
my $acu = $paref->{acu};
|
my $acu = $paref->{acu};
|
||||||
|
my $h = $paref->{h};
|
||||||
|
|
||||||
my $maxvar = AttrVal($name, 'affectMaxDayVariance', $defmaxvar); # max. Korrekturvarianz
|
my $maxvar = AttrVal($name, 'affectMaxDayVariance', $defmaxvar); # max. Korrekturvarianz
|
||||||
|
my $sr = ReadingsVal ($name, ".pvCorrectionFactor_".sprintf("%02d",$h)."_apipercentil", "");
|
||||||
|
|
||||||
for my $h (1..23) {
|
if($sr eq "done") {
|
||||||
next if(!$chour || $h > $chour);
|
# debugLog ($paref, 'pvCorrection', "Simple Corrf factor Hour: ".sprintf("%02d",$h)." already calculated");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
my $sr = ReadingsVal ($name, ".pvCorrectionFactor_".sprintf("%02d",$h)."_apipercentil", "");
|
debugLog ($paref, 'pvCorrection', "start calculation simple correction factor for hour: $h");
|
||||||
|
|
||||||
if($sr eq "done") {
|
my $pvre = CircularVal ($hash, sprintf("%02d",$h), 'pvrl', 0);
|
||||||
# debugLog ($paref, 'pvCorrection', "Simple Corrf factor Hour: ".sprintf("%02d",$h)." already calculated");
|
my $pvfc = CircularVal ($hash, sprintf("%02d",$h), 'pvapifc', 0);
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
my $pvre = CircularVal ($hash, sprintf("%02d",$h), 'pvrl', 0);
|
|
||||||
next if(!$pvre);
|
|
||||||
|
|
||||||
my $pvfc = CircularVal ($hash, sprintf("%02d",$h), 'pvapifc', 0);
|
|
||||||
next if(!$pvfc);
|
|
||||||
|
|
||||||
$paref->{hour} = $h;
|
|
||||||
my ($pvhis,$fchis,$dnum) = __Pv_Fc_Simple_Dnum_Hist ($paref); # historischen Percentilfaktor / Qualität ermitteln
|
|
||||||
|
|
||||||
my ($oldfac, $oldq) = CircularAutokorrVal ($hash, sprintf("%02d",$h), 'percentile', 0);
|
|
||||||
$oldfac = 1 if(1 * $oldfac == 0);
|
|
||||||
|
|
||||||
(my $factor, $dnum) = __calcNewFactor ({ name => $name,
|
|
||||||
oldfac => $oldfac,
|
|
||||||
dnum => $dnum,
|
|
||||||
pvre => $pvre,
|
|
||||||
pvfc => $pvfc,
|
|
||||||
pvhis => $pvhis,
|
|
||||||
fchis => $fchis
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (abs($factor - $oldfac) > $maxvar) {
|
|
||||||
$factor = sprintf "%.2f", ($factor > $oldfac ? $oldfac + $maxvar : $oldfac - $maxvar);
|
|
||||||
Log3 ($name, 3, "$name - new correction factor calculated (limited by affectMaxDayVariance): $factor (old: $oldfac) for hour: $h");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Log3 ($name, 3, "$name - new simple correction factor for hour $h calculated: $factor (old: $oldfac)") if($factor != $oldfac);
|
|
||||||
}
|
|
||||||
|
|
||||||
$pvre = sprintf "%.0f", $pvre;
|
|
||||||
$pvfc = sprintf "%.0f", $pvfc;
|
|
||||||
my $qual = __calcFcQuality ($pvfc, $pvre); # Qualität der Vorhersage für die vergangene Stunde
|
|
||||||
|
|
||||||
debugLog ($paref, 'pvCorrection', "Simple Corrf -> determined values - average forecast: $pvfc, average real: $pvre, old corrf: $oldfac, new corrf: $factor, days: $dnum");
|
|
||||||
debugLog ($paref, 'pvCorrection|saveData2Cache', "Simple Corrf -> write percentile correction values into Circular - hour: $h, factor: $factor, quality: $qual");
|
|
||||||
|
|
||||||
my $type = $paref->{type};
|
|
||||||
|
|
||||||
$data{$type}{$name}{circular}{sprintf("%02d",$h)}{pvcorrf}{percentile} = $factor; # Korrekturfaktor der jeweiligen Stunde als Datenquelle eintragen
|
|
||||||
$data{$type}{$name}{circular}{sprintf("%02d",$h)}{quality}{percentile} = $qual;
|
|
||||||
|
|
||||||
|
if (!$pvre || !$pvfc) {
|
||||||
push @$daref, ".pvCorrectionFactor_".sprintf("%02d",$h)."_apipercentil<>done";
|
push @$daref, ".pvCorrectionFactor_".sprintf("%02d",$h)."_apipercentil<>done";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ($acu =~ /on_simple/xs) {
|
$paref->{hour} = $h;
|
||||||
push @$daref, "pvCorrectionFactor_".sprintf("%02d",$h). "<>".$factor." (automatic - old factor: $oldfac, average days: $dnum)";
|
my ($pvhis,$fchis,$dnum) = __Pv_Fc_Simple_Dnum_Hist ($paref); # historischen Percentilfaktor / Qualität ermitteln
|
||||||
push @$daref, "pvCorrectionFactor_".sprintf("%02d",$h). "_autocalc<>done";
|
|
||||||
}
|
my ($oldfac, $oldq) = CircularAutokorrVal ($hash, sprintf("%02d",$h), 'percentile', 0);
|
||||||
|
$oldfac = 1 if(1 * $oldfac == 0);
|
||||||
|
|
||||||
|
(my $factor, $dnum) = __calcNewFactor ({ name => $name,
|
||||||
|
oldfac => $oldfac,
|
||||||
|
dnum => $dnum,
|
||||||
|
pvre => $pvre,
|
||||||
|
pvfc => $pvfc,
|
||||||
|
pvhis => $pvhis,
|
||||||
|
fchis => $fchis
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (abs($factor - $oldfac) > $maxvar) {
|
||||||
|
$factor = sprintf "%.2f", ($factor > $oldfac ? $oldfac + $maxvar : $oldfac - $maxvar);
|
||||||
|
Log3 ($name, 3, "$name - new simple correction factor calculated (limited by affectMaxDayVariance): $factor (old: $oldfac) for hour: $h");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Log3 ($name, 3, "$name - new simple correction factor for hour $h calculated: $factor (old: $oldfac)") if($factor != $oldfac);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pvre = sprintf "%.0f", $pvre;
|
||||||
|
$pvfc = sprintf "%.0f", $pvfc;
|
||||||
|
|
||||||
|
my $qual = __calcFcQuality ($pvfc, $pvre); # Qualität der Vorhersage für die vergangene Stunde
|
||||||
|
|
||||||
|
debugLog ($paref, 'pvCorrection', "Simple Corrf -> determined values - average forecast: $pvfc, average real: $pvre, old corrf: $oldfac, new corrf: $factor, days: $dnum");
|
||||||
|
debugLog ($paref, 'pvCorrection|saveData2Cache', "Simple Corrf -> write percentile correction values into Circular - hour: $h, factor: $factor, quality: $qual");
|
||||||
|
|
||||||
|
my $type = $paref->{type};
|
||||||
|
|
||||||
|
$data{$type}{$name}{circular}{sprintf("%02d",$h)}{pvcorrf}{percentile} = $factor; # Korrekturfaktor der jeweiligen Stunde als Datenquelle eintragen
|
||||||
|
$data{$type}{$name}{circular}{sprintf("%02d",$h)}{quality}{percentile} = $qual;
|
||||||
|
|
||||||
|
push @$daref, ".pvCorrectionFactor_".sprintf("%02d",$h)."_apipercentil<>done";
|
||||||
|
|
||||||
|
if ($acu =~ /on_simple/xs) {
|
||||||
|
push @$daref, "pvCorrectionFactor_".sprintf("%02d",$h). "<>".$factor." (automatic - old factor: $oldfac, average days: $dnum)";
|
||||||
|
push @$daref, "pvCorrectionFactor_".sprintf("%02d",$h). "_autocalc<>done";
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -10526,27 +10657,25 @@ sub _addHourAiRawdata {
|
|||||||
my $paref = shift;
|
my $paref = shift;
|
||||||
my $hash = $paref->{hash};
|
my $hash = $paref->{hash};
|
||||||
my $name = $paref->{name};
|
my $name = $paref->{name};
|
||||||
my $chour = $paref->{chour};
|
|
||||||
my $daref = $paref->{daref};
|
my $daref = $paref->{daref};
|
||||||
|
my $h = $paref->{h};
|
||||||
|
|
||||||
for my $h (1..23) {
|
my $rho = sprintf "%02d", $h;
|
||||||
next if(!$chour || $h > $chour);
|
my $sr = ReadingsVal ($name, ".signaldone_".$rho, "");
|
||||||
|
|
||||||
my $rho = sprintf "%02d", $h;
|
return if($sr eq "done");
|
||||||
my $sr = ReadingsVal ($name, ".signaldone_".$rho, "");
|
|
||||||
|
|
||||||
next if($sr eq "done");
|
debugLog ($paref, 'aiProcess', "start add AI raw data for hour: $h");
|
||||||
|
|
||||||
$paref->{ood} = 1;
|
$paref->{ood} = 1;
|
||||||
$paref->{rho} = $rho;
|
$paref->{rho} = $rho;
|
||||||
|
|
||||||
aiAddRawData ($paref); # Raw Daten für AI hinzufügen und sichern
|
aiAddRawData ($paref); # Raw Daten für AI hinzufügen und sichern
|
||||||
|
|
||||||
delete $paref->{ood};
|
delete $paref->{ood};
|
||||||
delete $paref->{rho};
|
delete $paref->{rho};
|
||||||
|
|
||||||
push @$daref, ".signaldone_".sprintf("%02d",$h)."<>done";
|
push @$daref, ".signaldone_".sprintf("%02d",$h)."<>done";
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -10595,7 +10724,7 @@ sub __Pv_Fc_Complex_Dnum_Hist {
|
|||||||
|
|
||||||
my $range = cloud2bin ($chwcc);
|
my $range = cloud2bin ($chwcc);
|
||||||
|
|
||||||
if(scalar(@efa)) {
|
if (scalar(@efa)) {
|
||||||
debugLog ($paref, 'pvCorrection', "Complex Corrf -> Raw Days ($calcd) for average check: ".join " ",@efa);
|
debugLog ($paref, 'pvCorrection', "Complex Corrf -> Raw Days ($calcd) for average check: ".join " ",@efa);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -10772,7 +10901,7 @@ sub __calcFcQuality {
|
|||||||
my $pvfc = shift; # PV Vorhersagewert
|
my $pvfc = shift; # PV Vorhersagewert
|
||||||
my $pvre = shift; # PV reale Erzeugung
|
my $pvre = shift; # PV reale Erzeugung
|
||||||
|
|
||||||
return '-' if(!$pvre);
|
return if(!$pvfc || !$pvre);
|
||||||
|
|
||||||
my $diff = $pvfc - $pvre;
|
my $diff = $pvfc - $pvre;
|
||||||
my $hdv = 1 - abs ($diff / $pvre); # Abweichung der Stunde, 1 = bestmöglicher Wert
|
my $hdv = 1 - abs ($diff / $pvre); # Abweichung der Stunde, 1 = bestmöglicher Wert
|
||||||
@ -12851,24 +12980,27 @@ sub isAddSwitchOffCond {
|
|||||||
$swoffcondregex = ConsumerVal ($hash, $c, 'swoffcondregex', '');
|
$swoffcondregex = ConsumerVal ($hash, $c, 'swoffcondregex', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
if($dswoffcond && !$defs{$dswoffcond}) {
|
if ($dswoffcond && !$defs{$dswoffcond}) {
|
||||||
$err = qq{ERROR - the device "$dswoffcond" doesn't exist! Check the key "swoffcond" or "interruptable" in attribute "consumer${c}"};
|
$err = qq{ERROR - the device "$dswoffcond" doesn't exist! Check the key "swoffcond" or "interruptable" in attribute "consumer${c}"};
|
||||||
return (0, $info, $err);
|
return (0, $info, $err);
|
||||||
}
|
}
|
||||||
|
|
||||||
my $condval = ReadingsVal ($dswoffcond, $rswoffcond, "");
|
my $condval = ReadingsVal ($dswoffcond, $rswoffcond, undef);
|
||||||
|
|
||||||
if ($hyst && isNumeric ($condval)) { # Hysterese berücksichtigen
|
if ($hyst && defined $condval && isNumeric ($condval)) { # Hysterese berücksichtigen
|
||||||
$condval -= $hyst;
|
$condval -= $hyst;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($condval && $condval =~ m/^$swoffcondregex$/x) {
|
if (defined $condval && $condval =~ m/^$swoffcondregex$/x) {
|
||||||
$info = qq{value "$condval" (hysteresis = $hyst) match the Regex "$swoffcondregex" \n}.
|
$info = qq{value "$condval" (hysteresis = $hyst) match the Regex "$swoffcondregex" \n}.
|
||||||
qq{-> Switch-off condition or interrupt in the "switch-off context", DO NOT switch on or DO NOT continue in the "switch-on context"\n}
|
qq{-> Switch-off condition or interrupt in the "switch-off context", DO NOT switch on or DO NOT continue in the "switch-on context"\n}
|
||||||
;
|
;
|
||||||
|
|
||||||
return (1, $info, $err);
|
return (1, $info, $err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$condval //= 'undef';
|
||||||
|
|
||||||
$info = qq{device: "$dswoffcond", reading: "$rswoffcond" , value: "$condval" (hysteresis = $hyst) doesn't match Regex: "$swoffcondregex" \n}.
|
$info = qq{device: "$dswoffcond", reading: "$rswoffcond" , value: "$condval" (hysteresis = $hyst) doesn't match Regex: "$swoffcondregex" \n}.
|
||||||
qq{-> DO NOT Switch-off or DO NOT interrupt in the "switch-off context", Switching on or continuing in the "switch-on" context\n}
|
qq{-> DO NOT Switch-off or DO NOT interrupt in the "switch-off context", Switching on or continuing in the "switch-on" context\n}
|
||||||
;
|
;
|
||||||
@ -15556,22 +15688,45 @@ to ensure that the system configuration is correct.
|
|||||||
|
|
||||||
<a id="SolarForecast-attr-graphicHeaderDetail"></a>
|
<a id="SolarForecast-attr-graphicHeaderDetail"></a>
|
||||||
<li><b>graphicHeaderDetail </b><br>
|
<li><b>graphicHeaderDetail </b><br>
|
||||||
Level of detail of the graphic header. <br>
|
Selection of the zones of the graphic header to be displayed. <br>
|
||||||
(default: all)
|
(default: all)
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<table>
|
<table>
|
||||||
<colgroup> <col width="15%"> <col width="85%"> </colgroup>
|
<colgroup> <col width="15%"> <col width="85%"> </colgroup>
|
||||||
<tr><td> <b>all</b> </td><td>Display generation (PV), consumption (CO), link to detail display + update time (default). </td></tr>
|
<tr><td> <b>all</b> </td><td>all zones of the head area (default) </td></tr>
|
||||||
<tr><td> <b>co</b> </td><td>Consumption only (CO) </td></tr>
|
<tr><td> <b>co</b> </td><td>show consumption range </td></tr>
|
||||||
<tr><td> <b>pv</b> </td><td>Generation only (PV) </td></tr>
|
<tr><td> <b>pv</b> </td><td>show creation area </td></tr>
|
||||||
<tr><td> <b>pvco</b> </td><td>Generation (PV) and consumption (CO) </td></tr>
|
<tr><td> <b>own</b> </td><td>user zone (see <a href="#SolarForecast-attr-graphicHeaderOwnspec">graphicHeaderOwnspec</a>) </td></tr>
|
||||||
<tr><td> <b>statusLink</b> </td><td>Link to detail display + status information </td></tr>
|
<tr><td> <b>status</b> </td><td>status information area </td></tr>
|
||||||
</table>
|
</table>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
<a id="SolarForecast-attr-graphicHeaderOwnspec"></a>
|
||||||
|
<li><b>graphicHeaderOwnspec <Label>:<Reading> <Label>:<Reading> ... </b><br>
|
||||||
|
Display of any reading values of the device. The values to be displayed are separated by spaces.
|
||||||
|
Each value is to be defined by a label and the corresponding reading connected by ":".
|
||||||
|
The input can be multiline. Spaces in the label are to be inserted by "&nbsp;".
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<b>Example: </b> <br>
|
||||||
|
<table>
|
||||||
|
<colgroup> <col width="30%"> <col width="70%"> </colgroup>
|
||||||
|
<tr><td> attr <name> graphicHeaderOwnspec </td><td>AutarkyRate:Current_AutarkyRate </td></tr>
|
||||||
|
<tr><td> </td><td>Surplus:Current_Surplus </td></tr>
|
||||||
|
<tr><td> </td><td>current&nbsp;Gridconsumption:Current_GridConsumption </td></tr>
|
||||||
|
<tr><td> </td><td>CO&nbsp;until&nbsp;sunset:statistic_todayConForecastTillSunset </td></tr>
|
||||||
|
<tr><td> </td><td>PV&nbsp;the&nbsp;day&nbsp;after&nbsp;tomorrow:statistic_dayAfterTomorrowPVforecast </td></tr>
|
||||||
|
<tr><td> </td><td>BAT&nbsp;in&nbsp;today:statistic_todayBatIn </td></tr>
|
||||||
|
<tr><td> </td><td>BAT&nbsp;out&nbsp;today:statistic_todayBatOut </td></tr>
|
||||||
|
</table>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
<a id="SolarForecast-attr-graphicHeaderShow"></a>
|
<a id="SolarForecast-attr-graphicHeaderShow"></a>
|
||||||
<li><b>graphicHeaderShow </b><br>
|
<li><b>graphicHeaderShow </b><br>
|
||||||
Show/hide the graphic table header with forecast data and certain current and
|
Show/hide the graphic table header with forecast data and certain current and
|
||||||
@ -17318,22 +17473,45 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
|
|||||||
|
|
||||||
<a id="SolarForecast-attr-graphicHeaderDetail"></a>
|
<a id="SolarForecast-attr-graphicHeaderDetail"></a>
|
||||||
<li><b>graphicHeaderDetail </b><br>
|
<li><b>graphicHeaderDetail </b><br>
|
||||||
Detaillierungsgrad des Grafik Kopfbereiches. <br>
|
Auswahl der anzuzeigenden Zonen des Grafik Kopfbereiches. <br>
|
||||||
(default: all)
|
(default: all)
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<table>
|
<table>
|
||||||
<colgroup> <col width="15%"> <col width="85%"> </colgroup>
|
<colgroup> <col width="15%"> <col width="85%"> </colgroup>
|
||||||
<tr><td> <b>all</b> </td><td>Anzeige Erzeugung (PV), Verbrauch (CO), Link zur Detailanzeige + Aktualisierungszeit (default) </td></tr>
|
<tr><td> <b>all</b> </td><td>alle Zonen des Kopfbereiches (default) </td></tr>
|
||||||
<tr><td> <b>co</b> </td><td>nur Verbrauch (CO) </td></tr>
|
<tr><td> <b>co</b> </td><td>Verbrauchsbereich anzeigen </td></tr>
|
||||||
<tr><td> <b>pv</b> </td><td>nur Erzeugung (PV) </td></tr>
|
<tr><td> <b>pv</b> </td><td>Erzeugungsbereich anzeigen </td></tr>
|
||||||
<tr><td> <b>pvco</b> </td><td>Erzeugung (PV) und Verbrauch (CO) </td></tr>
|
<tr><td> <b>own</b> </td><td>Nutzerzone (siehe <a href="#SolarForecast-attr-graphicHeaderOwnspec">graphicHeaderOwnspec</a>) </td></tr>
|
||||||
<tr><td> <b>statusLink</b> </td><td>Link zur Detailanzeige + Statusinformationen </td></tr>
|
<tr><td> <b>status</b> </td><td>Bereich der Statusinformationen </td></tr>
|
||||||
</table>
|
</table>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
<a id="SolarForecast-attr-graphicHeaderOwnspec"></a>
|
||||||
|
<li><b>graphicHeaderOwnspec <Label>:<Reading> <Label>:<Reading> ... </b><br>
|
||||||
|
Anzeige beliebiger Readingswerte des Devices. Die anzuzeigenden Werte werden durch Leerzeichen getrennt.
|
||||||
|
Jeder Wert ist jeweils durch ein Label und das dazugehörige Reading verbunden durch ":" zu definieren.
|
||||||
|
Die Eingabe kann mehrzeilig erfolgen. Leerzeichen im Label sind durch "&nbsp;" einzufügen.
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<b>Beispiel: </b> <br>
|
||||||
|
<table>
|
||||||
|
<colgroup> <col width="35%"> <col width="65%"> </colgroup>
|
||||||
|
<tr><td> attr <name> graphicHeaderOwnspec </td><td>AutarkyRate:Current_AutarkyRate </td></tr>
|
||||||
|
<tr><td> </td><td>Überschuß:Current_Surplus </td></tr>
|
||||||
|
<tr><td> </td><td>aktueller&nbsp;Netzbezug:Current_GridConsumption </td></tr>
|
||||||
|
<tr><td> </td><td>CO&nbsp;bis&nbsp;Sonnenuntergang:statistic_todayConForecastTillSunset </td></tr>
|
||||||
|
<tr><td> </td><td>PV&nbsp;Übermorgen:statistic_dayAfterTomorrowPVforecast </td></tr>
|
||||||
|
<tr><td> </td><td>BAT&nbsp;in&nbsp;heute:statistic_todayBatIn </td></tr>
|
||||||
|
<tr><td> </td><td>BAT&nbsp;out&nbsp;heute:statistic_todayBatOut </td></tr>
|
||||||
|
</table>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
<a id="SolarForecast-attr-graphicHeaderShow"></a>
|
<a id="SolarForecast-attr-graphicHeaderShow"></a>
|
||||||
<li><b>graphicHeaderShow </b><br>
|
<li><b>graphicHeaderShow </b><br>
|
||||||
Anzeigen/Verbergen des Grafik Tabellenkopfes mit Prognosedaten sowie bestimmten aktuellen und
|
Anzeigen/Verbergen des Grafik Tabellenkopfes mit Prognosedaten sowie bestimmten aktuellen und
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user