FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: Randybobandy am 21 April 2019, 09:24:51

Titel: Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: Randybobandy am 21 April 2019, 09:24:51
Ich probiere schon eine Weile und kriege es nicht zum laufen, dabei müsste es gefühlt ganz einfach sein.
Ich möchte eine Lampe schalten per HTTP request und den neuen Status der Lampe als Rückgabewert. Ich erhalten aber immer den alten Status von vor dem Schalten.

(Escaping habe ich zwecks besserer Lesbarkeit hier weggelassen)
http://meineip:8083/fhem?cmd=set Farbwuerfel toggle;list Farbwuerfel state&XHR=1&fwcsrf=csrf_meintoken

Beispielausgabe: Farbwuerfel          2019-04-21 08:53:30    off

Rückgabe ist "off", Lampe ist aber in Wirklichkeit schon "on", wegen des toggle Befehls.

Wenn ich noch ein sleep einbaue
set Farbwuerfel toggle;sleep 1;list Farbwuerfel state
Erhalte ich nur eine leere Seite zurück. Ich vermute, dass hier nur noch die Rückgabe des Befehls "set Farbwuerfel toggle" ankommt.

Hat jemand eine Idee?

Hintergrund ist der, dass es eine Android App "HTTP request shortcuts" gibt, mit der man sich HTTP requests als Widgets auf den Homescreen legen kann. Beim Anklicken eines Widgets kann die APP auch einen Rückgabewert anzeigen.
Titel: Antw:Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: amenomade am 21 April 2019, 11:12:53
Hast Du mit doppel Semikolon schon versucht?
Titel: Antw:Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: Otto123 am 21 April 2019, 11:18:05
Moin,

der Schaltbefehl und die Aktualisierung des State sind zwei getrennte Vorgänge. Die Zeit dazwischen hängt vom Gerät ab.
Bei einem Dummy funktioniert das was Du willst, bei jedem anderen Gerät wäre es rein zufällig.

Gruß Otto
Titel: Antw:Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: Randybobandy am 21 April 2019, 12:38:33
Doppel Semikolon hab ich auch schon probiert, dann funktioniert der Befehl garnicht da kommt "Unknown argument toggle;............"usw..

Zitatder Schaltbefehl und die Aktualisierung des State sind zwei getrennte Vorgänge. Die Zeit dazwischen hängt vom Gerät ab.
Ich habe ein bisschen im telnet damit experimentiert. Wenn ich beide Befehle ins telnet paste, so dass sie praktisch zeitgleich ausgeführt werden, dann klappt es nicht. Mache ich ca. 1 Sek. Pause dazwischen, dann klappt es wie gewünscht. Die Frage ist nur, kann ich eine kleine Pause in die URL für den HTTP request einbauen?

Ich habe auch schon ein eigenes Modul gebaut, mit folgendem code drin:
sub
mySwitch(){
fhem("set Farbwuerfel toggle");
sleep 1;
fhem("list Farbwuerfel state");
}


Erstaunlicherweise (für mich zumindest) erscheint, wenn ich das Modul über
http://meineip:8083/fhem?cmd={mySwitch()}&XHR=1&fwcsrf=csrf_meintoken
aufrufe, trotzdem der alte Zustand  :o
Titel: Antw:Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: justme1968 am 21 April 2019, 13:13:21
perl sleep blockiert fhem und es gibt keinen fortschritt.

du musst ein fhem sleep verwenden.

d.h. nicht mehrfach zwischen perl und fhem ebene wechseln.
Titel: Antw:Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: Randybobandy am 22 April 2019, 09:00:26
Zitatperl sleep blockiert fhem und es gibt keinen fortschritt.

Ein guter Einwand und jetzt kann ich mein Problem glaube ich wirklich reduziert auf den Punkt bringen.

Wenn ich oben im Webinterface von FHEM in das Eingabefeld folgenden Befehl eingebe (also fhem sleep):

set Farbwuerfel toggle; sleep 5; set Farbwuerfel toggle

Dann schaltet die Lampe um, dass Webinterface wird neu geladen und 5 Sekunden später schaltet die Lampe wieder um.

Wenn ich im Webinterface eingebe:

set Farbwuerfel toggle; sleep 5; list Farbwuerfel state

Dann schaltet die Lampe um, dass Webinterface wird neu geladen und 5 Sekunden erscheint garnichts. (Die Ausgabe vom list Befehl erscheint im Logfile anstatt im Webinterface)

