Jahreszeit Snippet per DOIF abfragen? Bin mal wieder zu doof dazu ^^

Begonnen von M_I_B, 12 Juli 2016, 21:55:49

Vorheriges Thema - Nächstes Thema

M_I_B

Hallo liebe Leute,

hier aus dem Forum habe ich mal irgend wo her folgendes Snippet, um die aktuelle Jahreszeit zu erhalten, was an sich auch funktioniert:
### Jahreszeit ###
define season DOIF (my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; [00:00] and (($mon == 2 && $mday >= 20) or $mon == 3 or $mon == 4 or ($mon == 5 and $mday < 21))) \
DOELSEIF (my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; [00:00] and (($mon == 5 and $mday >= 21) or $mon == 6 or $mon == 7 or ($mon == 8 and $mday < 22))) \
DOELSEIF (my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; [00:00] and (($mon == 8 and $mday >= 22) or $mon == 9 or $mon == 10 or ($mon == 11 && $mday < 21))) \
DOELSEIF (my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; [00:00] and (($mon == 11 and $mday >= 21) or $mon == 0 or $mon == 1 or ( $mon == 2 && $mday < 20)))
attr season alias Jahreszeit
attr season cmdState spring|summer|autumn|winter
attr season event-on-change-reading state
attr season eventMap spring:Frühling summer:Sommer autumn:Herbst winter:Winter initialized:---
attr season group Zeitdefinitionen
attr season icon scene_garden@lime
attr season room Umwelt


Das wollte ich jetzt eigentlich dazu nutzen, die in Arbeit befindliche Heizungssteuerung über die Jahreszeit in Kenntnis zu setzen. Dazu habe ich mal folgendes zum Testen gemacht:
Also Anzeige:
define test01 dummy
attr test01 group Heizung IST Werte
attr test01 room KG.Heizung


Als Abfrage:
define test1 DOIF ([season] eq "summer" or [season] eq "Sommer" or [season:state] eq "summer" or [season:state] eq "Sommer") (set test01 Sommer) DOELSE (set test01 Schitte)
attr test1 do always


Das season- Dingens steht auf Sommer resp summer (siehe List unten); wie es das macht ist mir ein Rätsel, da ich da nicht dran lang blicke... Funktioniert ja.
Aber egal was ich anstelle... der dumme Dummy wird nicht entsprechend gesetzt und verbleibt beim Kinderroman "drei Fragezeichen". Wo mache ich denn da meinen Denkfehler???

List season:
Internals:
   CFGFN      /opt/fhem/°INCLUDE°/GLOBAL.cfg
   DEF        (my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); [00:00] and (($mon == 2 && $mday >= 20) or $mon == 3 or $mon == 4 or ($mon == 5 and $mday < 21)))
DOELSEIF (my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); [00:00] and (($mon == 5 and $mday >= 21) or $mon == 6 or $mon == 7 or ($mon == 8 and $mday < 22)))
DOELSEIF (my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); [00:00] and (($mon == 8 and $mday >= 22) or $mon == 9 or $mon == 10 or ($mon == 11 && $mday < 21)))
DOELSEIF (my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); [00:00] and (($mon == 11 and $mday >= 21) or $mon == 0 or $mon == 1 or ( $mon == 2 && $mday < 20)))
   NAME       season
   NR         698
   NTFY_ORDER 50-season
   STATE      Sommer
   TYPE       DOIF
   Readings:
     2016-07-09 00:05:00   cmd             2
     2016-07-09 00:05:00   cmd_event       timer_2
     2016-07-09 00:05:00   cmd_nr          2
     2016-07-09 00:05:00   state           summer
     2016-07-12 21:39:50   timer_1_c1      13.07.2016 00:00:00
     2016-07-12 21:39:50   timer_2_c2      13.07.2016 00:00:00
     2016-07-12 21:39:50   timer_3_c3      13.07.2016 00:00:00
     2016-07-12 21:39:50   timer_4_c4      13.07.2016 00:00:00
   Condition:
     0          my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); DOIF_time_once($hash,$hash->{timer}{0},$wday,"") and (($mon == 2 && $mday >= 20) or $mon == 3 or $mon == 4 or ($mon == 5 and $mday < 21))
     1          my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); DOIF_time_once($hash,$hash->{timer}{1},$wday,"") and (($mon == 5 and $mday >= 21) or $mon == 6 or $mon == 7 or ($mon == 8 and $mday < 22))
     2          my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); DOIF_time_once($hash,$hash->{timer}{2},$wday,"") and (($mon == 8 and $mday >= 22) or $mon == 9 or $mon == 10 or ($mon == 11 && $mday < 21))
     3          my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); DOIF_time_once($hash,$hash->{timer}{3},$wday,"") and (($mon == 11 and $mday >= 21) or $mon == 0 or $mon == 1 or ( $mon == 2 && $mday < 20))
   Days:
   Devices:
   Do:
     0:
       0
     1:
       0
     2:
       0
     3:
       0
   Helper:
     globalinit 1
     last_timer 4
     sleeptimer -1
   Itimer:
   Localtime:
     0          1468360800
     1          1468360800
     2          1468360800
     3          1468360800
   Realtime:
     0          00:00:00
     1          00:00:00
     2          00:00:00
     3          00:00:00
   Regexp:
   State:
   Time:
     0          00:00:00
     1          00:00:00
     2          00:00:00
     3          00:00:00
   Timecond:
     0          0
     1          1
     2          2
     3          3
   Timer:
     0          0
     1          0
     2          0
     3          0
   Timers:
     0           0
     1           1
     2           2
     3           3
   Triggertime:
     1468360800:
       localtime  1468360800
       Hash:
