DOIF mit mehreren Bedingungen funktioniert nicht zum Stufen-Heizen mit PV Überschuss

Begonnen von Hadl, 20 August 2024, 23:15:09

Vorheriges Thema - Nächstes Thema

Hadl

Hallo zusammen,
ich hab ein DOIF das ich leider nicht zum laufen bekommen.
Ziel ist es einen Heizstab im Warmwasserspeicher (Boiler) mit einem Shelly2PM pro anzusteuern und meinen PV Überschuss zum Warmwassererwärmen zu nutzen.

Dazu verwende ich diese Readings:
PvUeberschuss = Übrige Leistung der PV Anlage
PvUeberschussVorBoiler = PvUeberschuss + aktuelle Leistung des Boiler-Shelly
Storage_0_Controller_StateOfCharge_Relative = PV Akku Prozentsatz

Mit diesem DOIF möchten ich den Shelly steuern, aber er geht immer in State 4 (DOELSE), obwohl die Bedingungen eindeutig für State1 sprechen (negativer PV Überschuss, halb leerer Akku).

Das userreading in Fronius_Symo1
PvUeberschuss:(PowerFlow_Site_P_PV|PowerFlow_Site_P_Load).* {\
my $val = ReadingsVal($name,"PowerFlow_Site_P_PV",0)-ReadingsVal($name,"PowerFlow_Site_P_Load",0);;;;$val\
}

und die Berechnung von PvUeberschussVorBoiler in einem notify
define notify_PvUeberschussVorBoiler notify Fronius_Symo1:PvUeberschuss:.*\
  {\
  my $val=\
    ReadingsVal('Fronius_Symo1', 'PvUeberschuss', '-999') + \
    ReadingsVal('ShellyBoiler', 'power_sum', '998');;;;\
  { fhem "sleep 0.1;; setreading Fronius_Symo1 PvUeberschussVorBoiler $val" }\
}
attr notify_PvUeberschussVorBoiler event-min-interval .*:3600
attr notify_PvUeberschussVorBoiler event-on-change-reading .*
attr notify_PvUeberschussVorBoiler room Heizung,PV
#   CFGFN     
#   DEF        Fronius_Symo1:PvUeberschuss:.*
#  {
#  my $val=
#    ReadingsVal('Fronius_Symo1', 'PvUeberschuss', '-999') +
#    ReadingsVal('ShellyBoiler', 'power_sum', '998');;
#  { fhem "sleep 0.1; setreading Fronius_Symo1 PvUeberschussVorBoiler $val" }
#}
#   FUUID      66c373a5-f33f-a72e-1251-bf9e5468ef315977
#   NAME       notify_PvUeberschussVorBoiler
#   NOTIFYDEV  Fronius_Symo1
#   NR         546
#   NTFY_ORDER 50-ntest
#   REGEXP     Fronius_Symo1:PvUeberschuss:.*
#   STATE      2024-08-21 00:29:49
#   TRIGGERTIME 1724192989.4857
#   TYPE       notify
#   eventCount 13
#   Helper:
#     DBLOG:
#       state:
#         logdb:
#           TIME       1724103145.07583
#           VALUE      active
#   READINGS:
#     2024-08-19 23:32:24   state           active
#     2024-08-21 00:29:49   triggeredByDev  Fronius_Symo1
#     2024-08-21 00:29:49   triggeredByEvent PvUeberschuss: -228.154475823045
#
setstate notify_PvUeberschussVorBoiler 2024-08-21 00:29:49
setstate notify_PvUeberschussVorBoiler 2024-08-19 23:32:24 state active
setstate notify_PvUeberschussVorBoiler 2024-08-21 00:29:49 triggeredByDev Fronius_Symo1
setstate notify_PvUeberschussVorBoiler 2024-08-21 00:29:49 triggeredByEvent PvUeberschuss: -228.154475823045


Das DOIF das nicht funktioniert
Internals:
   CFGFN     
   DEF        (([Fronius_Symo1:PvUeberschuss] < 100 and [Fronius_Symo1:Storage_0_Controller_StateOfCharge_Relative] < 80) or
  [Fronius_Symo1:Storage_0_Controller_StateOfCharge_Relative] < 50)
  (set ShellyBoiler 1kW-aus; set ShellyBoiler 2kW-aus)
