MQTT2_DEVICE - Werte aus Readings mappen, Anwendungsfall go-e

Begonnen von naerschhersch, 25 April 2022, 08:57:01

Vorheriges Thema - Nächstes Thema

naerschhersch

Ist dann wohl doch einfacher als gedacht.
Gut zu wissen, ich dachte das wäre komplizierter.

Eine weitere Frage: Kann man ein Reading von mehreren Triggern triggern lassen? Ich hab da auf die schnelle nichts gefunden.

Beta-User

Zitat von: naerschhersch am 25 April 2022, 13:56:13
Meine DOIFs triggern im Moment eben noch alle userReadings. Ich werde jetzt erstmal auf meine Readings einen Trigger setzen.
"triggern" oder "werden getriggert"?
Üblicherweise ist es so, dass eingehende MQTT-Nachrichten Readings erzeugen, diese ggf. dann wieder als trigger für userReadings genutzt werden und dann daran anschließend Eventhandler "dran sind", also getriggert werden.
Natürlich kann man auch aus einem Eventhandler wie DOIF heraus Readings setzen, dann werden die userReadings auch nur dann aktualisiert, wenn der trigger paßt (falls einer gesetzt ist, was m.E. immer dringlichst zu empfehlen ist). Das wäre "triggern".

Zitat
Was meinst du mit Daten von Extern? Ich rufe Daten von anderen Devices ab, ja.
Das war gemein. Was ist der Grund für diese Konstruktion?
(Bauchgefühl sagt: keine gute Lösung).

ZitatDer Code
amp_nutzbar:Uberschuss.* { my $us = ReadingsVal($name,'Uberschuss',0)/230; return 0 if !$us; sprintf("%.f",$us) },
passt nicht, denn Uberschuss kann auch negativ sein. Spricht denn irgendetwas gegen das IF-Konstrukt von vorher?
Geht auch mit (Perl-) if, du kannst aber auch "nicht $us" durch eine entsprechende andere Abfrage ersetzen:amp_nutzbar:Uberschuss.* { my $us = ReadingsVal($name,'Uberschuss',0)/230; return 0 if $us <= 0; sprintf("%.f",$us) },
Zitat
In das ganze myUtils müsste ich mich erst reinarbeiten. Ich habe das verstanden als global abrufbare Funktionen?
Ja, das trifft es recht gut.

Der Vorteil u.a.: Von "überall" her aufrufbar, und man kann komplexeren Code besser zergliedern als in einem Attribut, einfacher gleich "event-on-.*"-Prüfungen einbauen usw..

Zitat von: naerschhersch am 25 April 2022, 14:06:20
Eine weitere Frage: Kann man ein Reading von mehreren Triggern triggern lassen? Ich hab da auf die schnelle nichts gefunden.
Ein userReading kann einen trigger haben, der auf mehr als eine Reading-Aktualisierung paßt. Beispiel auf die Schnelle:
attr Jalousie_WZ userReadings dim:(dim|reportedState).* {$1 =~ /reportedState/ ? ReadingsNum($name,"reportedState",0):ReadingsNum($name,"state",0)}
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

naerschhersch

Meine DOIFs haben (nicht nur bei MQTT) einen set-Befehl ausgeführt, woraufhin wieder alle userReadings aktualisiert wurden und ein Event erzeugt haben, weil der zugewiesene Trigger fehlte. Durch die aktualisierten userReadings löste das DOIF wieder aus -> Endlosschleife. Indirekt triggerten die DOIFs also die userReadings.

Ich rufe die Daten anderer Devices ab, um überhaupt rechnen zu können. Das ganze dient ja zur Regelung der Wallbox über den Photovoltaik-Überschuss. Die Daten die ich abrufe, sind vom Hauskraftwerk, also die Schaltzentrale inkl. Hausakku, Wechselrichter und Netzanschluss etc. Außerdem noch vom dummy-device setPV, das ist quasi mein "Hauptschalter", ob ich überhaupt gerade regeln möchte. Außerdem sind darin Ausnahmen definiert, welcher Nutzer zu welcher Zeit automatisch auch ohne PV-Überschuss laden darf.
Ich könnte natürlich ein neues Device anlegen, inwelchem dann die Berechnungen etc durchgeführt werden. Welchen Mehrwert hätte das? Daten anderer Devices lesen muss dieses neue Device doch trotzdem.

Ich habe gerade mit Triggern auf den userReadings getestet, kein einziges löst mehr aus. Auch nicht mit der exakt so von dir formulierten und von mir copy-paste Variante. Events kommen zuverlässig rein (bspw: 2022-04-25 14:30:44 ModbusAttr S10E Uberschuss: -149). Woran könnte das liegen?

Danke dir für die multiple Trigger.

Beta-User