Attributes:
   alias      Jahreszeit
   cmdState   spring|summer|autumn|winter
   event-on-change-reading state
   eventMap   spring:Frühling summer:Sommer autumn:Herbst winter:Winter initialized:---
   group      Zeitdefinitionen
   icon       scene_garden@lime
   room       Umwelt

automatisierer

den Sinn eine Heizung nach der Jahreszeit zu steuern lasse ich mal dahingestellt...

Davon ab nutzt du das 'season DOIF' als reine Statusanzeige. Wenn du da nun einfach hinter jede Bedingung einen Befehl setzt, dann kannst du den Dummy damit einfach beschreiben.

### Jahreszeit ###
define season DOIF (my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; [00:00] and (($mon == 2 && $mday >= 20) or $mon == 3 or $mon == 4 or ($mon == 5 and $mday < 21))) (set test01 Fruehling)\
DOELSEIF (my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; [00:00] and (($mon == 5 and $mday >= 21) or $mon == 6 or $mon == 7 or ($mon == 8 and $mday < 22))) (set test01 Sommer)\
DOELSEIF (my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; [00:00] and (($mon == 8 and $mday >= 22) or $mon == 9 or $mon == 10 or ($mon == 11 && $mday < 21))) (set test01 Herbst)\
DOELSEIF (my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);; [00:00] and (($mon == 11 and $mday >= 21) or $mon == 0 or $mon == 1 or ( $mon == 2 && $mday < 20))) (set test01 Winter)
attr season alias Jahreszeit
attr season cmdState spring|summer|autumn|winter
attr season event-on-change-reading state
attr season eventMap spring:Fruehling summer:Sommer autumn:Herbst winter:Winter initialized:---
attr season group Zeitdefinitionen
attr season icon scene_garden@lime
attr season room Umwelt



dann noch:

1. rumfuschen in der .cfg ??
2. eventMap bei DOIF ??  dafür gibts cmdState
3. 'ü' in der definition??  koennte mir vorstellen das das auch zu Problemen führt

Damian

Bevor solche Definitionen Verbreitung finden.

Dieser Teil der Bedingung:

my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);;

ist überflüssig, da er bereits intern im DOIF-Modul stattfindet und man in der Bedingung diese Variablen ohne Weiteres nutzen kann.

Gruß

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

M_I_B

Zitat von: automatisierer am 12 Juli 2016, 22:58:51den Sinn eine Heizung nach der Jahreszeit zu steuern lasse ich mal dahingestellt...
... und ob das Sinn macht! Bestimmte Teile müssen im Sommer nicht laufen (Pumpen HK z.B.), andere auf jeden Fall (Pumpen STH z.B.). Viel lieber wäre mir eigentlich die Nutzung ext. Vorhersage-Wetterdaten, aber so weit bin ich noch nicht...

Zitat von: automatisierer am 12 Juli 2016, 22:58:51Davon ab nutzt du das 'season DOIF' als reine Statusanzeige. Wenn du da nun einfach hinter jede Bedingung einen Befehl setzt, dann kannst du den Dummy damit einfach beschreiben.
... au Backe, bin ich doof :o Ja klar, ist ja kein Device; jetzt wo Du es erwähnst ...

Zitat von: automatisierer am 12 Juli 2016, 22:58:51dann noch:

1. rumfuschen in der .cfg ??
2. eventMap bei DOIF ??  dafür gibts cmdState
3. 'ü' in der definition??  koennte mir vorstellen das das auch zu Problemen führt
zu 1.: Was meinst Du damit?
zu 2.: Hab ich nicht verbrochen und so aus dem Forum übernommen; funktioniert doch ...
zu 3.: Nö, hat es noch nie, bei mir zumindest nicht. Durchgehend UTF-8 und dann sollte das tun, oder? Hat es wohl auch anderweitig, da dieses Snippet wohl schon älter ist und wohl von mehreren unverändert genutzt wird...