DOELSEIF ([Fronius_Symo1:PvUeberschussVorBoiler] > 3000)
  (set ShellyBoiler 1kW-ein; set ShellyBoiler 2kW-ein)
DOELSEIF ([Fronius_Symo1:PvUeberschussVorBoiler] > 2000)
  (set ShellyBoiler 1kW-aus; set ShellyBoiler 2kW-ein)
DOELSE
  (set ShellyBoiler 1kW-ein; set ShellyBoiler 2kW-aus)
   FUUID      66b49139-f33f-a72e-f7a6-8156c6b502dbba8e
   MODEL      FHEM
   NAME       doif_Boiler_PvUeberschussVorAkku
   NOTIFYDEV  global,Fronius_Symo1
   NR         545
   NTFY_ORDER 50-doif_Boiler_PvUeberschussVorAkku
   STATE      cmd_4
   TYPE       DOIF
   VERSION    28546 2024-02-23 20:11:05
   eventCount 2947
   Helper:
     DBLOG:
       cmd:
         logdb:
           TIME       1724184931.83652
           VALUE      4
       cmd_event:
         logdb:
           TIME       1724184931.83652
           VALUE      Fronius_Symo1
       cmd_nr:
         logdb:
           TIME       1724184931.83652
           VALUE      4
       last_cmd:
         logdb:
           TIME       1723224541.84125
           VALUE      cmd_4
       mode:
         logdb:
           TIME       1724183179.56563
           VALUE      enabled
       state:
         logdb:
           TIME       1724184931.83652
           VALUE      cmd_4
       wait_timer:
         logdb:
           TIME       1724187066.51855
           VALUE      no timer
   READINGS:
     2024-08-20 22:51:06   Device          Fronius_Symo1
     2024-08-20 22:15:31   cmd             4
     2024-08-20 22:15:31   cmd_event       Fronius_Symo1
     2024-08-20 22:15:31   cmd_nr          4
     2024-08-20 22:51:06   e_Fronius_Symo1_PvUeberschuss -311.635201379657
     2024-08-20 22:51:06   e_Fronius_Symo1_PvUeberschussVorBoiler -311.635201379657
     2024-08-20 22:51:06   e_Fronius_Symo1_Storage_0_Controller_StateOfCharge_Relative 46.4
     2024-08-20 21:46:19   mode            enabled
     2024-08-20 22:15:31   state           cmd_4
     2024-08-20 22:51:06   wait_timer      no timer
   Regex:
     accu:
     bar:
     barAvg:
     collect:
     cond:
       Fronius_Symo1:
         0:
           PvUeberschuss ^Fronius_Symo1$:^PvUeberschuss:
           Storage_0_Controller_StateOfCharge_Relative ^Fronius_Symo1$:^Storage_0_Controller_StateOfCharge_Relative:
         1:
           PvUeberschussVorBoiler ^Fronius_Symo1$:^PvUeberschussVorBoiler:
         2:
           PvUeberschussVorBoiler ^Fronius_Symo1$:^PvUeberschussVorBoiler:
   attr:
     cmdState:
     wait:
       0:
         10
       1:
         10
       2:
         10
       3:
         10
     waitdel:
   condition:
     0          (::ReadingValDoIf($hash,'Fronius_Symo1','PvUeberschuss') < 100 and ::ReadingValDoIf($hash,'Fronius_Symo1','Storage_0_Controller_StateOfCharge_Relative') < 80) or   ::ReadingValDoIf($hash,'Fronius_Symo1','Storage_0_Controller_StateOfCharge_Relative') < 50
     1          ::ReadingValDoIf($hash,'Fronius_Symo1','PvUeberschussVorBoiler') > 3000
     2          ::ReadingValDoIf($hash,'Fronius_Symo1','PvUeberschussVorBoiler') > 2000
   do:
     0:
       0          set ShellyBoiler 1kW-aus; set ShellyBoiler 2kW-aus
     1:
       0          set ShellyBoiler 1kW-ein; set ShellyBoiler 2kW-ein
     2:
       0          set ShellyBoiler 1kW-aus; set ShellyBoiler 2kW-ein
     3:
       0          set ShellyBoiler 1kW-ein; set ShellyBoiler 2kW-aus
   helper:
     NOTIFYDEV  global,Fronius_Symo1
     event      PvUeberschussVorBoiler: -311.635201379657
     globalinit 1
     last_timer 0
     sleepdevice Fronius_Symo1
     sleepsubtimer 0
     sleeptimer -1
     timerdev   Fronius_Symo1
     timerevent PvUeberschussVorBoiler: -311.635201379657
     triggerDev Fronius_Symo1
     timerevents:
       PvUeberschussVorBoiler: -311.635201379657
     timereventsState:
       PvUeberschussVorBoiler: -311.635201379657
     triggerEvents:
       PvUeberschussVorBoiler: -311.635201379657
     triggerEventsState:
       PvUeberschussVorBoiler: -311.635201379657
   internals:
   readings:
     all         Fronius_Symo1:PvUeberschuss Fronius_Symo1:Storage_0_Controller_StateOfCharge_Relative Fronius_Symo1:PvUeberschussVorBoiler
   trigger:
   uiState:
   uiTable:
Attributes:
   event-min-interval .*:3600
   event-on-change-reading .*
   room       Heizung,PV
   wait       10:10:10:10

Dann gibts noch ein zweites kleineres Problem, das "wait" für mich eigentlich nicht richtig ist, denn wenn ich das für alle auf 300 sekunden stelle, zieht jedes Event (alle 60 Sekunden) den Timer neu auf und die Aktion wird nie durchgeführt.
Ich würde also gerne die Aktionen durchführen und dann 300 Sekunden den DOIF anhalten. Wäre hier wait 0,300:0,300:0,300:0,300 und ner zweiten Dummy aktion das richtige? Oder eher "cmdpause"? Ziel ist es sofort zu schalten, aber zu häufiges Schalten zu verhindern.

Kann jemand erkennen wo mein Fehler liegt, warum er nicht in State 1 springt?

Per

Da kann ich dir nicht helfen, aber ein Tipp zu deinem Userreading geben:
Pack ein Leerzeichen vor und nach das Minus, Perl kann da recht unerwartet reagieren.
Klammer + Minus funktioniert, aber Minus + Funktion/Variablen nicht, wenn das Ergebnis der Funktion/ Variable negativ ist.

MadMax-FHEM

#2
Neben den genannten Dingen:

Du hast ein userReadings-Ausschnitt gepostet ohne das zugehörige Device...

Warum ein notify auf das userReadings und dort dann weitere Readings berechnen vom selben Device?

-> warum nicht: entweder alles über userReadings oder notify? Das Durcheinander blickst du doch irgendwann nicht mehr...

event-on-Attribute machen bei einem notify überhaupt keinen Sinn!!
Ebensowenig bei DOIF (nehme ich an: nutze ich nicht)...

Ein notify reagiert auf Events.
Du musst die Attribute schon bei dem Device setzen, das die Events erzeugt, die du "einschränken" willst.

Und: ich würde die event-on-Attribute erst mal weglassen, bis alles tut und dann u.U. "einschränken"...

Bzgl. deines DOIF kann ich nix sagen.
Habe aber im Kopf, dass es Trigger-/Event-"Abfragen" gibt und es kann immer nur einen Event zur Zeit geben (fhem ist single-Threaded).
Es mag also sein, dass die "Zustände" passen, wenn EIN Trigger kommt aber eben nicht die "Trigger-Abfragen"...
War irgendwas mit einem Fragezeichen vor der "Abfrage"...

Ich würde auch, wo du eh mit Zahlenwerten rechnest/arbeitest ReadingsNum statt ReadingsVal nehmen...

Nur meine Anmekungen dazu...

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)

passibe

