Guten Abend Forum,
bin mir nicht ganz sicher ob ich hier ind er richtigen Abteilung bin.. Es geht um Json und wie ich die daten mit Retrofit/Gson (Android) aus FHEM auslesen kann.
Ich habe brereits die cmd=jsonlist2 gefunden, ganz weiter komme ich leider noich nicht.
Wie kann ich daraus einzelen Devices filtern... Ich frage Json mit diesem Befehl ab:
<IP-FHEM>/fhem?cmd=jsonlist2&Name=SZ_Wand_Climate&XHR=1
Soweit ich mich eingelesen habe, muss auch zwischen dem jsonlist2 und Name= ein UND (&) Zeichen stehen.
Das Ergebnis daraus sind alle Devices die ich FHEM angelegt habe.
{
"Arg":"",
"Results": [
{ ALLE DEVICES AUS FHEM
Gebe ich die Abfrage wie folgt ein bekomme ich zumidest das einzelne Gerät. Nur das "&" gegen "%20" getauscht und "Name" entfernt
<IP-FHEM>/fhem?cmd=jsonlist2%20SZ_Wand_Climate&XHR=1
Ergebnis:
{
"Arg":"SZ_Wand_Climate",
"Results": [
{
"Name":"SZ_Wand_Climate",
"PossibleSets":
"Internals": {
"NAME": "SZ_Wand_Climate",
"NOTIFYDEV": "global",
"NR": "106",
"NTFY_ORDER": "50-SZ_Wand_Climate",
"STATE": "T: 18.7 desired: 17.0",
"TYPE": "CUL_HM",
"chanNo": "02",
"device": "SZ_Wand",
"peerList": "SZ_HK_Climate,"
},
"Readings": {
"boostTime": { "Value":"-", "Time":"2020-04-28 14:39:15" },
"commReporting": { "Value":"on", "Time":"2020-04-28 14:39:15" },
"controlMode": { "Value":"auto", "Time":"2020-04-28 14:39:15" },
"desired-temp": { "Value":"17.0", "Time":"2020-05-01 23:17:01" },
"dewpoint": { "Value":"7.9", "Time":"2020-05-01 23:17:01" },
"humidity": { "Value":"55", "Time":"2020-05-01 23:17:01" },
Mich stört irgendwie der Eintrag "Arg" und das man ihn nur gefüllt bekommt wenn man "%20" anstatt "&" eingibt.
Ich bin mir nicht klar wie ich die %20 in zwischen jsonlist2 und SZ_Wand_CLimate in Retrofit programmieren muss..
Ich hoffe ich treffe auf jemanden der sich mit Retrofit oder Gson auskennt!!!!!
Danke!!
Schönen Gruß
Andre
ZitatIch hoffe ich treffe auf jemanden der sich mit Retrofit oder Gson auskennt!!!!!
Ich durfte mich vor Jahren mit dieser Kombo quaelen, und mein Eindruck war, dass jemand eine JSON-Bibliothek implementierte, ohne das Wesen von JSON zu begreifen, dazu kam eine umstaendliche und unflexible HTTP-Bibliothek. Ich qualifiziere mich damit nicht als Kenner dieser Bibliotheken, und nein, ich habe keine Alternativen.
Zu den Beobachtungen:
- JsonList2 ist ein normales FHEM Befehl (siehe Doku (https://fhem.de/commandref_modular.html#JsonList2)), den man in der Kommandozeile ausfuehren kann. Die Argumente werden FHEM-ueblich per Leerzeichen getrennt, und man findet sie in der Antwort im Arg wieder.
- FHEMWEB kann alles ausfuehren, was in der Kommandozeile akzeptiert wird.
- Die Argumente kann man im URL auch anders spezifizieren: wenn man cmd.XXX statt cmd verwendet, dann werden die URL Parameter dev.XXX, arg.XXX und val.XXX an das Befehl mit Leerzeichen angehaengt. D.h.:
http://localhost:8083/fhem?cmd.json=JsonList2&dev.json=global&fwcsrf=csrf_389277372435138&XHR=1
liefert das Ergebnis von "JsonList2 global" zurueck.
Ich meine mit dem zweiten Syntax kann man eine passenden Retrofit-Klasse bauen, in der Art
@GET("fhem")
Observable<Response<String>> fhem(@Query("cmd.retrofit") String cmd, @Query("dev.retrofit") String dev);
(ungetestet!)
Hallo Rudolf Danke für deine ausführliche Antwort. Ich werde das aufjedenfall ausprobieren.
Mich wundert es, das sowas keiner braucht :o
Mein aktuelles Projekt ist es, eine AndroidApp auf mein Smarthome zugeschnitten zu programmieren.
Ich habe gerade noch das Problem, dass ich die "Test App" (einen JSON Abfrage Button ;D ;D) auf meinem Smartphon installiere und dann die Fehlermeldung bekomme -> Cleartext HTTP traffic to <IP-FHEM> not permitted.
Ich habe im lokalen Netzwerk aber garkein Password definiert.
EDIT:
Sorry war ich wohl zu schnell.. Ist kein Problem in FHEM sondern in Android... Behoben mit:
https://stackoverflow.com/questions/39933345/no-network-security-config-specified-using-platform-default-android-log
Falls openssl auf dem FHEM-Rechner installiert ist, dann duerfte das Aktivieren von HTTPS einfach aus Setzen des Attributes bestehen.
Man kriegt zwar nur ein self-signed Zertifikat, aber immerhin.
Hallo Rudolf,
kurz nachdem ich auf deine erste Antwort gestoßen bin hat mir eine Kollege "Volley" für Android empfohlen. Das habe ich gerade als erstes ausprobiert und bin schwer begeistert, dass es funktioniert.
Hier mal ein Java-Code-Schnipsel:
private void jsonParse(String device, String reading, String value) {
String url = "http://<IP-FHEM>/fhem?cmd=jsonlist2%20" + device +"&" + reading +"&XHR=1";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new com.android.volley.Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
//Level0 Abfrage
JSONArray jsonArray = response.getJSONArray("Results");
//Level1 Abfrage
JSONObject jsonObjectLevel1 = jsonArray.getJSONObject(0);
//Level2 Abfrage
JSONObject jsonObjectLevel2 = jsonObjectLevel1.getJSONObject("Readings");
//Level3 Abfrage
JSONObject jsonObjectLevel3 = jsonObjectLevel2.getJSONObject(reading);
//Output aus 1.Abfrage Result
String nameOfDevice = jsonObjectLevel1.getString("Name");
//Output aus 2.Abfrage Results.Readings
String nameOfReading = jsonObjectLevel2.getString(reading);
//Output aus 3.Abfrage Results.Readings
String ValueOfReading = jsonObjectLevel3.getString(value);
mTextViewResult.append("Name: " + nameOfDevice + "\n\n" + "Reading: " + nameOfReading + "\n\n" + "Value: " + ValueOfReading + "\n\n");
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
mTextViewResult.setText(error.getMessage());
}
});
mQueue.add(request);
}
Ich rufe die Methode jsonParse() auf und übergebe die Werte, die ich aus der FHEM-Json lesen möchte in die URL und die Abfragen (hier device, reading, value). Diese hole ich mir dann Objectlevel für Objectlevel ab und schreibe es mir in die Ausgabe (siehe Bild).
Mal sehen wie Volley mit "Posts" umgeht.
EDIT:
Funktionert auch wunderbar!!
Java-Code-Schnipsel:
private void jsonPost(String device, String command, String value) {
String url = "http://<IP-FHEM>/fhem?cmd=set%20" + device +"%20" + command +"%20" + value;
StringRequest postRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>()
{
@Override
public void onResponse(String response) {
// response
Log.d("Response", response);
}
},
new Response.ErrorListener()
{
@Override
public void onErrorResponse(VolleyError error) {
// error
Log.d("Error.Response", String.valueOf(error));
}
}
);
mQueue.add(postRequest);
}
Die URL einfach an den POST angepasst und die POST-Methode von Volley eingesetzt.