[gelöst] curl+bash vs curl+fhem vs zB Postman (Tool für Requests)

Begonnen von fireball, 19 Dezember 2019, 17:11:47

Vorheriges Thema - Nächstes Thema

fireball

Hi Leute,

ich bin grad bisl verwirrt....

Ich stelle aber grad fest, dass ich ein unterschiedliches Verhalten bekommen, wenn ich:

1.   den Befehl in Postman oder als curl auf der Shell ausführe
        a.   Dann reagiert die Jalousie sofort und ich kann auch direkt mehre Befehle abfeuern und zB auf,zu,stop,auf,zu,stop machen, die Jalousie reagiert.
2.   Mach ich das ganze in fhem / als system-befehl oder in einem Bashscript, wo ich zwei Parameter übergebe, dann kann ich den Befehl einmal abfeuern und muss dann eine Zeit X warten, bis ich den nächsten machen kann.
a.   Die Jalousie nimmt den zweiten Befehl nicht an.

Habt ihr Ahnung, warum das so sein könnte oder eine Idee, wie man rausfindet, warum das so ist?
Ich bin schon soweit, dass es was mit den Maskierungen der Sonderzeichen zu tun haben muss?


Zu Punkt1:

curl -d '{"action": 1}' -H "Content-Type: application/json" -X POST http://IP-Adresse/ocf/wlss97/shutter/1 =>
Schließt (action=1) die Jalousie wlss97 .

Output auf der Bash
pi@raspberrypi:/opt/fhem/FHEM $ curl -d '{"action": 1}' -H "Content-Type: application/json" -X POST http://192.168.178.128/ocf/wlss97/shutter/1
{ "rt": [ "wiserone.r.window.cover" ], "if": [ "oic.if.baseline" ], "action": 1 }pi@raspberrypi:/opt/fhem/FHEM $
pi@raspberrypi:/opt/fhem/FHEM $


Zu Punkt2:
Mach ich das im Shell oder in fhem, dann geht's nur ,,einmal" oder gar nicht...

pi@raspberrypi:/opt/fhem/FHEM $ more ./rolladen_schalten.sh
#!/bin/sh
# Curl-Befehl zum Schalten von Merten Rolladen durch Uebergabe von zwei Parameter
# $1 = Jalousie, $2 = Aktion (auf, zu, stop)

echo "Jalousie: " $1
echo "Aktion :" $2
curl -d '{"action": $2}' -H "Content-Type: application/json" -X POST http://IP-Adresse/ocf/$1/shutter/1

Output auf der Bash mit de rÜbergabe zweier Paramter
pi@raspberrypi:/opt/fhem/FHEM $ sudo ./rolladen_schalten.sh wlss97 0
+ echo Jalousie:  wlss97
Jalousie:  wlss97
+ echo Aktion : 0
Aktion : 0
+ curl -d {"action": $2} -H Content-Type: application/json -X POST http://192.168.178.128/ocf/wlss97/shutter/1
{ "rt": [ "wiserone.r.window.cover" ], "if": [ "oic.if.baseline" ], "action": 2 }pi@raspberrypi:/opt/fhem/FHEM $


Bei {"action": $2} fehlen die einfachen Anführungszeichen, aber auch bei einigen Tests, wenn ich die bekomme, dann kommt entweder ein Fehler von der Bash oder der Schalter geht doch nicht mehrmals zu schalten.

Jemand ne Idee, wo der Fehler ist, warum ein Script/Ffhem anders reagiert ... ? Wie kann ich den gleichen curl Befehl auf der Bash auch in einem Bashscript ausführen oder in einem notify von Fehm?!

VG
René

Otto123

#1
Hallo Rene,

schau doch mal:
Zitat+ curl -d {"action": $2} -H Content-Type: application/json -X POST http://192.168.178.128/ocf/wlss97/shutter/1

Die Variable wird in einfachen ' ' nicht mehr aufgelöst!

