[Gelöst] Dummy device: tatsächlichen Status anzeigen

Begonnen von JO106, 01 Mai 2020, 09:06:35

Vorheriges Thema - Nächstes Thema

JO106

Hallo,

sicherlich ist diese Fragestellung schon das ein oder andere Mal gekommen, aber ich habe nichts Passendes für mein Problem finden können :(

Ziel ist die Steuerung von Relais, die an einem entfernten Raspi angeschlossen sind. Diese kann ich per CLI im OS schalten und abfragen. Für die Einbindung in FHEM habe ich daher ein dummy device definiert, mit dem ich auch erfolgreich schalten kann. Beispielhaft so:

define Pumpe dummy
attr Pumpe webCmd on:off
define Pumpe_off notify Pumpe:off {system('~pi/bin/fhemremotecmd picam5 pumpe 0 &');;}
define Pumpe_on  notify Pumpe:on  {system('~pi/bin/fhemremotecmd picam5 pumpe 1 &');;}


Ich möchte nun in FHEM den aktuellen Status (on/off) angezeigt bekommen, auch dann, wenn man den Schaltzustand an FHEM vorbei ändert. Was muss ich hinzufügen um das hinukriegen? Status kann ich hier mit dem Kommando pumpe ohne Parameter auslesen.

Oder gibt es für meine Aufgabenstellung einen besseren device type als dummy?

MadMax-FHEM

Spricht etwas dagegen auf dem "entfernten PI" auch fhem laufen zu haben!?

Dann dort mit fhem-Bordmitteln steuern, dann stimmt "dort" auch die Anzeige und dann die 2 fhem verbinden...

https://wiki.fhem.de/wiki/FHEM-Remote
https://wiki.fhem.de/wiki/FHEM2FHEM

Übrigens, dein "system-Aufruf" ist blockierend, kann also, wenn was nicht glatt läuft fhem blockieren...

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

JO106

Danke für schnelle Antwort. Müsste ich mir mal anschauen mit mehreren FHEM Servern, die man dann koppelt. Allerdings wären dann in meinem Fall ein halbes Dutzend FHEM Server zu bändigen ;-)

Eine Lösung mit einer zentralen FHEM-Instanz wäre mir daher lieber.

Den sytem-call habe ich als Background-Prozess definiert um eben Hänger/Timeouts etc. zu verhindern. Letztendlich macht er ja nur einen ssh-Aufruf zum Remote-System.

MadMax-FHEM

Zitat von: JO106 am 01 Mai 2020, 09:30:02
Den sytem-call habe ich als Background-Prozess definiert um eben Hänger/Timeouts etc. zu verhindern. Letztendlich macht er ja nur einen ssh-Aufruf zum Remote-System.

EBEN: ssh remote! Lass den remote Server mal nicht reagieren -> timeout! fhem WARTET und HÄNGT! Also zumindest so wie du aufrufst!

system(...) -> blockiert (kann)

qx(...) -> blockiert (kann)

"..." -> blockiert NICHT!! (so lagert fhem das in den Hintergrund aus OHNE zu blockieren) Nachteil: kein Rückgabewert des Aufrufs...

Siehe: https://heinz-otto.blogspot.com/2018/02/in-fhem-externe-programme-aufrufen.html


Aber gut, dann eben mit einem fhem ;)

Da gibt es verschiede Möglichkeiten.
Kommt drauf an wie du feststellen kannst, dass sich was (nicht durch fhem) geändert hat...

Allerdings gestaltet sich das mit deinem Dummy/Notify-Konstrukt schwierig.
Weil wenn du den Status des Dummy auf einen Wert setzt, der "von remote kommt" wird auch das Notify auslösen.
D.h. der remote-GPIO wird noch mal auf den selben Status gesetzt...
Oder du musst das im Notify abfangen...

Zum "Synchronisieren" gäbe es ein "at" was eben zyklisch den "Remote-Status" abfrägt und den Dummy "korrigiert"...

Du kannst auch, wenn du remote mitbekommst, dass sich der Zustand geändert hat fhem "von dort aus" informieren: telnet, http, ...

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

JO106

Hi Joachim,