Man müsste irgendwie den ersten Teil "set Farbwuerfel toggle" stumm schalten können bzw. die Ausgabe verzögern, bis alle Befehle abgearbeitet wurden aber ich vermute, das geht garnicht so wie ich mir das vorstelle.
Titel: Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: justme1968 am 22 April 2019, 09:17:20
fhem arbeitet asynchron und event basiert. es ist nicht vorgesehen synchron auf ein ergebnis zu warten.

mit fhem sleep wird der rest des kommandos im hintergrund ausgeführt und dort landet dann auch die ausgabe.

das beißt sich mit dem verbindungslosen http.

ich fürchte das was du möchtest geht so nicht.


wenn du telnet verwenden kannst wäre das vermutlich einfacher.
Titel: Antw:Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: Randybobandy am 22 April 2019, 14:32:29
Ok danke für eure Tipps. Ich bin auch ziemlich überzeugt jetzt, dass ich es nur mit FHEM alleine nicht lösen kann. Habe ein kleines Script gebastelt, welches auf Port 8181 lauscht und die Befehle dann an Fhem weitergibt. Über Sicherheitsaspekte usw. habe ich mir aber erstmal keine Gedanken gemacht. Das script läuft bei mir als normaler user von der Konsole ausgeführt. Wenn ich es ein paar Tage getestet habe und zufrieden bin, werde ich es vielleicht dämonisieren. Erstmal scheint es aber das zu tun, was ich will ;D

Fhem wird vom Script so ausgeführt:
    system ("/opt/fhem/fhem.pl 7072 \"set $device $command\"");
    my $result = `/opt/fhem/fhem.pl 7072 "list $device state"`;
Bei dieser Ausführungsart dauern die Befehle so lang, dass ich mir das sleep sparen konnte  ::).

Man kann das script dann so ansteuern: http://fhemip:8181/fhem?c=befehl&d=device
Für mein Bespiel von vorhin also http://fhemip:8181/fhem?c=toggle&d=Farbwuerfel

#!/usr/bin/perl
{
package MyWebServer;

use HTTP::Server::Simple::CGI;
use base qw(HTTP::Server::Simple::CGI);
use strict;

my %dispatch = (
    '/fhem' => \&fhem,
    # ...
);

sub handle_request {
    my $self = shift;
    my $cgi  = shift;

    my $path = $cgi->path_info();
    my $handler = $dispatch{$path};

    if (ref($handler) eq "CODE") {
        print "HTTP/1.0 200 OK\r\n";
        $handler->($cgi);

    } else {
        print "HTTP/1.0 404 Not found\r\n";
        print $cgi->header,
              $cgi->start_html('Not found'),
              $cgi->h1('Not found'),
              $cgi->end_html;
    }
}

sub fhem {
    my $cgi  = shift;   # CGI.pm object
    return if !ref $cgi;

    my $device = $cgi->param('d');
    my $command = $cgi->param('c');

    print "Content-type: text/plain\n\n";
    system ("/opt/fhem/fhem.pl 7072 \"set $device $command\"");
    my $result = `/opt/fhem/fhem.pl 7072 "list $device state"`;
    $result =~ s/\n//g;
    $result =~ /^(\w+)?.*\s(\w+)$/;
    my $result = "$1 $2";
    print "$result";
}

}

# start the server on port 8181
my $pid = MyWebServer->new(8181)->background();
print "Use 'kill $pid' to stop server.\n";


Bespielcode war von: https://metacpan.org/pod/HTTP::Server::Simple

Jetzt kann ich mir meine ganzen Devices direkt auf den Android home screen legen, wie ich es mir gewünscht hatte, mit aktuellem state als Rückgabe.
Titel: Antw:Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: knopf_piano am 22 April 2019, 17:48:12
gefällt mir,
bin auf mobilteil ausschließlich per http-request unterwegs (waf!). Responses war allerdings noch nicht im Fokus.
Fein wär noch, dass man den aktuellen status bekommt zum device, was am shortcut hängt.
Stell ich mir aber schwierig vor, das zu korrellieren, da man für dummys z.B. ein
list TYPE=dummy state
absetzen müßte und diese den shortcuts mit commando 'd'==device zuordnen müßte. Das müßte auch gepollt werden bzw. on-change aktualisiert werden...

Oder man baut sich einen zweiten shortcut, der eben den nur "state" des angesprochenen devices ausgibt.
Ich war mal so frei und hab's erweitert:
somit erzeugt ein http://fhemip:8181/fhem?c=state&d=device (http://fhemip:8181/fhem?c=state&d=device) den aktuellen Status, ohne Schalt-aktion


