57_CALVIEW.pm 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. # $Id: 57_CALVIEW.pm 17605 2018-10-23 16:37:40Z chris1284 $
  2. ############################
  3. # CALVIEW
  4. # needs a defined Device 57_Calendar
  5. # needs perl-modul Date::Parse
  6. ############################
  7. package main;
  8. use strict;
  9. use warnings;
  10. use POSIX;
  11. use Date::Parse;
  12. #use Date::Calc qw(Day_of_Week);
  13. sub CALVIEW_Initialize($)
  14. {
  15. my ($hash) = @_;
  16. $hash->{DefFn} = "CALVIEW_Define";
  17. $hash->{UndefFn} = "CALVIEW_Undef";
  18. $hash->{SetFn} = "CALVIEW_Set";
  19. $hash->{NotifyFn} = "CALVIEW_Notify";
  20. $hash->{AttrList} = "datestyle:ISO8601 " .
  21. "disable:0,1 " .
  22. "do_not_notify:1,0 " .
  23. "filterSummary:textField-long " .
  24. "fulldaytext " .
  25. "isbirthday:1,0 " .
  26. "maxreadings " .
  27. "modes:next ".
  28. "oldStyledReadings:1,0 " .
  29. "sourcecolor:textField-long " .
  30. "timeshort:1,0 " .
  31. "yobfield:_location,_description,_summary " .
  32. "weekdayformat:de-long,de-short,en-long,en-short " .
  33. $readingFnAttributes;
  34. }
  35. sub CALVIEW_Define($$){
  36. my ( $hash, $def ) = @_;
  37. my @a = split( "[ \t][ \t]*", $def );
  38. return "\"set CALVIEW\" needs at least an argument" if ( @a < 2 );
  39. my $name = $a[0];
  40. my $inter = 43200;
  41. $inter= $a[4] if($#a==4);
  42. my $modes = $a[3];
  43. my @calendars = split( ",", $a[2] );
  44. $hash->{NAME} = $name;
  45. my $calcounter = 1;
  46. foreach my $calender (@calendars)
  47. {
  48. return "invalid Calendername \"$calender\", define it first" if((devspec2array("NAME=$calender")) != 1 );
  49. }
  50. $hash->{KALENDER} = $a[2];
  51. $hash->{STATE} = "Initialized";
  52. $hash->{INTERVAL} = $inter;
  53. $modes = "next" if (!defined($modes));
  54. if ( $modes =~ /^\d+$/) {
  55. if($modes == 1) {$attr{$name}{modes} = "next";}
  56. elsif($modes == 0){$attr{$name}{modes} = "next";}
  57. elsif($modes == 2){$attr{$name}{modes} = "next";}
  58. elsif($modes == 3){$attr{$name}{modes} = "next";}
  59. }
  60. elsif($modes eq "next"){$attr{$name}{modes} = "next";}
  61. else {return "invalid mode \"$modes\", use 0,1,2 or next!"}
  62. InternalTimer(gettimeofday()+2, "CALVIEW_GetUpdate", $hash, 0);
  63. return undef;
  64. }
  65. sub CALVIEW_Undef($$){
  66. my ( $hash, $arg ) = @_;
  67. #DevIo_CloseDev($hash);
  68. RemoveInternalTimer($hash);
  69. return undef;
  70. }
  71. sub CALVIEW_Set($@){
  72. my ( $hash, @a ) = @_;
  73. return "\"set CALVIEW\" needs at least an argument" if ( @a < 2 );
  74. return "\"set CALVIEW\" Unknown argument $a[1], choose one of update" if($a[1] eq '?');
  75. my $name = shift @a;
  76. my $opt = shift @a;
  77. my $arg = join("", @a);
  78. if($opt eq "update"){CALVIEW_GetUpdate($hash);}
  79. }
  80. sub CALVIEW_GetUpdate($){
  81. my ($hash) = @_;
  82. my $name = $hash->{NAME};
  83. #cleanup readings
  84. delete ($hash->{READINGS});
  85. # new timer
  86. RemoveInternalTimer($hash);
  87. InternalTimer(gettimeofday()+$hash->{INTERVAL}, "CALVIEW_GetUpdate", $hash, 1);
  88. readingsBeginUpdate($hash); #start update
  89. my @termine = getsummery($hash);
  90. my $max = AttrVal($name,"maxreadings",0);
  91. if(defined $max && $max =~ /^[+-]?\d+$/){if($max > 190){$max = 190;}}
  92. else{my $max = 190;}
  93. my $counter = 1;
  94. my $samedatecounter = 2;
  95. my $lastterm;
  96. my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
  97. $year += 1900; $mon += 1;
  98. my $date = sprintf('%02d.%02d.%04d', $mday, $mon, $year);
  99. ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time + 86400);
  100. $year += 1900; $mon += 1;
  101. my $datenext = sprintf('%02d.%02d.%04d', $mday, $mon, $year);
  102. my @termineNew;
  103. my @tempstart;
  104. my @bts;
  105. my @tempend;
  106. my $isostarttime;
  107. my $isoendtime;
  108. my ($D,$M,$Y);
  109. my ($eD,$eM,$eY);
  110. my @arrWeekdayDe = ("Sonntag","Montag", "Dienstag","Mittwoch","Donnerstag","Freitag","Samstag");
  111. my @arrWeekdayDeShrt = ("So","Mo", "Di","Mi","Do","Fr","Sa");
  112. my @arrWeekdayEn = ("Sunday","Monday", "Tuesday","Wednesday","Thursday","Friday","Saturday");
  113. my @arrWeekdayEnShrt = ("Sun","Mon", "Tue","Wed","Thu","Fri","Sat");
  114. foreach my $item (@termine ){
  115. #start datum und zeit behandeln
  116. if( defined($item->[0])&& length($item->[0]) > 0) {
  117. @tempstart=split(/\s+/,$item->[0]);
  118. ($D,$M,$Y)=split(/\./,$tempstart[0]);
  119. @bts=str2time($M."/".$D."/".$Y." ".$tempstart[1]);
  120. $isostarttime = $Y."-".$M."-".$D."T".$tempstart[1];
  121. }
  122. else {$item->[0] = "no startdate"}
  123. #end datum und zeit behandeln
  124. if( defined($item->[2])&& length($item->[2]) > 0) {
  125. @tempend=split(/\s+/,$item->[2]);
  126. ($eD,$eM,$eY)=split(/\./,$tempend[0]);
  127. $isoendtime = $eY."-".$eM."-".$eD."T".$tempend[1];
  128. }
  129. else {$item->[2] = "no enddate"}
  130. #replace the "\," with ","
  131. if(length($item->[1]) > 0){ $item->[1] =~ s/\\,/,/g; }
  132. if( defined($item->[4]) && length($item->[4]) > 0){ $item->[4] =~ s/\\,/,/g; } elsif( !defined($item->[4])){$item->[4] = " ";}
  133. if( defined($item->[5]) && length($item->[5]) > 0){ $item->[5] =~ s/\\,/,/g; } elsif( !defined($item->[5])){$item->[5] = " ";}
  134. #berechnen verbleibender tage bis zum termin
  135. my $eventDate = fhemTimeLocal(0,0,0,$D,$M-1,$Y-1900);
  136. my $daysleft = floor(($eventDate - time) / 60 / 60 / 24 + 1);
  137. my $daysleft_long;
  138. #my $weekday = Day_of_Week($Y, $M, $D);
  139. my ($tsec,$tmin,$thour,$tmday,$tmon,$year,$weekday,$tyday,$tisdst) = localtime(time + (86400 * $daysleft));
  140. #"weekdayname:de-long,de-short,en-long,en-short " .
  141. my $weekdayname;
  142. if ( AttrVal($name,"weekdayformat","de-long") eq "de-short") {$weekdayname = $arrWeekdayDeShrt[$weekday]}
  143. elsif (AttrVal($name,"weekdayformat","de-long") eq "en-long") {$weekdayname = $arrWeekdayEn[$weekday]}
  144. elsif (AttrVal($name,"weekdayformat","de-long") eq "en-short") {$weekdayname = $arrWeekdayEnShrt[$weekday]}
  145. else {$weekdayname = $arrWeekdayDe[$weekday]}
  146. if( !defined($item->[6])){$item->[6] = " ";}
  147. if( $daysleft == 0){$daysleft_long = "heute";}
  148. elsif( $daysleft == 1){$daysleft_long = "morgen";}
  149. else{$daysleft_long = "in ".$daysleft." Tagen";}
  150. push @termineNew,{
  151. bdate => $tempstart[0],
  152. btime => $tempstart[1],
  153. bdatetimeiso => $isostarttime,
  154. daysleft => $daysleft,
  155. daysleftLong => $daysleft_long,
  156. summary => $item->[1],
  157. source => $item->[3],
  158. location => $item->[4],
  159. description => $item->[5],
  160. categories => $item->[6],
  161. edate => $tempend[0],
  162. etime => $tempend[1],
  163. edatetimeiso => $isoendtime,
  164. btimestamp => $bts[0],
  165. mode => $item->[7],
  166. weekday => $weekday,
  167. weekdayname => $weekdayname,
  168. duration => $item->[8]};
  169. }
  170. my $todaycounter = 1;
  171. my $tomorrowcounter = 1;
  172. my $readingstyle = AttrVal($name,"oldStyledReadings",0);
  173. my $isbday = AttrVal($name,"isbirthday",0);
  174. my $yobfield = AttrVal($name,"yobfield","_description");
  175. my $filterSummary = AttrVal($name,"filterSummary",".*:.*");
  176. my @arrFilters = split(',' , $filterSummary );
  177. my $sourceColor = AttrVal($name,"sourcecolor","");
  178. my @arrSourceColors = split(',' , $sourceColor );
  179. # sort the array by btimestamp
  180. my @sdata = map $_->[0],
  181. sort { $a->[1][0] <=> $b->[1][0] }
  182. map [$_, [$_->{btimestamp}]], @termineNew;
  183. if($readingstyle == 0){
  184. my $age = 0;
  185. my @termyear;
  186. my $validterm = 0;
  187. for my $termin (@sdata){
  188. my $termcolor="white";
  189. #if($termin->{summary} =~ /$filterSummary/ ){
  190. foreach my $filter (@arrFilters){
  191. my @arrFilter= split(':' , $filter);
  192. my $sourceFilter = $arrFilter[0];
  193. my $summaryFilter = $arrFilter[1];
  194. if( $termin->{source} =~ /$sourceFilter/i && $termin->{summary} =~ /$summaryFilter/i ){ $validterm =1;}
  195. };
  196. foreach my $color (@arrSourceColors){
  197. my @arrSourceColor = split(':' , $color);
  198. my $sourceName = $arrSourceColor[0];
  199. my $sourceColor = $arrSourceColor[1];
  200. if( $termin->{source} =~ /$sourceName/i ){ $termcolor = $sourceColor;}
  201. };
  202. if ($validterm ==1){
  203. #alter berechnen wenn attribut gesetzt ist. alter wird aus "jahr des termins" - "geburtsjahr aus location oder description" errechnet
  204. if($isbday == 1 ){
  205. @termyear = split(/\./,$termin->{bdate});
  206. if($yobfield eq "_location" && defined($termin->{location}) && length($termin->{location}) > 0 && $termin->{location} =~ /(\d{4})/) { my ($byear) = $termin->{location} =~ /(\d{4})/ ; $age = $termyear[2] - $byear;}
  207. elsif($yobfield eq "_description" && defined($termin->{description})&& length($termin->{description}) > 0 && $termin->{description} =~ /(\d{4})/) { my ($byear) = $termin->{description} =~ /(\d{4})/ ; $age = $termyear[2] - $byear;}
  208. elsif($yobfield eq "_summary" && defined($termin->{summary}) && length($termin->{summary}) > 0 && $termin->{summary} =~ /(\d{4})/ ) { my ($byear) = $termin->{summary} =~ /(\d{4})/ ; $age = $termyear[2] - $byear;}
  209. else {$age = " "}
  210. }
  211. my $timeshort = "";
  212. my($startday,$startmonth,$startyear)=split(/\./,$termin->{bdate});
  213. my($endday,$endmonth,$endyear)=split(/\./,$termin->{edate});
  214. my $nextday = $startday + 1;
  215. $nextday = sprintf ('%02d', $nextday);
  216. Log3 $name , 5, "CALVIEW $name - nextday = $nextday , endday = $endday , startday = $startday , btime ".$termin->{btime}." , etime ".$termin->{etime}."";
  217. #if( $endday eq $nextday && $termin->{btime} eq $termin->{etime} ){ $timeshort = AttrVal($name,"fulldaytext","ganztägig"); }
  218. if( $termin->{duration} == 86400 ){ $termin->{duration} = AttrVal($name,"fulldaytext","ganztägig");$timeshort = AttrVal($name,"fulldaytext","ganztägig"); }
  219. else {
  220. if(AttrVal($name,"timeshort","0") eq 0) {$timeshort = $termin->{btime}." - ".$termin->{etime}; }
  221. elsif(AttrVal($name,"timeshort","0") eq 1) {
  222. my $tmps = substr $termin->{btime},0,5 ;
  223. my $tmpe = substr $termin->{etime},0,5 ;
  224. $timeshort = $tmps." - ".$tmpe ;
  225. }
  226. }
  227. #standard reading t_[3steliger counter] anlegen
  228. if($isbday == 1 ){ readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_age", $age);}
  229. readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_bdate", $termin->{bdate});
  230. readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_btime", $termin->{btime});
  231. if(AttrVal($name,"datestyle","_description") eq "ISO8601"){readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_bdatetimeiso", $termin->{bdatetimeiso});readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_edatetimeiso", $termin->{edatetimeiso});}
  232. readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_daysleft", $termin->{daysleft});
  233. readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_daysleftLong", $termin->{daysleftLong});
  234. readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_summary", $termin->{summary});
  235. readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_source", $termin->{source});
  236. readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_sourcecolor", $termcolor);
  237. readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_location", $termin->{location});
  238. readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_description", $termin->{description});
  239. readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_categories", $termin->{categories});
  240. readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_edate", $termin->{edate});
  241. readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_etime", $termin->{etime});
  242. readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_mode", $termin->{mode});
  243. readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_timeshort", $timeshort );
  244. readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_weekday", $termin->{weekday} );
  245. readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_weekdayname", $termin->{weekdayname} );
  246. readingsBulkUpdate($hash, "t_".sprintf ('%03d', $counter)."_duration", $termin->{duration});
  247. #wenn termin heute today readings anlegen
  248. if ($date eq $termin->{bdate} ){
  249. if($isbday == 1 ){ readingsBulkUpdate($hash, "today_".sprintf ('%03d', $todaycounter)."_age", $age);}
  250. readingsBulkUpdate($hash, "today_".sprintf ('%03d', $todaycounter)."_bdate", "heute");
  251. readingsBulkUpdate($hash, "today_".sprintf ('%03d', $todaycounter)."_btime", $termin->{btime});
  252. if(AttrVal($name,"datestyle","_description") eq "ISO8601"){readingsBulkUpdate($hash, "today_".sprintf ('%03d', $todaycounter)."_bdatetimeiso", $termin->{bdatetimeiso});readingsBulkUpdate($hash, "today_".sprintf ('%03d', $todaycounter)."_edatetimiso", $termin->{edatetimeiso});}
  253. readingsBulkUpdate($hash, "today_".sprintf ('%03d', $counter)."_daysleft", $termin->{daysleft});
  254. readingsBulkUpdate($hash, "today_".sprintf ('%03d', $counter)."_daysleftLong", $termin->{daysleftLong});
  255. readingsBulkUpdate($hash, "today_".sprintf ('%03d', $todaycounter)."_summary", $termin->{summary});
  256. readingsBulkUpdate($hash, "today_".sprintf ('%03d', $todaycounter)."_source", $termin->{source});
  257. readingsBulkUpdate($hash, "today_".sprintf ('%03d', $todaycounter)."_sourcecolor", $termcolor);
  258. readingsBulkUpdate($hash, "today_".sprintf ('%03d', $todaycounter)."_location", $termin->{location});
  259. readingsBulkUpdate($hash, "today_".sprintf ('%03d', $todaycounter)."_description", $termin->{description});
  260. readingsBulkUpdate($hash, "today_".sprintf ('%03d', $todaycounter)."_categories", $termin->{categories});
  261. readingsBulkUpdate($hash, "today_".sprintf ('%03d', $todaycounter)."_edate", $termin->{edate});
  262. readingsBulkUpdate($hash, "today_".sprintf ('%03d', $todaycounter)."_etime", $termin->{etime});
  263. readingsBulkUpdate($hash, "today_".sprintf ('%03d', $todaycounter)."_mode", $termin->{mode});
  264. readingsBulkUpdate($hash, "today_".sprintf ('%03d', $todaycounter)."_timeshort", $timeshort );
  265. readingsBulkUpdate($hash, "today_".sprintf ('%03d', $todaycounter)."_weekday", $termin->{weekday} );
  266. readingsBulkUpdate($hash, "today_".sprintf ('%03d', $todaycounter)."_weekdayname", $termin->{weekdayname} );
  267. readingsBulkUpdate($hash, "today_".sprintf ('%03d', $todaycounter)."_duration", $termin->{duration});
  268. $todaycounter ++;
  269. }
  270. #wenn termin morgen tomorrow readings anlegen
  271. elsif ($datenext eq $termin->{bdate}){
  272. if($isbday == 1 ){readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_age", $age);}
  273. readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_bdate", "morgen");
  274. readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_btime", $termin->{btime});
  275. if(AttrVal($name,"datestyle","_description") eq "ISO8601"){readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_bdatetimeiso", $termin->{bdatetimeiso});readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_edatetimeiso", $termin->{edatetimeiso});}
  276. readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_daysleft", $termin->{daysleft});
  277. readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_daysleftLong", $termin->{daysleftLong});
  278. readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_summary", $termin->{summary});
  279. readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_source", $termin->{source});
  280. readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_sourcecolor", $termcolor);
  281. readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_location", $termin->{location});
  282. readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_description", $termin->{description});
  283. readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_categories", $termin->{categories});
  284. readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_edate", $termin->{edate});
  285. readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_etime", $termin->{etime});
  286. readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_mode", $termin->{mode});
  287. readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_timeshort", $timeshort );
  288. readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_weekday", $termin->{weekday} );
  289. readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_weekdayname", $termin->{weekdayname} );
  290. readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter)."_duration", $termin->{duration});
  291. $tomorrowcounter++;
  292. }
  293. $endday = '';
  294. $nextday ='';
  295. last if ($counter++ == $max);
  296. }
  297. $validterm = 0;
  298. $age = " ";
  299. };
  300. readingsBulkUpdate($hash, "state", "t: ".($counter-1)." td: ".($todaycounter-1)." tm: ".($tomorrowcounter-1));
  301. readingsBulkUpdate($hash, "c-term", $counter-1);
  302. readingsBulkUpdate($hash, "c-tomorrow", $tomorrowcounter-1);
  303. readingsBulkUpdate($hash, "c-today", $todaycounter-1);
  304. }
  305. else{
  306. my $lastreadingname = "";
  307. my $doppelcounter = 2;
  308. my $inverteddate;
  309. for my $termin (@sdata){ #termin als reading term_[3steliger counter]
  310. my @tempvar = split /\./, $termin->{bdate};
  311. $inverteddate = "$tempvar[2].$tempvar[1].$tempvar[0]";
  312. if($lastreadingname eq $termin->{bdate}."-".$termin->{btime}){ readingsBulkUpdate($hash, $inverteddate."-".$termin->{btime}."-$doppelcounter" , $termin->{summary}); $doppelcounter ++;}
  313. else{readingsBulkUpdate($hash, $inverteddate."-".$termin->{btime} , $termin->{summary}); $doppelcounter = 2;}
  314. $lastreadingname = $termin->{bdate}."-".$termin->{btime};
  315. last if ($counter++ == $max);
  316. };
  317. for my $termin (@sdata){ #check ob temin heute
  318. if ($date eq $termin->{bdate}){readingsBulkUpdate($hash, "today_".sprintf ('%03d', $todaycounter).$termin->{btime}, $termin->{summary});$todaycounter ++;}
  319. #check ob termin morgen
  320. elsif ($datenext eq $termin->{bdate}){readingsBulkUpdate($hash, "tomorrow_".sprintf ('%03d', $tomorrowcounter).$termin->{btime}, $termin->{summary});$tomorrowcounter++;}
  321. };
  322. }
  323. readingsEndUpdate($hash,1); #end update
  324. }
  325. sub getsummery($)
  326. {
  327. my ($hash) = @_;
  328. my @terminliste ;
  329. my $name = $hash->{NAME};
  330. my @calendernamen = split( ",", $hash->{KALENDER});
  331. my $modi = $attr{$name}{modes};
  332. my @modes = split(/,/,$modi);
  333. foreach my $calendername (@calendernamen){
  334. my $all = CallFn($calendername, "GetFn", $defs{$calendername},("-","events","format:custom='\$U|\$T1|\$T2|\$S|\$L|\$DS|\$CA|\$d'"));
  335. Log3 $name , 5, "CALVIEW $name - All data: \n$all ...";
  336. my @termine=split(/\n/,$all);
  337. foreach my $line (@termine){
  338. Log3 $name , 5, "CALVIEW $name - Termin: $line";
  339. my @lineparts = split(/\|/,$line);
  340. #my $terminstart = $lineparts[1];
  341. #my $terminend = $lineparts[2];
  342. #my $termintext = $lineparts[3];
  343. #my $terminort = $lineparts[4];
  344. #my $termindescription = $lineparts[5];
  345. #my $termincategories = $lineparts[6];
  346. #Log3 $name , 5, "CALVIEW $name - Termin splitted : $terminstart, $termintext, $terminend, $calendername, $terminort, $termindescription, $termincategories";
  347. push(@terminliste, [$lineparts[1], $lineparts[3], $lineparts[2], $calendername, $lineparts[4], $lineparts[5], $lineparts[6], "next", $lineparts[7]]);
  348. };
  349. };
  350. return @terminliste;
  351. }
  352. sub CALVIEW_Notify($$)
  353. {
  354. my ($hash, $extDevHash) = @_;
  355. my $name = $hash->{NAME}; # name calview device
  356. my $extDevName = $extDevHash->{NAME}; # name externes device
  357. my @calendernams = split( ",", $hash->{KALENDER});
  358. my $event;
  359. return "" if(IsDisabled($name)); # wenn attr disabled keine reaktion
  360. foreach my $calendar (@calendernams){
  361. if ($extDevName eq $calendar) {
  362. foreach $event (@{$extDevHash->{CHANGED}}) {
  363. if ($event eq "triggered") {
  364. Log3 $name , 5, "CALVIEW $name - CALENDAR:$extDevName triggered, updating CALVIEW $name (CALVIEW_Notify) ...";
  365. CALVIEW_GetUpdate($hash);
  366. Log3 $name , 5, "CALVIEW $name - CALENDAR:$extDevName successfully got all updates for CALVIEW $name (CALVIEW_Notify). Now process updates...";
  367. }
  368. }
  369. }
  370. }
  371. }
  372. 1;
  373. =pod
  374. =item device
  375. =item summary provides calendar events in a readable form
  376. =begin html
  377. <a name="CALVIEW"></a>
  378. <h3>CALVIEW</h3>
  379. <ul>This module creates a device with deadlines based on calendar-devices of the 57_Calendar.pm module. You need to install the perl-modul Date::Parse!</ul>
  380. <ul>Please configure the attribut HideOlderThen in your CALENDAR-Device, that controls if old events from past are shown!</ul>
  381. <b>Define</b>
  382. <ul><code>define &lt;Name&gt; CALVIEW &lt;calendarname(s) separate with ','&gt; &lt;next&gt; &lt;updateintervall in sec (default 43200)&gt;</code></ul>
  383. <ul><code>define myView CALVIEW Googlecalendar next</code></ul>
  384. <ul><code>define myView CALVIEW Googlecalendar,holiday next 900</code></ul>
  385. <ul>- setting the update interval is not needed normally because every calendar update triggers a caview update</ul>
  386. <a name="CALVIEW set"></a>
  387. <b>Set</b>
  388. <ul><code>set &lt;Name&gt; update</code></ul>
  389. <ul><code>set myView update</code></ul>
  390. <ul>this will manually update all readings from the given CALENDAR Devices</ul>
  391. <b>Attribute</b>
  392. <li>datestyle<br>
  393. not set - the default, disables displaying readings bdatetimeiso / edatetimeiso<br>
  394. ISO8601 - enables readings bdatetimeiso / edatetimeiso (start and end time of term ISO8601 formated like 2017-02-27T00:00:00)
  395. </li><br>
  396. <li>disable<br>
  397. 0 / not set - internal notify function enabled (default) <br>
  398. 1 - disable the internal notify-function of CALVIEW wich is triggered when one of the given CALENDAR devices has updated
  399. </li><br>filterSummary
  400. <li>filterSummary &lt;filtersouce&gt;:&lt;filtersummary&gt;[,&lt;filtersouce&gt;:&lt;filtersummary&gt;]<br>
  401. not set - displays all terms (default .*:.*) <br>
  402. &lt;filtersouce&gt;:&lt;filtersummary&gt;[,&lt;filtersouce&gt;:&lt;filtersummary&gt;] - CALVIEW will display term where summary matches the &lt;filtersouce&gt;:&lt;filtersummary&gt;, several filters must be separated by comma (,)
  403. e.g.: filterSummary Kalender_Abfall:Leichtverpackungen,Kalender_Abfall:Bioabfall
  404. filterSummary Kalender_Abfall:Leichtverpackungen,Kalender_Feiertage:.*,Kalender_Christian:.*,Kalender_Geburtstage:.*
  405. </li><br>
  406. <li>fulldaytext [text]<br>
  407. this text will be displayed in _timeshort reading for fullday terms (default ganztägig)
  408. </li><br>
  409. <li>isbirthday<br>
  410. 0 / not set - no age calculation (default) <br>
  411. 1 - age calculation active. The module calculates the age with year given in description or location (see att yobfield).
  412. </li><br>
  413. <li>maxreadings<br>
  414. defines the number of max term as readings
  415. </li><br>
  416. <li>modes<br>
  417. here the CALENDAR modes can be selected , to be displayed in the view
  418. </li><br>
  419. <li>oldStyledReadings<br>
  420. 0 the default style of readings <br>
  421. 1 readings look like "2015.06.21-00:00" with value "Start of Summer"
  422. </li><br>
  423. <li>sourcecolor &lt;calendername&gt;:&lt;colorcode&gt;[,&lt;calendername&gt;:&lt;colorcode&gt;]<br>
  424. here you can define the termcolor for terms from your calendars for the calview tabletui widget, several calendar:color pairs must be separated by comma
  425. </li><br>
  426. <li>timeshort<br>
  427. 0 time in _timeshort readings formated 00:00:00 <br>
  428. 1 time in _timeshort readings formated 00:00
  429. </li><br>
  430. <li>yobfield<br>
  431. _description - (default) year of birth will be read from term description <br>
  432. _location - year of birth will be read from term location <br>
  433. _summary - year of birth will be read from summary (uses the first sequence of 4 digits in the string)
  434. </li><br>
  435. <li>weekdayformat<br>
  436. formats the name of the reading weekdayname <br>
  437. - de-long - (default) german, long name like Dienstag <br>
  438. - de-short - german, short name like Di <br>
  439. - en-long - english, long name like Tuesday <br>
  440. - en-short - english, short name like Tue <br>
  441. </li><br>
  442. =end html
  443. =begin html_DE
  444. <a name="CALVIEW"></a>
  445. <h3>CALVIEW</h3>
  446. <ul>Dieses Modul erstellt ein Device welches als Readings Termine eines oder mehrere Kalender(s), basierend auf dem 57_Calendar.pm Modul, besitzt. Ihr müsst das Perl-Modul Date::Parse installieren!</ul>
  447. <ul>Bitte setzt das Attribut HideOlderThen in eurem CALENDAR_Device, da sonst auch vergangene Termine gezeigt werden.</ul>
  448. <b>Define</b>
  449. <ul><code>define &lt;Name&gt; CALVIEW &lt;Kalendername(n) getrennt durch ','&gt; &lt;next&gt; &lt;updateintervall in sek (default 43200)&gt;</code></ul>
  450. <ul><code>define myView CALVIEW Googlekalender next</code></ul>
  451. <ul><code>define myView CALVIEW Googlekalender,holiday next 900</code></ul>
  452. <ul>- die Einstellung des Aktualisierungsintervalls wird normalerweise nicht benötigt, da jede Kalenderaktualisierung ein Caview-Update auslöst</ul>
  453. <a name="CALVIEW set"></a>
  454. <b>Set</b>
  455. <ul>update readings:</ul>
  456. <ul><code>set &lt;Name&gt; update</code></ul>
  457. <ul><code>set myView update</code></ul><br>
  458. <b>Attributes</b>
  459. <li>datestyle<br>
  460. nicht gesetzt - Standard, Readings bdatetimeiso / edatetimeiso werden nicht gezeigt<br>
  461. ISO8601 - aktiviert die readings bdatetimeiso / edatetimeiso (zeigen Terminstart und Ende im ISO8601 Format zB. 2017-02-27T00:00:00)
  462. </li><br>
  463. <li>disable<br>
  464. 0 / nicht gesetzt - aktiviert die interne Notify-Funktion (Standard) <br>
  465. 1 - deaktiviert die interne Notify-Funktion welche ausgelöst wird wenn sich einer der Kalender aktualisiert hat
  466. </li><br>
  467. <li>filterSummary &lt;filtersouce&gt;:&lt;filtersummary&gt;[,&lt;filtersouce&gt;:&lt;filtersummary&gt;]<br>
  468. not set - zeigt alle Termine (Standard) <br>
  469. &lt;filtersouce&gt;:&lt;filtersummary&gt;[,&lt;filtersouce&gt;:&lt;filtersummary&gt;] - CALVIEW filtert Termine die &lt;filtersquelle&gt;:&lt;filtertitel&gt; entsprechen, mehrere Filter sind durch Komma (,) zu trennen.
  470. zb.: filterSummary Kalender_Abfall:Leichtverpackungen,Kalender_Abfall:Bioabfall
  471. filterSummary Kalender_Abfall:Leichtverpackungen,Kalender_Feiertage:.*,Kalender_Christian:.*,Kalender_Geburtstage:.*
  472. </li><br>
  473. <li>fulldaytext [text]<br>
  474. Dieser Text wird bei ganztägigen Terminen in _timeshort Readings genutzt (default ganztägig)
  475. </li><br>
  476. <li>isbirthday<br>
  477. 0 / nicht gesetzt - keine Altersberechnung (Standard) <br>
  478. 1 - aktiviert die Altersberechnung im Modul. Das Alter wird aus der in der Terminbeschreibung (description) angegebenen Jahreszahl (Geburtsjahr) berechnet. (siehe Attribut yobfield)
  479. </li><br>
  480. <li>maxreadings<br>
  481. bestimmt die Anzahl der Termine als Readings
  482. </li><br>
  483. <li>modes<br>
  484. hier können die CALENDAR modi gewählt werden, welche in der View angezeigt werden sollen
  485. </li><br>
  486. <li>oldStyledReadings<br>
  487. 0 die Standarddarstellung für Readings <br>
  488. 1 aktiviert die Termindarstellung im "alten" Format "2015.06.21-00:00" mit Wert "Start of Summer"
  489. </li><br>
  490. <li>sourcecolor &lt;calendername&gt;:&lt;colorcode&gt;[,&lt;calendername&gt;:&lt;colorcode&gt;]<br>
  491. Hier kann man die Farben für die einzelnen Calendar definieren die dann zb im Tabletui widget genutzt werden kann.
  492. Die calendar:color Elemente sind durch Komma zu trennen.
  493. So kann man zb die google-Kalender Farben auch in der TUI für eine gewohnte Anzeige nutzen.
  494. </li><br>
  495. <li>timeshort<br>
  496. 0 Zeit in _timeshort Readings im Format 00:00:00 - 00:00:00 <br>
  497. 1 Zeit in _timeshort Readings im Format 00:00 - 00:00
  498. </li><br>
  499. <li>yobfield<br>
  500. _description - (der Standard) Geburtsjahr wird aus der Terminbechreibung gelesen <br>
  501. _location - Geburtsjahr wird aus dem Terminort gelesen <br>
  502. _summary - Geburtsjahr wird aus dem Termintiele gelesen (verwendet wird die erste folge von 4 Ziffern im String))
  503. </li><br>
  504. <li>weekdayformat<br>
  505. formatiert den Namen im Reading weekdayname <br>
  506. - de-long - (default) Deutsch, lang zb Dienstag <br>
  507. - de-short - Deutsch, kurze zb Di <br>
  508. - en-long - English, lang zb Tuesday <br>
  509. - en-short - English, kurze zb Tue <br>
  510. </li><br>
  511. =end html_DE
  512. =cut