Laden...

Forenbeiträge von Sweeny Ingesamt 8 Beiträge

29.01.2023 - 13:55 Uhr

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

29.01.2023 - 10:57 Uhr

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.

29.01.2023 - 09:39 Uhr

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 🙂

28.01.2023 - 20:21 Uhr

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.

28.01.2023 - 20:06 Uhr

Danke Euch. Ich habe es geschafft!

Viele Grüße

Alex

28.01.2023 - 09:43 Uhr

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

23.01.2023 - 06:45 Uhr

Wenn Du den WebRequest beibehalten willst (was ich Dir nicht empfehle, genauso wenig die .NET Docs) - dann musst Du direkt bei Get auf den Response gehen.

Danke, Dir, Abt.
Ich werde mir HTTPClient genauer ansehen; hier aber noch der Abschluss mit WebRequest.

So sieht jetzt der Part aus:


        private string ViewPageGET(CookieContainer cookieJar, string pageURL)
        {
            string str = string.Empty;

            WebRequest request = WebRequest.Create(pageURL);
            request.Method = "GET";
            request.CookieContainer = cookieJar;
            using (WebResponse response = request.GetResponse())
            using (Stream stream = response.GetResponseStream())
            {
                StreamReader reader = new StreamReader(stream, Encoding.UTF8);
                String responseString = reader.ReadToEnd();
                return responseString;
            }
        }

Allerdings wird mir für die Zeile 7 mit dem CookieContainer angezeigt: > Fehlermeldung:

Fehler CS1061 "WebRequest" enthält keine Definition für "CookieContainer", und es wurde keine verfügbare CookieContainer-Erweiterungsmethode gefunden, die ein erstes Argument vom Typ "WebRequest" akzeptiert (möglicherweise fehlt eine using-Direktive oder ein Assemblyverweis).

Hättest Du da noch einen Tipp für mich?

Viele Grüße
Alex

21.01.2023 - 14:40 Uhr

Hallo zusammen,

ich entwickle mit dem .NET Framework 4.5 ein Baustein für ein Smart-Home-System. Genauer gesagt will ich über eine API zuerst eine Authentifizierung erreichen (klappt), dann Daten abrufen (klappt) und weitere Daten über einen weiteren Aufruf abrufen (klappt nicht).

Zuerst brauche ich POST, erhalte nach der Authentifizierung Cookies, die ich in einem CookieContainer speichere (klappt), diesen verwende ich dann wieder bei einem POST-Aufruf (klappt), dann benötige ich nochmals die Cookies für einen GET-Aufruf (klappt nicht). Da erhalte ich dann die Fehlermeldung "Inhaltsteil mit diesem Verbtyp kann nicht gesendet werden.".

Ich habe über Google herausgefunden, dass die Cookies nicht so einfach über GET übermittelt werden können?

Ich würde mich sehr über eine Idee freuen!

Alex

NUR AUSSCHNITT:


        public const string userAgent = "Mozilla/5.0 (Windows NT 6.1; rv:7.0.1) Gecko/20100101 Firefox/7.0.1";
        public CookieContainer cookieJar;

        private CookieContainer Login(string username, string password, string loginPageURL)
        {
            // Create a request using the provied URL. 
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(loginPageURL);

            // Set the Method property of the request to POST.
            request.Method = "POST";

            // Set the Cookiecontainer
            CookieContainer cookieJar = new CookieContainer();
            request.CookieContainer = cookieJar;

            // Create POST data and convert it to a byte array.
            //string postData = "username=" + username + "&password=" + password;
            //byte[] byteArray = Encoding.UTF8.GetBytes(postData);

            // Set the ContentType property of the WebRequest.
            request.ContentType = "application/x-www-form-urlencoded";

            // Set the User Agent
            request.UserAgent = userAgent;

            // Set the ContentLength property of the WebRequest.
            //request.ContentLength = byteArray.Length;

            // Get the request stream.
            Stream dataStream = request.GetRequestStream();

            // Write the data to the request stream.
            //dataStream.Write(byteArray, 0, byteArray.Length);

            // Close the Stream object.
            dataStream.Close();

            // Get the response.
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            // Get the stream containing content returned by the server.
            dataStream = response.GetResponseStream();

            // Open the stream using a StreamReader for easy access.
            StreamReader reader = new StreamReader(dataStream);

            // Read the content.
            string responseFromServer = reader.ReadToEnd();

            string cookie = cookieJar.GetCookieHeader(request.RequestUri);

            Login ID = JsonConvert.DeserializeObject<Login>(responseFromServer);

            this.PlantID.Value = ID.Back.Data[0].PlantId;

            // Clean up the streams.
            reader.Close();
            dataStream.Close();
            response.Close();

            return cookieJar;
        }

        private string ViewPageGET(CookieContainer cookieJar, string pageURL)
        {
            string str = string.Empty;

            HttpWebRequest request2 = (HttpWebRequest)WebRequest.Create(pageURL);

            // Set the Method property of the request to GET.
            request2.Method = "GET";

            // Put session back into CookieContainer
            request2.CookieContainer = cookieJar;

            // Get the request stream.
            Stream dataStream2 = request2.GetRequestStream();

            // Close the Stream object.
            dataStream2.Close();

            // Get the response.
            HttpWebResponse response2 = (HttpWebResponse)request2.GetResponse();

            // Get the stream containing content returned by the server.
            dataStream2 = response2.GetResponseStream();

            // Open the stream using a StreamReader for easy access.
            StreamReader reader2 = new StreamReader(dataStream2);

            // Read the content.
            str = reader2.ReadToEnd();

            return str;
        }

        public override void Execute()
        {
            if (this.Trigger.WasSet && this.Trigger.HasValue)
            {

                 try
                {
                    // URL für Login
                    string loginPageURL = "https://server.growatt.com/newTwoLoginAPI.do?userName=" + this.Benutzername + "&password=" + MD5Passwort;

                    // URL für Jahresproduktion - GET
                    string pageURL2 = "https://server.growatt.com/newPlantDetailAPI.do?plantId=" + this.PlantID + "&date=" + DateTime.Now.Year.ToString() + "&type=3";

                    // URL für Tagesproduktion - GET
                    string pageURL3 = "https://server.growatt.com/newPlantDetailAPI.do?plantId=" + this.PlantID + "&date=" + DateTime.Now.Date.ToString("yyyy-mm-dd") + "&type=1";

                    // Login-Aufruf
                    cookieJar = Login(this.Benutzername, this.Passwort, loginPageURL);

                    // Aufruf 2. API (GET)
                    Root2 Growattlogin2 = JsonConvert.DeserializeObject<Root2>(ViewPageGET(cookieJar, pageURL2));

                    // Aufruf 3. API (GET)
                   Root2 Growattlogin3 = JsonConvert.DeserializeObject<Root2>(ViewPageGET(cookieJar, pageURL3));

                    this.Year.Value = (float) Convert.ToDouble(Growattlogin2.Back.PlantData.CurrentEnergy.Replace(" kWh", ""));
                    this.Today.Value = (float) Convert.ToDouble(Growattlogin3.Back.PlantData.CurrentEnergy.Replace(" kWh", ""));

                    this.Fehler.Value = string.Empty;
                }
                catch (Exception ex)
                {
                    this.Fehler.Value = ex.Message;
                }
            }
}