#18
Zitat von: naerschhersch am 25 April 2022, 14:32:11
Meine DOIFs haben (nicht nur bei MQTT) einen set-Befehl ausgeführt, woraufhin wieder alle userReadings aktualisiert wurden und ein Event erzeugt haben, weil der zugewiesene Trigger fehlte. Durch die aktualisierten userReadings löste das DOIF wieder aus -> Endlosschleife. Indirekt triggerten die DOIFs also die userReadings.
Nochmal: An sich verhindert FHEM sowas, indem innerhalb einer Event-Verarbeitungs-Schleife jedes "auslösende Device" nur einmal "angefaßt wird. Da muss also noch was anderes dazwischen "rumspuken"...

ZitatIch rufe die Daten anderer Devices ab, um überhaupt rechnen zu können.
Dagegen spricht ja auch prinzipiell nichts. Es macht aber einen Unterschied, ob man das als eine Information unter vielen berücksichtigt, oder ob man sich das triggernd in ein "fremdes" Device holt, um dann damit weiterzuarbeiten.

Da FHEM z.B. an sich Endlosschleifen unterbindet, läuft man so nämlich Gefahr, irgendwas zu verpassen, weil die Kette an der falschen Stelle "unterbrochen" wird. Ergo: Immer mit den Werten der Ausgangsdevices rechnen lassen, und Infos nicht "über Kreuz" von woanders holen.

Zitat
Ich habe gerade mit Triggern auf den userReadings getestet, kein einziges löst mehr aus. Auch nicht mit der exakt so von dir formulierten und von mir copy-paste Variante. Events kommen zuverlässig rein (bspw: 2022-04-25 14:30:44 ModbusAttr S10E Uberschuss: -149). Woran könnte das liegen?

Sorry, hatte irgendwie das falsche Beispiel ausgesucht, das ist ja grade so ein Fall, in dem das Reading "Uberschuss" von einem anderen Device her kommt. So sollte es klappen (ob der trigger jetzt sinnvoll ist, ist eine andere Frage...):
amp_nutzbar:car_status_detailnr.* { my $us = ReadingsVal('S10E','Uberschuss',0)/230; return 0 if $us <= 0; sprintf("%.f",$us) },
Diese Kette von voneinander abhängigen userReadings ist auch nicht gut, kann sein, dass dann Probleme in der Auswertung entstehen, die jetzt noch überdeckt sind durch häufige Triggerungen (im schlimmsten Fall ist es ein Hash-Zugriff und damit zufällig!).

Gesamteindruck: Du versuchst grade die Einarbeitung in die "Untiefen" von FHEM an einer denkbar komplizierten Stelle...

EDIT: Typos berichtigt.
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

naerschhersch

#19
Wie würdest du das denn umsetzen?
Irgendwo muss ja eine Verknüpfung zwischen den Devices sein, sonst würde es ja keinen Sinn ergeben.
Ich habe bis jetzt die Berechnung der Werte jeweils in dem Device vorgenommen, indem sie auch benötigt werden.

Gibt es denn eine andere Möglichkeit, durch ein anderes Device getriggert zu werden?


Zitat von: Beta-User am 25 April 2022, 14:56:30
Diese Kette von voneinander abhängigen userReadings ist auch nicht gut, kann sein, dass dann Probleme in der Auswertung entstehen, die jetzt noch überdeckt sind durch häufige Triggerungen (im schlimmsten Fall ist es ein Hash-Zugriff und damit zufällig!).
Ich verstehe nicht ganz was du meinst. Lieber alle Berechnungen in einer Formel?

Zitat von: Beta-User am 25 April 2022, 14:56:30
Gesamteindruck: Du versuchst grade die Einarbeitung in die "Untiefen" von FHEM an einer denkbar komplizierten Stelle...
Gut möglich. Nur durch Druck entstehen Diamanten... oder so.

Zitat von: Beta-User am 25 April 2022, 14:56:30
Sorry, hatte irgendwie das falsche Beispiel ausgesucht, das ist ja grade so ein Fall, in dem das Reading "Uberschuss" von einem anderen Device her kommt. So sollte es klappen (ob der trigger jetzt sinnvoll ist, ist eine andere Frage...):
amp_nutzbar:car_status_detailnr.* { my $us = ReadingsVal('S10E','Uberschuss',0)/230; return 0 if $us <= 0; sprintf("%.f",$us) },
Der Trigger ist quasi absolut unbrauchbar, denn er wird nur bei Start/Ende des Ladevorgangs aktualisiert. Ich bräuchte irgendetwas, wie ich von dem anderen Device (S10E Hauskraftwerk) triggern kann.

Beta-User

#20
Zitat von: naerschhersch am 25 April 2022, 15:32:28
Wie würdest du das denn umsetzen?
Hmm, gar nicht so einfach, wenn man sich in das Gesamtbild noch nicht eingedacht hat. (etwas mehr unten).

Zitat
Irgendwo muss ja eine Verknüpfung zwischen den Devices sein, sonst würde es ja keinen Sinn ergeben.
Das verstehe ich nicht. Du stellst die Verknüfung her, indem du (bisher:) "jeden" trigger zugelassen hast und dann ständig die fremden Werte abgeholt/eingerechnet hast. Mein Vorschlag läuft darauf hinaus, das zu begrenzen, indem "irgendein spezieller" trigger ausgewählt wird - "car_status_detailnr" war nur ein mögliches Beispiel, es kann auch ein anderes sein, das (von Zeitpunkt und Häufigkeit her) sinnvoll paßt.

