gelöst:Schichtkalender mit iCal

Begonnen von heha, 23 Januar 2015, 11:01:56

Vorheriges Thema - Nächstes Thema

heha

Hallo,

ich möchte die Heizungsthermostate abhängig von der jeweiligen Schicht meiner Frau steuern.
Dafür gibt es einen Dummy "Schicht". Dessen Status möchte ich auf "frueh", "spaet", "nacht", "frei" setzen mittels Abfrage eines iCal-Kalenders.
Ich habe mir das Beispiel aus dem Wiki "Google-Kalender zur Steuerung von Dummies" umgebaut. Hier meine 99_myUtils.pm:


sub
Kalenderstatus ($)
{
my ($Ereignis) = @_;
my @Ereignisarray = split(/.*:\s/,$Ereignis);
my $Ereignisteil1 = $Ereignisarray[1];
my @uids=split(/;/,$Ereignisteil1);
foreach my $uid (@uids) {
my $Kalendertext = fhem("get SchichtCal summary $uid");
if ($Kalendertext =~ /.*Früh.*/) {
fhem("set Schicht frueh");
};
if ($Kalendertext =~ /.*Spät.*/) {
fhem("set Schicht spaet");
};
if ($Kalendertext =~ /.*Nacht.*/) {
fhem("set Schicht nacht");
} else {fhem("set Schicht frei")};
};
}
1;


Da im Kalender auch "Lange Früh" als Termin vorkommen kann, frage ich mit /.*Früh.*/ ab.
Falls kein Eintrag im Kalender ist, soll der Dummy "Schicht" auf "frei" gesetzt werden, deshalb das else.

Der Calendar und das notify sehen so aus:


define SchichtCal Calendar ical url https://p27-calendarws.icloud.com/ca/subscribe/1/xxxxxxxxxxxxxxxxxxxxxx

define SchichtCal_Status notify SchichtCal:modeAlarmOrStart.*0.* {Kalenderstatus("$EVENT");;}



Die Kalenderabfrage funktioniert. Ein get full all zeigt mir die Termine an. Bei einem set update wird mein Dummy aber nicht gesetzt.

Habe ich irgendwo einen Syntaxfehler drin oder ist grundsätzlich etwas falsch?

Es wäre schön, wenn mir hier jemand weiterhelfen könnte.

Viele Grüße, Helge

JensS

Hallo Helge,

meine Kentnisse in der Hinsicht sind eher dürftig aber vielleicht hilft's. Die Else würde ich aussen vor lassen, ansonsten würde ein elsif statt if vor Spät und Nacht auch gehen. Dazu müssten die Semikola vor elsif weg.
Für meine Zwecke hatte ich die Wiki-Variante etwas erweitert. http://forum.fhem.de/index.php/topic,30734.0.html Da könntest du die Dienstzeiten (Früh) direkt einem Device(Früh) zuordnen.

Gruß Jens
Debian auf APU2C4, HM-CFG-USB2, SIGNALduino, HM-ES-PMSw1-Pl, TFA 30.3121, TFA 30.3125, ITS-150, PIR-5000, configurable Firmata USB & LAN, 1-wire: DS-18B20, DS-18S20, DS-2408, DS-2413, diverse I2C-Komponenten, zigbee2mqtt, ESPEasy etc.

heha

Danke Jens,

das ist eine Menge zum Durcharbeiten, schaue ich mir mal an wenn mehr Zeit ist.

Mein aktueller Stand der 99_myUtils ist nach vielem Lesen nun folgender:

sub
Kalenderstatus ($)
{
my ($Ereignis) = @_;
my @Ereignisarray = split(/.*:\s/,$Ereignis);
my $Ereignisteil1 = $Ereignisarray[1];
my @uids=split(/;/,$Ereignisteil1);
foreach my $uid (@uids) {
my $Kalendertext = fhem("get SchichtCal summary $uid");
if ($Kalendertext =~ /Fr/) {
fhem("set Schicht frueh");
};
if ($Kalendertext =~ /Sp/) {
fhem("set Schicht spaet");
};
if ($Kalendertext =~ /Nacht/) {
fhem("set Schicht nacht");
};
if ($Kalendertext =~ /Fortbildung/) {
fhem("set Schicht frueh");
};
if ($Kalendertext =~ /Urlaub/) {
fhem("set Schicht frei");
};
};
}
1;


und das notify in der fhem.cfg:


define SchichtCal_Status notify IF (SchichtCal:modeAlarmOrStart.*) ({Kalenderstatus("$EVENT");;}) ELSE (set Schicht frei)


Funktioniert aber nicht. Ist die Syntax im notify so ok?

Zum Lernen und für die Fehlersuche: Wie kann ich die Subroutine in der Kommandozeile ausführen lassen, damit ich die Ausgabe dann sehe?


JensS

Bei meinem Termin-Beginn-notify sieht es so aus: Kalender_fhem:modeStarted.*.* {Kalenderstart("$EVENT");;}
Debian auf APU2C4, HM-CFG-USB2, SIGNALduino, HM-ES-PMSw1-Pl, TFA 30.3121, TFA 30.3125, ITS-150, PIR-5000, configurable Firmata USB & LAN, 1-wire: DS-18B20, DS-18S20, DS-2408, DS-2413, diverse I2C-Komponenten, zigbee2mqtt, ESPEasy etc.

heha