also nochmal zum system-call: Sowohl nach meinem Verständnis als auch nach der Beschreibung von heinz-otto sollte meine Variante ohne Blockierung funktionieren. Der system-Call startet remotefhemcmd im Background und kehrt damit quasi sofort zu FHEM zurück egal ob und wie lange der ssh-Aufruf dann läuft. Ich habe mal testweise als Kommando "sleep 100 &" eingetragen. Ergebnis: Keine Blockierung.
ZitatNach meinen Informationen, lässt sich das Verhalten mit qx() nicht ändern. Die Befehle werden immer seriell ausgeführt, Perl wartet auf die Rückgabe!
Der system() Aufruf hat andere Möglichkeiten. Bei ihm kann man mit dem & Zeichen am Ende (für die Shell typisch) die Ausführung im Hintergrund starten. Die Ausgabe im Script landet damit nach der Pause im Logfile von FHEM.

Aber zu dem Vorschlag mit dem at Befehl: Wie könnte dieser aussehen?
define Pumpe_Sync at +*00:10:00 { unknown_command }

Da ist mir derzeit völlig unklar wie ich den Output meines pumpe Kommandos (on bzw. off) in den state für meine Pumpe hineinkriege.

Viele Grüße
Jürgen

MadMax-FHEM

#5
Zitat von: JO106 am 01 Mai 2020, 10:40:21
Hi Joachim,

also nochmal zum system-call: Sowohl nach meinem Verständnis als auch nach der Beschreibung von heinz-otto sollte meine Variante ohne Blockierung funktionieren. Der system-Call startet remotefhemcmd im Background und kehrt damit quasi sofort zu FHEM zurück egal ob und wie lange der ssh-Aufruf dann läuft. Ich habe mal testweise als Kommando "sleep 100 &" eingetragen. Ergebnis: Keine Blockierung.

Hallo Jürgen,

STIMMT!! SORRY! ;)

Ich hatte das '&' übersehen... ;)

Mit dem '&' ist es nat. nicht blockierend...


Zitat von: JO106 am 01 Mai 2020, 10:40:21
Aber zu dem Vorschlag mit dem at Befehl: Wie könnte dieser aussehen?
define Pumpe_Sync at +*00:10:00 { unknown_command }

Da ist mir derzeit völlig unklar wie ich den Output meines pumpe Kommandos (on bzw. off) in den state für meine Pumpe hineinkriege.

Viele Grüße
Jürgen

Ja so in etwa...
...d.h. dir fehlt noch 'unknown_command'!? ;)

Wie kannst du denn den Pumpenstatus abfragen!?
Wieder per Shellscript!?

Das kannst du per at genauso aufrufen, wie im notify...
...du kannst dann IM Shellscript auch Werte in einem fhem Dummy setzen...

Z.B. per Telnet (setzt voraus, dass du ein Telnet-Device in fhem "definiert" hast):

/usr/bin/perl /opt/fhem/fhem.pl 7072 "setreading dmDummyName ReadingName ReadingWert"


Bzw. in deinem Fall wohl eher:

/usr/bin/perl /opt/fhem/fhem.pl 7072 "set dmDummyName ReadingWert"



Es geht auch mittels http(s), also dem "normalen" Webzugang zu deinem fhem:
https://github.com/heinz-otto/fhemcl

EDIT: aber wie erwähnt musst du verm./besser irgendwie dafür sorgen, dass dann nicht wieder ein 'on' zur Pumpe kommt, wenn ein 'on' per Abfrage "zurückkommt"... D.h. du schaltest per fhem ein -> 'on' zum GPIO/Pumpe. Dann kommt das at, frägt ab und setzt dann ja ebenfalls (immer) wieder 'on' -> Notify reagiert und schickt 'on' zur Pumpe. Vermutlich nicht schlimm aber unschön... Ich würde daher beim Dummy mal "event-on-change-reading" entsprechend setzen. Dann feuert dieser nur noch Events (worauf ein Notify reagieren könnte/würde), wenn sich der Wert auch geändert hat. Also nur noch von 'on' zu 'off' und umgekehrt. Aber KEIN Event, wenn 'on' zu 'on' "wechselt"... ;)


Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

JO106

Hi Joachim,

