FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: wollik am 17 Januar 2024, 16:22:36

Titel: Dummy State via Ssystemcommand setzen
Beitrag von: wollik am 17 Januar 2024, 16:22:36
Hallo ins Forum,
ich bekomme es einfach nicht hin den State meines dummys EV_Load als Ausgabewert eines Scripts auf der fhem Commandozeile zu setzen.

defmod EV_Load dummy
attr EV_Load icon wallbox

mit: set EV_Load 1234
wird der State auf 1234 gesetzt.

mit: set EV_Load { .... }
wird immer dieser Befehl in den State geschrieben, nicht aber der Rückgabewert was in den Klammern gemacht wird.
Weder mit fhem, Backtricks, System noch mit qx funktioniert das;(

Von außen (einem anderen Rechner), kann ich diesen State des EV_Load dummies via wget setzen.
Aber ich brauche einen Weg um das intern in fhem setzen zu können indem ich einen Befehl via BASH ausführe und den Rückgabewert dann zum Setzen verwende.
Wenn ich den curl Befehl im fhem + Fenster ausführe wird der Rückgabewert richtig angezeigt.

Mein Ziel ist, über curl Aufrufe, Werte abzuholen und in Fhem Variablen zu schreiben.
Ich kann das natürlich Alles in der Bash erledigen, aber wollte das mit Fhem lösen.

Bitte hat jemand hierzu eine Idee.

Viele Grüße
wollik

 








Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: Otto123 am 17 Januar 2024, 16:42:41
Hallo Wollik,
Zitat von: wollik am 17 Januar 2024, 16:22:36mit: set EV_Load { .... }
mit set EV_Load {( ... )} wird es klappen ;)
Siehe doku https://fhem.de/commandref_modular_DE.html#set

Aber qx() wird das System blockieren für die Zeitdauer der Ausführung.
Zitat von: wollik am 17 Januar 2024, 16:22:36über curl Aufrufe, Werte abzuholen und in Fhem Variablen zu schreiben.
Dafür geht auch ein Perl Kommando aus FHEM: https://wiki.fhem.de/wiki/HttpUtils


Gruß Otto
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: Wernieman am 17 Januar 2024, 16:48:37
Anstatt Curl kannst Du auch mit FHEM Bordmitteln arbeiten.
Stichworte:
https://wiki.fhem.de/wiki/HTTPMOD (https://wiki.fhem.de/wiki/HTTPMOD)
https://wiki.fhem.de/wiki/HttpUtils (https://wiki.fhem.de/wiki/HttpUtils)

Ansonsten ... in Perl den Wert des externen Scriptes ermitteln und mit Bordmitteln reinschreiben. Edit: Siehe auch Beitrag von @Otto. ABER .. die Scripte blockieren so lange FHEM, wie sie laufen, denn FHEM ist nur single-Threaded. Deshalb ist es besser, das Script "non-Blocking" mit "" laufen zu lassen und im Script die Rückgabewerte zu FHEM zu puschen. Wie Du es z.B. bei anderen "externen Scripten" gelöst hast. Alternativ zu wget/curl auch gerne per telnet/telnet-ssl. Siehe Doku (und diverse Threads im Forum)
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: wollik am 18 Januar 2024, 21:12:32
Hallo Otto, hallo Wernieman,
D A N K E mit den runden Klammern funktioniert es jetzt!
Leider bekomme ich keinen Eintrag ins Log obwohl sich der Wert des Dummies nach dem curl Befehl geändert hat.

Von http bin ich weg, da das Rückgabeformat json ist und ich noch filtern muß.

