2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-07 19:04:20 +00:00

76_SolarForecast: change set currentMeterDev to attr setupMeterDev

git-svn-id: https://svn.fhem.de/fhem/trunk@28930 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2024-06-01 09:44:41 +00:00
parent 7bfba9e290
commit c3d79174bb
3 changed files with 1072 additions and 653 deletions

View File

@ -1,5 +1,6 @@
# 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
- change: 76_SolarForecast: change set currentMeterDev to attr setupMeterDev
- feature: 76_SolarForecast: ctrlStatisticReadings: new runTimeAvgDayConsumer
- change: 76_SolarForecast: ctrlDebug consumerSwitching splitted into
separated consumers, minor bug fix

View File

@ -157,6 +157,8 @@ BEGIN {
# Versions History intern
my %vNotesIntern = (
"1.22.0" => "01.06.2024 change setter currentMeterDev to attr setupMeterDev, plantConfiguration: setModel after restore ",
"1.21.5" => "30.05.2024 listDataPool: list current can operate three hash levels, first preparation for remote objects ",
"1.21.4" => "28.05.2024 __getCyclesAndRuntime: rename numberDayStarts to cycleDayNum ".
"currentRunMtsConsumer_XX: edit commandref, Consumers: replace avgruntime by runtimeAvgDay ".
"ctrlStatisticReadings: new runTimeAvgDayConsumer_XX, pvHistory: new key avgcycmntscsmXX",
@ -489,7 +491,6 @@ my @fs = qw( ftui_forecast.css
my @rconfigs = qw( pvCorrectionFactor_Auto
currentBatteryDev
currentInverterDev
currentMeterDev
currentRadiationAPI
inverterStrings
moduleAzimuth
@ -521,6 +522,7 @@ my @aconfigs = qw( affect70percentRule affectBatteryPreferredCharge affectConsFo
graphicHeaderDetail graphicHeaderShow graphicHistoryHour graphicHourCount graphicHourStyle
graphicLayoutType graphicSelect graphicShowDiff graphicShowNight graphicShowWeather
graphicSpaceSize graphicStartHtml graphicEndHtml graphicWeatherColor graphicWeatherColorNight
setupMeterDev
);
for my $cinit (1..$maxconsumer) {
@ -542,7 +544,6 @@ my %hset = ( # Ha
inverterStrings => { fn => \&_setinverterStrings },
clientAction => { fn => \&_setclientAction },
currentInverterDev => { fn => \&_setinverterDevice },
currentMeterDev => { fn => \&_setmeterDevice },
currentBatteryDev => { fn => \&_setbatteryDevice },
energyH4Trigger => { fn => \&_setTrigger },
plantConfiguration => { fn => \&_setplantConfiguration },
@ -603,6 +604,7 @@ my %hattr = ( # H
ctrlWeatherDev1 => { fn => \&_attrWeatherDev },
ctrlWeatherDev2 => { fn => \&_attrWeatherDev },
ctrlWeatherDev3 => { fn => \&_attrWeatherDev },
setupMeterDev => { fn => \&_attrMeterDev },
);
my %htr = ( # Hash even/odd für <tr>
@ -651,8 +653,8 @@ my %hqtxt = (
DE => qq{Bitte geben sie den Strahlungsvorhersage Dienst mit "set LINK currentRadiationAPI" an} },
cid => { EN => qq{Please specify the Inverter device with "set LINK currentInverterDev"},
DE => qq{Bitte geben sie das Wechselrichter Device mit "set LINK currentInverterDev" an} },
mid => { EN => qq{Please specify the device for energy measurement with "set LINK currentMeterDev"},
DE => qq{Bitte geben sie das Device zur Energiemessung mit "set LINK currentMeterDev" an} },
mid => { EN => qq{Please specify the device for energy measurement with "attr LINK setupMeterDev"},
DE => qq{Bitte geben sie das Device zur Energiemessung mit "attr LINK setupMeterDev" an} },
ist => { EN => qq{Please define all of your used string names with "set LINK inverterStrings"},
DE => qq{Bitte geben sie alle von Ihnen verwendeten Stringnamen mit "set LINK inverterStrings" an} },
mps => { EN => qq{Please enter the DC peak power of each string with "set LINK modulePeakString"},
@ -1094,6 +1096,7 @@ my %hfspvh = (
# Information zu verwendeten internen Datenhashes
# $data{$type}{$name}{circular} # Ringspeicher
# $data{$type}{$name}{current} # current values
# $data{$type}{$name}{current}{x_remote} # Steuerung und Werte remote Devices
# $data{$type}{$name}{pvhist} # historische Werte
# $data{$type}{$name}{nexthours} # NextHours Werte
# $data{$type}{$name}{consumers} # Consumer Hash
@ -1210,6 +1213,7 @@ sub Initialize {
"graphicEndHtml ".
"graphicWeatherColor:colorpicker,RGB ".
"graphicWeatherColorNight:colorpicker,RGB ".
"setupMeterDev:textField-long ".
$consumer.
$readingFnAttributes;
@ -1463,7 +1467,6 @@ sub Set {
"currentRadiationAPI:$rdd ".
"currentBatteryDev:textField-long ".
"currentInverterDev:textField-long ".
"currentMeterDev:textField-long ".
"energyH4Trigger:textField-long ".
"inverterStrings ".
"modulePeakString ".
@ -1861,56 +1864,6 @@ sub _setinverterStrings { ## no critic "not used"
return $ret;
}
################################################################
# Setter currentMeterDev
################################################################
sub _setmeterDevice { ## no critic "not used"
my $paref = shift;
my $hash = $paref->{hash};
my $name = $paref->{name};
my $type = $paref->{type};
my $opt = $paref->{opt};
my $arg = $paref->{arg};
if (!$arg) {
return qq{The command "$opt" needs an argument !};
}
my ($err, $medev, $h) = isDeviceValid ( { name => $name, obj => $arg, method => 'string' } );
return $err if($err);
if (!$h->{gcon} || !$h->{contotal} || !$h->{gfeedin} || !$h->{feedtotal}) {
return qq{The syntax of "$opt" is not correct. Please consider the commandref.};
}
if ($h->{gcon} eq "-gfeedin" && $h->{gfeedin} eq "-gcon") {
return qq{Incorrect input. It is not allowed that the keys gcon and gfeedin refer to each other.};
}
if ($h->{conprice}) { # Bezugspreis (Arbeitspreis) pro kWh
my @acp = split ":", $h->{conprice};
return qq{Incorrect input for key 'conprice'. Please consider the commandref.} if(scalar(@acp) != 2 && scalar(@acp) != 3);
}
if ($h->{feedprice}) { # Einspeisevergütung pro kWh
my @afp = split ":", $h->{feedprice};
return qq{Incorrect input for key 'feedprice'. Please consider the commandref.} if(scalar(@afp) != 2 && scalar(@afp) != 3);
}
## alte Speicherwerte löschen
###############################
delete $data{$type}{$name}{circular}{'99'}{feedintotal};
delete $data{$type}{$name}{circular}{'99'}{initdayfeedin};
delete $data{$type}{$name}{circular}{'99'}{gridcontotal};
delete $data{$type}{$name}{circular}{'99'}{initdaygcon};
readingsSingleUpdate ($hash, 'currentMeterDev', $arg, 1);
createAssociatedWith ($hash);
writeCacheToFile ($hash, 'plantconfig', $plantcfg.$name); # Anlagenkonfiguration File schreiben
return;
}
################################################################
# Setter currentBatteryDev
################################################################
@ -2168,6 +2121,7 @@ sub _setplantConfiguration { ## no critic "not used"
if (!$err) {
if ($nr || $na) {
setModel ($hash);
return qq{Plant Configuration restored from file "$plantcfg.$name". Number of restored Readings/Attributes: $nr/$na};
}
else {
@ -2449,7 +2403,6 @@ sub _setreset { ## no critic "not used"
if ($prop eq 'currentMeterSet') {
readingsDelete ($hash, "Current_GridConsumption");
readingsDelete ($hash, "Current_GridFeedIn");
readingsDelete ($hash, 'currentMeterDev');
delete $data{$type}{$name}{circular}{'99'}{initdayfeedin};
delete $data{$type}{$name}{circular}{'99'}{gridcontotal};
delete $data{$type}{$name}{circular}{'99'}{initdaygcon};
@ -2461,6 +2414,11 @@ sub _setreset { ## no critic "not used"
delete $data{$type}{$name}{current}{autarkyrate};
delete $data{$type}{$name}{current}{selfconsumption};
delete $data{$type}{$name}{current}{selfconsumptionrate};
delete $data{$type}{$name}{current}{eFeedInTariff};
delete $data{$type}{$name}{current}{eFeedInTariffCcy};
delete $data{$type}{$name}{current}{ePurchasePrice};
delete $data{$type}{$name}{current}{ePurchasePriceCcy};
delete $data{$type}{$name}{current}{x_remote};
writeCacheToFile ($hash, "plantconfig", $plantcfg.$name); # Anlagenkonfiguration File schreiben
}
@ -4671,7 +4629,7 @@ sub _getlistCurrent {
my $hash = $paref->{hash};
my $ret = listDataPool ($hash, 'current');
$ret .= lineFromSpaces ($ret, 5);
$ret .= lineFromSpaces ($ret, 30);
return $ret;
}
@ -5595,7 +5553,7 @@ sub _attrconsumer { ## no critic "not used"
delete $data{$type}{$name}{consumers}{$c}; # Consumer Hash Verbraucher löschen
}
writeCacheToFile ($hash, "consumers", $csmcache.$name); # Cache File Consumer schreiben
writeCacheToFile ($hash, 'consumers', $csmcache.$name); # Cache File Consumer schreiben
$data{$type}{$name}{current}{consumerCollected} = 0; # Consumer neu sammeln
@ -5677,6 +5635,52 @@ sub _attrctrlDebug { ## no critic "not used"
return;
}
################################################################
# Attr setupMeterDev
################################################################
sub _attrMeterDev { ## no critic "not used"
my $paref = shift;
my $hash = $paref->{hash};
my $name = $paref->{name};
my $aVal = $paref->{aVal};
my $aName = $paref->{aName};
my $type = $paref->{type};
return if(!$init_done);
if ($paref->{cmd} eq 'set' ) {
my ($err, $medev, $h) = isDeviceValid ( { name => $name, obj => $aVal, method => 'string' } );
return $err if($err);
if (!$h->{gcon} || !$h->{contotal} || !$h->{gfeedin} || !$h->{feedtotal}) {
return qq{The syntax of "$aName" is not correct. Please consider the commandref.};
}
if ($h->{gcon} eq "-gfeedin" && $h->{gfeedin} eq "-gcon") {
return qq{Incorrect input. It is not allowed that the keys gcon and gfeedin refer to each other.};
}
if ($h->{conprice}) { # Bezugspreis (Arbeitspreis) pro kWh
my @acp = split ":", $h->{conprice};
return qq{Incorrect input for key 'conprice'. Please consider the commandref.} if(scalar(@acp) != 2 && scalar(@acp) != 3);
}
if ($h->{feedprice}) { # Einspeisevergütung pro kWh
my @afp = split ":", $h->{feedprice};
return qq{Incorrect input for key 'feedprice'. Please consider the commandref.} if(scalar(@afp) != 2 && scalar(@afp) != 3);
}
}
if ($paref->{cmd} eq 'del' ) {
delete $data{$type}{$name}{current}{x_remote};
}
InternalTimer (gettimeofday()+2, 'FHEM::SolarForecast::createAssociatedWith', $hash, 0);
InternalTimer (gettimeofday()+3, 'FHEM::SolarForecast::writeCacheToFile', [$name, 'plantconfig', $plantcfg.$name], 0); # Anlagenkonfiguration File schreiben
return;
}
################################################################
# Attr ctrlWeatherDevX
################################################################
@ -5724,16 +5728,16 @@ sub _attrgraphicBeamXContent { ## no critic "not used"
return if(!$init_done);
my $medev = ReadingsVal ($name, "currentMeterDev", ""); # aktuelles Meter device
my $medev = AttrVal ($name, 'setupMeterDev', ''); # aktuelles Meter device
my ($a,$h) = parseParams ($medev);
if ($cmd eq "set") {
if ($cmd eq 'set') {
if ($aVal eq 'energycosts') {
return "Define key 'conprice' in the currentMeterDev first before setting $aVal" if(!defined $h->{conprice});
return "Define key 'conprice' in the setupMeterDev attribute first before setting $aVal" if(!defined $h->{conprice});
}
if ($aVal eq 'feedincome') {
return "Define key 'feedprice' in the currentMeterDev first before setting $aVal" if(!defined $h->{feedprice});
return "Define key 'feedprice' in the setupMeterDev attribute first before setting $aVal" if(!defined $h->{feedprice});
}
}
@ -6063,7 +6067,17 @@ sub writeCacheToFile {
my $cachename = shift;
my $file = shift;
my $name = $hash->{NAME};
my $name;
if (ref $hash eq 'HASH') {
$name = $hash->{NAME};
}
elsif (ref $hash eq 'ARRAY') { # Array Referenz wurde übergeben
$name = $hash->[0];
$cachename = $hash->[1];
$file = $hash->[2];
$hash = $defs{$name};
}
my $type = $hash->{TYPE};
my @data;
@ -6390,7 +6404,11 @@ sub centralTask {
### nicht mehr benötigte Daten verarbeiten - Bereich kann später wieder raus !!
##########################################################################################################################
my $val = ReadingsVal ($name, 'currentMeterDev', ''); # 01.06.2024
if ($val) {
CommandAttr (undef, "$name setupMeterDev $val");
readingsDelete ($hash, 'currentMeterDev');
}
##########################################################################################################################
setModel ($hash); # Model setzen
@ -6450,6 +6468,7 @@ sub centralTask {
$centpars->{state} = 'updated'; # kann durch Subs überschrieben werden!
_composeRemoteObj ($centpars); # Remote Objekte identifizieren und zusammenstellen
_collectAllRegConsumers ($centpars); # alle Verbraucher Infos laden
_specialActivities ($centpars); # zusätzliche Events generieren + Sonderaufgaben
_transferWeatherValues ($centpars); # Wetterwerte übertragen
@ -6679,6 +6698,92 @@ sub controller {
return ($interval, $disabled, $inactive);
}
#####################################################################
# Remote Objekte identifizieren und zusammenstellen
# <Device>@fhem.myds.me:8088/api/
#####################################################################
sub _composeRemoteObj {
my $paref = shift;
my $name = $paref->{name};
$paref->{obj} = 'setupMeterDev';
$paref->{method} = 'attr';
__remoteMeterObj ($paref);
delete $paref->{method};
delete $paref->{obj};
return;
}
#####################################################################
# Remote Meter Objekt identifizieren und zusammenstellen
#####################################################################
sub __remoteMeterObj {
my $paref = shift;
my $name = $paref->{name};
my $type = $paref->{type};
my $obj = $paref->{obj};
my $method = $paref->{method} // return qq{no extraction method for Object '$obj' defined};
my $err = '';
my $dev = '';
my $rem = '';
my @acp = ();
my @afp = ();
if ($method eq 'reading') {
$dev = ReadingsVal ($name, $obj, '');
return qq{Reading '$obj' is not set or is empty} if(!$dev);
}
elsif ($method eq 'attr') {
$dev = AttrVal ($name, $obj, '');
return qq{Attribute '$obj' is not set} if(!$dev);
}
elsif ($method eq 'string') {
return qq{Object '$obj' is empty} if(!$obj);
$dev = $obj;
}
my ($a, $h) = parseParams ($dev);
$dev = $a->[0]; # das Device aus dem Object
($dev, $rem) = split '@', $dev; # Meterdev extrahieren
return if(!$rem); # keine remote Devicekonfiguration
my ($server, $infix) = split '/', $rem;
my $gc = (split ":", $h->{gcon})[0]; # Readingname für aktuellen Netzbezug
my $gf = (split ":", $h->{gfeedin})[0]; # Readingname für aktuelle Netzeinspeisung
my $gt = (split ":", $h->{contotal})[0]; # Readingname für Bezug total
my $ft = (split ":", $h->{feedtotal})[0]; # Readingname für Einspeisung total
@acp = split ":", $h->{conprice} if($h->{conprice});
@afp = split ":", $h->{feedprice} if($h->{feedprice});
$data{$type}{$name}{current}{x_remote}{$dev}{server} = $server;
$data{$type}{$name}{current}{x_remote}{$dev}{infix} = $infix;
$data{$type}{$name}{current}{x_remote}{$dev}{readings}{$gt} = undef;
$data{$type}{$name}{current}{x_remote}{$dev}{readings}{$ft} = undef;
$data{$type}{$name}{current}{x_remote}{$dev}{readings}{$gc} = undef if($h->{gcon} ne '-gfeedin');
$data{$type}{$name}{current}{x_remote}{$dev}{readings}{$gf} = undef if($h->{gfeedin} ne '-gcon');
if (scalar(@acp) == 2) {
$data{$type}{$name}{current}{x_remote}{$dev}{readings}{$acp[0]} = undef; # conprice wird durch Reading im Meterdev geliefert
}
elsif (scalar(@acp) == 3) { # conprice wird durch weiteres Device / Reading geliefert
$data{$type}{$name}{current}{x_remote}{$acp[0]}{readings}{$acp[1]} = undef;
}
if (scalar(@afp) == 2) {
$data{$type}{$name}{current}{x_remote}{$dev}{readings}{$afp[0]} = undef; # feedprice wird durch Reading im Meterdev geliefert
}
elsif (scalar(@afp) == 3) { # feedprice wird durch weiteres Device / Reading geliefert
$data{$type}{$name}{current}{x_remote}{$afp[0]}{readings}{$afp[1]} = undef;
}
return;
}
################################################################
# Grunddaten aller registrierten Consumer speichern
################################################################
@ -7998,7 +8103,7 @@ sub _transferMeterValues {
my $t = $paref->{t};
my $chour = $paref->{chour};
my ($err, $medev, $h) = isDeviceValid ( { name => $name, obj => 'currentMeterDev', method => 'reading' } );
my ($err, $medev, $h) = isDeviceValid ( { name => $name, obj => 'setupMeterDev', method => 'attr' } );
return if($err);
my $type = $paref->{type};
@ -8019,8 +8124,7 @@ sub _transferMeterValues {
$data{$type}{$name}{current}{ePurchasePrice} = ReadingsNum ($acp[0], $acp[1], 0);
$data{$type}{$name}{current}{ePurchasePriceCcy} = $acp[2];
}
if (scalar(@acp) == 2) {
elsif (scalar(@acp) == 2) {
if (isNumeric($acp[0])) {
$data{$type}{$name}{current}{ePurchasePrice} = $acp[0];
$data{$type}{$name}{current}{ePurchasePriceCcy} = $acp[1];
@ -8046,8 +8150,7 @@ sub _transferMeterValues {
$data{$type}{$name}{current}{eFeedInTariff} = ReadingsNum ($afp[0], $afp[1], 0);
$data{$type}{$name}{current}{eFeedInTariffCcy} = $afp[2];
}
if (scalar(@afp) == 2) {
elsif (scalar(@afp) == 2) {
if (isNumeric($afp[0])) {
$data{$type}{$name}{current}{eFeedInTariff} = $afp[0];
$data{$type}{$name}{current}{eFeedInTariffCcy} = $afp[1];
@ -8079,7 +8182,7 @@ sub _transferMeterValues {
my $params;
if ($gc eq "-gfeedin") { # Spezialfall gcon bei neg. gfeedin # Spezialfall: bei negativen gfeedin -> $gco = abs($gf), $gf = 0
if ($gc eq '-gfeedin') { # Spezialfall gcon bei neg. gfeedin # Spezialfall: bei negativen gfeedin -> $gco = abs($gf), $gf = 0
$params = {
dev => $medev,
rdg => $gf,
@ -8089,7 +8192,7 @@ sub _transferMeterValues {
($gfin,$gco) = substSpecialCases ($params);
}
if ($gf eq "-gcon") { # Spezialfall gfeedin bei neg. gcon
if ($gf eq '-gcon') { # Spezialfall gfeedin bei neg. gcon
$params = {
dev => $medev,
rdg => $gc,
@ -10245,8 +10348,8 @@ sub _estConsumptionForecast {
my $dayname = $paref->{dayname}; # aktueller Tagname
my ($err, $medev, $h) = isDeviceValid ( { name => $name,
obj => 'currentMeterDev',
method => 'reading',
obj => 'setupMeterDev',
method => 'attr',
}
); # aktuelles Meter device
return if($err);
@ -11401,7 +11504,7 @@ sub _checkSetupNotComplete {
my $wedev = AttrVal ($name, 'ctrlWeatherDev1', undef); # Device Vorhersage Wetterdaten (Bewölkung etc.)
my $radev = ReadingsVal ($name, 'currentRadiationAPI', undef); # Device Strahlungsdaten Vorhersage
my $indev = ReadingsVal ($name, 'currentInverterDev', undef); # Inverter Device
my $medev = ReadingsVal ($name, 'currentMeterDev', undef); # Meter Device
my $medev = AttrVal ($name, 'setupMeterDev', undef); # Meter Device
my $peaks = ReadingsVal ($name, 'modulePeakString', undef); # String Peak
my $maz = ReadingsVal ($name, 'moduleAzimuth', undef); # Modulausrichtung Konfig (Azimut)
@ -14818,7 +14921,7 @@ sub listDataPool {
my $cret;
for my $ckey (sort keys %{$h->{$idx}}) {
if(ref $h->{$idx}{$ckey} eq "HASH") {
if (ref $h->{$idx}{$ckey} eq 'HASH') {
my $hk = qq{};
for my $f (sort {$a<=>$b} keys %{$h->{$idx}{$ckey}}) {
$hk .= " " if($hk);
@ -14977,14 +15080,50 @@ sub listDataPool {
if (!keys %{$h}) {
return qq{Current values cache is empty.};
}
for my $idx (sort keys %{$h}) {
if (ref $h->{$idx} ne "ARRAY") {
$sq .= $idx." => ".(defined $h->{$idx} ? $h->{$idx} : '')."\n";
}
else {
if (ref $h->{$idx} eq 'ARRAY') {
my $aser = join " ",@{$h->{$idx}};
$sq .= $idx." => ".$aser."\n";
}
elsif (ref $h->{$idx} eq 'HASH') {
my $s1;
my $sp1 = _ldpspaces ($idx, q{});
$sq .= $idx." => ";
for my $idx1 (sort keys %{$h->{$idx}}) {
if (ref $h->{$idx}{$idx1} eq 'HASH') {
my $s2;
my $sp2 = _ldpspaces ($idx1, $sp1);
$sq .= ($s1 ? $sp1 : "").$idx1." => ";
for my $idx2 (sort keys %{$h->{$idx}{$idx1}}) {
my $s3;
my $sp3 = _ldpspaces ($idx2, $sp2);
$sq .= ($s2 ? $sp2 : "").$idx2." => ";
if (ref $h->{$idx}{$idx1}{$idx2} eq 'HASH') {
for my $idx3 (sort keys %{$h->{$idx}{$idx1}{$idx2}}) {
$sq .= ($s3 ? $sp3 : "").$idx3." => ".(defined $h->{$idx}{$idx1}{$idx2}{$idx3} ? $h->{$idx}{$idx1}{$idx2}{$idx3} : '')."\n";
$s3 = 1;
}
}
else {
$sq .= (defined $h->{$idx}{$idx1}{$idx2} ? $h->{$idx}{$idx1}{$idx2} : '')."\n";
}
$s1 = 1;
$s2 = 1;
}
}
else {
$sq .= (defined $h->{$idx}{$idx1} ? $h->{$idx}{$idx1} : '')."\n";
}
}
}
else {
$sq .= $idx." => ".(defined $h->{$idx} ? $h->{$idx} : '')."\n";
}
}
}
@ -15016,7 +15155,7 @@ sub listDataPool {
while (my ($tag, $item) = each %{$git->($itref->{$idx})}) {
$sq .= ($s1 ? $sp1 : "").$tag." => ";
if (ref $item eq "HASH") {
if (ref $item eq 'HASH') {
my $s2;
my $sp2 = _ldpspaces ($tag, $sp1);
@ -16012,7 +16151,7 @@ sub createAssociatedWith {
my $name = $hash->{NAME};
my $type = $hash->{TYPE};
RemoveInternalTimer($hash, "FHEM::SolarForecast::createAssociatedWith");
RemoveInternalTimer ($hash, 'FHEM::SolarForecast::createAssociatedWith');
if ($init_done) {
my (@cd, @nd);
@ -16038,7 +16177,7 @@ sub createAssociatedWith {
($ain,$h) = parseParams ($indev);
$indev = $ain->[0] // "";
my $medev = ReadingsVal($name, 'currentMeterDev', ''); # Meter Device
my $medev = AttrVal ($name, 'setupMeterDev', ''); # Meter Device
($ame,$h) = parseParams ($medev);
$medev = $ame->[0] // "";
@ -16085,7 +16224,7 @@ sub createAssociatedWith {
}
}
else {
InternalTimer(gettimeofday()+3, "FHEM::SolarForecast::createAssociatedWith", $hash, 0);
InternalTimer (gettimeofday() + 3, 'FHEM::SolarForecast::createAssociatedWith', $hash, 0);
}
return;
@ -16777,6 +16916,11 @@ sub isDeviceValid {
my ($a, $h) = parseParams ($dev);
if ($a->[0] && $a->[0] =~ /\@/xs ) { # Remote Device
$a->[0] = (split '@', $a->[0])[0];
return ($err, $a->[0], $h); # ToDo: $h aus remote Werten anreichern
}
if (!$a->[0] || !$defs{$a->[0]}) {
$a->[0] //= '';
$err = qq{The device '$a->[0]' doesn't exist or is not a valid device.};
@ -17964,19 +18108,19 @@ To create the solar forecast, the SolarForecast module can use different service
<ul>
<table>
<colgroup> <col width="25%"> <col width="75%"> </colgroup>
<tr><td> <b>DWD</b> </td><td>solar forecast based on the radiation forecast of the German Weather Service (Model DWD) </td></tr>
<tr><td> <b>SolCast-API </b> </td><td>uses forecast data of the <a href='https://toolkit.solcast.com.au/rooftop-sites/' target='_blank'>SolCast API</a> (Model SolCastAPI) </td></tr>
<tr><td> <b>ForecastSolar-API</b> </td><td>uses forecast data of the <a href='https://doc.forecast.solar/api' target='_blank'>Forecast.Solar API</a> (Model ForecastSolarAPI) </td></tr>
<tr><td> <b>VictronKI-API</b> </td><td>Victron Energy API of the <a href='https://www.victronenergy.com/blog/2023/07/05/new-vrm-solar-production-forecast-feature/' target='_blank'>VRM Portal</a> (Model VictronKiAPI) </td></tr>
<tr><td> <b>DWD</b> </td><td>solar forecast based on MOSMIX data of the German Weather Service </td></tr>
<tr><td> <b>SolCast-API </b> </td><td>uses forecast data of the <a href='https://toolkit.solcast.com.au/rooftop-sites/' target='_blank'>SolCast API</a> </td></tr>
<tr><td> <b>ForecastSolar-API</b> </td><td>uses forecast data of the <a href='https://doc.forecast.solar/api' target='_blank'>Forecast.Solar API</a> </td></tr>
<tr><td> <b>OpenMeteoDWD-API</b> </td><td>ICON weather models of the German Weather Service (DWD) via <a href='https://open-meteo.com/en/docs/dwd-api' target='_blank'>Open-Meteo</a> </td></tr>
<tr><td> <b>OpenMeteoDWDEnsemble-API</b> </td><td>Access to the <a href='https://www.dwd.de/DE/forschung/wettervorhersage/num_modellierung/04_ensemble_methoden/ensemble_vorhersage/ensemble_vorhersagen.html' target='_blank'>global ensemble forecast system (EPS)</a> of the DWD </td></tr>
<tr><td> <b>OpenMeteoWorld-API</b> </td><td>Seamlessly combines weather models from organizations such as NOAA, DWD, CMCC and ECMWF via <a href='https://open-meteo.com/en/docs' target='_blank'>Open-Meteo</a> </td></tr>
<tr><td> <b>VictronKI-API</b> </td><td>Victron Energy API of the <a href='https://www.victronenergy.com/blog/2023/07/05/new-vrm-solar-production-forecast-feature/' target='_blank'>VRM Portal</a> </td></tr>
</table>
</ul>
<br>
AI support can be enabled when using the Model DWD. <br>
The use of the mentioned API's is limited to the respective free version of the selected service. <br>
In the assigned DWD_OpenData Device (attribute "ctrlWeatherDevX") the suitable weather station is to be specified
to get meteorological data (cloudiness, sunrise, etc.) or a radiation forecast (Model DWD) for the plant
location. <br><br>
AI support can be activated depending on the model used. <br><br>
In addition to the PV generation forecast, consumption values or grid reference values are recorded and used for a
consumption forecast. <br>
@ -18003,7 +18147,7 @@ to ensure that the system configuration is correct.
<br>
After the definition of the device, depending on the forecast sources used, it is mandatory to store additional
plant-specific information with the corresponding set commands. <br>
plant-specific information. <br>
The following set commands and attributes are used to store information that is relevant for the function of the
module: <br><br>
@ -18013,7 +18157,7 @@ to ensure that the system configuration is correct.
<tr><td> <b>ctrlWeatherDevX</b> </td><td>DWD_OpenData Device which provides meteorological data (e.g. cloud cover) </td></tr>
<tr><td> <b>currentRadiationAPI </b> </td><td>DWD_OpenData Device or API for the delivery of radiation data. </td></tr>
<tr><td> <b>currentInverterDev</b> </td><td>Device which provides PV performance data </td></tr>
<tr><td> <b>currentMeterDev</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>
<tr><td> <b>currentBatteryDev</b> </td><td>Device which provides battery performance data (if available) </td></tr>
<tr><td> <b>inverterStrings</b> </td><td>Identifier of the existing plant strings </td></tr>
<tr><td> <b>moduleAzimuth</b> </td><td>Azimuth of the plant strings </td></tr>
@ -18229,65 +18373,6 @@ to ensure that the system configuration is correct.
</ul>
<br>
<ul>
<a id="SolarForecast-set-currentMeterDev"></a>
<li><b>currentMeterDev &lt;Meter Device Name&gt; gcon=&lt;Readingname&gt;:&lt;Unit&gt; contotal=&lt;Readingname&gt;:&lt;Unit&gt;
gfeedin=&lt;Readingname&gt;:&lt;Unit&gt; feedtotal=&lt;Readingname&gt;:&lt;Unit&gt;
[conprice=&lt;Field&gt;] [feedprice=&lt;Field&gt;] </b> <br><br>
Sets any device and its readings for energy measurement.
The module assumes that the numeric value of the readings is positive.
It can also be a dummy device with corresponding readings. The meaning of the respective "Readingname" is:
<br><br>
<ul>
<table>
<colgroup> <col width="15%"> <col width="85%"> </colgroup>
<tr><td> <b>gcon</b> </td><td>Reading which supplies the power currently drawn from the grid </td></tr>
<tr><td> <b>contotal</b> </td><td>Reading which provides the sum of the energy drawn from the grid (a constantly increasing meter) </td></tr>
<tr><td> </td><td>If the counter is reset to '0' at the beginning of the day (daily counter), the module handles this situation accordingly.</td></tr>
<tr><td> </td><td>In this case, a message is displayed in the log with verbose 3. </td></tr>
<tr><td> <b>gfeedin</b> </td><td>Reading which supplies the power currently fed into the grid </td></tr>
<tr><td> <b>feedtotal</b> </td><td>Reading which provides the sum of the energy fed into the grid (a constantly increasing meter) </td></tr>
<tr><td> </td><td>If the counter is reset to '0' at the beginning of the day (daily counter), the module handles this situation accordingly.</td></tr>
<tr><td> </td><td>In this case, a message is displayed in the log with verbose 3. </td></tr>
<tr><td> <b>Unit</b> </td><td>the respective unit (W,kW,Wh,kWh) </td></tr>
<tr><td> </td><td> </td></tr>
<tr><td> <b>conprice</b> </td><td>Price for the purchase of one kWh (optional). The &lt;field&gt; can be specified in one of the following variants: </td></tr>
<tr><td> </td><td>&lt;Price&gt;:&lt;Currency&gt; - Price as a numerical value and its currency </td></tr>
<tr><td> </td><td>&lt;Reading&gt;:&lt;Currency&gt; - Reading of the <b>meter device</b> that contains the price : Currency </td></tr>
<tr><td> </td><td>&lt;Device&gt;:&lt;Reading&gt;:&lt;Currency&gt; - any device and reading containing the price : Currency </td></tr>
<tr><td> </td><td> </td></tr>
<tr><td> <b>feedprice</b> </td><td>Remuneration for the feed-in of one kWh (optional). The &lt;field&gt; can be specified in one of the following variants: </td></tr>
<tr><td> </td><td>&lt;Remuneration&gt;:&lt;Currency&gt; - Remuneration as a numerical value and its currency </td></tr>
<tr><td> </td><td>&lt;Reading&gt;:&lt;Currency&gt; - Reading of the <b>meter device</b> that contains the remuneration : Currency </td></tr>
<tr><td> </td><td>&lt;Device&gt;:&lt;Reading&gt;:&lt;Currency&gt; - any device and reading containing the remuneration : Currency </td></tr>
</table>
</ul>
<br>
<b>Special cases:</b> If the reading for gcon and gfeedin should be identical but signed,
the keys gfeedin and gcon can be defined as follows: <br><br>
<ul>
gfeedin=-gcon &nbsp;&nbsp;&nbsp;(a negative value of gcon is used as gfeedin) <br>
gcon=-gfeedin &nbsp;&nbsp;&nbsp;(a negative value of gfeedin is used as gcon)
</ul>
<br>
The unit is omitted in the particular special case. <br><br>
<ul>
<b>Example: </b> <br>
set &lt;name&gt; currentMeterDev Meter gcon=Wirkleistung:W contotal=BezWirkZaehler:kWh gfeedin=-gcon feedtotal=EinWirkZaehler:kWh conprice=powerCost: feedprice=0.1269: <br>
<br>
# Device Meter provides the current grid reference in the reading "Wirkleistung" (W),
the sum of the grid reference in the reading "BezWirkZaehler" (kWh), the current feed in "Wirkleistung" if "Wirkleistung" is negative,
the sum of the feed in the reading "EinWirkZaehler". (kWh)
</ul>
</li>
</ul>
<br>
<ul>
<a id="SolarForecast-set-currentRadiationAPI"></a>
<li><b>currentRadiationAPI </b> <br><br>
@ -18979,7 +19064,7 @@ to ensure that the system configuration is correct.
<tr><td> <b>batsetsoc</b> </td><td>optimum SOC setpoint (%) for the day </td></tr>
<tr><td> <b>confc</b> </td><td>expected energy consumption (Wh) </td></tr>
<tr><td> <b>con</b> </td><td>real energy consumption (Wh) of the house </td></tr>
<tr><td> <b>conprice</b> </td><td>Price for the purchase of one kWh. The currency of the price is defined in the currentMeterDev. </td></tr>
<tr><td> <b>conprice</b> </td><td>Price for the purchase of one kWh. The currency of the price is defined in the setupMeterDev. </td></tr>
<tr><td> <b>csmtXX</b> </td><td>total energy consumption of ConsumerXX </td></tr>
<tr><td> <b>csmeXX</b> </td><td>Energy consumption of ConsumerXX in the hour of the day (hour 99 = daily energy consumption) </td></tr>
<tr><td> <b>cyclescsmXX</b> </td><td>Number of active cycles of ConsumerXX of the day </td></tr>
@ -18987,7 +19072,7 @@ to ensure that the system configuration is correct.
<tr><td> <b>etotal</b> </td><td>total energy yield (Wh) at the beginning of the hour </td></tr>
<tr><td> <b>gcon</b> </td><td>real power consumption (Wh) from the electricity grid </td></tr>
<tr><td> <b>gfeedin</b> </td><td>real feed-in (Wh) into the electricity grid </td></tr>
<tr><td> <b>feedprice</b> </td><td>Remuneration for the feed-in of one kWh. The currency of the price is defined in the currentMeterDev. </td></tr>
<tr><td> <b>feedprice</b> </td><td>Remuneration for the feed-in of one kWh. The currency of the price is defined in the setupMeterDev. </td></tr>
<tr><td> <b>hourscsmeXX</b> </td><td>total active hours of the day from ConsumerXX </td></tr>
<tr><td> <b>minutescsmXX</b> </td><td>total active minutes in the hour of ConsumerXX </td></tr>
<tr><td> <b>pvfc</b> </td><td>the predicted PV yield (Wh) </td></tr>
@ -19924,8 +20009,8 @@ to ensure that the system configuration is correct.
<colgroup> <col width="20%"> <col width="80%"> </colgroup>
<tr><td> <b>consumption</b> </td><td>Energy consumption </td></tr>
<tr><td> <b>consumptionForecast</b> </td><td>forecasted energy consumption </td></tr>
<tr><td> <b>energycosts</b> </td><td>Cost of energy purchased from the grid. The currency is defined in the currentMeterDev, key conprice. </td></tr>
<tr><td> <b>feedincome</b> </td><td>Remuneration for feeding into the grid. The currency is defined in the currentMeterDev, key feedprice. </td></tr>
<tr><td> <b>energycosts</b> </td><td>Cost of energy purchased from the grid. The currency is defined in the setupMeterDev, key conprice. </td></tr>
<tr><td> <b>feedincome</b> </td><td>Remuneration for feeding into the grid. The currency is defined in the setupMeterDev, key feedprice. </td></tr>
<tr><td> <b>gridconsumption</b> </td><td>Energy purchase from the public grid </td></tr>
<tr><td> <b>gridfeedin</b> </td><td>Feed into the public grid </td></tr>
<tr><td> <b>pvReal</b> </td><td>real PV generation (default for graphicBeam1Content) </td></tr>
@ -19935,7 +20020,7 @@ to ensure that the system configuration is correct.
<br>
<b>Hinweis:</b> The selection of the parameters energycosts and feedincome only makes sense if the optional keys
conprice and feedprice are set in currentMeterDev.
conprice and feedprice are set in setupMeterDev.
</li>
<br>
@ -20217,6 +20302,63 @@ to ensure that the system configuration is correct.
</li>
<br>
<a id="SolarForecast-attr-setupMeterDev"></a>
<li><b>setupMeterDev &lt;Meter Device Name&gt; gcon=&lt;Readingname&gt;:&lt;Unit&gt; contotal=&lt;Readingname&gt;:&lt;Unit&gt;
gfeedin=&lt;Readingname&gt;:&lt;Unit&gt; feedtotal=&lt;Readingname&gt;:&lt;Unit&gt;
[conprice=&lt;Field&gt;] [feedprice=&lt;Field&gt;] </b> <br><br>
Sets any device and its readings for energy measurement.
The module assumes that the numeric value of the readings is positive.
It can also be a dummy device with corresponding readings. The meaning of the respective "Readingname" is:
<br><br>
<ul>
<table>
<colgroup> <col width="15%"> <col width="85%"> </colgroup>
<tr><td> <b>gcon</b> </td><td>Reading which supplies the power currently drawn from the grid </td></tr>
<tr><td> <b>contotal</b> </td><td>Reading which provides the sum of the energy drawn from the grid (a constantly increasing meter) </td></tr>
<tr><td> </td><td>If the counter is reset to '0' at the beginning of the day (daily counter), the module handles this situation accordingly.</td></tr>
<tr><td> </td><td>In this case, a message is displayed in the log with verbose 3. </td></tr>
<tr><td> <b>gfeedin</b> </td><td>Reading which supplies the power currently fed into the grid </td></tr>
<tr><td> <b>feedtotal</b> </td><td>Reading which provides the sum of the energy fed into the grid (a constantly increasing meter) </td></tr>
<tr><td> </td><td>If the counter is reset to '0' at the beginning of the day (daily counter), the module handles this situation accordingly.</td></tr>
<tr><td> </td><td>In this case, a message is displayed in the log with verbose 3. </td></tr>
<tr><td> <b>Unit</b> </td><td>the respective unit (W,kW,Wh,kWh) </td></tr>
<tr><td> </td><td> </td></tr>
<tr><td> <b>conprice</b> </td><td>Price for the purchase of one kWh (optional). The &lt;field&gt; can be specified in one of the following variants: </td></tr>
<tr><td> </td><td>&lt;Price&gt;:&lt;Currency&gt; - Price as a numerical value and its currency </td></tr>
<tr><td> </td><td>&lt;Reading&gt;:&lt;Currency&gt; - Reading of the <b>meter device</b> that contains the price : Currency </td></tr>
<tr><td> </td><td>&lt;Device&gt;:&lt;Reading&gt;:&lt;Currency&gt; - any device and reading containing the price : Currency </td></tr>
<tr><td> </td><td> </td></tr>
<tr><td> <b>feedprice</b> </td><td>Remuneration for the feed-in of one kWh (optional). The &lt;field&gt; can be specified in one of the following variants: </td></tr>
<tr><td> </td><td>&lt;Remuneration&gt;:&lt;Currency&gt; - Remuneration as a numerical value and its currency </td></tr>
<tr><td> </td><td>&lt;Reading&gt;:&lt;Currency&gt; - Reading of the <b>meter device</b> that contains the remuneration : Currency </td></tr>
<tr><td> </td><td>&lt;Device&gt;:&lt;Reading&gt;:&lt;Currency&gt; - any device and reading containing the remuneration : Currency </td></tr>
</table>
</ul>
<br>
<b>Special cases:</b> If the reading for gcon and gfeedin should be identical but signed,
the keys gfeedin and gcon can be defined as follows: <br><br>
<ul>
gfeedin=-gcon &nbsp;&nbsp;&nbsp;(a negative value of gcon is used as gfeedin) <br>
gcon=-gfeedin &nbsp;&nbsp;&nbsp;(a negative value of gfeedin is used as gcon)
</ul>
<br>
The unit is omitted in the particular special case. <br><br>
<ul>
<b>Example: </b> <br>
attr &lt;name&gt; setupMeterDev Meter gcon=Wirkleistung:W contotal=BezWirkZaehler:kWh gfeedin=-gcon feedtotal=EinWirkZaehler:kWh conprice=powerCost: feedprice=0.1269: <br>
<br>
# Device Meter provides the current grid reference in the reading "Wirkleistung" (W),
the sum of the grid reference in the reading "BezWirkZaehler" (kWh), the current feed in "Wirkleistung" if "Wirkleistung" is negative,
the sum of the feed in the reading "EinWirkZaehler". (kWh)
</ul>
</li>
<br>
</ul>
</ul>
@ -20236,20 +20378,20 @@ Zur Erstellung der solaren Vorhersage kann das Modul SolarForecast unterschiedli
<ul>
<table>
<colgroup> <col width="25%"> <col width="75%"> </colgroup>
<tr><td> <b>DWD</b> </td><td>solare Vorhersage basierend auf der Strahlungsprognose des Deutschen Wetterdienstes (Model DWD) </td></tr>
<tr><td> <b>SolCast-API </b> </td><td>verwendet Prognosedaten der <a href='https://toolkit.solcast.com.au/rooftop-sites/' target='_blank'>SolCast API</a> (Model SolCastAPI) </td></tr>
<tr><td> <b>ForecastSolar-API</b> </td><td>verwendet Prognosedaten der <a href='https://doc.forecast.solar/api' target='_blank'>Forecast.Solar API</a> (Model ForecastSolarAPI) </td></tr>
<tr><td> <b>VictronKI-API</b> </td><td>Victron Energy API des <a href='https://www.victronenergy.com/blog/2023/07/05/new-vrm-solar-production-forecast-feature/' target='_blank'>VRM Portals</a> (Model VictronKiAPI) </td></tr>
<colgroup> <col width="32%"> <col width="68%"> </colgroup>
<tr><td> <b>DWD</b> </td><td>solare Vorhersage basierend auf MOSMIX Daten des Deutschen Wetterdienstes </td></tr>
<tr><td> <b>SolCast-API </b> </td><td>verwendet Prognosedaten der <a href='https://toolkit.solcast.com.au/rooftop-sites/' target='_blank'>SolCast API</a> </td></tr>
<tr><td> <b>ForecastSolar-API</b> </td><td>verwendet Prognosedaten der <a href='https://doc.forecast.solar/api' target='_blank'>Forecast.Solar API</a> </td></tr>
<tr><td> <b>OpenMeteoDWD-API</b> </td><td>ICON-Wettermodelle des Deutschen Wetterdienstes (DWD) über <a href='https://open-meteo.com/en/docs/dwd-api' target='_blank'>Open-Meteo</a> </td></tr>
<tr><td> <b>OpenMeteoDWDEnsemble-API</b> </td><td>Zugang zum <a href='https://www.dwd.de/DE/forschung/wettervorhersage/num_modellierung/04_ensemble_methoden/ensemble_vorhersage/ensemble_vorhersagen.html' target='_blank'>globalen Ensemble-Vorhersagesystem (EPS)</a> des DWD </td></tr>
<tr><td> <b>OpenMeteoWorld-API</b> </td><td>vereint nahtlos Wettermodelle von Organisationen wie NOAA, DWD, CMCC und ECMWF über <a href='https://open-meteo.com/en/docs' target='_blank'>Open-Meteo</a> </td></tr>
<tr><td> <b>VictronKI-API</b> </td><td>Victron Energy API des <a href='https://www.victronenergy.com/blog/2023/07/05/new-vrm-solar-production-forecast-feature/' target='_blank'>VRM Portals</a> </td></tr>
</table>
</ul>
<br>
Bei Verwendung des Model DWD kann eine KI-Unterstützung aktiviert werden. <br>
Die Nutzung der erwähnten API's beschränkt sich auf die jeweils kostenlose Version des Dienstes. <br>
Im zugeordneten DWD_OpenData Device (Attribut "ctrlWeatherDevX") ist die passende Wetterstation
festzulegen um meteorologische Daten (Bewölkung, Sonnenaufgang, u.a.) bzw. eine Strahlungsprognose (Model DWD)
für den Anlagenstandort zu erhalten. <br><br>
Die KI-Unterstützung kann in Abhängigkeit vom verwendeten Model aktiviert werden. <br><br>
Über die PV Erzeugungsprognose hinaus werden Verbrauchswerte bzw. Netzbezugswerte erfasst und für eine
Verbrauchsprognose verwendet. <br>
@ -20257,7 +20399,7 @@ Das Modul errechnet aus den Prognosewerten einen zukünftigen Energieüberschuß
genutzt wird. Weiterhin bietet das Modul eine <a href="#SolarForecast-Consumer">Consumer Integration</a> zur integrierten
Planung und Steuerung von PV Überschuß abhängigen Verbraucherschaltungen. <br><br>
Bei der ersten Definition des Moduls wird der Benutzer über eine Guided Procedure unterstützt um alle initialen Eingaben
Bei der ersten Definition des Moduls wird der Benutzer über eine Guided Procedure unterstützt um alle initial notwendigen Eingaben
vorzunehmen. <br>
Am Ende des Vorganges und nach relevanten Änderungen der Anlagen- bzw. Devicekonfiguration sollte unbedingt mit einem
<a href="#SolarForecast-set-plantConfiguration">set &lt;name&gt; plantConfiguration ceck</a>
@ -20277,8 +20419,8 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<br>
Nach der Definition des Devices sind in Abhängigkeit der verwendeten Prognosequellen zwingend weitere
anlagenspezifische Angaben mit den entsprechenden set-Kommandos zu hinterlegen. <br>
Mit nachfolgenden set-Kommandos und Attributen werden für die Funktion des Moduls maßgebliche Informationen
anlagenspezifische Angaben zu hinterlegen. <br>
Mit nachfolgenden Set-Kommandos und Attributen werden für die Funktion des Moduls maßgebliche Informationen
hinterlegt: <br><br>
<ul>
@ -20287,7 +20429,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<tr><td> <b>ctrlWeatherDevX</b> </td><td>DWD_OpenData Device welches meteorologische Daten (z.B. Bewölkung) liefert </td></tr>
<tr><td> <b>currentRadiationAPI </b> </td><td>DWD_OpenData Device bzw. API zur Lieferung von Strahlungsdaten </td></tr>
<tr><td> <b>currentInverterDev</b> </td><td>Device welches PV Leistungsdaten liefert </td></tr>
<tr><td> <b>currentMeterDev</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>
<tr><td> <b>currentBatteryDev</b> </td><td>Device welches Batterie Leistungsdaten liefert (sofern vorhanden) </td></tr>
<tr><td> <b>inverterStrings</b> </td><td>Bezeichner der vorhandenen Anlagenstrings </td></tr>
<tr><td> <b>moduleAzimuth</b> </td><td>Ausrichtung (Azimut) der Anlagenstrings </td></tr>
@ -20503,65 +20645,6 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
</ul>
<br>
<ul>
<a id="SolarForecast-set-currentMeterDev"></a>
<li><b>currentMeterDev &lt;Meter Device Name&gt; gcon=&lt;Readingname&gt;:&lt;Einheit&gt; contotal=&lt;Readingname&gt;:&lt;Einheit&gt;
gfeedin=&lt;Readingname&gt;:&lt;Einheit&gt; feedtotal=&lt;Readingname&gt;:&lt;Einheit&gt;
[conprice=&lt;Feld&gt;] [feedprice=&lt;Feld&gt;] </b> <br><br>
Legt ein beliebiges Device und seine Readings zur Energiemessung fest.
Das Modul geht davon aus, dass der numerische Wert der Readings positiv ist.
Es kann auch ein Dummy Device mit entsprechenden Readings sein. Die Bedeutung des jeweiligen "Readingname" ist:
<br><br>
<ul>
<table>
<colgroup> <col width="15%"> <col width="85%"> </colgroup>
<tr><td> <b>gcon</b> </td><td>Reading welches die aktuell aus dem Netz bezogene Leistung liefert </td></tr>
<tr><td> <b>contotal</b> </td><td>Reading welches die Summe der aus dem Netz bezogenen Energie liefert (ein sich stetig erhöhender Zähler) </td></tr>
<tr><td> </td><td>Wird der Zähler zu Beginn des Tages auf '0' zurückgesetzt (Tageszähler), behandelt das Modul diese Situation entsprechend. </td></tr>
<tr><td> </td><td>In diesem Fall erfolgt eine Meldung im Log mit verbose 3. </td></tr>
<tr><td> <b>gfeedin</b> </td><td>Reading welches die aktuell in das Netz eingespeiste Leistung liefert </td></tr>
<tr><td> <b>feedtotal</b> </td><td>Reading welches die Summe der in das Netz eingespeisten Energie liefert (ein sich stetig erhöhender Zähler) </td></tr>
<tr><td> </td><td>Wird der Zähler zu Beginn des Tages auf '0' zurückgesetzt (Tageszähler), behandelt das Modul diese Situation entsprechend. </td></tr>
<tr><td> </td><td>In diesem Fall erfolgt eine Meldung im Log mit verbose 3. </td></tr>
<tr><td> <b>Einheit</b> </td><td>die jeweilige Einheit (W,kW,Wh,kWh) </td></tr>
<tr><td> </td><td> </td></tr>
<tr><td> <b>conprice</b> </td><td>Preis für den Bezug einer kWh (optional). Die Angabe &lt;Feld&gt; ist in einer der folgenden Varianten möglich: </td></tr>
<tr><td> </td><td>&lt;Preis&gt;:&lt;Währung&gt; - Preis als numerischer Wert und dessen Währung </td></tr>
<tr><td> </td><td>&lt;Reading&gt;:&lt;Währung&gt; - Reading des <b>Meter Device</b> das den Preis enthält : Währung </td></tr>
<tr><td> </td><td>&lt;Device&gt;:&lt;Reading&gt;:&lt;Währung&gt; - beliebiges Device und Reading welches den Preis enthält : Währung </td></tr>
<tr><td> </td><td> </td></tr>
<tr><td> <b>feedprice</b> </td><td>Vergütung für die Einspeisung einer kWh (optional). Die Angabe &lt;Feld&gt; ist in einer der folgenden Varianten möglich: </td></tr>
<tr><td> </td><td>&lt;Vergütung&gt;:&lt;Währung&gt; - Vergütung als numerischer Wert und dessen Währung </td></tr>
<tr><td> </td><td>&lt;Reading&gt;:&lt;Währung&gt; - Reading des <b>Meter Device</b> das die Vergütung enthält : Währung </td></tr>
<tr><td> </td><td>&lt;Device&gt;:&lt;Reading&gt;:&lt;Währung&gt; - beliebiges Device und Reading welches die Vergütung enthält : Währung </td></tr>
</table>
</ul>
<br>
<b>Sonderfälle:</b> Sollte das Reading für gcon und gfeedin identisch, aber vorzeichenbehaftet sein,
können die Schlüssel gfeedin und gcon wie folgt definiert werden: <br><br>
<ul>
gfeedin=-gcon &nbsp;&nbsp;&nbsp;(ein negativer Wert von gcon wird als gfeedin verwendet) <br>
gcon=-gfeedin &nbsp;&nbsp;&nbsp;(ein negativer Wert von gfeedin wird als gcon verwendet)
</ul>
<br>
Die Einheit entfällt in dem jeweiligen Sonderfall. <br><br>
<ul>
<b>Beispiel: </b> <br>
set &lt;name&gt; currentMeterDev Meter gcon=Wirkleistung:W contotal=BezWirkZaehler:kWh gfeedin=-gcon feedtotal=EinWirkZaehler:kWh conprice=powerCost: feedprice=0.1269: <br>
<br>
# Device Meter liefert den aktuellen Netzbezug im Reading "Wirkleistung" (W),
die Summe des Netzbezugs im Reading "BezWirkZaehler" (kWh), die aktuelle Einspeisung in "Wirkleistung" wenn "Wirkleistung" negativ ist,
die Summe der Einspeisung im Reading "EinWirkZaehler" (kWh)
</ul>
</li>
</ul>
<br>
<ul>
<a id="SolarForecast-set-currentRadiationAPI"></a>
<li><b>currentRadiationAPI </b> <br><br>
@ -21265,13 +21348,13 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<tr><td> <b>csmeXX</b> </td><td>Energieverbrauch von ConsumerXX in der Stunde des Tages (Stunde 99 = Tagesenergieverbrauch) </td></tr>
<tr><td> <b>confc</b> </td><td>erwarteter Energieverbrauch (Wh) </td></tr>
<tr><td> <b>con</b> </td><td>realer Energieverbrauch (Wh) des Hauses </td></tr>
<tr><td> <b>conprice</b> </td><td>Preis für den Bezug einer kWh. Die Einheit des Preises ist im currentMeterDev definiert. </td></tr>
<tr><td> <b>conprice</b> </td><td>Preis für den Bezug einer kWh. Die Einheit des Preises ist im setupMeterDev definiert. </td></tr>
<tr><td> <b>cyclescsmXX</b> </td><td>Anzahl aktive Zyklen von ConsumerXX des Tages </td></tr>
<tr><td> <b>DoN</b> </td><td>Sonnenauf- und untergangsstatus (0 - Nacht, 1 - Tag) </td></tr>
<tr><td> <b>etotal</b> </td><td>totaler Energieertrag (Wh) zu Beginn der Stunde </td></tr>
<tr><td> <b>gcon</b> </td><td>realer Leistungsbezug (Wh) aus dem Stromnetz </td></tr>
<tr><td> <b>gfeedin</b> </td><td>reale Einspeisung (Wh) in das Stromnetz </td></tr>
<tr><td> <b>feedprice</b> </td><td>Vergütung für die Einpeisung einer kWh. Die Währung des Preises ist im currentMeterDev definiert. </td></tr>
<tr><td> <b>feedprice</b> </td><td>Vergütung für die Einpeisung einer kWh. Die Währung des Preises ist im setupMeterDev definiert. </td></tr>
<tr><td> <b>avgcycmntscsmXX</b> </td><td>durchschnittliche Dauer eines Einschaltzyklus des Tages von ConsumerXX in Minuten </td></tr>
<tr><td> <b>hourscsmeXX</b> </td><td>Summe Aktivstunden des Tages von ConsumerXX </td></tr>
<tr><td> <b>minutescsmXX</b> </td><td>Summe Aktivminuten in der Stunde von ConsumerXX </td></tr>
@ -21797,7 +21880,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
Für die ausgewählten Consumer (Nummer) werden Readings der Form <b>consumerXX_ConsumptionRecommended</b> erstellt. <br>
Diese Readings signalisieren ob das Einschalten dieses Consumers abhängig von seinen Verbrauchsdaten und der aktuellen
PV-Erzeugung bzw. des aktuellen Energieüberschusses empfohlen ist. Der Wert des erstellten Readings korreliert
mit den berechneten Planungsdaten das Consumers, kann aber von dem Planungszeitraum abweichen. <br>
mit den berechneten Planungsdaten des Consumers, kann aber von dem Planungszeitraum abweichen. <br>
</li>
<br>
@ -22210,8 +22293,8 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<colgroup> <col width="20%"> <col width="80%"> </colgroup>
<tr><td> <b>consumption</b> </td><td>Energieverbrauch </td></tr>
<tr><td> <b>consumptionForecast</b> </td><td>prognostizierter Energieverbrauch </td></tr>
<tr><td> <b>energycosts</b> </td><td>Kosten des Energiebezuges aus dem Netz. Die Währung ist im currentMeterDev, Schlüssel conprice, definiert. </td></tr>
<tr><td> <b>feedincome</b> </td><td>Vergütung für die Netzeinspeisung. Die Währung ist im currentMeterDev, Schlüssel feedprice, definiert. </td></tr>
<tr><td> <b>energycosts</b> </td><td>Kosten des Energiebezuges aus dem Netz. Die Währung ist im setupMeterDev, Schlüssel conprice, definiert. </td></tr>
<tr><td> <b>feedincome</b> </td><td>Vergütung für die Netzeinspeisung. Die Währung ist im setupMeterDev, Schlüssel feedprice, definiert. </td></tr>
<tr><td> <b>gridconsumption</b> </td><td>Energiebezug aus dem öffentlichen Netz </td></tr>
<tr><td> <b>gridfeedin</b> </td><td>Einspeisung in das öffentliche Netz </td></tr>
<tr><td> <b>pvReal</b> </td><td>reale PV-Erzeugung (default für graphicBeam1Content) </td></tr>
@ -22220,7 +22303,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
</ul>
<br>
<b>Hinweis:</b> Die Auswahl der Parameter energycosts und feedincome ist nur sinnvoll wenn in currentMeterDev die
<b>Hinweis:</b> Die Auswahl der Parameter energycosts und feedincome ist nur sinnvoll wenn in setupMeterDev die
optionalen Schlüssel conprice und feedprice gesetzt sind.
</li>
<br>
@ -22501,6 +22584,63 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
</li>
<br>
<a id="SolarForecast-attr-setupMeterDev"></a>
<li><b>setupMeterDev &lt;Meter Device Name&gt; gcon=&lt;Readingname&gt;:&lt;Einheit&gt; contotal=&lt;Readingname&gt;:&lt;Einheit&gt;
gfeedin=&lt;Readingname&gt;:&lt;Einheit&gt; feedtotal=&lt;Readingname&gt;:&lt;Einheit&gt;
[conprice=&lt;Feld&gt;] [feedprice=&lt;Feld&gt;] </b> <br><br>
Legt ein beliebiges Device und seine Readings zur Energiemessung fest.
Das Modul geht davon aus, dass der numerische Wert der Readings positiv ist.
Es kann auch ein Dummy Device mit entsprechenden Readings sein. Die Bedeutung des jeweiligen "Readingname" ist:
<br><br>
<ul>
<table>
<colgroup> <col width="15%"> <col width="85%"> </colgroup>
<tr><td> <b>gcon</b> </td><td>Reading welches die aktuell aus dem Netz bezogene Leistung liefert </td></tr>
<tr><td> <b>contotal</b> </td><td>Reading welches die Summe der aus dem Netz bezogenen Energie liefert (ein sich stetig erhöhender Zähler) </td></tr>
<tr><td> </td><td>Wird der Zähler zu Beginn des Tages auf '0' zurückgesetzt (Tageszähler), behandelt das Modul diese Situation entsprechend. </td></tr>
<tr><td> </td><td>In diesem Fall erfolgt eine Meldung im Log mit verbose 3. </td></tr>
<tr><td> <b>gfeedin</b> </td><td>Reading welches die aktuell in das Netz eingespeiste Leistung liefert </td></tr>
<tr><td> <b>feedtotal</b> </td><td>Reading welches die Summe der in das Netz eingespeisten Energie liefert (ein sich stetig erhöhender Zähler) </td></tr>
<tr><td> </td><td>Wird der Zähler zu Beginn des Tages auf '0' zurückgesetzt (Tageszähler), behandelt das Modul diese Situation entsprechend. </td></tr>
<tr><td> </td><td>In diesem Fall erfolgt eine Meldung im Log mit verbose 3. </td></tr>
<tr><td> <b>Einheit</b> </td><td>die jeweilige Einheit (W,kW,Wh,kWh) </td></tr>
<tr><td> </td><td> </td></tr>
<tr><td> <b>conprice</b> </td><td>Preis für den Bezug einer kWh (optional). Die Angabe &lt;Feld&gt; ist in einer der folgenden Varianten möglich: </td></tr>
<tr><td> </td><td>&lt;Preis&gt;:&lt;Währung&gt; - Preis als numerischer Wert und dessen Währung </td></tr>
<tr><td> </td><td>&lt;Reading&gt;:&lt;Währung&gt; - Reading des <b>Meter Device</b> das den Preis enthält : Währung </td></tr>
<tr><td> </td><td>&lt;Device&gt;:&lt;Reading&gt;:&lt;Währung&gt; - beliebiges Device und Reading welches den Preis enthält : Währung </td></tr>
<tr><td> </td><td> </td></tr>
<tr><td> <b>feedprice</b> </td><td>Vergütung für die Einspeisung einer kWh (optional). Die Angabe &lt;Feld&gt; ist in einer der folgenden Varianten möglich: </td></tr>
<tr><td> </td><td>&lt;Vergütung&gt;:&lt;Währung&gt; - Vergütung als numerischer Wert und dessen Währung </td></tr>
<tr><td> </td><td>&lt;Reading&gt;:&lt;Währung&gt; - Reading des <b>Meter Device</b> das die Vergütung enthält : Währung </td></tr>
<tr><td> </td><td>&lt;Device&gt;:&lt;Reading&gt;:&lt;Währung&gt; - beliebiges Device und Reading welches die Vergütung enthält : Währung </td></tr>
</table>
</ul>
<br>
<b>Sonderfälle:</b> Sollte das Reading für gcon und gfeedin identisch, aber vorzeichenbehaftet sein,
können die Schlüssel gfeedin und gcon wie folgt definiert werden: <br><br>
<ul>
gfeedin=-gcon &nbsp;&nbsp;&nbsp;(ein negativer Wert von gcon wird als gfeedin verwendet) <br>
gcon=-gfeedin &nbsp;&nbsp;&nbsp;(ein negativer Wert von gfeedin wird als gcon verwendet)
</ul>
<br>
Die Einheit entfällt in dem jeweiligen Sonderfall. <br><br>
<ul>
<b>Beispiel: </b> <br>
attr &lt;name&gt; setupMeterDev Meter gcon=Wirkleistung:W contotal=BezWirkZaehler:kWh gfeedin=-gcon feedtotal=EinWirkZaehler:kWh conprice=powerCost: feedprice=0.1269: <br>
<br>
# Device Meter liefert den aktuellen Netzbezug im Reading "Wirkleistung" (W),
die Summe des Netzbezugs im Reading "BezWirkZaehler" (kWh), die aktuelle Einspeisung in "Wirkleistung" wenn "Wirkleistung" negativ ist,
die Summe der Einspeisung im Reading "EinWirkZaehler" (kWh)
</ul>
</li>
<br>
</ul>
</ul>

File diff suppressed because it is too large Load Diff