Einfaches Codebeispiel Java/Android Set Lampe on / Lampe off ?

Begonnen von jmbtlb1, 27 Dezember 2018, 12:09:18

Vorheriges Thema - Nächstes Thema

jmbtlb1

Hallo zusammen,
ich suche ein einfaches Java/Android Codebeispiel aus dem hervorgeht wie die Kommunikation zwischen fhem und einer Android Java App läuft

Also z.B. eine App mit 2 Buttons , etwa so:

Knopf1 drücken  -> Set LampeWZ on
Knopf2 drücken -> Set LampeWZ off

Ich bin relativ fit in VB , Java habe ich gerade erst angefangen.

Freu mich über eine Rückmeldung !

Gruß & Danke
Michael

Felix_86

Ich habe in diesem Fall mit einem Telnet-Kommando gearbeitet, dass ich aus der Android App über das Netzwerk an FHEM schicke.
Sicher nicht die beste / sicherste Lösung, aber zuvor den csrfToken aus der Web-URL zu parsen, war mir auf Android / Java doch zu viel.

private void commandSendtoFHEM() {

        try {
            Socket fhemTelnetSocket = new Socket(servername, serverport);
            out = new PrintWriter(fhemTelnetSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(fhemTelnetSocket.getInputStream()));
            out.println("setreading Dummy_Pepper action_to toFHEM");
            out.println("set Dummy_Pepper Pepper ruft Hilfe");

            // Führt zum hängenbleiben
            // output = in.readLine();

            out.close();
            in.close();
            fhemTelnetSocket.close();

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
Grüße von Felix

Pi3, Raspbian 11, FHEM 6.2, ca 320 Device
SIGNALduino (TCM, TX, IT), CUL (EM, FS20, HMS), JeeLink (PCA301), HUEBridge, HUEDevice, mailcheck, echodevice, alexa, TelegramBot, Weather (OWM), DWD_OpenData, FRITZBOX, TabletUI, Calendar, Abfall, Vitoconnect, LGTV_WebOS

Felix_86

Zitat von: jmbtlb1 per PM erhalten am 02.01.2019 um 12:43:26
Hallo Felix
erstmal : Ein schönes neues Jahr 2019 !

Ich habe mal versucht deine Anregung so um zusetzten.
Da tut sich aber nix, keine Fehlermeldung aber auch keine Reaktion im FHEM
Wo ist da mein Denkfehler ?
Gruß & Danke aus Münster
Michael

private   void btnFHEM(){
         try {
              Socket fhemTelnetSocket = new Socket("192.168.178.48", 7072);
              out = new PrintWriter(fhemTelnetSocket.getOutputStream(), true);
             //out.println("set%20WZ_Lampe_Fenster%20on");
              out.println("fhem?cmd=set WZ_Lampe_Fenster on");
             // out.println("set WZ_Lampe_Fenster on");
              out.close();
              fhemTelnetSocket.close();
         }
         catch (IOException ex){
           textView.setText(ex.getMessage());
           Toast.makeText(this, "Fehler", Toast.LENGTH_SHORT).show();
         }
    }

Nach meinem Wissen und bisheriger Umsetzung schickt man das Telnet-Kommando so, wie man es in der FHEM Komandozeile im Webinterface auch einträgt. Also z.B. "set WZ_Lampe_Fenster on" und nicht "set%20WZ_Lampe_Fenster%20on" oder irgendwas mit "fhem?cmd" (das ist nur bei Verwendung eines HTTP Request erforderlich (z.B. mittels curl)).

Ich würde mittels tcpdump (Raspberry) oder Wireshark (Windows) auf dem FHEM-Zielsystem erstmal nachschauen, ob dort die Telnet-Pakete aus der Android App überhaupt ankommen.
Anhand der Reaktion des FHEM-Zielsystem kann man dann evtl. Rückschlüsse ziehen.

Gibt es denn im FHEM Event Monitor im Webinterface Einträge, wenn du das Telnet-Kommando schickst?
Grüße von Felix

Pi3, Raspbian 11, FHEM 6.2, ca 320 Device
SIGNALduino (TCM, TX, IT), CUL (EM, FS20, HMS), JeeLink (PCA301), HUEBridge, HUEDevice, mailcheck, echodevice, alexa, TelegramBot, Weather (OWM), DWD_OpenData, FRITZBOX, TabletUI, Calendar, Abfall, Vitoconnect, LGTV_WebOS

jmbtlb1

Das erstes Codebeispiel schaltet die Lampe an , aber dabei wird natürlich das FHEM Webinterface aufgerufen, was ich nicht brauche, aber immerhin : Lampe an !

Im 2. Beispiel habe ich versucht das auf eine URL Connection umzubauen , das tut sich aber nichts ...

Beispiel 1
private void btnIntendParse(){
        // ->  Lampe schaltet ein durch  Aufruf der FHEM Webseite Port 8083
        //     Eintrag im fhem Logfile vorhanden
        //     soweit so gut : Aber ich suche  ein Codeschnipsel OHNE die Page zu öffnen :)
        sURL ="http://192.168.178.48:8083/fhem?cmd=set%20WZ_Lampe_Fenster%20on";
        Intent URLparse = new Intent();
        URLparse.setAction((Intent.ACTION_VIEW));
        URLparse.setData(Uri.parse(sURL));
        startActivity(URLparse);
    }


2.Beispiel
    private   void btnFHEMWebURL(){
        try {
            // Idee war hier die Webseite ohen Öffnen anzusprechen , da tut sich aber leider Nichts
            URL uURL = new URL("http://192.168.178.48:8083");
            HttpURLConnection urlConnection = (HttpURLConnection) uURL.openConnection();
            PrintStream outStream = new PrintStream(urlConnection.getOutputStream());
            outStream.println("/fhem?cmd=set%20WZ_Lampe_Fenster%20on");
            outStream.close();
        }
        catch (IOException exe){
            textView.setText(exe.getMessage());
            Toast.makeText(this, "Fehler", Toast.LENGTH_SHORT).show();
        }
    }

vbs

Ich würde die Requests erstmal "trocken" üben, also im Browser, perl curl oder Postman o.ä.

Desweiteren mal im Forum gucken, z.B.:
https://forum.fhem.de/index.php?topic=43159.0

Konkret, ich glaube auch bei dir fehlt "&XHR=1".

Üblicherweise liefert der Webserver bzw. der TCP-Stack eine Fehlermeldung zurück, die sehr hilfreich ist, um die Lösung zu finden. Der solltest du in jedem Fall Beachtung schenken.

jmbtlb1

Beispiel 1 mit parse:
&XHR=1 war schon mal ein guter Hinweis

Manuell eingegeben schaltet : set%20WZ_Lampe_Fenster%20on&XHR=1

sauber ein.
FHEM Webseitenaufruf im Beispiel1 wird jetzt unterdrückt , der Browser bleibt offen
Frage : Kann man den nach dem parsen per Programmbefehl schliessen ?
Im Postmanprotokoll sind keine Auffälligkeiten


Bei Beispiel 2 gibt es keine  Fehlermeldung , es passiert einfach nichts

Gruß Michael

vbs


Felix_86

Da ich nicht mit einem HTTP Request arbeite, sondern einfach nur ein Telnet-Kommando mit der entsprechenden Aktion schicke und das zuverlässig und problemlos läuft, bin ich raus.
Wie oben geschrieben, habe ich mich mit dem Senden eines HTTP Request nicht auseinander gesetzt - sehe aktuell auch keinen Vorteil.
Grüße von Felix

Pi3, Raspbian 11, FHEM 6.2, ca 320 Device
SIGNALduino (TCM, TX, IT), CUL (EM, FS20, HMS), JeeLink (PCA301), HUEBridge, HUEDevice, mailcheck, echodevice, alexa, TelegramBot, Weather (OWM), DWD_OpenData, FRITZBOX, TabletUI, Calendar, Abfall, Vitoconnect, LGTV_WebOS

vbs

Telnet ist mMn keine gute Wahl aus mehreren Gründen. Soweit ich weiß mittlerweile auch defaultmäßig deaktiviert in FHEM.

rudolfkoenig

ZitatTelnet ist mMn keine gute Wahl aus mehreren Gründen. Soweit ich weiß mittlerweile auch defaultmäßig deaktiviert in FHEM.
telnet ist eine "plain TCP" Schnittstelle, sie nennt sich telnet, weil man mit dem telnet Programm bedienbar ist, sie beherrscht aber nur das "Passwort nicht zeigen" telnet Escape Sequenz.
Sie ist nicht mehr Teil der ausgelieferten fhem.cfg, damit der FHEM-Anfaenger weniger verwirrt wird.
Es spricht nichts dagegen, fuer solche Faelle sie zu aktivieren.

Die mir bekannten Alternativen zu telnet sind:
- HTTP, ueber FHEMWEB. Hier muss man die FHEMWEB spezifische Syntax befolgen, die Parameter sind URL-kodiert.
- MQTT, z.Bsp. ueber MQTT2_SERVER. Man setzt rawEvents, und fuehrt per notify Befehle aus.

Alle drei Methoden kann man mit SSL und Passwort schuetzen, ich wuerde diejenige waehlen, dessen Client-Bibliothek ich am besten beherrsche.

Werner Schäffer

#10
Zitat von: vbs am 05 Januar 2019, 15:51:28
Telnet ist mMn keine gute Wahl aus mehreren Gründen. Soweit ich weiß mittlerweile auch defaultmäßig deaktiviert in FHEM.

Ich habe telnet bei mir aktiviert ohne Passwort aber nur für Zugriffe von localhost. Damit kommuniziert fhem.js, ein Nodejs Server, mit dem fhem.
Über das Netz sollte man telnet allerdings nicht zulassen, das ist dann ein offenes Scheunentor, vor allem wenn man dies noch über das lokale Netz hinaus ausdehnt.

Ich würde dir deshalb empfehlen gar nicht erst weiter zu versuchen von einer Android App über telnet einen Zugriff auf fhem zu machen, sondern Alternativen überlegen.

rudolfkoenig

ZitatÜber das Netz sollte man telnet allerdings nicht zulassen, das ist dann ein offenes Scheunentor, vor allem wenn man dies noch über das lokale Netz hinaus ausdehnt.
Das gilt aber fuer alle Diente.
FHEM versucht den Anfaenger vor der eigener Dummheit zu schuetzen, indem man Verbindungen aus dem nicht lokalen Internet nur mit Passwort zulaesst.

jmbtlb1

Hallo zusammen
mir geht es erstmal nur darum im internen Netz zu verstehen wie die Verbindung Android zu fhem funktioniert.
Sicherheitsaspekte muss man immer im Hinterkopf behalten , aber erst wenn die Lampe leuchtet  :)

Mein letzter Versuch:
     private   void btnFHEMWebSocket(){         
         try {
             Socket fhemWEBSocket = new Socket("192.168.178.48", 8083);
             out1 = new PrintWriter(fhemWEBSocket.getOutputStream(), true);
             out1.write("/fhem?cmd=set%20WZ_Lampe_Fenster%20on&XHR=1%0A%0D");
             fhemWEBSocket.close();
         }
         catch (IOException ex){...
Da da kann doch eigentlich nicht viel fehlen ?

Gruß Michael


Werner Schäffer

#13
Ich würde für Verbindungen nach Außen unbedingt auch den Einsatz eines Proxies (ich nutze nginx) empfehlen. Dann hat man getrennte Welten, auf localhost ist alles erlaubt, im Heimnetz dies und jenes und was von außen kommt wird durch den Proxy verschlüsselt, geschützt und so weiter ...

Werner Schäffer

Michael, du versuchst auf dem fhem Port 8083 eine Websocket-Verbindung, das ist etwas anderes als http und wird vermutlich nicht funktionieren, da fhem auf http-Requests antworten kann aber nicht auf Websocket-Requests (soweit ich weiß, aber Rudolf weiß da sicher mehr).