2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-02-25 09:55:38 +00:00

93_DbRep: fix period calculation when using attr timeYearPeriod

git-svn-id: https://svn.fhem.de/fhem/trunk@28140 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2023-11-08 20:57:09 +00:00
parent 74ed39e7bc
commit fa1c51e655
2 changed files with 190 additions and 164 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.
- bugfix: 93_DbRep: fix period calculation when using attr timeYearPeriod
- change: 93_DbRep: dumpMySQL clientSide: add create database to dump file
- change: 93_DbRep: dumpMySQL clientSide: change dump file to stricter rights
- bugfix: 47_OBIS: Implement "nohacks" attribute

View File

@ -59,6 +59,7 @@ no if $] >= 5.017011, warnings => 'experimental::smartmatch';
# Version History intern
my %DbRep_vNotesIntern = (
"8.52.14" => "08.11.2023 fix period calculation when using attr timeYearPeriod ",
"8.52.13" => "07.11.2023 dumpMySQL clientSide: add create database to dump file ",
"8.52.12" => "05.11.2023 dumpMySQL clientSide: change the dump file to stricter rights ",
"8.52.11" => "17.09.2023 improve the markout in func DbRep_checkValidTimeSequence, Forum:#134973 ",
@ -1729,39 +1730,44 @@ sub DbRep_Attr {
}
}
if ($aName eq "timeYearPeriod") {
# 06-01 02-28
if ($aName eq "timeYearPeriod") { # z.Bsp: 06-01 02-28
unless ($aVal =~ /^(\d{2})-(\d{2})\s(\d{2})-(\d{2})$/x ) {
return "The Value of \"$aName\" isn't valid. Set the account period as \"MM-DD MM-DD\".";
}
my ($mm1, $dd1, $mm2, $dd2) = ($aVal =~ /^(\d{2})-(\d{2}) (\d{2})-(\d{2})$/);
my (undef,undef,undef,$mday,$mon,$year1,undef,undef,undef) = localtime(time); # Istzeit Ableitung
my $year2 = $year1;
# a b c d
# 06-01 02-28 , wenn c < a && $mon < a -> Jahr(a)-1, sonst Jahr(c)+1
my $c = ($mon+1).$mday;
my $e = $mm2.$dd2;
my (undef,undef,undef,$mday,$mon,$year,undef,undef,undef) = localtime (time); # Istzeit Ableitung
my ($ybp, $yep);
if ($mm2 <= $mm1 && $c <= $e) {
$year1--;
$year += 1900;
$mon++;
my $bdval = $mm1 * 30 + int $dd1;
my $adval = $mon * 30 + int $mday;
if ($adval >= $bdval) {
$ybp = $year;
$yep = $year++;
}
else {
$year2++;
$ybp = $year--;
$yep = $year;
}
eval { my $t1 = timelocal(00, 00, 00, $dd1, $mm1-1, $year1-1900);
my $t2 = timelocal(00, 00, 00, $dd2, $mm2-1, $year2-1900); };
if ($@) {
my @l = split (/at/, $@);
return " The Value of $aName is out of range - $l[0]";
eval { my $t1 = timelocal(00, 00, 00, $dd1, $mm1-1, $ybp-1900);
my $t2 = timelocal(00, 00, 00, $dd2, $mm2-1, $yep-1900);
}
or do {
return " The Value of $aName is out of range";
};
delete($attr{$name}{timestamp_begin}) if ($attr{$name}{timestamp_begin});
delete($attr{$name}{timestamp_end}) if ($attr{$name}{timestamp_end});
delete($attr{$name}{timeDiffToNow}) if ($attr{$name}{timeDiffToNow});
delete($attr{$name}{timeOlderThan}) if ($attr{$name}{timeOlderThan});
return;
}
if ($aName eq "timestamp_begin" || $aName eq "timestamp_end") {
my @dtas = qw(current_year_begin
current_year_end
@ -1941,6 +1947,7 @@ sub DbRep_Notify {
$own_hash->{HELPER}{OLDDEV} = $evl[1];
$own_hash->{HELPER}{NEWDEV} = $evl[2];
$own_hash->{HELPER}{RENMODE} = "devren";
DbRep_Main($own_hash, "deviceRename");
for my $repname (devspec2array("TYPE=DbRep")) { # die Attribute "device" in allen DbRep-Devices mit der Datenbank = DB des Agenten von alten Device in neues Device ändern
@ -2666,24 +2673,29 @@ sub DbRep_createTimeArray {
$tsend = AttrVal ($name, "timestamp_end", strftime "%Y-%m-%d %H:%M:%S", localtime(time));
$tsend = DbRep_formatpicker($tsend);
if (my $tap = AttrVal($name, "timeYearPeriod", undef)) {
# a b c d
# 06-01 02-28 , wenn c < a && $mon < a -> Jahr(a)-1, sonst Jahr(c)+1
my $ybp = $year+1900;
my $yep = $year+1900;
if (my $tap = AttrVal ($name, 'timeYearPeriod', undef)) {
my ($ybp, $yep);
my (undef,undef,undef,$mday,$mon,$year,undef,undef,undef) = localtime (time); # Istzeit Ableitung
$tap =~ qr/^(\d{2})-(\d{2}) (\d{2})-(\d{2})$/p;
my $mbp = $1;
my $dbp = $2;
my $mep = $3;
my $dep = $4;
my $c = ($mon+1).$mday;
my $e = $mep.$dep;
if ($mep <= $mbp && $c <= $e) {
$ybp--;
$year += 1900;
$mon++;
my $bdval = $mbp * 30 + int $dbp;
my $adval = $mon * 30 + int $mday;
if ($adval >= $bdval) {
$ybp = $year;
$yep = $year + 1;
}
else {
$yep++;
$ybp = $year - 1;
$yep = $year;
}
$tsbegin = "$ybp-$mbp-$dbp 00:00:00";
@ -2753,6 +2765,7 @@ sub DbRep_createTimeArray {
$tsub = 345600 if($wday == 5); # wenn Start am "Fr" dann Korrektur -4 Tage
$tsub = 432000 if($wday == 6); # wenn Start am "Sa" dann Korrektur -5 Tage
$tsub = 518400 if($wday == 0); # wenn Start am "So" dann Korrektur -6 Tage
($rsec,$rmin,$rhour,$rmday,$rmon,$ryear) = localtime(time-$tsub);
$tsbegin = strftime "%Y-%m-%d %T", localtime(timelocal(0,0,0,$rmday,$rmon,$ryear)) if(AttrVal($name, "timestamp_begin", "") eq "current_week_begin");
$tsend = strftime "%Y-%m-%d %T", localtime(timelocal(0,0,0,$rmday,$rmon,$ryear)) if(AttrVal($name, "timestamp_end", "") eq "current_week_begin");
@ -2767,6 +2780,7 @@ sub DbRep_createTimeArray {
$tadd = 172800 if($wday == 5); # wenn Start am "Fr" dann Korrektur +2 Tage
$tadd = 86400 if($wday == 6); # wenn Start am "Sa" dann Korrektur +1 Tage
$tadd = 0 if($wday == 0); # wenn Start am "So" keine Korrektur
($rsec,$rmin,$rhour,$rmday,$rmon,$ryear) = localtime(time+$tadd);
$tsbegin = strftime "%Y-%m-%d %T", localtime(timelocal(59,59,23,$rmday,$rmon,$ryear)) if(AttrVal($name, "timestamp_begin", "") eq "current_week_end");
$tsend = strftime "%Y-%m-%d %T", localtime(timelocal(59,59,23,$rmday,$rmon,$ryear)) if(AttrVal($name, "timestamp_end", "") eq "current_week_end");
@ -2781,6 +2795,7 @@ sub DbRep_createTimeArray {
$tsub = 950400 if($wday == 5); # wenn Start am "Fr" dann Korrektur -11 Tage
$tsub = 1036800 if($wday == 6); # wenn Start am "Sa" dann Korrektur -12 Tage
$tsub = 1123200 if($wday == 0); # wenn Start am "So" dann Korrektur -13 Tage
($rsec,$rmin,$rhour,$rmday,$rmon,$ryear) = localtime(time-$tsub);
$tsbegin = strftime "%Y-%m-%d %T", localtime(timelocal(0,0,0,$rmday,$rmon,$ryear)) if(AttrVal($name, "timestamp_begin", "") eq "previous_week_begin");
$tsend = strftime "%Y-%m-%d %T", localtime(timelocal(0,0,0,$rmday,$rmon,$ryear)) if(AttrVal($name, "timestamp_end", "") eq "previous_week_begin");
@ -2795,6 +2810,7 @@ sub DbRep_createTimeArray {
$tsub = 432000 if($wday == 5); # wenn Start am "Fr" dann Korrektur -5 Tage
$tsub = 518400 if($wday == 6); # wenn Start am "Sa" dann Korrektur -6 Tage
$tsub = 604800 if($wday == 0); # wenn Start am "So" dann Korrektur -7 Tage
($rsec,$rmin,$rhour,$rmday,$rmon,$ryear) = localtime(time-$tsub);
$tsbegin = strftime "%Y-%m-%d %T", localtime(timelocal(59,59,23,$rmday,$rmon,$ryear)) if(AttrVal($name, "timestamp_begin", "") eq "previous_week_end");
$tsend = strftime "%Y-%m-%d %T", localtime(timelocal(59,59,23,$rmday,$rmon,$ryear)) if(AttrVal($name, "timestamp_end", "") eq "previous_week_end");
@ -12033,21 +12049,26 @@ sub DbRep_checktimeaggr {
if ($aggregation ne "no") {
$IsAggrSet = 1;
}
if($hash->{LASTCMD} =~ /delSeqDoublets|delDoublets/) {
$aggregation = ($aggregation eq "no") ? "day" : $aggregation; # wenn Aggregation "no", für delSeqDoublets immer "day" setzen
$IsAggrSet = 1;
}
if($hash->{LASTCMD} =~ /averageValue/ && AttrVal($name, "averageCalcForm", "avgArithmeticMean") =~ /avgDailyMeanGWS/x) {
$aggregation = "day"; # für Tagesmittelwertberechnung des deutschen Wetterdienstes immer "day"
$IsAggrSet = 1;
}
if($hash->{LASTCMD} =~ /^sql|delEntries|fetchrows|deviceRename|readingRename|tableCurrentFillup|reduceLog|\breadingsDifferenceByTimeDelta\b/) {
$IsAggrSet = 0;
$aggregation = "no";
}
if($hash->{LASTCMD} =~ /deviceRename|readingRename/) {
$IsTimeSet = 0;
}
if($hash->{LASTCMD} =~ /changeValue/) {
if($hash->{HELPER}{COMPLEX}) {
$IsAggrSet = 1;
@ -12058,6 +12079,7 @@ sub DbRep_checktimeaggr {
$aggregation = "no";
}
}
if($hash->{LASTCMD} =~ /syncStandby/ ) {
if($aggregation !~ /minute|hour|day|week/) {
$aggregation = "day";
@ -17106,20 +17128,22 @@ sub bdump {
</li>
<a id="DbRep-attr-timeYearPeriod"></a>
<li><b>timeYearPeriod </b> - By this attribute an annual time period will be determined for database data selection.
The time limits are calculated dynamically during execution time. Every time an annual period is determined.
Periods of less than a year are not possible to set. <br>
This attribute is particularly intended to make reports synchronous to an account period, e.g. of an energy- or gas provider.
<li><b>timeYearPeriod &lt;Month&gt;-&lt;Day&gt; &lt;Month&gt;-&lt;Day&gt;</b> <br>
An annual period is determined for the database selection.
The annual period is calculated dynamically at execution time.
It is not possible to provide information during the year. <br>
This attribute is primarily intended to create evaluations synchronized with a billing period, e.g. that of an energy or
gas supplier.
<br><br>
<ul>
<b>Example:</b> <br><br>
attr &lt;name&gt; timeYearPeriod 06-25 06-24 <br><br>
# evaluates the database within the time limits 25. june AAAA and 24. june BBBB. <br>
# The year AAAA respectively year BBBB is calculated dynamically depending of the current date. <br>
# If the current date >= 25. june and =< 31. december, than AAAA = current year and BBBB = current year+1 <br>
# If the current date >= 01. january und =< 24. june, than AAAA = current year-1 and BBBB = current year
Evaluates the database in the time limits June 25 AAAA to June 24 BBBB. <br>
The year AAAA or BBBB is calculated depending on the current date. <br>
If the current date is >= June 25 and <= December 31, then AAAA = current year and BBBB = current year+1 <br>
If the current date is >= January 01 and <= June 24, then AAAA = current year-1 and BBBB = current year
</ul>
<br><br>
</li>
@ -20162,9 +20186,10 @@ sub bdump {
</li>
<a id="DbRep-attr-timeYearPeriod"></a>
<li><b>timeYearPeriod </b> - Mit Hilfe dieses Attributes wird eine jährliche Zeitperiode für die Datenbankselektion bestimmt.
Die Zeitgrenzen werden zur Ausführungszeit dynamisch berechnet. Es wird immer eine Jahresperiode
bestimmt. Eine unterjährige Angabe ist nicht möglich. <br>
<li><b>timeYearPeriod &lt;Monat&gt;-&lt;Tag&gt; &lt;Monat&gt;-&lt;Tag&gt;</b> <br>
Es wird eine jährliche Periode für die Datenbankselektion bestimmt.
Die Jahresperiode wird dynamisch zur Ausführungszeit berechnet.
Eine unterjährige Angabe ist nicht möglich. <br>
Dieses Attribut ist vor allem dazu gedacht Auswertungen synchron zu einer Abrechnungsperiode, z.B. der eines
Energie- oder Gaslieferanten, anzufertigen.
<br><br>
@ -20173,10 +20198,10 @@ sub bdump {
<b>Beispiel:</b> <br><br>
attr &lt;name&gt; timeYearPeriod 06-25 06-24 <br><br>
# wertet die Datenbank in den Zeitgrenzen 25. Juni AAAA bis 24. Juni BBBB aus. <br>
# Das Jahr AAAA bzw. BBBB wird in Abhängigkeit des aktuellen Datums errechnet. <br>
# Ist das aktuelle Datum >= 25. Juni und =< 31. Dezember, dann ist AAAA = aktuelles Jahr und BBBB = aktuelles Jahr+1 <br>
# Ist das aktuelle Datum >= 01. Januar und =< 24. Juni, dann ist AAAA = aktuelles Jahr-1 und BBBB = aktuelles Jahr
Wertet die Datenbank in den Zeitgrenzen 25. Juni AAAA bis 24. Juni BBBB aus. <br>
Das Jahr AAAA bzw. BBBB wird in Abhängigkeit des aktuellen Datums errechnet. <br>
Ist das aktuelle Datum >= 25. Juni und <= 31. Dezember, dann ist AAAA = aktuelles Jahr und BBBB = aktuelles Jahr+1 <br>
Ist das aktuelle Datum >= 01. Januar und <= 24. Juni, dann ist AAAA = aktuelles Jahr-1 und BBBB = aktuelles Jahr
</ul>
<br><br>
</li>