Abarbeitung der DOIFs priorisieren

Begonnen von erdnar, 03 Oktober 2024, 14:55:06

Vorheriges Thema - Nächstes Thema

erdnar

Mit Hilfe mehrerer DOIFs werden meinem Saugroboter verschiedene Aufgaben zugeordnet.
Zur Zeit starten diese DOIFs in zufälliger Reihenfolge bei gleichem Trigger (z.B. Bewohner da, Robi fertig, Akku voll genug,... ).
Jetzt möchte ich gern diese Aufgaben priorisieren können, also wenn die Räume 2, 3 und 4 noch zu reinigen sind, dann bitte Reihenfolge 2-4-3.
Die Rangfolge steht jeweils als Zahl in einem Reading "Prio" jedes dieser DOIFs.

Ich hatte es mit [+[$SELF:Prio]] versucht (größere Zahl = längere Wartezeit), aber das war ein Fehler, da der Timer ja immer wieder neu anläuft.

Ich hoffe auf eure Feiertagsideen
Dank vorab
ErdnaR

misux

Hast du ein Reading welcher aussagt das die Arbeit von Zimmer 1 oder so fertig ist?
Falls ja, kannst ja ein weiteres Doif erstellen der das mit in Betracht zieht und mit Zimmer 2 weiter macht.

If Zimmer 1 finished and Zimmer 02 nicht finished and Akku noch über 30% dann mach Zimmer 02 weiter...

Oder so.

Ein List vom Gerät und dein Doif könnte helfen zu helfen... 😂

erdnar

Danke für das Interesse.
Für jede Zone die der Sauger einzeln abarbeiten soll gibt es ein DOIF wie in nachfolgendem List.
Diese unterscheiden sich fast nur im ersten Bedingungsteil (Anwesenheiten etc.) und in der Zone.
Das Reading sw bestimmt mit on/off, ob das DOIF aktiv ist oder nicht.
Es kommt also vor, dass nur eine Zone (also ein DOIF) aktiviert wird, mehrere oder alle, manuell oder automatisch (z.B. bei Wohnung leer).

Mein Ziel: Jedes DOIF soll für sich entscheiden können ob es die höchste Priorität (Reading Prio) aller aktiven DOIFs hat, die ihre eigenen Startbedingungen erfüllen.