Zitat von: Damian am 12 Juli 2016, 23:30:21Dieser Teil der Bedingung:
my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);;
ist überflüssig, da er bereits intern im DOIF-Modul stattfindet und man in der Bedingung diese Variablen ohne Weiteres nutzen kann.
Ok, da ich das ganze Ding nicht wirklich verstehe, weiß ich das natürlich auch nicht ::)
Also einfach weglöschen ohne weitere Anpassung?

Per

Zitat von: M_I_B am 13 Juli 2016, 19:42:07Ja klar, ist ja kein Device; jetzt wo Du es erwähnst ...
Eigentlich ist es schon ein Device, zumindest im Sinn von Fhem. Genau wie beim Dummy kannst du die Zustände auch setzen und auswerten. Allerdings halt kein physisches.
Und manchmal ist genau diese Funktion recht brauchbar.

Zitat von: M_I_B am 13 Juli 2016, 19:42:07zu 1.: Was meinst Du damit?
Er meint, dass du nicht mit dem Editor die fhem.cfg direkt bearbeiten sollst.
Diese gebehtsmühlenartige Wiederholung verstehe ich auch nicht.

M_I_B

Zitat von: Per am 14 Juli 2016, 10:50:54... Allerdings halt kein physisches. Und manchmal ist genau diese Funktion recht brauchbar.
Ja, so meinte ich das auch. Aber nu is ja klar... Außer das ein Weglöschen der von Damian angesprochenen Teile das Teil außer Funktion gesetzt hat... Zumindest hat er heute Nacht um 00:00 nicht seinen händisch verstellten Zustand auf Sommer geändert..

Zitat von: Per am 14 Juli 2016, 10:50:54Er meint, dass du nicht mit dem Editor die fhem.cfg direkt bearbeiten sollst.
Diese gebehtsmühlenartige Wiederholung verstehe ich auch nicht.
Ach so, diese Nummer ::) Ich mache das seit Anfang an so und komme damit deutlich besser klar als mit dem FHEM- eigenen ... Eine gewisse Syntax- Prüfung und vollständige Klammerprüfung habe ich in Notepad++ ebenso ... also alles schön ...

automatisierer

define season DOIF ([00:00] and (($month==2 and $mday>=20) or $month==3 or $month==4 or ($month==5 and $mday<21))) (set dingsbums Fruehling)\
DOELSEIF ([00:00] and (($month==5 and $mday>=21) or $month==6 or $month==7 or ($month==8and $mday<22))) (set dingsbums Sommer) \
DOELSEIF ([00:00] and (($month==8 and $mday>=22) or $month==9 or $month==10 or ($month==11 and $mday<21))) (set dingsbums Herbst)\
DOELSEIF ([00:00] and (($month==11 and $mday>=21) or $month==0 or $month==1 or ($month==2 and $mday<20))) (set dingsbums Winter)
attr season cmdState Fruehling|Sommer|Herbst|Winter

M_I_B

Supi! Vielen Dank!
Ich hatte das gerade mal über das Vorhandene kopiert, weil es auf der ersten Blick genau so aussah wie meines nach der Änderung / Löschung. Aber dann... In der alten Definition ist der Monat mit $mon angegeben, in der Deinen mit $month, vermutlich weil vorher eben im gelöschten Teil $mon definiert war, die interne Variable des DOIF aber $month setzt... Liege ich da richtig?

EDIT:
Ich habe es jetzt noch mal etwas lesbarer gemacht, einen Error- Status hinzu gefügt, die Stati aus einem Buchstaben gebaut (Faulheit siegt ...) und alles durch Ändern der Zeiten ausgetestet... einwandfrei!
Vielen Dank Euch allen, die geholfen haben!

Wer's braucht:

define season_get DOIF ([00:00] and (($month == 2 and $mday >= 20) or $month == 3 or $month == 4 or ($month == 5 and $mday < 21))) (set season F) \
DOELSEIF ([00:00] and (($month == 5 and $mday >= 21) or $month == 6 or $month == 7 or ($month == 8 and $mday < 22))) (set season S) \
DOELSEIF ([00:00] and (($month == 8 and $mday >= 22) or $month == 9 or $month == 10 or ($month == 11 and $mday < 21))) (set season H) \
DOELSEIF ([00:00] and (($month == 11 and $mday >= 21) or $month == 0 or $month == 1 or ($month == 2 and $mday < 20))) (set season W) \
DOELSE (set season ERR)
attr season_get cmdState F|S|H|W|ERR
# attr season_get event-on-change-reading state
attr season_get icon scene_garden@lime
attr season_get alias Jahreszeit
attr season_get group Zeitdefinitionen
attr season_get room Umwelt

