Abhängig von Differenz zwischen 2 Readings über Zeit abschalten

Begonnen von tobox, 29 Mai 2020, 11:58:26

Vorheriges Thema - Nächstes Thema

tobox

Ich habe viele DOIFs am laufen, mit allen Möglichen Features. Aber die Poolheizung will einfach nicht!

Ich will abschalten, wenn die Rücklauftemperatur über 3 Minuten lang weniger als 0.2° wärmer ist als die Vorlauftemperatur.

Dazu habe ich folgendes gemacht:

define Poolpumpe_automatik_di DOIF ([9:30] or [10:00] or [12:30] or [15:00] or [17:00]) ( { PoolPumpe("on", "Morgens anpumpen");; } ) DOELSEIF\
(([Pool_Wassertemperatur:temperature]     <[Wetterstation:temperature]) and ([SolarAkt:Body_Data_PAC_Value] < 1000)                                            ) ( { PoolPumpe("on", "Aussentemperatur hoch genug");; } ) DOELSEIF \
(([Pool_Wassertemperatur:temperature] - 1 <[Wetterstation:temperature]) and ([SolarAkt:Body_Data_PAC_Value] > 1000) and ([SolarAkt:Body_Data_PAC_Value] < 2000)) ( { PoolPumpe("on", "Solar Power 1000W-2000W");; } ) DOELSEIF \
(([Pool_Wassertemperatur:temperature] - 2 <[Wetterstation:temperature]) and ([SolarAkt:Body_Data_PAC_Value] > 2000))                                             ( { PoolPumpe("on", "Solar Power groesser 2000W");; } ) DOELSEIF \
([Pool_Vorlauftemperatur:temperature] + 0.2 > [Pool_Ruecklauftemperatur:temperature]) ( { PoolPumpe("off", "Heizleistung zu gering- VL: " . ReadingsNum("Pool_Vorlauftemperatur","temperature",0) . " RL: " . ReadingsNum("Pool_Ruecklauftemperatur","temperature",0));; } )\

attr Poolpumpe_automatik_di DbLogExclude .*:0
attr Poolpumpe_automatik_di alias Poolpumpe automatisch steuern
attr Poolpumpe_automatik_di checkall all
attr Poolpumpe_automatik_di devStateIcon disabled:general_aus@red:initialize initialize:general_an@green:disable initialized:general_an@green:disable cmd.*:general_an@green:disable
attr Poolpumpe_automatik_di room Pool
attr Poolpumpe_automatik_di wait 0:120:120:120:180


Ich habe schon Fragezeichen an alle möglich Readings gemacht, "checkall" benutzt und rausgelassen, aber eben kam wieder die Nachricht:

Poolpumpe off: Heizleistung zu gering- VL: 22.9 RL: 24.7

Was ja eindeutig bedeutet, dass zum Zeitpunkt der Ausführung die RL-Temperatur deutlich höher war als die VL-Temperatur. Die Temperaturen ändern sich extrem träge und stabil, ohne Sprünge, und werden sogar alle 15 Sekunden aktualisiert.

Wer kann mir helfen? Die Doku habe ich schon vorwärts und rückwärts durchgewälzt, aber irgendwie will es einfach nicht.

Edit: Gerade gemerkt, dass PoopPumpe ja eine Perl-Sub ist, die ich mitschicken sollte:

sub PoolPumpe {
    my $sollzustand = shift;
    my $msg = shift;

    fhem("set Sonoff_Dose_1 $sollzustand");
    fhem("set teleBot message Poolpumpe $sollzustand: $msg");
    Log 3, "Poolpumpe $sollzustand: $msg";
}

Otto123

Ich weiß nicht genau, aber die Berechnung würde ich in Klammern setzen. Bei den Vergleichen an sich brauchst Du sie in Deinem Fall nicht.
(([Pool_Wassertemperatur:temperature] - 2) <[Wetterstation:temperature] and [SolarAkt:Body_Data_PAC_Value] > 2000)   Zumindest in der Doku steht es so: https://fhem.de/commandref_DE.html#DOIF_Weitere_Anwendungsbeispiele
Und Perl macht erst den Vergleich und dann and -> https://perldoc.perl.org/perlop.html#Operator-Precedence-and-Associativity
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

tobox

Also das mit der Präzedenz würde mich wundern. Bei allen Programmiersprachen haben Berechnungen höhere Präzedenz als Vergleiche, so auch Perl (siehe von Dir verlinkte Seite).

Plus/Minus hat Präzedenz 8, Größer/Kleine hat 11, wobei 8 "Höher" als 11 bedeutet.