#!/usr/bin/perl
{
package MyWebServer;

use HTTP::Server::Simple::CGI;
use base qw(HTTP::Server::Simple::CGI);
use strict;

my %dispatch = (
    '/fhem' => \&fhem,
    # ...
);

sub handle_request {
    my $self = shift;
    my $cgi  = shift;

    my $path = $cgi->path_info();
    my $handler = $dispatch{$path};

    if (ref($handler) eq "CODE") {
        print "HTTP/1.0 200 OK\r\n";
        $handler->($cgi);

    } else {
        print "HTTP/1.0 404 Not found\r\n";
        print $cgi->header,
              $cgi->start_html('Not found'),
              $cgi->h1('Not found'),
              $cgi->end_html;
    }
}

sub fhem {
    my $cgi  = shift;   # CGI.pm object
    return if !ref $cgi;

    my $device = $cgi->param('d');
    my $command = $cgi->param('c');

    print "Content-type: text/plain\n\n";
    if($command ne "state")
    {
system ("/opt/fhem/fhem.pl 7072 \"set $device $command\"");
    }
   
    my $result = `/opt/fhem/fhem.pl 7072 "list $device state"`;
    $result =~ s/\n//g;
    $result =~ /^(\w+)?.*\s(\w+)$/;
    #my $result = "$1 $2";
    my $result = "device:\t$1\nstate:\t\t$2";
    print "$result";
}

}

# start the server on port 8181
my $pid = MyWebServer->new(8181)->background();
print "Use 'kill $pid' to stop server.\n";
Titel: Antw:Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: knopf_piano am 22 April 2019, 21:05:58
Hat jemand ne ahnung, wie ich dem teil das telnet-passwd mitgebe?
echo {passwd}| etc schon probiert, ohne erfolg. vielleicht weiß es ja doch einer :-)

ich schlage diesen weg ein, damit komm ich via user/passwd zum ziel, auch das list. ich meld mich...

https://forum.fhem.de/index.php/topic,68133.msg722644.html#msg722644 (https://forum.fhem.de/index.php/topic,68133.msg722644.html#msg722644)
Titel: Antw:Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: Otto123 am 22 April 2019, 21:45:36
Sollte so gehen:
https://forum.fhem.de/index.php/topic,14332.msg90785.html#msg90785

Gruß Otto
Titel: Antw:Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: knopf_piano am 22 April 2019, 22:20:20
hatte ich schon versucht... bringt fehler, auxh mit passwd-argument


perl /opt/fhem/fhem.pl 7072  "list TV_BackgroundLight state"                                         Use of uninitialized value in numeric gt (>) at /opt/fhem/fhem.pl line 524.

perl /opt/fhem/fhem.pl 7072  list TV_BackgroundLight state  Use of uninitialized value in numeric gt (>) at /opt/fhem/fhem.pl line 524.


Gesendet von meinem SM-J510FN mit Tapatalk
Titel: Antw:Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: Otto123 am 22 April 2019, 23:08:50
Was Du da schreibst ist für mich nicht nachvollziehbar. Da solltest Du mehr Infos liefern. Was genau hast Du wie konfiguriert?
Ich habe ein allowedWEB Device konfiguriert, dort dann:
set allowedWEB password password
attr allowedWEB validFor telnetPort

Dann funktioniert folgender Befehl im Terminal
perl /opt/fhem/fhem.pl 7072 password "list global"

Gruß Otto
Titel: Antw:Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: knopf_piano am 23 April 2019, 05:53:05
hier die Infos:

#################################
define telnetPort telnet 7072 global
setuuid telnetPort 5c4613d2-f33f-35e2-3875-c2ea646c190bcaaf
attr telnetPort SSL 0
#################################
define allowed_telnetPort allowed
setuuid allowed_telnetPort 5c4613d2-f33f-35e2-11df-a9cba40532aa0d1c
attr allowed_telnetPort password mypassword
attr allowed_telnetPort validFor telnetPort

identisch wie du, jedoch mit Fehler:

perl /opt/fhem/fhem.pl 7072 mypassword "list global"                                                     
Use of uninitialized value in numeric gt (>) at /opt/fhem/fhem.pl line 524.

oder ohne passwd

perl /opt/fhem/fhem.pl 7072 "list global"       
Use of uninitialized value in numeric gt (>) at /opt/fhem/fhem.pl line 524.