In FHEM machst Du einfach "Shell Befehl"Die Doppelten Anführungszeichen sind wichtig!

Siehe Doku FHEM Kommandos.

ich hatte hierzu auch mal ein bisschen experimentiert und dokumentiert.

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

fireball

Hi Otto,

ja ich hab jetzt schon x- Versionen durch... das ist definitiv nicht der Fehler... für das Bsp, da hast du aber recht.

Ich habe das Script jetzt nochmal umgestellt, was mir grad noch aufgefallen ist, dass ich oben die Shell nehme, aber nicht die Bash. Das habe ich grad geändert, dann ändert sich auch das Verhalten der Interpretation der Zeichen, aber auch das hilft nicht wirklich:

#!/bin/bash
set -x
# Curl-Befehl zum Schalten von Merten Rolladen durch Uebergabe von zwei Parameter
# $1 = Jalousie, $2 = Aktion (auf, zu, stop)

data="{\"action:\" $2}"
url="http://192.168.178.128/ocf/$1/shutter/1"
echo "Jalousie: " $1
echo "Aktion :" $2
echo "url :" $url
echo "post :" $data
echo ##########################
#curl -XPOST -g --data $generate_post_data -H "Content-Type: application/json" $url
curl -XPOST -g -d $data -H "Content-Type: application/json" $url



pi@raspberrypi:/opt/fhem/FHEM $ sudo ./rolladen_schalten.sh wlss97 1
+ data='{"action:" 1}'
+ url=http://192.168.178.128/ocf/wlss97/shutter/1
+ echo 'Jalousie: ' wlss97
Jalousie:  wlss97
+ echo 'Aktion :' 1
Aktion : 1
+ echo 'url :' http://192.168.178.128/ocf/wlss97/shutter/1
url : http://192.168.178.128/ocf/wlss97/shutter/1
+ echo 'post :' '{"action:"' '1}'
post : {"action:" 1}
+ echo

+ curl -XPOST -g -d '{"action:"' '1}' -H 'Content-Type: application/json' http://192.168.178.128/ocf/wlss97/shutter/1
curl: (6) Could not resolve host: 1}
{ "rt": [ "wiserone.r.window.cover" ], "if": [ "oic.if.baseline" ], "action": 0 }pi@raspberrypi:/opt/fhem/FHEM $


Der Aufruf passt fast genau zum Aufruf mit curl direkt auf der Bash, sogar der Schlater fühlt sich angesprochen, denn die kleine Lampe im Schalter leuchtet auf.
Aber ich glaube, die Geschichte, wie die "Daten" des Postrequest ankommen passen dem Schalter nicht.

nochmal zum Vergleich Curl aus Script vs Curl auf der Bash
+ curl -XPOST -g -d '{"action:"' '1}' -H 'Content-Type: application/json' http://192.168.178.128/ocf/wlss97/shutter/1
curl -X POST -d '{"action": 1}' -H "Content-Tye: application/json" http://192.168.178.128/ocf/wlss97/shutter/1


So das -g musste ich setzen wegen "globbing" keine Ahnung was das bedeutet, aber es hilft einen Fehler zu vermeiden.
Die Anführungsstriche bei -H könnten es sein, habe aber grad auch getestet, dass man den Content-Type weglassen kann.
curl -X POST -d '{"action": 2}'  http://192.168.178.128/ocf/wlss97/shutter/1

So... also ich geh davon aus es liegt definitiv an dem Datenfeld.... aber was ist da im Script anders als auf der Bash?!

VG
René

sledge

Der Doppelpunkt bei "action" ist einmal innerhalb / einmal außerhalb der Anführungszeichen - zB.
FHEM: debian Intel-NUC / 25 x MAX!, 15 x HM-bidcos, MQTT, 3 x 1wire, 20 x Shelly, 20 x Tasmota, 12 x Yeelight, Opentherm-GW, Espeasy, alexa-fhem, kodi, unifi, musiccast, ...

fireball