Ich habe es jetzt so weit hinbekommen, dass mein Dummy je nach Termin gesetzt wird. Nur falls mein Kalender keinen Termin hat, sollte der Dummy auf "frei" gesetzt werden. Das funktioniert leider nicht. Der alte state wird durch die else nicht überschrieben. Die Suchabfragen müssten doch alle unwahr zurückgeben bei leerem String und die else zuschlagen, oder?

sub
Kalenderstatus($)
{
my ($Ereignis) = @_;
my @Ereignisarray = split(/.*:\s/,$Ereignis);
my $Ereignisteil1 = $Ereignisarray[1];
my @uids=split(/;/,$Ereignisteil1);
foreach my $uid (@uids) {
my $Kalendertext = fhem("get TestCal summary $uid");
if ($Kalendertext =~ /Fr/) {
fhem("set SchichtTest frueh");
}
elsif ($Kalendertext =~ /Sp/) {
fhem("set SchichtTest spaet");
}
elsif ($Kalendertext =~ /Nacht/) {
fhem("set SchichtTest nacht");
}
elsif ($Kalendertext =~ /Fortbildung/) {
fhem("set SchichtTest frueh");
}
elsif ($Kalendertext =~ /Urlaub/) {
fhem("set SchichtTest frei");
}
else {
fhem("set SchichtTest frei");
};
};
}
1;

JensS

Nein, die Aufgabe des Kalenders ist eben, Termine auszuwerten. Falls du explizit 2frei" brauchst, musst die einen Termin "frei" anlegen. Mit diesem Termin kannst dann einen dummy schalten, von dem wiederum ein notify früh, spät und Fortbildung off schalten kann. Das klingt komliziert, ist ist es auch.  ;)
Gruß Jens
Debian auf APU2C4, HM-CFG-USB2, SIGNALduino, HM-ES-PMSw1-Pl, TFA 30.3121, TFA 30.3125, ITS-150, PIR-5000, configurable Firmata USB & LAN, 1-wire: DS-18B20, DS-18S20, DS-2408, DS-2413, diverse I2C-Komponenten, zigbee2mqtt, ESPEasy etc.

heha

Ja aber: Was in der sub passiert, ist doch reiner Perl-Code. Dafür ist doch dann die else da, wenn die Stringabfragen davor nicht erfolgreich waren und müsste wiederum den fhem-Befehl ausführen und meinen Dummy setzen. Das hat jetzt erst mal mit dem Kalendermodul nichts zu tun oder?

JensS

Letztendlich muss dafür ein Termin existieren. Wenn dieser die obigen Bedingungen nicht erfüllt, dann greift natürlich else für den Termin. Falls du noch weitere Termine, wie z.B. Abfallkalender hast, wird auch dort eine freie Schicht eingetragen, weil früh, spät, etc. nicht greift.
Debian auf APU2C4, HM-CFG-USB2, SIGNALduino, HM-ES-PMSw1-Pl, TFA 30.3121, TFA 30.3125, ITS-150, PIR-5000, configurable Firmata USB & LAN, 1-wire: DS-18B20, DS-18S20, DS-2408, DS-2413, diverse I2C-Komponenten, zigbee2mqtt, ESPEasy etc.

heha

Hm, ich denke jetzt verstehe ich es.
Ich versuche mal über ein DOIF anstelle des notify meinen dummy bei leerem Termin zu setzen.

JensS

DOIF([frueh] eq "off" and [spaet] eq "off")(set frei on)DOELSE(set frei off) - so etwa?
Debian auf APU2C4, HM-CFG-USB2, SIGNALduino, HM-ES-PMSw1-Pl, TFA 30.3121, TFA 30.3125, ITS-150, PIR-5000, configurable Firmata USB & LAN, 1-wire: DS-18B20, DS-18S20, DS-2408, DS-2413, diverse I2C-Komponenten, zigbee2mqtt, ESPEasy etc.

heha

Nachdem ich nun begriffen habe, dass sich ein leeres Reading im Kalendermodul nicht abfragen lässt, kam mir doch die geniale Idee:  ;)

In der Nacht setzte ich meinen Dummy "Schicht" auf "frei" und frage dann meinen Kalender ab.
define SchichtCalReset DOIF ([03:00:00])(set Schicht frei) DOELSEIF ([03:00:10])(set SchichtCal reload)
Wenn kein Termin vorhanden ist, bleibt's bei "frei", ansonsten wird durch ein notify
define SchichtCalSet notify SchichtCal:modeStarted.*.* {Kalenderstatus("$EVENT");;;;} die sub in der 99_myUtils.pm ausgeführt
sub
Kalenderstatus($)
{
my ($Ereignis) = @_;
my @Ereignisarray = split(/.*:\s/,$Ereignis);
my $Ereignisteil1 = $Ereignisarray[1];
my @uids=split(/;/,$Ereignisteil1);
foreach my $uid (@uids) {
my $Kalendertext = fhem("get SchichtCal summary $uid");
if ($Kalendertext =~ /Fr/) {
fhem("set Schicht frueh");
}
elsif ($Kalendertext =~ /Sp/) {
fhem("set Schicht spaet");
}
elsif ($Kalendertext =~ /Nacht/) {
fhem("set Schicht nacht");
}
elsif ($Kalendertext =~ /Fortbildung/) {
fhem("set Schicht frueh");
};
};
}

Sollte ein Suchtext gefunden werden, wird mein Dummy entsprechend gesetzt.
Im Anschluss schicken dann weitere DOIF's die jeweiligen Temperaturlisten an die Thermostate.

Vielleicht ginge es auch noch einfacher, aber so funktioniert es wie gewünscht und ich bedanke mich bei Jens für die Unterstützung.