[erledigt] mal wieder auf Kriegsfuß mit dem Escaping - JSON mittels curl richtig posten

Allgemeines zur HomeMatic Haussteuerung

Moderator: Co-Administratoren

Antworten
Benutzeravatar
Baxxy
Beiträge: 11084
Registriert: 18.12.2018, 15:45
System: Alternative CCU (auf Basis OCCU)
Hat sich bedankt: 638 Mal
Danksagung erhalten: 2299 Mal

[erledigt] mal wieder auf Kriegsfuß mit dem Escaping - JSON mittels curl richtig posten

Beitrag von Baxxy » 05.09.2022, 17:10

Irgendwelche Strings (für Homematic-Script) richtig zu escapen hat mich schon viele Nerven gekostet, so auch diese mal.

Ziel der Übung ist es eine oder mehrere Variablen in ein JSON zu verpacken und das Ganze dann per curl POST in einen Homeassistant-Sensor zu schreiben.

Das valide und funktionale json sieht so aus:

Code: Alles auswählen

curl -X POST http://192.168.113.11:8123/api/states/input_number.strompreis
   -H "Authorization: Bearer baxxy_kann_das_nicht123" \
   -H "Content-Type: application/json" \
   -d '{"state": "0.37", "attributes": {"unit_of_measurement": "€/kWh", "editable": "true", "min": "0", "max": "2", "step": "1", "mode": "box", "icon": "mdi:currency-eur", "friendly_name": "Strompreis_Test"}}' \
Escaped für die Konsole (funktional) so:

Code: Alles auswählen

curl -X POST http://192.168.113.11:8123/api/states/input_number.strompreis -H "Authorization: Bearer baxxy_kann_das_nicht123" -H "Content-Type: application/json" -d "{\"state\": \"0.37\", \"attributes\": {\"unit_of_measurement\": \"€/kWh\", \"editable\": \"true\", \"min\": \"0\", \"max\": \"2\", \"step\": \"1\", \"mode\": \"box\", \"icon\": \"mdi:currency-eur\", \"friendly_name\": \"Strompreis_Test\"}}"
Und nun der Homematic-Teil, aktueller Stand:

Code: Alles auswählen

var value = 0.36;
string curlcmd = "curl -v -X POST http://192.168.113.11:8123/api/states/input_number.strompreis -H ";
string jsondaten = '"Authorization: Bearer baxxy_kann_das_nicht123" -H "Content-Type: application/json" -d "{\"state\": \"'#value#'\", \"attributes\": {\"unit_of_measurement\": \"€/kWh\", \"editable\": \"true\", \"min\": \"0\", \"max\": \"2\", \"step\": \"1\", \"mode\": \"box\", \"icon\": \"mdi:currency-eur\", \"friendly_name\": \"Strompreis_Test\"}}"';
string combined = curlcmd + jsondaten;
string out;
system.Exec(combined ,&out);
WriteLine(out);
Ergebnis:

Code: Alles auswählen

{"message":"Invalid JSON specified."}
Ich habe schon zig Versuche mit dem SDV und online-Escapern durch, bekomme das aber nicht auf die Reihe.

Wäre super wenn jemand funktionale Hinweise oder besser noch gleich ein funktionale Beispiel hätte, gerne auch mit meinen Beispieldaten. :mrgreen:
Zuletzt geändert von Baxxy am 05.09.2022, 23:12, insgesamt 1-mal geändert.

MichaelN
Beiträge: 9850
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 712 Mal
Danksagung erhalten: 1671 Mal

Re: mal wieder auf Kriegsfuß mit dem Escaping - JSON mittels curl richtig posten

Beitrag von MichaelN » 05.09.2022, 17:16

Wieso benutzt du nicht einfach ^ als string delemiter?
LG, Michael.

Wenn du eine App zur Bedienung brauchst, dann hast du kein Smarthome.

Wettervorhersage über AccuWeather oder OpenWeatherMap+++ Rollladensteuerung 2.0 +++ JSON-API-Ausgaben auswerten +++ undokumentierte Skript-Befehle und Debugging-Tipps +++

Benutzeravatar
Baxxy
Beiträge: 11084
Registriert: 18.12.2018, 15:45
System: Alternative CCU (auf Basis OCCU)
Hat sich bedankt: 638 Mal
Danksagung erhalten: 2299 Mal