Vermutlich tatsächlich das Fragezeichen-Ding. Im and-Zweig muss vor eine der Bedingungen ein Fragezeichen, die können niemals beide zum gleichen Zeitpunkt wahr sein, denn es wird immer nur ein Event ausgewertet.
Also vermutlich (denn du willst ja auf das Überschuss-Event triggern):

(([Fronius_Symo1:PvUeberschuss] < 100 and [?Fronius_Symo1:Storage_0_Controller_StateOfCharge_Relative] < 80) or
  [Fronius_Symo1:Storage_0_Controller_StateOfCharge_Relative] < 50)

MadMax-FHEM

#4
Mal davon ab, dass man "and" nicht klammern muss: is wie "Punkt vor Strich" ;)

Und auch eine Bedingung mit "or" wäre von dem "Event-Problem" betroffen...
...wenn es das tatsächlich wäre...
(wie geschrieben: nutze DOIF nicht, mir reichen notify und co)

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)

Hadl

Zitat von: Per am 21 August 2024, 07:35:14Pack ein Leerzeichen vor und nach das Minus, Perl kann da recht unerwartet reagieren.
Danke, hab ich gemacht, ändert aber am Verhalten nichts.

Zitat von: MadMax-FHEM am 21 August 2024, 10:39:05Du hast ein userReadings-Ausschnitt gepostet ohne das zugehörige Device...

Warum ein notify auf das userReadings und dort dann weitere Readings berechnen vom selben Device?
-> warum nicht: entweder alles über userReadings oder notify? Das Durcheinander blickst du doch irgendwann nicht mehr...
Das Device ist mein Fronius Wechselrichter, das wäre etwas viel geworden die komplette Info zu Posten, hier nochmal das wichtigste!
Das userreading nutze ich um innerhalb des Devices neue Werte zu berechnen, wie z.B. die Differenz aus PV Leistung und Verbrauch im Haus
PvUeberschussVorBoiler hätte ich auch gerne als UserReading Berechnet, hab das aber nicht hinbekommen nen Wert von nem anderen Device (Leistungsmessung Boiler) mit einzurechnen. Daher das Notify mit dem sleep. Nur so hab ich's hinbekommen und auch nen Event damit generiert um im DOIF weiterzurechnen.

define Fronius_Symo1 fronius xx.xx.xx.xx
attr Fronius_Symo1 IntervalArchiveData 120
attr Fronius_Symo1 event-min-interval .*:3600
attr Fronius_Symo1 event-on-change-reading .*
attr Fronius_Symo1 room PV,Interessantes,Stromzaehler
attr Fronius_Symo1 userReadings PowerInverter1:PowerFlow_Inverters_1_E_Total.* differential {my $val=ReadingsVal($name,"PowerFlow_Inverters_1_E_Total",0);;;;$val},\
EnergySite:PowerFlow_Inverters_1_E_Total.* {\
my $val = ReadingsVal($name,"PowerFlow_Inverters_1_E_Total",0)-\
          ReadingsVal($name,"Meter_0_EnergyReal_WAC_Minus_Absolute",0)+\
          ReadingsVal($name,"Meter_0_EnergyReal_WAC_Plus_Absolute",0);;;;$val\
},\
PvUeberschuss:(PowerFlow_Site_P_PV|PowerFlow_Site_P_Load).* {\
my $val = ReadingsVal($name,"PowerFlow_Site_P_PV",0)-ReadingsVal($name,"PowerFlow_Site_P_Load",0);;;;$val\
},\
PowerSitefromEnergy:EnergySite.* differential {my $val=ReadingsVal($name,"EnergySite",0);;;;$val}

Zitat von: MadMax-FHEM am 21 August 2024, 10:39:05Habe aber im Kopf, dass es Trigger-/Event-"Abfragen" gibt und es kann immer nur einen Event zur Zeit geben (fhem ist single-Threaded).
Es mag also sein, dass die "Zustände" passen, wenn EIN Trigger kommt aber eben nicht die "Trigger-Abfragen"...
War irgendwas mit einem Fragezeichen vor der "Abfrage"...
Hmm, das hört sich spannend an. Klar die unterschiedlichen Werte kommen alle nacheinander, ich ging bis jetzt davon aus, das er für die anderen Werte dann den letzten Zustand (aus dem "e_" Reading) verwendet. Kannst du das mit dem Fragezeichen noch etwas näher erklären?
Wenn er immer das DOELSE ansteuert, wenn der letzte Event nicht vollständig zur Auswertung aller DOIF's/DOELSE's reicht wäre das ne Erklärung, aber dann sollte doch kein DOIF mit mehr als einer Bedingung funktionieren...

