76_SolarForecast: contrib Version 1.53.2
git-svn-id: https://svn.fhem.de/fhem/trunk@30091 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
@@ -160,6 +160,9 @@ BEGIN {
|
||||
|
||||
# Versions History intern
|
||||
my %vNotesIntern = (
|
||||
"1.53.2" => "03.07.2025 graphicControl->showDiff can be set separately for each level ".
|
||||
"setupInverterDevXX: Check that there are no commas with spaces before and after (strings) ",
|
||||
"1.53.1" => "30.06.2025 add utf8 smileys, fix Perl warning uninitialized value \$color ",
|
||||
"1.53.0" => "28.06.2025 new battery style (batcontainer), new key setupBatteryDevXX->label, new reading Battery_ChargeUnrestricted_XX ".
|
||||
"attribute graphicShowDiff replaced by graphicControl->showDiff ".
|
||||
"check local coordinates are set in global device and fill message system if failure ".
|
||||
@@ -944,12 +947,12 @@ my %hqtxt = ( # H
|
||||
DE => qq{Die FHEM Tablet UI Widget-Dateien sind nicht aktuell.} },
|
||||
widerr => { EN => qq{The FHEM Tablet UI V2 is installed but the update status of widget Files can't be checked.},
|
||||
DE => qq{FTUI V2 ist installiert, der Aktualisierungsstatus der Widgets kann nicht geprüft werden.} },
|
||||
pmtp => { EN => qq{produced more than predicted :-D},
|
||||
DE => qq{mehr produziert als vorhergesagt :-D} },
|
||||
petp => { EN => qq{produced same as predicted :-)},
|
||||
DE => qq{produziert wie vorhergesagt :-)} },
|
||||
pltp => { EN => qq{produced less than predicted :-(},
|
||||
DE => qq{weniger produziert als vorhergesagt :-(} },
|
||||
pmtp => { EN => qq{produced more than predicted 😃},
|
||||
DE => qq{mehr produziert als vorhergesagt 😃} },
|
||||
petp => { EN => qq{produced same as predicted 😊},
|
||||
DE => qq{produziert wie vorhergesagt 😊} },
|
||||
pltp => { EN => qq{produced less than predicted 😓},
|
||||
DE => qq{weniger produziert als vorhergesagt 😓} },
|
||||
wusond => { EN => qq{wait until sunset},
|
||||
DE => qq{bis zum Sonnenuntergang warten} },
|
||||
snbefb => { EN => qq{Should not be empty. Maybe the device has just been redefined.},
|
||||
@@ -1126,7 +1129,7 @@ my %htitles = (
|
||||
aswfc2o => { EN => qq{The weather data is outdated.\nCheck the plant with 'set <NAME> plantConfiguration check'.},
|
||||
DE => qq{Die Wetterdaten sind veraltet.\nPrüfen sie die Anlage mit 'set <NAME> plantConfiguration check'.} },
|
||||
rdcstat => { EN => qq{no reduction status available\nPlease set the key ‘reductionState’ with 'attr <NAME> plantControl'},
|
||||
DE => qq{kein Abregelungsstatus verfügbar\nSetzen sie bitte den Schüssel 'reductionState' mit 'attr <NAME> plantControl'} },
|
||||
DE => qq{kein Abregelungsstatus verfügbar\nSetzen sie bitte den Schlüssel 'reductionState' mit 'attr <NAME> plantControl'} },
|
||||
);
|
||||
|
||||
# Wetterintertretation
|
||||
@@ -6486,17 +6489,18 @@ sub _attrgraphicControl { ## no critic "not used"
|
||||
my $cmd = $paref->{cmd};
|
||||
|
||||
my $valid = {
|
||||
beamPaddingBottom => { comp => '\d+', act => 0 },
|
||||
beamPaddingTop => { comp => '\d+', act => 0 },
|
||||
beamWidth => { comp => '([2-9][0-9]|100)', act => 0 },
|
||||
energyUnit => { comp => '(Wh|kWh)', act => 0 },
|
||||
headerDetail => { comp => '.*', act => 1 },
|
||||
hourCount => { comp => '([4-9]|1[0-9]|2[0-4])', act => 0 },
|
||||
hourStyle => { comp => ':(0{1,2})', act => 0 },
|
||||
layoutType => { comp => '(single|double|diff)', act => 0 },
|
||||
scaleMode => { comp => '(?:[1-3]:(?:log|lin))(?:,(?:[1-3]:(?:log|lin)))*', act => 0 },
|
||||
showDiff => { comp => '(no|top|bottom)', act => 0 },
|
||||
spaceSize => { comp => '\d+', act => 0 },
|
||||
beamPaddingBottom => { comp => '\d+', act => 0 },
|
||||
beamPaddingTop => { comp => '\d+', act => 0 },
|
||||
beamWidth => { comp => '([2-9][0-9]|100)', act => 0 },
|
||||
energyUnit => { comp => '(Wh|kWh)', act => 0 },
|
||||
headerDetail => { comp => '.*', act => 1 },
|
||||
hourCount => { comp => '([4-9]|1[0-9]|2[0-4])', act => 0 },
|
||||
hourStyle => { comp => ':(0{1,2})', act => 0 },
|
||||
layoutType => { comp => '(single|double|diff)', act => 0 },
|
||||
scaleMode => { comp => '(?:[1-3]:(?:log|lin))(?:,(?:[1-3]:(?:log|lin)))*', act => 0 },
|
||||
#showDiff => { comp => '(no|top|bottom)', act => 0 },
|
||||
showDiff => { comp => '(?:[1-3]:(?:top|bottom))(?:,(?:[1-3]:(?:top|bottom)))*', act => 0 },
|
||||
spaceSize => { comp => '\d+', act => 0 },
|
||||
};
|
||||
|
||||
my ($a, $h) = parseParams ($aVal);
|
||||
@@ -6951,7 +6955,11 @@ sub _attrInverterDev { ## no critic "not used"
|
||||
asynchron => { comp => '(0|1)', act => 0 },
|
||||
};
|
||||
|
||||
if ($paref->{cmd} eq 'set') {
|
||||
if ($paref->{cmd} eq 'set') {
|
||||
if ($aVal =~ /strings=/xs && $aVal !~ /strings=(?!.*(\s,|,\s)).*$/xs) {
|
||||
return "The key 'string' is not specified correctly. Please refer to the command reference.";
|
||||
}
|
||||
|
||||
my ($err, $indev, $h) = isDeviceValid ( { name => $name, obj => $aVal, method => 'string' } );
|
||||
return $err if($err);
|
||||
|
||||
@@ -14984,7 +14992,6 @@ sub entryGraphic {
|
||||
colorw => AttrVal ($name, 'graphicWeatherColor', WTHCOLDDEF), # Wetter Icon Farbe Tag
|
||||
colorwn => AttrVal ($name, 'graphicWeatherColorNight', WTHCOLNDEF), # Wetter Icon Farbe Nacht
|
||||
wlalias => AttrVal ($name, 'alias', $name),
|
||||
show_diff => CurrentVal ($name, 'showDiff', 'no'), # zusätzliche Anzeige $di{} in allen Typen
|
||||
lotype => CurrentVal ($name, 'layoutType', 'double'),
|
||||
hourstyle => CurrentVal ($name, 'hourStyle', ''),
|
||||
hdrDetail => CurrentVal ($name, 'headerDetail', 'all'), # ermöglicht den Inhalt zu begrenzen, um bspw. passgenau in ftui einzubetten
|
||||
@@ -15078,7 +15085,8 @@ sub entryGraphic {
|
||||
|
||||
## Balkengrafiken
|
||||
###################################################################################
|
||||
my $scm = _parseScaleModes ($name); # Scale Modes auflösen
|
||||
my $scm = _parseScaleModes ($name); # Scale Modes auflösen
|
||||
my $sdf = _parseShowdiffModes ($name);
|
||||
|
||||
## Balkengrafik Ebene 1
|
||||
#########################
|
||||
@@ -15086,6 +15094,7 @@ sub entryGraphic {
|
||||
my %hfcg1;
|
||||
$paref->{chartlvl} = 1; # Balkengrafik Ebene 1
|
||||
$paref->{scm} = $scm->{1}; # Scale Mode Level 1
|
||||
$paref->{showdiff} = $sdf->{1}; # show Diff Mode Level 1
|
||||
$paref->{hfcg} = \%hfcg1; # hfcg = hash forecast graphic
|
||||
|
||||
## Werte aktuelle Stunde
|
||||
@@ -15124,6 +15133,7 @@ sub entryGraphic {
|
||||
|
||||
$paref->{chartlvl} = 2;
|
||||
$paref->{scm} = $scm->{2}; # Scale Mode Level 2
|
||||
$paref->{showdiff} = $sdf->{2}; # show Diff Mode Level 2
|
||||
$paref->{beam1cont} = $paref->{beam3cont};
|
||||
$paref->{beam2cont} = $paref->{beam4cont};
|
||||
$paref->{colorb1} = AttrVal ($name, 'graphicBeam3Color', B3COLDEF);
|
||||
@@ -15167,6 +15177,7 @@ sub entryGraphic {
|
||||
|
||||
$paref->{chartlvl} = 3;
|
||||
$paref->{scm} = $scm->{3}; # Scale Mode Level 3
|
||||
$paref->{showdiff} = $sdf->{3}; # show Diff Mode Level 3
|
||||
$paref->{beam1cont} = $paref->{beam5cont};
|
||||
$paref->{beam2cont} = $paref->{beam6cont};
|
||||
$paref->{colorb1} = AttrVal ($name, 'graphicBeam5Color', B5COLDEF);
|
||||
@@ -15365,7 +15376,7 @@ return;
|
||||
}
|
||||
|
||||
################################################################
|
||||
# Parsed den Scale Mode für jede Balkengrafik Ebene
|
||||
# Parse den Scale Mode für jede Balkengrafik Ebene
|
||||
# z.B. scaleMode=1:log,2:lin,3:lin
|
||||
################################################################
|
||||
sub _parseScaleModes {
|
||||
@@ -15391,6 +15402,43 @@ sub _parseScaleModes {
|
||||
return $scm;
|
||||
}
|
||||
|
||||
################################################################
|
||||
# Parse den Diff Mode für jede Balkengrafik Ebene
|
||||
# z.B. showDiff=1:top,2:bottom,3:bottom
|
||||
################################################################
|
||||
sub _parseShowdiffModes {
|
||||
my $name = shift;
|
||||
my $sdf;
|
||||
|
||||
for my $bl (1..MAXBEAMLEVEL) { # Hashref Diff Modes initial mit Standard füllen
|
||||
$sdf->{"$bl"} = '';
|
||||
}
|
||||
|
||||
my $mo = CurrentVal ($name, 'showDiff', '');
|
||||
|
||||
### nicht mehr benötigte Daten verarbeiten - Bereich kann später wieder raus !! 03.07.
|
||||
###########################################################################################
|
||||
if ($mo) {
|
||||
$mo = $mo eq 'no' ? qq{1:'',2:'',3:''} :
|
||||
$mo eq 'top' ? qq{1:top,2:top,3:top} :
|
||||
$mo eq 'bottom' ? qq{1:bottom,2:bottom,3:bottom} :
|
||||
$mo;
|
||||
}
|
||||
##########################################################################################
|
||||
|
||||
if ($mo) {
|
||||
my @moa = split ',', $mo;
|
||||
|
||||
for my $elem (@moa) {
|
||||
my ($lvl, $mode) = split ':', $elem;
|
||||
$sdf->{"$lvl"} = $mode;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $sdf;
|
||||
}
|
||||
|
||||
################################################################
|
||||
# forecastGraphic Headerzeile generieren
|
||||
################################################################
|
||||
@@ -16746,7 +16794,7 @@ sub _beamGraphicFirstHour {
|
||||
$hfcg->{0}{beam1} //= 0;
|
||||
$hfcg->{0}{beam2} //= 0;
|
||||
$hfcg->{0}{diff} = sprintf "%.1f", ($hfcg->{0}{beam1} - $hfcg->{0}{beam2});
|
||||
$hfcg->{0}{diff} = sprintf "%.0f", $hfcg->{0}{diff} if(int ($hfcg->{0}{diff}) - $hfcg->{0}{diff} == 0);
|
||||
$hfcg->{0}{diff} = sprintf "%.0f", $hfcg->{0}{diff} if(($hfcg->{0}{beam1} - $hfcg->{0}{beam2}) * 1 == 0);
|
||||
|
||||
my $epc = CurrentVal ($hash, 'ePurchasePriceCcy', 0);
|
||||
my $efc = CurrentVal ($hash, 'eFeedInTariffCcy', 0);
|
||||
@@ -16956,7 +17004,7 @@ sub _beamGraphicRemainingHours {
|
||||
$hfcg->{$i}{beam1} //= 0;
|
||||
$hfcg->{$i}{beam2} //= 0;
|
||||
$hfcg->{$i}{diff} = sprintf "%.1f", ($hfcg->{$i}{beam1} - $hfcg->{$i}{beam2});
|
||||
$hfcg->{$i}{diff} = sprintf "%.0f", $hfcg->{$i}{diff} if(int ($hfcg->{$i}{diff}) - $hfcg->{$i}{diff} == 0);
|
||||
$hfcg->{$i}{diff} = sprintf "%.0f", $hfcg->{$i}{diff} if(($hfcg->{$i}{beam1} - $hfcg->{$i}{beam2}) * 1 == 0);
|
||||
|
||||
$maxVal = $hfcg->{$i}{beam1} if($hfcg->{$i}{beam1} > $maxVal);
|
||||
$maxVal = $hfcg->{$i}{beam2} if($hfcg->{$i}{beam2} > $maxVal);
|
||||
@@ -17048,7 +17096,7 @@ sub _beamGraphic {
|
||||
my $maxhours = $paref->{maxhours};
|
||||
my $weather = $paref->{weather};
|
||||
my $show_night = $paref->{show_night}; # alle Balken (Spalten) anzeigen ?
|
||||
my $show_diff = $paref->{show_diff}; # zusätzliche Anzeige $di{} in allen Typen
|
||||
my $showdiff = $paref->{showdiff}; # zusätzliche Anzeige $di{} in allen Typen
|
||||
my $scm = $paref->{scm}; # Scale Mode
|
||||
my $lotype = $paref->{lotype};
|
||||
my $height = $paref->{height};
|
||||
@@ -17102,7 +17150,7 @@ sub _beamGraphic {
|
||||
####################################
|
||||
$ret .= __batteryOnBeam ($paref);
|
||||
|
||||
if ($show_diff eq 'top') { # Zusätzliche Zeile Ertrag - Verbrauch
|
||||
if ($showdiff eq 'top') { # Zusätzliche Zeile Ertrag - Verbrauch
|
||||
$ret .= "<tr class='$htr{$m}{cl}'><td class='solarfc'></td>";
|
||||
|
||||
my $ii = 0;
|
||||
@@ -17368,7 +17416,7 @@ sub _beamGraphic {
|
||||
}
|
||||
}
|
||||
|
||||
if ($show_diff eq 'bottom') { # zusätzliche diff Anzeige
|
||||
if ($showdiff eq 'bottom') { # zusätzliche diff Anzeige
|
||||
$val = normBeamWidth ($paref, 'diff', $i, 'beam1');
|
||||
|
||||
if ($val ne ' ') { # negative Zahlen in Fettschrift, 0 aber ohne +
|
||||
@@ -18706,7 +18754,7 @@ sub __substituteIcon {
|
||||
$txt = $pretxt.$soctxt; # resultierender Text
|
||||
}
|
||||
|
||||
if ($color eq 'dyn') {
|
||||
if ($color && $color eq 'dyn') {
|
||||
$color = val2dynColor ($soc, 0, $flag ? 0 : 0.4);
|
||||
}
|
||||
}
|
||||
@@ -26697,9 +26745,9 @@ to ensure that the system configuration is correct.
|
||||
<tr><td> </td><td><b><Level>:log</b> - logarithmic scaling </td></tr>
|
||||
<tr><td> </td><td> </td></tr>
|
||||
<tr><td> <b>showDiff</b> </td><td>Additional numerical display of the difference ‘<primary bar content> - <secondary bar content>’. </td></tr>
|
||||
<tr><td> </td><td><b>no</b> - no difference display (default) </td></tr>
|
||||
<tr><td> </td><td><b>top</b> - display above the bars </td></tr>
|
||||
<tr><td> </td><td><b>bottom</b> - display below the bars </td></tr>
|
||||
<tr><td> </td><td>The specification for each level consists of the level number (1..X), a ‘:’ followed by the position ‘top’ or ‘bottom’. </td></tr>
|
||||
<tr><td> </td><td><b><Level>:top</b> - display above the bars </td></tr>
|
||||
<tr><td> </td><td><b><Level>:bottom</b> - display below the bars </td></tr>
|
||||
<tr><td> </td><td> </td></tr>
|
||||
<tr><td> <b>spaceSize</b> </td><td>Defines how much space in px is kept free above or below the bar (for display type layoutType=diff) to display the </td></tr>
|
||||
<tr><td> </td><td>values. For styles with large fonts, the default value may be too small or a bar may slide over the baseline. </td></tr>
|
||||
@@ -26711,7 +26759,7 @@ to ensure that the system configuration is correct.
|
||||
|
||||
<ul>
|
||||
<b>Example: </b> <br>
|
||||
attr <name> graphicControl beamWidth=45 headerDetail=co,pv energyUnit=kWh hourCount=10 layoutType=diff hourStyle=:00 scaleMode=1:log,2:lin,3:log
|
||||
attr <name> graphicControl beamWidth=45 headerDetail=co,pv energyUnit=kWh hourCount=10 layoutType=diff hourStyle=:00 scaleMode=1:log,2:lin,3:log showDiff=1:top,2:bottom
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
@@ -28726,7 +28774,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
|
||||
Dabei ist <Device> ein in FHEM bereits angelegtes Verbraucher Device, z.B. eine Schaltsteckdose.
|
||||
Die meisten Schlüssel sind optional, sind aber für bestimmte Funktionalitäten Voraussetzung und werden mit
|
||||
default-Werten besetzt. <br>
|
||||
Ist der Schüssel "auto" definiert, kann der Automatikmodus in der integrierten Verbrauchergrafik mit den
|
||||
Ist der Schlüssel "auto" definiert, kann der Automatikmodus in der integrierten Verbrauchergrafik mit den
|
||||
entsprechenden Drucktasten umgeschaltet werden. Das angegebene Reading wird ggf. im Consumer Device angelegt falls
|
||||
es nicht vorhanden ist. <br><br>
|
||||
|
||||
@@ -29352,9 +29400,9 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
|
||||
<tr><td> </td><td><b><Ebene>:log</b> - logarithmische Skalierung </td></tr>
|
||||
<tr><td> </td><td> </td></tr>
|
||||
<tr><td> <b>showDiff</b> </td><td>Zusätzliche numerische Anzeige der Differenz '<primärer Balkeninhalt> - <sekundärer Balkeninhalt>'. </td></tr>
|
||||
<tr><td> </td><td><b>no</b> - keine Differenzanzeige (default) </td></tr>
|
||||
<tr><td> </td><td><b>top</b> - Anzeige über den Balken </td></tr>
|
||||
<tr><td> </td><td><b>bottom</b> - Anzeige unter den Balken </td></tr>
|
||||
<tr><td> </td><td>Die Angabe für jede Ebene besteht aus der Ebenen-Nummer (1..X), einem ':' gefolgt von der Position 'top' oder 'bottom'. </td></tr>
|
||||
<tr><td> </td><td><b><Ebene>:top</b> - Anzeige über den Balken </td></tr>
|
||||
<tr><td> </td><td><b><Ebene>:bottom</b> - Anzeige unter den Balken </td></tr>
|
||||
<tr><td> </td><td> </td></tr>
|
||||
<tr><td> <b>spaceSize</b> </td><td>Legt fest, wieviel Platz in px über oder unter den Balken (bei Anzeigetyp layoutType=diff) zur Anzeige der </td></tr>
|
||||
<tr><td> </td><td>Werte freigehalten wird. Bei Styles mit großen Fonts kann der default-Wert zu klein sein bzw. rutscht ein </td></tr>
|
||||
@@ -29366,7 +29414,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
|
||||
|
||||
<ul>
|
||||
<b>Beispiel: </b> <br>
|
||||
attr <name> graphicControl beamWidth=45 headerDetail=co,pv energyUnit=kWh hourCount=10 layoutType=diff hourStyle=:00 scaleMode=1:log,2:lin,3:log showDiff=top
|
||||
attr <name> graphicControl beamWidth=45 headerDetail=co,pv energyUnit=kWh hourCount=10 layoutType=diff hourStyle=:00 scaleMode=1:log,2:lin,3:log showDiff=1:top,2:bottom
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
@@ -29681,7 +29729,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
|
||||
<tr><td> </td><td><b><entladen></b> - Icon wird verwendet wenn die Batterie aktuell entladen wird </td></tr>
|
||||
<tr><td> </td><td><b><unterlassen></b> - Icon wenn Aufladen nur bei Überschreitung des Einspeiselimits empfohlen </td></tr>
|
||||
<tr><td> </td><td> </td></tr>
|
||||
<tr><td> <b>label</b> </td><td>Wird die Batterie in der Balkengrafik mit dem Schüssel 'show' angezeigt, kann das Symbol mit dem </td></tr>
|
||||
<tr><td> <b>label</b> </td><td>Wird die Batterie in der Balkengrafik mit dem Schlüssel 'show' angezeigt, kann das Symbol mit dem </td></tr>
|
||||
<tr><td> </td><td>aktuellen SOC-Wert (%) beschriftet werden. </td></tr>
|
||||
<tr><td> </td><td><b>none</b> - keine Beschriftung (default) </td></tr>
|
||||
<tr><td> </td><td><b>below</b> - Beschriftung unterhalb des Batteriesymbols </td></tr>
|
||||
|
||||
Reference in New Issue
Block a user