Re: mal wieder auf Kriegsfuß mit dem Escaping - JSON mittels curl richtig posten

Beitrag von Baxxy » 05.09.2022, 17:23

Hmm, wo denn? Bei jsondaten?

Dann bekomme ich value irgendwie nicht rein.

MichaelN
Beiträge: 9850
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 712 Mal
Danksagung erhalten: 1671 Mal

Re: mal wieder auf Kriegsfuß mit dem Escaping - JSON mittels curl richtig posten

Beitrag von MichaelN » 05.09.2022, 17:33

Mich überfordert das auch immer wieder. Ich hätte gedacht mit ^ kannst du anschließend die " angeben wie erforderlich, da die in Homematic Script dann keine Funktion mehr haben bis zum nächsten ^
LG, Michael.

Wenn du eine App zur Bedienung brauchst, dann hast du kein Smarthome.

Wettervorhersage über AccuWeather oder OpenWeatherMap+++ Rollladensteuerung 2.0 +++ JSON-API-Ausgaben auswerten +++ undokumentierte Skript-Befehle und Debugging-Tipps +++

Benutzeravatar
Henke
Beiträge: 1543
Registriert: 27.06.2022, 20:51
System: CCU
Hat sich bedankt: 144 Mal
Danksagung erhalten: 315 Mal

Re: mal wieder auf Kriegsfuß mit dem Escaping - JSON mittels curl richtig posten

Beitrag von Henke » 05.09.2022, 17:53

Code: Alles auswählen

! soll: curl -v -X POST http://192.168.113.11:8123/api/states/input_number.strompreis -H "Authorization: Bearer baxxy_kann_das_nicht123" -H "Content-Type: application/json" -d "{\"state\": \"0.37\", \"attributes\": {\"unit_of_measurement\": \"€/kWh\", \"editable\": \"true\", \"min\": \"0\", \"max\": \"2\", \"step\": \"1\", \"mode\": \"box\", \"icon\": \"mdi:currency-eur\", \"friendly_name\": \"Strompreis_Test\"}}"
!  ist: curl -v -X POST http://192.168.113.11:8123/api/states/input_number.strompreis -H "Authorization: Bearer baxxy_kann_das_nicht123" -H "Content-Type: application/json" -d "{"state": "0.360000", "attributes": {"unit_of_measurement": "€/kWh", "editable": "true", "min": "0", "max": "2", "step": "1", "mode": "box", "icon": "mdi:currency-eur", "friendly_name": "Strompreis_Test"}}"
Ich mach dir das mal in schön...

Der sollte laufen:

Code: Alles auswählen

string jsondaten = '"Authorization: Bearer baxxy_kann_das_nicht123" -H "Content-Type: application/json" -d "{\\\"state\\\": \\\"'#value#'\\\", \\\"attributes\\\": {\\\"unit_of_measurement\\\": \\\"€/kWh\\\", \\\"editable\\\": \\\"true\\\", \\\"min\\\": \\\"0\\\", \\\"max\\\": \\\"2\\\", \\\"step\\\": \\\"1\\\", \\\"mode\\\": \\\"box\\\", \\\"icon\\\": \\\"mdi:currency-eur\\\", \\\"friendly_name\\\": \\\"Strompreis_Test\\\"}}"';
Aber der ist besser zu warten und testen:

Code: Alles auswählen

var value = 0.36;
string AN = '\\\"';
string curlcmd = "curl -v -X POST http://192.168.113.11:8123/api/states/input_number.strompreis";
curlcmd = curlcmd # ' -H "Authorization: Bearer baxxy_kann_das_nicht123"';
curlcmd = curlcmd # ' -H "Content-Type: application/json"';
string jsondaten = ' -d ';
jsondaten = jsondaten # '"{';
jsondaten = jsondaten #AN#'state'#AN# ': ' #AN#value#AN# ',';
jsondaten = jsondaten #AN#'attributes'#AN#': {'#AN#'unit_of_measurement'#AN#': '#AN#'€/kWh'#AN#', '#AN#'editable'#AN#': '#AN#'true'#AN#', '#AN#'min'#AN#': '#AN#'0'#AN#', '#AN#'max'#AN#': '#AN#'2'#AN#', '#AN#'step'#AN#': '#AN#'1'#AN#', '#AN#'mode'#AN#': '#AN#'box'#AN#', '#AN#'icon'#AN#': '#AN#'mdi:currency-eur'#AN#', '#AN#'friendly_name'#AN#': '#AN#'Strompreis_Test'#AN#'}';
jsondaten = jsondaten # '}"';
string combined = curlcmd # jsondaten;
! WriteLine(combined);
string out;
system.Exec(combined ,&out);
WriteLine(out);