Zitat
Ich habe bis jetzt die Berechnung der Werte jeweils in dem Device vorgenommen, indem sie auch benötigt werden.
Da stellt sich die Frage, was (wofür?) "benötigt" wird. Manches scheint nur eine Art Zwischenwert zu sein, damit andere, abhängige Werte berechnet werden können. Sowas würde ich eher in myUtils auslagern, da kann man dann auch gleich prüfen, ob überhaupt eine Änderung vorliegt und dann z.B. auch keine Aktualisierung vornehmen (dann stimmt nämlich auch der Zeitstempel, ab wann ein bestimmter Zustand eingetreten ist).

ZitatGibt es denn eine andere Möglichkeit, durch ein anderes Device getriggert zu werden?
userReadings werden bei jeder (triggernden) Aktualisierung im Device "durchgesehen". Man kann das beliebig von außen anschubsen:
setreading goe_mqtt update 1
(und dann den trigger auf "update:.1")  begrenzen!).

ZitatIch verstehe nicht ganz was du meinst.
Zwei Aspekte:
a) die Häufigkeit der Berechnung. Wenn kein trigger für das jeweilige userReading angegeben ist, wird die Berechnung für jede "Event-Loop" an dem Device gemacht, also bei dir evtl. 14x (= Zahl der readingList-Zeilen) statt 1x (oder weniger!).
b) deine userReadings bauen aufeinander auf. Habe grade in fhem.pl nachgesehen, userReadings werden in der Reihenfolge abgearbeitet, wie sie definiert sind, das müßte also so gehen wie von dir gedacht. Es gibt aber keine Garantie, dass es nicht irgendwann zu Änderungen am allgemeinen Verhalten von FHEM an dieser Stelle kommt...

ZitatLieber alle Berechnungen in einer Formel?
Jein. Ein userReadings-Eintrag erlaubt eben nur genau ein Reading. Wenn du mehrere brauchst, ist das einfach das falsche Mittel => myUtils in readingList mit (vereinfacht) Rückgabe eines Hashes. Da können dann mehrere Werte übergeben werden, _müssen aber nicht_.

ZitatGut möglich. Nur durch Druck entstehen Diamanten... oder so.
Gute Sichtweise, ich hoffe, der Druck paßt soweit ;D .

Zitat
Der Trigger ist quasi absolut unbrauchbar, denn er wird nur bei Start/Ende des Ladevorgangs aktualisiert. Ich bräuchte irgendetwas, wie ich von dem anderen Device (S10E Hauskraftwerk) triggern kann.
Man kann zum einen ein anderes Reading nehmen (oder mehrere Alternativen), und/oder auch einfach mit einem Eventhandler "quer" schreiben, was dann wenigstens den Vorteil hat, dass der Zeitstempel stimmt.

Fazit: Bin nicht sicher, ob es nicht sinnvoller wäre, diese ganzen berechneten Readings an ein anderes Device zu hängen (falls man sie überhaupt benötigt). Zumindest ist mir ist jedenfalls auch nach nochmaliger Durchsicht der userReadings-Liste insgesamt noch nicht klar, für was diese "Zwischenwerte" eigentlich gebraucht werden. Es scheinen irgendwelche Grendzwerte oä. zu sein, aber die eigentliche Auswertung sieht man nicht, die findet wohl woanders statt.

Nachtrag:
Da du den Charger (und ggf. vieles andere mehr) ja vermutlich v.a. anhand eines "Leitwertes" schalten willst, der woanders herkommt, würde ich meine Logik prinzipiell auf Eventverarbeitung an diesem "Leitwert" (z.B. aktuelle Produktion der PV-Anlage) ausrichten, und dann "von dort aus" checken, was alles denn wie zu schalten ist (bzw. wegen entsprechender User-Eingriffe nicht (ab-) zu schalten ist).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

naerschhersch

#21
So, ich habe mir jetzt übergangsweise ein notify erstellt, welches in den go-e ein Reading "update" scheibt. Dieses triggert dann, ist quasi die clock.
Funktioniert erstmal, ich möchte das dennoch gern weiterbauen und verbessern. Nicht zuletzt steht ja auch ein Lernprozess dahinter.

Zitat von: Beta-User am 25 April 2022, 16:15:10
Da stellt sich die Frage, was (wofür?) "benötigt" wird. Manches scheint nur eine Art Zwischenwert zu sein, damit andere, abhängige Werte berechnet werden können.
Diese Werte nehme ich teilweise auch, um im FTUI Visualisierungen vornehmen zu können. Ja, nicht alles, aber einiges.
Allerdings nehme ich Zwischenberechnungen auch, um nicht alles in jeder Formel neu zu berechnen. Die nutzbaren Ampere zum Beispiel.

