Hauptmenü

get/set im Sekundentakt

Begonnen von crispyduck, 01 November 2017, 07:34:04

Vorheriges Thema - Nächstes Thema

crispyduck

Hallo,

ich möchte die Leistung eines Heizstabes im Sekundentakt an den aktuellen Stromüberschuss im Haus anpassen.

Den Heizstab regle ich über einen Leistungssteller, welcher wiederum über ein SPI Digitalpotentiometer gesteuert wird. Für letzteres hab ich mir ein Modul geschrieben um den Wert des Potis von 0-100% einstellen kann, wobei 0% ein shutdown des Potis ist.

Funktioniert soweit auch alles.

Nun zur eigentlichen Frage, etwas im Sekundentakt zu triggern ist ja nicht gerade ideal für FHEM, daher sollte dies zumindest relativ gut umgesätzt werden.
Ist es in ordnung dies wie folgt komplett in ein DOIF zu packen:

define di_heizstab_regelung
DOIF ([08:00-16:30] and [+1] and fhem ('get Stromzaehler1 Power_Sum__W') < 0)
(IF ([Stromzaehler1:Power_Sum__W] > -2000) (set Poti {([Stromzaehler1:Power_Sum__W]/-20)}) ELSE (set Poti 100))
DOELSEIF ([Poti] ne "shutdown")
(set Poti 0)

attr di_heizstab_regelung do always


Also nur in der Zeit 08:00-16:30 soll jede Sekunde ein get an den Stromzähler geschickt werden und je nach Reading Power_Sum__W bei Überschuss kleiner 2000W (> -2000) der Poti als % von 2000 gesetzt werden, bei Überschuss größer-gleich 2000W wird der Poti auf 100% gesetzt.
Ausserhalb des Zeitraumes oder wenn kein Überschuss bestäht (Power_Sum__W >= 0) soll der Poti wenn nicht ohnehin schon im shutdown auf 0 gesätzt werden.

Funktioniert so Testweise sehr gut, kann man das so lassen, oder würdet ihr mir einen anderen Weg empfählen?

Der DOIF timer [+1] läuft immer, auch wenn es nicht 08:00-16:30 ist, erzäugt dies dann auch Last am System?

Danke,
crispyduck

Damian

Das ist keine gute Lösung. Wenn du noch öfters solche DOIFs baust, wird sich dein FHEM irgendwann mit sich selbst beschäftigen.
Produziert Stromzaehler1 kein Event bei Änderung von Power_Sum__W?
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

crispyduck

Danke, also doch wie schon irgendwie befürchtet.  ???

Naja, könnte dann nur das Modbus Modul so einstellen das es jede Sekunde pollt. Wird dadurch schätze ich mal aber auch nicht besser, das Reading Power_Sum__W wird sich auch dann fast immer ändern.

Hab ja schon überlegt das außerhalb von FHEM zu machen, Problem ist allerdings das FHEM mein Modbus Master ist.

Wie könnte man das besser umsetzen?

Lg,
crispyduck

Damian

Du hast damit meine Frage nicht beantwortet:

Gibt es Events von Power_Sum__W oder nicht?
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

crispyduck

Sorry, nein gibt es aktuell nicht. Könnte nur ein event-on-Change setzen.

Lg,
crispyduck

Damian

Wenn das Modul sonst keine Events produziert, dann kann man nur pollen. Wenn man mit einer längeren Reaktionszeit leben kann, kann man ruhig das Abfrageintervall höher setzen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

crispyduck

Sorry, verstehe jetzt nicht ganz wie es gemeint ist.

Heißt, ich kann es in FHEM eigentlich nicht anders oder besser lösen? Kann es auf ein paar Sekunden rauf drehen, aber viel größer sollte der Intervall nicht sein.

Sonst irgend einen Vorschlag wie ich das umsetzen könnte?

