Laden...

Tibber CURL-Request

Erstellt von Sweeny vor einem Jahr Letzter Beitrag vor einem Jahr 819 Views
S
Sweeny Themenstarter:in
8 Beiträge seit 2023
vor einem Jahr
Tibber CURL-Request

Hallo zusammen,

ich will einen Logikbaustein für den Abruf von Tibber-Strompreisen (Stromanbieter) in einem bestimmten Smart-Home-System entwickeln.
Ich bin fast fertig, aber irgendwie funktioniert der CURL-Abruf nicht. Ich weiß, CURL ist nicht die beste Wahl, aber aufgrund der Beschränkungen des SDK/der Software kann ich nichts anderes verwenden.

Es ist alles nur ein Ausschnitt...

Das Problem: Irgendwie komme ich mit den Backslashes etc. nicht zu recht. Es wird von der API nichts zurückgegeben; ich glaube, ich habe irgendwo einen "Syntax"-Fehler eingebaut.

Hat da jemand eine Idee für mich?


        private static string DownloadByCurl(string str)
        {
            Process process = new Process();
            process.StartInfo.FileName = "curl";
            process.StartInfo.Arguments = str;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError = true;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.StandardOutputEncoding = Encoding.UTF8;
            process.Start();
            string end = process.StandardOutput.ReadToEnd();
            process.WaitForExit();
            return end;          
        }

        public override void Execute()
        {
            if (this.Trigger.WasSet && this.Trigger.Value)
            {
                try
                {
                    string query = "{ \"query:\" \"{viewer {homes {currentSubscription {priceInfo {current {total energy tax startsAt }}}}}} \"}";
                    string url = "-H \"Authorization: Bearer " + this.Token + "\" ";
                    url += "-H \"Content-Type: application/json\" ";
                    url += "-X POST ";
                    url += "-d '" + query + "' ";
                    url += "https://api.tibber.com/v1-beta/gql";

                    string get = DownloadByCurl(url);
                    Root TibberResult = JsonConvert.DeserializeObject<Root>(get);


                    this.Fehler.Value = string.Empty;
                    this.Output.Value = get;
                    this.Output2.Value = url;
                }
...

Offiziell schreibt TIBBER (Token ist natürlich nur ein Demotoken):


curl \
-H "Authorization: Bearer 5K4MVS-OjfWhK_4yrjOlFe1F6kJXPVf7eQYggo8ebAE" \
-H "Content-Type: application/json" \
-X POST \
-d  '{ "query": "{viewer {homes {currentSubscription {priceInfo {current {total energy tax startsAt }}}}}}" }' [url]https://api.tibber.com/v1-beta/gql[/url]

Viele Grüße

Alex

4.938 Beiträge seit 2008
vor einem Jahr

Auf Anhieb sehe ich, daß die Query falsch ist (es ist ja JSON-Format):


string query = "{ \"query\" : /*...*/ }"; // Doppelpunkt außerhalb der Hochkommata

Am besten, du testest es direkt in der Eingabeaufforderung mit curl (setze einen Haltepunkt und kopiere dann den Inhalt der Variablen url).

PS: Hat dir meine Antwort in deinem anderen Thema bzgl. WebRequest weitergeholfen?

T
2.223 Beiträge seit 2008
vor einem Jahr

Warum arbeitest du nicht direkt mit dem HttpClient?
Im Endeffekt machst du nur ein HTTP Post mit Json per CURL, was du auch selbst machen kannst.
Spart den Overhead ein extra Pogramm aufzurufen müssen.
Den Request kannst du, wie schon beim Response, über ein eigenes Objekt zum passenden Json serialisieren lassen.
Dadurch löst du auch direkt deinen falschen Syntax, wie Th69 bemerkt hat.
Ebenfalls sieht auch der Rest des Json falsch aus, da du hier keinen korrekten Aufbau hast.
Kannst du alles mit einer passenden Klasse lösen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

S
Sweeny Themenstarter:in
8 Beiträge seit 2023
vor einem Jahr

Auf Anhieb sehe ich, daß die Query falsch ist (es ist ja JSON-Format):

Ja, richtig. Ich habs geändert. Problem bleibt aber leider gleich.
Ich habe schon in Postman alles nachgebaut, da scheint es aber zu klappen - zumindest kommt überhaupt eine Rückmeldung von der API, also z.B. auch Syntax-Fehler etc.

Bei mir kommt aber gar nix (also Variable GET ist fast immer leer). Als ob der Request gar nicht abgesendet wird. In der Output-Variable URL scheint aber alles richtig zu sein...
Zum Beispiel so:


-H "Authorization: Bearer xxxx_xxx-xxx_o-xxx-xxx" -H "Content-Type: application/json" -X POST -d '{ "query": "{viewer {homes {currentSubscription {priceInfo {current {total energy tax startsAt }}}}}} "}' [url]https://api.tibber.com/v1-beta/gql[/url]

du testest es direkt in der Eingabeaufforderung mit curl (setze einen Haltepunkt und kopiere dann den Inhalt der Variablen url).

Tja, das ist irgendwie auch ein Grundproblem. Ich schreibe das alles für ein Stück Hardware, das eigentlich mit Linux und MONO läuft, debuggen kann ich eigentlich nur auf dem Gerät. Eine spezielle SDK hängt auch noch mittendrin. Oder ich kenne mich nicht gut genug aus.

Zu Deinem PS: Jep, Danke. Hab ich in Griff bekommen. Siehe auch meinen Post gerade.

T
2.223 Beiträge seit 2008
vor einem Jahr

@Sweeny
Wäre toll wenn du auch auf meinen Post eingegangen wärst.
Vermutlich könntest du das mit dem HttpClient und PostAsync direkt lösen.

Ansonsten würde ich, wenn möglich, auch empfehlen von Mono direkt auf die aktuelle .NET Version zu wechseln.
Die gibt es auch für Linux 😉

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

S
Sweeny Themenstarter:in
8 Beiträge seit 2023
vor einem Jahr

Wäre toll wenn du auch auf meinen Post eingegangen wärst.

Ist hier klar Offtopic, nur trotzdem kurz...
Okay... Ich baue den Baustein für einen proprietären Smarthome-Server eines großen deutschen Herstellers. Dieses System nutzt für den Betrieb der c#-Bausteine das Mono-Framework, was der Hersteller leider seit 2017 nicht mehr aktualisiert hat. Ja, das ist schlecht, ja, sie haben gemeldet, dass das System in den nächsten Monaten aktualisiert wird. Dadurch kann ich keine Server über diese Bausteine ansprechen, die aktuellere TLS-Versionen nutzen. Das Betriebssystem selbst kommt allerdings mit TLS 1.2 und TLS 1.3 problemlos klar. Und der Hersteller verhindert nicht, dass man den Betriebssystem-Befehl für den Download (oder Upload) von Dateien nutzt. Daher muss ich CURL nutzen, sagen mir zumindest Leute, die seit Jahren Bausteine für den Server entwickeln.

Natürlich kann man jetzt über den Hersteller ablästern,... lassen wir aber hier 🙂

4.938 Beiträge seit 2008
vor einem Jahr

Auf welcher Hardware dein eigentlicher Code läuft spielt ja für den Aufruf ersteinmal keine Rolle.
Du mußt schauen, daß du ersteinmal einen funktionierenden Aufruf mit CURL hinbekommst (egal, ob von Windows, Linux oder einem anderen System).

T
2.223 Beiträge seit 2008
vor einem Jahr

@Sweeney
Hat nichts mit Offtopic zu tun.
Gehört sogar zu den Grundlagen des Themas und ist auch ein wichtiger Hinweis, den ich als Außenstehender nicht wissen kann.
Diese Info gehört auch direkt in den Start Post, damit man die Ausgangslage kennt und dann auch richtig antworten kann.

Warum man auf Curl setzen muss erklärt sich mir immer noch nicht, da es ja nur ein Http Post macht, den du auch selbst direkt absetzen kannst.
Wenn der Hersteller hier keine Einschränkung auf den User Agent o.ä. macht um nur Curl Anfragen zuzulassen, wäre das eine sinnvollere Option als einen extra Prozess zustarten.
Sowas kann man aber auch recht einfach selbst austesten.

Ebenfalls wäre dann aber immer noch das Json Thema im Raum.
Auch hier würde ich meine Empfehlung beibehalten und es per Serialisierung sauber lösen.
Json Strings selbst zusammen zu setzen ist hier komplett unnötig un kostet dich nur zusätzlich Zeit.
Dafür gbt es System.Text.Json oder Alternativ auch NewtonSoft.Json seit Jahren saubere Lösungen.

Nachtrag:
Hab anhand deines Aufruf mal die Api Doku geprüft.
Hierbei wird GraphQL verwendet aber als query String im Request mitgegeben.
Im einfachsten Fall kannst du dir eine simple Request Klasse mit Query als String anlegen und per Json serialisieren lassen.
Nur die eigentliche Query muss dann sauber umgesetz sein.

Doku:
Tibber Developer

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

S
Sweeny Themenstarter:in
8 Beiträge seit 2023
vor einem Jahr

Du mußt schauen, daß du ersteinmal einen funktionierenden Aufruf mit CURL hinbekommst (egal, ob von Windows, Linux oder einem anderen System).

Das ist gar kein Problem - über Postman geht das:


curl --location --request POST 'https://api.tibber.com/v1-beta/gql' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer xxx-xxx' \
--data-raw '{"query":"query{ viewer { homes { currentSubscription { priceInfo { current { total energy  tax startsAt } } } } } }","variables":{}}'

Ich bekomme es aber eben nicht über c# hin.

4.938 Beiträge seit 2008
vor einem Jahr

Benutzt du das neueste VS? Seit der letzten C#-Version 11 gibt es Raw string literal, d.h. du kannst den gesamten Aufruf direkt in deinen Code einbauen (ohne explizit Zeichen 'escapen' zu müssen).

S
Sweeny Themenstarter:in
8 Beiträge seit 2023
vor einem Jahr

Benutzt du das neueste VS?

Das SDK, das ich nutzen muss, ist da leider nicht kompatibel... Ich glaube auch, es liegt am escapen.

Viele Grüße
Alex

4.938 Beiträge seit 2008
vor einem Jahr

Ich meinte, daß du ersteinmal unter Windows testest, ob der Code funktioniert. Und wenn das klappt, dann baust du den Code nach und nach um, so daß es dann bei deiner anderen Umgebung kompiliert und funktioniert.