Was macht denn das Fragezeichen und wann braucht man es?

MadMax-FHEM

#6
Zitat von: Hadl am 21 August 2024, 15:04:14Das Device ist mein Fronius Wechselrichter, das wäre etwas viel geworden die komplette Info zu Posten, hier nochmal das wichtigste!
Das musst du schon den Hilfswilligen überlassen ;)

Zitat von: Hadl am 21 August 2024, 15:04:14PvUeberschussVorBoiler hätte ich auch gerne als UserReading Berechnet, hab das aber nicht hinbekommen nen Wert von nem anderen Device (Leistungsmessung Boiler) mit einzurechnen. Daher das Notify mit dem sleep. Nur so hab ich's hinbekommen und auch nen Event damit generiert um im DOIF weiterzurechnen.
Du kannst auch in einem userReadings Werte aus anderen Devices abfragen: ReadingsVal/ReadingNum("DevicenameAnderesDevice", "Readingname", Defaultwert)
Allerdings wird ein userReadings nur durch Events getriggert, die eben das Device erzeugt, an dem das userReadings "dranhängt".
Ein notify durch die entsprechende Trigger-RegEx (die eben Events von verschiedenen Devices zulässt/ermöglicht)...

Man kann beides machen, also userReadings und notify, allerdings würde ich halt nur eines von beiden machen (weil auch dein userReadings würde per notify gehen), weil wenn Readings von verschiedenen Seiten/Mechanismen kommen, dann weißt du beim Suchen von Problemen eben u.U. nicht mehr so einfach wo was herkommt...
...das ist alles.

Zitat von: Hadl am 21 August 2024, 15:04:14Wenn er immer das DOELSE ansteuert, wenn der letzte Event nicht vollständig zur Auswertung aller DOIF's/DOELSE's reicht wäre das ne Erklärung, aber dann sollte doch kein DOIF mit mehr als einer Bedingung funktionieren...

Was macht denn das Fragezeichen und wann braucht man es?

Doch, weil es eben Bedinungen gibt, die nur abgefragt werden wenn EIN Event triggert -> eine Möglichkeit ist bei DOIF wohl das Fragezeichen
Andere Bedingungen prüfen eben, ob ein bestimmtes Event kam (sieht bei DOIF offenbar ähnlich aus, bewirkt aber unterschiedliche Dinge)...
...und wenn du 2 oder mehr "Event-Abfragen" verknüpfst, kann das nie passen, weil es eben immer nur einen Event zur Zeit gibt.

Wozu man das und andere Dinge bei DOIF braucht -> commandref und Doku zu DOIF...

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)

Damian

Zitat von: Hadl am 20 August 2024, 23:15:09Dann gibts noch ein zweites kleineres Problem, das "wait" für mich eigentlich nicht richtig ist, denn wenn ich das für alle auf 300 sekunden stelle, zieht jedes Event (alle 60 Sekunden) den Timer neu auf und die Aktion wird nie durchgeführt.
Ich würde also gerne die Aktionen durchführen und dann 300 Sekunden den DOIF anhalten. Wäre hier wait 0,300:0,300:0,300:0,300 und ner zweiten Dummy aktion das richtige? Oder eher "cmdpause"? Ziel ist es sofort zu schalten, aber zu häufiges Schalten zu verhindern.

Kann jemand erkennen wo mein Fehler liegt, warum er nicht in State 1 springt?

Beim DOIF wird nicht jeder Zweig abgearbeitet, sondern nur die, zu denen es einen Trigger gibt. z. B. wird cmd2 nicht beachtet, wenn der Trigger von [Fronius_Symo1:Storage_0_Controller_StateOfCharge_Relative] kommt. Durch das Notify mit Verzögerung wird dein DOIF mehrfach getriggert.

