mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 06:39:11 +00:00
76_SolarForecast: Setter writeHistory replaced by operatingMemory save, backup and recover in-memory operating data
git-svn-id: https://svn.fhem.de/fhem/trunk@28432 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
a454d5eb4f
commit
aad0ac51ac
@ -1,5 +1,7 @@
|
||||
# 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.
|
||||
- feature: 76_SolarForecast: Setter writeHistory replaced by operatingMemory
|
||||
save, backup and recover in-memory operating data
|
||||
- feature: 76_SolarForecast: generate plant backup files
|
||||
- bugfix: 76_SolarForecast: minor fixes
|
||||
- feature: 76_SolarForecast: consumerXX: notbefore, notafter can be {<code>}
|
||||
|
@ -157,6 +157,8 @@ BEGIN {
|
||||
|
||||
# Versions History intern
|
||||
my %vNotesIntern = (
|
||||
"1.13.0" => "27.01.2024 minor change of deleteOldBckpFiles, Setter writeHistory replaced by operatingMemory ".
|
||||
"save, backup and recover in-memory operating data ",
|
||||
"1.12.0" => "26.01.2024 create backup files and delete old generations of them ",
|
||||
"1.11.1" => "26.01.2024 fix ___switchonTimelimits ",
|
||||
"1.11.0" => "25.01.2024 consumerXX: notbefore, notafter format extended to possible perl code {...} ",
|
||||
@ -439,7 +441,7 @@ my %hset = ( # Ha
|
||||
moduleRoofTops => { fn => \&_setmoduleRoofTops },
|
||||
moduleTiltAngle => { fn => \&_setmoduleTiltAngle },
|
||||
moduleDirection => { fn => \&_setmoduleDirection },
|
||||
writeHistory => { fn => \&_setwriteHistory },
|
||||
operatingMemory => { fn => \&_setoperatingMemory },
|
||||
vrmCredentials => { fn => \&_setVictronCredentials },
|
||||
aiDecTree => { fn => \&_setaiDecTree },
|
||||
);
|
||||
@ -913,6 +915,7 @@ sub Initialize {
|
||||
"ctrlAIdataStorageDuration ".
|
||||
"ctrlAutoRefresh:selectnumbers,120,0.2,1800,0,log10 ".
|
||||
"ctrlAutoRefreshFW:$fwd ".
|
||||
"ctrlBackupFilesKeep:select,1,2,3,4,5,6,7,8,9,10 ".
|
||||
"ctrlBatSocManagement:textField-long ".
|
||||
"ctrlConsRecommendReadings:multiple-strict,$allcs ".
|
||||
"ctrlDebug:multiple-strict,$dm,#14 ".
|
||||
@ -1008,26 +1011,32 @@ sub Define {
|
||||
|
||||
$params->{file} = $pvhcache.$name; # Cache File PV History einlesen wenn vorhanden
|
||||
$params->{cachename} = 'pvhist';
|
||||
$params->{title} = 'pvHistory';
|
||||
_readCacheFile ($params);
|
||||
|
||||
$params->{file} = $pvccache.$name; # Cache File PV Circular einlesen wenn vorhanden
|
||||
$params->{cachename} = 'circular';
|
||||
$params->{title} = 'pvCircular';
|
||||
_readCacheFile ($params);
|
||||
|
||||
$params->{file} = $csmcache.$name; # Cache File Consumer einlesen wenn vorhanden
|
||||
$params->{cachename} = 'consumers';
|
||||
$params->{title} = 'consumerMaster';
|
||||
_readCacheFile ($params);
|
||||
|
||||
$params->{file} = $scpicache.$name; # Cache File SolCast API Werte einlesen wenn vorhanden
|
||||
$params->{cachename} = 'solcastapi';
|
||||
$params->{title} = 'solApiData';
|
||||
_readCacheFile ($params);
|
||||
|
||||
$params->{file} = $aitrained.$name; # AI Cache File einlesen wenn vorhanden
|
||||
$params->{cachename} = 'aitrained';
|
||||
$params->{title} = 'aiTrainedData';
|
||||
_readCacheFile ($params);
|
||||
|
||||
$params->{file} = $airaw.$name; # AI Rawdaten File einlesen wenn vorhanden
|
||||
$params->{cachename} = 'airaw';
|
||||
$params->{title} = 'aiRawData';
|
||||
_readCacheFile ($params);
|
||||
|
||||
singleUpdateState ( {hash => $hash, state => 'initialized', evt => 1} );
|
||||
@ -1048,6 +1057,7 @@ sub _readCacheFile {
|
||||
my $type = $paref->{type};
|
||||
my $file = $paref->{file};
|
||||
my $cachename = $paref->{cachename};
|
||||
my $title = $paref->{title};
|
||||
|
||||
if ($cachename eq 'aitrained') {
|
||||
my ($err, $dtree) = fileRetrieve ($file);
|
||||
@ -1058,7 +1068,7 @@ sub _readCacheFile {
|
||||
if ($valid) {
|
||||
$data{$type}{$name}{aidectree}{aitrained} = $dtree;
|
||||
$data{$type}{$name}{current}{aitrainstate} = 'ok';
|
||||
Log3 ($name, 3, qq{$name - cached data "$cachename" restored});
|
||||
Log3 ($name, 3, qq{$name - cached data "$title" restored});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1071,7 +1081,7 @@ sub _readCacheFile {
|
||||
if (!$err && $data) {
|
||||
$data{$type}{$name}{aidectree}{airaw} = $data;
|
||||
$data{$type}{$name}{current}{aitrawstate} = 'ok';
|
||||
Log3 ($name, 3, qq{$name - cached data "$cachename" restored});
|
||||
Log3 ($name, 3, qq{$name - cached data "$title" restored});
|
||||
}
|
||||
|
||||
return;
|
||||
@ -1085,10 +1095,10 @@ sub _readCacheFile {
|
||||
|
||||
if ($success) {
|
||||
$data{$hash->{TYPE}}{$name}{$cachename} = decode_json ($json);
|
||||
Log3 ($name, 3, qq{$name - cached data "$cachename" restored});
|
||||
Log3 ($name, 3, qq{$name - cached data "$title" restored});
|
||||
}
|
||||
else {
|
||||
Log3 ($name, 1, qq{$name - WARNING - The content of file "$file" is not readable and may be corrupt});
|
||||
Log3 ($name, 1, qq{$name - WARNING - The content of file "$file" is not readable or may be corrupt});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1111,8 +1121,9 @@ sub Set {
|
||||
|
||||
return if((controller($name))[1]);
|
||||
|
||||
my ($setlist,@fcdevs,@cfs,@condevs);
|
||||
my ($setlist,@fcdevs,@cfs,@condevs,@bkps);
|
||||
my ($fcd,$ind,$med,$cf,$sp,$coms) = ('','','','','','');
|
||||
my $type = $hash->{TYPE};
|
||||
|
||||
my @re = qw( aiData
|
||||
batteryTriggerSet
|
||||
@ -1138,6 +1149,7 @@ sub Set {
|
||||
push @fcdevs, 'SolCast-API';
|
||||
push @fcdevs, 'ForecastSolar-API';
|
||||
push @fcdevs, 'VictronKI-API';
|
||||
|
||||
my $rdd = join ",", @fcdevs;
|
||||
|
||||
for my $h (@chours) {
|
||||
@ -1145,15 +1157,25 @@ sub Set {
|
||||
}
|
||||
$cf = join " ", @cfs;
|
||||
|
||||
my $type = $hash->{TYPE};
|
||||
|
||||
for my $c (sort{$a<=>$b} keys %{$data{$type}{$name}{consumers}}) {
|
||||
push @condevs, $c if($c);
|
||||
}
|
||||
$coms = @condevs ? join ",", @condevs : 'noArg';
|
||||
|
||||
$coms = @condevs ? join ",", @condevs : 'noArg';
|
||||
my $ipai = isPrepared4AI ($hash);
|
||||
|
||||
opendir (DIR, $cachedir);
|
||||
|
||||
while (my $file = readdir (DIR)) {
|
||||
next unless (-f "$cachedir/$file");
|
||||
next unless ($file =~ /_${name}_/);
|
||||
next unless ($file =~ /_\d{4}_\d{2}_\d{2}_\d{2}_\d{2}_\d{2}$/);
|
||||
push @bkps, 'recover-'.$file;
|
||||
}
|
||||
|
||||
closedir (DIR);
|
||||
my $rf = @bkps ? ','.join ",", reverse sort @bkps : '';
|
||||
|
||||
## allg. gültige Setter
|
||||
#########################
|
||||
$setlist = "Unknown argument $opt, choose one of ".
|
||||
@ -1167,12 +1189,12 @@ sub Set {
|
||||
"energyH4Trigger:textField-long ".
|
||||
"inverterStrings ".
|
||||
"modulePeakString ".
|
||||
"operatingMemory:backup,save".$rf." ".
|
||||
"operationMode:active,inactive ".
|
||||
"plantConfiguration:check,save,restore ".
|
||||
"powerTrigger:textField-long ".
|
||||
"pvCorrectionFactor_Auto:noLearning,on_simple".($ipai ? ',on_simple_ai,' : ',')."on_complex".($ipai ? ',on_complex_ai,' : ',')."off ".
|
||||
"reset:$resets ".
|
||||
"writeHistory:noArg ".
|
||||
$cf." "
|
||||
;
|
||||
|
||||
@ -1862,7 +1884,7 @@ sub _setplantConfiguration { ## no critic "not used"
|
||||
}
|
||||
|
||||
if ($arg eq "save") {
|
||||
$err = writeCacheToFile ($hash, "plantconfig", $plantcfg.$name); # Anlagenkonfiguration File schreiben
|
||||
$err = writeCacheToFile ($hash, 'plantconfig', $plantcfg.$name); # Anlagenkonfiguration File schreiben
|
||||
if ($err) {
|
||||
return $err;
|
||||
}
|
||||
@ -1876,6 +1898,7 @@ sub _setplantConfiguration { ## no critic "not used"
|
||||
|
||||
if (!$err) {
|
||||
my $rbit = 0;
|
||||
|
||||
for my $elem (@pvconf) {
|
||||
my ($reading, $val) = split "<>", $elem;
|
||||
next if(!$reading || !defined $val);
|
||||
@ -2237,19 +2260,47 @@ return;
|
||||
}
|
||||
|
||||
################################################################
|
||||
# Setter writeHistory
|
||||
# Setter operatingMemory
|
||||
# (Ersatz für Setter writeHistory)
|
||||
################################################################
|
||||
sub _setwriteHistory { ## no critic "not used"
|
||||
sub _setoperatingMemory { ## no critic "not used"
|
||||
my $paref = shift;
|
||||
my $hash = $paref->{hash};
|
||||
my $name = $paref->{name};
|
||||
my $prop = $paref->{prop} // return qq{no operation specified for command};
|
||||
|
||||
my $ret = writeCacheToFile ($hash, "circular", $pvccache.$name); # Cache File für PV Circular schreiben
|
||||
return $ret if($ret);
|
||||
if ($prop eq 'save') {
|
||||
periodicWriteCachefiles ($hash); # Cache File für PV History, PV Circular schreiben
|
||||
}
|
||||
|
||||
$ret = writeCacheToFile ($hash, "pvhist", $pvhcache.$name); # Cache File für PV History schreiben
|
||||
if ($prop eq 'backup') {
|
||||
periodicWriteCachefiles ($hash, 'bckp'); # Backup Files erstellen und alte Versionen löschen
|
||||
}
|
||||
|
||||
return $ret;
|
||||
if ($prop =~ /^recover-/xs) { # Sicherung wiederherstellen
|
||||
my $file = (split "-", $prop)[1];
|
||||
|
||||
Log3 ($name, 3, "$name - recover saved cache file: $file");
|
||||
|
||||
if ($file =~ /^PVH_/xs) { # Cache File PV History einlesen
|
||||
$paref->{cachename} = 'pvhist';
|
||||
$paref->{title} = 'pvHistory';
|
||||
}
|
||||
|
||||
if ($file =~ /^PVC_/xs) { # Cache File PV Circular einlesen
|
||||
$paref->{cachename} = 'circular';
|
||||
$paref->{title} = 'pvCircular';
|
||||
}
|
||||
|
||||
$paref->{file} = "$cachedir/$file";
|
||||
_readCacheFile ($paref);
|
||||
|
||||
delete $paref->{file};
|
||||
delete $paref->{cachename};
|
||||
delete $paref->{title};
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
################################################################
|
||||
@ -4700,9 +4751,12 @@ sub deleteOldBckpFiles {
|
||||
my $max = int @files - $dfk;
|
||||
|
||||
for (my $i = 0; $i < $max; $i++) {
|
||||
unlink "$cachedir/$files[$i]";
|
||||
my $done = 1;
|
||||
unlink "$cachedir/$files[$i]" or do { Log3 ($name, 1, "$name - WARNING - Could not delete '$cachedir/$files[$i]': $!");
|
||||
$done = 0;
|
||||
};
|
||||
|
||||
Log3 ($name, 3, "$name - old backup file '$cachedir/$files[$i]' deleted");
|
||||
Log3 ($name, 3, "$name - old backup file '$cachedir/$files[$i]' deleted") if($done);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -12073,7 +12127,8 @@ sub finishTrain {
|
||||
name => $name,
|
||||
type => $type,
|
||||
file => $aitrained.$name,
|
||||
cachename => 'aitrained'
|
||||
cachename => 'aitrained',
|
||||
title => 'aiTrainedData'
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -16132,6 +16187,33 @@ to ensure that the system configuration is correct.
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul>
|
||||
<a id="SolarForecast-set-operatingMemory"></a>
|
||||
<li><b>operatingMemory backup | save | recover-<File> </b> <br><br>
|
||||
|
||||
The pvHistory (PVH) and pvCircular (PVC) components of the internal cache database are stored in the file system. <br>
|
||||
The target directory is "../FHEM/FhemUtils". This process is carried out regularly by the module in the background. <br><br>
|
||||
|
||||
<ul>
|
||||
<table>
|
||||
<colgroup> <col width="17%"> <col width="83%"> </colgroup>
|
||||
<tr><td> <b>backup</b> </td><td>Saves the active in-memory structures with the current timestamp. </td></tr>
|
||||
<tr><td> </td><td><a href="#SolarForecast-attr-ctrlBackupFilesKeep">ctrlBackupFilesKeep</a> generations of the files are saved. Older versions are deleted. </td></tr>
|
||||
<tr><td> </td><td>Files: PVH_SolarForecast_<name>_<Timestamp>, PVC_SolarForecast_<name>_<Timestamp> </td></tr>
|
||||
<tr><td> </td><td> </td></tr>
|
||||
<tr><td> <b>save</b> </td><td>The active in-memory structures are saved. </td></tr>
|
||||
<tr><td> </td><td>Files: PVH_SolarForecast_<name>, PVC_SolarForecast_<name> </td></tr>
|
||||
<tr><td> </td><td> </td></tr>
|
||||
<tr><td> <b>recover-<File></b> </td><td>Restores the data of the selected backup file as an active in-memory structure. </td></tr>
|
||||
<tr><td> </td><td>To avoid inconsistencies, the PVH.* and PVC.* files should be restored in pairs </td></tr>
|
||||
<tr><td> </td><td>with the same time stamp. </td></tr>
|
||||
</table>
|
||||
</ul>
|
||||
<br>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
|
||||
<ul>
|
||||
<a id="SolarForecast-set-operationMode"></a>
|
||||
<li><b>operationMode </b> <br><br>
|
||||
@ -16379,17 +16461,6 @@ to ensure that the system configuration is correct.
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul>
|
||||
<a id="SolarForecast-set-writeHistory"></a>
|
||||
<li><b>writeHistory </b> <br><br>
|
||||
|
||||
The internal cache database is stored in the file system. By default, this process is
|
||||
regularly in the background. In the internal "LCACHEFILE", the last file written and the time
|
||||
of the last storage is documented. <br>
|
||||
</li>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
@ -16987,8 +17058,16 @@ to ensure that the system configuration is correct.
|
||||
</li>
|
||||
<br>
|
||||
|
||||
<a id="SolarForecast-attr-ctrlBackupFilesKeep"></a>
|
||||
<li><b>ctrlBackupFilesKeep</b><br>
|
||||
Defines the number of generations of backup files
|
||||
(see also <a href="#SolarForecast-set-operatingMemory">set <name> operatingMemory backup</a>). <br>
|
||||
(default: 3)
|
||||
</li>
|
||||
<br>
|
||||
|
||||
<a id="SolarForecast-attr-ctrlBatSocManagement"></a>
|
||||
<li><b>ctrlBatSocManagement lowSoc=<Value> upSoC=<Value> [maxSoC=<Value>] [careCycle=<Value>] </b><br>
|
||||
<li><b>ctrlBatSocManagement lowSoc=<Value> upSoC=<Value> [maxSoC=<Value>] [careCycle=<Value>] </b> <br><br>
|
||||
If a battery device (currentBatteryDev) is installed, this attribute activates the battery SoC management. <br>
|
||||
The <b>Battery_OptimumTargetSoC</b> reading contains the optimum minimum SoC calculated by the module. <br>
|
||||
The <b>Battery_ChargeRequest</b> reading is set to '1' if the current SoC has fallen below the minimum SoC. <br>
|
||||
@ -18184,6 +18263,33 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul>
|
||||
<a id="SolarForecast-set-operatingMemory"></a>
|
||||
<li><b>operatingMemory backup | save | recover-<Datei> </b> <br><br>
|
||||
|
||||
Die Komponenten pvHistory (PVH) und pvCircular (PVC) der internen Cache Datenbank werden im Filesystem gespeichert. <br>
|
||||
Das Zielverzeichnis ist "../FHEM/FhemUtils". Dieser Vorgang wird vom Modul regelmäßig im Hintergrund ausgeführt. <br><br>
|
||||
|
||||
<ul>
|
||||
<table>
|
||||
<colgroup> <col width="17%"> <col width="83%"> </colgroup>
|
||||
<tr><td> <b>backup</b> </td><td>Sichert die aktiven In-Memory Strukturen mit dem aktuellen Zeitstempel. </td></tr>
|
||||
<tr><td> </td><td>Es werden <a href="#SolarForecast-attr-ctrlBackupFilesKeep">ctrlBackupFilesKeep</a> Generationen der Dateien gespeichert. Ältere Versionen werden gelöscht. </td></tr>
|
||||
<tr><td> </td><td>Dateien: PVH_SolarForecast_<name>_<Zeitstempel>, PVC_SolarForecast_<name>_<Zeitstempel> </td></tr>
|
||||
<tr><td> </td><td> </td></tr>
|
||||
<tr><td> <b>save</b> </td><td>Die aktiven In-Memory Strukturen werden gespeichert. </td></tr>
|
||||
<tr><td> </td><td>Dateien: PVH_SolarForecast_<name>, PVC_SolarForecast_<name> </td></tr>
|
||||
<tr><td> </td><td> </td></tr>
|
||||
<tr><td> <b>recover-<Datei></b> </td><td>Stellt die Daten der ausgewählten Sicherungsdatei als aktive In-Memory Struktur wieder her. </td></tr>
|
||||
<tr><td> </td><td>Um Inkonsistenzen zu vermeiden, sollten die Dateien PVH.* und PVC.* mit dem gleichen </td></tr>
|
||||
<tr><td> </td><td>Zeitstempel paarweise recovert werden. </td></tr>
|
||||
</table>
|
||||
</ul>
|
||||
<br>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
|
||||
<ul>
|
||||
<a id="SolarForecast-set-operationMode"></a>
|
||||
<li><b>operationMode </b> <br><br>
|
||||
@ -18438,17 +18544,6 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul>
|
||||
<a id="SolarForecast-set-writeHistory"></a>
|
||||
<li><b>writeHistory </b> <br><br>
|
||||
|
||||
Die interne Cache Datenbank wird im Filesystem gespeichert. Dieser Vorgang wird per default
|
||||
regelmäßig im Hintergrund ausgeführt. Im Internal "LCACHEFILE" wird die letzte geschriebene Datei und der Zeitpunkt
|
||||
der letzten Speicherung dokumentiert. <br>
|
||||
</li>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
@ -19046,8 +19141,16 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
|
||||
</li>
|
||||
<br>
|
||||
|
||||
<a id="SolarForecast-attr-ctrlBackupFilesKeep"></a>
|
||||
<li><b>ctrlBackupFilesKeep</b><br>
|
||||
Legt die Anzahl der Generationen von Sicherungsdateien
|
||||
(siehe <a href="#SolarForecast-set-operatingMemory">set <name> operatingMemory backup</a>) fest. <br>
|
||||
(default: 3)
|
||||
</li>
|
||||
<br>
|
||||
|
||||
<a id="SolarForecast-attr-ctrlBatSocManagement"></a>
|
||||
<li><b>ctrlBatSocManagement lowSoc=<Wert> upSoC=<Wert> [maxSoC=<Wert>] [careCycle=<Wert>] </b><br>
|
||||
<li><b>ctrlBatSocManagement lowSoc=<Wert> upSoC=<Wert> [maxSoC=<Wert>] [careCycle=<Wert>] </b> <br><br>
|
||||
Sofern ein Batterie Device (currentBatteryDev) installiert ist, aktiviert dieses Attribut das Batterie
|
||||
SoC-Management. <br>
|
||||
Das Reading <b>Battery_OptimumTargetSoC</b> enthält den vom Modul berechneten optimalen Mindest-SoC. <br>
|
||||
|
Loading…
Reference in New Issue
Block a user