Zitat von: Beta-User am 25 April 2022, 16:15:10
a) die Häufigkeit der Berechnung. Wenn kein trigger für das jeweilige userReading angegeben ist, wird die Berechnung für jede "Event-Loop" an dem Device gemacht, also bei dir evtl. 14x (= Zahl der readingList-Zeilen) statt 1x (oder weniger!).
Sollte vorrübergehend durch das update-Reading behoben sein (siehe oben).

Zitat von: Beta-User am 25 April 2022, 16:15:10
deine userReadings bauen aufeinander auf. Habe grade in fhem.pl nachgesehen, userReadings werden in der Reihenfolge abgearbeitet, wie sie definiert sind, das müßte also so gehen wie von dir gedacht. Es gibt aber keine Garantie, dass es nicht irgendwann zu Änderungen am allgemeinen Verhalten von FHEM an dieser Stelle kommt.
Also doch lieber alle Berechnungen für jede Formel neu vornehmen? Für mein Verständnis bietet das mehr Rechenaufwand, wenn für jede Formel eine deutlich höhere Zahl von Readings abgerufen und miteinander verrechnet werden muss.

Zitat von: Beta-User am 25 April 2022, 16:15:10
Jein. Ein userReadings-Eintrag erlaubt eben nur genau ein Reading. Wenn du mehrere brauchst, ist das einfach das falsche Mittel => myUtils in readingList mit (vereinfacht) Rückgabe eines Hashes. Da können dann mehrere Werte übergeben werden, _müssen aber nicht_.
Ich glaube hierfür fehlt mir ein bisschen Werkzeug. Muss ich mich reinlesen, ist noch nicht geschehen. Was wäre hiervon Vorteil? Dass man nur eine Formel hat am Ende?

Zitat von: Beta-User am 25 April 2022, 16:15:10
Fazit: Bin nicht sicher, ob es nicht sinnvoller wäre, diese ganzen berechneten Readings an ein anderes Device zu hängen (falls man sie überhaupt benötigt).
Ein neues Dummy für die Berechnungen? ist da nicht genau das selbe Problem, dass von überall Daten in unterschiedlichen Intervallen zu unterschiedlichen Zeiten kommen? Auch hier fehlt mir die Vorstellung des Vorteils.

Zitat von: Beta-User am 25 April 2022, 16:15:10
Da du den Charger (und ggf. vieles andere mehr) ja vermutlich v.a. anhand eines "Leitwertes" schalten willst, der woanders herkommt, würde ich meine Logik prinzipiell auf Eventverarbeitung an diesem "Leitwert" (z.B. aktuelle Produktion der PV-Anlage) ausrichten, und dann "von dort aus" checken, was alles denn wie zu schalten ist (bzw. wegen entsprechender User-Eingriffe nicht (ab-) zu schalten ist).
Hier geht es aber auch nur um eine gemeinsame Zeit bzw einen gemeinsamen Impuls?


Hier erstmal die akutelle Version
Internals:
   CID        go_echarger_XXXXXX
   DEF        go_echarger_XXXXXX
   FUUID      62659de8-f33f-6332-cdc2-1baaa38ecf935cb2
   IODev      m2s
   LASTInputDev m2s
   MSGCNT     59067
   NAME       goe_mqtt
   NR         70
   STATE      Leerlauf - 0 W (6 A)
   TYPE       MQTT2_DEVICE
   m2s_CONN   m2s_192.168.178.49_59817
   m2s_MSGCNT 59067
   m2s_TIME   2022-04-25 22:17:22
   JSONMAP:
     go-eCharger_XXXXXX_nrg_1 nrg_Spannung_L1
     go-eCharger_XXXXXX_nrg_10 nrg_Leistung_L3
     go-eCharger_XXXXXX_nrg_11 nrg_Leistung_N
     go-eCharger_XXXXXX_nrg_12 nrg_Leistung_gesamt
     go-eCharger_XXXXXX_nrg_13 nrg_Leistung_Faktor_L1
     go-eCharger_XXXXXX_nrg_14 nrg_Leistung_Faktor_L2
     go-eCharger_XXXXXX_nrg_15 nrg_Leistung_Faktor_L3
     go-eCharger_XXXXXX_nrg_16 nrg_Leistung_Faktor_N
     go-eCharger_XXXXXX_nrg_2 nrg_Spannung_L2
     go-eCharger_XXXXXX_nrg_3 nrg_Spannung_L3
     go-eCharger_XXXXXX_nrg_4 nrg_Spannung_N
     go-eCharger_XXXXXX_nrg_5 nrg_Strom_L1
     go-eCharger_XXXXXX_nrg_6 nrg_Strom_L2
     go-eCharger_XXXXXX_nrg_7 nrg_Strom_L3
     go-eCharger_XXXXXX_nrg_8 nrg_Leistung_L1
     go-eCharger_XXXXXX_nrg_9 nrg_Leistung_L2
   OLDREADINGS:
   READINGS:
     2022-04-25 22:14:41   alw_get         0
     2022-04-25 22:17:19   alw_set         0
     2022-04-25 22:14:42   amp_get         6
     2022-04-25 22:17:19   amp_nutzbar     0
     2022-04-25 22:17:19   amp_set         6
     2022-04-25 22:14:42   car_status      Leerlauf
     2022-04-25 22:14:43   car_status_detail NotChargingBecauseMinPauseDuration
     2022-04-25 22:14:43   car_status_detailnr 2
     2022-04-25 22:14:42   cbl_limit       20
     2022-04-25 22:15:19   frc_forceState  aus
     2022-04-25 22:14:42   lbp_time        null
     2022-04-25 22:17:22   nrg_Leistung_Faktor_L1 0
     2022-04-25 22:17:22   nrg_Leistung_Faktor_L2 0
     2022-04-25 22:17:22   nrg_Leistung_Faktor_L3 0
     2022-04-25 22:17:22   nrg_Leistung_Faktor_N 0
     2022-04-25 22:17:22   nrg_Leistung_L1 0
     2022-04-25 22:17:22   nrg_Leistung_L2 0
     2022-04-25 22:17:22   nrg_Leistung_L3 0
     2022-04-25 22:17:22   nrg_Leistung_N  0
     2022-04-25 22:17:22   nrg_Leistung_gesamt 0
     2022-04-25 22:17:22   nrg_Spannung_L1 229
     2022-04-25 22:17:22   nrg_Spannung_L2 230
     2022-04-25 22:17:22   nrg_Spannung_L3 232
     2022-04-25 22:17:22   nrg_Spannung_N  0
     2022-04-25 22:17:22   nrg_Strom_L1    0
     2022-04-25 22:17:22   nrg_Strom_L2    0
     2022-04-25 22:17:22   nrg_Strom_L3    0
     2022-04-25 22:17:22   psm_3p_aktiv    false
     2022-04-25 22:14:42   psm_car         3
     2022-04-25 22:14:43   psm_phaseswitchmode 3
     2022-04-25 22:17:22   pv_mode         auto
     2022-04-25 22:17:19   result          success
     2022-04-25 22:17:19   state           Start/Stop
     2022-04-25 22:14:43   trx_user        kein Nutzer
     2022-04-25 22:17:19   update          1
     2022-04-25 22:14:42   wh              0
     2022-04-25 22:14:41   wh_gesamt       1009436
     2022-04-25 22:14:42   wh_kwh_geladen  0.00