ja wie von Dir vermutet kann ich den Status in der fhem.cfg auslesen mit:
system('remotefhemcmd pumpe &')
Das Script liefert auf StdOut den String "on" oder "off". Alternativ könnte ich auch einen entsprechenden Returncode verwenden oder andere Strings. Was mir fehlt ist die Zuweisung an die entsprechende Status-Variable für mein dummy device Namens "Pumpe". Könntest du mir den korrekten Eintrag, also das <unknown_command> für dieses Szenario nennen? Stehe da auf grade total auf dem Schlauch.

Das mit dem "event-on-change-reading" hört sich gut an. Außerdem elegant. Werde ich testen.

Viele Grüße
Jürgen


MadMax-FHEM

Kannst du denn nicht IN remotefhemcmd eine der beiden Varianten einbauen, also:

telnet (code siehe oben)

oder http(s) siehe Link zu Otto's Blog...

Weil mit system bekommst du eben KEINEN Returnwert nach fhem zurück...
...und eine Ausgabe auf der Console hilft ja nicht ;)

Wenn du das Script nicht anpassen kannst, dann musst du in den saueren Apfel beißen und 'qx' nehmen und damit aber ein Blockieren riskieren...

Der Aufruf im Script mit Telnet sollte so aussehen:


/usr/bin/perl /opt/fhem/fhem.pl 7072 "set Pumpe $Returnwert"


Den Returnwert musst du halt im Script 'remotefhemcmd' in eine Variable schreiben ($Returnwert ;)  ) und dann eben obengenannten Aufruf ins Script einbauen...

Sofern perl bei dir auch unter /usr/bin/ liegt und du einen Telnetport in fhem hast:


define TelnetPort telnet 7072


sollte reichen, da ja lokal (localhost) verwendet...
...wenn nicht:


define TelnetPort telnet 7072 global


ODER aber den bereits vorhandenen fhemWEB-Zugnag verwenden, dazu siehe Otto's Blog...

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

JO106

Hallo Joachim,

ich habe jetzt ein paar Sachen ausprobiert: Das mit dem "event-on-change-reading" Attribut hat irgendwie nicht so richtig funktioniert. Auch mein DevStateIcon war dann weg.

Ohne funktionierendes "event-on-change-reading" würde ich mir eine Endlos-Schleife einbauen, wenn ich in meinem Pumpen-Script per telnet oder http jedesmal den Status in FHEM setze, weil ja dann gleich wieder über notfiy ein neuer Script-Aufruf erfolgt.

Werde das Script dahingehend ändern, dass es, wenn über FHEM aufgerufen, keinen Status an FHEM sendet (etwa über telnet). Dies steuere ich über eine zusätzliche Aufrufoption. Ohne dieses Flag, sprich bei Aufruf von Hand oder mittels anderer Tools an FHEM vorbei wird dann der korrekte Status an FHEM mittels Deines Vorschlags  /usr/bin/perl /opt/fhem/fhem.pl 7072 "setreading $1 state $2" korrigiert. $1 und $2 werden dabei natürlich durch die passenden Device- und State-Values substituiert.
Das hat dann auch den Vorteil, dass ich nicht zyklisch in FHEM oder sonstwo abfragen muss und damit auch nur so aktuell wäre, wie der Abfragezyklus.

Danke für Deine Unterstützung  :)

Viele Grüße
Jürgen

MadMax-FHEM

Musst du setreading state machen!?

Sollte doch auch: set Dummyname Wert gehen...

Evtl. fehlt dir ein setList on off

Wie hast du denn event-on-change-reading definiert!?

Ich mache immer event-on-change-reading .*

Also erst mal "auf alle Readings"...
Brauche ich dann Events auch wenn keine Änderung war (ABER: ein Event gekommen ist/wäre, also gleicher Wert noch mal), dann mache ich das dann mit event-min etc.

Einfach mal bzgl. dieser Attribute einlesen...

ABER: bei einem Dummy (der ja eigentlich nicht autom. [außer bei dir jetzt] Werte-Updates bekommt) und in deiner Konstellation mit im Script eingebauter "Bremse" ist es so wohl auch ok...

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

JO106

Hi Joachim,

vielen Dank für die vielen Tipps. Das "event-on-change-reading" geht jetzt auch. Ich hatte "state" statt ".*" verwendet.
Ich denke, damit habe ich mein Problem gelöst.

Nochmals Danke und schönes Wochenende
Jürgen