Hauptmenü

neues Modul DOIF

Begonnen von Damian, 21 Mai 2014, 15:53:18

Vorheriges Thema - Nächstes Thema

moonsorrox

#810
Zitat von: maxritti am 02 Dezember 2014, 15:16:47
Aus meiner Sicht kann man die Frage klar mit NEIN beantworten.
Und dem schließe ich mich jetzt auch an und denke für Deine Anforderung solltest Du ein separates Thema erstellen.
OK Danke, schade trotzdem.
Ich werde das Thema mal in dem Bereich Beleuchtung anfangen, glaube auch das ist da besser aufgehoben.
EDITH:// hatte ganz vergessen das ich hier schon mal angefangen habe mit dem Thema
Intel-NUC i5: FHEM-Server 6.1 :: Perl v5.18.2

Homematic: HM-USB-CFG2,HM-CFG-LAN Adapter, HM-LC-BL1-FM, HM-LC-Sw1PBU-FM, HM-LC-Sw1-PI-2, HM-WDS10-TH-O, HM-CC-TC, HM-LC-SW2-FM

Otto

Hallo,

ich verstehe die Schaltung nicht:
define di_Rollo_WZ_mitte DOIF (([Bewegungsmelder1:brightness]>120 and [07:15-10:00|012456]) or [06:45|3]) (set Rollo_WZ_mitte:FILTER=level!=100 on) DOELSEIF ([Bewegungsmelder1:brightness]<90 and [17:00-22:00]|0123456) (set Rollo_WZ_mitte:FILTER=level!=0 off)

Das Rollo fährt Mittwoch um 6:45 hoch und später um 6:49 wieder runter.
Warum fährt es vor 17:00 runter??

Gruß Otto
Gruss Otto

.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.

docker - homematic

Brockmann

Zitat von: Otto am 03 Dezember 2014, 07:31:30
Das Rollo fährt Mittwoch um 6:45 hoch und später um 6:49 wieder runter.
Warum fährt es vor 17:00 runter??
Wenn es wirklich genau so definiert ist, liegt das an der allerletzten eckigen Klammer. Die muss hinter die Tage, nicht davor, so wie bei der anderen Bedingung auch.

Brockmann

Da das nächste Feature-Update ja noch ein wenig hin ist, wollte ich mir eine dringend benötigte Funktionalität selbst zurechtbasteln, nämlich die Möglichkeit, ein DOIF höchstens alle X Sekunden auszuführen.
Meine Idee dazu: man ziehe von der aktuellen Zeit den Zeitpunkt des Reading cmd_event, ab, der ja beim letzten Ausführen des DOIF gesetzt wurde. Wenn dieser Wert > X, darf das DOIF ausgeführt werden. Das ganze wird als zusätzliche Bedingung ins DOIF gepackt:

define DI_test DOIF ([Dummy] and {time_str2num("$year-$month-$mday $hms") - time_str2num(ReadingsTimestamp("DI_test","cmd_event",0)) > 10})
   (trigger global bla)
attr DI_test do always


Theoretisch funktioniert der Teil in geschweiften Klammern, zumindest kann ich den so in der FHEM-Befehlszeile eingeben und bekomme die erwartete Antwort.
Aber als Bedingung in DOIF bewirkt es nicht das gewünschte, sondern die Bedingung ist anscheinend immer wahr, denn die Aktion wird jedes Mal ausgeführt. Aber ich bekomme auch bei jedem Aufruf eine Warnung im Log:
PERL WARNING: Odd number of elements in anonymous hash at (eval 17759) line 1.

Nun weiß ich nicht, ob ich was falsch mache, DOIF sich hier irgendwie verschluckt oder ob dieser Ansatz grundlegend nicht funktionieren kann.

Damian