Ich vermute aktuell, dass ich eher noch einen Zustand brauche, in den das DOIF wechseln kann, wenn die Rücklauftemperatur ausreichend hoch ist.

Otto123

Wenn Du meinst das DOIF eine Programmiersprache ist :)
Ja ich weiß - ist nicht logisch. 8) dann wundert mich aber die Doku.

Dann liefere doch mal bitte ein list zu dem fraglichen Zeitpunkt.

Wobei Du noch beachten musst (kann ich auf die Schnelle nicht verstehen) das DOIF quasi von "oben nach unten" durchgeht und beim ersten "true" einrastet. Sprich: dann werden weiter Bedingungen nicht mehr geprüft!
Also eventuell musst Du einfach umsortieren und die letzte Bedingung an den Anfang setzen

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

also:

((([Pool_Wassertemperatur:temperature] - 2) < [Wetterstation:temperature]) and ([SolarAkt:Body_Data_PAC_Value] > 2000))

ist das Gleiche, wie:

(Pool_Wassertemperatur:temperature] - 2 < [Wetterstation:temperature] and [SolarAkt:Body_Data_PAC_Value] > 2000)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Otto123

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

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

tobox

Aber auf meine ursprüngliche Frage weiß keiner eine Antwort?  :(

MadMax-FHEM

#8
Zitat von: tobox am 31 Mai 2020, 09:34:48
Aber auf meine ursprüngliche Frage weiß keiner eine Antwort?  :(

Du hast aber auch noch kein list im "fraglechen" Zustand geliefert... ;)

Zitat von: Otto
Dann liefere doch mal bitte ein list zu dem fraglichen Zeitpunkt.
https://forum.fhem.de/index.php/topic,111639.msg1058805.html#msg1058805

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

Otto123

Moin,

und diesen Hinweis hattest Du probiert?
ZitatWobei Du noch beachten musst (kann ich auf die Schnelle nicht verstehen) das DOIF quasi von "oben nach unten" durchgeht und beim ersten "true" einrastet. Sprich: dann werden weiter Bedingungen nicht mehr geprüft!
Also eventuell musst Du einfach umsortieren und die letzte Bedingung an den Anfang setzen
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

tobox

Zitat von: MadMax-FHEM am 31 Mai 2020, 09:46:31
Du hast aber auch noch kein list im "fraglechen" Zustand geliefert... ;)
https://forum.fhem.de/index.php/topic,111639.msg1058805.html#msg1058805

Da habe ich wohl zu schnell gelesen... Sorry. Ich versuche eins nachzureichen! Danke schonmal für die Hilfe soweit.

tobox

So, das Problem ist immer noch da.

Umsortieren kann meiner Meinung nach nichts bringen, da der "fehlerhafte" Zustand schon der letzte ist!

Ich habe mehrere "lists" produziert, im folgenden das wahrscheinlich interessanteste. Ich habe das DOIF geändert, so dass es um 9:38 Uhr nochmal startet. Dann ist auch um 9:38 Uhr die Pumpe angegangen, und kurz danach habe ich das List gemacht. Wie man sieht, ist das DOIF in CMD1 (korrekt) und hat einen wait_timer für cmd_5 (auch korrekt). Aber warum steht hinter cmd_5 etwas von Solar_akt? Der hat doch mit cmd_5 gar nichts zu tun? Da sollten doch die beiden Temperaturen abgefragt werden? Sehr seltsam. Auf jeden Fall kam 9:42 Uhr die Meldung: "Poolpumpe off: Heizleistung zu gering- VL: 25.4 RL: 26.6".


Internals:
   CFGFN      Pool.cfg
   DEF        ([9:38] or [10:00] or [12:30] or [15:00] or [17:00]) ( { PoolPumpe("on", "Morgens anpumpen"); } ) DOELSEIF
