2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 12:49:34 +00:00

76_SolarForecast: attr ctrlWeatherDevX to setupWeatherDevX

git-svn-id: https://svn.fhem.de/fhem/trunk@29089 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2024-08-20 19:14:29 +00:00
parent bc513f5e97
commit 38d823c13f
3 changed files with 551 additions and 572 deletions

View File

@ -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: attr ctrlWeatherDevX to setupWeatherDevX,
- bufgix: 76_SMAInverter: fix PW Lengs Bug - bufgix: 76_SMAInverter: fix PW Lengs Bug
- bugfix: 10_KNX: prevent set/get-cmd during fhem start - bugfix: 10_KNX: prevent set/get-cmd during fhem start
add sub dpts for dpt14, enfoce gadname rules add sub dpts for dpt14, enfoce gadname rules

View File

@ -155,6 +155,7 @@ BEGIN {
# Versions History intern # Versions History intern
my %vNotesIntern = ( my %vNotesIntern = (
"1.31.0" => "20.08.2024 rename attributes ctrlWeatherDevX to setupWeatherDevX ",
"1.30.0" => "18.08.2024 new attribute flowGraphicShift, Forum:https://forum.fhem.de/index.php?msg=1318597 ", "1.30.0" => "18.08.2024 new attribute flowGraphicShift, Forum:https://forum.fhem.de/index.php?msg=1318597 ",
"1.29.4" => "03.08.2024 delete writeCacheToFile from _getRoofTopData, _specialActivities: avoid loop caused by \@widgetreadings ", "1.29.4" => "03.08.2024 delete writeCacheToFile from _getRoofTopData, _specialActivities: avoid loop caused by \@widgetreadings ",
"1.29.3" => "20.07.2024 eleminate hand over \$hash in _getRoofTopData routines, fix label 'gcon' to 'gcons' ", "1.29.3" => "20.07.2024 eleminate hand over \$hash in _getRoofTopData routines, fix label 'gcon' to 'gcons' ",
@ -388,7 +389,7 @@ my $WhtokJ = 3.6;
my $defmaxvar = 0.5; # max. Varianz pro Tagesberechnung Autokorrekturfaktor my $defmaxvar = 0.5; # max. Varianz pro Tagesberechnung Autokorrekturfaktor
my $definterval = 70; # Standard Abfrageintervall my $definterval = 70; # Standard Abfrageintervall
my $slidenumdef = 3; # max. Anzahl der Arrayelemente in Schieberegistern my $slidenumdef = 3; # max. Anzahl der Arrayelemente in Schieberegistern
my $weatherDevMax = 3; # max. Anzahl Wetter Devices (Attr ctrlWeatherDevX) my $weatherDevMax = 3; # max. Anzahl Wetter Devices (Attr setupWeatherDevX)
my $maxSoCdef = 95; # default Wert (%) auf den die Batterie maximal aufgeladen werden soll bzw. als aufgeladen gilt my $maxSoCdef = 95; # default Wert (%) auf den die Batterie maximal aufgeladen werden soll bzw. als aufgeladen gilt
my $carecycledef = 20; # max. Anzahl Tage die zwischen der Batterieladung auf maxSoC liegen dürfen my $carecycledef = 20; # max. Anzahl Tage die zwischen der Batterieladung auf maxSoC liegen dürfen
my $batSocChgDay = 5; # prozentuale SoC Änderung pro Tag my $batSocChgDay = 5; # prozentuale SoC Änderung pro Tag
@ -522,7 +523,7 @@ my @aconfigs = qw( affect70percentRule affectBatteryPreferredCharge affectConsFo
ctrlBatSocManagement ctrlConsRecommendReadings ctrlGenPVdeviation ctrlInterval ctrlBatSocManagement ctrlConsRecommendReadings ctrlGenPVdeviation ctrlInterval
ctrlLanguage ctrlNextDayForecastReadings ctrlShowLink ctrlSolCastAPImaxReq ctrlLanguage ctrlNextDayForecastReadings ctrlShowLink ctrlSolCastAPImaxReq
ctrlSolCastAPIoptimizeReq ctrlStatisticReadings ctrlUserExitFn ctrlSolCastAPIoptimizeReq ctrlStatisticReadings ctrlUserExitFn
ctrlWeatherDev1 ctrlWeatherDev2 ctrlWeatherDev3 setupWeatherDev1 setupWeatherDev2 setupWeatherDev3
disable disable
flowGraphicSize flowGraphicAnimate flowGraphicConsumerDistance flowGraphicShowConsumer flowGraphicSize flowGraphicAnimate flowGraphicConsumerDistance flowGraphicShowConsumer
flowGraphicShowConsumerDummy flowGraphicShowConsumerPower flowGraphicShowConsumerRemainTime flowGraphicShowConsumerDummy flowGraphicShowConsumerPower flowGraphicShowConsumerRemainTime
@ -609,9 +610,9 @@ my %hattr = ( # H
ctrlConsRecommendReadings => { fn => \&_attrcreateConsRecRdgs }, ctrlConsRecommendReadings => { fn => \&_attrcreateConsRecRdgs },
ctrlStatisticReadings => { fn => \&_attrcreateStatisticRdgs }, ctrlStatisticReadings => { fn => \&_attrcreateStatisticRdgs },
ctrlDebug => { fn => \&_attrctrlDebug }, ctrlDebug => { fn => \&_attrctrlDebug },
ctrlWeatherDev1 => { fn => \&_attrWeatherDev }, setupWeatherDev1 => { fn => \&_attrWeatherDev },
ctrlWeatherDev2 => { fn => \&_attrWeatherDev }, setupWeatherDev2 => { fn => \&_attrWeatherDev },
ctrlWeatherDev3 => { fn => \&_attrWeatherDev }, setupWeatherDev3 => { fn => \&_attrWeatherDev },
setupMeterDev => { fn => \&_attrMeterDev }, setupMeterDev => { fn => \&_attrMeterDev },
setupBatteryDev => { fn => \&_attrBatteryDev }, setupBatteryDev => { fn => \&_attrBatteryDev },
setupInverterDev => { fn => \&_attrInverterDev }, setupInverterDev => { fn => \&_attrInverterDev },
@ -661,8 +662,8 @@ my %hqtxt = (
"set LINK plantConfiguration check" oder mit Druck auf das angebotene Icon.<br> "set LINK plantConfiguration check" oder mit Druck auf das angebotene Icon.<br>
Korrigieren sie bitte eventuelle Fehler und beachten sie m&ouml;gliche Hinweise.<br> Korrigieren sie bitte eventuelle Fehler und beachten sie m&ouml;gliche Hinweise.<br>
(Die Anzeigesprache kann mit dem Attribut "ctrlLanguage" umgestellt werden.)<hr><br>} }, (Die Anzeigesprache kann mit dem Attribut "ctrlLanguage" umgestellt werden.)<hr><br>} },
cfd => { EN => qq{Please enter at least one weather forecast device with "attr LINK ctrlWeatherDev1"}, cfd => { EN => qq{Please enter at least one weather forecast device with "attr LINK setupWeatherDev1"},
DE => qq{Bitte geben sie mindestens ein Wettervorhersage Device mit "attr LINK ctrlWeatherDev1" an} }, DE => qq{Bitte geben sie mindestens ein Wettervorhersage Device mit "attr LINK setupWeatherDev1" an} },
crd => { EN => qq{Please select the radiation forecast service with "attr LINK setupRadiationAPI"}, crd => { EN => qq{Please select the radiation forecast service with "attr LINK setupRadiationAPI"},
DE => qq{Bitte geben sie den Strahlungsvorhersage Dienst mit "attr LINK setupRadiationAPI" an} }, DE => qq{Bitte geben sie den Strahlungsvorhersage Dienst mit "attr LINK setupRadiationAPI" an} },
cid => { EN => qq{Please specify the Inverter device with "attr LINK setupInverterDev"}, cid => { EN => qq{Please specify the Inverter device with "attr LINK setupInverterDev"},
@ -1182,9 +1183,6 @@ sub Initialize {
"ctrlSolCastAPIoptimizeReq:1,0 ". "ctrlSolCastAPIoptimizeReq:1,0 ".
"ctrlStatisticReadings:multiple-strict,$srd ". "ctrlStatisticReadings:multiple-strict,$srd ".
"ctrlUserExitFn:textField-long ". "ctrlUserExitFn:textField-long ".
"ctrlWeatherDev1 ".
"ctrlWeatherDev2 ".
"ctrlWeatherDev3 ".
"disable:1,0 ". "disable:1,0 ".
"flowGraphicSize ". "flowGraphicSize ".
"flowGraphicAnimate:1,0 ". "flowGraphicAnimate:1,0 ".
@ -1232,6 +1230,9 @@ sub Initialize {
"setupInverterDev:textField-long ". "setupInverterDev:textField-long ".
"setupInverterStrings ". "setupInverterStrings ".
"setupMeterDev:textField-long ". "setupMeterDev:textField-long ".
"setupWeatherDev1 ".
"setupWeatherDev2 ".
"setupWeatherDev3 ".
"setupRoofTops ". "setupRoofTops ".
"setupBatteryDev:textField-long ". "setupBatteryDev:textField-long ".
"setupRadiationAPI ". "setupRadiationAPI ".
@ -1245,6 +1246,9 @@ sub Initialize {
# $hash->{FW_atPageEnd} = 1; # wenn 1 -> kein Longpoll ohne informid in HTML-Tag # $hash->{FW_atPageEnd} = 1; # wenn 1 -> kein Longpoll ohne informid in HTML-Tag
$hash->{AttrRenameMap} = { "graphicBeamHeight" => "graphicBeamHeightLevel1", # 07.05.24 $hash->{AttrRenameMap} = { "graphicBeamHeight" => "graphicBeamHeightLevel1", # 07.05.24
"ctrlWeatherDev1" => "setupWeatherDev1", # 20.08.24
"ctrlWeatherDev2" => "setupWeatherDev2",
"ctrlWeatherDev3" => "setupWeatherDev3",
}; };
eval { FHEM::Meta::InitMod( __FILE__, $hash ) }; ## no critic 'eval' eval { FHEM::Meta::InitMod( __FILE__, $hash ) }; ## no critic 'eval'
@ -5669,7 +5673,7 @@ return;
} }
################################################################ ################################################################
# Attr ctrlWeatherDevX # Attr setupWeatherDevX
################################################################ ################################################################
sub _attrWeatherDev { ## no critic "not used" sub _attrWeatherDev { ## no critic "not used"
my $paref = shift; my $paref = shift;
@ -5687,11 +5691,11 @@ sub _attrWeatherDev { ## no critic "not used"
} }
if ($aVal =~ /^OpenMeteo/xs) { if ($aVal =~ /^OpenMeteo/xs) {
if ($aName ne 'ctrlWeatherDev1') { if ($aName ne 'setupWeatherDev1') {
return qq{Only the leading attribute 'ctrlWeatherDev1' can set to '$aVal'}; return qq{Only the leading attribute 'setupWeatherDev1' can set to '$aVal'};
} }
InternalTimer (gettimeofday()+1, 'FHEM::SolarForecast::__setRadAPIdelayed', $hash, 0); # automatisch setupRadiationAPI setzen wenn ctrlWeatherDev1 InternalTimer (gettimeofday()+1, 'FHEM::SolarForecast::__setRadAPIdelayed', $hash, 0); # automatisch setupRadiationAPI setzen wenn setupWeatherDev1
return; return;
} }
@ -5723,12 +5727,12 @@ sub _attrRadiationAPI { ## no critic "not used"
return qq{The device "$aVal" doesn't exist or has no TYPE "DWD_OpenData"}; return qq{The device "$aVal" doesn't exist or has no TYPE "DWD_OpenData"};
} }
my $awdev1 = AttrVal ($name, 'ctrlWeatherDev1', ''); my $awdev1 = AttrVal ($name, 'setupWeatherDev1', '');
if (($awdev1 eq 'OpenMeteoDWD-API' && $aVal ne 'OpenMeteoDWD-API') || if (($awdev1 eq 'OpenMeteoDWD-API' && $aVal ne 'OpenMeteoDWD-API') ||
($awdev1 eq 'OpenMeteoDWDEnsemble-API' && $aVal ne 'OpenMeteoDWDEnsemble-API') || ($awdev1 eq 'OpenMeteoDWDEnsemble-API' && $aVal ne 'OpenMeteoDWDEnsemble-API') ||
($awdev1 eq 'OpenMeteoWorld-API' && $aVal ne 'OpenMeteoWorld-API')) { ($awdev1 eq 'OpenMeteoWorld-API' && $aVal ne 'OpenMeteoWorld-API')) {
return "The attribute 'ctrlWeatherDev1' is set to '$awdev1'. \n". return "The attribute 'setupWeatherDev1' is set to '$awdev1'. \n".
"Change that attribute to another weather device first if you want use an other API."; "Change that attribute to another weather device first if you want use an other API.";
} }
@ -5798,7 +5802,7 @@ sub __setRadAPIdelayed {
my $hash = shift; my $hash = shift;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $awdev1 = AttrVal ($name, 'ctrlWeatherDev1', ''); my $awdev1 = AttrVal ($name, 'setupWeatherDev1', '');
CommandAttr (undef, "$name setupRadiationAPI $awdev1"); # automatisch setupRadiationAPI setzen CommandAttr (undef, "$name setupRadiationAPI $awdev1"); # automatisch setupRadiationAPI setzen
@ -6428,7 +6432,7 @@ sub _addDynAttr {
my $hash = shift; my $hash = shift;
my $type = $hash->{TYPE}; my $type = $hash->{TYPE};
## Attr ctrlWeatherDevX zur Laufzeit hinzufügen ## Attr setupWeatherDevX zur Laufzeit hinzufügen
################################################# #################################################
my $adwds = ''; my $adwds = '';
my @alldwd = devspec2array ("TYPE=DWD_OpenData"); my @alldwd = devspec2array ("TYPE=DWD_OpenData");
@ -6445,16 +6449,17 @@ sub _addDynAttr {
my @deva = split " ", $modules{$type}{AttrList}; my @deva = split " ", $modules{$type}{AttrList};
my $atd = 'ctrlWeatherDev|setupRadiationAPI'; my $atd = 'setupWeatherDev|setupRadiationAPI';
@deva = grep {!/$atd/} @deva; @deva = grep {!/$atd/} @deva;
for my $step (1..$weatherDevMax) { for my $step (1..$weatherDevMax) {
if ($step == 1) { if ($step == 1) {
push @deva, ($adwds ? "ctrlWeatherDev1:OpenMeteoDWD-API,OpenMeteoDWDEnsemble-API,OpenMeteoWorld-API,$adwds" : "ctrlWeatherDev1:OpenMeteoDWD-API,OpenMeteoDWDEnsemble-API,OpenMeteoWorld-API"); push @deva, ($adwds ? "setupWeatherDev1:OpenMeteoDWD-API,OpenMeteoDWDEnsemble-API,OpenMeteoWorld-API,$adwds" :
"setupWeatherDev1:OpenMeteoDWD-API,OpenMeteoDWDEnsemble-API,OpenMeteoWorld-API");
next; next;
} }
push @deva, ($adwds ? "ctrlWeatherDev".$step.":$adwds" : ""); push @deva, ($adwds ? "setupWeatherDev".$step.":$adwds" : "");
} }
push @deva, "setupRadiationAPI:$rdd "; push @deva, "setupRadiationAPI:$rdd ";
@ -6496,18 +6501,6 @@ sub centralTask {
### 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 $val4 = ReadingsVal ($name, 'currentRadiationAPI', ''); # 10.06.2024
if ($val4) {
CommandAttr (undef, "$name setupRadiationAPI $val4");
readingsDelete ($hash, 'currentRadiationAPI');
}
my $val5 = ReadingsVal ($name, 'modulePeakString', ''); # 12.06.2024
if ($val5) {
CommandAttr (undef, "$name setupStringPeak $val5");
readingsDelete ($hash, 'modulePeakString');
}
my $dir = ReadingsVal ($name, 'moduleAzimuth', ''); # 16.06.2024 my $dir = ReadingsVal ($name, 'moduleAzimuth', ''); # 16.06.2024
if ($dir) { if ($dir) {
readingsSingleUpdate ($hash, 'setupStringAzimuth', $dir, 0); readingsSingleUpdate ($hash, 'setupStringAzimuth', $dir, 0);
@ -7362,7 +7355,7 @@ sub _transferWeatherValues {
my $chour = $paref->{chour}; my $chour = $paref->{chour};
my $hash = $defs{$name}; my $hash = $defs{$name};
my ($valid, $fcname, $apiu) = isWeatherDevValid ($hash, 'ctrlWeatherDev1'); # Standard Weather Forecast Device my ($valid, $fcname, $apiu) = isWeatherDevValid ($hash, 'setupWeatherDev1'); # Standard Weather Forecast Device
return if(!$valid); return if(!$valid);
my $type = $paref->{type}; my $type = $paref->{type};
@ -7443,7 +7436,7 @@ return;
} }
################################################################ ################################################################
# lese Wetterdaten aus Device im Attribut ctrlWeatherDevX # lese Wetterdaten aus Device im Attribut setupWeatherDevX
# X = laufende Schleifenvariable $step # X = laufende Schleifenvariable $step
################################################################ ################################################################
sub __readDataWeather { sub __readDataWeather {
@ -7454,7 +7447,7 @@ sub __readDataWeather {
my $step = $paref->{step}; my $step = $paref->{step};
my $hash = $defs{$name}; my $hash = $defs{$name};
my ($valid, $fcname, $apiu) = isWeatherDevValid ($hash, 'ctrlWeatherDev'.$step); # Weather Forecast Device my ($valid, $fcname, $apiu) = isWeatherDevValid ($hash, 'setupWeatherDev'.$step); # Weather Forecast Device
return if(!$valid); return if(!$valid);
if ($apiu) { # eine API wird verwendet if ($apiu) { # eine API wird verwendet
@ -7562,7 +7555,7 @@ sub __mergeDataWeather {
my $ds = 0; my $ds = 0;
for my $wd (1..$weatherDevMax) { for my $wd (1..$weatherDevMax) {
my ($valid, $fcname, $apiu) = isWeatherDevValid ($hash, 'ctrlWeatherDev'.$wd); # Weather Forecast Device my ($valid, $fcname, $apiu) = isWeatherDevValid ($hash, 'setupWeatherDev'.$wd); # Weather Forecast Device
$ds++ if($valid); $ds++ if($valid);
} }
@ -11689,7 +11682,7 @@ sub _checkSetupNotComplete {
########################################################################################## ##########################################################################################
my $is = AttrVal ($name, 'setupInverterStrings', undef); # String Konfig my $is = AttrVal ($name, 'setupInverterStrings', undef); # String Konfig
my $wedev = AttrVal ($name, 'ctrlWeatherDev1', undef); # Device Vorhersage Wetterdaten (Bewölkung etc.) my $wedev = AttrVal ($name, 'setupWeatherDev1', undef); # Device Vorhersage Wetterdaten (Bewölkung etc.)
my $radev = AttrVal ($name, 'setupRadiationAPI', undef); # Device Strahlungsdaten Vorhersage my $radev = AttrVal ($name, 'setupRadiationAPI', undef); # Device Strahlungsdaten Vorhersage
my $indev = AttrVal ($name, 'setupInverterDev', undef); # Inverter Device my $indev = AttrVal ($name, 'setupInverterDev', undef); # Inverter Device
my $medev = AttrVal ($name, 'setupMeterDev', undef); # Meter Device my $medev = AttrVal ($name, 'setupMeterDev', undef); # Meter Device
@ -13638,19 +13631,15 @@ sub _flowGraphic {
my $csc_style = $csc && $cpv ? 'flowg active_out' : 'flowg inactive_out'; my $csc_style = $csc && $cpv ? 'flowg active_out' : 'flowg inactive_out';
my $cgfi_style = $cgfi ? 'flowg active_out' : 'flowg inactive_out'; my $cgfi_style = $cgfi ? 'flowg active_out' : 'flowg inactive_out';
my $vbminx = -10 * $flowgshift; # min-x and min-y represent the smallest X and Y coordinates that the viewBox may have my $vbminx = -10 * $flowgshift; # min-x and min-y represent the smallest X and Y coordinates that the viewBox may have
my $vbminy = -25; my $vbminy = -25;
my $vbwidth = 800; # width and height specify the viewBox size my $vbwidth = 800; # width and height specify the viewBox size
my $vbhight = !$flowgcons ? 480 : my $vbhight = !$flowgcons ? 480 :
$flowgconTime ? 700 : $flowgconTime ? 700 :
680; 680;
my $vbox = "$vbminx $vbminy $vbwidth $vbhight"; my $vbox = "$vbminx $vbminy $vbwidth $vbhight";
#my $vbox = !$flowgcons ? "$vbminx -25 800 480" :
# $flowgconTime ? "$vbminx -25 800 700" :
# "$vbminx -25 800 680";
my $ret = << "END0"; my $ret = << "END0";
<style> <style>
$css $css
@ -13777,7 +13766,7 @@ END3
$consumer_style = 'flowg active_in' if($cc_dummy > 1); $consumer_style = 'flowg active_in' if($cc_dummy > 1);
my $chain_color = ""; # Farbe der Laufkette Consumer-Dummy my $chain_color = ""; # Farbe der Laufkette Consumer-Dummy
if($cc_dummy > 0.5) { if ($cc_dummy > 0.5) {
$chain_color = 'style="stroke: #'.substr(Color::pahColor(0,500,1000,$cc_dummy,[0,255,0, 127,255,0, 255,255,0, 255,127,0, 255,0,0]),0,6).';"'; $chain_color = 'style="stroke: #'.substr(Color::pahColor(0,500,1000,$cc_dummy,[0,255,0, 127,255,0, 255,255,0, 255,127,0, 255,0,0]),0,6).';"';
#$chain_color = 'style="stroke: #DF0101;"'; #$chain_color = 'style="stroke: #DF0101;"';
} }
@ -13815,7 +13804,7 @@ END3
$consumer_style = 'flowg active_out' if($p > $defpopercent); $consumer_style = 'flowg active_out' if($p > $defpopercent);
my $chain_color = ""; # Farbe der Laufkette des Consumers my $chain_color = ""; # Farbe der Laufkette des Consumers
if($p > 0.5) { if ($p > 0.5) {
$chain_color = 'style="stroke: #'.substr(Color::pahColor(0,50,100,$p,[0,255,0, 127,255,0, 255,255,0, 255,127,0, 255,0,0]),0,6).';"'; $chain_color = 'style="stroke: #'.substr(Color::pahColor(0,50,100,$p,[0,255,0, 127,255,0, 255,255,0, 255,127,0, 255,0,0]),0,6).';"';
#$chain_color = 'style="stroke: #DF0101;"'; #$chain_color = 'style="stroke: #DF0101;"';
} }
@ -13951,7 +13940,7 @@ sub consinject {
if ($_) { if ($_) {
my ($cons,$im,$start,$end) = split (':', $_); my ($cons,$im,$start,$end) = split (':', $_);
if($debug =~ /graphic/x) { if ($debug =~ /graphic/x) {
Log3 ($name, 1, qq{$name DEBUG> Consumer to show -> $cons, relative to current time -> start: $start, end: $end}) if($i<1); Log3 ($name, 1, qq{$name DEBUG> Consumer to show -> $cons, relative to current time -> start: $start, end: $end}) if($i<1);
} }
@ -14040,7 +14029,7 @@ sub weather_icon {
$id = int $id; $id = int $id;
my $txt = $lang eq "DE" ? "txtd" : "txte"; my $txt = $lang eq "DE" ? "txtd" : "txte";
if(defined $weather_ids{$id}) { if (defined $weather_ids{$id}) {
return $weather_ids{$id}{icon}, encode("utf8", $weather_ids{$id}{$txt}); return $weather_ids{$id}{icon}, encode("utf8", $weather_ids{$id}{$txt});
} }
@ -14069,7 +14058,7 @@ sub checkdwdattr {
$err = qq{ERROR - device "$dwddev" -> attribute "forecastProperties" must contain: }.join ",",@aneeded; $err = qq{ERROR - device "$dwddev" -> attribute "forecastProperties" must contain: }.join ",",@aneeded;
} }
if($fcr != 1) { if ($fcr != 1) {
$err .= ", " if($err); $err .= ", " if($err);
$err .= qq{ERROR - device "$dwddev" -> attribute "forecastResolution" must be set to "1"}; $err .= qq{ERROR - device "$dwddev" -> attribute "forecastResolution" must be set to "1"};
} }
@ -14734,7 +14723,6 @@ return $ridx;
################################################################ ################################################################
sub writeToHistory { sub writeToHistory {
my $ph = shift; my $ph = shift;
my $paref = $ph->{paref}; my $paref = $ph->{paref};
my $key = $ph->{key}; my $key = $ph->{key};
my $val = $ph->{val}; my $val = $ph->{val};
@ -15616,14 +15604,14 @@ sub checkPlantConfig {
my $resh; my $resh;
for my $step (1..$weatherDevMax) { for my $step (1..$weatherDevMax) {
my ($valid, $fcname, $apiu) = isWeatherDevValid ($hash, 'ctrlWeatherDev'.$step); my ($valid, $fcname, $apiu) = isWeatherDevValid ($hash, 'setupWeatherDev'.$step);
next if(!$fcname && $step ne 1); next if(!$fcname && $step ne 1);
if (!$valid) { if (!$valid) {
$result->{'DWD Weather Properties'}{state} = $nok; $result->{'DWD Weather Properties'}{state} = $nok;
if (!$fcname) { if (!$fcname) {
$result->{'DWD Weather Properties'}{result} .= qq{No DWD device is defined in attribute "ctrlWeatherDev$step". <br>}; $result->{'DWD Weather Properties'}{result} .= qq{No DWD device is defined in attribute "setupWeatherDev$step". <br>};
} }
else { else {
$result->{'DWD Weather Properties'}{result} .= qq{The DWD device "$fcname" doesn't exist. <br>}; $result->{'DWD Weather Properties'}{result} .= qq{The DWD device "$fcname" doesn't exist. <br>};
@ -15649,7 +15637,7 @@ sub checkPlantConfig {
$result->{'DWD Weather Properties'}{info} = 1; $result->{'DWD Weather Properties'}{info} = 1;
} }
$result->{'DWD Weather Properties'}{result} .= $hqtxt{fulfd}{$lang}." ($hqtxt{attrib}{$lang}: ctrlWeatherDev$step)<br>"; $result->{'DWD Weather Properties'}{result} .= $hqtxt{fulfd}{$lang}." ($hqtxt{attrib}{$lang}: setupWeatherDev$step)<br>";
} }
$result->{'DWD Weather Properties'}{note} .= qq{checked parameters and attributes of device "$fcname": <br>}; $result->{'DWD Weather Properties'}{note} .= qq{checked parameters and attributes of device "$fcname": <br>};
@ -15657,7 +15645,7 @@ sub checkPlantConfig {
$result->{'DWD Weather Properties'}{note} .= 'forecastRefresh '.($mosm eq 'MOSMIX_L' ? '-> set attribute to below "6" if possible' : '').'<br>'; $result->{'DWD Weather Properties'}{note} .= 'forecastRefresh '.($mosm eq 'MOSMIX_L' ? '-> set attribute to below "6" if possible' : '').'<br>';
} }
else { else {
$result->{'DWD Weather Properties'}{result} .= $hqtxt{fulfd}{$lang}." ($hqtxt{attrib}{$lang}: ctrlWeatherDev$step)<br>"; $result->{'DWD Weather Properties'}{result} .= $hqtxt{fulfd}{$lang}." ($hqtxt{attrib}{$lang}: setupWeatherDev$step)<br>";
} }
} }
} }
@ -16364,15 +16352,15 @@ sub createAssociatedWith {
my (@cd, @nd); my (@cd, @nd);
my ($afc, $ara, $ain, $ame, $aba, $h); my ($afc, $ara, $ain, $ame, $aba, $h);
my $fcdev1 = AttrVal ($name, 'ctrlWeatherDev1', ''); # Weather forecast Device 1 my $fcdev1 = AttrVal ($name, 'setupWeatherDev1', ''); # Weather forecast Device 1
($afc,$h) = parseParams ($fcdev1); ($afc,$h) = parseParams ($fcdev1);
$fcdev1 = $afc->[0] // ""; $fcdev1 = $afc->[0] // "";
my $fcdev2 = AttrVal ($name, 'ctrlWeatherDev2', ''); # Weather forecast Device 2 my $fcdev2 = AttrVal ($name, 'setupWeatherDev2', ''); # Weather forecast Device 2
($afc,$h) = parseParams ($fcdev2); ($afc,$h) = parseParams ($fcdev2);
$fcdev2 = $afc->[0] // ""; $fcdev2 = $afc->[0] // "";
my $fcdev3 = AttrVal ($name, 'ctrlWeatherDev3', ''); # Weather forecast Device 3 my $fcdev3 = AttrVal ($name, 'setupWeatherDev3', ''); # Weather forecast Device 3
($afc,$h) = parseParams ($fcdev3); ($afc,$h) = parseParams ($fcdev3);
$fcdev3 = $afc->[0] // ""; $fcdev3 = $afc->[0] // "";
@ -17143,7 +17131,7 @@ return ($err, $a->[0], $h);
} }
##################################################################### #####################################################################
# Prüft ob das in ctrlWeatherDevX # Prüft ob das in setupWeatherDevX
# übergebene Weather Device valide ist # übergebene Weather Device valide ist
# return - $valid -> ist die Angabe valide (1) # return - $valid -> ist die Angabe valide (1)
# $apiu -> wird ein Device oder API verwendet # $apiu -> wird ein Device oder API verwendet
@ -17191,13 +17179,13 @@ sub isWeatherAgeExceeded {
my ($newts, $th); my ($newts, $th);
for my $step (1..$weatherDevMax) { for my $step (1..$weatherDevMax) {
my ($valid, $fcname, $apiu) = isWeatherDevValid ($hash, 'ctrlWeatherDev'.$step); my ($valid, $fcname, $apiu) = isWeatherDevValid ($hash, 'setupWeatherDev'.$step);
next if(!$fcname && $step ne 1); next if(!$fcname && $step ne 1);
if (!$apiu) { if (!$apiu) {
if (!$fcname || !$valid) { if (!$fcname || !$valid) {
if (!$fcname) { if (!$fcname) {
return (qq{No DWD device is defined in attribute "ctrlWeatherDev$step"}, $resh); return (qq{No DWD device is defined in attribute "setupWeatherDev$step"}, $resh);
} }
else { else {
return (qq{The DWD device "$fcname" doesn't exist}, $resh); return (qq{The DWD device "$fcname" doesn't exist}, $resh);
@ -18362,7 +18350,7 @@ to ensure that the system configuration is correct.
<ul> <ul>
<table> <table>
<colgroup> <col width="25%"> <col width="75%"> </colgroup> <colgroup> <col width="25%"> <col width="75%"> </colgroup>
<tr><td> <b>ctrlWeatherDevX</b> </td><td>DWD_OpenData Device which provides meteorological data (e.g. cloud cover) </td></tr> <tr><td> <b>setupWeatherDevX</b> </td><td>DWD_OpenData Device which provides meteorological data (e.g. cloud cover) </td></tr>
<tr><td> <b>setupRadiationAPI </b> </td><td>DWD_OpenData Device or API for the delivery of radiation data. </td></tr> <tr><td> <b>setupRadiationAPI </b> </td><td>DWD_OpenData Device or API for the delivery of radiation data. </td></tr>
<tr><td> <b>setupInverterDev</b> </td><td>Device which provides PV performance data </td></tr> <tr><td> <b>setupInverterDev</b> </td><td>Device which provides PV performance data </td></tr>
<tr><td> <b>setupMeterDev</b> </td><td>Device which supplies network I/O data </td></tr> <tr><td> <b>setupMeterDev</b> </td><td>Device which supplies network I/O data </td></tr>
@ -19756,12 +19744,12 @@ to ensure that the system configuration is correct.
</li> </li>
<br> <br>
<a id="SolarForecast-attr-ctrlWeatherDev" data-pattern="ctrlWeatherDev.*"></a> <a id="SolarForecast-attr-setupWeatherDev" data-pattern="setupWeatherDev.*"></a>
<li><b>ctrlWeatherDevX </b> <br><br> <li><b>setupWeatherDevX </b> <br><br>
Specifies the device or API for providing the required weather data (cloud cover, precipitation, etc.).<br> Specifies the device or API for providing the required weather data (cloud cover, precipitation, etc.).<br>
The attribute 'ctrlWeatherDev1' specifies the leading weather service and is mandatory.<br> The attribute 'setupWeatherDev1' specifies the leading weather service and is mandatory.<br>
If an Open-Meteo API is selected in the 'ctrlWeatherDev1' attribute, this Open-Meteo service is automatically set as the If an Open-Meteo API is selected in the 'setupWeatherDev1' attribute, this Open-Meteo service is automatically set as the
source of the radiation data (Attribute setupRadiationAPI). <br><br> source of the radiation data (Attribute setupRadiationAPI). <br><br>
<b>OpenMeteoDWD-API</b> <br> <b>OpenMeteoDWD-API</b> <br>
@ -19807,9 +19795,9 @@ to ensure that the system configuration is correct.
As an alternative to Open-Meteo, an FHEM 'DWD_OpenData' device can be used to supply the weather data.<br> As an alternative to Open-Meteo, an FHEM 'DWD_OpenData' device can be used to supply the weather data.<br>
If no device of this type exists, at least one DWD_OpenData device must first be defined. If no device of this type exists, at least one DWD_OpenData device must first be defined.
(see <a href="http://fhem.de/commandref.html#DWD_OpenData">DWD_OpenData Commandref</a>). <br> (see <a href="http://fhem.de/commandref.html#DWD_OpenData">DWD_OpenData Commandref</a>). <br>
If more than one ctrlWeatherDevX is specified, the average of all weather stations is determined If more than one setupWeatherDevX is specified, the average of all weather stations is determined
if the respective value was supplied and is numerical. <br> if the respective value was supplied and is numerical. <br>
Otherwise, the data from 'ctrlWeatherDev1' is always used as the leading weather device.<br> Otherwise, the data from 'setupWeatherDev1' is always used as the leading weather device.<br>
At least these attributes must be set in the selected DWD_OpenData Device: <br><br> At least these attributes must be set in the selected DWD_OpenData Device: <br><br>
<ul> <ul>
@ -20447,7 +20435,7 @@ to ensure that the system configuration is correct.
Defines the source for the delivery of the solar radiation data. You can select a device of the type DWD_OpenData or Defines the source for the delivery of the solar radiation data. You can select a device of the type DWD_OpenData or
an implemented API can be selected. <br> an implemented API can be selected. <br>
<b>Note:</b> If OpenMeteoDWD-API is set in the 'ctrlWeatherDev1' attribute, no radiation data service other than <b>Note:</b> If OpenMeteoDWD-API is set in the 'setupWeatherDev1' attribute, no radiation data service other than
OpenMeteoDWD-API can be selected. <br><br> OpenMeteoDWD-API can be selected. <br><br>
<b>OpenMeteoDWD-API</b> <br> <b>OpenMeteoDWD-API</b> <br>
@ -20645,7 +20633,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<ul> <ul>
<table> <table>
<colgroup> <col width="25%"> <col width="75%"> </colgroup> <colgroup> <col width="25%"> <col width="75%"> </colgroup>
<tr><td> <b>ctrlWeatherDevX</b> </td><td>DWD_OpenData Device welches meteorologische Daten (z.B. Bewölkung) liefert </td></tr> <tr><td> <b>setupWeatherDevX</b> </td><td>DWD_OpenData Device welches meteorologische Daten (z.B. Bewölkung) liefert </td></tr>
<tr><td> <b>setupRadiationAPI </b> </td><td>DWD_OpenData Device bzw. API zur Lieferung von Strahlungsdaten </td></tr> <tr><td> <b>setupRadiationAPI </b> </td><td>DWD_OpenData Device bzw. API zur Lieferung von Strahlungsdaten </td></tr>
<tr><td> <b>setupInverterDev</b> </td><td>Device welches PV Leistungsdaten liefert </td></tr> <tr><td> <b>setupInverterDev</b> </td><td>Device welches PV Leistungsdaten liefert </td></tr>
<tr><td> <b>setupMeterDev</b> </td><td>Device welches Netz I/O-Daten liefert </td></tr> <tr><td> <b>setupMeterDev</b> </td><td>Device welches Netz I/O-Daten liefert </td></tr>
@ -22049,12 +22037,12 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
</li> </li>
<br> <br>
<a id="SolarForecast-attr-ctrlWeatherDev" data-pattern="ctrlWeatherDev.*"></a> <a id="SolarForecast-attr-setupWeatherDev" data-pattern="setupWeatherDev.*"></a>
<li><b>ctrlWeatherDevX </b> <br><br> <li><b>setupWeatherDevX </b> <br><br>
Gibt das Gerät oder die API zur Lieferung der erforderlichen Wetterdaten (Wolkendecke, Niederschlag usw.) an.<br> Gibt das Gerät oder die API zur Lieferung der erforderlichen Wetterdaten (Wolkendecke, Niederschlag usw.) an.<br>
Das Attribut 'ctrlWeatherDev1' definiert den führenden Wetterdienst und ist zwingend erforderlich.<br> Das Attribut 'setupWeatherDev1' definiert den führenden Wetterdienst und ist zwingend erforderlich.<br>
Ist eine Open-Meteo API im Attribut 'ctrlWeatherDev1' ausgewählt, wird dieser Open-Meteo Dienst automatisch auch als Quelle Ist eine Open-Meteo API im Attribut 'setupWeatherDev1' ausgewählt, wird dieser Open-Meteo Dienst automatisch auch als Quelle
der Strahlungsdaten (Attribut setupRadiationAPI) eingestellt. <br><br> der Strahlungsdaten (Attribut setupRadiationAPI) eingestellt. <br><br>
<b>OpenMeteoDWD-API</b> <br> <b>OpenMeteoDWD-API</b> <br>
@ -22100,9 +22088,9 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
Alternativ zu Open-Meteo kann ein FHEM 'DWD_OpenData'-Gerät zur Lieferung der Wetterdaten dienen.<br> Alternativ zu Open-Meteo kann ein FHEM 'DWD_OpenData'-Gerät zur Lieferung der Wetterdaten dienen.<br>
Ist noch kein Gerät dieses Typs vorhanden, muß zunächst mindestens ein DWD_OpenData Gerät Ist noch kein Gerät dieses Typs vorhanden, muß zunächst mindestens ein DWD_OpenData Gerät
definiert werden (siehe <a href="http://fhem.de/commandref.html#DWD_OpenData">DWD_OpenData Commandref</a>). <br> definiert werden (siehe <a href="http://fhem.de/commandref.html#DWD_OpenData">DWD_OpenData Commandref</a>). <br>
Sind mehr als ein ctrlWeatherDevX angegeben, wird der Durchschnitt aller Wetterstationen ermittelt Sind mehr als ein setupWeatherDevX angegeben, wird der Durchschnitt aller Wetterstationen ermittelt
sofern der jeweilige Wert geliefert wurde und numerisch ist. <br> sofern der jeweilige Wert geliefert wurde und numerisch ist. <br>
Anderenfalls werden immer die Daten von 'ctrlWeatherDev1' als führendes Wetterdevice genutzt. <br> Anderenfalls werden immer die Daten von 'setupWeatherDev1' als führendes Wetterdevice genutzt. <br>
Im ausgewählten DWD_OpenData Gerät müssen mindestens diese Attribute gesetzt sein: <br><br> Im ausgewählten DWD_OpenData Gerät müssen mindestens diese Attribute gesetzt sein: <br><br>
<ul> <ul>
@ -22738,7 +22726,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
Legt die Quelle zur Lieferung der solaren Strahlungsdaten fest. Es kann ein Device vom Typ DWD_OpenData oder Legt die Quelle zur Lieferung der solaren Strahlungsdaten fest. Es kann ein Device vom Typ DWD_OpenData oder
eine implementierte API eines Dienstes ausgewählt werden. <br> eine implementierte API eines Dienstes ausgewählt werden. <br>
<b>Hinweis:</b> Ist eine OpenMeteo API im Attribut 'ctrlWeatherDev1' gesetzt, kann kein anderer Strahlungsdatendienst als <b>Hinweis:</b> Ist eine OpenMeteo API im Attribut 'setupWeatherDev1' gesetzt, kann kein anderer Strahlungsdatendienst als
diese OpenMeteo API ausgewählt werden. <br><br> diese OpenMeteo API ausgewählt werden. <br><br>
<b>OpenMeteoDWD-API</b> <br> <b>OpenMeteoDWD-API</b> <br>

File diff suppressed because it is too large Load Diff