Das habe ich jetzt in eine doif Anweisung gehängt, die nach einem anderen Dummywert zeitgesteuert ausgeführt wird. Auch von der doif Anweisung bekomme ich keinen Logeintrag ;(
Bitte wie könnte ich einen Logeintrag erzeugen, wenn sich der Dummywert ändert, oder wenn die doif Anweisung ausgrführt wird?

Viele Grüße
wollik



 

Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: Wernieman am 18 Januar 2024, 21:42:21
Wie hast Du das Logdefice definiert?
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: wollik am 19 Januar 2024, 17:27:54
Hallo Wernieman,
ich will in kein extra Log schreiben, sondern in das Defaultlog, in dem alle FHEM Events landen.

Viele Grüße
wollik
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: Otto123 am 19 Januar 2024, 18:05:40
Hi,

set Befehle werden aber mit verbose level 3 ins FHEM Log geschrieben.

Hast Du verbose irgendwie auf anderem Level?

Gruß Otto
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: wollik am 22 Januar 2024, 21:48:58
Hallo Otto,
ich habe den globalen Wert für verbose auf 3 was der Default sein müßte.

Viele Grüße
wollik
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: betateilchen am 22 Januar 2024, 21:53:43
Ist das nicht wieder mal alles viel zu kompliziert gedacht?

Rückgabewert aus bash in json?

Warum packst Du das nicht einfach in ein JsonMod device? Da kann man seit einiger Zeit auch shell-scripts als Quelle angeben und das json aus dem Ergebnis direkt weiterverarbeiten lassen.
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: Otto123 am 22 Januar 2024, 22:04:20
Zitat von: wollik am 22 Januar 2024, 21:48:58ich habe den globalen Wert für verbose auf 3 was der Default sein müßte.
wusste ich nicht, wenn Du den Dummy set loggen willst, musst Du bei ihm (also nicht global) verbose 4 einstellen.
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: wollik am 24 Januar 2024, 12:38:01
Hallo Otto,
ich habe mir eine zweite Fhem Instanz eingreichtet um nur die DOIF's zu Testen.
Also das Loggen funktioniert auch mit dem Defaultwert verbose=3. Ich hatte nur keine Einträge, weil ich
das DOIF mit dem Zeitinterval nicht auf:  do allways  gesetzt hatte.
Jetzt wird das curl regelmäßig gestartet und die Updates der gesetzten Werte erscheinen im Log.

D A N K E
wollik
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: wollik am 24 Januar 2024, 16:56:30
Hallo Otto,
bitte hättest Du noch ein Beispiel, wie ich in einem DOIF auch if, elsif und else Abfragen verwenden kann?
Leider komme ich mit der Syntax nicht hin, ich bekomme immer den Fehler:
right bracket without left bracket
Bei diesem DEF:
([+[Check_Interval]]) (set Conn 1,IF ([Conn] eq "1"){(set My_Value 400)IF ([My_Value] gt "200"){(set Check_Interval 120)}ELSE {(set Check_Interval 300)}},set Min_Value 123)

Mit Umbrüchen zur besseren Ansicht:
defmod Get_Conn DOIF ([+[Check_Interval]])
   (set Conn 1,
   IF ([Conn] eq "1"){
      set My_Value 400
      IF ([My_Value] gt "200"){
         (set Check_Interval 120)}
      ELSE {(set Check_Interval 300)
      }
   }
   ,set Min_Val 123)
 


Vermutlich verwende ich die if's und die Klammern falsch und komme nach sehr vielen Versuchen hiermit nicht weiter, bitte hättest Du dazu eine Idee?

Viele Grüße
wollik




Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: Otto123 am 24 Januar 2024, 19:10:36
Hi,
Zitat von: wollik am 24 Januar 2024, 16:56:30Vermutlich verwende ich die if's und die Klammern falsch und komme nach sehr vielen Versuchen hiermit nicht weiter, bitte hättest Du dazu eine Idee?
Du verwechselst primär Perl if (Bedingung) {Perl Befehle} else {Perl Befehle}[/font] mit FHEM IF(Bedingung) (FHEM Befehle) ELSE (FHEM Befehle)

(set Conn 1,
  IF ([Conn] eq "1") (
    set My_Value 400,
    IF ([My_Value] gt "200") (set Check_Interval 120)
    ELSE (set Check_Interval 300)
  ) , set Min_Val 123
)

Allerdings habe ich nur versucht die Klammern zu setzen, den Sinn des Codes habe ich  nicht verstanden ;)
Gruß Otto
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: wollik am 25 Januar 2024, 11:36:10
Hallo Otto,
JA das wars!
Die Logik ist nur zum Testen, wann welcher Befehl im DOFI ausgeführt wird. Die Bedingungen der IF's wechsle ich dann im DOIF und bekomme dann andere Einträge und evtl. Fehler im Eventlog für meine Überprüfungen.

