2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 06:39:11 +00:00

76_SolarForecast: possible asynchron mode Battery Dev, code change

git-svn-id: https://svn.fhem.de/fhem/trunk@29410 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2024-12-07 21:09:23 +00:00
parent 97c43e7138
commit ef7624a8aa
2 changed files with 143 additions and 33 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
- feature: 76_SolarForecast: possible asynchron mode Battery Dev, code change
- feature: 76_SMAInverter.pm: add installer login, code optimized - feature: 76_SMAInverter.pm: add installer login, code optimized
- feature: 76_SolarForecast: possible asynchron mode for Meter & Inverter - feature: 76_SolarForecast: possible asynchron mode for Meter & Inverter
- change: 93_DbLog: insertmode 0 - improved output of errors in Logfile - change: 93_DbLog: insertmode 0 - improved output of errors in Logfile

View File

@ -157,6 +157,8 @@ BEGIN {
# Versions History intern # Versions History intern
my %vNotesIntern = ( my %vNotesIntern = (
"1.39.1" => "07.12.2024 new control releaseCentralTask, new delHashRefDeep in some cases ".
"possible asynchron mode for setupBatteryDev ",
"1.39.0" => "04.12.2024 possible asynchron mode for setupMeterDev, setupInverterDevXX ". "1.39.0" => "04.12.2024 possible asynchron mode for setupMeterDev, setupInverterDevXX ".
"include FHEM::SynoModules::ErrCodes ", "include FHEM::SynoModules::ErrCodes ",
"1.38.0" => "30.11.2024 optimize data handling, rename getter solApiData to radiationApiData, ". "1.38.0" => "30.11.2024 optimize data handling, rename getter solApiData to radiationApiData, ".
@ -2121,7 +2123,10 @@ sub _setreset { ## no critic "not used"
$dday = sprintf "%02d", $dday; $dday = sprintf "%02d", $dday;
if ($dhour) { if ($dhour) {
$dhour = sprintf "%02d", $dhour; $dhour = sprintf "%02d", $dhour;
delHashRefDeep ($data{$type}{$name}{pvhist}{$dday}{$dhour});
delete $data{$type}{$name}{pvhist}{$dday}{$dhour}; delete $data{$type}{$name}{pvhist}{$dday}{$dhour};
Log3 ($name, 3, qq{$name - Day "$dday" hour "$dhour" deleted from pvHistory}); Log3 ($name, 3, qq{$name - Day "$dday" hour "$dhour" deleted from pvHistory});
$paref->{reorg} = 1; # den Tag Stunde "99" reorganisieren $paref->{reorg} = 1; # den Tag Stunde "99" reorganisieren
@ -2135,11 +2140,13 @@ sub _setreset { ## no critic "not used"
delete $paref->{histname}; delete $paref->{histname};
} }
else { else {
delHashRefDeep ($data{$type}{$name}{pvhist}{$dday});
delete $data{$type}{$name}{pvhist}{$dday}; delete $data{$type}{$name}{pvhist}{$dday};
Log3 ($name, 3, qq{$name - Day "$dday" deleted from pvHistory}); Log3 ($name, 3, qq{$name - Day "$dday" deleted from pvHistory});
} }
} }
else { else {
delHashRefDeep ($data{$type}{$name}{pvhist});
delete $data{$type}{$name}{pvhist}; delete $data{$type}{$name}{pvhist};
Log3 ($name, 3, qq{$name - all days deleted from pvHistory}); Log3 ($name, 3, qq{$name - all days deleted from pvHistory});
} }
@ -5672,8 +5679,8 @@ sub _attrconsumer { ## no critic "not used"
$data{$type}{$name}{current}{consumerCollected} = 0; # Consumer neu sammeln $data{$type}{$name}{current}{consumerCollected} = 0; # Consumer neu sammeln
InternalTimer (gettimeofday()+0.5, 'FHEM::SolarForecast::centralTask', [$name, 0], 0); InternalTimer (gettimeofday() + 0.5, 'FHEM::SolarForecast::centralTask', [$name, 0], 0);
InternalTimer (gettimeofday()+2, 'FHEM::SolarForecast::createAssociatedWith', $hash, 0); InternalTimer (gettimeofday() + 2, 'FHEM::SolarForecast::createAssociatedWith', $hash, 0);
return; return;
} }
@ -5918,9 +5925,9 @@ sub _attrProducerDev { ## no critic "not used"
} }
} }
InternalTimer (gettimeofday()+0.5, 'FHEM::SolarForecast::centralTask', [$name, 0], 0); InternalTimer (gettimeofday() + 0.5, 'FHEM::SolarForecast::centralTask', [$name, 0], 0);
InternalTimer (gettimeofday() + 2, 'FHEM::SolarForecast::createAssociatedWith', $hash, 0); InternalTimer (gettimeofday() + 2, 'FHEM::SolarForecast::createAssociatedWith', $hash, 0);
InternalTimer (gettimeofday() + 3, 'FHEM::SolarForecast::writeCacheToFile', [$name, 'plantconfig', $plantcfg.$name], 0); # Anlagenkonfiguration File schreiben InternalTimer (gettimeofday() + 3, 'FHEM::SolarForecast::writeCacheToFile', [$name, 'plantconfig', $plantcfg.$name], 0); # Anlagenkonfiguration File schreiben
return; return;
} }
@ -5997,9 +6004,9 @@ sub _attrInverterDev { ## no critic "not used"
} }
} }
InternalTimer (gettimeofday()+0.5, 'FHEM::SolarForecast::centralTask', [$name, 0], 0); InternalTimer (gettimeofday() + 0.5, 'FHEM::SolarForecast::centralTask', [$name, 0], 0);
InternalTimer (gettimeofday() + 2, 'FHEM::SolarForecast::createAssociatedWith', $hash, 0); InternalTimer (gettimeofday() + 2, 'FHEM::SolarForecast::createAssociatedWith', $hash, 0);
InternalTimer (gettimeofday() + 3, 'FHEM::SolarForecast::writeCacheToFile', [$name, 'plantconfig', $plantcfg.$name], 0); # Anlagenkonfiguration File schreiben InternalTimer (gettimeofday() + 3, 'FHEM::SolarForecast::writeCacheToFile', [$name, 'plantconfig', $plantcfg.$name], 0); # Anlagenkonfiguration File schreiben
return; return;
} }
@ -6175,6 +6182,7 @@ sub _attrBatteryDev { ## no critic "not used"
delete $data{$type}{$name}{current}{powerbatin}; delete $data{$type}{$name}{current}{powerbatin};
delete $data{$type}{$name}{current}{batcharge}; delete $data{$type}{$name}{current}{batcharge};
delete $data{$type}{$name}{current}{batinstcap}; delete $data{$type}{$name}{current}{batinstcap};
delete $data{$type}{$name}{current}{batasynchron};
} }
InternalTimer (gettimeofday() + 2, 'FHEM::SolarForecast::createAssociatedWith', $hash, 0); InternalTimer (gettimeofday() + 2, 'FHEM::SolarForecast::createAssociatedWith', $hash, 0);
@ -6355,7 +6363,7 @@ sub Notify {
my $debug = getDebug ($myHash); # Debug Mode my $debug = getDebug ($myHash); # Debug Mode
my ($err, $medev, $h, $async); my ($err, $medev, $badev, $h, $async);
## Meter Event? ## Meter Event?
################# #################
@ -6370,6 +6378,41 @@ sub Notify {
} }
if ($async) { if ($async) {
if (CurrentVal ($myHash, 'ctrunning', 0)) {
if ($debug =~ /notifyHandling/x) {
Log3 ($myName, 1, qq{$myName DEBUG> notifyHandling - central task was called from NOTIFY when it is already running ... end this call});
}
return;
}
centralTask ($myHash, 0); # keine Events in SolarForecast außer 'state'
return;
}
}
}
## Battery Event?
###################
($err, $badev, $h) = isDeviceValid ( { name => $myName, obj => 'setupBatteryDev', method => 'attr' } );
if (!$err) {
if ($devName eq $badev) {
$async = $h->{asynchron} // 0;
if ($debug =~ /notifyHandling/x) {
Log3 ($myName, 1, qq{$myName DEBUG> notifyHandling - Event of Battery device >$devName< received - asynchronous mode: $async});
}
if ($async) {
if (CurrentVal ($myHash, 'ctrunning', 0)) {
if ($debug =~ /notifyHandling/x) {
Log3 ($myName, 1, qq{$myName DEBUG> notifyHandling - central task was called from NOTIFY when it is already running ... end this call});
}
return;
}
centralTask ($myHash, 0); # keine Events in SolarForecast außer 'state' centralTask ($myHash, 0); # keine Events in SolarForecast außer 'state'
return; return;
} }
@ -6390,6 +6433,14 @@ sub Notify {
} }
if ($iasync) { if ($iasync) {
if (CurrentVal ($myHash, 'ctrunning', 0)) {
if ($debug =~ /notifyHandling/x) {
Log3 ($myName, 1, qq{$myName DEBUG> notifyHandling - central task was called from NOTIFY when it is already running ... end this call});
}
return;
}
centralTask ($myHash, 0); # keine Events in SolarForecast außer 'state' centralTask ($myHash, 0); # keine Events in SolarForecast außer 'state'
return; return;
} }
@ -7014,6 +7065,7 @@ sub runTask {
Log3 ($name, 1, "$name DEBUG> INFO - runTask starts data collection at the end of an hour"); Log3 ($name, 1, "$name DEBUG> INFO - runTask starts data collection at the end of an hour");
} }
releaseCentralTask ($hash);
centralTask ($hash, 1); centralTask ($hash, 1);
} }
} }
@ -7029,6 +7081,7 @@ sub runTask {
Log3 ($name, 1, "$name DEBUG> INFO - runTask starts data collection at the beginning of an hour"); Log3 ($name, 1, "$name DEBUG> INFO - runTask starts data collection at the beginning of an hour");
} }
releaseCentralTask ($hash);
centralTask ($hash, 1); centralTask ($hash, 1);
} }
} }
@ -7188,17 +7241,12 @@ sub centralTask {
$data{$type}{$name}{statusapi}{'?VRM'}{'?API'}{credentials} = $vrmcr; $data{$type}{$name}{statusapi}{'?VRM'}{'?API'}{credentials} = $vrmcr;
delete $data{$type}{$name}{solcastapi}{'?VRM'}; delete $data{$type}{$name}{solcastapi}{'?VRM'};
} }
########################################################################################################################## ##########################################################################################################################
my (undef, $disabled, $inactive) = controller ($name); my (undef, $disabled, $inactive) = controller ($name);
return if($disabled || $inactive); # disabled / inactive return if($disabled || $inactive); # disabled / inactive
if (CurrentVal ($hash, 'ctrunning', 0)) {
Log3 ($name, 3, "$name - INFO - central task was called when it was already running ... end this call");
$data{$type}{$name}{current}{ctrunning} = 0;
return;
}
if (!CurrentVal ($hash, 'allStringsFullfilled', 0)) { # die String Konfiguration erstellen wenn noch nicht erfolgreich ausgeführt if (!CurrentVal ($hash, 'allStringsFullfilled', 0)) { # die String Konfiguration erstellen wenn noch nicht erfolgreich ausgeführt
my $ret = createStringConfig ($hash); my $ret = createStringConfig ($hash);
@ -7212,6 +7260,11 @@ sub centralTask {
} }
} }
if (CurrentVal ($hash, 'ctrunning', 0)) {
Log3 ($name, 3, "$name - INFO - central task was called when it was already running ... end this call");
return;
}
my $t = time; # aktuelle Unix-Zeit my $t = time; # aktuelle Unix-Zeit
my $date = strftime "%Y-%m-%d", localtime($t); # aktuelles Datum my $date = strftime "%Y-%m-%d", localtime($t); # aktuelles Datum
my $chour = strftime "%H", localtime($t); # aktuelle Stunde in 24h format (00-23) my $chour = strftime "%H", localtime($t); # aktuelle Stunde in 24h format (00-23)
@ -7222,6 +7275,8 @@ sub centralTask {
$data{$type}{$name}{current}{ctrunning} = 1; # Central Task running Statusbit $data{$type}{$name}{current}{ctrunning} = 1; # Central Task running Statusbit
InternalTimer (gettimeofday() + 1.2, "FHEM::SolarForecast::releaseCentralTask", $hash, 0); # Freigabe centralTask
my $centpars = { my $centpars = {
name => $name, name => $name,
type => $type, type => $type,
@ -7282,15 +7337,13 @@ sub centralTask {
if ($evt) { if ($evt) {
$centpars->{evt} = $evt; $centpars->{evt} = $evt;
InternalTimer(gettimeofday()+1, "FHEM::SolarForecast::singleUpdateState", {hash => $hash, state => $centpars->{state}, evt => $centpars->{evt}}, 0); InternalTimer (gettimeofday() + 1, "FHEM::SolarForecast::singleUpdateState", {hash => $hash, state => $centpars->{state}, evt => $centpars->{evt}}, 0);
} }
else { else {
$centpars->{evt} = 1; $centpars->{evt} = 1;
singleUpdateState ( {hash => $hash, state => $centpars->{state}, evt => $centpars->{evt}} ); singleUpdateState ( {hash => $hash, state => $centpars->{state}, evt => $centpars->{evt}} );
} }
$data{$type}{$name}{current}{ctrunning} = 0;
return; return;
} }
@ -7580,7 +7633,7 @@ sub _collectAllRegConsumers {
my ($err) = isDeviceValid ( { name => $name, obj => $dswitch, method => 'string' } ); my ($err) = isDeviceValid ( { name => $name, obj => $dswitch, method => 'string' } );
next if($err); next if($err);
push @{$data{$type}{$name}{current}{consumerdevs}}, $dswitch; # Switchdevice zusätzlich in CurrentHash eintragen push @{$data{$type}{$name}{current}{consumerdevs}}, $dswitch if($dswitch ne $consumer); # Switchdevice zusätzlich in CurrentHash eintragen
} }
else { else {
$dswitch = $consumer; $dswitch = $consumer;
@ -7810,6 +7863,7 @@ sub _specialActivities {
$data{$type}{$name}{circular}{99}{ydayDvtn} = CircularVal ($hash, 99, 'tdayDvtn', '-'); $data{$type}{$name}{circular}{99}{ydayDvtn} = CircularVal ($hash, 99, 'tdayDvtn', '-');
delete $data{$type}{$name}{circular}{99}{tdayDvtn}; delete $data{$type}{$name}{circular}{99}{tdayDvtn};
delHashRefDeep ($data{$type}{$name}{pvhist}{$day});
delete $data{$type}{$name}{pvhist}{$day}; # den (alten) aktuellen Tag aus History löschen delete $data{$type}{$name}{pvhist}{$day}; # den (alten) aktuellen Tag aus History löschen
writeCacheToFile ($hash, 'plantconfig', $plantcfg.$name); # Anlagenkonfiguration sichern writeCacheToFile ($hash, 'plantconfig', $plantcfg.$name); # Anlagenkonfiguration sichern
@ -7971,7 +8025,10 @@ sub __delObsoleteAPIData {
## Wetter-API Daten löschen ## Wetter-API Daten löschen
############################# #############################
if (keys %{$data{$type}{$name}{weatherapi}}) { if (keys %{$data{$type}{$name}{weatherapi}}) {
delete $data{$type}{$name}{weatherapi}{OpenMeteo} if($wapi ne 'OpenMeteo'); if ($wapi ne 'OpenMeteo') {
delHashRefDeep ($data{$type}{$name}{weatherapi}{OpenMeteo});
delete $data{$type}{$name}{weatherapi}{OpenMeteo};
}
} }
## Status-API Daten löschen ## Status-API Daten löschen
@ -7998,9 +8055,13 @@ sub __delObsoleteAPIData {
} }
} }
### nicht mehr benötigte Daten verarbeiten - Bereich kann später wieder raus !!
##########################################################################################################################
# 01.12.2024
for my $idx (keys %{$data{$type}{$name}{solcastapi}{'?All'}}) { # Wetterindexe löschen (kann später raus) for my $idx (keys %{$data{$type}{$name}{solcastapi}{'?All'}}) { # Wetterindexe löschen (kann später raus)
delete $data{$type}{$name}{solcastapi}{'?All'}{$idx} if($idx =~ /^fc?([0-9]{1,2})_?([0-9]{1,2})$/xs); delete $data{$type}{$name}{solcastapi}{'?All'}{$idx} if($idx =~ /^fc?([0-9]{1,2})_?([0-9]{1,2})$/xs);
} }
#####################################################################################################################
} }
## veraltete Strings aus Strings-Hash löschen ## veraltete Strings aus Strings-Hash löschen
@ -9354,9 +9415,10 @@ sub _transferBatteryValues {
storeReading ('Current_PowerBatOut', (int $pbo).' W'); storeReading ('Current_PowerBatOut', (int $pbo).' W');
storeReading ('Current_BatCharge', $soc.' %'); storeReading ('Current_BatCharge', $soc.' %');
$data{$type}{$name}{current}{powerbatin} = int $pbi; # Hilfshash Wert aktuelle Batterieladung $data{$type}{$name}{current}{powerbatin} = int $pbi; # Hilfshash Wert aktuelle Batterieladung
$data{$type}{$name}{current}{powerbatout} = int $pbo; # Hilfshash Wert aktuelle Batterieentladung $data{$type}{$name}{current}{powerbatout} = int $pbo; # Hilfshash Wert aktuelle Batterieentladung
$data{$type}{$name}{current}{batcharge} = $soc; # aktuelle Batterieladung $data{$type}{$name}{current}{batcharge} = $soc; # aktuelle Batterieladung
$data{$type}{$name}{current}{batasynchron} = $h->{asynchron} if($h->{asynchron}); # asynchroner Modus = X
push @{$data{$type}{$name}{current}{socslidereg}}, $soc; # Schieberegister Batterie SOC push @{$data{$type}{$name}{current}{socslidereg}}, $soc; # Schieberegister Batterie SOC
limitArray ($data{$type}{$name}{current}{socslidereg}, $slidenumdef); limitArray ($data{$type}{$name}{current}{socslidereg}, $slidenumdef);
@ -17822,6 +17884,43 @@ sub singleUpdateState {
return; return;
} }
################################################################
# Zentralschleife freigeben
################################################################
sub releaseCentralTask {
my $hash = shift;
RemoveInternalTimer ($hash, 'FHEM::SolarForecast::releaseCentralTask');
$data{$hash->{TYPE}}{$hash->{NAME}}{current}{ctrunning} = 0;
return;
}
################################################################
# Hash Referenz rekursiv löschen
#
# Stellt sicher, dass alle verschachtelten Strukturen explizit
# gelöscht werden. Dies ist besonders nützlich um
# sicherzustellen, dass keine zirkulären Referenzen bestehen,
# die die Speicherfreigabe verhindern könnten.
################################################################
sub delHashRefDeep {
my $href = shift;
for my $key (keys %{$href}) {
if (ref $href->{$key} eq 'HASH') {
delHashRefDeep ($href->{$key});
}
delete $href->{$key};
}
$href = undef; # Optional: Garbage Collection erzwingen
return;
}
################################################################ ################################################################
# erstellt einen Debug-Eintrag im Log # erstellt einen Debug-Eintrag im Log
################################################################ ################################################################
@ -17874,28 +17973,29 @@ sub createAssociatedWith {
my $fcdev1 = AttrVal ($name, 'setupWeatherDev1', ''); # 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, 'setupWeatherDev2', ''); # 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, 'setupWeatherDev3', ''); # 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] // '';
my $radev = AttrVal ($name, 'setupRadiationAPI', ''); # Radiation forecast Device my $radev = AttrVal ($name, 'setupRadiationAPI', ''); # Radiation forecast Device
($ara,$h) = parseParams ($radev); ($ara,$h) = parseParams ($radev);
$radev = $ara->[0] // ""; $radev = $ara->[0] // '';
my $medev = AttrVal ($name, 'setupMeterDev', ''); # Meter Device my $medev = AttrVal ($name, 'setupMeterDev', ''); # Meter Device
($ame,$h) = parseParams ($medev); ($ame,$h) = parseParams ($medev);
$medev = $ame->[0] // ""; $medev = $ame->[0] // '';
push @cd, $medev; push @cd, $medev;
my $badev = AttrVal ($name, 'setupBatteryDev', ''); # Battery Device my $badev = AttrVal ($name, 'setupBatteryDev', ''); # Battery Device
($aba,$h) = parseParams ($badev); ($aba,$h) = parseParams ($badev);
$badev = $aba->[0] // ""; $badev = $aba->[0] // '';
push @cd, $badev;
for my $c (sort{$a<=>$b} keys %{$data{$type}{$name}{consumers}}) { # Consumer Devices for my $c (sort{$a<=>$b} keys %{$data{$type}{$name}{consumers}}) { # Consumer Devices
my $consumer = AttrVal ($name, "consumer${c}", ""); my $consumer = AttrVal ($name, "consumer${c}", "");
@ -21960,7 +22060,7 @@ to ensure that the system configuration is correct.
<a id="SolarForecast-attr-setupBatteryDev"></a> <a id="SolarForecast-attr-setupBatteryDev"></a>
<li><b>setupBatteryDev &lt;Battery Device Name&gt; pin=&lt;Readingname&gt;:&lt;Unit&gt; pout=&lt;Readingname&gt;:&lt;Unit&gt; <li><b>setupBatteryDev &lt;Battery Device Name&gt; pin=&lt;Readingname&gt;:&lt;Unit&gt; pout=&lt;Readingname&gt;:&lt;Unit&gt;
[intotal=&lt;Readingname&gt;:&lt;Unit&gt;] [outtotal=&lt;Readingname&gt;:&lt;Unit&gt;] [intotal=&lt;Readingname&gt;:&lt;Unit&gt;] [outtotal=&lt;Readingname&gt;:&lt;Unit&gt;]
cap=&lt;Option&gt; [charge=&lt;Readingname&gt;] </b> <br><br> cap=&lt;Option&gt; [charge=&lt;Readingname&gt;] [asynchron=&lt;Option&gt] </b> <br><br>
Specifies an arbitrary Device and its Readings to deliver the battery performance data. Specifies an arbitrary Device and its Readings to deliver the battery performance data.
The module assumes that the numerical value of the readings is always positive. The module assumes that the numerical value of the readings is always positive.
@ -21979,6 +22079,11 @@ to ensure that the system configuration is correct.
<tr><td> </td><td><b>&lt;Readingname&gt;:&lt;unit&gt;</b> - Reading which provides the capacity and unit (Wh, kWh) </td></tr> <tr><td> </td><td><b>&lt;Readingname&gt;:&lt;unit&gt;</b> - Reading which provides the capacity and unit (Wh, kWh) </td></tr>
<tr><td> <b>charge</b> </td><td>Reading which provides the current state of charge (SOC in percent) (optional) </td></tr> <tr><td> <b>charge</b> </td><td>Reading which provides the current state of charge (SOC in percent) (optional) </td></tr>
<tr><td> <b>Unit</b> </td><td>the respective unit (W,Wh,kW,kWh) </td></tr> <tr><td> <b>Unit</b> </td><td>the respective unit (W,Wh,kW,kWh) </td></tr>
<tr><td> </td><td> </td></tr>
<tr><td> <b>asynchron</b> </td><td>Data collection mode according to the ctrlInterval setting (synchronous) or additionally by </td></tr>
<tr><td> </td><td>event processing (asynchronous). </td></tr>
<tr><td> </td><td><b>0</b> - no data collection after receiving an event from the device (default) </td></tr>
<tr><td> </td><td><b>1</b> - trigger a data collection when an event is received from the device </td></tr>
</table> </table>
</ul> </ul>
<br> <br>
@ -22122,7 +22227,6 @@ to ensure that the system configuration is correct.
<tr><td> </td><td>event processing (asynchronous). </td></tr> <tr><td> </td><td>event processing (asynchronous). </td></tr>
<tr><td> </td><td><b>0</b> - no data collection after receiving an event from the device (default) </td></tr> <tr><td> </td><td><b>0</b> - no data collection after receiving an event from the device (default) </td></tr>
<tr><td> </td><td><b>1</b> - trigger a data collection when an event is received from the device </td></tr> <tr><td> </td><td><b>1</b> - trigger a data collection when an event is received from the device </td></tr>
</table> </table>
</ul> </ul>
<br> <br>
@ -24379,7 +24483,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<a id="SolarForecast-attr-setupBatteryDev"></a> <a id="SolarForecast-attr-setupBatteryDev"></a>
<li><b>setupBatteryDev &lt;Batterie Device Name&gt; pin=&lt;Readingname&gt;:&lt;Einheit&gt; pout=&lt;Readingname&gt;:&lt;Einheit&gt; <li><b>setupBatteryDev &lt;Batterie Device Name&gt; pin=&lt;Readingname&gt;:&lt;Einheit&gt; pout=&lt;Readingname&gt;:&lt;Einheit&gt;
[intotal=&lt;Readingname&gt;:&lt;Einheit&gt;] [outtotal=&lt;Readingname&gt;:&lt;Einheit&gt;] [intotal=&lt;Readingname&gt;:&lt;Einheit&gt;] [outtotal=&lt;Readingname&gt;:&lt;Einheit&gt;]
cap=&lt;Option&gt; [charge=&lt;Readingname&gt;] </b> <br><br> cap=&lt;Option&gt; [charge=&lt;Readingname&gt;] [asynchron=&lt;Option&gt] </b> <br><br>
Legt ein beliebiges Device und seine Readings zur Lieferung der Batterie Leistungsdaten fest. Legt ein beliebiges Device und seine Readings zur Lieferung der Batterie Leistungsdaten fest.
Das Modul geht davon aus, dass der numerische Wert der Readings immer positiv ist. Das Modul geht davon aus, dass der numerische Wert der Readings immer positiv ist.
@ -24398,6 +24502,11 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<tr><td> </td><td><b>&lt;Readingname&gt;:&lt;Einheit&gt;</b> - Reading welches die Kapazität liefert und Einheit (Wh, kWh) </td></tr> <tr><td> </td><td><b>&lt;Readingname&gt;:&lt;Einheit&gt;</b> - Reading welches die Kapazität liefert und Einheit (Wh, kWh) </td></tr>
<tr><td> <b>charge</b> </td><td>Reading welches den aktuellen Ladezustand (SOC in Prozent) liefert (optional) </td></tr> <tr><td> <b>charge</b> </td><td>Reading welches den aktuellen Ladezustand (SOC in Prozent) liefert (optional) </td></tr>
<tr><td> <b>Einheit</b> </td><td>die jeweilige Einheit (W,Wh,kW,kWh) </td></tr> <tr><td> <b>Einheit</b> </td><td>die jeweilige Einheit (W,Wh,kW,kWh) </td></tr>
<tr><td> </td><td> </td></tr>
<tr><td> <b>asynchron</b> </td><td>Modus der Datensammlung entsprechend Einstellung ctrlInterval (synchron) oder zusätzlich durch </td></tr>
<tr><td> </td><td>Eventverarbeitung (asynchron). </td></tr>
<tr><td> </td><td><b>0</b> - keine Datensammlung nach Empfang eines Events des Gerätes (default) </td></tr>
<tr><td> </td><td><b>1</b> - auslösen einer Datensammlung bei Empfang eines Events des Gerätes </td></tr>
</table> </table>
</ul> </ul>
<br> <br>