! curl -v -X POST http://192.168.113.11:8123/api/states/input_number.strompreis -H "Authorization: Bearer baxxy_kann_das_nicht123" -H "Content-Type: application/json" -d "{\"state\": \"0.360000\",\"attributes\": {\"unit_of_measurement\": \"€/kWh\", \"editable\": \"true\", \"min\": \"0\", \"max\": \"2\", \"step\": \"1\", \"mode\": \"box\", \"icon\": \"mdi:currency-eur\", \"friendly_name\": \"Strompreis_Test\"}}"
! curl -v -X POST http://192.168.113.11:8123/api/states/input_number.strompreis -H "Authorization: Bearer baxxy_kann_das_nicht123" -H "Content-Type: application/json" -d "{\"state\": \"0.360000\",\"attributes\": {\"unit_of_measurement\": \"€/kWh\", \"editable\": \"true\", \"min\": \"0\", \"max\": \"2\", \"step\": \"1\", \"mode\": \"box\", \"icon\": \"mdi:currency-eur\", \"friendly_name\": \"Strompreis_Test\"}}"

Benutzeravatar
Henke
Beiträge: 1543
Registriert: 27.06.2022, 20:51
System: CCU
Hat sich bedankt: 144 Mal
Danksagung erhalten: 315 Mal

Re: mal wieder auf Kriegsfuß mit dem Escaping - JSON mittels curl richtig posten

Beitrag von Henke » 05.09.2022, 19:01

Nicht wirklich zufriedenstellend.
Teste mal diese beiden Methoden. Die erste angepasst und ein "quick and dirty" um dauerhaft die Problematik zu umgehen.

Code: Alles auswählen

var value = 0.36;

