Laden...

Forenbeiträge von ChristophSharp Ingesamt 6 Beiträge

17.07.2022 - 14:58 Uhr

Habe mich bei der Thematik eingelesen und mehreres ausprobiert.
Komme leider einfach nicht weiter. Hat eventuell einer einen Beispielcode der genau meine Problematik abdeckt.
Oder kann mir einer einen passenden Code für kleines Geld schreiben?

13.06.2022 - 23:31 Uhr

Hallo,
Abt vielen Dank für die Antwort.

Zu Punkt 1 . Verschlüsselung ist mit dem Shelly nicht möglich. Nur Http!

Habe noch einmal etwas zusammengebastelt.
Funktioniert auch wieder ohne Authentifizierung.
Mit der Authentifizierung kommt Fehlercode
System.Net.WebException: 'The remote server returned an error: (401) Unauthorized.'

Hier der Code


 private void LmuButton(object sender, EventArgs e)
        {

            var user = "admin";
            var password = "password";
            var url = "http://192.168.10.68/relay/0?turn=on";




            NetworkCredential myCred = new NetworkCredential(
            user, password);

            CredentialCache myCache = new CredentialCache();

            myCache.Add(new Uri(url), "Digest", myCred);
            

            WebRequest wr = WebRequest.Create(url);
            wr.Credentials = myCache;


            var client = new HttpClient();
            HttpWebResponse response = (HttpWebResponse)wr.GetResponse();


        }

Ja der Code ist noch asynchron.
Hat noch jemand einen Tipp?
Vielen Dank schon mal!

Viele Grüße
Christoph

12.06.2022 - 21:53 Uhr

Hallo liebe Leute,

Möchte in meiner Xamarin Forms App einen Shelly 1 Pro per Url ansprechen.
Seit der Pro Version wird eine Digest Authentifizierung benötigt ansonsten ist der Shelly ungeschützt.

Wenn ich die Authentifizierung ausschalte funktioniert der nachfolgende Code:


 private void LmuButton(object sender, EventArgs e)
             {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://192.168.10.68/relay/0?turn=on");
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            }

Die Doko vom Shelly beinhaltet JavaScript Code die ich bisher leider nicht richtig in c# übersetzen kann.

https://shelly-api-docs.shelly.cloud/gen2/Overview/CommonDeviceTraits/#authentication

Hier Ausschnitte aus der Doku

Schritte im Prozess:

Der Client fordert eine geschützte Ressource an, ohne Anmeldeinformationen bereitzustellen.
Eine Serverantwort mit Fehler 401 (nicht autorisiert) wird empfangen.
Der Client fordert dieselbe geschützte Ressource an, gibt aber diesmal Anmeldeinformationen an.
Die Anforderung ist erfolgreich und der Zugriff auf die Ressource wird gewährt.
Bei der Kommunikation über HTTP muss dieser Vorgang für jede Anfrage wiederholt werden, die Sie an das Gerät senden. Für die Kommunikation über Websocket müssen die Schritte 1 und 2 jedoch nicht mehr als einmal durchlaufen werden: Sie müssen das authObjekt nur einmal erstellen (mehr dazu weiter unten ) und es dann für alle aufeinanderfolgenden Anforderungen an dieses Gerät verwenden.

Authentifizierung über
Bei der Kommunikation über einen HTTP-Kanal finden Sie diese Informationen im WWW-Authenticate- Header der Antwort.

Beispiel:

Anfrage
curl -X POST -i -d '{"id":1, "method":"Shelly.GetStatus"}' http://${SHELLY}/rpc
Antwort


HTTP/1.1 401 Unauthorized
Server: Mongoose/6.18
Content-Type: application/json
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: *
Content-Length: 0
Connection: close
WWW-Authenticate: Digest qop="auth", realm="shellypro4pm-f008d1d8b8b8", nonce="60dc59c6", algorithm=SHA-256

Authentifizierung über
Bei der Kommunikation über einen Websocket-Kanal enthält die Antwort einen Fehlerrahmen, in dem die oben genannten Attribute zu finden sind.

