mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 06:39:11 +00:00
76_SolarForecast: extended Debug collectData for EnergyConsumption
git-svn-id: https://svn.fhem.de/fhem/trunk@29370 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
4a079a1bb2
commit
b1cc861b9e
@ -1,5 +1,6 @@
|
|||||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||||
# Do not insert empty lines here, update check depends on it
|
# Do not insert empty lines here, update check depends on it
|
||||||
|
- change: 76_SolarForecast: extended Debug collectData for EnergyConsumption
|
||||||
- bugfix: 49_SSCam: some fixes API does not exist
|
- bugfix: 49_SSCam: some fixes API does not exist
|
||||||
- change: 76_SolarForecast: Attr flowGraphicControl key shift changed to
|
- change: 76_SolarForecast: Attr flowGraphicControl key shift changed to
|
||||||
shiftx, new key shifty,
|
shiftx, new key shifty,
|
||||||
|
@ -156,6 +156,8 @@ BEGIN {
|
|||||||
|
|
||||||
# Versions History intern
|
# Versions History intern
|
||||||
my %vNotesIntern = (
|
my %vNotesIntern = (
|
||||||
|
"1.37.8" => "27.11.2024 edit commref, func _searchCacheFiles for renaming Cache files when device is renamed ".
|
||||||
|
"_saveEnergyConsumption: extended for Debug collectData ",
|
||||||
"1.37.7" => "26.11.2024 Attr flowGraphicControl: key shift changed to shiftx, new key shifty ".
|
"1.37.7" => "26.11.2024 Attr flowGraphicControl: key shift changed to shiftx, new key shifty ".
|
||||||
"change: 'trackFlex' && \$wcc >= 70 to \$wcc >= 80 ".
|
"change: 'trackFlex' && \$wcc >= 70 to \$wcc >= 80 ".
|
||||||
"obsolete Attr deleted: flowGraphicCss, flowGraphicSize, flowGraphicAnimate, flowGraphicConsumerDistance, ".
|
"obsolete Attr deleted: flowGraphicCss, flowGraphicSize, flowGraphicAnimate, flowGraphicConsumerDistance, ".
|
||||||
@ -350,7 +352,7 @@ my %vNotesIntern = (
|
|||||||
|
|
||||||
## Standardvariablen
|
## Standardvariablen
|
||||||
######################
|
######################
|
||||||
my @da; # Readings-Store
|
my @da; # zentraler Readings-Store
|
||||||
my $deflang = 'EN'; # default Sprache wenn nicht konfiguriert
|
my $deflang = 'EN'; # default Sprache wenn nicht konfiguriert
|
||||||
my @chours = (5..21); # Stunden des Tages mit möglichen Korrekturwerten
|
my @chours = (5..21); # Stunden des Tages mit möglichen Korrekturwerten
|
||||||
my $kJtokWh = 0.0002777777778; # Umrechnungsfaktor kJ in kWh
|
my $kJtokWh = 0.0002777777778; # Umrechnungsfaktor kJ in kWh
|
||||||
@ -6359,6 +6361,15 @@ sub Rename {
|
|||||||
$data{$type}{$new_name} = $data{$type}{$old_name};
|
$data{$type}{$new_name} = $data{$type}{$old_name};
|
||||||
delete $data{$type}{$old_name};
|
delete $data{$type}{$old_name};
|
||||||
|
|
||||||
|
my @ftd = _searchCacheFiles ($old_name);
|
||||||
|
|
||||||
|
for my $oldf (@ftd) {
|
||||||
|
my $newf = $oldf;
|
||||||
|
$newf =~ s/_SolarForecast_${old_name}/_SolarForecast_${new_name}/xsg;
|
||||||
|
rename ($oldf, $newf) or
|
||||||
|
Log3 ($new_name, 2, qq{$new_name - WARNING - File "$oldf" could not be renamed: $!});
|
||||||
|
}
|
||||||
|
|
||||||
# Log3 ($new_name, 1, qq{$new_name - Dump -> \n}. Dumper $data{$type}{$new_name});
|
# Log3 ($new_name, 1, qq{$new_name - Dump -> \n}. Dumper $data{$type}{$new_name});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -6414,26 +6425,7 @@ sub Delete {
|
|||||||
my $arg = shift;
|
my $arg = shift;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
my @ftd = ( $pvhcache.$name,
|
my @ftd = _searchCacheFiles ($name);
|
||||||
$pvccache.$name,
|
|
||||||
$plantcfg.$name,
|
|
||||||
$csmcache.$name,
|
|
||||||
$scpicache.$name,
|
|
||||||
$airaw.$name,
|
|
||||||
$aitrained.$name,
|
|
||||||
$pvhexprtcsv.$name
|
|
||||||
);
|
|
||||||
|
|
||||||
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 @ftd, "$cachedir/$file";
|
|
||||||
}
|
|
||||||
|
|
||||||
closedir (DIR);
|
|
||||||
|
|
||||||
for my $f (@ftd) {
|
for my $f (@ftd) {
|
||||||
my $err = FileDelete ($f);
|
my $err = FileDelete ($f);
|
||||||
@ -6442,7 +6434,7 @@ sub Delete {
|
|||||||
Log3 ($name, 1, qq{$name - Message while deleting file "$f": $err});
|
Log3 ($name, 1, qq{$name - Message while deleting file "$f": $err});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Log3 ($name, 3, qq{$name - INFO - File "$f" successfully deleted.});
|
Log3 ($name, 3, qq{$name - INFO - File "$f" deleted.});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6453,6 +6445,28 @@ sub Delete {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#################################################################
|
||||||
|
# Cache Files im Cache Directory suchen und als Array
|
||||||
|
# zurückliefern
|
||||||
|
#################################################################
|
||||||
|
sub _searchCacheFiles {
|
||||||
|
my $name = shift;
|
||||||
|
|
||||||
|
my @ftd;
|
||||||
|
|
||||||
|
opendir (DIR, $cachedir);
|
||||||
|
|
||||||
|
while (my $file = readdir (DIR)) {
|
||||||
|
next unless (-f "$cachedir/$file");
|
||||||
|
next unless ($file =~ /_SolarForecast_${name}/);
|
||||||
|
push @ftd, "$cachedir/$file";
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir (DIR);
|
||||||
|
|
||||||
|
return @ftd;
|
||||||
|
}
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
# Timer schreiben Memory Struktur in File
|
# Timer schreiben Memory Struktur in File
|
||||||
################################################################
|
################################################################
|
||||||
@ -11847,26 +11861,28 @@ sub _saveEnergyConsumption {
|
|||||||
my $paref = shift;
|
my $paref = shift;
|
||||||
my $name = $paref->{name};
|
my $name = $paref->{name};
|
||||||
my $chour = $paref->{chour};
|
my $chour = $paref->{chour};
|
||||||
|
my $debug = $paref->{debug};
|
||||||
|
|
||||||
my $shr = sprintf "%02d", ($chour + 1);
|
my $shr = sprintf "%02d", ($chour + 1);
|
||||||
my $pvrl = ReadingsNum ($name, "Today_Hour".$shr."_PVreal", 0);
|
my $pvrl = ReadingsNum ($name, "Today_Hour".$shr."_PVreal", 0); # Reading enthält die Summe aller Inverterdevices
|
||||||
my $gfeedin = ReadingsNum ($name, "Today_Hour".$shr."_GridFeedIn", 0);
|
my $gfeedin = ReadingsNum ($name, "Today_Hour".$shr."_GridFeedIn", 0);
|
||||||
my $gcon = ReadingsNum ($name, "Today_Hour".$shr."_GridConsumption", 0);
|
my $gcon = ReadingsNum ($name, "Today_Hour".$shr."_GridConsumption", 0);
|
||||||
my $batin = ReadingsNum ($name, "Today_Hour".$shr."_BatIn", 0);
|
my $batin = ReadingsNum ($name, "Today_Hour".$shr."_BatIn", 0);
|
||||||
my $batout = ReadingsNum ($name, "Today_Hour".$shr."_BatOut", 0);
|
my $batout = ReadingsNum ($name, "Today_Hour".$shr."_BatOut", 0);
|
||||||
|
my $ppreal = 0;
|
||||||
|
|
||||||
my $con = $pvrl - $gfeedin + $gcon - $batin + $batout;
|
for my $prn (1..$maxproducer) { # V1.32.0 : Erzeugung sonstiger Producer (01..03) hinzufügen
|
||||||
|
$prn = sprintf "%02d", $prn;
|
||||||
for my $prn (1..$maxproducer) { # V1.32.0 : Erzeugung sonstiger Producer (01..03) hinzufügen
|
$ppreal += ReadingsNum ($name, "Today_Hour".$shr."_PPreal".$prn, 0);
|
||||||
$prn = sprintf "%02d", $prn;
|
|
||||||
$con += ReadingsNum ($name, "Today_Hour".$shr."_PPreal".$prn, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (int $paref->{minute} > 30 && $con < 0) { # V1.32.0 : erst den "eingeschwungenen" Zustand mit mehreren Meßwerten auswerten
|
my $con = $pvrl + $ppreal - $gfeedin + $gcon - $batin + $batout;
|
||||||
|
|
||||||
|
if (int $paref->{minute} > 30 && $con < 0) { # V1.32.0 : erst den "eingeschwungenen" Zustand mit mehreren Meßwerten auswerten
|
||||||
my $vl = 3;
|
my $vl = 3;
|
||||||
my $pre = '- WARNING -';
|
my $pre = '- WARNING -';
|
||||||
|
|
||||||
if ($paref->{debug} =~ /consumption/xs) {
|
if ($debug =~ /consumption/xs) {
|
||||||
$vl = 1;
|
$vl = 1;
|
||||||
$pre = 'DEBUG> - WARNING -';
|
$pre = 'DEBUG> - WARNING -';
|
||||||
}
|
}
|
||||||
@ -11874,6 +11890,11 @@ sub _saveEnergyConsumption {
|
|||||||
Log3 ($name, $vl, "$name $pre The calculated Energy consumption of the house is negative. This appears to be an error. Check Readings _PVreal, _GridFeedIn, _GridConsumption, _BatIn, _BatOut of hour >$shr<");
|
Log3 ($name, $vl, "$name $pre The calculated Energy consumption of the house is negative. This appears to be an error. Check Readings _PVreal, _GridFeedIn, _GridConsumption, _BatIn, _BatOut of hour >$shr<");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($debug =~ /collectData/xs) {
|
||||||
|
Log3 ($name, 1, "$name DEBUG> EnergyConsumption input -> PV: $pvrl, PP: $ppreal, GridIn: $gfeedin, GridCon: $gcon, BatIn: $batin, BatOut: $batout");
|
||||||
|
Log3 ($name, 1, "$name DEBUG> EnergyConsumption result -> $con Wh");
|
||||||
|
}
|
||||||
|
|
||||||
writeToHistory ( { paref => $paref, key => 'con', val => $con, hour => $shr } );
|
writeToHistory ( { paref => $paref, key => 'con', val => $con, hour => $shr } );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -21010,11 +21031,15 @@ to ensure that the system configuration is correct.
|
|||||||
<a id="SolarForecast-attr-ctrlInterval"></a>
|
<a id="SolarForecast-attr-ctrlInterval"></a>
|
||||||
<li><b>ctrlInterval <Sekunden> </b><br>
|
<li><b>ctrlInterval <Sekunden> </b><br>
|
||||||
Repetition interval of the data collection. <br>
|
Repetition interval of the data collection. <br>
|
||||||
Regardless of the set interval, data is collected automatically a few seconds before the end and after the start
|
If ctrlInterval is explicitly set to “0”, no regular data collection takes place and must be started externally
|
||||||
of a full hour. <br>
|
with “get <name> data”. <br>
|
||||||
If ctrlInterval is explicitly set to "0", no automatic data collection takes place and must be carried out
|
|
||||||
externally with "get <name> data". <br>
|
|
||||||
(default: 70)
|
(default: 70)
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
<b>Note:</b> Regardless of the set interval (even with “0”), data is collected automatically a few seconds
|
||||||
|
before the end and after the start of a full hour. <br>
|
||||||
|
Furthermore, data is collected automatically when an event from a device defined as “asynchron”
|
||||||
|
device (consumer, meter, etc.) is received and processed.
|
||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
<a id="SolarForecast-attr-ctrlLanguage"></a>
|
<a id="SolarForecast-attr-ctrlLanguage"></a>
|
||||||
@ -21637,7 +21662,7 @@ to ensure that the system configuration is correct.
|
|||||||
<tr><td> </td><td>If 'strings' is not specified, all defined string names are assigned to the inverter. </td></tr>
|
<tr><td> </td><td>If 'strings' is not specified, all defined string names are assigned to the inverter. </td></tr>
|
||||||
<tr><td> <b>feed</b> </td><td>Defines special properties of the device's energy supply (optional). </td></tr>
|
<tr><td> <b>feed</b> </td><td>Defines special properties of the device's energy supply (optional). </td></tr>
|
||||||
<tr><td> </td><td>If the key is not set, the device feeds the PV energy into the house's AC grid. </td></tr>
|
<tr><td> </td><td>If the key is not set, the device feeds the PV energy into the house's AC grid. </td></tr>
|
||||||
<tr><td> </td><td><b>bat</b> - the device supplies energy exclusively to the battery </td></tr>
|
<tr><td> </td><td><b>bat</b> - Solar charger for direct battery charging. Any surplus is fed into the inverter/house network. </td></tr>
|
||||||
<tr><td> </td><td><b>grid</b> - the energy is fed exclusively into the public grid </td></tr>
|
<tr><td> </td><td><b>grid</b> - the energy is fed exclusively into the public grid </td></tr>
|
||||||
<tr><td> <b>limit</b> </td><td>Defines any active power limitation in % (optional). </td></tr>
|
<tr><td> <b>limit</b> </td><td>Defines any active power limitation in % (optional). </td></tr>
|
||||||
<tr><td> <b>icon</b> </td><td>Icon for displaying the inverter in the flow chart (optional) </td></tr>
|
<tr><td> <b>icon</b> </td><td>Icon for displaying the inverter in the flow chart (optional) </td></tr>
|
||||||
@ -23376,11 +23401,15 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
|
|||||||
<a id="SolarForecast-attr-ctrlInterval"></a>
|
<a id="SolarForecast-attr-ctrlInterval"></a>
|
||||||
<li><b>ctrlInterval <Sekunden> </b><br>
|
<li><b>ctrlInterval <Sekunden> </b><br>
|
||||||
Wiederholungsintervall der Datensammlung. <br>
|
Wiederholungsintervall der Datensammlung. <br>
|
||||||
Unabhängig vom eingestellten Intervall erfolgt einige Sekunden vor dem Ende sowie nach dem Beginn einer
|
Ist ctrlInterval explizit auf "0" gesetzt, erfolgt keine regelmäßige Datensammlung und muss mit
|
||||||
vollen Stunde eine automatische Datensammlung. <br>
|
"get <name> data" extern gestartet werden. <br>
|
||||||
Ist ctrlInterval explizit auf "0" gesetzt, erfolgt keinerlei automatische Datensammlung und muss mit
|
|
||||||
"get <name> data" extern erfolgen. <br>
|
|
||||||
(default: 70)
|
(default: 70)
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
<b>Hinweis:</b> Unabhängig vom eingestellten Intervall (auch bei "0") erfolgt einige Sekunden vor dem Ende
|
||||||
|
sowie nach dem Beginn einer vollen Stunde eine automatische Datensammlung. <br>
|
||||||
|
Weiterhin erfolgt eine automatische Datensammlung wenn ein Event eines als "asynchron"
|
||||||
|
definierten Gerätes (Consumer, Meter, etc.) empfangen und verarbeitet wird.
|
||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
<a id="SolarForecast-attr-ctrlLanguage"></a>
|
<a id="SolarForecast-attr-ctrlLanguage"></a>
|
||||||
@ -24003,7 +24032,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
|
|||||||
<tr><td> </td><td>Ist 'strings' nicht angegeben, werden alle definierten Stringnamen dem Wechselrichter zugeordnet. </td></tr>
|
<tr><td> </td><td>Ist 'strings' nicht angegeben, werden alle definierten Stringnamen dem Wechselrichter zugeordnet. </td></tr>
|
||||||
<tr><td> <b>feed</b> </td><td>Definiert spezielle Eigenschaften der Energielieferung des Gerätes (optional). </td></tr>
|
<tr><td> <b>feed</b> </td><td>Definiert spezielle Eigenschaften der Energielieferung des Gerätes (optional). </td></tr>
|
||||||
<tr><td> </td><td>Ist der Schlüssel nicht gesetzt, speist das Gerät die PV-Energie in das Wechselstromnetz des Hauses ein. </td></tr>
|
<tr><td> </td><td>Ist der Schlüssel nicht gesetzt, speist das Gerät die PV-Energie in das Wechselstromnetz des Hauses ein. </td></tr>
|
||||||
<tr><td> </td><td><b>bat</b> - das Gerät liefert die Energie ausschließlich an die Batterie </td></tr>
|
<tr><td> </td><td><b>bat</b> - Solar-Ladegerät zur Batterie Direktladung. Ein Überschuß wird dem Inverter/Hausnetz zugeführt. </td></tr>
|
||||||
<tr><td> </td><td><b>grid</b> - die Energie wird ausschließlich in das öffentlich Netz eingespeist </td></tr>
|
<tr><td> </td><td><b>grid</b> - die Energie wird ausschließlich in das öffentlich Netz eingespeist </td></tr>
|
||||||
<tr><td> <b>limit</b> </td><td>Definiert eine eventuelle Wirkleistungsbeschränkung in % (optional). </td></tr>
|
<tr><td> <b>limit</b> </td><td>Definiert eine eventuelle Wirkleistungsbeschränkung in % (optional). </td></tr>
|
||||||
<tr><td> <b>icon</b> </td><td>Icon zur Darstellung des Inverters in der Flowgrafik (optional) </td></tr>
|
<tr><td> <b>icon</b> </td><td>Icon zur Darstellung des Inverters in der Flowgrafik (optional) </td></tr>
|
||||||
|
@ -156,6 +156,8 @@ BEGIN {
|
|||||||
|
|
||||||
# Versions History intern
|
# Versions History intern
|
||||||
my %vNotesIntern = (
|
my %vNotesIntern = (
|
||||||
|
"1.37.8" => "27.11.2024 edit commref, func _searchCacheFiles for renaming Cache files when device is renamed ".
|
||||||
|
"_saveEnergyConsumption: extended for Debug collectData ",
|
||||||
"1.37.7" => "26.11.2024 Attr flowGraphicControl: key shift changed to shiftx, new key shifty ".
|
"1.37.7" => "26.11.2024 Attr flowGraphicControl: key shift changed to shiftx, new key shifty ".
|
||||||
"change: 'trackFlex' && \$wcc >= 70 to \$wcc >= 80 ".
|
"change: 'trackFlex' && \$wcc >= 70 to \$wcc >= 80 ".
|
||||||
"obsolete Attr deleted: flowGraphicCss, flowGraphicSize, flowGraphicAnimate, flowGraphicConsumerDistance, ".
|
"obsolete Attr deleted: flowGraphicCss, flowGraphicSize, flowGraphicAnimate, flowGraphicConsumerDistance, ".
|
||||||
@ -350,7 +352,7 @@ my %vNotesIntern = (
|
|||||||
|
|
||||||
## Standardvariablen
|
## Standardvariablen
|
||||||
######################
|
######################
|
||||||
my @da; # Readings-Store
|
my @da; # zentraler Readings-Store
|
||||||
my $deflang = 'EN'; # default Sprache wenn nicht konfiguriert
|
my $deflang = 'EN'; # default Sprache wenn nicht konfiguriert
|
||||||
my @chours = (5..21); # Stunden des Tages mit möglichen Korrekturwerten
|
my @chours = (5..21); # Stunden des Tages mit möglichen Korrekturwerten
|
||||||
my $kJtokWh = 0.0002777777778; # Umrechnungsfaktor kJ in kWh
|
my $kJtokWh = 0.0002777777778; # Umrechnungsfaktor kJ in kWh
|
||||||
@ -6359,6 +6361,15 @@ sub Rename {
|
|||||||
$data{$type}{$new_name} = $data{$type}{$old_name};
|
$data{$type}{$new_name} = $data{$type}{$old_name};
|
||||||
delete $data{$type}{$old_name};
|
delete $data{$type}{$old_name};
|
||||||
|
|
||||||
|
my @ftd = _searchCacheFiles ($old_name);
|
||||||
|
|
||||||
|
for my $oldf (@ftd) {
|
||||||
|
my $newf = $oldf;
|
||||||
|
$newf =~ s/_SolarForecast_${old_name}/_SolarForecast_${new_name}/xsg;
|
||||||
|
rename ($oldf, $newf) or
|
||||||
|
Log3 ($new_name, 2, qq{$new_name - WARNING - File "$oldf" could not be renamed: $!});
|
||||||
|
}
|
||||||
|
|
||||||
# Log3 ($new_name, 1, qq{$new_name - Dump -> \n}. Dumper $data{$type}{$new_name});
|
# Log3 ($new_name, 1, qq{$new_name - Dump -> \n}. Dumper $data{$type}{$new_name});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -6414,26 +6425,7 @@ sub Delete {
|
|||||||
my $arg = shift;
|
my $arg = shift;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
my @ftd = ( $pvhcache.$name,
|
my @ftd = _searchCacheFiles ($name);
|
||||||
$pvccache.$name,
|
|
||||||
$plantcfg.$name,
|
|
||||||
$csmcache.$name,
|
|
||||||
$scpicache.$name,
|
|
||||||
$airaw.$name,
|
|
||||||
$aitrained.$name,
|
|
||||||
$pvhexprtcsv.$name
|
|
||||||
);
|
|
||||||
|
|
||||||
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 @ftd, "$cachedir/$file";
|
|
||||||
}
|
|
||||||
|
|
||||||
closedir (DIR);
|
|
||||||
|
|
||||||
for my $f (@ftd) {
|
for my $f (@ftd) {
|
||||||
my $err = FileDelete ($f);
|
my $err = FileDelete ($f);
|
||||||
@ -6442,7 +6434,7 @@ sub Delete {
|
|||||||
Log3 ($name, 1, qq{$name - Message while deleting file "$f": $err});
|
Log3 ($name, 1, qq{$name - Message while deleting file "$f": $err});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Log3 ($name, 3, qq{$name - INFO - File "$f" successfully deleted.});
|
Log3 ($name, 3, qq{$name - INFO - File "$f" deleted.});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6453,6 +6445,28 @@ sub Delete {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#################################################################
|
||||||
|
# Cache Files im Cache Directory suchen und als Array
|
||||||
|
# zurückliefern
|
||||||
|
#################################################################
|
||||||
|
sub _searchCacheFiles {
|
||||||
|
my $name = shift;
|
||||||
|
|
||||||
|
my @ftd;
|
||||||
|
|
||||||
|
opendir (DIR, $cachedir);
|
||||||
|
|
||||||
|
while (my $file = readdir (DIR)) {
|
||||||
|
next unless (-f "$cachedir/$file");
|
||||||
|
next unless ($file =~ /_SolarForecast_${name}/);
|
||||||
|
push @ftd, "$cachedir/$file";
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir (DIR);
|
||||||
|
|
||||||
|
return @ftd;
|
||||||
|
}
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
# Timer schreiben Memory Struktur in File
|
# Timer schreiben Memory Struktur in File
|
||||||
################################################################
|
################################################################
|
||||||
@ -11847,26 +11861,28 @@ sub _saveEnergyConsumption {
|
|||||||
my $paref = shift;
|
my $paref = shift;
|
||||||
my $name = $paref->{name};
|
my $name = $paref->{name};
|
||||||
my $chour = $paref->{chour};
|
my $chour = $paref->{chour};
|
||||||
|
my $debug = $paref->{debug};
|
||||||
|
|
||||||
my $shr = sprintf "%02d", ($chour + 1);
|
my $shr = sprintf "%02d", ($chour + 1);
|
||||||
my $pvrl = ReadingsNum ($name, "Today_Hour".$shr."_PVreal", 0);
|
my $pvrl = ReadingsNum ($name, "Today_Hour".$shr."_PVreal", 0); # Reading enthält die Summe aller Inverterdevices
|
||||||
my $gfeedin = ReadingsNum ($name, "Today_Hour".$shr."_GridFeedIn", 0);
|
my $gfeedin = ReadingsNum ($name, "Today_Hour".$shr."_GridFeedIn", 0);
|
||||||
my $gcon = ReadingsNum ($name, "Today_Hour".$shr."_GridConsumption", 0);
|
my $gcon = ReadingsNum ($name, "Today_Hour".$shr."_GridConsumption", 0);
|
||||||
my $batin = ReadingsNum ($name, "Today_Hour".$shr."_BatIn", 0);
|
my $batin = ReadingsNum ($name, "Today_Hour".$shr."_BatIn", 0);
|
||||||
my $batout = ReadingsNum ($name, "Today_Hour".$shr."_BatOut", 0);
|
my $batout = ReadingsNum ($name, "Today_Hour".$shr."_BatOut", 0);
|
||||||
|
my $ppreal = 0;
|
||||||
|
|
||||||
my $con = $pvrl - $gfeedin + $gcon - $batin + $batout;
|
for my $prn (1..$maxproducer) { # V1.32.0 : Erzeugung sonstiger Producer (01..03) hinzufügen
|
||||||
|
$prn = sprintf "%02d", $prn;
|
||||||
for my $prn (1..$maxproducer) { # V1.32.0 : Erzeugung sonstiger Producer (01..03) hinzufügen
|
$ppreal += ReadingsNum ($name, "Today_Hour".$shr."_PPreal".$prn, 0);
|
||||||
$prn = sprintf "%02d", $prn;
|
|
||||||
$con += ReadingsNum ($name, "Today_Hour".$shr."_PPreal".$prn, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (int $paref->{minute} > 30 && $con < 0) { # V1.32.0 : erst den "eingeschwungenen" Zustand mit mehreren Meßwerten auswerten
|
my $con = $pvrl + $ppreal - $gfeedin + $gcon - $batin + $batout;
|
||||||
|
|
||||||
|
if (int $paref->{minute} > 30 && $con < 0) { # V1.32.0 : erst den "eingeschwungenen" Zustand mit mehreren Meßwerten auswerten
|
||||||
my $vl = 3;
|
my $vl = 3;
|
||||||
my $pre = '- WARNING -';
|
my $pre = '- WARNING -';
|
||||||
|
|
||||||
if ($paref->{debug} =~ /consumption/xs) {
|
if ($debug =~ /consumption/xs) {
|
||||||
$vl = 1;
|
$vl = 1;
|
||||||
$pre = 'DEBUG> - WARNING -';
|
$pre = 'DEBUG> - WARNING -';
|
||||||
}
|
}
|
||||||
@ -11874,6 +11890,11 @@ sub _saveEnergyConsumption {
|
|||||||
Log3 ($name, $vl, "$name $pre The calculated Energy consumption of the house is negative. This appears to be an error. Check Readings _PVreal, _GridFeedIn, _GridConsumption, _BatIn, _BatOut of hour >$shr<");
|
Log3 ($name, $vl, "$name $pre The calculated Energy consumption of the house is negative. This appears to be an error. Check Readings _PVreal, _GridFeedIn, _GridConsumption, _BatIn, _BatOut of hour >$shr<");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($debug =~ /collectData/xs) {
|
||||||
|
Log3 ($name, 1, "$name DEBUG> EnergyConsumption input -> PV: $pvrl, PP: $ppreal, GridIn: $gfeedin, GridCon: $gcon, BatIn: $batin, BatOut: $batout");
|
||||||
|
Log3 ($name, 1, "$name DEBUG> EnergyConsumption result -> $con Wh");
|
||||||
|
}
|
||||||
|
|
||||||
writeToHistory ( { paref => $paref, key => 'con', val => $con, hour => $shr } );
|
writeToHistory ( { paref => $paref, key => 'con', val => $con, hour => $shr } );
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -21010,11 +21031,15 @@ to ensure that the system configuration is correct.
|
|||||||
<a id="SolarForecast-attr-ctrlInterval"></a>
|
<a id="SolarForecast-attr-ctrlInterval"></a>
|
||||||
<li><b>ctrlInterval <Sekunden> </b><br>
|
<li><b>ctrlInterval <Sekunden> </b><br>
|
||||||
Repetition interval of the data collection. <br>
|
Repetition interval of the data collection. <br>
|
||||||
Regardless of the set interval, data is collected automatically a few seconds before the end and after the start
|
If ctrlInterval is explicitly set to “0”, no regular data collection takes place and must be started externally
|
||||||
of a full hour. <br>
|
with “get <name> data”. <br>
|
||||||
If ctrlInterval is explicitly set to "0", no automatic data collection takes place and must be carried out
|
|
||||||
externally with "get <name> data". <br>
|
|
||||||
(default: 70)
|
(default: 70)
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
<b>Note:</b> Regardless of the set interval (even with “0”), data is collected automatically a few seconds
|
||||||
|
before the end and after the start of a full hour. <br>
|
||||||
|
Furthermore, data is collected automatically when an event from a device defined as “asynchron”
|
||||||
|
device (consumer, meter, etc.) is received and processed.
|
||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
<a id="SolarForecast-attr-ctrlLanguage"></a>
|
<a id="SolarForecast-attr-ctrlLanguage"></a>
|
||||||
@ -21637,7 +21662,7 @@ to ensure that the system configuration is correct.
|
|||||||
<tr><td> </td><td>If 'strings' is not specified, all defined string names are assigned to the inverter. </td></tr>
|
<tr><td> </td><td>If 'strings' is not specified, all defined string names are assigned to the inverter. </td></tr>
|
||||||
<tr><td> <b>feed</b> </td><td>Defines special properties of the device's energy supply (optional). </td></tr>
|
<tr><td> <b>feed</b> </td><td>Defines special properties of the device's energy supply (optional). </td></tr>
|
||||||
<tr><td> </td><td>If the key is not set, the device feeds the PV energy into the house's AC grid. </td></tr>
|
<tr><td> </td><td>If the key is not set, the device feeds the PV energy into the house's AC grid. </td></tr>
|
||||||
<tr><td> </td><td><b>bat</b> - the device supplies energy exclusively to the battery </td></tr>
|
<tr><td> </td><td><b>bat</b> - Solar charger for direct battery charging. Any surplus is fed into the inverter/house network. </td></tr>
|
||||||
<tr><td> </td><td><b>grid</b> - the energy is fed exclusively into the public grid </td></tr>
|
<tr><td> </td><td><b>grid</b> - the energy is fed exclusively into the public grid </td></tr>
|
||||||
<tr><td> <b>limit</b> </td><td>Defines any active power limitation in % (optional). </td></tr>
|
<tr><td> <b>limit</b> </td><td>Defines any active power limitation in % (optional). </td></tr>
|
||||||
<tr><td> <b>icon</b> </td><td>Icon for displaying the inverter in the flow chart (optional) </td></tr>
|
<tr><td> <b>icon</b> </td><td>Icon for displaying the inverter in the flow chart (optional) </td></tr>
|
||||||
@ -23376,11 +23401,15 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
|
|||||||
<a id="SolarForecast-attr-ctrlInterval"></a>
|
<a id="SolarForecast-attr-ctrlInterval"></a>
|
||||||
<li><b>ctrlInterval <Sekunden> </b><br>
|
<li><b>ctrlInterval <Sekunden> </b><br>
|
||||||
Wiederholungsintervall der Datensammlung. <br>
|
Wiederholungsintervall der Datensammlung. <br>
|
||||||
Unabhängig vom eingestellten Intervall erfolgt einige Sekunden vor dem Ende sowie nach dem Beginn einer
|
Ist ctrlInterval explizit auf "0" gesetzt, erfolgt keine regelmäßige Datensammlung und muss mit
|
||||||
vollen Stunde eine automatische Datensammlung. <br>
|
"get <name> data" extern gestartet werden. <br>
|
||||||
Ist ctrlInterval explizit auf "0" gesetzt, erfolgt keinerlei automatische Datensammlung und muss mit
|
|
||||||
"get <name> data" extern erfolgen. <br>
|
|
||||||
(default: 70)
|
(default: 70)
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
<b>Hinweis:</b> Unabhängig vom eingestellten Intervall (auch bei "0") erfolgt einige Sekunden vor dem Ende
|
||||||
|
sowie nach dem Beginn einer vollen Stunde eine automatische Datensammlung. <br>
|
||||||
|
Weiterhin erfolgt eine automatische Datensammlung wenn ein Event eines als "asynchron"
|
||||||
|
definierten Gerätes (Consumer, Meter, etc.) empfangen und verarbeitet wird.
|
||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
<a id="SolarForecast-attr-ctrlLanguage"></a>
|
<a id="SolarForecast-attr-ctrlLanguage"></a>
|
||||||
@ -24003,7 +24032,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
|
|||||||
<tr><td> </td><td>Ist 'strings' nicht angegeben, werden alle definierten Stringnamen dem Wechselrichter zugeordnet. </td></tr>
|
<tr><td> </td><td>Ist 'strings' nicht angegeben, werden alle definierten Stringnamen dem Wechselrichter zugeordnet. </td></tr>
|
||||||
<tr><td> <b>feed</b> </td><td>Definiert spezielle Eigenschaften der Energielieferung des Gerätes (optional). </td></tr>
|
<tr><td> <b>feed</b> </td><td>Definiert spezielle Eigenschaften der Energielieferung des Gerätes (optional). </td></tr>
|
||||||
<tr><td> </td><td>Ist der Schlüssel nicht gesetzt, speist das Gerät die PV-Energie in das Wechselstromnetz des Hauses ein. </td></tr>
|
<tr><td> </td><td>Ist der Schlüssel nicht gesetzt, speist das Gerät die PV-Energie in das Wechselstromnetz des Hauses ein. </td></tr>
|
||||||
<tr><td> </td><td><b>bat</b> - das Gerät liefert die Energie ausschließlich an die Batterie </td></tr>
|
<tr><td> </td><td><b>bat</b> - Solar-Ladegerät zur Batterie Direktladung. Ein Überschuß wird dem Inverter/Hausnetz zugeführt. </td></tr>
|
||||||
<tr><td> </td><td><b>grid</b> - die Energie wird ausschließlich in das öffentlich Netz eingespeist </td></tr>
|
<tr><td> </td><td><b>grid</b> - die Energie wird ausschließlich in das öffentlich Netz eingespeist </td></tr>
|
||||||
<tr><td> <b>limit</b> </td><td>Definiert eine eventuelle Wirkleistungsbeschränkung in % (optional). </td></tr>
|
<tr><td> <b>limit</b> </td><td>Definiert eine eventuelle Wirkleistungsbeschränkung in % (optional). </td></tr>
|
||||||
<tr><td> <b>icon</b> </td><td>Icon zur Darstellung des Inverters in der Flowgrafik (optional) </td></tr>
|
<tr><td> <b>icon</b> </td><td>Icon zur Darstellung des Inverters in der Flowgrafik (optional) </td></tr>
|
||||||
|
Loading…
Reference in New Issue
Block a user