Zitat von: Brockmann am 03 Dezember 2014, 14:18:46
Da das nächste Feature-Update ja noch ein wenig hin ist, wollte ich mir eine dringend benötigte Funktionalität selbst zurechtbasteln, nämlich die Möglichkeit, ein DOIF höchstens alle X Sekunden auszuführen.
Meine Idee dazu: man ziehe von der aktuellen Zeit den Zeitpunkt des Reading cmd_event, ab, der ja beim letzten Ausführen des DOIF gesetzt wurde. Wenn dieser Wert > X, darf das DOIF ausgeführt werden. Das ganze wird als zusätzliche Bedingung ins DOIF gepackt:

define DI_test DOIF ([Dummy] and {time_str2num("$year-$month-$mday $hms") - time_str2num(ReadingsTimestamp("DI_test","cmd_event",0)) > 10})
   (trigger global bla)
attr DI_test do always


Theoretisch funktioniert der Teil in geschweiften Klammern, zumindest kann ich den so in der FHEM-Befehlszeile eingeben und bekomme die erwartete Antwort.
Aber als Bedingung in DOIF bewirkt es nicht das gewünschte, sondern die Bedingung ist anscheinend immer wahr, denn die Aktion wird jedes Mal ausgeführt. Aber ich bekomme auch bei jedem Aufruf eine Warnung im Log:
PERL WARNING: Odd number of elements in anonymous hash at (eval 17759) line 1.

Nun weiß ich nicht, ob ich was falsch mache, DOIF sich hier irgendwie verschluckt oder ob dieser Ansatz grundlegend nicht funktionieren kann.

In der Bedingung von DOIF befindest du dich bereits auf der Perl-Ebene, da sind die geschweiften Klammern an dieser Stelle zu viel des Guten. Das kannst du aber auch einfacher haben und ohne Fehlermeldung ;) :


define DI_test DOIF ([Dummy] and (time() - time_str2num(ReadingsTimestamp("DI_test","cmd_event",0))) > 10)
   (trigger global bla)
attr DI_test do always


Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Spartacus

Hallo,
mit DOIF kann man Zeitintervalle angeben, an denen bestimmte Aktionen stattfinden sollen. Das bezieht sich m.W. aber nur auf Wochentage und Zeitintervalle mit Stunden, Minuten und Sekunden.
Geht das auch mit dem Datumswerten?

z.B.
vom 01.01.-10.01. von 16:00 bis 19:00
vom 11.01. bis 10.12. von 0:00 bis 24:00
vom 11.12. bis 31.12. von 16:00 bis 24:00

Danke und Gruß,
Christian
Fhem-System: 1 x raspberry PI Typ B, 1 x enOcean PI Typ B | Enocean: PTM210, FMS61NP, FAM14, 2 x FSR14-4x, FTS14-EM | LaCrosse: 2 x TX29D über Jeelink V3 | 1-Wire: 2 x DS18B20 über DS9490R

Damian

#816
Zitat von: Spartacus am 03 Dezember 2014, 20:36:40
Hallo,
mit DOIF kann man Zeitintervalle angeben, an denen bestimmte Aktionen stattfinden sollen. Das bezieht sich m.W. aber nur auf Wochentage und Zeitintervalle mit Stunden, Minuten und Sekunden.
Geht das auch mit dem Datumswerten?

z.B.
vom 01.01.-10.01. von 16:00 bis 19:00
vom 11.01. bis 10.12. von 0:00 bis 24:00
vom 11.12. bis 31.12. von 16:00 bis 24:00

Danke und Gruß,
Christian

Natürlich nicht, sonst stünde das in der Commandref. Du kannst aber folgende Variablen abfragen: $mday,$month,$year,$wday,$yday

11.12. bis 31.12. von 16:00 bis 24:00 wäre dann:

($mday>=11 and $mday<=31 and $month==11 and [16:00-00:00])

Monate werden von 0 bis 11 gezählt. (Das habe nicht ich mir ausgedacht, sondern es wird von der localtime-Routine in Perl geliefert)

Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Spartacus