! Version 1 ---------------------------------------
string curlcmd = "curl -v -X POST http://192.168.113.11:8123/api/states/input_number.strompreis";
curlcmd = curlcmd # ' -H "Authorization: Bearer baxxy_kann_das_nicht123"';
curlcmd = curlcmd # ' -H "Content-Type: application/json"';
string jsondaten = ' -d ';
jsondaten = jsondaten # '"{';
jsondaten = jsondaten # '%22state%22: %22' #value# '%22,';
jsondaten = jsondaten # '%22attributes%22: {%22unit_of_measurement%22: %22€/kWh%22, %22editable%22: %22true%22, %22min%22: %220%22, %22max%22: %222%22, %22step%22: %221%22, %22mode%22: %22box%22, %22icon%22: %22mdi:currency-eur%22, %22friendly_name%22: %22Strompreis_Test%22}';
jsondaten = jsondaten # '}"';
string combined = curlcmd # jsondaten;
combined = combined.UriDecode();
WriteLine( 'Lesbar:' # combined);
WriteLine( 'Exec:' #combined.UriEncode());
string out;
system.Exec(combined.UriEncode() ,&out);
WriteLine(out);

! Version 2 ---------------------------------------
! Quick and dirty

! Input testen, läuft, hierhin kopieren
string aa = 'curl -v -X POST http://192.168.113.11:8123/api/states/input_number.strompreis -H "Authorization: Bearer baxxy_kann_das_nicht123" -H "Content-Type: application/json" -d "{\"state\": \"0.360000\",\"attributes\": {\"unit_of_measurement\": \"€/kWh\", \"editable\": \"true\", \"min\": \"0\", \"max\": \"2\", \"step\": \"1\", \"mode\": \"box\", \"icon\": \"mdi:currency-eur\", \"friendly_name\": \"Strompreis_Test\"}}"';
WriteLine(aa.UriDecode());
WriteLine(aa.UriEncode());
! Output kopieren
string bb =  'curl%20%2Dv%20%2DX%20POST%20http%3A%2F%2F192%2E168%2E113%2E11%3A8123%2Fapi%2Fstates%2Finput%5Fnumber%2Estrompreis%20%2DH%20%22Authorization%3A%20Bearer%20baxxy%5Fkann%5Fdas%5Fnicht123%22%20%2DH%20%22Content%2DType%3A%20application%2Fjson%22%20%2Dd%20%22%7B%22state%22%3A%20%220%2E360000%22%2C%22attributes%22%3A%20%7B%22unit%5Fof%5Fmeasurement%22%3A%20%22%80%2FkWh%22%2C%20%22editable%22%3A%20%22true%22%2C%20%22min%22%3A%20%220%22%2C%20%22max%22%3A%20%222%22%2C%20%22step%22%3A%20%221%22%2C%20%22mode%22%3A%20%22box%22%2C%20%22icon%22%3A%20%22mdi%3Acurrency%2Deur%22%2C%20%22friendly%5Fname%22%3A%20%22Strompreis%5FTest%22%7D%7D%22';

! Stelle mit Wert suchen und eintragen
string bex =  'curl%20%2Dv%20%2DX%20POST%20http%3A%2F%2F192%2E168%2E113%2E11%3A8123%2Fapi%2Fstates%2Finput%5Fnumber%2Estrompreis%20%2DH%20%22Authorization%3A%20Bearer%20baxxy%5Fkann%5Fdas%5Fnicht123%22%20%2DH%20%22Content%2DType%3A%20application%2Fjson%22%20%2Dd%20%22%7B%22state%22%3A%20%22' # value #
'%22%2C%22attributes%22%3A%20%7B%22unit%5Fof%5Fmeasurement%22%3A%20%22%80%2FkWh%22%2C%20%22editable%22%3A%20%22true%22%2C%20%22min%22%3A%20%220%22%2C%20%22max%22%3A%20%222%22%2C%20%22step%22%3A%20%221%22%2C%20%22mode%22%3A%20%22box%22%2C%20%22icon%22%3A%20%22mdi%3Acurrency%2Deur%22%2C%20%22friendly%5Fname%22%3A%20%22Strompreis%5FTest%22%7D%7D%22';
WriteLine( 'Und ab zum Exec: ' # bex );
system.Exec(bex ,&out);

! Sollte klappen und wenn es steht kann alles zwischen "Input testen" und 'Stelle mit Wert suchen' raus.
LG
Michael

Benutzeravatar
Black
Beiträge: 5552
Registriert: 12.09.2015, 22:31
System: Alternative CCU (auf Basis OCCU)
Wohnort: Wegberg
Hat sich bedankt: 435 Mal
Danksagung erhalten: 1097 Mal
Kontaktdaten:

Re: mal wieder auf Kriegsfuß mit dem Escaping - JSON mittels curl richtig posten

Beitrag von Black » 05.09.2022, 20:39

hilft dir diese zeile weiter ?

Code: Alles auswählen

string jsondaten = ^"Authorization: Bearer baxxy_kann_das_nicht123" -H "Content-Type: application/json" -d "{\"state\": \"^#value#^\", \"attributes\": {\"unit_of_measurement\": \"€/kWh\", \"editable\": \"true\", \"min\": \"0\", \"max\": \"2\", \"step\": \"1\", \"mode\": \"box\", \"icon\": \"mdi:currency-eur\", \"friendly_name\": \"Strompreis_Test\"}}"^;
black
Wenn das Fernsehprogramm immer mehr durch nervende Werbung unterbrochen wird und der Radiomoderator nur noch Müll erzählt, ist es besser, die Zeit für sinnvolle Dinge zu nutzen -
mal aufs Klo zu gehen, ein Bier zu holen oder einfach mal den roten AUS-Knopf zu drücken. Klick - und weg

Script Time Scheduler V1.3
AstroSteuerung über Zeitmodul flexibel mit Offset / spätestens, frühestens
SDV 5.03.01 Das umfassende Entwicklungs und Diagnosetool für Homematik
Selektive Backups - Nützliche Dinge, die die WebUI nicht kann

Intel NUC6 Celeron 16GB mit 512GB SSD unter Proxxmox mit insgesamt 5 VM: 2 x bloatwarebefreiter Raspberrymatik, 2 x IOBroker als Middleware und einer MariaDB zur Archivierung. Verbrauch: 6W

technical contribution against annoying advertising

Benutzeravatar
Baxxy
Beiträge: 11084
Registriert: 18.12.2018, 15:45
System: Alternative CCU (auf Basis OCCU)
Hat sich bedankt: 638 Mal
Danksagung erhalten: 2299 Mal

Re: mal wieder auf Kriegsfuß mit dem Escaping - JSON mittels curl richtig posten

Beitrag von Baxxy » 05.09.2022, 21:00

Zunächst mal besten Dank für die Hilfe und die ganzen Beispiele.
Henke hat geschrieben:
05.09.2022, 17:53
Der sollte laufen:
Leider läuft nichts davon, aber...
es lag gar nicht am escaping.
Genau genommen war ich schon nah dran bei einem der Versuche:

Code: Alles auswählen

string jsondaten = '"Authorization: Bearer baxxy_kann_das_nicht123" -H "Content-Type: application/json" -d "{\\"state\\": \\"'#value.ToString(2)#'\\", \\"attributes\\": {\\"unit_of_measurement\\": \\"€/kWh\\", \\"editable\\": \\"true\\", \\"min\\": \\"0\\", \\"max\\": \\"2\\", \\"step\\": \\"1\\", \\"mode\\": \\"box\\", \\"icon\\": \\"mdi:currency-eur\\", \\"friendly_name\\": \\"Strompreis_Test\\"}}"'; 
Spielverderber ist hier eindeutig das - Zeichen.
Geht das noch problemlos über die Konsole klemmt's...
mit dem SDV:

Code: Alles auswählen

{"message":"Invalid JSON specified."}
und 
> Host: 192.168.113.11:8123
> User-Agent: curl/7.84.0
> Accept: */*
> Authorization: Bearer baxxy_kann_das_nicht123
> Content-Type: application/json
> Content-Length: 201
> 
} [201 bytes data]
< HTTP/1.1 400 Bad Request
< Content-Type: application/json
< Content-Length: 37
< Date: Mon, 05 Sep 2022 18:48:29 GMT
< Server: Python/3.10 aiohttp/3.8.1
mit "Script testen" in der RaspberryMatic:
hier geht das Json durch, aber das € - Zeichen wird zum ? (Fragezeichen)

Code: Alles auswählen

"unit_of_measurement":"?/kWh",
und
> Host: 192.168.113.11:8123
> User-Agent: curl/7.84.0
> Accept: */*
> Authorization: Bearer baxxy_kann_das_nicht123
> Content-Type: application/json
> Content-Length: 201
> 
} [201 bytes data]
< HTTP/1.1 200 OK
< Content-Type: application/json
< Location: /api/states/input_number.strompreis
< Content-Length: 429
< Date: Mon, 05 Sep 2022 18:55:36 GMT
< Server: Python/3.10 aiohttp/3.8.1
@Black, gucke ich mir später noch an.

Benutzeravatar
Black
Beiträge: 5552
Registriert: 12.09.2015, 22:31
System: Alternative CCU (auf Basis OCCU)
Wohnort: Wegberg
Hat sich bedankt: 435 Mal
Danksagung erhalten: 1097 Mal
Kontaktdaten:

Re: mal wieder auf Kriegsfuß mit dem Escaping - JSON mittels curl richtig posten

Beitrag von Black » 05.09.2022, 21:52

@Baxxy:
Alternativ hätte ich noch das für dich:

Code: Alles auswählen

string jsondaten = '"Authorization: Bearer baxxy_kann_das_nicht123" -H "Content-Type: application/json" -d \'{"state": "'#value#'", "attributes": {"unit_of_measurement": "€/kWh", "editable": "true", "min": "0", "max": "2", "step": "1", "mode": "box", "icon": "mdi:currency-eur", "friendly_name": "Strompreis_Test"}}\'';  
Wenn das Fernsehprogramm immer mehr durch nervende Werbung unterbrochen wird und der Radiomoderator nur noch Müll erzählt, ist es besser, die Zeit für sinnvolle Dinge zu nutzen -
mal aufs Klo zu gehen, ein Bier zu holen oder einfach mal den roten AUS-Knopf zu drücken. Klick - und weg

Script Time Scheduler V1.3
AstroSteuerung über Zeitmodul flexibel mit Offset / spätestens, frühestens
SDV 5.03.01 Das umfassende Entwicklungs und Diagnosetool für Homematik
Selektive Backups - Nützliche Dinge, die die WebUI nicht kann

Intel NUC6 Celeron 16GB mit 512GB SSD unter Proxxmox mit insgesamt 5 VM: 2 x bloatwarebefreiter Raspberrymatik, 2 x IOBroker als Middleware und einer MariaDB zur Archivierung. Verbrauch: 6W

technical contribution against annoying advertising

Benutzeravatar
Baxxy
Beiträge: 11084
Registriert: 18.12.2018, 15:45
System: Alternative CCU (auf Basis OCCU)
Hat sich bedankt: 638 Mal
Danksagung erhalten: 2299 Mal

Re: mal wieder auf Kriegsfuß mit dem Escaping - JSON mittels curl richtig posten

Beitrag von Baxxy » 05.09.2022, 23:08

So nun noch mal zusammengefasst mit allen funktionierenden Beispielen.
Sortiert nach "Stringlänge" von jsondaten. :wink:

Code: Alles auswählen

!- CURL JSON-POST Test
string stdout; string stderr;

var value = 0.39;
string unit = "EUR/kWh";
string curlcmd = "curl -v http://192.168.113.11:8123/api/states/input_number.strompreis";
string token = "baxxy_kann_das_nicht123";

!- @Black (A)
 string jsondaten = " -H "+'"Authorization: Bearer '#token#'" -H "Content-Type: application/json" -d \'{"state": "'#value.ToString(2)#'", "attributes": {"unit_of_measurement": "'#unit#'", "editable": "true", "min": "0", "max": "2", "step": "1", "mode": "box", "icon": "mdi:currency-eur", "friendly_name": "Strompreis_Test"}}\'';
!- @Black (B)
!string jsondaten = " -H "+^"Authorization: Bearer ^#token#^" -H "Content-Type: application/json" -d "{\"state\": \"^#value.ToString(2)#^\", \"attributes\": {\"unit_of_measurement\": \"^#unit#^\", \"editable\": \"true\", \"min\": \"0\", \"max\": \"2\", \"step\": \"1\", \"mode\": \"box\", \"icon\": \"mdi:currency-eur\", \"friendly_name\": \"Strompreis_Test\"}}"^;
!- @Baxxy (C)
!string jsondaten = " -H "+'"Authorization: Bearer '#token#'" -H "Content-Type: application/json" -d "{\\"state\\": \\"'#value.ToString(2)#'\\", \\"attributes\\": {\\"unit_of_measurement\\": \\"'#unit#'\\", \\"editable\\": \\"true\\", \\"min\\": \\"0\\", \\"max\\": \\"2\\", \\"step\\": \\"1\\", \\"mode\\": \\"box\\", \\"icon\\": \\"mdi:currency-eur\\", \\"friendly_name\\": \\"Strompreis_Test\\"}}"';
!- @Henke (D)
!string jsondaten = " -H "+'"Authorization: Bearer '#token#'" -H "Content-Type: application/json" -d "{\\\"state\\\": \\\"'#value.ToString(2)#'\\\", \\\"attributes\\\": {\\\"unit_of_measurement\\\": \\\"'#unit#'\\\", \\\"editable\\\": \\\"true\\\", \\\"min\\\": \\\"0\\\", \\\"max\\\": \\\"2\\\", \\\"step\\\": \\\"1\\\", \\\"mode\\\": \\\"box\\\", \\\"icon\\\": \\\"mdi:currency-eur\\\", \\\"friendly_name\\\": \\\"Strompreis_Test\\\"}}"';

string combined = curlcmd + jsondaten;
!WriteLine(combined);

system.Exec(combined , &stdout, &stderr);
WriteLine(stdout);
WriteLine(stderr);
Das eigentliche Problem war tatsächlich nicht das escapen, sondern es ist das €-Zeichen. Ohne dem läuft's!

Danke an alle Helfer und Tippgeber! :)

Antworten

Zurück zu „HomeMatic allgemein“