Ich würde alles in einem Device machen, um keine Nebeneffekte zu bekommen. Wenn du die Berechnungen in DOIF_Readings packst, dann kannst du direkt diese Readings in deinen Bedingungen angeben, ohne dass neue Events produziert werden.

Die Verzögerungen kannst du dir normalerweise auch sparen, denn DOIF wiederholt im Normalfall (ohne do always-Attribut) keine Ausführung (z. B. cmd1 wird erst dann wieder ausgeführt, wenn zwischendurch ein anderer Zweig ausgeführt wurde)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Per

Zitat von: MadMax-FHEM am 21 August 2024, 10:39:05Habe aber im Kopf, dass es Trigger-/Event-"Abfragen" gibt und es kann immer nur einen Event zur Zeit geben (fhem ist single-Threaded).
Es mag also sein, dass die "Zustände" passen, wenn EIN Trigger kommt aber eben nicht die "Trigger-Abfragen"...
Völlig korrekt, ABER: hier werden keine Events abgefragt, sondern Status. Event Abfragen hätten eine andere Syntax.

Hadl

#9
Vielen Dank für eure Hilfe, leider bin ich noch nicht am Ziel...

Zitat von: MadMax-FHEM am 21 August 2024, 15:11:37Du kannst auch in einem userReadings Werte aus anderen Devices abfragen: ReadingsVal/ReadingNum("DevicenameAnderesDevice", "Readingname", Defaultwert)
Allerdings wird ein userReadings nur durch Events getriggert, die eben das Device erzeugt, an dem das userReadings "dranhängt".
Ein notify durch die entsprechende Trigger-RegEx (die eben Events von verschiedenen Devices zulässt/ermöglicht)...

Man kann beides machen, also userReadings und notify, allerdings würde ich halt nur eines von beiden machen (weil auch dein userReadings würde per notify gehen), weil wenn Readings von verschiedenen Seiten/Mechanismen kommen, dann weißt du beim Suchen von Problemen eben u.U. nicht mehr so einfach wo was herkommt...
...das ist alles.
Ja, das war genau der Grund, warum ich mich für das notify entschieden habe, um auch wirklich getriggert zu werden wenn sich einer der Eingänge ändert! Ihr habt Recht, er wäre klarer, wenn ich auch die UserReadings durch notify's ersetzen würde.
Wenn ich euch aber richtig verstehe ist das nur zur besseren Verständlichkeit, erklärt aber nicht das aktuelle Problem.

Zitat von: MadMax-FHEM am 21 August 2024, 15:11:37Doch, weil es eben Bedinungen gibt, die nur abgefragt werden wenn EIN Event triggert -> eine Möglichkeit ist bei DOIF wohl das Fragezeichen
Andere Bedingungen prüfen eben, ob ein bestimmtes Event kam (sieht bei DOIF offenbar ähnlich aus, bewirkt aber unterschiedliche Dinge)...
...und wenn du 2 oder mehr "Event-Abfragen" verknüpfst, kann das nie passen, weil es eben immer nur einen Event zur Zeit gibt.
Zitat von: Damian am 21 August 2024, 17:09:26Beim DOIF wird nicht jeder Zweig abgearbeitet, sondern nur die, zu denen es einen Trigger gibt. z. B. wird cmd2 nicht beachtet, wenn der Trigger von [Fronius_Symo1:Storage_0_Controller_StateOfCharge_Relative] kommt. Durch das Notify mit Verzögerung wird dein DOIF mehrfach getriggert.
Oh, das hört sich dann nach meinem Problem an! Wenn sich jetzt der Akku Ladezustand von 98% auf 99% ändert, ich aber weiterhin > 3KW Überschuss habe, will ich weiterhin die 3 KW haben (cmd_2), aktuell geht er mir auf 1kW runter (cmd_4 wegen DOELSE)
Der Akkuzustand wird ja nur in der Bedingung für cmd_1 verwendet oder führt dann eben zu cmd_4 wenn cmd_2-3 "ignoriert" werden.
Das würde zu den Beobachtungen passen, ist aber nicht was ich erreichen will. Wie kann ich ne vollständige Prüfung erreichen, egal welcher Input sich ändert?
Das Fragezeichen scheint die Triggerung ja eher gewollt zu verhindern, hilft mir hier also nicht.
Zitat von: DOIF CommandRefAngaben in eckigen Klammern, die mit einem Fragezeichen beginnen, führen zu keiner Triggerung des Moduls, sie dienen lediglich der Abfrage.