D A N K E nochmals
wollik
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: wollik am 26 Januar 2024, 14:56:08
Hallo Otto,
S O R R Y dass ich schon wieder frage!
Ich habe in den Logs folgende Updatesituation von Dummys in DOIF's festgestellt:
1. Wenn ein Dummy direkt gesetzt wird, wird die Änderung direkt mit dem neuen Wert gelogged.

2. Wenn innerhalb einer IF Anweisung das Dummy über einen Rückgabewert (z.B. von einem Externen Prog gesetzt wird, wird der Wert im Log richtig angezeit (Siehe Value__Set).

3. So lange man/frau sich innerhalb dieser IF Anweisung bewegt wird leider der alte Wert des Dummys verwendet !?! (Siehe Value_Copy Werte) Somit kann mit diesem falschen Wert nicht weiter gearbeitet werden ;(

4. Nach der IF Anweisung wird der Wert des Dummys aber dann richtig gesetzt, so wie es auch beim ersten Setzen im Log protokolliert wurde.

5. Um mit den richtigen Werten in dieser IF Abfrage weiter arbeiten zu können, müßte man/frau nochmals so eine zweite IF Abfrage ausßerhalb verwenden, evtl. wäre es auch mit einem sleep möglich zu warten bis der Wert richtig gesetzt ist aber das würde dann unser FHEM blokieren.

Zum Nachstellen habe ich eine kleine Umgebung gebaut, die via DIOF alle 11 Sekunden einen Zeitstempel (MM:SS) via Bash holt und in das Dummy VALUE__Set schreibt.
In der problematischen IF-Anweisung wird dieser Wert in das Dummy_Copy copiert der dann leider den alten Wert des Dummys Value__Set vom vorherigen run reincopiert. Ich mache das ein paar mal um aufzuzeigen, dass das Problem in dieser IF-Anweisung liegt.
Danach wird die IF-Anweisung verlasssen und der Zeitstempel in das Dummy Value_Last kopiert was, nun den richtigen Wert anzeigt.

Hier die lesbare DOIF:

defmod Test DOIF ([+[Interval]])
(set Conn 1,
   IF ([Conn] eq "1")(
      set My_Value 400,
     IF ([My_Value] gt "200")(
        (set Value__Set {(`date |cut -d ':' -f2,3|cut -d ' ' -f1`)}),
        set Value_Copy [Value__Set],
        set Value_Copy [Value__Set],
        set Value_Copy [Value__Set],
        set Value_Copy [Value__Set],
        set Value_Copy [Value__Set])
      ELSE (set Check_Interval 300)
     ),
     set Value_Last [Value__Set]
)


Bitte hast Du dazu eine Idee?

Viele Grüße
wollik

DOIF_Log.txt
DOIF_Raw_Definition.txt 








Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: Otto123 am 26 Januar 2024, 15:12:20
Hallo Wollik,

kann ich nicht bestätigen. Ich habe eine Test DOIF in meiner Umgebung in deinem Sinne (vereinfacht) modifiziert, denke ich ;)
defmod IntervallTest DOIF ([00:05-23:55,+00:00:05]) (setreading $SELF Value__Set {(`date +%M:%S | tr -d '\n '`)},setreading $SELF Value_Copy [$SELF:Value__Set])
attr IntervallTest do always
attr IntervallTest room Test
Das arbeitet wie erwartet, bei Readings werdem synchron gesetzt. Oder ich habe Dein Problem nicht verstanden :)
BTW: man kann den Zeitstring auch so erzeugen {( strftime("%M:%S",localtime) )}, aber ich glaube Du wolltest einen Scriptaufruf simulieren?

Gruß Otto
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: wollik am 26 Januar 2024, 21:28:20
Hallo Otto,
ja das funktiniert, das Problem tritt in einer If Anweisung auf, wenn man/frau dort den Dummywert setzt.
Und ja in meinem Beispiel verwende ich das Shell Beispiel mit dem date Befehl nur als einfaches Beispiel. Da kommt eine andere Shell Befehlskette zum Einsatz.

Ich muß das Setzen des Dummys leider in runde Klammern schreiben sonst bekomme ich den Fehler, das die rechte Klammer der If Anweisung fehlt.

Bitte hast Du das einmal mit meinem DOIF Test versucht (Siehe Attachment), da der Fehler nur in einem IF Konstrukt auftritt.
Evtl. hast Du auch eine Idee wie ich die zusätzlichen Klammern um das Seten weg bekomme? dann funktioniert das Setzen ja evtl. richtig.