Attributes:
   DbLogExclude .*
   autocreate 0
   jsonMap    go-eCharger_XXXXXX_nrg_1:nrg_Spannung_L1
go-eCharger_XXXXXX_nrg_3:nrg_Spannung_L3
go-eCharger_XXXXXX_nrg_2:nrg_Spannung_L2
go-eCharger_XXXXXX_nrg_4:nrg_Spannung_N
go-eCharger_XXXXXX_nrg_5:nrg_Strom_L1
go-eCharger_XXXXXX_nrg_6:nrg_Strom_L2
go-eCharger_XXXXXX_nrg_7:nrg_Strom_L3
go-eCharger_XXXXXX_nrg_8:nrg_Leistung_L1
go-eCharger_XXXXXX_nrg_9:nrg_Leistung_L2
go-eCharger_XXXXXX_nrg_10:nrg_Leistung_L3
go-eCharger_XXXXXX_nrg_11:nrg_Leistung_N
go-eCharger_XXXXXX_nrg_12:nrg_Leistung_gesamt
go-eCharger_XXXXXX_nrg_13:nrg_Leistung_Faktor_L1
go-eCharger_XXXXXX_nrg_14:nrg_Leistung_Faktor_L2
go-eCharger_XXXXXX_nrg_15:nrg_Leistung_Faktor_L3
go-eCharger_XXXXXX_nrg_16:nrg_Leistung_Faktor_N
   readingList go_echarger_XXXXXX:/go-eCharger/XXXXXX/nrg:.* { json2nameValue($EVENT,"go-eCharger_XXXXXX_nrg_",$JSONMAP) }
go_echarger_XXXXXX:/go-eCharger/XXXXXX/amp:.* amp_get
go_echarger_XXXXXX:/go-eCharger/XXXXXX/modelStatus:.* car_status_detailnr
go_echarger_XXXXXX:/go-eCharger/XXXXXX/eto:.* wh_gesamt
go_echarger_XXXXXX:/go-eCharger/XXXXXX/cbl:.* cbl_limit
go_echarger_XXXXXX:/go-eCharger/XXXXXX/wh:.* wh
go_echarger_XXXXXX:/go-eCharger/XXXXXX/lbp:.* lbp_time
go_echarger_XXXXXX:/go-eCharger/XXXXXX/cus:.* cus_cable_status
go_echarger_XXXXXX:/go-eCharger/XXXXXX/frc/result:.* result
go_echarger_XXXXXX:/go-eCharger/XXXXXX/psm/result:.* result
go_echarger_XXXXXX:/go-eCharger/XXXXXX/trx:.* {my %n=( 'null' => 'kein Nutzer', '0' => 'ohne Karte', '1' => 'XXX' , '2' => 'XXX', '3' => 'XXX', '4' => 'XXX');; return { 'trx_user' =>$n{$EVENT}}}
go_echarger_XXXXXX:/go-eCharger/XXXXXX/psm:.* {my %psm=( '1' => '1', '2' => '3');; return { 'psm_phaseswitchmode' =>$psm{$EVENT}}}
go_echarger_XXXXXX:/go-eCharger/XXXXXX/car:.* {my %car=( '0' => 'unbekannt','1' => 'Leerlauf','2' => 'Ladevorgang','3' => 'Ladung verboten','4' => 'Stop','5' => 'Fehler',);; return { 'car_status' =>$car{$EVENT}}}
go_echarger_XXXXXX:/go-eCharger/XXXXXX/alw:.* {my %alw=( 'false' => '0','true' => '1');; return { 'alw_get' =>$alw{$EVENT}}}
go_echarger_XXXXXX:/go-eCharger/XXXXXX/frc:.* {my %frc=( '0' => 'neutral','1' => 'aus','2' => 'an');; return { 'frc_forceState' =>$frc{$EVENT}}}
   room       MQTT2_DEVICE,goe
   setExtensionsEvent 0
   setList    Leistung:selectnumbers,6,1,16,0,lin /go-eCharger/XXXXXX/amp/set $EVTPART1