(([Pool_Wassertemperatur:temperature]     <[Wetterstation:temperature]) and ([SolarAkt:Body_Data_PAC_Value] < 1000)                                            ) ( { PoolPumpe("on", "Aussentemperatur hoch genug"); } ) DOELSEIF
(([Pool_Wassertemperatur:temperature] - 1 <[Wetterstation:temperature]) and ([SolarAkt:Body_Data_PAC_Value] > 1000) and ([SolarAkt:Body_Data_PAC_Value] < 2000)) ( { PoolPumpe("on", "Solar Power 1000W-2000W"); } ) DOELSEIF
(([Pool_Wassertemperatur:temperature] - 2 <[Wetterstation:temperature]) and ([SolarAkt:Body_Data_PAC_Value] > 2000))                                             ( { PoolPumpe("on", "Solar Power groesser 2000W"); } ) DOELSEIF
([Pool_Vorlauftemperatur:temperature] + 0.2 > [Pool_Ruecklauftemperatur:temperature]) ( { PoolPumpe("off", "Heizleistung zu gering- VL: " . ReadingsNum("Pool_Vorlauftemperatur","temperature",0) . " RL: " . ReadingsNum("Pool_Ruecklauftemperatur","temperature",0)); } )

   FUUID      532fa99e-f33f-ee95-072d-d4453443d89aa8a9
   MODEL      FHEM
   NAME       Poolpumpe_automatik_di
   NOTIFYDEV  global,SolarAkt,Pool_Ruecklauftemperatur,Wetterstation,Pool_Vorlauftemperatur,Pool_Wassertemperatur
   NR         1730
   NTFY_ORDER 50-Poolpumpe_automatik_di
   STATE      cmd_1
   TYPE       DOIF
   VERSION    21813 2020-04-30 10:05:47
   READINGS:
     2020-06-02 09:39:55   Device          Pool_Ruecklauftemperatur
     2020-06-02 09:38:00   cmd             1
     2020-06-02 09:38:00   cmd_event       timer_1
     2020-06-02 09:38:00   cmd_nr          1
     2020-06-02 09:39:55   e_Pool_Ruecklauftemperatur_temperature 26.8
     2020-06-02 09:38:55   e_Pool_Vorlauftemperatur_temperature 25.4
     2020-06-02 09:38:25   e_Pool_Wassertemperatur_temperature 25.9
     2020-06-02 09:39:20   e_SolarAkt_Body_Data_PAC_Value 490
     2020-06-02 09:39:30   e_Wetterstation_temperature 24.2
     2020-06-02 09:37:08   mode            enabled
     2020-06-02 09:38:00   state           cmd_1
     2020-06-02 09:38:00   timer_01_c01    03.06.2020 09:38:00
     2020-06-02 09:37:08   timer_02_c01    02.06.2020 10:00:00
     2020-06-02 09:37:08   timer_03_c01    02.06.2020 12:30:00
     2020-06-02 09:37:08   timer_04_c01    02.06.2020 15:00:00
     2020-06-02 09:37:08   timer_05_c01    02.06.2020 17:00:00
     2020-06-02 09:38:20   wait_timer      02.06.2020 09:41:20 cmd_5 SolarAkt
   Regex:
     accu:
     cond:
       Pool_Ruecklauftemperatur:
         0:
         1:
         2:
         3:
         4:
           temperature ^Pool_Ruecklauftemperatur$:^temperature:
       Pool_Vorlauftemperatur:
         0:
         1:
         2:
         3:
         4:
           temperature ^Pool_Vorlauftemperatur$:^temperature:
       Pool_Wassertemperatur:
         0:
         1:
           temperature ^Pool_Wassertemperatur$:^temperature:
         2:
           temperature ^Pool_Wassertemperatur$:^temperature:
         3:
           temperature ^Pool_Wassertemperatur$:^temperature:
         4:
       SolarAkt:
         0:
         1:
           Body_Data_PAC_Value ^SolarAkt$:^Body_Data_PAC_Value:
         2:
           Body_Data_PAC_Value ^SolarAkt$:^Body_Data_PAC_Value:
         3:
           Body_Data_PAC_Value ^SolarAkt$:^Body_Data_PAC_Value:
         4:
       Wetterstation:
         0:
         1:
           temperature ^Wetterstation$:^temperature:
         2:
           temperature ^Wetterstation$:^temperature:
         3:
           temperature ^Wetterstation$:^temperature:
         4:
   attr:
     cmdState:
     wait:
       0:
         0
       1:
         120
       2:
         120
       3:
         120
       4:
         180
     waitdel:
   condition:
     0          ::DOIF_time_once($hash,0,$wday) or ::DOIF_time_once($hash,1,$wday) or ::DOIF_time_once($hash,2,$wday) or ::DOIF_time_once($hash,3,$wday) or ::DOIF_time_once($hash,4,$wday)
     1          (::ReadingValDoIf($hash,'Pool_Wassertemperatur','temperature')     <::ReadingValDoIf($hash,'Wetterstation','temperature')) and (::ReadingValDoIf($hash,'SolarAkt','Body_Data_PAC_Value') < 1000)                                           
     2          (::ReadingValDoIf($hash,'Pool_Wassertemperatur','temperature') - 1 <::ReadingValDoIf($hash,'Wetterstation','temperature')) and (::ReadingValDoIf($hash,'SolarAkt','Body_Data_PAC_Value') > 1000) and (::ReadingValDoIf($hash,'SolarAkt','Body_Data_PAC_Value') < 2000)
     3          (::ReadingValDoIf($hash,'Pool_Wassertemperatur','temperature') - 2 <::ReadingValDoIf($hash,'Wetterstation','temperature')) and (::ReadingValDoIf($hash,'SolarAkt','Body_Data_PAC_Value') > 2000)
     4          ::ReadingValDoIf($hash,'Pool_Vorlauftemperatur','temperature') + 0.2 > ::ReadingValDoIf($hash,'Pool_Ruecklauftemperatur','temperature')
   days:
   do:
     0:
       0           { PoolPumpe("on", "Morgens anpumpen"); }
     1:
       0           { PoolPumpe("on", "Aussentemperatur hoch genug"); }
     2:
       0           { PoolPumpe("on", "Solar Power 1000W-2000W"); }
     3:
       0           { PoolPumpe("on", "Solar Power groesser 2000W"); }
     4:
       0           { PoolPumpe("off", "Heizleistung zu gering- VL: " . ReadingsNum("Pool_Vorlauftemperatur","temperature",0) . " RL: " . ReadingsNum("Pool_Ruecklauftemperatur","temperature",0)); }
     5:
   helper:
     DEVFILTER  ^global$|^Pool_Ruecklauftemperatur$|^Pool_Wassertemperatur$|^Pool_Vorlauftemperatur$|^Wetterstation$|^SolarAkt$
     NOTIFYDEV  global|Pool_Ruecklauftemperatur|Pool_Wassertemperatur|Pool_Vorlauftemperatur|Wetterstation|SolarAkt
     event      26.8,temperature: 26.8
     globalinit 1
     last_timer 5
     sleepdevice SolarAkt
     sleepsubtimer 0
     sleeptimer 4
     timerdev   Pool_Wassertemperatur
     timerevent 25.9,temperature: 25.9
     triggerDev Pool_Ruecklauftemperatur
     timerevents:
       25.9
       temperature: 25.9
     timereventsState:
       state: 25.9
       temperature: 25.9
     triggerEvents:
       26.8
       temperature: 26.8
     triggerEventsState:
       state: 26.8
       temperature: 26.8
   internals:
   interval:
   intervalfunc:
   localtime:
     0          1591169880
     1          1591084800
     2          1591093800
     3          1591102800
     4          1591110000
   readings:
     all         Pool_Wassertemperatur:temperature Wetterstation:temperature SolarAkt:Body_Data_PAC_Value Pool_Vorlauftemperatur:temperature Pool_Ruecklauftemperatur:temperature
   realtime:
     0          09:38:00
     1          10:00:00
     2          12:30:00
     3          15:00:00
     4          17:00:00
   time:
     0          9:38
     1          10:00:00
     2          12:30:00
     3          15:00:00
     4          17:00:00
   timeCond:
     0          0
     1          0
     2          0
     3          0
     4          0
   timer:
     0          0
     1          0
     2          0
     3          0
     4          0
   timers:
     0           0  1  2  3  4
   trigger:
   triggertime:
     1591084800:
       localtime  1591084800
       hash:
     1591093800:
       localtime  1591093800
       hash:
     1591102800:
       localtime  1591102800
       hash:
     1591110000:
       localtime  1591110000
       hash:
     1591169880:
       localtime  1591169880
       hash:
   uiState:
   uiTable:
Attributes:
   DbLogExclude .*:0
   alias      Poolpumpe automatisch steuern
   checkall   all
   devStateIcon disabled:general_aus@red:initialize initialize:general_an@green:disable initialized:general_an@green:disable cmd.*:general_an@green:disable
   room       Pool
   wait       0:120:120:120:180

tobox

Ohne genau überblicken zu können, was das genau macht, habe ich jetzt mal "checkReadingEvent 0" gesetzt. ReadingsProxy-Devices scheinen da wohl problematisch zu sein in DOIFs. Ich berichte, wenn es geholfen hat.

tobox

Ich glaube, ich habe es jetzt hinbekommen. Das Problem war wohl tatsächlich, dass es kein anderes matchendes DOIF-cmd gab, in das das DOIF während des WAIT reinspringen konnte.

Das Verhalten war reproduzier bar so:

- wenn kurz nach  dem Einschalten VL+0.2<RL war, wurde ein Timer mit 180s gesetzt
- egal, wie sich VL und RL dann geändert haben, nach 180s wurde abgeschaltet

Das ist nicht das Verhalten, das ich nach der DOIF-Doku und dem wait attribut erwartet habe. Jetzt habe ich ein DOELSE hinzugefügt. Jetzt wird der 180s Timer sofort gelöscht, wenn VL+0.2<RL nicht mehr gilt.