Viele Grüße
wollik
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: Otto123 am 26 Januar 2024, 22:24:38
Zitat von: wollik am 26 Januar 2024, 21:28:20Evtl. hast Du auch eine Idee wie ich die zusätzlichen Klammern um das Seten weg bekomme?
Das liegt am DOIF: https://fhem.de/commandref_modular_DE.html#DOIF_Angaben_im_Ausfuehrungsteil
ZitatFalls ein Komma nicht als Trennzeichen zwischen FHEM-Befehlen gelten soll, so muss der FHEM-Ausdruck zusätzlich in runde Klammern gesetzt werden: ...((set lamp1,lamp2 on),set switch on)

Und zu deinem eigentlichen Problem kann ich nur sagen: Verschiebe das bitte nach dem DOIF Board und "Mister IF/DOIF - bitte übernehmen Sie" :)
So wird der Effekt sichtbar, ohne IF () () tritt es nicht auf.
([00:05-23:55,+00:00:05]) (IF (1) (setreading $SELF Value__Set {(`date +%M:%S| tr -d '\n '`)},setreading $SELF Value_Copy [$SELF:Value__Set]) )
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: Damian am 27 Januar 2024, 09:23:11
Beim FHEM-IF wird der Code vor seiner Ausführung in Perl-if übersetzt, zu diesem Zeitpunkt werden Readingangaben in eckigen Klammern durch entsprechende Werte ersetzt. Das bedeutet, dass ein Verändern des Readings kurz davor nicht mehr greift, weil die Inhalte der Readings bereits zuvor ersetzt wurden.

In solchen Fällen solltest du auf Perl-if ausweichen.
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: wollik am 03 Februar 2025, 16:02:39
Hallo Otto,
ich bin immer noch auf der Suche mittels at ein Shell Script (oder einen Shell Befehl) auszuführen und den Returnwert in ein Userattribut eines Devices zu schreiben.
Ich will kein dummy beschreiben, sondern brauche den Wert im Userattribut!
Leider verstehe ich nicht wie ich das machen könnte:

Hier meine Details:
device = OpenWB
userattrib = TS

defmod Get_TS at +*00:02:00 {\
   my $TimeStamp = qx(date +"%M:%S");;\
   ("set OpenWP:TS $TimeStamp");;\
}