Zitat von: Damian am 21 August 2024, 17:09:26Ich würde alles in einem Device machen, um keine Nebeneffekte zu bekommen. Wenn du die Berechnungen in DOIF_Readings packst, dann kannst du direkt diese Readings in deinen Bedingungen angeben, ohne dass neue Events produziert werden.
OK, also die notify (ehemals auch userReadings) dann in das DOIF schreiben als Readings schreiben lassen? Ein neuer Event muss natürlich schon produziert werden wenn ich das Reading update, sonst wird ja der DOIF nicht mit den aktuellen Werten (oder sogar nie) gerechnet.

Zitat von: Damian am 21 August 2024, 17:09:26Die Verzögerungen kannst du dir normalerweise auch sparen, denn DOIF wiederholt im Normalfall (ohne do always-Attribut) keine Ausführung (z. B. cmd1 wird erst dann wieder ausgeführt, wenn zwischendurch ein anderer Zweig ausgeführt wurde)
Das wiederholen an sich wäre kein Problem, denn der shelly macht einfach nichts, wenn ich den 1kW Ausgang mehrmals einschalte. Was ich verhindern will, das er bei jeder Wolke am Himmel oder jedem Regelvorgang des Backofens die Ausgänge anders schaltet, da ich wirklich Leistung schalte und ich um die Lebensdauer des Shelly besorgt bin. Daher will ich wenn ich mal umgeschalten habe für 3-5 Minuten nicht auf etwas anderes schalten.
Das hab ich nun mit dem hier passend hinbekommen:
attr doif_Boiler_PvUeberschussVorAkku cmdpause 180:180:180:180Nur das Problem das wenn sich der Akku Ladezustand im nicht relevanten Bereich (also z.B. 99,8% auf 99,9% was in dem Bereich oft passiert) ändert er immer auf cmd_1 oder cmd_4 geht weis ich nicht wie ich das lösen soll.
Das macht auch viele unnötige Schaltvorgänge aus!
Der Akku soll natürlich auch nicht ignoriert werden denn wenn er von 50,0% auf 49,9% geht soll natürlich cmd_1 (Boiler Heizung komplett aus) angesteuert werden.

Edit:
Hab mich jetzt nochmal durch die CommandRef gegraben und das "checkall" Attribut gefunden! Ich denke das sollte mein Problem lösen... Ich frag mich aber warum das nicht standartmäßig aktiviert ist...
attr doif_Boiler_PvUeberschussVorAkku checkall allIch werd das morgen mal beobachten obs nun klappt, der erste Eindruck ist gut! Vielen Dank euch allen für die wertvollen Hinweise!

Damian

Zitat von: Hadl am 21 August 2024, 20:20:31VOh, das hört sich dann nach meinem Problem an! Wenn sich jetzt der Akku Ladezustand von 98% auf 99% ändert, ich aber weiterhin > 3KW Überschuss habe, will ich weiterhin die 3 KW haben (cmd_2), aktuell geht er mir auf 1kW runter (cmd_4 wegen DOELSE)
Der Akkuzustand wird ja nur in der Bedingung für cmd_1 verwendet oder führt dann eben zu cmd_4 wenn cmd_2-3 "ignoriert" werden.
Das würde zu den Beobachtungen passen, ist aber nicht was ich erreichen will. Wie kann ich ne vollständige Prüfung erreichen, egal welcher Input sich ändert?
Das Fragezeichen scheint die Triggerung ja eher gewollt zu verhindern, hilft mir hier also nicht.