Beispiel:

Anfrage
curl -X POST -d '{"id":1, "method":"Shelly.DetectLocation"}' http://${SHELLY}/rpc
Antwort
{
"id": 1,
"src": "shellypro4pm-f008d1d8b8b8",
"dst": "user_1",
"error": {
"code": 401,
"message": "{"auth_type": "digest", "nonce": 1625038762, "nc": 1, "realm": "shellypro4pm-f008d1d8b8b8", "algorithm": "SHA-256"}"
}
}
Erfolgreiche Anfrage mit
Damit die Anfrage richtig funktioniert, authsollte dem Anfragerahmen ein zusätzliches JSON-Objekt hinzugefügt werden. Es sollte enthalten:


realm: string, device_id des Shelly-Geräts. Erforderlich
username: string, muss auf admin gesetzt werden . Erforderlich
nonce: Zahl, Zufalls- oder Pseudo-Zufallszahl zur Verhinderung von Replay-Angriffen, entnommen aus der Fehlermeldung. Erforderlich
cnonce: Nummer, Client-Nonce, vom Client generierte Zufallszahl. Erforderlich
response: string, Kodierung des Strings <ha1> + ":" + <nonce> + ":" + <nc> + ":" + <cnonce> + ":" + "auth" + ":" + <ha2>in SHA256. Erforderlich
ha1: Zeichenfolge, <user>:<realm>:<password>codiert in SHA256
ha2: string, "dummy_method:dummy_uri" codiert in SHA256
algorithm: Zeichenkette, SHA-256 . Erforderlich

Beispiel:

Anfrage1


curl -X POST -d '{"id":1, "method":"Shelly.DetectLocation", "auth":
 {"realm": "shellypro4pm-f008d1d8b8b8", "username": "admin", "nonce": 1625038762,
 "cnonce": 313273957, "response": "eab75cbbd7acdb7082164cb52148cfbe351f28bf80856f93a23387c6157dbb69",
 "algorithm": "SHA-256"}}' \
  http://${SHELLY}/rpc

Oder:

Anfrage2
curl --digest -u admin:mypass http://${SHELLY}/rpc/Shelly.DetectLocation
Oder:

Anfrage3
curl --anyauth -u admin:mypass -X POST -d '{"id":1, "method":"Shelly.DetectLocation"}' http://${SHELLY}/rpc
Antwort


{
   "id": 1,
   "src": "shellypro4pm-f008d1d8b8b8",
   "dst": "user_1",
   "result": {
      "tz": "Europe/Sofia",
      "lat": 42.67236,
      "lon": 23.38738
   }
}

Ich hoffe mir kann einer weiterhelfen?😉

Viele Grüße
Christoph

09.04.2022 - 11:32 Uhr

Vielen lieben Dank für eure Hilfe!
Jetzt funktioniert es.

Es war allerdings hier noch ein Fehler:


public async Task<Person> GetVornameAsync(int id)
       {

               var person = await _database.Table<Person>.Where(p=>p.ID==id).FirstOrDefault();
               return person;
       }

Und so funktioniert es:


 public async Task<Person> GetPersonAsync(int id)
        {

            var person = await _database.Table<Person>().FirstOrDefaultAsync(p => p.ID == id);
            return person;
        }

Ich hatte die ganze Zeit einen falschen Ansatzpunkt verfolgt.
Angenehmes Wochenende wünsche ich noch!

Christoph

09.04.2022 - 00:31 Uhr

Vielen Dank schon einmal für die Hilfe.
Dennoch komme ich einfach nicht auf die richtige Lösung. Habe jetzt auch wieder alle Varianten durch ob mit Linq oder Query, Asyncron oder nicht, irgendwas klappt nicht.
Habe den Code folgendermaßen geändert:

page.xaml.cs


  private async void LoginButton(object sender, EventArgs e)
        {
            var ausgabe =  await App.Database.GetVornameAsync(200);

            string ausgabe2 = ausgabe.ToString();

            _ = DisplayAlert("Info", ausgabe2, "OK");

        }

