[geöst] DOIF Operatoren funktionieren nicht

Begonnen von PS915, 08 Februar 2019, 22:20:24

Vorheriges Thema - Nächstes Thema

PS915

Naben zusammen,

aktuell versuche ich mich mit Operatoren um folgendes DOIF zu vereinfachen:

([kw:kw_now] eq 1) (set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 4)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 7)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 10)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 13)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 16)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 19)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 22)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 25)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 28)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 31)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 34)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 37)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 40)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 43)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 46)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 52)(set var.rollladen.nachtschicht on)
DOELSE (set var.rollladen.nachtschicht off)


Leider funktioniert es nicht, wie gewünscht. Sind meine Operatoren falsch? Hier meine Bisherigen Versuche:

([kw:kw_now] eq 1||4||7||10||13||16||19||22||25||28|31||34||37||40||43||46||49||52) (set var.rollladen.nachtschicht on) DOELSE (set var.rollladen.nachtschicht off)
([kw:kw_now] == 1||4||7||10||13||16||19||22||25||28|31||34||37||40||43||46||49||52) (set var.rollladen.nachtschicht on) DOELSE (set var.rollladen.nachtschicht off)

Gruß,
Phil

Otto123

Hi,

http://perldoc.perl.org/perlop.html#Operator-Precedence-and-Associativity

Also egal ob [kw:kw_now] eq 1 wahr ist ||4 ist auf alle Fälle wahr.

Dein Ausdruck macht so keinen Sinn. Aber wenn Du noch sagst was Du eigentlich machst, gibt es vielleicht auch eine Idee zur Lösung.

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

PS915

#2
Hey Otto,

also mein Grundproblem ist folgendes: Bei meiner Rollladensteureung möchte ich auf in meinen Nachtschichtwochen (jede dritte Woche) reagieren und in diesen Kalenderwochen (KW) meine Rollläden anders steuern. Dies mache ich mit DOIF, was auch schon ganz gut funktioniert.

Ich habe mir nun einen Dummy angelegt, wo ich manuell per WebFrontEnd auf "on" schalte während ich Nachtschicht habe.

Da ich aber immer einen festgelegten Schichtrhythmus habe, könnte ich anhand der KW dieses Dummy auch automatisch schalten lassen.
Im Moment mache ich es wie folgt:

Ein Dummy berechnet sich die KW und schreibt sie in einen userReadings. (https://forum.fhem.de/index.php/topic,37427.msg682632.html#msg682632)
Ein at triggert diesen dummy, damit die Berechnung der neuen KW bei einem Übergang in die nächste KW auch aktualisiert wird.

Danach prüfe ich die userReadings kw:kw_now gegen meinen Schichtplan. Hier setzen ich dann den Dummy, welcher aussagt, ob gerade Nachtschicht ist oder nicht.Jedoch habe ich es jetzt mit sehr vielen DOIFELSE und würde es daher etwas vereinfachen wollen.

Zu guterletzt habe ich Diverse DOIFs, die diesen Dummy als Bedingung haben. Z.B
##Rollladen Schlafzimmer Nachtschicht morgens runterfahren
define rollladen.drive.schlafzimmer.nachtschicht_down DOIF ([08:00|2345] and [var.rollladen.nachtschicht:state] eq "on") (set rollladen.OG.Schlafzimmer 0) DOELSE ()


Idealerster weise, wäre natürlich eine Art Operator direkt in DOIF, gegen den ich prüfen kann, aber ich habe bisher nur Wochentage, Zeiten und Datum gefunden.

Wenn es hilfreich ist, kann ich die ganzen devices mal listen. Eventuell mache ich das ganze ja wieder etwas umstädlich, aber mir ist als FHEM/Perl Anfänger nichts besseres eingefallen.

Gruß,
Phil


PS: Leider musste ich auch den Umweg über Dummy und At gehen, da dieser Befehl zum erkennen der Nachtschicht nicht funktioiert:
define rollladen.check_nachtschicht DOIF ({getWeekNumber()} eq 6) (set var.rollladen.nachtschicht "on") DOELSE ()



EDIT: List Devices

KWs berechnen
Internals:
   FUUID      5c5defea-f33f-1bb7-9524-72d3cdaf5138c5c1
   NAME       kw
   NR         321
   STATE      6
   TYPE       dummy
   READINGS:
     2019-02-08 23:17:35   kw_now          6
     2019-02-08 23:17:35   state           0
Attributes:
   room       Rolläden
   stateFormat [kw:kw_now]
   userReadings kw_now {getWeekNumber()}


Berechnung triggern
Internals:
   COMMAND    set kw 0
   DEF        +*00:01:00 set kw 0
   FUUID      5c5de308-f33f-1bb7-6b97-e165cde2e06ddaee
   NAME       kw_update
   NR         319
   NTM        23:19:35
   PERIODIC   yes
   RELATIVE   yes
   REP        -1
   STATE      Next: 23:19:35
   TIMESPEC   00:01:00
   TRIGGERTIME 1549664375.63124
   TRIGGERTIME_FMT 2019-02-08 23:19:35
   TYPE       at
   READINGS:
     2019-02-08 23:18:35   state           Next: 23:19:35
Attributes:
   room       Rolläden


Nachtschicht Variable setzen
Internals:
   DEF        ([kw:kw_now] eq 1) (set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 4)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 7)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 10)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 13)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 16)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 19)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 22)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 25)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 28)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 31)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 34)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 37)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 40)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 43)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 46)(set var.rollladen.nachtschicht on)