Hallo Damian,
danke für den Hinweis. Aber irgendwie sehe ich den Wald vor Bäumen nicht, oder ich habe Dich falsch verstanden...
Auf jeden Fall ist die Funzel nicht angegangen, es wurde direkt das DOELSE ausgeführt...
define di.01.rp.01.EG.ku.SD.Kochinsel DOIF ($mday>=1 and $mday<=4 and $month==11 and [21:48-22:00])\
(set rp.01.EG.ku.SD.Kochinsel on)\
DOELSE\
(set rp.01.EG.ku.SD.Kochinsel off)

bitte nicht über die kryptischen Namen wundern...die werden nach einem Schema zusammengebaut...
Christian
Fhem-System: 1 x raspberry PI Typ B, 1 x enOcean PI Typ B | Enocean: PTM210, FMS61NP, FAM14, 2 x FSR14-4x, FTS14-EM | LaCrosse: 2 x TX29D über Jeelink V3 | 1-Wire: 2 x DS18B20 über DS9490R

Damian

Zitat von: Spartacus am 03 Dezember 2014, 21:57:46
Hallo Damian,
danke für den Hinweis. Aber irgendwie sehe ich den Wald vor Bäumen nicht, oder ich habe Dich falsch verstanden...
Auf jeden Fall ist die Funzel nicht angegangen, es wurde direkt das DOELSE ausgeführt...
define di.01.rp.01.EG.ku.SD.Kochinsel DOIF ($mday>=1 and $mday<=4 and $month==11 and [21:48-22:00])\
(set rp.01.EG.ku.SD.Kochinsel on)\
DOELSE\
(set rp.01.EG.ku.SD.Kochinsel off)

bitte nicht über die kryptischen Namen wundern...die werden nach einem Schema zusammengebaut...
Christian

Ich sehe keinen Fehler. Hast du auch die aktuelle Version von DOIF? Sonst bitte Ausgabe von list di.01.rp.01.EG.ku.SD.Kochinsel  nach dem Schalten hier posten.

Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Spartacus

Hi Damian,
ich habe die Uhrzeiten mal angepasst:

Status vor dem Schalten:
Internals:
   CFGFN      config/Kueche.cfg
   DEF        ($mday>=1 and $mday<=5 and $month==11 and [09:05-09:15]) (set rp.01.EG.ku.SD.Kochinsel on)
DOELSE (set rp.01.EG.ku.SD.Kochinsel off)
   NAME       di.01.rp.01.EG.ku.SD.Kochinsel
   NR         454
   NTFY_ORDER 50-di.01.rp.01.EG.ku.SD.Kochinsel
   STATE      initialized
   TYPE       DOIF
   Readings:
     2014-12-04 09:00:33   state           initialized
     2014-12-04 09:00:33   timer_1_c1      04.12.2014 09:05:00
     2014-12-04 09:00:33   timer_2_c1      04.12.2014 09:15:00
   Condition:
     0          $mday>=1 and $mday<=5 and $month==11 and DOIF_time($hash->{realtime}{0},$hash->{realtime}{1},$wday,$hms,"")
   Days:
   Devices:
   Do:
     0          set rp.01.EG.ku.SD.Kochinsel on
     1          set rp.01.EG.ku.SD.Kochinsel off
   Helper:
     last_timer 2
     sleeptimer -1
   Realtime:
     0          09:05:00
     1          09:15:00
   State:
   Time:
     0          09:05:00
     1          09:15:00
   Timecond:
     0          0
     1          0
   Timer:
     0          0
     1          0
   Timerfunc:
   Timers:
     0           0  1
Attributes:
   alias      autom. Weihnachtsbaumbeleuchtung
   cmdState   on|off
   devStateIcon .*on:light_light_dim_100@lightgreen .*off:light_light_dim_00@red
   group      Scripte
   icon       scene_x-mas@lightgreen
   room       01-Küche

Status nach dem Schalten:
Internals:
   CFGFN      config/Kueche.cfg
   DEF        ($mday>=1 and $mday<=5 and $month==11 and [09:05-09:15]) (set rp.01.EG.ku.SD.Kochinsel on)