Start/Stop:neutral,aus,an { my %hash = ( 'neutral' => '0', 'aus' => '1', 'an' => '2'); qq(/go-eCharger/XXXXXX/frc/set $hash{$EVTPART1}) }
Phasenzahl:1,3 { my %hash = ('1' => '1', '3' => '2'); qq(/go-eCharger/XXXXXX/psm/set $hash{$EVTPART1}) }
   stateFormat car_status - nrg_Leistung_gesamt W (amp_get A)
   userReadings amp_nutzbar:update.* { my $us = ReadingsVal($name,'Uberschuss',0)/230; return 0 if $us <= 0; sprintf("%.f",$us) },

psm_3p_aktiv:nrg_Leistung_L3.* {
    my $PL3 = ReadingsVal($name,"nrg_Leistung_L3",0);
    return "false" if $PL3 == 0;
    return "true";
},

alw_set:amp_nutzbar.* {
    my $an = ReadingsVal($name,"amp_nutzbar",0);
return 0 if $an < 6;
    return 1;
},

wh_kwh_geladen:wh.* {
sprintf("%.2f",ReadingsVal($name,"wh",0) / 1000)
},

pv_mode {
if (ReadingsVal("setPV","masterswitch",0)==1 and ReadingsVal("setPV","user_exception",0)==0)
{"auto"}
elsif (ReadingsVal("setPV","masterswitch",0)==1 and ReadingsVal("setPV","user_exception",0)==1)
{"Ausnahme aktiv"}
else
{"manuell"};
},

car_status_detail:car_status_detailnr.* {
my $frc=(
'0' => 'NotChargingBecauseNoChargeCtrlData',
'1' => 'Ladestopp Temperatursensor',
2 => 'Authentifizierung notwendig',
'3' => 'Laden erzwungen',
'4' => 'Laden verboten',
'5' => 'Zeitplan nicht eingehalten',
'6' => 'Energielimit nicht eingehalten',
'7' => 'preisgünstig Laden',
'22' => 'ausstecken simulieren',
'23' => 'Phasenwechsel',
'24' => 'NotChargingBecauseMinPauseDuration'
);;
my $rv = ReadingsVal($name,"car_status_detailnr",0);;
$rv => $frc;;
$frc
},
amp_set:amp_nutzbar.* {
my $ampn = ReadingsVal($name,'amp_nutzbar',0);
    my $PL3 = ReadingsVal($name,"nrg_Leistung_L3",0);

if ($PL3 == 0)
{if ($ampn > 16)
{16}
else
{if ($ampn < 6)
{6}
else
{ $ampn }
}
}
else
{if ( ( $ampn / 3 ) > 16)
{16}
else
{sprintf("%.f",$ampn)}
};
},
   verbose    2

Beta-User

#22
Zitat von: naerschhersch am 25 April 2022, 22:06:33
So, ich habe mir jetzt übergangsweise ein notify erstellt, welches in den go-e ein Reading "update" scheibt. Dieses triggert dann, ist quasi die clock.
Falls das "zufällig" auf den auszuwertenden Ausgangswert triggert: Besser dann direkt das "echte" Reading schreiben! Das aber begrenzen auf die Fälle, in denen wirklich eine Änderung vorliegt. Sonst passiert gerne sowas wie hier: https://forum.fhem.de/index.php/topic,127077.msg1219651.html#msg1219651....

Schön ist jedenfalls, dass das Grundprinzip jetzt anscheinend klar geworden ist :) .

Zitat
Diese Werte nehme ich teilweise auch, um im FTUI Visualisierungen vornehmen zu können. Ja, nicht alles, aber einiges.
Muss jeder selbst wissen, was er braucht. Bauchgefühl sagt allerdings weiter, dass es sinnvoll wäre, den notify/userReadings-Code so zu gestalten, dass jeweils nur _Änderungen_ zu einem neuen Wert des (user-) Readings führen sollten. Bei notify sollte es kein Problem sein, Infos zu finden, wie man das macht, bei userReadings ist das nicht so verbreitet. Es muss einfach Perl-"undef" zurückgegeben werden, also ein "return;" ohne "irgendwas" (wenn man es PBP-like richtig macht: auch ohne "undef"!).