Also wenn eine Bedingung hier also etwas > 3 KW bei cmd_2 eine Bedeutung hat, warum nimmst du sie nicht in die Bedingung mit auf, wie in cmd1.

Die Idee im DOIF-FHEM-Modus ist, die Angabe in der Bedingung anzugeben, die auch eine Relevanz für die nachfolgende Ausführung haben, die Vorgehensweise hat sich schon tausendfach bewährt.

Mit checkall hast du aber das passende Attribut für dich schon gefunden - ich habe es selbst noch nie gebraucht.

Im DOIF-Perl-Modus würde man das in Perl als if-elsif-...-else programmieren, dort werden dann alle Zweige durchlaufen, allerdings kannst du dort keine Attribute, wie z. B. wait nutzen, das durch Verzögern ein Toggeln verhindert. Das muss man dann schon selbst z. B. über die set_Exec-Funktion programmieren.

Übrigens, bei DOIF_Readings gibt es keine neuen Events, das Modul ruft sich rekursiv selbst auf. Das ist etwas effizienter und aus meiner Sicht auch eleganter, als das ganze System mit Events zu belasten, auf die man wiederum nur selbst reagieren will.


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

Hadl

Zitat von: Damian am 21 August 2024, 21:41:04Also wenn eine Bedingung hier also etwas > 3 KW bei cmd_2 eine Bedeutung hat, warum nimmst du sie nicht in die Bedingung mit auf, wie in cmd1.
Mit checkall hast du aber das passende Attribut für dich schon gefunden - ich habe es selbst noch nie gebraucht.
Aktuell besteht die zweite Bedingung nur aus genau dieser Abfrage: "([Fronius_Symo1:PvUeberschussVorBoiler] > 3000)"
Ich will aber auch dortrein, wenn sich gerade der Akkuzustand mit nem unbedeutenden Unterschied geändert hat.
checkall liest sich dafür vielversprechend!

Zitat von: Damian am 21 August 2024, 21:41:04Übrigens, bei DOIF_Readings gibt es keine neuen Events, das Modul ruft sich rekursiv selbst auf. Das ist etwas effizienter und aus meiner Sicht auch eleganter, als das ganze System mit Events zu belasten, auf die man wiederum nur selbst reagieren will.
Ich bin ein Freund von Graphen, und die gibts am leichtesten mit Log einträgen und damit Events. Du hast natürlich Recht, das belastet auch das System!

Vielen Dank für eure Hilfe!

Damian

Zitat von: Hadl am 21 August 2024, 22:26:34Aktuell besteht die zweite Bedingung nur aus genau dieser Abfrage: "([Fronius_Symo1:PvUeberschussVorBoiler] > 3000)"
Ich will aber auch dortrein, wenn sich gerade der Akkuzustand mit nem unbedeutenden Unterschied geändert hat.

dann könnte man ja auch angeben: ([Fronius_Symo1:Storage_0_Controller_StateOfCharge_Relative] or [Fronius_Symo1:PvUeberschussVorBoiler] > 3000)
Du kannst aber gerne checkall ausprobieren.

Zitat von: Hadl am 21 August 2024, 22:26:34Ich bin ein Freund von Graphen, und die gibts am leichtesten mit Log einträgen und damit Events. Du hast natürlich Recht, das belastet auch das System!
Dafür gibt es Event_Reading im DOIF.

Ich bin ein Freund von "alles an einer Stelle" damit man auch ein Jahr später noch weiß, was alles zusammengehört.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Per

Statt UserReadings kannst du im DOIF DOIFreadings verwenden, die haben keine Außenwirkung (Events), triggern aber IHR DOIF trotzdem.
Statt einem Wert kannst du im UserReading (oder DOIFreading) auch gleich einen Vergleich machen, dann gibt es den Event nicht bei jeder Änderung, sondern nur bei Überschreitung der Grenze.
Statt checkall kannst du auch das triggernde Device in den gewünschten Vergleich mit aufnehmen und als immer true betrachten
and [dev:read] == [dev:read]Hat bisweilen weniger Nebenwirkungen.