DOELSE (set rp.01.EG.ku.SD.Kochinsel off)
   NAME       di.01.rp.01.EG.ku.SD.Kochinsel
   NR         454
   NTFY_ORDER 50-di.01.rp.01.EG.ku.SD.Kochinsel
   STATE      off
   TYPE       DOIF
   Readings:
     2014-12-04 09:05:00   cmd_event       timer_1
     2014-12-04 09:05:00   cmd_nr          2
     2014-12-04 09:05:00   state           off
     2014-12-04 09:05:00   timer_1_c1      05.12.2014 09:05:00
     2014-12-04 09:00:33   timer_2_c1      04.12.2014 09:15:00
   Condition:
     0          $mday>=1 and $mday<=5 and $month==11 and DOIF_time($hash->{realtime}{0},$hash->{realtime}{1},$wday,$hms,"")
   Days:
   Devices:
   Do:
     0          set rp.01.EG.ku.SD.Kochinsel on
     1          set rp.01.EG.ku.SD.Kochinsel off
   Helper:
     last_timer 2
     sleeptimer -1
   Internals:
   Readings:
   Realtime:
     0          09:05:00
     1          09:15:00
   State:
   Time:
     0          09:05:00
     1          09:15:00
   Timecond:
     0          0
     1          0
   Timer:
     0          0
     1          0
   Timerfunc:
   Timers:
     0           0  1
Attributes:
   alias      autom. Weihnachtsbaumbeleuchtung
   cmdState   on|off
   devStateIcon .*on:light_light_dim_100@lightgreen .*off:light_light_dim_00@red
   group      Scripte
   icon       scene_x-mas@lightgreen
   room       01-Küche


Danke und Gruß,
Christian
Fhem-System: 1 x raspberry PI Typ B, 1 x enOcean PI Typ B | Enocean: PTM210, FMS61NP, FAM14, 2 x FSR14-4x, FTS14-EM | LaCrosse: 2 x TX29D über Jeelink V3 | 1-Wire: 2 x DS18B20 über DS9490R

Damian

Die Lösung ist ganz einfach. Ich habe bereit intern im DOIF-Modul den Monat, der von der localtime-Routine geliefert wird um eins erhöht. Damit ist $month 1 bis 12, so wie man es erwartet.

Du musst also für Dezember $month==12 abfragen.

Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Spartacus

Hi Damian,
danke! Jetzt funzt es!
Gruß,
Christian.
Fhem-System: 1 x raspberry PI Typ B, 1 x enOcean PI Typ B | Enocean: PTM210, FMS61NP, FAM14, 2 x FSR14-4x, FTS14-EM | LaCrosse: 2 x TX29D über Jeelink V3 | 1-Wire: 2 x DS18B20 über DS9490R

Brockmann

Zitat von: Damian am 03 Dezember 2014, 15:27:53
In der Bedingung von DOIF befindest du dich bereits auf der Perl-Ebene, da sind die geschweiften Klammern an dieser Stelle zu viel des Guten. Das kannst du aber auch einfacher haben und ohne Fehlermeldung ;) :
Danke für den Hinweis. So klappt es. Die engültige Lösung war das aber auch noch nicht, da ich einen Denkfehler drin hatte:
Wenn ich in der Kondition den Zeitpunkt des letzten cmd_event abfrage und die Kondition dadurch scheitert, wird logischerweise trotzdem jedes Mal ein neues cmd_event gesetzt. Dadurch wird dieser Zeitpunkt immer nachgezogen und wenn das DOIF sehr häufig angetriggert wird, kann es dadurch im Extremfall niemals wahr werden.

Damit es robust läuft, habe ich nun ein eigenes Reading dafür verwendet, das jedes Mal gesetzt wird, wenn die Aktion ausgeführt wurde. In dessen Timestamp ist somit der Zeitpunkt der letzten Ausführung zuverlässig festgehalten und darauf kann man sich beziehen. Das Beispiel würde dann ungefähr so aussehen (Klammern ohne Gewähr):


define DI_test DOIF ([Dummy] and (time() - time_str2num(ReadingsTimestamp("DI_test", "last_exec", "0000-00-00 00:00:00"))) >= 10)
   (
   trigger global bla,
   setReading DI_test last_exec wasauchimmer
   )