Jo, du hast recht, alles durchgetestet. Ich denke die Post-Daten kommen anders an...

pi@raspberrypi:/opt/fhem/FHEM $ sudo ./rolladen_schalten.sh wlss97 0
+ data=''\''{action: 0}'\'''
+ url=http://192.168.178.128/ocf/wlss97/shutter/1
+ echo 'Jalousie: ' wlss97
Jalousie:  wlss97
+ echo 'Aktion :' 0
Aktion : 0
+ echo 'url :' http://192.168.178.128/ocf/wlss97/shutter/1
url : http://192.168.178.128/ocf/wlss97/shutter/1
+ echo 'post :' ''\''{action:' '0}'\'''
post : '{action: 0}'
+ echo

+ curl -XPOST -g -d ''\''{action:' '0}'\''' -H 'Content-Type: application/json' http://192.168.178.128/ocf/wlss97/shutter/1
curl: (6) Could not resolve host: 0}'
{ "rt": [ "wiserone.r.window.cover" ], "if": [ "oic.if.baseline" ], "action": 1 }pi@raspberrypi:/opt/fhem/FHEM $


man sieht am Response...
{ "rt": [ "wiserone.r.window.cover" ], "if": [ "oic.if.baseline" ], "action": 1 }
de Request kam an, der Schalter an auch reagiert, aber er schaltet nicht.... :(

fireball

Sooo ich habe einen Hinweis im Netz gefunden und darin steht genau, wie man das Problem umgehen kann und die Lösung funktioniert auch (teilweise).
Es liegt definitv an den Wert, den die -d (POST-Daten) bekommen.

Das Script hier geht: 
#!/bin/bash
set -x
# Curl-Befehl zum Schalten von Merten Rolladen durch Uebergabe von zwei Parameter
# $1 = Jalousie, $2 = Aktion (auf, zu, stop)

################################################
genieren von Post-Daten
################################################
generate_post_data()
{
  cat <<EOF
  {"action": 2}
EOF
}

################################################
Befehl
################################################

curl -i -H "Content-Type: application/json" \
-X POST --data "$(generate_post_data)" "http://192.168.178.128/ocf/$1/shutter/1"


Jetzt nochmal ne Frage an die Profis...
Wie bekomme ich aber jetzt einen Parameter in die Funktion generate_post_data() den ich dem Script mitgegeben habe?!

also
generate_post_data()
{
  cat <<EOF
  {"action": 2}
EOF
}


Wenn das einer mir sagen könnte, dann würde ich wahrscheinlich endlich einer Lösung zum schalten meiner Jalousien näher kommen und dann kann ich für alle die die gleiche Schaltung haben etwas zusammenschreiben.

VG
René

fireball

Soooo ich habs rausgefunden, es liegt also definitiv an den HTTP-POST Daten,
Die Lösung für das Script sieht jetzt so aus:

#!/bin/bash
#set -x
# Curl-Befehl zum Schalten von Merten Rolladen durch Uebergabe von zwei Parameter
# $1 = Jalousie, $2 = Aktion (auf, zu, stop)
################################################
#genieren von Post-Daten
################################################
read -d '' -r  post_data <<EOF
{"action": $2}
EOF
################################################
#Befehl
################################################
curl -i -H "Content-Type: application/json" \
-X POST --data "$post_data" "http://192.168.178.128/ocf/$1/shutter/1"


Man muss die HTTP-POST Daten speziell genieren, damit sich da keine versteckten Sonderzeichen einschleichen oder falsch interpretiert werden.

Hier noch die Verweise auf die Seiten, wo ich die entscheidenen Hinweise gefunden haben:
Hier die Lösung mit dem Generieren der POST-Daten über eine Funktion
https://stackoverflow.com/questions/17029902/using-curl-post-with-variables-defined-in-bash-script-functions

Und hier mit dem Lesen in eine Variable.
https://stackoverflow.com/questions/42990239/curl-post-with-json-data-fails?noredirect=1&lq=1