Hallo eine Frage, wie umgehe ich diese Warnung?
Ich habe einen ein JsonMod, das ich zyklisch auslese, und per notify hänge ich dort auf einem Wert.
In dem Notify führe ich dann setreading auf das Device aus.
So sieht das notify aus
define awattar.notify notify awattar:period:.* { awattar_calc() }
attr awattar.notify room PV
# DEF awattar:period:.* { awattar_calc() }
# FUUID 63b30b0f-f33f-1e88-6be6-ccc99f004ba38835
# FVERSION 91_notify.pm:0.258880/2022-03-27
# NAME awattar.notify
# NOTIFYDEV awattar
# NR 398
# NTFY_ORDER 50-awattar.notify
# REGEXP awattar:period:.*
# STATE 2023-11-14 14:30:00
# TRIGGERTIME 1699968600.63273
# TYPE notify
# READINGS:
# 2023-10-28 12:11:24 state active
# 2023-11-14 14:30:00 triggeredByDev awattar
# 2023-11-14 14:30:00 triggeredByEvent period: 1699966800000
#
setstate awattar.notify 2023-11-14 14:30:00
setstate awattar.notify 2023-10-28 12:11:24 state active
setstate awattar.notify 2023-11-14 14:30:00 triggeredByDev awattar
setstate awattar.notify 2023-11-14 14:30:00 triggeredByEvent period: 1699966800000
im code was da ausgeführt ist steht dann ein
fhem ("setreading awattar todayPriceAvg ".($todaySum/$todayCount));
fhem ("setreading awattar minPrice ".$minPrice." @ ".$minPriceAt." Tomorrow ".$minPriceTomorrow);
was soll ich anders machen?
Zitatfhem ("sleep 0.1; setreading awattar todayPriceAvg ".($todaySum/$todayCount));
Ok danke werde es so einbauen.
Eine Frage noch - ist das DIE absolut richtige Lösung wie man so was macht.
(Ein sleep hat für mich immer den Beigeschmack das es eine Hilfslösung ist)
Aber auf jeden Fall passt es mal so - nur falls ich mal Zeit habe das schöner zu machen wäre ein Tipp wie man das dann richtig macht noch gut falls es das gibt und nicht eh das sleep das richtige ist :D
Ich würde userReadings in den Raum werfen...
Dein Konstrukt braucht ja das sleep nur, weil fhem (zurecht) verhindert, dass in/aus einem notify das durch einen Event eines Devices GENAU bei DIESEM Device ein Reading setzt, was ja (potentiell) wieder das notify triggern kann -> Loop...
Da du ja in deinem notify Readings genau des Devices setzt/setzen willst, worauf das notify reagiert (wenn, zum "Glück" auch andere Readings! Weil sonst würdest du selbst mit sleep eben genau eine Loop basteln) ist doch ein userReadings genau passend?
Und du sparst dir ein zusätzliches Device: das notify :)
Gruß, Joachim
Meine Idee war halt folgende, ich haben einen Intervall beim JsonMod von 30 Minuten einsgestellt, dh, ich bekomme alle 30 Minuten Daten.
Jedes mal wenn er mir die Daten liefert da habe ich ja leider nur rausgefunden das ich mich auf einen Wert per notify hänge der da immer daher kommt, dann muss ich die Daten neu rechnen was eine etwas komplizierte Berechnung ist.
Wenn ich diese komplizierte Berechnung in ein Userreading setze dann rechnet er mir das ja viel zu oft aus oder?
Ich könnte sonst auch einen Timer setzen der mir alle 30 Minuten aber eben 1 Minute oder 2 Minuten später dann das script anwirft - finde ich eben auch nicht so ideal.
Alternativ könnte ich auch im Notify von dem einen Wert, einen at erzeugen der dann in 1 Sekunde das Script startet.
Zitat von: sn0000py am 17 November 2023, 10:29:46Eine Frage noch - ist das DIE absolut richtige Lösung wie man so was macht.
(Ein sleep hat für mich immer den Beigeschmack das es eine Hilfslösung ist)
das von mir vorgeschlagene sleep ist ein "normaler" fhem-cmd, kein voodoo. ;)
siehe commandref:
Zitatsleep <sec|timespec|regex> [<id>] [quiet]
sleep followed by another command is comparable to a nameless at or notify, it executes the following commands after waiting for the specified time or an event matching <regex>. The delay can be given
in seconds, with millisecond accuracy, as you can specify decimal places,
as a timespec (HH:MM or HH:MM:SS or {perlfunc})
or as a regex (devicename or devicename:event)
A sleep with an <id> will replace a sleep with the same <id> and can be canceled by cancel. When called in a notify/at/etc, then nonempty return values of the following commands are logged to the global logfile with loglevel 2.
If quiet is specified, then skip this logging.
Example:
define n3 notify btn3.* set lamp on;;sleep 1.5;;set lamp off
define a3 at +*00:05 set Windsensor 1w_measure;; sleep 2 quiet;; get Windsensor 1w_temp
Note: a sleep not followed by any command will block FHEM, is deprecated, and it issues a WARNING in the FHEM log.
@Snoopy Ich habe Deinen Beitrag #4 jetzt mehrfach gelesen ich verstehe nicht was Du damit sagen willst. :)
Aber: Ein userReadings setzt Du mit einem Trigger auf ein Reading in deinem jsonmod Device welches genau in diesem 30 Minuten Takt getriggert wird. Dann wird das userReadings genau einmal in 30 Minuten gerechnet.
Also in etwa so
attr awattar userReadings minPrice:period:.* { awattar_calc(OHNE das Setreading inside SONDERN mit return Wert ) }
Nachtrag:
Zitat von: sn0000py am 17 November 2023, 14:11:42einen at erzeugen der dann in 1 Sekunde das Script startet.
genau das macht ein FHEM Sleep ;D
Zitat von: sn0000py am 17 November 2023, 14:11:42Wenn ich diese komplizierte Berechnung in ein Userreading setze dann rechnet er mir das ja viel zu oft aus oder?
Wie Otto schon geschrieben hat: denselben Trigger nehmen, wie auch das notify, dann findet die "Berechnung" GEANU SO OFT statt wie mit dem notify 8)
Zitat von: sn0000py am 17 November 2023, 14:11:42Alternativ könnte ich auch im Notify von dem einen Wert, einen at erzeugen der dann in 1 Sekunde das Script startet.
Man kann sich auch mit dem recheten großen Zeh im linken Ohr kratzen ;) :D
(wenn man Schlangenmensch ist :D )
Gruß, Joachim
Zitat von: Otto123 am 17 November 2023, 14:44:20@Snoopy Ich habe Deinen Beitrag #4 jetzt mehrfach gelesen ich verstehe nicht was Du damit sagen willst. :)
Aber: Ein userReadings setzt Du mit einem Trigger auf ein Reading in deinem jsonmod Device welches genau in diesem 30 Minuten Takt getriggert wird. Dann wird das userReadings genau einmal in 30 Minuten gerechnet.
Also in etwa so
attr awattar userReadings minPrice:period:.* { awattar_calc(OHNE das Setreading inside SONDERN mit return Wert ) }
Oh okay, das mit dem Trigger kannte ich noch nicht.
Aber ich muss dann trotzdem für jedes userReading dann einmal das awattar_calc durchlaufen lassen, und jedesmal einen anderen wert zurückgeben.
dh wenn ich 5 solcher userReadings dann habe wird das awattar_calc dann aber 5 mal ausgeführt - oder?
Das was dann noch erschwerend dazu kommt ist, das wenn eine gewisse Bedingung in der Berechnung vorkommt mehrere userreadings gesetzt werden.
also timer_00_00 bis timer_00_23 und timer_01_00 bis timer_00_23
Ich könnte sonst die userreadings auch in ein anders Device dummy Device schreiben sann sollte ich diese "Probleme" auch nicht mehr haben.
Und nein bin kein Schlangenmensch habe es mit dem großen Zeh probiert funktioniert nicht, nehme nun die Finger :D - aber da ist es leichter das rauszufinden :D
Dein notify wird doch, wenn der Trigger passt auch nur dann ausgeführt, wenn ein passender Event kommt -> genauso userReadings...
Pro Reading das du haben willst gibt es ein KOMMASEPARIERTES "Pärchen" aus NeuerReadingname:Trigger {"Berechnung"}
EDIT: es heißt ja userReadings
Wenn deine Trigger jeweils passen, wird auch nur dann "berechnet", wie beim notify auch...
Dummy: ist ja wieder mit dem großen Zeh kratzen...
...Ausnahmw: dummy funktioniert ;)
Gruß, Joachim
Zitat von: sn0000py am 17 November 2023, 16:14:26Ich könnte sonst die userreadings auch in ein anders Device dummy Device schreiben sann sollte ich diese "Probleme" auch nicht mehr haben.
klingt für mich nach der kleinsten Änderung :) gegenüber Deiner jetzigen Lösung.
Kann JsonMod das nicht alles direkt in der readingList abhandeln? So als return mit einem Array of Hashes aus Readings und Werten? Ich meine bei MQTT2 Devices geht sowas.
Ich kenne die Komplexität Deiner Berechnung nicht und ob es wirklich ein Performance Problem geben kann. Ich mache an andere Stelle sowas wo ich alles in eine Perl Sub packe, die wird mit Parameter aufgerufen und je nach Parameter kommt ein Wert zurück. Da pflegt man die Readingnamen in FHEM und die Logik in der Sub.
Ok danke, werde es in ein eigenes Dummy Device nun schreiben.
Ob die Berechnung zu komplex ist vermutlich schon (aber nicht weil es so komplex sein muss sondern weil mein Programmierstil zu umständlich ist)
Für mich wäre es halt einfach logischer ein 100% definiertes Notify zu bekommen, wenn das JsonMod fertig ist (gibt es ja leider nicht muss da auf ein Reading hängen, das jedesmal drinnen ist)
Und genau dann alle Werte durchrechnen was zu rechnen sind - weil genau dann hab ich neue Werte und die anderen Werte können sich geändert haben und da rechne ich dann.
Ich verstehe ja immer noch nicht warum du denkst ein notify und dann in ein anderes Device schreiben wäre einfacher als das ganze in userReadings zu packen...
Sei's drum...
Viel Erfolg, Joachim
vermutlich weil ich entweder noch einen Denkfehler habe oder das userreadings noch nicht ganz verstanden habe oder wie gesagt immer noch versuche mit dem großen Zeh im Ohr zu kratzen ;)
Das ist der vereinfachte Code der nach einem erfolgreichen JsonMod Abfrage ausgeführt wird
sub awattar_calc() {
for(my $i = 0; $i <= 48; $i++) {
my $thisSettValue = "Akku=$akkuState,Boiler=$setBoiler";
my $thisSettName = sprintf("sett_%02d", $i);
fhem ("setreading awattar $thisSettName $thisSettValue");
}
fhem ("setreading awattar todayPriceAvg ".($todaySum/$todayCount));
fhem ("setreading awattar minPrice ".$minPrice." @ ".$minPriceAt." Tomorrow ".$minPriceTomorrow);
}
dh ich würde da dann 50 userreadings anlegen, und dann bei jedem userreadings die awattar_calc hinterlegen mit einem index - und aufgrund diesem index gibt die awattar_calc dann jeweils einen anderen Wert zurück?
Das was du jetzt hier postest weicht aber schon (total) von der eingangs gestellten Frage bzw. dem Input dort ab!
Oben/zu Beginn ging es um 2 Berechnungen bzw. 2 setreadings -> 2 userReadings und fertig.
Das hier ist (nat.) ganz was anderes...
Gruß, Joachim
Mal ein ganz anderer Ansatz.
Du könntest auch in einer at-Definition einfach nur die Funktion awattar_calc aufrufen, in der du aber den Json dann mit HttpUtils_NonblockingGet holst, aus dem Json liest die Werte, die Du für deine Berechnungen brauchst und ergänzt diese Name/Wert Paare dann einfach in dem Json. Danach übergibst diesen "neuen" Json der Funktion json2reading und alles ist tutti und einem Device umgesetzt.
Zitat von: sn0000py am 19 November 2023, 12:42:23Für mich wäre es halt einfach logischer ein 100% definiertes Notify zu bekommen, wenn das JsonMod fertig ist
Naja, ich würde vermuten es ist aber genau so: wenn jsmod fertig ist werden die Readings geschrieben. Und ja, einen state schreibt es offenbar nicht. Kannst ja mal einen Vorschlag machen herrmannj machen.
Du kannst das schon so machen mit Deinen Readings, Du musst halt im Hinterkopf haben: schreiben ins auslösenden Device geht nur verzögert wegen der Gefahr der Rekursion (und Endlosschleife)
Du brauchst aber mMn nicht unbedingt 3 oder mehr Devices: entweder triggerst Du ein notify und schreibst die Readings in Dein jsonmod Device oder Du triggerst ein userReadings und schreibst die Readings in einen Dummy.
userReadings ist wie ein notify im eigenen Device, was Du im Ausführungsteil machen kannst ist mit dem notify gleich. Was Du zurückgibst ist wieder was anderes. Ich meine damit: Du musst nicht 50 Readings über separate Definitionen machen - Du darfst Dich nur nicht selbst dabei überholen. :)
Oder wie Tom sagt einfach in einem at alles triggern, daran habe ich vorhin auch gedacht.