mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 12:49:34 +00:00
57_Calendar.pm ready for testing, documentation added
git-svn-id: https://svn.fhem.de/fhem/trunk@1597 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
36bc553df4
commit
1a3952141a
@ -26,7 +26,7 @@
|
||||
- feature: at attribute alignTime added
|
||||
- feature: FHEMWEB attribute values via dropdown, slider for dimmer
|
||||
- feature: new attribute group for FHEMWEB (Boris)
|
||||
- change: 11_FHT.pm, 50_WS300.pm, 59_Weather.pm migrated to redingsUpdate
|
||||
- change: 11_FHT.pm, 50_WS300.pm, 59_Weather.pm migrated to readingsUpdate
|
||||
mechanism (Boris)
|
||||
- change: updatefhem modifications to support a clean install of fhem and
|
||||
pgm2 installation, see commandref.html (M. Fischer)
|
||||
@ -38,6 +38,7 @@
|
||||
new global attribute <backupsymlink> added
|
||||
new global attribute <backupcmd> added
|
||||
new global attribute <backup_before_update> added
|
||||
- feature: new module 57_Calendar.pm (Boris(
|
||||
|
||||
- 2011-12-31 (5.2)
|
||||
- bugfix: applying smallscreen attributes to firefox/opera
|
||||
|
@ -1,11 +1,12 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
# 57_Calendar.pm
|
||||
# written by Dr. Boris Neubert 2012-05-20
|
||||
# written by Dr. Boris Neubert 2012-06-01
|
||||
# e-mail: omega at online dot de
|
||||
#
|
||||
##############################################
|
||||
# $Id$
|
||||
# $Id $
|
||||
|
||||
|
||||
use strict;
|
||||
@ -45,9 +46,12 @@ sub new {
|
||||
|
||||
sub addproperty {
|
||||
my ($self,$line)= @_;
|
||||
#main::debug $line;
|
||||
my ($property,$parameter)= split(":", $line);
|
||||
# TRIGGER;VALUE=DATE-TIME:20120531T150000Z
|
||||
#main::debug "line= $line";
|
||||
my ($property,$parameter)= split(":", $line); # TRIGGER;VALUE=DATE-TIME 20120531T150000Z
|
||||
#main::debug "property= $property parameter= $parameter";
|
||||
my ($key,$parts)= split(";", $property,2);
|
||||
#main::debug "key= $key parts= $parts";
|
||||
$parts= "" unless(defined($parts));
|
||||
$self->{properties}{$key}= {
|
||||
PARTS => "$parts",
|
||||
@ -122,7 +126,9 @@ sub new {
|
||||
my $self= {};
|
||||
bless $self, $class;
|
||||
$self->{_state}= "";
|
||||
$self->{_mode}= "undefined";
|
||||
$self->setState("new");
|
||||
$self->setMode("undefined");
|
||||
$self->{alarmTriggered}= 0;
|
||||
$self->{startTriggered}= 0;
|
||||
$self->{endTriggered}= 0;
|
||||
@ -134,6 +140,12 @@ sub uid {
|
||||
return $self->{uid};
|
||||
}
|
||||
|
||||
sub start {
|
||||
my ($self)= @_;
|
||||
return $self->{start};
|
||||
}
|
||||
|
||||
|
||||
sub setState {
|
||||
my ($self,$state)= @_;
|
||||
#main::debug "Before setState $state: States(" . $self->uid() . ") " . $self->{_previousState} . " -> " . $self->{_state};
|
||||
@ -143,6 +155,14 @@ sub setState {
|
||||
return $state;
|
||||
}
|
||||
|
||||
sub setMode {
|
||||
my ($self,$mode)= @_;
|
||||
$self->{_previousMode}= $self->{_mode};
|
||||
$self->{_mode}= $mode;
|
||||
main::debug "After setMode $mode: Modes(" . $self->uid() . ") " . $self->{_previousMode} . " -> " . $self->{_mode};
|
||||
return $mode;
|
||||
}
|
||||
|
||||
sub touch {
|
||||
my ($self,$t)= @_;
|
||||
$self->{_lastSeen}= $t;
|
||||
@ -159,6 +179,11 @@ sub state {
|
||||
return $self->{_state};
|
||||
}
|
||||
|
||||
sub mode {
|
||||
my ($self)= @_;
|
||||
return $self->{_mode};
|
||||
}
|
||||
|
||||
sub lastModified {
|
||||
my ($self)= @_;
|
||||
return $self->{lastModified};
|
||||
@ -192,10 +217,15 @@ sub isDeleted {
|
||||
|
||||
sub stateChanged {
|
||||
my ($self)= @_;
|
||||
main::debug "States(" . $self->uid() . ") " . $self->{_previousState} . " -> " . $self->{_state};
|
||||
#main::debug "States(" . $self->uid() . ") " . $self->{_previousState} . " -> " . $self->{_state};
|
||||
return $self->{_state} ne $self->{_previousState} ? 1 : 0;
|
||||
}
|
||||
|
||||
sub modeChanged {
|
||||
my ($self)= @_;
|
||||
return $self->{_mode} ne $self->{_previousMode} ? 1 : 0;
|
||||
}
|
||||
|
||||
# converts a date/time string to the number of non-leap seconds since the epoch
|
||||
# 20120520T185202Z: date/time string in ISO8601 format, time zone GMT
|
||||
# 20120520: a date string has no time zone associated
|
||||
@ -227,6 +257,8 @@ sub tm {
|
||||
sub d {
|
||||
my ($d)= @_;
|
||||
|
||||
main::debug "Duration $d";
|
||||
|
||||
my $sign= 1;
|
||||
my $t= 0;
|
||||
|
||||
@ -247,16 +279,33 @@ sub d {
|
||||
return $t;
|
||||
}
|
||||
|
||||
sub dt {
|
||||
my ($t0,$value,$parts)= @_;
|
||||
main::debug "t0= $t0 parts= $parts value= $value";
|
||||
if(defined($parts) && $parts =~ m/VALUE=DATE/) {
|
||||
return tm($value);
|
||||
} else {
|
||||
return $t0+d($value);
|
||||
}
|
||||
}
|
||||
|
||||
sub ts {
|
||||
my ($tm)= @_;
|
||||
my ($second,$minute,$hour,$day,$month,$year,$wday,$yday,$isdst)= localtime($tm);
|
||||
return sprintf("%02d.%02d.%4d %02d:%02d:%02d", $day,$month+1,$year+1900,$hour,$minute,$second);
|
||||
}
|
||||
|
||||
sub ts0 {
|
||||
my ($tm)= @_;
|
||||
my ($second,$minute,$hour,$day,$month,$year,$wday,$yday,$isdst)= localtime($tm);
|
||||
return sprintf("%02d.%02d.%2d %02d:%02d", $day,$month+1,$year-100,$hour,$minute);
|
||||
}
|
||||
|
||||
sub fromVEvent {
|
||||
my ($self,$vevent)= @_;
|
||||
|
||||
$self->{uid}= $vevent->value("UID");
|
||||
$self->{uid}=~ s/\W//g; # remove all non-alphanumeric characters, this makes life easier for perl specials
|
||||
$self->{start}= tm($vevent->value("DTSTART"));
|
||||
$self->{end}= tm($vevent->value("DTEND"));
|
||||
$self->{lastModified}= tm($vevent->value("LAST-MODIFIED"));
|
||||
@ -265,9 +314,9 @@ sub fromVEvent {
|
||||
|
||||
# alarms
|
||||
my @valarms= grep { $_->{type} eq "VALARM" } @{$vevent->{entries}};
|
||||
my @durations= sort map { d($_->value("TRIGGER")) } @valarms;
|
||||
if(@durations) {
|
||||
$self->{alarm}= $self->{start}+$durations[0];
|
||||
my @alarmtimes= sort map { dt($self->{start}, $_->value("TRIGGER"), $_->parts("TRIGGER")) } @valarms;
|
||||
if(@alarmtimes) {
|
||||
$self->{alarm}= $alarmtimes[0];
|
||||
} else {
|
||||
$self->{alarm}= undef;
|
||||
}
|
||||
@ -294,17 +343,31 @@ sub summary {
|
||||
|
||||
sub asText {
|
||||
my ($self)= @_;
|
||||
#return sprintf("%s-%s %s",
|
||||
# ts($self->{start}),
|
||||
# ts($self->{end}),
|
||||
# $self->{summary}
|
||||
#);
|
||||
return sprintf("%s %s",
|
||||
ts($self->{start}),
|
||||
ts0($self->{start}),
|
||||
$self->{summary}
|
||||
);
|
||||
}
|
||||
|
||||
sub asFull {
|
||||
my ($self)= @_;
|
||||
return sprintf("%s %7s %8s %s %s-%s %s",
|
||||
$self->uid(),
|
||||
$self->state(),
|
||||
$self->mode(),
|
||||
$self->{alarm} ? ts($self->{alarm}) : " ",
|
||||
ts($self->{start}),
|
||||
ts($self->{end}),
|
||||
$self->{summary}
|
||||
);
|
||||
}
|
||||
|
||||
# returns 1 if time is between alarm time and start time, else 0
|
||||
sub isUpcoming {
|
||||
my ($self,$t) = @_;
|
||||
return $t< $self->{alarm} ? 1 : 0;
|
||||
}
|
||||
|
||||
# returns 1 if time is between alarm time and start time, else 0
|
||||
sub isAlarmed {
|
||||
my ($self,$t) = @_;
|
||||
@ -313,11 +376,16 @@ sub isAlarmed {
|
||||
}
|
||||
|
||||
# return 1 if time is between start time and end time, else 0
|
||||
sub isRunning {
|
||||
sub isStarted {
|
||||
my ($self,$t) = @_;
|
||||
return $self->{start}<= $t && $t<= $self->{end} ? 1 : 0;
|
||||
}
|
||||
|
||||
sub isEnded {
|
||||
my ($self,$t) = @_;
|
||||
return $self->{end}< $t ? 1 : 0;
|
||||
}
|
||||
|
||||
sub nextTime {
|
||||
my ($self,$t) = @_;
|
||||
my @times= ( $self->{start}, $self->{end} );
|
||||
@ -398,21 +466,29 @@ sub updateFromCalendar {
|
||||
|
||||
$uid= $event->uid();
|
||||
#main::debug "Processing event $uid.";
|
||||
#foreach my $ee ($self->events()) {
|
||||
# main::debug $ee->asFull();
|
||||
#}
|
||||
if(defined($self->event($uid))) {
|
||||
# the event already exists
|
||||
#main::debug "Event $uid already exists.";
|
||||
$event->setState($self->event($uid)->state()); # copy the state from the existing event
|
||||
$event->setMode($self->event($uid)->mode()); # copy the mode from the existing event
|
||||
#main::debug "Our lastModified: " . ts($self->event($uid)->lastModified());
|
||||
#main::debug "New lastModified: " . ts($event->lastModified());
|
||||
if($self->event($uid)->lastModified() != $event->lastModified()) {
|
||||
$event->setState("updated")
|
||||
$event->setState("updated");
|
||||
#main::debug "We set it to updated.";
|
||||
} else {
|
||||
$event->setState("known")
|
||||
}
|
||||
};
|
||||
# new events that have ended are omitted
|
||||
if($event->state() ne "new" || !$event->isEnded($t)) {
|
||||
$event->touch($t);
|
||||
$self->setEvent($event);
|
||||
}
|
||||
}
|
||||
|
||||
# untouched elements get marked as deleted
|
||||
foreach $event ($self->events()) {
|
||||
@ -439,37 +515,83 @@ sub Calendar_Initialize($) {
|
||||
|
||||
}
|
||||
|
||||
###################################
|
||||
sub Calendar_Wakeup($) {
|
||||
|
||||
my ($hash) = @_;
|
||||
|
||||
my $t= time();
|
||||
|
||||
Calendar_GetUpdate($hash) if($t>= $hash->{fhem}{nxtUpdtTs});
|
||||
Calendar_CheckTimes($hash);
|
||||
|
||||
my $nt= $hash->{fhem}{nxtUpdtTs};
|
||||
|
||||
# find next event
|
||||
foreach my $event ($hash->{fhem}{events}->events()) {
|
||||
my $et= $event->nextTime($t);
|
||||
$nt= $et if(defined($et) && ($et< $nt));
|
||||
}
|
||||
|
||||
my ($second,$minute,$hour,$day,$month,$year,$wday,$yday,$isdst)= localtime($nt);
|
||||
$hash->{fhem}{nextUpdate}= sprintf("%02d.%02d.%4d %02d:%02d:%02d", $day,$month+1,$year+1900,$hour,$minute,$second);
|
||||
|
||||
InternalTimer($nt, "Calendar_Wakeup", $hash, 0) ;
|
||||
|
||||
}
|
||||
|
||||
###################################
|
||||
sub Calendar_CheckTimes($) {
|
||||
|
||||
my ($hash) = @_;
|
||||
my ($hash) = @_;
|
||||
|
||||
my $eventsObj= $hash->{fhem}{events};
|
||||
my $t= time();
|
||||
|
||||
# we now run over all events and update the readings for those with changed states
|
||||
# we now run over all events and update the readings
|
||||
my @allevents= $eventsObj->events();
|
||||
my @running= sort map { $_->uid() } grep { $_->isRunning($t) } @allevents;
|
||||
my @alarmed= sort map { $_->uid() } grep { $_->isAlarmed($t) } @allevents;
|
||||
my @upcomingevents= grep { $_->isUpcoming($t) } @allevents;
|
||||
my @alarmedevents= grep { $_->isAlarmed($t) } @allevents;
|
||||
my @startedevents= grep { $_->isStarted($t) } @allevents;
|
||||
my @endedevents= grep { $_->isEnded($t) } @allevents;
|
||||
|
||||
my $event;
|
||||
main::debug "Updating modes...";
|
||||
foreach $event (@upcomingevents) { $event->setMode("upcoming"); }
|
||||
foreach $event (@alarmedevents) { $event->setMode("alarm"); }
|
||||
foreach $event (@startedevents) { $event->setMode("start"); }
|
||||
foreach $event (@endedevents) { $event->setMode("end"); }
|
||||
|
||||
my @changedevents= grep { $_->modeChanged() } @allevents;
|
||||
|
||||
my @upcoming= sort map { $_->uid() } @upcomingevents;
|
||||
my @alarm= sort map { $_->uid() } @alarmedevents;
|
||||
my @alarmed= sort map { $_->uid() } grep { $_->modeChanged() } @alarmedevents;
|
||||
my @start= sort map { $_->uid() } @startedevents;
|
||||
my @started= sort map { $_->uid() } grep { $_->modeChanged() } @startedevents;
|
||||
my @end= sort map { $_->uid() } @endedevents;
|
||||
my @ended= sort map { $_->uid() } grep { $_->modeChanged() } @endedevents;
|
||||
my @changed= sort map { $_->uid() } @changedevents;
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
readingsUpdate($hash, "running", join(";", @running));
|
||||
readingsUpdate($hash, "alarmed", join(";", @alarmed));
|
||||
readingsUpdate($hash, "modeUpcoming", join(";", @upcoming));
|
||||
readingsUpdate($hash, "modeAlarm", join(";", @alarm));
|
||||
readingsUpdate($hash, "modeAlarmed", join(";", @alarmed));
|
||||
readingsUpdate($hash, "modeAlarmOrStart", join(";", @alarm,@start));
|
||||
readingsUpdate($hash, "modeChanged", join(";", @changed));
|
||||
readingsUpdate($hash, "modeStart", join(";", @start));
|
||||
readingsUpdate($hash, "modeStarted", join(";", @started));
|
||||
readingsUpdate($hash, "modeEnd", join(";", @end));
|
||||
readingsUpdate($hash, "modeEnded", join(";", @ended));
|
||||
readingsEndUpdate($hash, 1); # DoTrigger, because sub is called by a timer instead of dispatch
|
||||
|
||||
}
|
||||
|
||||
|
||||
###################################
|
||||
sub Calendar_GetUpdate($$)
|
||||
{
|
||||
my ($hash,$starttimer) = @_;
|
||||
sub Calendar_GetUpdate($) {
|
||||
|
||||
|
||||
if($starttimer) {
|
||||
#main::debug "Start timer: $starttimer, " . $hash->{fhem}{interval} . "s";
|
||||
InternalTimer(gettimeofday()+$hash->{fhem}{interval}, "Calendar_GetUpdate", $hash, 0) ;
|
||||
}
|
||||
my ($hash) = @_;
|
||||
|
||||
my $url= $hash->{fhem}{url};
|
||||
|
||||
@ -508,13 +630,13 @@ sub Calendar_GetUpdate($$)
|
||||
#$hash->{STATE}= $val;
|
||||
readingsBeginUpdate($hash);
|
||||
readingsUpdate($hash, "all", join(";", @all));
|
||||
readingsUpdate($hash, "new", join(";", @new));
|
||||
readingsUpdate($hash, "updated", join(";", @updated));
|
||||
readingsUpdate($hash, "deleted", join(";", @deleted));
|
||||
readingsUpdate($hash, "changed", join(";", @changed));
|
||||
readingsUpdate($hash, "stateNew", join(";", @new));
|
||||
readingsUpdate($hash, "stateUpdated", join(";", @updated));
|
||||
readingsUpdate($hash, "stateDeleted", join(";", @deleted));
|
||||
readingsUpdate($hash, "stateChanged", join(";", @changed));
|
||||
readingsEndUpdate($hash, 1); # DoTrigger, because sub is called by a timer instead of dispatch
|
||||
|
||||
Calendar_CheckTimes($hash);
|
||||
$hash->{fhem}{nxtUpdtTs}= time()+$hash->{fhem}{interval};
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -526,7 +648,8 @@ sub Calendar_Set($@) {
|
||||
|
||||
# usage check
|
||||
if((@a == 2) && ($a[1] eq "update")) {
|
||||
Calendar_GetUpdate($hash,0);
|
||||
$hash->{fhem}{nxtUpdtTs}= 0; # force update
|
||||
Calendar_Wakeup($hash);
|
||||
return undef;
|
||||
} else {
|
||||
return "Unknown argument $cmd, choose one of update";
|
||||
@ -538,44 +661,47 @@ sub Calendar_Get($@) {
|
||||
|
||||
my ($hash, @a) = @_;
|
||||
|
||||
return "argument is missing" if($#a != 2);
|
||||
|
||||
my $eventsObj= $hash->{fhem}{events};
|
||||
my @uids;
|
||||
my @events;
|
||||
|
||||
my $cmd= $a[1];
|
||||
if($cmd eq "text") {
|
||||
|
||||
if($cmd eq "text" || $cmd eq "full") {
|
||||
|
||||
return "argument is missing" if($#a != 2);
|
||||
my $reading= $a[2];
|
||||
|
||||
# $reading is alarmed, all, changed, deleted, new, running, updated
|
||||
# $reading is alarmed, all, changed, deleted, new, started, updated
|
||||
# if $reading does not match any of these it is assumed to be a uid
|
||||
if(defined($hash->{READINGS}{$reading})) {
|
||||
@uids= split(";", $hash->{READINGS}{$reading}{VAL});
|
||||
@events= grep { my $uid= $_->uid(); $hash->{READINGS}{$reading}{VAL} =~ m/$uid/ } $eventsObj->events();
|
||||
} else {
|
||||
@uids= sort map { $_->uid() } grep { $_->uid() eq $reading } $eventsObj->events();
|
||||
@events= grep { $_->uid() eq $reading } $eventsObj->events();
|
||||
}
|
||||
|
||||
my @texts;
|
||||
if(@uids) {
|
||||
foreach my $uid (@uids) {
|
||||
my $event= $eventsObj->event($uid);
|
||||
push @texts, $event->asText();
|
||||
|
||||
|
||||
if(@events) {
|
||||
foreach my $event (sort { $a->start() <=> $b->start() } @events) {
|
||||
push @texts, $event->asText() if $cmd eq "text";
|
||||
push @texts, $event->asFull() if $cmd eq "full";
|
||||
}
|
||||
}
|
||||
return join("\n", @texts);
|
||||
|
||||
} elsif($cmd eq "find") {
|
||||
|
||||
return "argument is missing" if($#a != 2);
|
||||
my $regexp= $a[2];
|
||||
my @uids;
|
||||
foreach my $event ($eventsObj->events()) {
|
||||
push @uids, $event->uid() if($event->summary() =~ m/$regexp/);
|
||||
}
|
||||
return join(";", @uids);
|
||||
|
||||
} else {
|
||||
return "Unknown argument $cmd, choose one of text find";
|
||||
return "Unknown argument $cmd, choose one of text full find";
|
||||
}
|
||||
|
||||
}
|
||||
@ -606,7 +732,8 @@ sub Calendar_Define($$) {
|
||||
$hash->{fhem}{events}= Calendar::Events->new();
|
||||
|
||||
#main::debug "Interval: ${interval}s";
|
||||
Calendar_GetUpdate($hash,1);
|
||||
$hash->{fhem}{nxtUpdtTs}= 0;
|
||||
Calendar_Wakeup($hash);
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
@ -70,6 +70,7 @@
|
||||
<a href="#ALL4000T">ALL4000T</a>
|
||||
<a href="#ALL4027">ALL4027</a>
|
||||
<a href="#BS">BS</a>
|
||||
<a href="#Calendar">Calendar</a>
|
||||
<a href="#CM11">CM11</a>
|
||||
<a href="#CUL">CUL</a>
|
||||
<a href="#CUL_EM">CUL_EM</a>
|
||||
@ -1356,6 +1357,170 @@ A line ending with \ will be concatenated with the next one, so long lines
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<a name="Calendar"></a>
|
||||
<h3>Calendar</h3>
|
||||
<ul>
|
||||
<br>
|
||||
|
||||
Note: this module requires the Time::Local module.<br><br>
|
||||
|
||||
<a name="Calendardefine"></a>
|
||||
<b>Define</b>
|
||||
<ul>
|
||||
<code>define <name> Calendar ical url <URL> [<interval>]</code><br>
|
||||
<br>
|
||||
Defines a calendar device.<br><br>
|
||||
|
||||
A calendar device periodically gathers calendar events from the source calendar at the given URL. The URL must
|
||||
start with <code>http://</code>, not <code>https://</code>, and the file at the given URL
|
||||
must be in ICal format.<br><br>
|
||||
|
||||
The optional parameter <code>interval</code> is the time between subsequent updates
|
||||
in seconds. It defaults to 3600 (1 hour).<br><br>
|
||||
|
||||
Examples:
|
||||
<pre>
|
||||
define MyCalendar Calendar ical url http://www.google.com/calendar/ical/john.doe@example.com/private-foo4711/basic.ics
|
||||
define YourCalendar Calendar ical url http://www.google.com/calendar/ical/jane.doe@example.com/private-bar0815/basic.ics 86400
|
||||
</pre>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<a name="Calendarset"></a>
|
||||
<b>Set </b>
|
||||
<ul>
|
||||
<code>set <name> update</code><br><br>
|
||||
|
||||
Forces the retrieval of the calendar from the URL. The next automatic retrieval is scheduled to occur
|
||||
<code>interval</code> seconds later.<br><br>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
|
||||
<a name="Calendarget"></a>
|
||||
<b>Get</b>
|
||||
<ul>
|
||||
<code>get <name> full|text <reading>|<uid></code><br><br>
|
||||
|
||||
Returns, line by line, the full state or a textual representation of the calendar event(s) listed in the
|
||||
reading lt;reading> or identified by the UID <uid>.<br><br>
|
||||
|
||||
<code>get <name> find <regexp></code><br><br>
|
||||
|
||||
Returns, line by line, the UIDs of all calendar events whose summary matches the regular expression
|
||||
<regexp>.<br><br>
|
||||
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<a name="Calendarattr"></a>
|
||||
<b>Attributes</b>
|
||||
<ul>
|
||||
<li><a href="#event-on-update-reading">event-on-update-reading</a></li>
|
||||
<li><a href="#event-on-change-reading">event-on-change-reading</a></li>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<b>Description</b>
|
||||
<ul>
|
||||
|
||||
A calendar is a set of calendar events. A calendar event has a summary (usually the title shown in a visual
|
||||
representation of the source calendar), a start time, an end time, and zero, one or more alarm times. The calendar events are
|
||||
fetched from the source calendar at the given URL. In case of multiple alarm times for a calendar event, only the
|
||||
earliest alarm time is kept. Recurring calendar events are currently not supported.<p>
|
||||
|
||||
A calendar event is identified by its UID. The UID is taken from the source calendar. All non-alphanumerical characters
|
||||
are stripped off the UID to make your life easier.<p>
|
||||
|
||||
A calendar event can be in one of the following states:
|
||||
<table>
|
||||
<tr><td>new</td><td>The calendar event was first seen at the most recent update. Either this was your first retrieval of
|
||||
the calendar or you newly added the calendar event to the source calendar.</td></tr>
|
||||
<tr><td>known</td><td>The calendar event was already there before the most recent update.</td></tr>
|
||||
<tr><td>updated</td><td>The calendar event was already there before the most recent update but it has changed since it
|
||||
was last retrieved.</td></tr>
|
||||
<tr><td>deleted</td><td>The calendar event was there before the most recent update but is no longer. You removed it from the source calendar. The calendar event will be removed from all lists at the next update.</td></tr>
|
||||
</table>
|
||||
Calendar events that lie completely in the past (current time on wall clock is later than the calendar event's end time)
|
||||
are not retrieved and are thus not accessible through the calendar.
|
||||
<p>
|
||||
|
||||
A calendar event can be in one of the following modes:
|
||||
<table>
|
||||
<tr><td>upcoming</td><td>Neither the alarm time nor the start time of the calendar event is reached.</td></tr>
|
||||
<tr><td>alarm</td><td>The alarm time has passed but the start time of the calendar event is not yet reached.</td></tr>
|
||||
<tr><td>start</td><td>The start time has passed but the end time of the calendar event is not yet reached.</td></tr>
|
||||
<tr><td>end</td><td>The end time of the calendar event has passed.</td></tr>
|
||||
</table>
|
||||
A calendar event transitions from one mode to another immediately when the time for the change has come. This is done by waiting
|
||||
for the earliest future time among all alarm, start or end times of all calendar events.
|
||||
<p>
|
||||
|
||||
A calendar device has several readings. Each reading is a semicolon-separated list of UIDs of
|
||||
calendar events that satisfy certain conditions:
|
||||
<table>
|
||||
<tr><td>all</td><td>all events</td></tr>
|
||||
<tr><td>modeAlarm</td><td>events in alarm mode</td></tr>
|
||||
<tr><td>modeAlarmOrStart</td><td>events in alarm or start mode</td></tr>
|
||||
<tr><td>modeAlarmed</td><td>events that have just transitioned from upcoming to alarm mode</td></tr>
|
||||
<tr><td>modeChanged</td><td>events that have just changed their mode somehow</td></tr>
|
||||
<tr><td>modeEnd</td><td>events in end mode</td></tr>
|
||||
<tr><td>modeEnded</td><td>events that have just transitioned from start to end mode</td></tr>
|
||||
<tr><td>modeStart</td><td>events in start mode</td></tr>
|
||||
<tr><td>modeStarted</td><td>events that have just transitioned to start mode</td></tr>
|
||||
<tr><td>modeUpcoming</td><td>events in upcoming mode</td></tr>
|
||||
<tr><td>stateChanged</td><td>events that have just changed their state somehow</td></tr>
|
||||
<tr><td>stateDeleted</td><td>events in state deleted</td></tr>
|
||||
<tr><td>stateNew</td><td>events in state new</td></tr>
|
||||
<tr><td>stateUpdated</td><td>events in state updated</td></tr>
|
||||
</table>
|
||||
</ul>
|
||||
<p>
|
||||
|
||||
<b>Usage scenarios</b>
|
||||
<ul>
|
||||
<i>Show all calendar events with details</i><br><br>
|
||||
<ul>
|
||||
<code>
|
||||
get MyCalendar full all<br>
|
||||
2767324dsfretfvds7dsfn3e4dsa234r234sdfds6bh874googlecom known alarm 31.05.2012 17:00:00 07.06.2012 16:30:00-07.06.2012 18:00:00 Erna for coffee<br>
|
||||
992hydf4;44awer5466lhfdsrgl7tin6b6mckf8glmhui4googlecom known upcoming 08.06.2012 00:00:00-09.06.2012 00:00:00 Vacation
|
||||
</code><br><br>
|
||||
</ul>
|
||||
|
||||
<i>Show calendar events in your photo frame</i><br><br>
|
||||
<ul>
|
||||
Put a line in the <a href="#RSSlayout">layout description</a> to show calendar events in alarm or start mode:<br><br>
|
||||
<code>text 20 60 { fhem("get MyCalendar text modeAlarmOrStart") }</code><br><br>
|
||||
This may look like:<br><br>
|
||||
<code>
|
||||
07.06.12 16:30 Erna for coffee<br>
|
||||
08.06.12 00:00 Vacation
|
||||
</code><br><br>
|
||||
</ul>
|
||||
|
||||
<i>Switch the light on when Erna comes</i><br><br>
|
||||
<ul>
|
||||
First find the UID of the calendar event:<br><br>
|
||||
<code>
|
||||
get MyCalendar find .*Erna.*<br>
|
||||
2767324dsfretfvds7dsfn3e4dsa234r234sdfds6bh874googlecom
|
||||
</code><br><br>
|
||||
The define a notify:<br><br>
|
||||
<code>
|
||||
define ErnaComes notify MyCalendar:modeStarted.*2767324dsfretfvds7dsfn3e4dsa234r234sdfds6bh874googlecom.* set MyLight on
|
||||
</code><br><br>
|
||||
You can also do some logging:<br><br>
|
||||
<code>
|
||||
define LogErna notify MyCalendar:modeAlarmed.*2767324dsfretfvds7dsfn3e4dsa234r234sdfds6bh874googlecom.* { Log 1, "ALARM name=%NAME event=%EVENT part1=%EVTPART0 part2=%EVTPART1" }
|
||||
</code><br><br>
|
||||
</ul>
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<a name="FHZ"></a>
|
||||
|
Loading…
Reference in New Issue
Block a user