Database.cs


 public async Task<Person> GetVornameAsync(int id)
        {
                     
                var v = await _database.QueryAsync<Person>("SELECT Vorname FROM person WHERE ID =" + id);
                var v2 = v.FirstOrDefault();

                return v2;
        }

Nehme ich

Task<List<Person>>

dann funktioniert wieder die FirstOrDefault() Methoden nicht.

Bekomme momentan folgenden Fehler "System.NullReferenceException: 'Object reference not set to an instance of an object"
Rufe ich die App.Database.GetVornameAsync(200) Methode ohne await auf, so habe ich zwar keinen Fehler aber wieder im DisplayAlert
folgenden Text stehen: "System.Threading.Tasks.Task1[System.Collections.Generic.List1[Projekt.Models.Person]]"
Ich hoffe einer hat noch einen Tipp für mich.

Schönes Wochenende

Christoph

07.04.2022 - 23:04 Uhr

Hallo liebe Forumsmitglieder,

suche jetzt schon Tage nach einer Lösung für meine Xamarin App die ich mit Visual Studio erstelle.
Die Dokumentation von Microsoft ist leider in diesem Bereich unvollständig.
Was ich hinbekomme ist folgendes: Sqlite Datenbank erstellen. Daten in Listview hinzufügen ,anzeigen, löschen usw.
Das ganze hört auf wenn ich die Daten aus Sqlite weiterverarbeiten möchte.
Abfragen in einen ListView anzeigen das funktioniert alles soweit. Nur ich bekomme die Daten einfach nicht zurück als String.

Was möchte ich erreichen?

z.B nach der ID 200 in der Datenbank suchen.
Von ID 200 den Vornamen in ein DisplayAlert auf dem Smartphone anzeigen.

Was bekomme ich momentan:

Leider nicht den Vornamen sondern nur folgenden Text:
System.Threading.Tasks.Task1[System.Collections.Generic.List1[Projekt.Models.Person]]

Hier mein Code

Database.cs


  public class Database
    {
        readonly SQLiteAsyncConnection _database;

        public Database(string dbPath)
        {
            _database = new SQLiteAsyncConnection(dbPath);
            _database.CreateTableAsync<Person>().Wait();
            
        }


public Task GetVornameAsync(int id)
        {
            return = _database.QueryAsync<Person>("SELECT Vorname FROM person WHERE ID ="+id);
                     
        }

Person.cs


using System;
using System.Collections.Generic;
using System.Text;
using SQLite;

namespace Test.Models
{
    [Table("person")]
    public class Person
    {
        [PrimaryKey, AutoIncrement]
        public int ID { get; set; }
               
        [MaxLength(250), Unique]
        public string SqlID { get; set; }

        [MaxLength(250)]
        public string Vorname { get; set; }

        [MaxLength(250)]
        public string Nachname { get; set; }

        [MaxLength(250)]
        public string Passwort { get; set; }
        
        public bool Passwort_Speichern { get; set; }

        public bool Admin { get; set; }
               
        public DateTime Letzte_Aktualisierung { get; set; }

        public int Urlaub_Jahr { get; set; }
               
        public int Urlaub_Vorjahr { get; set; }
               
        public int Urlaub_Genommen { get; set; }
               
        public int Urlaub_Rest { get; set; }
              
        public int Ueberstunden { get; set; }

       
    }
    }

page.xaml.cs


  private async void LoginButton(object sender, EventArgs e)
        {
            var ausgabe = App.Database.GetVornameAsync(200);

            string ausgabe2 = ausgabe.ToString();

            _ = DisplayAlert("Info", ausgabe2, "OK");



        }

App.xaml.cs


  public partial class App : Application
    {
        
        static Database database;

        public static Database Database
        {
            get
            {
                

                if (database == null)
                {
                    database = new Database(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "test.db3"));
               }
                return database;

            }
        }

Ich hoffe mir kann endlich einer weiter helfen!

Viele Grüße

Christoph