Dieses einfache Version soll alle 2 Minuten via Shell Befehl den Timestamp holen und in das Userattribut schreiben.
weder (set... noch setreading... ) funktionieren;(
Bitte hättest Du dazu eine Idee?

Viele Grüße
wollik




Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: TomLee am 03 Februar 2025, 16:56:25
Hallo,

Hier (https://fhem.de/commandref_modular.html#attr) ist der Befehl beschrieben um in Attribute zu schreiben.

defmod Get_TS at +*00:02:00 {\
  my $TimeStamp = qx(date +"%M:%S");;\
  fhem("attr $SELF TS $TimeStamp");;\
}

Gruß

Thomas
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: wollik am 03 Februar 2025, 17:14:29
Hallo TomLee,
D A N K E  für die schnelle Antwort.
JA ich hatte das auch schon versucht, funktioniert leider nicht;(

defmod Get_WB_Energy at +*00:00:30 {\
   my $TimeStamp = qx(date +"%M:%S");;\
   fhem("attr OpenWB Total_Active_Energy $TimeStamp");;\
}


Welcher Wert wird mit $SELF angesprochen ?

Viele Grüße
wollik
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: TomLee am 03 Februar 2025, 17:29:25
ZitatWelcher Wert wird mit $SELF angesprochen ?

Upps, sry. Das at selbst. Das Du in ein anderes Device schreiben willst hab ich gar nicht beachtet.

Oben schreibst Du noch das ein userattr TS hast, jetzt willst in Total_Active_Energy schreiben. Existiert das userattr ?

Extra noch einen Hinweis auf den Parameter -silent hab ich auch vergessen zu erwähnen, wenn das wirklich so zum Einsatz kommen soll.


Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: wollik am 03 Februar 2025, 18:23:06
Hallo TomLee,
sorry das Userattribut Total_Active_Energy existiert und wird vom Device OpenWB auch regelmäßig im 10 Minutentakt befüllt. Ich hatte das Alles vereinfacht also kein TS sondern Total_Active_Energy.

Nun mit diesem at sollte das Attribut alle 30 Sekunden geschrieben werden, was ich zum Testen auf diesen kurzen Wert gesetzt habe.

Ich brauche die geschriebenen Werte von Total_Active_Energy im Log, darum habe ich kein -silent.

Aber wie gesagt, ich bekomme den Attributwert nicht geschrieben;( weil ich das Setzen via set oder setreading oder ... nicht hinbekomme.


Viele Grüße
wollik
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: TomLee am 03 Februar 2025, 18:52:04
Glaube jetzt versteh ich.

Du möchtest den Wert nicht in ein Attribut schreiben, sondern wirklich in ein Reading.

Du befindest dich in dem Ausführungsteil des at in Perl (die geschweiften Klammern). In Perl musst einen FHEM-Befehl über die Funktion fhem() ausführen. Das ist die Syntax so wie ich sie gezeigt habe, nur das mein Beispiel den FHEM-Befehl attr ausführt.

Du magst den FHEM-Befehl setreading ausführen, das würde dann so aussehen:

fhem("setreading OpenWB Total_Active_Energy $TimeStamp")

Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: wollik am 03 Februar 2025, 19:32:05
Hallo TomLee,
ich habe es jetzt hinbekommen!
hier meine Definition:

defmod Get_WB_Energy at +*00:00:10 {\
   my $TimeStamp = qx(date +"%M:%S");;\
   fhem("setreading OpenWB Total_Active_Energy $TimeStamp");;\
}


Ich hatte zuvor mit attr Anstelle von setreading das versucht;(

Vielen Lieben DANK an Alle
wollik

Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: Otto123 am 03 Februar 2025, 21:04:26
weniger umständlich, nur Perl und kein Shellzugriff:
defmod Get_WB_Energy at +*00:00:10 setreading OpenWB Total_Active_Energy { (strftime("%M:%S",localtime) )}
Aber ich weiß - set magic ist nicht so beliebt. :D
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: TomLee am 03 Februar 2025, 21:46:11
noch weniger umständlich :)

setreading OpenWB Total_Active_Energy {("$min:$sec")}
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: wollik am 04 Februar 2025, 12:54:14
Hallo Otto, hallo TomLee,
das Beispiel mit dem Timestamp war nur zur Demonstration.
Der richtige Shell Befehl besorgt sich Daten, bereitet diese dann auf und das Ergebnis wird zurück gegeben.

Der Befehl mit {("$min:$sec")} funktioniert und schreibt den Timestamp in das Reading.
Der Befehl mit { (strftime("%M:%S",localtime) )} funktioniert nicht sondern schreibt "{ (strftime("%M:%S",localtime) )}" in das Setting. Wenn ich die Spaces entferne funktioniert es!

Wie würde das dann aussehen wenn ich den Returnwert vom Shell Befehl haben möchte?
mit:
defmod WB_Energy_Test at +00:00:05 setreading OpenWB Total_Active_Energy {(\
    my $WB_Energy = qx(date +"%H:%M");;    \
    print ":0:> $WB_Energy\n";; )\
}
 

funktioniert es nicht, sondern der Inhalt in { } wird in das reading gesetzt.

Wie müßste der Befehl in { } formatiert werden um das Ergebniss vom Shell Script zu bekommen?


D A N K E an Euch
Wollik
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: Otto123 am 04 Februar 2025, 13:16:06
print funktioniert an der Stelle mM nicht. Ich nehme stattdessen immer return.
Wenn Du sagst die Spaces zwischen {( stören, dann stört der Zeilenumbruch \ dazwischen mit Sicherheit.

Mann muss die Perlbefehle im set magic zusätzlich klammern (siehe commandref) also
{ <Perlbefehl> } wird zu {( <Perlbefehl> )}
Titel: Aw: Dummy State via Ssystemcommand setzen
Beitrag von: wollik am 04 Februar 2025, 14:05:06
Hallo Otto,
JA ohne Spaces mit dem direkten Perlbefehl funktioniert es!!!
Also {(qx(......))} setzt den Wert via Return von qx.

D A N K E !!!

Viele Grüße
wollik