Beispiel:
alw_set:amp_nutzbar.* {
    my $an = ReadingsVal($name,'amp_nutzbar',0);
    my $old = ReadingsVal($name,'alw_set',undef);
    if ( $an < 6 ) {
        return if $old == 0;
        return 0;
    }
    return if $old;
    return 1;
},


Zitat
Allerdings nehme ich Zwischenberechnungen auch, um nicht alles in jeder Formel neu zu berechnen. Die nutzbaren Ampere zum Beispiel.
Sollte vorrübergehend durch das update-Reading behoben sein (siehe oben).
Es kommt darauf an. Da ich "in jeder Formel" nicht kenne, kann ich dazu nichts sagen, aber im Zweifel stellt sich die Frage, was wie oft aufgerufen wird. Wenn du 1000x "vorsorglich" Werte ermittelst, statt 5x dann, wenn du sie wirklich brauchst, bist du mit 5x immer noch effektiver dran...
Wenn du vorbereitend für jeden Durchgang dann die Werte bereitstellst, die du mehrfach brauchst (aber auch nur dann rechnest, wenn es "news" gibt), ist das die effektivere Variante. Bisher (=ohne trigger) war es jedenfalls sicher ineffektiv gewesen!


Also doch lieber alle Berechnungen für jede Formel neu vornehmen?

Es kann aber auch sein, dass du _einen Durchgang_ machst, und dann alle neuen (Ergebnis-) Werte (also auch das aus "den Formeln") auf einmal neu setzt, ohne die Zwischenwerte nochmal zwischenzuspeichern. Dann rechnest du wirklich nur einmal...

ZitatWas wäre hiervon Vorteil? Dass man nur eine Formel hat am Ende?
Da mir nicht klar ist, was sich hinter der Formel von "jeder Formel" verbirgt, ist das schwierig zu beantworten. Ich denke eher in Events und deren Auswertung, und wenn man da eben "alles auf einmal" macht und durchgeht, hat man einen stringenten logischen Ablauf "von oben nach unten" und keine "Zustandsdenke". In dem einen Ablauf kann man dann eine Vielzahl von Schaltungen durchführen, Readings setzen usw.. Tendenziell ist das die Variante, die FHEM am wenigsten belastet.

Vielleicht schreibst du einfach mal auf einen Zettel, wie der _Ablauf_ sein soll, also
- welche Eingangs-Ereignisse gibt es? (ggf. sind das mehrere).
- welche Auswertungen müssen erfolgen, welche Prioritäten gelten dabei, was muss man sich wirklich für den nächsten Durchlauf merken?

Erst danach kann jemand von außen ggf. Hinweise geben, was ggf. wohin (mit welchem Werkzeug) geschrieben werden sollte. Auch ein notify oder DOIF kann ggf. Readings haben, das muss also nicht immer dummy sein (ich rate prinzipiell von dummy ab, das macht es häufig (!) unübersichtlich.).

PS: Funktioniert eigentlich "car_status_detail"?
Sieht irgendwie komisch aus...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

naerschhersch

Zitat von: Beta-User am 26 April 2022, 10:18:09
Falls das "zufällig" auf den auszuwertenden Ausgangswert triggert: Besser dann direkt das "echte" Reading schreiben! Das aber begrenzen auf die Fälle, in denen wirklich eine Änderung vorliegt.
Es triggert "zufällig" auf die Solarproduktion, welche sich aber naturgemäß stetig ändert. Zwei nacheinander gleich gemessene Werte sind (außer Nachts) in der Praxis nicht vorhanden.

Sonst habe ich erstmal ein "Schema" über das Projekt angehangen. Die Readings unter dem Strich sind errechnet, die darüber gemessen. Ich habe nicht alle Readings mitaufgenommen. Ich hoffe das reicht erstmal für den Überblick.

Nein, "car_status_detail" läuft (noch) nicht. Steht aber erst ganz hinten an.

Beta-User

#24
Zitat von: naerschhersch am 26 April 2022, 16:19:05
Es triggert "zufällig" auf die Solarproduktion, welche sich aber naturgemäß stetig ändert. Zwei nacheinander gleich gemessene Werte sind (außer Nachts) in der Praxis nicht vorhanden.
Sorry, wenn ich mich missverständlich ausgedrückt hatte. Es ging nicht unbedingt um die Änderung des Ausgangswerts, sondern um die Änderung des "weitergegebenen (gerundeten) Werts".