define season dummy
attr season icon scene_garden@lime
attr season devStateIcon F:jz_1 S:jz_2 H:jz_3 W:jz_0 ERR:error
attr season alias Jahreszeit
attr season group Zeitdefinitionen,Heizung IST Werte
attr season room KG.Heizung


die verwendeten Icon's gibts hier

Starkstrombastler

Da das DOIF schrittweise abgeabeitet wird, geht es noch etwas einfacher:
define season_get DOIF ([00:00] and $month == 11 and $mday >= 21 ) (set Jahreszeit Winter)
DOELSE ([00:00] and $month == 8 and $mday >= 22 ) (set Jahreszeit Herbst)
DOELSE ([00:00] and $month == 5 and $mday >= 21 ) (set Jahreszeit Sommer)
DOELSE ([00:00] and $month == 2 and $mday >= 20 ) (set Jahreszeit Frühling)
DOELSE (set Jahreszeit ERR)
IPC\Ubuntu + Fhem, 1wire, Shellies, Siemens Logo!, Z-Wave, PhilipsTV, Vu+duo2, KM200

M_I_B

... hmmm ... Interessante, quasi negierte Alternative und deutlich einfacher; werde ich mir ggf. zu Eigen machen ;) Dank dafür...

*grübel* Ist es bei deiner Version nicht so, das wenn "Jahreszeit" mal wegen Stress leer ist/wird oder Blödsinn drin steht, erst bis zum entsprechenden Jahrestag gewartet werden muss, bis die korrekte, neue Jahreszeit gesetzt wird? Also nehmen wir an, ich hätte manuell jetzt "Jahreszeit" auf BlaBlub gesetzt, dann wird erst am 21.11. dieser Inhalt auf "Winter" korrigiert... jo?

Per

Wie wäre es mit
define season_get DOIF ([00:00] and 10 * $month + $mday >= 1121) (set Jahreszeit Winter)
DOELSEIF ([00:00] and 10 * $month + $mday >= 822) (set Jahreszeit Herbst)
DOELSEIF ([00:00] and 10 * $month + $mday >= 521) (set Jahreszeit Sommer)
DOELSEIF ([00:00] and 10 * $month + $mday >= 220) (set Jahreszeit Frühling)
DOELSE (set Jahreszeit Winter)

Wobei sich das in Perl bestimmt leichter schreiben lässt (Format zweistellig und dann $month.$mday oder date("mdd") oder so ).

Danke an M_I_B für die 3 IF ;)

M_I_B

... stimmt! Das vereint den Vorteil von Starkstrombastler mit Setzen täglich ...
Noch einfacher? Gibt es nicht eine Variable Tag des Jahres (1-365) ?!?

BTW: DOIF > DOELSE > DOELSE ...? Nicht DOIF > DOELSEIF?

Per

Zitat von: M_I_B am 08 November 2016, 12:24:56
Noch einfacher? Gibt es nicht eine Variable Tag des Jahres (1-365) ?!?
Bestimmt, bekommst du im Schaltjahr aber die ungeheure Abweichung von einem Tag! Dann kann man bestimmt auch gleich mit Monaten arbeiten.

Zitat von: M_I_B am 08 November 2016, 12:24:56BTW: DOIF > DOELSE > DOELSE ...? Nicht DOIF > DOELSEIF?
Yup, cut'&'paste-Fehler  :-[

M_I_B

Zitat... bekommst du im Schaltjahr aber die ungeheure Abweichung von einem Tag! ...
... jau! Ein Tag Fehler ist natürlich vollkommen unakzeptabel ;) Man könnte ja auch von hinten rechnen; was über bleibt ist dann halt noch Winter. Ist halt auch die Frage, ob man die kalendarischen oder die meteorologischen Daten verwenden möchte/will ...

ZitatYup, cut'&'paste-Fehler  :-[
... tja  ;D ;D ;D

Per

Zitat von: M_I_B am 08 November 2016, 13:08:27Man könnte ja auch von hinten rechnen; was über bleibt ist dann halt noch Winter.
Geht nur, wenn die Info auch vom System kommt, hatte ich auch schon überlegt, reichen meine Perl-Kenntisse aber nicht aus.

Zitat von: M_I_B am 08 November 2016, 13:08:27Ist halt auch die Frage, ob man die kalendarischen oder die meteorologischen Daten verwenden möchte/will ...
Meteorologisch ist ja einfach, musst du nur die Monate vergleichen, ohne Tagesangabe.

Zitat von: M_I_B am 08 November 2016, 13:08:27tja  ;D ;D ;D
Eigentlich war es gar nicht mein Fehler, habe ihn nur (ungeprüft, das war mein Fehler!) übernommen :P