2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-09 14:47:00 +00:00

57_SSCal: fix problem recurring MONTHLY appointment by day

git-svn-id: https://svn.fhem.de/fhem/trunk@26236 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2022-07-16 16:31:39 +00:00
parent 75ab4b1ff5
commit 3a2f4c61d8
2 changed files with 51 additions and 41 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: 57_SSCal: fix problem recurring MONTHLY appointment by day
- bugfix: 96_Snapcast: prevent crash in case of external group commands
- feature: 70_ESCVP21net: added undocumented settings (IMGPROC, IRIS, LIRIS)
- feature: 30_HUEBridge, 31_HUEDevice: support for Hue tap dial switch

View File

@ -3,7 +3,7 @@
#########################################################################################################################
# 57_SSCal.pm
#
# (c) 2019 - 2021 by Heiko Maaz
# (c) 2019 - 2022 by Heiko Maaz
# e-mail: Heiko dot Maaz at t-online dot de
#
# This Module integrate the Synology Calendar into FHEM
@ -140,6 +140,8 @@ BEGIN {
# Versions History intern
my %vNotesIntern = (
"2.4.10" => "16.07.2022 fix problem recurring MONTHLY appointment by day, ".
"forum: https://forum.fhem.de/index.php/topic,106963.msg1228098.html#msg1228098 ",
"2.4.9" => "11.07.2021 set adaption of AUTH for DSM7 compatibility ",
"2.4.8" => "16.12.2020 accep umlauts in calendar name ",
"2.4.7" => "08.12.2020 fix handle code recognition in createAtDevices as single line ",
@ -1561,30 +1563,31 @@ return;
# Extrahiert empfangene Kalendertermine (Events)
#############################################################################################
sub extractEventlist { ## no critic 'complexity'
my ($name) = @_;
my $hash = $defs{$name};
my $data = delete $hash->{eventlist}; # zentrales Eventhash löschen !
my $am = AttrVal($name, "asyncMode", 0);
my $name = shift;
my $hash = $defs{$name};
my $data = delete $hash->{eventlist}; # zentrales Eventhash löschen !
my $am = AttrVal($name, "asyncMode", 0);
my ($tz,$bdate,$btime,$bts,$edate,$etime,$ets,$ci,$bi,$ei,$startEndDiff,$excl,$es,$em,$eh);
my ($nbdate,$nbtime,$nbts,$nedate,$netime,$nets);
my @row_array;
my (undef,$tstart,$tend) = timeEdge($name); # Sollstart- und Sollendezeit der Kalenderereignisse ermitteln
my $datetimestart = FmtDateTime($tstart);
my $datetimeend = FmtDateTime($tend);
my $n = 0; # Zusatz f. lfd. Nr. zur Unterscheidung exakt zeitgleicher Events
my (undef,$tstart,$tend) = timeEdge ($name); # Sollstart- und Sollendezeit der Kalenderereignisse ermitteln
my $datetimestart = FmtDateTime ($tstart);
my $datetimeend = FmtDateTime ($tend);
my $n = 0; # Zusatz f. lfd. Nr. zur Unterscheidung exakt zeitgleicher Events
for my $key (keys %{$data->{data}}) {
my $i = 0;
while ($data->{data}{$key}[$i]) {
my $ignore = 0;
my $done = 0;
my $next = 0;
my $ignore = 0;
my $done = 0;
my $next = 0;
($nbdate,$nedate) = ("","");
my $uid = $data->{data}{$key}[$i]{ical_uid}; # UID des Events
my $uid = $data->{data}{$key}[$i]{ical_uid}; # UID des Events
extractIcal ($name,$data->{data}{$key}[$i]); # VCALENDAR Extrakt in {HELPER}{VCALENDAR} importieren
my $isallday = $data->{data}{$key}[$i]{is_all_day};
@ -1597,9 +1600,9 @@ sub extractEventlist { ## no critic 'complexi
my ($eyear, $emonth, $emday) = $edate =~ /(\d{4})-(\d{2})-(\d{2})/x;
$netime = $etime;
# Bugfix API - wenn is_all_day und an erster Stelle im 'data' Ergebnis des API-Calls ist Endedate/time nicht korrekt !
if($isallday && ($bdate ne $edate) && $netime =~ /^00:59:59$/x) {
if($isallday && ($bdate ne $edate) && $netime =~ /^00:59:59$/x) { # Bugfix API - wenn is_all_day und an erster Stelle im 'data' Ergebnis des API-Calls ist Endedate/time nicht korrekt !
($es, $em, $eh, $emday, $emonth, $eyear, undef, undef, undef) = localtime($ets-=3600);
$eyear = sprintf("%02d", $eyear+=1900);
$emonth = sprintf("%02d", $emonth+=1);
$emday = sprintf("%02d", $emday);
@ -1610,18 +1613,20 @@ sub extractEventlist { ## no critic 'complexi
($ei,undef,$edate,$etime,$ets,undef) = explodeDateTime ($hash, $eyear.$emonth.$emday."T".$netime, 0, 0, 0);
}
$startEndDiff = $ets - $bts; # Differenz Event Ende / Start in Sekunden
$startEndDiff = $ets - $bts; # Differenz Event Ende / Start in Sekunden
if(!$data->{data}{$key}[$i]{is_repeat_evt}) { # einmaliger Event
if(!$data->{data}{$key}[$i]{is_repeat_evt}) { # einmaliger Event
Log3($name, 5, "$name - Single event Begin: $bdate, End: $edate");
if($ets < $tstart || $bts > $tend) {
Log3($name, 4, "$name - Ignore single event -> $data->{data}{$key}[$i]{summary} start: $bdate $btime, end: $edate $etime");
$ignore = 1;
$done = 0;
}
elsif ($excl) {
Log3($name, 4, "$name - Ignored by Ical compare -> $data->{data}{$key}[$i]{summary} start: $bdate $btime, end: $edate $etime");
$ignore = 1;
$done = 0;
}
@ -1643,35 +1648,36 @@ sub extractEventlist { ## no critic 'complexi
$done = 1;
}
}
elsif ($data->{data}{$key}[$i]{is_repeat_evt}) { # Event ist wiederholend
elsif ($data->{data}{$key}[$i]{is_repeat_evt}) { # Event ist wiederholend
Log3($name, 5, "$name - Recurring event Begin: $bdate, End: $edate");
my ($freq,$count,$interval,$until,$uets,$bymonthday,$byday);
my $rr = $data->{data}{$key}[$i]{evt_repeat_setting}{repeat_rule};
# Format: FREQ=YEARLY;COUNT=1;INTERVAL=2;BYMONTHDAY=15;BYMONTH=10;UNTIL=2020-12-31T00:00:00
my @para = split(";", $rr);
my @para = split ";", $rr;
for my $par (@para) {
my ($p1,$p2) = split("=", $par);
my ($p1,$p2) = split "=", $par;
if ($p1 eq "FREQ") {
$freq = $p2;
}
if ($p1 eq "COUNT") { # Event endet automatisch nach x Wiederholungen
if ($p1 eq "COUNT") { # Event endet automatisch nach x Wiederholungen
$count = $p2;
}
if ($p1 eq "INTERVAL") { # Wiederholungsintervall
if ($p1 eq "INTERVAL") { # Wiederholungsintervall
$interval = $p2;
}
if ($p1 eq "UNTIL") { # festes Intervallende angegeben
if ($p1 eq "UNTIL") { # festes Intervallende angegeben
$until = $p2;
$until =~ s/[-:]//gx;
$uets = (explodeDateTime ($hash, $until, 0, 0, 0))[4];
}
if ($p1 eq "BYMONTHDAY") { # Wiederholungseigenschaft -> Tag des Monats z.B. 13 (Tag 13)
if ($p1 eq "BYMONTHDAY") { # Wiederholungseigenschaft -> Tag des Monats z.B. 13 (Tag 13)
$bymonthday = $p2;
}
if ($p1 eq "BYDAY") { # Wiederholungseigenschaft -> Wochentag z.B. 2WE,-1SU,4FR (kann auch Liste bei WEEKLY sein)
if ($p1 eq "BYDAY") { # Wiederholungseigenschaft -> Wochentag z.B. 2WE,-1SU,4FR (kann auch Liste bei WEEKLY sein)
$byday = $p2;
}
}
@ -1699,7 +1705,7 @@ sub extractEventlist { ## no critic 'complexi
$nbtime =~ s/://gx;
$netime =~ s/://gx;
my $dtstart = $byear.$bmonth.$bmday."T".$nbtime;
my $dtstart = $byear.$bmonth.$bmday."T".$nbtime;
($bi,undef,$nbdate,$nbtime,$nbts,$excl) = explodeDateTime ($hash, $byear.$bmonth.$bmday."T".$nbtime, 0, $uid, $dtstart); # Beginn des Wiederholungsevents
($ei,undef,$nedate,$netime,$nets,undef) = explodeDateTime ($hash, $eyear.$emonth.$emday."T".$netime, 0, $uid, $dtstart); # Ende des Wiederholungsevents
@ -1742,12 +1748,12 @@ sub extractEventlist { ## no critic 'complexi
$bmonth += $interval if($ci>=0);
$byear += int( $bmonth/13);
$bmonth %= 12 if($bmonth>12);
$bmonth = sprintf("%02d", $bmonth);
$bmonth = sprintf("%02d", $bmonth);
$emonth += $interval if($ci>=0);
$eyear += int( $emonth/13);
$emonth %= 12 if($emonth>12);
$emonth = sprintf("%02d", $emonth);
$emonth = sprintf("%02d", $emonth);
$nbtime =~ s/://gx;
$netime =~ s/://gx;
@ -1791,12 +1797,13 @@ sub extractEventlist { ## no critic 'complexi
if ($byday) { # Wiederholungseigenschaft -> Wochentag z.B. 2WE,-1SU,4FR (kann auch Liste bei WEEKLY sein)
my ($nbhh,$nbmm,$nbss,$nehh,$nemm,$ness,$numOfRatedDay,$rDaysToAddOrSub,$rNewTime);
my @ByDays = split(",", $byday); # Array der Wiederholungstage
my @ByDays = split ",", $byday; # Array der Wiederholungstage
for my $rByDay (@ByDays) {
my $rByDayLength = length($rByDay); # die Länge des Strings
my $rDayStr; # Tag auf den das Datum gesetzt werden soll
my $rDayInterval; # z.B. 2 = 2nd Tag des Monats oder -1 = letzter Tag des Monats
if ($rByDayLength > 2) {
$rDayStr = substr($rByDay, -2);
$rDayInterval = int(substr($rByDay, 0, $rByDayLength - 2));
@ -1806,7 +1813,7 @@ sub extractEventlist { ## no critic 'complexi
$rDayInterval = 1;
}
my $numOfAppointmentDay = _weekdayNumber ($rByDay); # liefert Nr des Wochentages: SU = 0 ... SA = 6
my $numOfAppointmentDay = _weekdayNumber ($rDayStr); # liefert Nr des Wochentages: SU = 0 ... SA = 6
for ($ci=-1; $ci<($count); $ci++) {
if ($rDayInterval > 0) { # Angabe "jeder x Wochentag" ist positiv (-2 wäre z.B. vom Ende des Monats zu zähelen)
@ -1815,8 +1822,9 @@ sub extractEventlist { ## no critic 'complexi
$bmonth %= 12 if($bmonth>12);
$bmonth = sprintf("%02d", $bmonth);
($nbhh,$nbmm,$nbss) = split(":", $nbtime);
($nbhh,$nbmm,$nbss) = split ":", $nbtime;
my $firstOfNextMonth = fhemTimeLocal($nbss, $nbmm, $nbhh, 1, $bmonth-1, $byear-1900);
($nbss, $nbmm, $nbhh, $bmday, $bmonth, $byear, $numOfRatedDay, undef, undef) = localtime($firstOfNextMonth); # den 1. des Monats sowie die dazu gehörige Nr. des Wochentages
if ($numOfRatedDay <= $numOfAppointmentDay) { # Nr Wochentag des 1. des Monats <= als Wiederholungstag
@ -1825,7 +1833,8 @@ sub extractEventlist { ## no critic 'complexi
else {
$rDaysToAddOrSub = 7 - $numOfRatedDay + $numOfAppointmentDay;
}
$rDaysToAddOrSub += (7 * ($rDayInterval - 1)); # addiere Tagesintervall, z.B. 4th Freitag ...
$rDaysToAddOrSub += (7 * ($rDayInterval - 1)); # addiere Tagesintervall, z.B. 4th Freitag ...
$rNewTime = plusNSeconds($firstOfNextMonth, 86400*$rDaysToAddOrSub, 1);
($nbss,$nbmm,$nbhh,$bmday,$bmonth,$byear,$ness,$nemm,$nehh,$emday,$emonth,$eyear) = DTfromStartandDiff ($rNewTime,$startEndDiff);
@ -1841,7 +1850,7 @@ sub extractEventlist { ## no critic 'complexi
$nbtime = $nbhh.$nbmm.$nbss;
$netime = $nehh.$nemm.$ness;
my $dtstart = $byear.$bmonth.$bmday."T".$nbtime;
my $dtstart = $byear.$bmonth.$bmday."T".$nbtime;
($bi,undef,$nbdate,$nbtime,$nbts,$excl) = explodeDateTime ($hash, $byear.$bmonth.$bmday."T".$nbtime, 0, $uid, $dtstart); # Beginn des Wiederholungsevents
($ei,undef,$nedate,$netime,$nets,undef) = explodeDateTime ($hash, $eyear.$emonth.$emday."T".$netime, 0, $uid, $dtstart); # Ende des Wiederholungsevents
@ -1884,10 +1893,10 @@ sub extractEventlist { ## no critic 'complexi
if ($byday) { # Wiederholungseigenschaft -> Wochentag z.B. 2WE,-1SU,4FR (kann auch Liste bei WEEKLY sein)
my ($nbhh,$nbmm,$nbss,$nehh,$nemm,$ness,$rNewTime);
my ($numOfRatedDay,$rDaysToAddOrSub);
my @ByDays = split(",", $byday); # Array der Wiederholungstage
my @ByDays = split ",", $byday; # Array der Wiederholungstage
my $btsstart = $bts;
$ci = -1;
$ci = -1;
while ($ci<$count) {
$rNewTime = $btsstart;
@ -1899,7 +1908,7 @@ sub extractEventlist { ## no critic 'complexi
($nbss, $nbmm, $nbhh, $bmday, $bmonth, $byear, $numOfRatedDay, undef, undef) = localtime($rNewTime);
($nbhh,$nbmm,$nbss) = split(":", $nbtime);
($nbhh,$nbmm,$nbss) = split ":", $nbtime;
if ($numOfRatedDay <= $numOfAppointmentDay) { # Nr nächster Wochentag <= Planwochentag
$rDaysToAddOrSub = $numOfAppointmentDay - $numOfRatedDay;
@ -1914,7 +1923,7 @@ sub extractEventlist { ## no critic 'complexi
$nbtime = $nbhh.$nbmm.$nbss;
$netime = $nehh.$nemm.$ness;
my $dtstart = $byear.$bmonth.$bmday."T".$nbtime;
my $dtstart = $byear.$bmonth.$bmday."T".$nbtime;
($bi,undef,$nbdate,$nbtime,$nbts,$excl) = explodeDateTime ($hash, $byear.$bmonth.$bmday."T".$nbtime, 0, $uid, $dtstart); # Beginn des Wiederholungsevents
($ei,undef,$nedate,$netime,$nets,undef) = explodeDateTime ($hash, $eyear.$emonth.$emday."T".$netime, 0, $uid, $dtstart); # Ende des Wiederholungsevents
@ -1964,7 +1973,7 @@ sub extractEventlist { ## no critic 'complexi
$nbtime = $nbhh.$nbmm.$nbss;
$netime = $nehh.$nemm.$ness;
my $dtstart = $byear.$bmonth.$bmday."T".$nbtime;
my $dtstart = $byear.$bmonth.$bmday."T".$nbtime;
($bi,undef,$nbdate,$nbtime,$nbts,$excl) = explodeDateTime ($hash, $byear.$bmonth.$bmday."T".$nbtime, 0, $uid, $dtstart); # Beginn des Wiederholungsevents
($ei,undef,$nedate,$netime,$nets,undef) = explodeDateTime ($hash, $eyear.$emonth.$emday."T".$netime, 0, $uid, $dtstart); # Ende des Wiederholungsevents
@ -2013,7 +2022,7 @@ sub extractEventlist { ## no critic 'complexi
$nbtime = $nbhh.$nbmm.$nbss;
$netime = $nehh.$nemm.$ness;
my $dtstart = $byear.$bmonth.$bmday."T".$nbtime;
my $dtstart = $byear.$bmonth.$bmday."T".$nbtime;
($bi,undef,$nbdate,$nbtime,$nbts,$excl) = explodeDateTime ($hash, $byear.$bmonth.$bmday."T".$nbtime, 0, $uid, $dtstart); # Beginn des Wiederholungsevents
($ei,undef,$nedate,$netime,$nets,undef) = explodeDateTime ($hash, $eyear.$emonth.$emday."T".$netime, 0, $uid, $dtstart); # Ende des Wiederholungsevents