Hi,
ich habe ein Problem und komme leider nicht auf den Fehler.
Ich möchte einen Wert aus einem Dummy A zu einem Wert in einem Dummy B dazu addieren.
Wie funktioniert das?
Ich habe folgendes DOIF:
(["Antwort"] eq "A")
(
setreading Ergebins ReadingA {(Value("dummy_a:ReadingA")) + (Value("Ergebnis:ReadingA"))},
setreading Ergebnis ReadingB {(Value("dummy_a:ReadingB")) + (Value("Ergebnis:ReadingB"))},
setreading Ergebnis ReadingC {(Value("dummy_a:ReadingC")) + (Value("Ergebnis:ReadingC"))})
Aber irgendwie funktioniert das nicht. Was mache ich falsch?
Danke
Gruss
Dennis
Hallo Dennis,
Genau die selbe Frage mit den selben Voraussetzungen hatten wir letzte oder vorletzte Woche hier schon. Bitte verwende einmal die Suche unterhalb des DOIF Forums.
ok danke. Werde suchen. 8)
Hi,
ich muss doch nochmal hier fragen, oder soll ich lieber im DOIF Forum einen neuen Thread anlegen?
Also ich addiere die Werte so, allerdings passiert da nichts:
setreading Funktion GF {([$DEVICE:GF] + [Funktion:GF])},
setreading Funktion AGT {([$DEVICE:AGT] + [Funktion:AGT])},
setreading Funktion MA {([$DEVICE:MA] + [Funktion:MA])})
Wenn ich so addiere, also ohne die geschweiften Klammern:
setreading Funktion GF ([$DEVICE:GF] + [Funktion:GF]),
setreading Funktion AGT ([$DEVICE:AGT] + [Funktion:AGT]),
setreading Funktion MA ([$DEVICE:MA] + [Funktion:MA]))
dann steht im Ergebnis "(0+1)". Also quasi nicht das Ergebnis sondern der Rechenterm.
Ich glaube ich habe hier nur ein Klammer bzw. Verständnisproblem bei der Addition, oder?
Gruss
Dennis
Kann mir niemand bei meinem Problem helfen? Ich denke es ist nur ein Syntax Problem, aber ich komme nicht drauf:
Im Prinzip mache ich folgende Rechenoperation:
setreading Funktion GF {( id_[$DEVICE:msgPeerId:GF] + [Funktion:GF])}
Ich muss den Wert, der im Reading GF im dummy id_4654984 steht, zum Reading GF im dummy "Funktion" hinzuzählen.
Aber wie greife ich denn von der Syntax her auf das Reading GF im dummy id_4654984 zu?
Denn so wie ich es aktuell habe, kommt ein Syntax Fehler.
Danke
Gruss
Dennis
Hallo Dennis,
laut Doku geht das https://fhem.de/commandref_DE.html#DOIF_Berechnungen_im_Ausfuehrungsteil
Fang einfacher an, erstmal mit festen Werten und arbeite Dich hoch.
Reading GF im dummy id_4654984 -> [id_4654984:GF]
Gruß Otto
Hallo Otto,
mit festen Werten habe ich ja getestet. Das funktioniert wunderbar. Nur sobald ich auf die dynamischen Werte zurückgreife bekomme ich einen Syntaxfehler.
Ab dem id_ können beliebig viele verschiedene Werte stehen. Jedes id_???? steht für ein eigenes dummy. Die Readings der dummys sind aber immer gleich aber mit unterschiedlichen Zahlen gefüllt.
Und diese Werte der Readings will ich in einem Gesamt-Dummy zusammenzählen.
Gruss
Dennis
Das liegt daran das wenn man Werte ein ließt, aus einem Dummy zum Beispiel, diese als String und nicht als Zahl eingelesen werden.
Und es gibt keine Möglichkeit die Werte als Zahl einzulesen?
Es stehen in den Readings nur 0 oder 1 drin. Sonst nichts.
Gruss
Dennis
Dann hat sich doch aber die Frage nach dem Syntax schon geklärt und deine Versuche weiter oben sind zum Teil als sinnlos erkannt?
Es gibt da folgenden Teil in der Doku, Groß und Kleinschreibung ist bei allem (außer in Windows) wichtig!
ZitatIn der Bedingung und im Ausführungsteil werden die Schlüsselwörter $SELF durch den eigenen Namen des DOIF-Moduls, $DEVICE durch das aktuelle Device, $EVENT durch die passende Eventzeile, $EVENTS kommagetrennt durch alle Eventzeilen des Triggers ersetzt.
Entsprechend können Perl-Variablen in der DOIF-Bedingung ausgewertet werden, sie werden in Kleinbuchstaben geschrieben. Sie lauten: $device, $event, $events
Ich versteh noch nicht wie die Namen der Dummys in dein DOIF kommen sollen?
Gruß Otto
Ich denke es liegt an DOIF. Ich müsste das auch erst testen.
Später
[Name:Reading:d] gibt den numerischen Anteil zurück.
ok dann werde ich mal weiter ausholen:
Über Telegram schicken mir verschiedene Benutzer einen Status. Diesen Status der User schreibe ich jeweils in ein eigenes dummy.
Die Telegram ID 5356474 hat ein dummy namens id_5356474 und dort schreibe ich rein, wenn sich dieser User gemeldet hat. Genauso bei allen anderen Teilnehmner dieses telegram bot.
Zusätzlich sind in jedem dummy ein paar Fertigkeiten hinterlegt in Form von 0 oder 1. Wenn in einem Reading "Mechaniker" eine 1 steht, dann hat der User diese Fertigkeit. bei einer 0 eben nicht.
Und jetzt möchte ich unter allen Usern, die sich mit einem bestimmten Status gemeldet haben, die einzelnen Fähigkeiten zusammenzählen in einem extra Gesamt-dummy.
Ich will also zum Schluss in einem Dummy stehen haben, wieviele Mechaniker, wieviele Programmierer usw. sich gemeldet haben.
Es funktioniert bereits, dass sich die Leute erfolgreich melden und der jeweilige Text im jeweiligen dummy landet.
Was nicht funktioniert ist, wenn sich jemand mit OK gemeldet hat, dass seine entsprechenden Fähigkeiten in das Dummy "Funktion" geschrieben werden. Weil ich nicht weiß, wie ich anhand der verschiedenen ID's auf die Readings zugreife. Ich möchte also die Gesamtanzahl der Programmierer und der Mechaniker usw. haben. Als Zahl.
Aktuell sieht mein DOIF so aus:
(["Status:msgPeerId"] and ([?Status:msgText] eq "OK"))
(set id_[$DEVICE:msgPeerId] [$DEVICE:msgText],
setreading Funktion Mechaniker {(( id_[$DEVICE:msgPeerId]:Mechaniker) + [Funktion:Mechaniker])},
setreading Funktion Programmierer {(( id_[$DEVICE:msgPeerId]:Programmierer) + [Funktion:Programmierer])}
Gruss
Dennis
Hi Dennis,
klingt kompliziert und eigentlich will ich den Text nicht komplett verstehen :)
Also wenn das wirklich funktioniert (habe ich nie probiert)
id_[$DEVICE:msgPeerId]
Dann ist das ( id_[$DEVICE:msgPeerId]:Mechaniker) Unfug und müsste so aussehen [id_[$DEVICE:msgPeerId]:Mechaniker:d]
Aber das ist nur aus dem was ich zu wissen glaube hergeleitet. ::)
Ich weiß nicht ob man dort [] schachteln kann, ich weiß auch nicht ob man ReadingsNum() schachteln könnte. Im Zweifel musst Du Perl aufmachen und mit Variablen die einzelne Werte zwischen speichern.
Gruß Otto
Nö, funktioniert leider nicht.
Mal noch anders gefragt:
setreading Funktion Programmierer {(10 + [Funktion:Programmierer])}
Bei diesem Beispiel zählt er mir jeweils 10 zu dem bereits enthaltenen Wert im Reading "Programmierer" hinzu.
Wie ersetze ich jetzt aber die "10" mit dem Wert, der im dummy id_[$DEVICE:msgPeerId] im Reading Programmierer steht? Das ist mein Problem.
Gruss
Dennis
id_[$DEVICE:msgPeerId:GF] so etwas geht nicht. Hinter [$DEVICE:msgPeerId:GF] steckt eine Perlfunktion, da kannst du nicht etwas davor oder dahinter hängen.
Aber wenn ich es so schreibe:
[$DEVICE:msgPeerId:Programmierer]
bekomme ich den Fehler:
ZitatDOIF: unknown expression format: Programmierer
Ich bin kein Perl Programmierer ::) also nur meine Idee von oben umgesetzt. Du könntest bei Dir Teile davon direkt in der Kommandozeile testen.
Für die DEF!
{my $a = ReadingsVal("$device","msgPeerId","");return ReadingsNum("id_".$a,"Mechaniker",0)}
Falls DOIF sowas zulässt sollte der Code oben die 10 ersetzen. Ob das klappt, keine Ahnung.
Gruß Otto
Zitat von: dennis_n am 25 Februar 2018, 18:21:10
Aber wenn ich es so schreibe:
[$DEVICE:msgPeerId:Programmierer]
bekomme ich den Fehler:
Das ist auch einfach Unfug ... an der Stelle geht nicht irgendwas sondern so etwas wie d (Zahl filtern)
ZitatAb featurelevel 5.7 ersetzt das set und setreading Befehl
[device:name] mit dem Wert des Readings, Internals oder Attributes für device, falls sowohl device, als auch Reading, Internal oder Attribut existiert, und nicht leer ist.
Man kann einen der Präfixe r:, i: oder a: verwenden, um die Suche einzuschränken, genau wie im devspec.
Das Suffix :d extrahiert die erste Zahl.
Das Suffix :i extrahiert die erste Zahl als Ganzzahl.
Das Suffix :r<n> extrahiert die erste Zahl, und rundet sie auf <n> Dezimalstellen. Falls <n> fehlt, dann wird auf eine Dezimalstelle gerundet.
Das Suffix :t liefert den Zeitstempel des Readings
Das Suffix :sec liefert Anzahl der Sekunden seit Änderung des Readings.
Beispiel:
set Lamp blink [blinkDummy:number] [r:blinkDummy:duration:d]
Sinnloses Zeug probieren bringt nichts, Du musst schon ein bisschen in die Doku schauen!
Zitat von: dennis_n am 25 Februar 2018, 18:21:10
[$DEVICE:msgPeerId:Programmierer]
Wo hast Du diese Syntax gefunden?
Danke Leute, aber ich bekomme es einfach nicht hin. Auch nach lesen der Doku, beiße ich mir die Zähne daran aus. Ich bin halt kein Programmierer. :'(
Wenn mir das niemand anschaulich erklären kann, muss ich aufgeben.
Ich kann ja verstehen, dass das für jemanden sehr zeitintensiv sein kann, einem Nicht-Programmierer soetwas zu erklären. Aber daher schreibe ich ja auch im Anfängerforum. Ich würde es gerne verstehen.
Speziell für meinen Anwendungsfall mit der Abfrage der unterschidlichen User (z.B. id_7796976) bekomme ich das nicht hin. Mir leuchtet die Syntax einfach nicht ein.
Gruss
Dennis
Moin,
und welchen Fehler bekommst Du bei meinem Code aus #17?
Gruß Otto
Moin Otto,
da bekomme ich keinen Fehler. Das funktioniert. Sorry, ahbe vergessen dazu Rückmeldung zu geben.
Mir geht es allerdings um die Syntax mit dem :d usw. Das verstehe ich einfach nicht und würde es gerne für die Zukunft verstehen. Mir leuchtet die Syntax ja auch ein, wenn ich ein ganz normales Device habe. Sobald ich aber ein Devicenamen aus "id_" und einer belieben Zahl habe, verstehe ich nicht, wie ich das Device anspreche.
Gruss
Dennis
Hi,
du verstehst die klare Aussage von Damian nicht:?
Zitatid_[$DEVICE:msgPeerId:GF] so etwas geht nicht.
Und Du verstehst mein Zitat aus der Doku nicht? Das Du nicht :GF schreiben kannst weil das der Programmierer dort nicht vorgesehen hat und nur ein festgelegtes Set an Parametern gilt?
:o :o :o
Irgendwie versteh ich das jetzt nicht!
Das Du Device Name nach Deinem Konstrukt erzeugst und anschließend nicht weißt wie Du sie ansprichst ist doch selbsterzeugtes Leid? ;D
Und für diesen eigenartig komplizierten Fall hast Du doch sogar eine Lösung, auch wenn die nicht elegant aussieht - oder?
Gruß Otto
Hallo Otto,
natürlich verstehe ich, dass es nciht geht, weil es der Programmierer nicht vorgesehen hat.
Ich hatte Deine Aussage und Deinen verweis auf die Doku allerdings so verstanden, dass es eine elegantere Lösung gibt und nur ich nciht auf die Lösung komme.
Egal, Dein Weg habe ich jetzt übernommen und alles funktioniert. Daher danke ich Dir für Deine Geduld mit mir :-*
Gruss
Dennis
nein, mein letzter Hinweis zur Doku war einfach so gemeint: Es macht keinen Sinn sich einen Syntax der schön und einfach aussieht und an andere Stelle vielleicht sogar so ähnlich aussieht zusammen zu basteln und dann zu wundern, dass es nicht geht. Wenns nicht geh,t muss man in die Doku schauen wie der Syntax wirklich ist.
Hallo Otto,
leider, leider habe ich gerade im Test mit mehreren Personen festgestellt, dass es doch nicht funktioniert wie es soll.
Aktuell sieht es so aus:
setreading Funktion Programmierer {({my $a = ReadingsVal("$device","msgPeerId","");return ReadingsNum("id_".$a,"Programmierer",0)} + [Funktion:Programmierer])},
Was dabei passiert ist, dass die Rückmeldung der einzelnen Personen nicht im dummy Funktion addiert werden, sondern immer mit dem letzten, der sich meldet überschrieben wird.
Wenn sich also jemand meldt, der in seinem id_8789879 dummy Programmierer = 0 stehen hat, dann wird dieser Wert in den dummy Funktion geschrieben und wenn jemand bei id_535363 Programmierer = 1 stehen hat, dann wird dieser Wert in den dummy Funktion geschrieben.
Ich will ja aber die zusammenzählen, die sich mit Programmierer = 1 gemeldet haben.
Gruss
Dennis
Hallo Dennis,
ich weiß nicht genau, was innerhalb eines DOIFs für Schweinereien gehen, aber im setreading funktioniert dein Code nicht.
Du machst quasi {Perl(Rechnen{Perl} + [fhem])} das funktioniert nicht. Da solltest Du eigentlich einen Syntaxfehler bekommen.
Es ist relativ leicht so etwas separat zu testen, da musst Du mal hinkommen. Sonst verstehst Du das nicht!
Also die Idee:Bleib doch einfach innerhalb von Perl.
Was laut Doku geht ist setreading Device reading {Perl}
Wie habe ich getestet? Mit einem dummy wert. Der hat im state ein Zahl. Das folgende Beispiel in der FHEM Kommandozeile gibt einen Fehler innerhalb des Readings zurück!
setreading wert Text_wert {({(my $a=5;;my $b=$a*2;;return $b)} + [wert:state])}
BTW das return ist unnötig, dass braucht man nicht. Schlimmstenfalls stört es sogar! :-[
Was an Varianten geht ist (getestet)setreading wert Text_wert {(my $a=5;;my $b=$a+2)}
setreading wert Text_wert {(my $a=5;;my $b=$a+ReadingsNum("wert","state",0))}
setreading wert Text_wert {(my $a=5;;$a+ReadingsNum("wert","state",0))}
Man kann die letzte Zuweisung offenbar weglassen, der Rückgabewert ist die letzte Operation. (http://perldoc.perl.org/functions/return.html) Wie gesagt, ich probiere auch bloß ...
Also für Dich sollte dies gehen (im DEF Editor einfügen){(my $a = ReadingsVal("$device","msgPeerId","");ReadingsNum("id_".$a,"Programmierer",0) + ReadingsNum("Funktion","Programmierer",0))}
Mir ist die Notwendigkeit der zweiten Klammer () noch nicht ganz klar. Bei den Test in der Kommandozeile ist das Ergebnis ohne Klammer nur die Formel, mit Klammer wird gerechnet und der Wert zurückgegeben.
Gruß Otto
Jetzt funktioniert es bestens, Otto.
Vielen vielen Dank.
Gruss
Dennis