Im schlimmsten Fall dachte ich lasse die FHEM Installation auf der Raspi nur für die Modbus Kommunikation + Regelung des Heizstabes, und mache eine zweite Installation auf der NAS.

Danke,crispyduck

crispyduck

#7
Hallo,

habe das Ganze jetzt mit nur ein paar anderen Sachen auf einer eigenen FHEM Instanz am laufen. Das ganze funktioniert mit folgendem DOIF recht gut:

([{sunrise('REAL')}-{sunset('REAL',-1000)}] and [+2] and ((fhem ("get StromGesamt Power_Sum__W"))-[HeizstabPower:state])<0) (IF(([StromGesamt Power_Sum__W]-[HeizstabPower:state])<-1850)(set Poti pot1 100, set HeizstabPower 1850) ELSE(set Poti pot1 {(([StromGesamt:Power_Sum__W]-[HeizstabPower:state])/-18.5)}, set HeizstabPower {([StromGesamt:Power_Sum__W]-[HeizstabPower:state])})) DOELSEIF([Poti:pot1] ne 0)(set Poti pot1 0, set HeizstabPower 0)

Wie schon mal geschrieben wird dabei ein Heizstab über einen linearen Digipot "Poti" in % geregelt. "StromGesamt Power_Sum__W" hängt in Serie zum EVU Zähler, zählt somit auch den Heizstab mit. Beim setzen des Digipots wird auch immer [HeizstabPower:state] auf den ungefähren aktuellen Power Wert gesetzt.
Da "StromGesamt Power_Sum__W" ja den Heizstab mit zählt ist die Leistung die insgesamt am Heizstab zu verbraten ist [StromGesamt Power_Sum__W]-[HeizstabPower:state].

Bei dem DOIF wird jetzt bis zu 4 mal [StromGesamt Power_Sum__W]-[HeizstabPower:state] berechnet. lässt sich das auch irgendwie in der Bedingung in eine Variable speichern? Würde das überhaupt sinn machen?

Funktionieren tut es so ja, überlege nur ob man das optimieren kann/soll. Oder wäre es überhaupt sinnvoll dies in eine my_Utils Funktion auszulagern und nur zeitgesteuert mit DOIF abzufragen?

Danke,
crispyduck

abc2006

#8

Zitatlässt sich das auch irgendwie in der Bedingung in eine Variable speicher

ja:

setreading $SELF Differenz [StromGesamt:Power_Sum__W]-[HeizstabPower:state]

sollte gehen. Zugreifen dann mit [$SELF:Differenz]. Ob das allerdings weniger Rechenaufwand ist, der sich bemerkbar macht ... kA.

imho: wenns für dich so läuft, ohne dass Hänger auftreten, ists doch okay.

edit: Syntax

Grüße,
Stephan
FHEM nightly auf Intel Atom (lubuntu) mit VDSL 50000 ;-)
Nutze zur Zeit OneWire und KNX

Damian

Zitat von: abc2006 am 12 Dezember 2017, 09:11:59

ja:

setreading $SELF Differenz [StromGesamt Power_Sum__W]-[HeizstabPower:state]

sollte gehen. Zugreifen dann mit [$SELF:Differenz]. Ob das allerdings weniger Rechenaufwand ist, der sich bemerkbar macht ... kA.

imho: wenns für dich so läuft, ohne dass Hänger auftreten, ists doch okay.

Grüße,
Stephan

Was soll denn [StromGesamt Power_Sum__W] sein? Wenn Power_Sum__W ein Reading ist, dann muss das [StromGesamt:Power_Sum__W] heißen.


[/([{sunrise('REAL')}-{sunset('REAL',-1000)}] and [+2] and ([StromGesamt:Power_Sum__W]-[HeizstabPower:state])<0)


Wenn [StromGesamt:Power_Sum__W] und [HeizstabPower:state] ordentliche Events produzieren, dann sollte das Pollen mit  [+2] überflüssig sein.

also:

[/([{sunrise('REAL')}-{sunset('REAL',-1000)}] and ([StromGesamt:Power_Sum__W]-[HeizstabPower:state])<0)

setreading erzeugt zusätzliche Events.

Wenn schon, dann würde ich DOIF_Readings (in der aktuellen DOIF-Version) empfehlen, die erzeugen keine zusätzlichen Events und triggern dennoch das DOIF

hier z. B.

attr <doifname> DOIF_Readings diff:[StromGesamt:Power_Sum__W]-[HeizstabPower:state]


und dann

[/([{sunrise('REAL')}-{sunset('REAL',-1000)}] and [$SELF:diff] < 0) (set ... )


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

crispyduck

Danke!

DOIF_Readings kannte ich noch gar nicht.

Da
Zitat von: Damian am 12 Dezember 2017, 09:58:32
hier z. B.

attr <doifname> DOIF_Readings diff:[StromGesamt:Power_Sum__W]-[HeizstabPower:state]


und dann

[/([{sunrise('REAL')}-{sunset('REAL',-1000)}] and [$SELF:diff] < 0) (set ... )


Das ist doch genial und eine schöne Lösung.  :D

Problem ist aber das [StromGesamt:Power_Sum__W] inkl. vieler anderer Werte vom Device StromGesamt nur alle 5 Minuten gepollt und das Reading upgedated wird.
Daher das [+2] und ein fhem ("get StromGesamt Power_Sum__W") in der Bedingung:

([{sunrise('REAL')}-{sunset('REAL',-1000)}] and [+2] and ((fhem ("get StromGesamt Power_Sum__W"))-[HeizstabPower:state])<0)

Ich weiß das ist nicht schön, aber mir fällt irgendwie nichts besseres ein um unter Tags nur den Wert für Power_Sum__W ständig zu pollen.

danke,
crispyduck

Damian

Zitat von: crispyduck am 12 Dezember 2017, 10:23:19

Problem ist aber das [StromGesamt:Power_Sum__W] inkl. vieler anderer Werte vom Device StromGesamt nur alle 5 Minuten gepollt und das Reading upgedated wird.
Daher das [+2] und ein fhem ("get StromGesamt Power_Sum__W") in der Bedingung:

([{sunrise('REAL')}-{sunset('REAL',-1000)}] and [+2] and ((fhem ("get StromGesamt Power_Sum__W"))-[HeizstabPower:state])<0)

Ich weiß das ist nicht schön, aber mir fällt irgendwie nichts besseres ein um unter Tags nur den Wert für Power_Sum__W ständig zu pollen.

danke,
crispyduck

Na ja, wenn sie sich nur alle 5 Minuten ändern, dann nutzt dir das Pollen auch nichts, da kannst du 100 mal in der Sekunde die gleiche Differenz abfragen, eine Änderung kann es aber erst nach 5 Minuten geben.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

crispyduck

Sorry, hab mich schlecht ausgedrückt, mit einem fhem(get StromGesamt Power_Sum__W) wird ein get am device StromGesamt ausgeführt welches dann nur den aktuellen Wert für Power_Sum__W vom Stromzähler pollt und in das Reading [StromGesamt:Power_Sum__W] schreibt.

Der Stromzähler selbst misst die Werte im Sekundentakt, und da dies die momentane Leistungsaufnahme vom gesamten Haus weniger aktuelle PV Leistung ist ändert sich das auch eigentlich immer.

Muss also um den aktuellen Wert zu erhalten und das Reading Power_Sum__W upzudaten immer ein get am device StromGesamt ausführen.

Das könnte natürlich auch ein separates AT machen,... aber würde das ja gerne in einem DOIF unterbringen, daher das fhem(get StromGesamt Power_Sum__W) in der Bedingung.

lg,
crispyduck

crispyduck

Habe gerade upgedated und spiele jetzt mit dem neuen Attribut.

und wundere mich gerade über ein Verhalten. Habe folgendes DOIF:

define di_test ([+2] and fhem ("get StromGesamt Power_Sum__W") and ([$SELF:diff] > 0) ) (set test [$SELF:diff])

attr di_test DOIF_Readings diff:[StromGesamt:Power_Sum__W]-[HeizstabPower:state]
attr di_test do always


dabei ändert sich zwar alle 2 Sekunden das Reading [StromGesamt:Power_Sum__W, aber [$SELF:diff] ändert sich nicht.
Sobald aber in FHEM ein "get StromGesamt Power_Sum__W" ausführe oder es ein anderes device ausgeführt wird, ändert sich auch [$SELF:diff].
Events werden beide Male generiert.

Verstehe nicht ganz wieso. Wann wird ein DOIF_Readings upgedated und warum in dem Fall wo fhem ("get StromGesamt Power_Sum__W") in der Bedingung de DOIFs steht?

Danke,
crispyduck

Wo

Damian

fhem ("get StromGesamt Power_Sum__W")  würde ich eher im Ausführungsteil und nicht in der Bedingung ausführen. Du erzeugt ein Event auf das du im gleichen Modul reagieren willst - das gibt Rekursionen, die das Modul unterbindet. Daher solltest du das zyklische Abfragen und setzen des Readings von der restlichen Logik durch getrenntes DOIF entkoppeln.

DOIF_Readings erzeugen außerdem keine Events, wenn sich etwas ändert, dann sieht man es nicht direkt im Browser, man muss schon mal ein Refresh F5 des Browser machen, um zu sehen, ob sich das Reading wirklich geändert hat oder nicht.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

crispyduck

Danke! Sage ja es ist nicht schön, aber funktioniert.  ;)

Nein, werde das nochmal überdenken, vielleicht finde ich doch einen anderen Lösungsweg, eventuell mach ich ein eigenes device das mir nur den einen Wert im Sekundentakt abfragt und eben in der Nacht disabled wird.

Aber 1000 Dank für die Info mit dem neuen Attribut, bin dadurch erst auf uiTable aufmerksam geworden.
Wollte jetzt über Weihnachten mit Tablet UI anfangen, glaube das lasse ich jetzt und mach es mit deinem Modul!

Das schaut ja spitze aus! Nochmal 1000 Dank für das Modul!  :D

@DOIF_Readings, ist zwar auch nicht wirklich sinnvoll was ich da probiere, aber hätte mir bei folgendem erwartet das es hoch zählt:

define di_test DOIF ([+2]) (set test [$SELF:add])

attr di_test DOIF_Readings add:[test:state]+1
attr di_test do always


Tut es aber nicht, sondern "add" wird nur neu berechnet wenn "test" von außerhalb des DOIFs geändert wird.

Oder darf man soetwas einfach gar nicht machen da je
ZitatÄnderungen dieser Readings triggern allerdings das eigene DOIF-Modul, wenn sich deren Inhalt ändert.

Danke,
crispyduck

Damian

Wozu so kompliziert. Ursache und Wirkung sollte nicht im gleichen Modul stattfinden - Rekursionsgefahr. Was geht: externes Reading->DOIF_Reading->DOIF_Reading in der Bedingung

define di_test DOIF ([+2]) (set test {([test]+1)})

attr di_test do always


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

crispyduck

Danke, das ist eh klar. Hab mich jetzt nur bisschen mit dem neuen attribut gespielt, und da ist mir aufgefallen das eben die Berechnung im DOIF_Readings nicht upgedated wird wenn eines der Readings der Berechnung vom DOIF selbst geändert wurde.

Das add:[test:state]+1 war jetzt nur ein einfaches beispiel.

Heißt also man sollte im Ausführungsteil des DOIFs keine Readings ändern die im selben DOIF zur Berechnung eines DOIF_Readings genutzt werden.
Dachte bei Rekursionsgefahr also bei Ursache und Wirkung nur an Bedingung und Ausführungsteil.

Das DOIF_Readings wird also nur berechnet wenn der trigger/die Reading Änderung von ausserhalb des DOIFs kommt und nicht durch das DOIF selbst.

Idee war das attribut DOIF_Readings für ein DOIF zu verwenden welches zu einer definierten Zeit eine mehrfach verwendete Berechnung nutzt in welche auch das Ergebnis des letzten DOIF aufrufes mit einfließen soll.
Das DOIF_Readings würde dabei nicht upgedated werden wenn sich nur das Reading geändert hat welches durch die letzte DOIF ausführung gesetzt wurde.

Vereinfacht dargestellt dachte ich das man mit dem neuen attr aus:

define di_test DOIF ([+2]) (set test {([test:state]+[test1:state])})
attr di_test do always


das nachen könnte:

define di_test DOIF ([+2]) (set test [$SELF:add])
attr di_test DOIF_Readings add:[test:state]+[test1:state]
attr di_test do always


Das klappt so dann aber nicht, wenn sich [test1:state] nicht verändert hat.

Lg
crispyduck

Damian

#18
Zitat von: crispyduck am 12 Dezember 2017, 19:57:40

define di_test DOIF ([+2]) (set test [$SELF:add])
attr di_test DOIF_Readings add:[test:state]+[test1:state]
attr di_test do always


Das klappt so dann aber nicht, wenn sich [test1:state] nicht verändert hat.

Lg
crispyduck

Wie schon geschrieben, sind DOIF_Readings dazu gedacht Berechnungen durchzuführen, um deren Ergebnis in der DOIF-Bedingung bzw. in uiTable und sogar im state-Attribut zu nutzen und nicht umgekehrt. Deswegen reagieren sie nicht auf Veränderungen im Ausführungsteil, das braucht man auch nicht, da man im Ausführungsteil per setreading seine eigenen Readings berechnen und setzen kann, hier in deinem Beispiel:

define di_test DOIF ([+2]) (setreading $SELF add {([test:state]+[test1:state])})
attr di_test do always
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

crispyduck

#19
Danke, alles klar. Einfach nur gut wenn man weiß was man machen kann und was man nicht machen sollte.  ;)

Zitat von: Damian am 12 Dezember 2017, 22:00:12
Beispiel:

define di_test DOIF ([+2]) (setreading $SELF add {([test:state]+[test1:state])})
attr di_test do always


Wenn man die selbe Berechnung aber auch schon in der Bedingung braucht muss sie zumindest zwei mal berechnet werden, oder kann man das auch schon irgendwie in der Bedingung in eine Variable schreiben?
Folgendes z.B., immer wieder die gleiche (vereinfachte) Berechnung [test:state]+[test1:state]
define di_test DOIF ([+2] and ([test:state]+[test1:state]) > 5) (set test {([test:state]+[test1:state])}) DOELSEIF (([test:state]+[test1:state]) < 0) (set test {([test:state]+[test1:state])-5)})......
attr di_test do always


Damian

Die Berechnung werden in Perl und im Speicher ausgeführt, daher von der Performance unkritisch. Gleiche Variablen zwischen Bedingung und Ausführungsteil gibt es nicht.

Wenn test und test1 extern sind (keine eignen Readings wären), dann wäre DOIF_Readings dafür prädestiniert, ansonsten gibt es auch UserReadings, die erzeugen allerdings Events und das kostet mehr Performance als die gleichen Readings im DOIF mehrfach anzugeben.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

crispyduck

Herzlichen Dank für deine Antwort. Sorry für die späte Antwort, aber habe leider keine Benachrichtigung erhalten.

Dank deinen Antworten habe ich mich jetzt erst mehr mit den events meines systems auseinander gesetzt und auch einige eingespart.

Lg
Andi