Internals:
   DEF        (
(
[d_paulzimmer_reinigen] eq "on"
or
(
[$SELF:sw] eq "ON"
and
(
[$SELF:anwesend] eq "egal"
or
[D_pr_Handy_PK] eq [$SELF:anwesend]
or
[D_Familie] eq [$SELF:anwesend]
)
and
[07:00:01-20:00]
)
)
and
(
[SaugerS7:in_cleaning] eq "no" ## momentan keine laufende Reinigung
or
[AK_ENERGY_P:ENERGY_Power] > [MQ_GollumSchalter:minLadePower] ## wenn Sauger in Station dann gleich weiter, auch wenn in_cleaning noch yes
)
and
[SaugerS7:batteryPercent] > [$SELF:minAkku] ## unter 20% Akku unterbricht der Sauger seine Arbeit, minAkku also 20 + Verbrauch des Zimmers
and
[+[$SELF:Prio]] ## Wartezeit für Reihenfolge
)
(setreading SaugerS7 in_cleaning yes)
(setreading $SELF sw go)
(
{fhem("
set MQ_GollumSchalter on;
sleep 15;
set Sauger7 reconnect;
sleep 15;
set SaugerS7 cleaning_mode auto;
set d_paulzimmer_reinigen off;
setreading SaugerS7 Doif D_SaugRoboter_Paulzimmer_reinigen;
setreading D_SaugRoboter_Paulzimmer_reinigen anwesend [D_SaugRoboter_Paulzimmer_reinigen:StandardPresent];
set SaugerS7 zone Paul
")}
)

DOELSEIF ##02
(1==2)
(setreading $SELF sw OFF)

DOELSEIF ##03
(1==2)
(setreading $SELF sw ON)

DOELSEIF ##04
(1==2)
(setreading $SELF anwesend absent)

DOELSEIF ##05
(1==2)
(setreading $SELF anwesend absent2)

DOELSEIF ##06
(1==2)
(setreading $SELF anwesend egal)

DOELSEIF ##07 wenn Sauger mit Bereich fertig, dann Logo`s ändern
(
ReadingsAge("$SELF","sw","0") > 120
and
[?$SELF:sw] eq "go"
and
[SaugerS7:in_cleaning] eq "no"
and
(
[SaugerS7:state] eq "Returnin.*"
or
[SaugerS7:state] eq "Charging"
)
)
(
IF (ReadingsAge("$SELF","sw","0") < [$SELF:Laufzeit])
(setreading $SELF sw fail)
ELSE
(setreading $SELF sw OFF)
)
   FUUID      660d1a0c-f33f-50f1-aba9-b21774412cf4968c
   MODEL      FHEM
   NAME       D_SaugRoboter_Paulzimmer_reinigen
   NOTIFYDEV  SaugerS7,global,D_SaugRoboter_Paulzimmer_reinigen,D_Familie,d_paulzimmer_reinigen,AK_ENERGY_P,MQ_GollumSchalter,D_pr_Handy_PK
   NR         924
   NTFY_ORDER 50-D_SaugRoboter_Paulzimmer_reinigen
   STATE      <div style='color:black'>
absent
black_btn_CAMBLANK
OFF
   TYPE       DOIF
   VERSION    28546 2024-02-23 20:11:05
   eventCount 44
   READINGS:
     2024-10-05 13:00:29   Device          SaugerS7
     2024-08-04 13:52:02   Laufzeit        700
     2024-09-30 12:48:33   Prio            3
     2024-09-09 11:24:46   StandardPresent absent
     2024-10-05 12:40:42   anwesend        absent
     2024-10-04 11:16:21   cmd             7
     2024-10-04 11:16:21   cmd_event       SaugerS7
     2024-10-04 11:16:21   cmd_nr          7
     2024-10-04 15:23:19   e_D_Familie_STATE present
     2024-10-05 12:40:42   e_D_SaugRoboter_Paulzimmer_reinigen_anwesend absent
     2024-10-04 10:47:07   e_D_SaugRoboter_Paulzimmer_reinigen_sw ON
     2024-10-05 08:13:07   e_D_pr_Handy_PK_STATE absent
     2024-10-05 13:00:29   e_SaugerS7_batteryPercent 96
     2024-10-05 13:00:29   e_SaugerS7_in_cleaning no
     2024-10-05 13:00:29   e_SaugerS7_state Charging
     2024-10-04 10:59:15   e_d_paulzimmer_reinigen_STATE off
     2024-09-29 13:42:49   minAkku         35
     2024-09-29 18:30:37   mode            enabled
     2024-10-04 11:16:21   state           cmd_7
     2024-10-04 19:59:30   sw              OFF
     2024-10-04 20:00:00   timer_01_c01    05.10.2024 07:00:01
     2024-10-04 20:00:00   timer_02_c01    05.10.2024 20:00:00
     2024-10-05 13:00:51   timer_03_c01    05.10.2024 13:00:54
   Regex:
     accu:
     bar:
     barAvg:
     collect:
     cond:
       AK_ENERGY_P:
         0:
           ENERGY_Power ^AK_ENERGY_P$:^ENERGY_Power:
       D_Familie:
         0:
           &STATE     ^D_Familie$
         1:
         2:
         3:
         4:
         5:
         6:
       D_SaugRoboter_Paulzimmer_reinigen:
         0:
           anwesend   ^D_SaugRoboter_Paulzimmer_reinigen$:^anwesend:
           minAkku    ^D_SaugRoboter_Paulzimmer_reinigen$:^minAkku:
           sw         ^D_SaugRoboter_Paulzimmer_reinigen$:^sw:
         1:
         2:
         3:
         4:
         5:
         6:
       D_pr_Handy_PK:
         0:
           &STATE     ^D_pr_Handy_PK$
         1:
         2:
         3:
         4:
         5:
         6:
       MQ_GollumSchalter:
         0:
           minLadePower ^MQ_GollumSchalter$:^minLadePower:
       SaugerS7:
         0:
           batteryPercent ^SaugerS7$:^batteryPercent:
           in_cleaning ^SaugerS7$:^in_cleaning:
         1:
         2:
         3:
         4:
         5:
         6:
           in_cleaning ^SaugerS7$:^in_cleaning:
           state      ^SaugerS7$:^state:
       d_paulzimmer_reinigen:
         0:
           &STATE     ^d_paulzimmer_reinigen$
         1:
         2:
         3:
         4:
         5:
         6:
     itimer:
       D_SaugRoboter_Paulzimmer_reinigen:
         itimer:
           Prio       ^D_SaugRoboter_Paulzimmer_reinigen$:^Prio:
   attr:
     cmdState:
       0:
         on
         off
       1:
         off
     wait:
     waitdel:
   condition:
     0            ( ::InternalDoIf($hash,'d_paulzimmer_reinigen','STATE') eq "on" or ( ::ReadingValDoIf($hash,'D_SaugRoboter_Paulzimmer_reinigen','sw') eq "ON" and ( ::ReadingValDoIf($hash,'D_SaugRoboter_Paulzimmer_reinigen','anwesend') eq "egal" or ::InternalDoIf($hash,'D_pr_Handy_PK','STATE') eq ::ReadingValDoIf($hash,'D_SaugRoboter_Paulzimmer_reinigen','anwesend') or ::InternalDoIf($hash,'D_Familie','STATE') eq ::ReadingValDoIf($hash,'D_SaugRoboter_Paulzimmer_reinigen','anwesend') ) and ::DOIF_time($hash,0,1,$wday,$hms) ) ) and ( ::ReadingValDoIf($hash,'SaugerS7','in_cleaning') eq "no" or ::ReadingValDoIf($hash,'AK_ENERGY_P','ENERGY_Power') > ::ReadingValDoIf($hash,'MQ_GollumSchalter','minLadePower') ) and ::ReadingValDoIf($hash,'SaugerS7','batteryPercent') > ::ReadingValDoIf($hash,'D_SaugRoboter_Paulzimmer_reinigen','minAkku') and ::DOIF_time_once($hash,2,$wday)
     1          1==2
     2          1==2
     3          1==2
     4          1==2
     5          1==2
     6            ReadingsAge("D_SaugRoboter_Paulzimmer_reinigen","sw","0") > 120 and ::ReadingValDoIf($hash,'D_SaugRoboter_Paulzimmer_reinigen','sw') eq "go" and ::ReadingValDoIf($hash,'SaugerS7','in_cleaning') eq "no" and ( ::ReadingValDoIf($hash,'SaugerS7','state') eq "Returnin.*" or ::ReadingValDoIf($hash,'SaugerS7','state') eq "Charging" )
   days:
   do:
     0:
       0          setreading SaugerS7 in_cleaning yes
       1          setreading D_SaugRoboter_Paulzimmer_reinigen sw go
       2            {fhem(" set MQ_GollumSchalter on; sleep 15; set Sauger7 reconnect; sleep 15; set SaugerS7 cleaning_mode auto; set d_paulzimmer_reinigen off; setreading SaugerS7 Doif D_SaugRoboter_Paulzimmer_reinigen; setreading D_SaugRoboter_Paulzimmer_reinigen anwesend [D_SaugRoboter_Paulzimmer_reinigen:StandardPresent]; set SaugerS7 zone Paul ")}
     1:
       0          setreading D_SaugRoboter_Paulzimmer_reinigen sw OFF
     2:
       0          setreading D_SaugRoboter_Paulzimmer_reinigen sw ON
     3:
       0          setreading D_SaugRoboter_Paulzimmer_reinigen anwesend absent
     4:
       0          setreading D_SaugRoboter_Paulzimmer_reinigen anwesend absent2
     5:
       0          setreading D_SaugRoboter_Paulzimmer_reinigen anwesend egal
     6:
       0           IF (ReadingsAge("D_SaugRoboter_Paulzimmer_reinigen","sw","0") < [D_SaugRoboter_Paulzimmer_reinigen:Laufzeit]) (setreading D_SaugRoboter_Paulzimmer_reinigen sw fail) ELSE (setreading D_SaugRoboter_Paulzimmer_reinigen sw OFF)
     7:
   helper:
     NOTIFYDEV  SaugerS7,global,D_SaugRoboter_Paulzimmer_reinigen,D_Familie,d_paulzimmer_reinigen,AK_ENERGY_P,MQ_GollumSchalter,D_pr_Handy_PK
     event      timer_3
     globalinit 1
     last_timer 3
     sleeptimer -1
     timerdev   SaugerS7
     timerevent Charging,batteryPercent: 86,batteryState: ok,last_clean_time: 0.25,last_clean_area: 12.72,error_code: None,map_present: yes,in_cleaning: no,in_returning: no,in_fresh_state: yes,lab_status: yes,fan_power: 102,dnd: off,cleaning_mode: balanced,water_box_carriage_status: yes,water_box_status: yes,water_box_mode: medium,mop_forbidden_enable: yes,lock_status: off,batt_prozent: 75
     triggerDev
     timerevents:
       Charging
       batteryPercent: 86
       batteryState: ok
       last_clean_time: 0.25
       last_clean_area: 12.72
       error_code: None
       map_present: yes
       in_cleaning: no
       in_returning: no
       in_fresh_state: yes
       lab_status: yes
       fan_power: 102
       dnd: off
       cleaning_mode: balanced
       water_box_carriage_status: yes
       water_box_status: yes
       water_box_mode: medium
       mop_forbidden_enable: yes
       lock_status: off
       batt_prozent: 75
       save_last_clean_area: 12.72
       save_last_clean_time: 0.25
       total_clean_area: 28186.4
       total_area_diff: 12.7200000000012
       total_area_diff_prozent: 10
     timereventsState:
       state: Charging
       batteryPercent: 86
       batteryState: ok
       last_clean_time: 0.25
       last_clean_area: 12.72
       error_code: None
       map_present: yes
       in_cleaning: no
       in_returning: no
       in_fresh_state: yes
       lab_status: yes
       fan_power: 102
       dnd: off
       cleaning_mode: balanced
       water_box_carriage_status: yes
       water_box_status: yes
       water_box_mode: medium
       mop_forbidden_enable: yes
       lock_status: off
       batt_prozent: 75
     triggerEvents:
       timer_3
     triggerEventsState:
       timer_3
   internals:
     all         d_paulzimmer_reinigen:STATE D_pr_Handy_PK:STATE D_Familie:STATE
   interval:
     0          -1
     1          0
   intervalfunc:
   intervaltimer:
   localtime:
     0          1728104401
     1          1728151200
     2          1728126054
   perlblock:
   readings:
     all         D_SaugRoboter_Paulzimmer_reinigen:sw D_SaugRoboter_Paulzimmer_reinigen:anwesend SaugerS7:in_cleaning AK_ENERGY_P:ENERGY_Power MQ_GollumSchalter:minLadePower SaugerS7:batteryPercent D_SaugRoboter_Paulzimmer_reinigen:minAkku SaugerS7:state
   realtime:
     0          07:00:01
     1          20:00:00
     2          13:00:54
   time:
     0          07:00:01
     1          20:00:00
     2          +[D_SaugRoboter_Paulzimmer_reinigen:Prio]
   timeCond:
     0          0
     1          0
     2          0
   timer:
     0          0
     1          0
     2          0
   timers:
     0           0  1  2
   trigger:
   triggertime:
     1728126054:
       localtime  1728126054
       hash:
     1728151200:
       localtime  1728151200
       hash:
   uiState:
   uiTable:
Attributes:
   alias      a_D_PAUL-Zimmer bei Abwesenheit reinigen
   cmdState   on,off|off
   devStateIcon on|ON:message_ok@green:cmd_2 ; fail:time_timer@yellow:cmd_2 ; off|OFF:control_x@grey:cmd_3 ; disabled:control_x@red ; initialized:rc_PROG@yellow ; absent2:control_building_empty@blue:cmd_6 ; absent:status_away_2@orange:cmd_5 ; egal:status_available@green:cmd_4 ; go:vacuum_top@orange:cmd_2
   do         always
   event-on-change-reading .*
   eventMap   off:OFF on:ON
   group      Roboter
   icon       scene_gaming@grey
   readingList Prio
   room       Roboter,doif
   setList    Prio:1,2,3,4,5,6,7,8,9,10,11,12,13
   sortby     111
   stateFormat <div style='color:black'>
anwesend
black_btn_CAMBLANK
sw
   webCmd     Prio

erdnar

Ich habe für mich jetzt eine Lösung gefunden, die zumindest funktioniert.
Ein gesondertes DOIF prüft, welches die niedrigste Prio der DOIFs ist, die Reinigen "wollen/sollen" und schreibt das in ein Reading:
([D_SaugRoboter_.*_reinigen:Prio])
({
my $A = (ReadingsNum("D_SaugRoboter_Raum1_reinigen","Prio_OK",'99'));
my $B = (ReadingsNum("D_SaugRoboter_Paulzimmer_reinigen","Prio_OK",'99'));
my $C = (ReadingsNum("D_SaugRoboter_Raum2_reinigen","Prio_OK",'99'));
my $D = (ReadingsNum("D_SaugRoboter_Raum3_reinigen","Prio_OK",'99'));
my $E = (ReadingsNum("D_SaugRoboter_Raum4_reinigen","Prio_OK",'99'));
my $F = (ReadingsNum("D_SaugRoboter_Raum5_reinigen","Prio_OK",'99'));
...
my $Start2go = minNum($A,$B,$C,$D,$E,$F,$G,$H,$I,$J,$K,$L,$M,$N);
fhem ("setreading D_alleRaeume_SaugRoboter_reinigen Starter $Start2go");})
Und die einzelnen DOIFs schauen dann selbst im Bedingungsteil ...
[$SELF:Prio_OK] <= [D_alleRaeume_SaugRoboter_reinigen:Starter]und starten ggfs. ihre Zonenreinigung.