attr DI_test do always


Gibt jeweils beim ersten Durchlauf, wenn das last_exec-Reading noch nicht existiert, eine Warnung, wohl weil dieser kreative "000..."-Fallback-String keine saubere time-Definition ist.
PERL WARNING: Use of uninitialized value in subtraction (-) at (eval 38499) line 1.

Aber von solchen Kleinlichkeiten sollte man sich nicht aufhalten lassen...  ;)
Wobei, wenn jemand einen Tipp hat, wie ich die Warnung vermeiden kann, optimiere ich das gerne noch.

Spartacus

Hallo,
bin immer noch am basteln und finde den Fehler nicht!
Schaltzeiten sollen sein:
im Zeitraum vom: 27.12. bis 12.01.
mo-fr 07:00 bis 08:30 und 16:30 bis 22:30
sa,so, feiertags, 08:30 bis 23:00

am:
24.12 16:00 bis 23:00
31.12 08:30 bis 01:00


(([07:00-08:30|12345] and [hl.01.Feiertag:today] eq "none" or
[16:30-22:30|12345] and [hl.01.Feiertag:today] eq "none" or
[08:30-23:00] and [hl.01.Feiertag:today] ne "none" or
[08:30-23:00|60]) and (($mday>=27 and $month==12) or ($mday<=12 and $month==1))) or
([16:00-23:00] and [hl.01.Feiertag:state] eq "Heiligabend") or
([08:30-02:00] and [hl.01.Feiertag:state] eq "Silverster") (set rp.01.EG.ku.SD.Kochinsel on)
DOELSE (set rp.01.EG.ku.SD.Kochinsel off)


Danke,
Spartacus
Fhem-System: 1 x raspberry PI Typ B, 1 x enOcean PI Typ B | Enocean: PTM210, FMS61NP, FAM14, 2 x FSR14-4x, FTS14-EM | LaCrosse: 2 x TX29D über Jeelink V3 | 1-Wire: 2 x DS18B20 über DS9490R

Damian

Zitat von: Brockmann am 04 Dezember 2014, 17:53:19
Danke für den Hinweis. So klappt es. Die engültige Lösung war das aber auch noch nicht, da ich einen Denkfehler drin hatte:
Wenn ich in der Kondition den Zeitpunkt des letzten cmd_event abfrage und die Kondition dadurch scheitert, wird logischerweise trotzdem jedes Mal ein neues cmd_event gesetzt. Dadurch wird dieser Zeitpunkt immer nachgezogen und wenn das DOIF sehr häufig angetriggert wird, kann es dadurch im Extremfall niemals wahr werden.

Damit es robust läuft, habe ich nun ein eigenes Reading dafür verwendet, das jedes Mal gesetzt wird, wenn die Aktion ausgeführt wurde. In dessen Timestamp ist somit der Zeitpunkt der letzten Ausführung zuverlässig festgehalten und darauf kann man sich beziehen. Das Beispiel würde dann ungefähr so aussehen (Klammern ohne Gewähr):


define DI_test DOIF ([Dummy] and (time() - time_str2num(ReadingsTimestamp("DI_test", "last_exec", "0000-00-00 00:00:00"))) >= 10)
   (
   trigger global bla,
   setReading DI_test last_exec wasauchimmer
   )
attr DI_test do always


Gibt jeweils beim ersten Durchlauf, wenn das last_exec-Reading noch nicht existiert, eine Warnung, wohl weil dieser kreative "000..."-Fallback-String keine saubere time-Definition ist.
PERL WARNING: Use of uninitialized value in subtraction (-) at (eval 38499) line 1.

Aber von solchen Kleinlichkeiten sollte man sich nicht aufhalten lassen...  ;)
Wobei, wenn jemand einen Tipp hat, wie ich die Warnung vermeiden kann, optimiere ich das gerne noch.

Der Urknall der Computerzeit ist:

{time_str2num("1970-01-01 01:00:00")}

vergleiche mit dem Ergebnis von:

{localtime (0)}

Gruß

Damian
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF