Hallo,
ich habe hier folgendes DOIF aufgebaut:
nternals:
CFGFN config/05-Garten.cfg
DEF ([16:30-{OffTimeLicht()}] and
[state.TW.Tageslicht.dum] eq "dunkel" and
[?state.TW.Tageslicht.dum:SU] lt {TimeOffset (OffTimeLicht(),'-30')})
(set GA.ss.SA.Licht on)
DOELSE
(set GA.ss.SA.Licht off)
NAME di.01.GA.ss.SA.Licht
NR 498
NTFY_ORDER 50-di.01.GA.ss.SA.Licht
STATE on
TYPE DOIF
Readings:
2015-02-23 18:03:07 cmd_event state.TW.Tageslicht.dum
2015-02-23 18:03:07 cmd_nr 1
2015-02-23 18:03:07 e_state.TW.Tageslicht.dum_STATE dunkel
2015-02-23 18:03:07 state on
2015-02-23 16:30:00 timer_1_c1 24.02.2015 16:30:00
2015-02-22 22:00:00 timer_2_c1 23.02.2015 22:00:00
Condition:
0 DOIF_time($hash->{realtime}{0},$hash->{realtime}{1},$wday,$hms,"") and InternalDoIf('state.TW.Tageslicht.dum','STATE','') eq "dunkel" and ReadingValDoIf('state.TW.Tageslicht.dum','SU','') lt {TimeOffset (OffTimeLicht(),'-30')}
Days:
Devices:
0 state.TW.Tageslicht.dum
all state.TW.Tageslicht.dum
Do:
0 set GA.ss.SA.Licht on
1 set GA.ss.SA.Licht off
Helper:
last_timer 2
sleeptimer -1
Internals:
0 state.TW.Tageslicht.dum:STATE
all state.TW.Tageslicht.dum:STATE
Readings:
Realtime:
0 16:30:00
1 22:00:00
State:
Time:
0 16:30:00
1 {OffTimeLicht()}
Timecond:
0 0
1 0
Timer:
0 0
1 0
Timerfunc:
Timers:
0 0 1
Trigger:
Attributes:
alias autom. Gartenlicht
cmdState on|off
devStateIcon .*on:light_light_dim_100@lightgreen .*off:light_light_dim_00@red
do always
group Scripte
room 05-Garten
sortby 01
Getriggert wird hier jeweils um 16:30 und um die Zeit, die in der SUB "OffTimeLicht" berechnet wird. Dass heißt, meine Offtime basiert immer auf den Berechnungen des Vortages. (Timer2 ist von gestern 22:00). Das ist aber schlecht, da ich mit dem Trigger der Einschaltzeit eigentlich auch die aktuelle Ausschaltzeit benötige. gibt es hier eine Methode, wie ich das realisieren kann?
Spartacus
Hi,
ich habe nun versucht, die Berechnung der OffTimeLicht in dem Trigger um 16:30 zu berechnen und in einer Variablen zu speichern. my $OffTime= OfftimeLicht() um dann einen Trigger für die Ausschaltzeit zu generieren.
([16:30] {my $OffTime= OfftimeLicht()}) (set Aktor on)
DOELSEIF
([$OffTime)]) (set Aktor off)
Aber diese Logik funzt nicht! Offenbar kann man auf diese variable Zeit nicht triggern!
Hat jemand eine Idee?
Christian
Zitat von: Spartacus am 24 Februar 2015, 17:51:32
Hi,
ich habe nun versucht, die Berechnung der OffTimeLicht in dem Trigger um 16:30 zu berechnen und in einer Variablen zu speichern. my $OffTime= OfftimeLicht() um dann einen Trigger für die Ausschaltzeit zu generieren.
([16:30] {my $OffTime= OfftimeLicht()}) (set Aktor on)
DOELSEIF
([$OffTime)]) (set Aktor off)
Aber diese Logik funzt nicht! Offenbar kann man auf diese variable Zeit nicht triggern!
Hat jemand eine Idee?
Christian
Wie sieht OfftimeLicht() aus?
Ich würde die Zeitangabe ganz in der perl-fuction berechen, sodass der Returnwert wie folgt aussieht:
hh:mm-hh:mm
und DOIF Define:
([{TimeLicht()}]) (set Aktor on) DOELSE (set Aktor off)
Hallo flurin,
das ist ein guter Tipp! Vielen Dank! Allerdings nutze ich die Routine noch dazu um die Schaltschwelle für das Ausschalten einzustellen.
Die Sub TimeOffset ist geklaut und subtrahiert 30min von der Ausschaltzeit. Das soll im Sommer verhindern (?state.TW.Tageslicht.dum:SU=> Zeit des Sonnenuntergangs), dass die Einschaltzeit mindestens 30min vor der Ausschaltzeit liegt um ein zu kurzes Einschalten des Aktors zu vermeiden. Etwas Besseres ist mir hier nicht eingefallen. Wenn ich jetzt in meiner Zeitberechnung "TimeOffLicht" [Start-Ende] zurückgebe, funktioniert mein Offset nicht mehr, oder?
DOIF:
([16:30-{OffTimeLicht()}] and
[state.TW.Tageslicht.dum] eq "dunkel" and
[?state.TW.Tageslicht.dum:SU] lt {TimeOffset (OffTimeLicht(),'-30')})
(set GA.ss.SA.Licht on)
DOELSE
(set GA.ss.SA.Licht off)
SUB OffTimeLicht:
sub OffTimeLicht ()
{
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
if (ReadingsVal("hl.01.Feiertag","today","") =~ m/Silvester/)
{
return ("02:30:00")
}
elsif ((ReadingsVal("hl.01.Feiertag","tomorrow","")=~ m/none/) && ($wday =~ m/[01234]/))
{
return ("22:00:00")
}
elsif ((ReadingsVal("hl.01.Feiertag","tomorrow","") !~ m/none/) || ($wday =~ m/[56]/))
{
return ("23:00:00")
}
}
SUB TimeOffset:
sub TimeOffset($;$)
{
my $PtimeOrg = shift;
my $Poffset = shift;
$PtimeOrg = "" unless(defined($PtimeOrg));
$Poffset = 0 unless(defined($Poffset));
my ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime;
if ($PtimeOrg !~ /[0-2][0-9]:[0-5][0-9]/ or substr($PtimeOrg,0,2) >= 24) {$PtimeOrg = $hour.":".$min;}
my $TimeP = mktime(0,substr($PtimeOrg,3,2),substr($PtimeOrg,0,2),$mday,$month,$year,$wday,$yday,$isdst);
my $TimePM = $TimeP + $Poffset * 60;
my ($Psec,$Pmin,$Phour,$Pmday,$Pmonth,$Pyear,$Pwday,$Pyday,$Pisdst) = localtime($TimePM);
my $ReturnText = sprintf("%02d:%02d", $Phour, $Pmin);
}
Gruß,
Christian
Versuchs mal so:
sub OffTimeLicht ($)
{
my ($start_time) = @_;
my $ret;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
if (ReadingsVal("hl.01.Feiertag","today","") =~ m/Silvester/)
{
$ret = "02:30";
}
elsif ((ReadingsVal("hl.01.Feiertag","tomorrow","")=~ m/none/) && ($wday =~ m/[01234]/))
{
$ret = "22:00";
}
elsif ((ReadingsVal("hl.01.Feiertag","tomorrow","") !~ m/none/) || ($wday =~ m/[56]/))
{
$ret = "23:00";
}
if (defined($start_time)) {
$ret = $start_time."-".$ret;
}
return $ret;
}
und
([{OffTimeLicht("16:30")}] and
[state.TW.Tageslicht.dum] eq "dunkel" and
[?state.TW.Tageslicht.dum:SU] lt {TimeOffset (OffTimeLicht(""),'-30')})
(set GA.ss.SA.Licht on)
DOELSE
(set GA.ss.SA.Licht off)
ungetestet!
Hallo flurin,
Nicht schlecht! Das hätte ich im Leben nicht hingekriegt! Wenn ich die Sub ohne Startzeit aufrufe, dann soll die Endzeit zurückgegeben werden.
Der Aufruf von {OffTimeLicht("16:30")}
liefert mir nun den kompletten String!
16:30-22:00. Das ist perfekt!
Der Aufruf {OffTimeLicht("")}
liefert mir "-22:00". Müsste hier nicht nur "22:00" ausgegeben werden? Sorry, ich verstehe nicht genau, was der Code hier macht!
if (defined($start_time)) {
$ret = $start_time."-".$ret;
Christian
Zitat von: Spartacus am 24 Februar 2015, 20:10:38
Der Aufruf {OffTimeLicht("")}
liefert mir "-22:00". Müsste hier nicht nur "22:00" ausgegeben werden? Sorry, ich verstehe nicht genau, was der Code hier macht!
if (defined($start_time)) {
$ret = $start_time."-".$ret;
OK, ändere diesen Code wie folgt:
if ($start_time ne "") {
$ret = $start_time."-".$ret;
}
Hallo,
es funzt! Du setzt die Startzeit in diesem Code zusammen;
$ret = $start_time."-".$ret;
"Übergabeparameter" - "berechnete EndeZeit".
Danke,
jetzt habe ich es gerafft!
Christian.
uups!
zu früh gefreut! Das DOIF scheint es nicht zu fressen!
di.01.GA.ss.SA.Licht DOIF: the at function "OffTimeLicht("16:30")" must return a timespec and not 16:30 - 22:00.: {OffTimeLicht("16:30")}
Das heißt, die Rückgabe wird nicht als Zeit interpretiert, oder?
Christian
Gemäss Dokumentation
+ Zeitangaben in der Bedingung: [HH:MM:SS] oder [HH:MM] oder [{<perl-function>}]
+ Zeitintervalle: [<begin>-<end>] für <begin> bzw. <end> kann das obige Zeitformat gewählt werden
hätte eigentlich Deine ursprüngliche Fassung funktionieren müssen.
Ich bin nicht sicher ob, es nur so geht:
[HH:MM-HH:MM]
aber so nicht:
[HH:MM-{<perl-function>}]
Ev. kann Damian hier weiterhelfen.
Zitat von: flurin am 24 Februar 2015, 21:13:20
Gemäss Dokumentation
+ Zeitangaben in der Bedingung: [HH:MM:SS] oder [HH:MM] oder [{<perl-function>}]
+ Zeitintervalle: [<begin>-<end>] für <begin> bzw. <end> kann das obige Zeitformat gewählt werden
hätte eigentlich Deine ursprüngliche Fassung funktionieren müssen.
Ich bin nicht sicher ob, es nur so geht:
[HH:MM-HH:MM]
aber so nicht:
[06:30-{<perl-function>}]
Ev. kann Damian hier weiterhelfen.
lt. der zitierten Doku geht:
[HH:MM-HH:MM]
oder
[{perl-fkt}-HH:MM]
oder
[HH:MM-{perl-fkt}]
oder
[{perl-fkt}-{perl-fkt}]
statt HH:MM kann überall auch HH:MM:SS stehen.
perl-fkt, die "HH:MM-HH:MM" liefert, geht nicht, ist auch nicht mit der obigen Doku konform.
Gruß
Damian
Zitat von: Damian am 24 Februar 2015, 21:20:45
perl-fkt, die "HH:MM-HH:MM" liefert, geht nicht, ist auch nicht mit der obigen Doku konform.
Gruß
Damian
OK, Danke!
Es wäre aber schön, wenn es gehen würde :)
Ich nehme an, dass sowas auch kein Problem ist:
[HH:MM-HH:MM:SS]
Gruss
flurin
Zitat von: flurin am 24 Februar 2015, 21:27:31
OK, Danke!
Es wäre aber schön, wenn es gehen würde :)
Die Zeitfunktion wird nicht von DOIF ausgewertet, sondern ist eine Funktion aus fhem.pl, die auch at benutzt. Daher eine andere Baustelle ;)
Gruß
Damian
Hallo zusammen,
dann funktioniert der Ansatz nicht! Das heißt, die "bis"-Zeit kann nicht beim Trigger auf die "Start"-Zeit berechnet werden! Ich hatte gehofft, es gäbe eine Lösung für dieses Problem!
Schade!
Christian
Zitat von: Spartacus am 24 Februar 2015, 21:36:34
Hallo zusammen,
dann funktioniert der Ansatz nicht! Das heißt, die "bis"-Zeit kann nicht beim Trigger auf die "Start"-Zeit berechnet werden! Ich hatte gehofft, es gäbe eine Lösung für dieses Problem!
Schade!
Christian
Wenn deine Ausschaltzeit abhängig ist von der Einschaltzeit, dann ist doch der Ansatz:
[Einschaltzeit-{timeroff("Einschaltzeit")}]
Gruß
Damian
Zitat von: Spartacus am 24 Februar 2015, 21:36:34
Hallo zusammen,
dann funktioniert der Ansatz nicht! Das heißt, die "bis"-Zeit kann nicht beim Trigger auf die "Start"-Zeit berechnet werden! Ich hatte gehofft, es gäbe eine Lösung für dieses Problem!
Schade!
Christian
Du könntest auch mit zwei DOIF versuchen.
Mit dem ersten DOIF ([06:30]) ... könntest Du die Endzeit berechnen und in ein Dummy speichern.
Mit dem zweiten DOIF die Endzeit vom Dummy benutzen.
Ich komme heute nicht mehr dazu aber ich schaue es mir morgen noch mal an.
Gruss
flurin
Hi Damian,
verstehe ich noch nicht ganz!
Bsp.
Einschaltzeit 16:30 Uhr
([16:30-{OffTimeLicht("16:30")}]) set Licht on
würde dann mit dem Trigger auf die Einschaltzeit "16:30" auch gleichzeitig die SUB OffTimeLicht aufgerufen und die aktuelle Ausschaltzeit berechnet?
Bei diesem Aufruf
([16:30-{OffTimeLicht()}]) set Licht on
hinkt die Ausschaltzeit immer hinterher und wird nur beim initialisieren korrekt berechnet.
Oder wie meinst Du das?
Christian
Zitat von: Spartacus am 24 Februar 2015, 22:04:34
Hi Damian,
verstehe ich noch nicht ganz!
Bsp.
Einschaltzeit 16:30 Uhr
([16:30-{OffTimeLicht("16:30")}]) set Licht on
würde dann mit dem Trigger auf die Einschaltzeit "16:30" auch gleichzeitig die SUB OffTimeLicht aufgerufen und die aktuelle Ausschaltzeit berechnet?
Bei diesem Aufruf
([16:30-{OffTimeLicht()}]) set Licht on
hinkt die Ausschaltzeit immer hinterher und wird nur beim initialisieren korrekt berechnet.
Oder wie meinst Du das?
Christian
OffTimeLicht wird beim Initialisieren des Moduls aufgerufen und immer dann, wenn die errechnete Zeit (hier Ausschaltzeit) zuschlägt. Wenn das nicht ausreicht, gäbe es die Möglichkeit über modify zum Einschaltzeitpunkt, die Ausschaltzeit berechnen zu lassen, siehe:
http://forum.fhem.de/index.php/topic,23833.msg256172.html#msg256172
Gruß
Damian
Hallo Damian,
Danke, schaue ich mir noch mal genauer an! Wie am Anfang des Threads beschrieben, reicht es nicht, die Zeit beim Trigger auf die Ausschaltzeit zu berechnen.
@flurin
Danke auch Dir für Deine Unterstützung ! Ich versuche mal parallel eine andere Lösung zu bauen. Vielleicht ist ja weekday-timer eine Option!
Christian
Hi Christian
Eine Zwischenlösung für Dein Problem.
Ansatz: DOIF mit einer Perl-Funktion definieren.
in fhem.cfg eintragen oder noch besser im Eingabefeld eingeben:
define di_define_DOIF DOIF ([06:30]) ( { define_DOIF("di_test_lamp","06:30") } )
attr di_define_DOIF group DOIF
Bei define_DOIF wird der Name des DOIF und die Startzeit übergeben.
99_myUtils.pm: Code copy/paste
sub define_DOIF($$)
{
my ($doif,$start_time) = @_;
my $end_time = OffTimeLicht();
if (defined($defs{$doif} )) {
fhem("delete $doif");
}
fhem("define $doif DOIF ([$start_time-$end_time]) (set flex_lamp on) DOELSE (set flex_lamp off)");
fhem("attr $doif group DOIF");
}
define_DOIF entsprechend ändern/ausbauen.
OffTimeLicht() ist Deine ursprüngliche Perl-Funktion.
TODO: define mit modify ersetzen.
Gruss
flurin
Hallo flurin,
ganz lieben Dank für Deine Lösung. Sobald ich daheim bin, werde ich es ausprobieren. Der Code ist ziemlich komplex geworden, für so eine "einfache" Anforderung.
Du schreibst, "Zwischenlösung" was genau meinst Du damit?
Ich werde berichten,
Danke und Gruß,
Christian
Zitat von: Spartacus am 25 Februar 2015, 16:13:16
Hallo flurin,
ganz lieben Dank für Deine Lösung. Sobald ich daheim bin, werde ich es ausprobieren. Der Code ist ziemlich komplex geworden, für so eine "einfache" Anforderung.
Du schreibst, "Zwischenlösung" was genau meinst Du damit?
Eine einfachere Lösung sehe ich mit 3 (So-Do, Fr-Sa und Silvester) DOIF's, end_time wäre dann fix: 22:00, 23:00 und 02:30.
Zwischenlösung, weil mir das tägliche "delete/define" nicht gefällt. Aber eine Optimierung würde den Code noch mehr aufblasen.
Gruss
flurin
Hallo flurin,
ok, verstanden! Ich versuche gerade noch den Vorschlag von Damian mit dem modify aufzugreifen. Demnach soll das beim Einschalten die Ausschaltzeit in meiner Funktion aufrufen und dann aktualisieren. Aber diese Lösung habe ich noch nicht durchblickt...
Christian
Moin,
Das mit dem Modify habe ich nicht hingekriegt! Habe ich irgendwie nicht durchblickt! Braucht man da auch zwei DOIFs?
Werde als Fallback dann auf die 3 DOIFs ausweichen, so wie flurin vorgeschlagen hat!
Christian
Moin,
Das mit dem Modify habe ich nicht hingekriegt! Habe ich irgendwie nicht durchblickt! Braucht man da auch zwei DOIFs?
Werde als Fallback dann auf die 3 DOIFs ausweichen, so wie flurin vorgeschlagen hat!
Christian
Zitat von: Spartacus am 26 Februar 2015, 22:35:55
Moin,
Das mit dem Modify habe ich nicht hingekriegt! Habe ich irgendwie nicht durchblickt! Braucht man da auch zwei DOIFs?
Werde als Fallback dann auf die 3 DOIFs ausweichen, so wie flurin vorgeschlagen hat!
Christian
Modify brauchst du nicht mehr, siehe Nachbarthread: Schalten mit indirekten Zeitangaben
Gruß
Damian
Wahnsinn!
Das ist ja ein Service! Da guckt man mal einen Tag nicht in den DOIF-Bereich und schon hat Damian was gebaut!
Danke,
Werde ich morgen testen!
Christian