Also aus dem notify für "set goe_mqtt update 1" wird sowas (raw-Format):
my not_example1 S10E:Uberschuss:.* { \
  my $us = ReadingsVal($name,'Uberschuss',0)/230;;\
  my $old = ReadingsVal('goe_mqtt','amp_nutzbar',-1);;\
  return if $us <= 0 && !$old;; #unchanged, do nothing\
  return fhem('setreading goe_mqtt amp_nutzbar 0') if $us <= 0;;\
  $us = sprintf("%.f",$us);;\
  return if $us eq $old;; #unchanged, do nothing\
  return fhem("setreading goe_mqtt amp_nutzbar $us");;\
}
Wie du siehst, wird da auch nur solange weitergerechnet, wie noch was unklar ist...
Die weiteren userReadings kannst du trotzdem triggern bzw. errechnen lassen, wenn das Reading von außen gesetzt wird.

Da stellt sich dann nach deinem Schema die Frage, ob interne Trigger ausreichen, um auf Änderungen der "Haupt- und Nebenschalter" in "setPV" (Warum extra, wenn es nur für den Charger verwendet wird?) zu reagieren, oder ob das auch irgendwie per Event-Handler "abgefrühstückt werden" kann.

Zitat
Sonst habe ich erstmal ein "Schema" über das Projekt angehangen. Die Readings unter dem Strich sind errechnet, die darüber gemessen. Ich habe nicht alle Readings mitaufgenommen. Ich hoffe das reicht erstmal für den Überblick.
Ist etwas klarer. Demnach kommen die "eigentlichen Trigger" von den beiden Geräten "S10E" und "setPV", nämlich die überhaupt verfügbare Energiemenge und die Uservorgaben.

Zitat
Nein, "car_status_detail" läuft (noch) nicht. Steht aber erst ganz hinten an.
Der Code sieht auch "verbogen" aus, aber das bleibt erst mal "deine Nuss" :P ...

PS: Der Thread-Titel ist zwischenzeitlich irgendwie unpassend...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

naerschhersch

Zitat von: Beta-User am 26 April 2022, 16:43:27
Da stellt sich dann nach deinem Schema die Frage, ob interne Trigger ausreichen, um auf Änderungen der "Haupt- und Nebenschalter" in "setPV" (Warum extra, wenn es nur für den Charger verwendet wird?) zu reagieren, oder ob das auch irgendwie per Event-Handler "abgefrühstückt werden" kann.
Hauptschalter - Soll die PV-Überschussladung überhaupt aktiv sein? Das ist der generelle Switch, falls man (bspw. im Winter) auch laden will, wenn keine Sonne scheint.
Nebenschalter - Wird automatisch gesetzt, wenn ein bestimmter Nutzer lädt und eine definierte Zeitspanne aktiv ist. Da geht es darum, dass ein bestimmter Nutzer, der weite Strecken fährt, auch am Morgen wirklich vollgeladen ist.

Ich möchte die Steuerung einerseits grundlegend ausschalten und andererseits Ausnahmen definieren können. Das war die erstbeste mir eingefallene Lösung.

Zitat von: Beta-User am 26 April 2022, 16:43:27
Demnach kommen die "eigentlichen Trigger" von den beiden Geräten "S10E" und "setPV", nämlich die überhaupt verfügbare Energiemenge und die Uservorgaben.
Wenn wir uns gedanklich auf go-e beschränken, ja.

Zitat von: Beta-User am 26 April 2022, 16:43:27
PS: Der Thread-Titel ist zwischenzeitlich irgendwie unpassend...
Das ist mir auch schon aufgefallen, theoretisch wäre auch der Forenbereich nicht mehr wirklich korrekt.

Im Anhang noch die Trigger zwischen Geräten, wie ich sie mir vorstellen würde.

Beta-User

Zitat von: naerschhersch am 26 April 2022, 16:59:33
Das war die erstbeste mir eingefallene Lösung.
Meistens ist das ja auch nicht die schlechteste Idee, erst mal mit der "erstbesten" Lösung anzufangen.

Dein Problem: Du erfindest das Rad neu, es gibt afaik (mindestens) eine ziemlich ausgereifte Terminologie (und Visualisierung) zum Gesamtkomplex: https://forum.fhem.de/index.php/topic,116747.0.html

Bedeutet aber nicht, dass es nicht sinnvoll wäre, sich mit gewissen "Grundlagen" des Datenflusses in FHEM allgemein mal intensiver einzdenken...

Zitat
Das ist mir auch schon aufgefallen, theoretisch wäre auch der Forenbereich nicht mehr wirklich korrekt.
Würde vorschlagen, wir arbeiten hier noch "deine Nuss" ab, das ist (mehr oder weniger) ein häufigeres MQTT-Thema.

Für den Rest: Bitte erst mal diese sehr umfangreichen Dokumente lesen, die rund um das Thema "verbraucherabhängige Steuerung des Solarstromverbrauchs" vorhanden sind, und dann die Elemente einzeln "abfrühstücken", die ggf. noch offen sind.
Falls zu einzelnen Punkten Fragen sind (auch zu code-Vorschlägen hier), dann entweder "Perl für FHEM-User" oder "Anfängerbereich" wählen, gerne dann mit einem Link aus dem Thread hier (und einen hierher).

Theoretisch könntest du auch verschieben und/oder den Titel ändern, aber zumindest teilweise paßt das ja, und auch "die Nuss" ist ja grade so ein Problemchen.
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files