DOELSEIF([kw:kw_now] eq 52)(set var.rollladen.nachtschicht on)
DOELSE (set var.rollladen.nachtschicht off)
   FUUID      5c5ddd14-f33f-1bb7-5113-bbc776c1f54cd770
   MODEL      FHEM
   NAME       rollladen.check_nachtschicht
   NR         317
   NTFY_ORDER 50-rollladen.check_nachtschicht
   STATE      cmd_18
   TYPE       DOIF
   READINGS:
     2019-02-08 23:18:35   Device          kw
     2019-02-08 22:41:49   cmd             18
     2019-02-08 22:41:49   cmd_event       rollladen.check_nachtschicht
     2019-02-08 22:41:49   cmd_nr          18
     2019-02-08 23:18:35   e_kw_kw_now     6
     2019-02-08 22:41:46   mode            enabled
     2019-02-08 22:41:49   state           cmd_18
   Regex:
   attr:
     cmdState:
     wait:
     waitdel:
   condition:
     0          ::ReadingValDoIf($hash,'kw','kw_now') eq 1
     1          ::ReadingValDoIf($hash,'kw','kw_now') eq 4
     10         ::ReadingValDoIf($hash,'kw','kw_now') eq 31
     11         ::ReadingValDoIf($hash,'kw','kw_now') eq 34
     12         ::ReadingValDoIf($hash,'kw','kw_now') eq 37
     13         ::ReadingValDoIf($hash,'kw','kw_now') eq 40
     14         ::ReadingValDoIf($hash,'kw','kw_now') eq 43
     15         ::ReadingValDoIf($hash,'kw','kw_now') eq 46
     16         ::ReadingValDoIf($hash,'kw','kw_now') eq 52
     2          ::ReadingValDoIf($hash,'kw','kw_now') eq 7
     3          ::ReadingValDoIf($hash,'kw','kw_now') eq 10
     4          ::ReadingValDoIf($hash,'kw','kw_now') eq 13
     5          ::ReadingValDoIf($hash,'kw','kw_now') eq 16
     6          ::ReadingValDoIf($hash,'kw','kw_now') eq 19
     7          ::ReadingValDoIf($hash,'kw','kw_now') eq 22
     8          ::ReadingValDoIf($hash,'kw','kw_now') eq 25
     9          ::ReadingValDoIf($hash,'kw','kw_now') eq 28
   devices:
     0           kw
     1           kw
     10          kw
     11          kw
     12          kw
     13          kw
     14          kw
     15          kw
     16          kw
     2           kw
     3           kw
     4           kw
     5           kw
     6           kw
     7           kw
     8           kw
     9           kw
     all         kw
   do:
     0:
       0          set var.rollladen.nachtschicht on
     1:
       0          set var.rollladen.nachtschicht on
     10:
       0          set var.rollladen.nachtschicht on
     11:
       0          set var.rollladen.nachtschicht on
     12:
       0          set var.rollladen.nachtschicht on
     13:
       0          set var.rollladen.nachtschicht on
     14:
       0          set var.rollladen.nachtschicht on
     15:
       0          set var.rollladen.nachtschicht on
     16:
       0          set var.rollladen.nachtschicht on
     17:
       0          set var.rollladen.nachtschicht off
     2:
       0          set var.rollladen.nachtschicht on
     3:
       0          set var.rollladen.nachtschicht on
     4:
       0          set var.rollladen.nachtschicht on
     5:
       0          set var.rollladen.nachtschicht on
     6:
       0          set var.rollladen.nachtschicht on
     7:
       0          set var.rollladen.nachtschicht on
     8:
       0          set var.rollladen.nachtschicht on
     9:
       0          set var.rollladen.nachtschicht on
   helper:
     event      0,kw_now: 6
     globalinit 1
     last_timer 0
     sleeptimer -1
     timerdev   kw
     timerevent 0,kw_now: 6
     triggerDev kw
     DOIF_eventas:
       cmd_nr: 18
       cmd: 18
       cmd_event: rollladen.check_nachtschicht
       state: cmd_18
     timerevents:
       0
       kw_now: 6
     timereventsState:
       state: 0
       kw_now: 6
     triggerEvents:
       0
       kw_now: 6
     triggerEventsState:
       state: 0
       kw_now: 6
   internals:
   itimer:
   readings:
     0           kw:kw_now
     1           kw:kw_now
     10          kw:kw_now
     11          kw:kw_now
     12          kw:kw_now
     13          kw:kw_now
     14          kw:kw_now
     15          kw:kw_now
     16          kw:kw_now
     2           kw:kw_now
     3           kw:kw_now
     4           kw:kw_now
     5           kw:kw_now
     6           kw:kw_now
     7           kw:kw_now
     8           kw:kw_now
     9           kw:kw_now
     all         kw:kw_now
   trigger:
   uiState:
   uiTable:
Attributes:
   room       Rolläden

Otto123

Hallo Phil,

also zur Kalenderwoche gab es diese Jahr schon mal was: https://forum.fhem.de/index.php?topic=95215.0

Die müsstest Du doch dann "bloß" modulo 3 dividieren.
Dazu gab die Suche auf die Schnelle das hier : https://forum.fhem.de/index.php?topic=53706.0

Damit müsste das Ganze doch in einem Ausdruck gehen?

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

Damian

Zitat von: PS915 am 08 Februar 2019, 23:10:49


PS: Leider musste ich auch den Umweg über Dummy und At gehen, da dieser Befehl zum erkennen der Nachtschicht nicht funktioiert:
define rollladen.check_nachtschicht DOIF ({getWeekNumber()} eq 6) (set var.rollladen.nachtschicht "on") DOELSE ()

Perl-Funktionen werden in der DOIF-Bedingung nicht in geschweifte klammern gesetzt; Zahlen mit == vergleichen.

define rollladen.check_nachtschicht DOIF (getWeekNumber() == 6) (set var.rollladen.nachtschicht "on")
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

PS915

Okay, nun habe ich verstanden wie man Perl Funktionen in DOIF ausführen kann, Danke!

Ich habe nun einen AT gesetzt, welcher jede Nacht um 02:00 ein "set rollladen.check_nachtschicht checkall" abgibt, damit das DOIF angestoßen wird die aktuelle KW zu prüfen. Kann ich das triggern auch mit dem DOIF selber machen? Gibt es dort irgendwelche Attribute, die ich setzten könnte?

Um die Abfrage etwas übersichtlicher zu machen, habe ich es nun mit dem binären Operator "or" und "||" versucht, wie hier (https://de.wikibooks.org/wiki/Perl-Programmierung:_Operatoren) beschrieben:

(getWeekNumber() == 1 or 4 or 7 or 10 or 13 or 16 or 19 or 22 or 25 or 28 or 31 or 34 or 37 or 40 or 43 or 46 or 49 or 52) (set var.rollladen.nachtschicht on) DOELSE (set var.rollladen.nachtschicht off)


Leider liefert die Abfrage immer "cmd_1" zurück. Ich kann es natürlich so lassen und mit vielen DOELSEIF arbeiten, jedoch würde ich gern verstehen wo mein Fehler liegt!

Otto123

#6
Dein Ausdruck ist logisch immer noch "sinnlos" - das geht so nicht!

Er löst den Vergleich getWeekNumber() == 1  der wird wahr oder falsch
Dann verknüpft er diese Ergebnis  oder mit 4 -> das ist immer wahr (weil 4 nicht 0 ist)
usw...

Du kannst diesen Ausdruck nicht so vereinfachen! Hab ich doch oben schon gesagt.

Du kannst getWeekNumber() modulo 3 teilen und einfach das Ergebnis weiter verarbeiten. Also etwa so((getWeekNumber() % 3) == 0)(set var.rollladen.nachtschicht on)falls die Woche diejenige welche ist. Ansonsten (((getWeekNumber() % 3) - 1) == 0)(set var.rollladen.nachtschicht on)falls nächste Woche diejenige welche ist.

Du kannst auch das Ergebnis direkt manipulieren und im set befehl verwenden:

{((getWeekNumber() % 3) - 1) == 0 ? "on":"off"}

Nur als Idee
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

PS915

#7
Hey Ott,

ah, jetzt habe ich es endlich verstanden und auch der Tipp mit dem /3 ist ganz schön "smart"  ::)

Vielen Dank! Thema gelöst würde ich mal sagen! =)