kann ich noch was liefern? weiß sonst nicht, was telnet seitig fehlerhaft wäre. normaler telnet login auf 7072 funktioniert jedenfalls mit passwd-abfrage

ich hab

# $Id: fhem.pl 19085 2019-04-01 17:00:24Z rudolfkoenig $


Gesendet von meinem SM-J510FN mit Tapatalk
Titel: Antw:Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: Randybobandy am 23 April 2019, 07:18:47
ich kanns gerade nicht testen aber wie wäre es mit sowas
use Net::Telnet ();
$t = new Net::Telnet (Timeout => 10,
                      Prompt => '/bash\$ $/');
$t->open($host);
$t->login($username, $passwd);
@lines = $t->cmd("who");
print @lines;
Titel: Antw:Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: Otto123 am 23 April 2019, 09:06:30
Moin knopf_piano,

ich habe irgendwie das Gefühl die Fehlermeldung hat mit etwas anderem zu tun. Die Frage wäre ja noch: bekommst DU mit oder ohne password denn eine Ausgabe.
Bei mir gibt es wenn Passwort aber dann kein Passwort angegeben einfach keine Ausgabe.

Kommt der Fehler auch beim normalen FHEM Start im Log?

Gruß Otto
Titel: Antw:Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: knopf_piano am 23 April 2019, 18:22:21
Hi Otto,
das bekomme ich ins log, wenn ich den http-request abschicke und wie oben mittels perl webserver ans telnet anschieße. Gleicher log-Eintrag bei Kommando via shell

telnet SSL/HTTPS error:  SSL accept attempt failed error:1408F10B:SSL routines:ssl3_get_record:wrong version number (peer: 192.168.178.22)

egal ob

attr telnetPort SSL 1
oder


attr telnetPort SSL 0

Titel: Antw:Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: Otto123 am 23 April 2019, 18:29:55
ssl und telnet - habe ich noch nicht gemacht. Da kann ich nicht helfen.

Gruß Otto
Titel: Antw:Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: knopf_piano am 23 April 2019, 18:38:19
dank dir!
war ja off-topic-problem :-\
Titel: Antw:Mit HTTP request Lampe schalten, neuen Status auslesen (HTTP request shortcuts)
Beitrag von: draddy am 09 März 2022, 08:41:13
moin,

*puuuust* bissl staubig hier  ;D

nur für den fall, das es jemanden interessiert, oder wie ich zufällig in dem Beitrag landen;

Habe in HTTP Request Shortcuts Jetzt mal folgendes gemacht;
3 "Schalter"

habe bei beiden befehlen &XHR=1 angegeben um das öffnen der Webseite  zu unterdrücken.
Response-Einstellungen: Bei Erfolg Nichts anzeigen

Shortcut Nr2. bei Auslöse&Ausführ-Einstellungen: Verzögerung 1 Sekunde einstellen

etwas Feenstaub unter Scripting - "Im Erfolgsfall ausführen"

const myB = response.body.trim().split(" ");
const myS = myB[myB.length-1];
showToast(myS);

if (myS === "on") {
    changeIcon(/[shortcut]/"53fec09f-62d4-4a6c-b6be-502e7f66e2c3"/[/shortcut]/, "flat_color_brightness_5");
} else {
    changeIcon(/[shortcut]/"53fec09f-62d4-4a6c-b6be-502e7f66e2c3"/[/shortcut]/, "flat_color_brightness");
}


den Ausführungsbereich vom if else würde ich löschen, und über das "Code Einfügen" Menü auswählen, - so hat man sicher die richtige Shortcut ID und Buttons die man will.

Das wars, Fertig ist ein Widget fähiger Button fürs Android Gerät welcher sogar  den Status anzeigt.

ACHTUNG: die APP bietet, zumindest Stand jetzt, wohl keine Möglichkeit etwas periodisch abfragen zu lassen, d.h. es kann immer nur der last known state angezeigt werden, wenn danach in fhem oder so geschaltet wird, bekommt die APP das erst mit wenn man an dieser Schaltet.

Finde ich, da ich sehr frei darin bin WAS ich schalten will und sogar eigene Icons verwenden kann, doch recht nett ;)

Lg
Jens

€dit: habe die Zeile const myS = myB[myB.length-1]; nun dynamisch gemacht, der wert ist, abhängig vom Namen, nicht immer gleich, aber immer die letzte stellte des arrays (länge -1 weil Zähler bei 0 beginnt!)