Android (LIRC) Java TCP Server on RaspberryPi

Hallo,

nach einer etwas längeren Pause kommt wieder was neues. Was bereits in älteren Beiträgen zu lesen war ist die Tatsache, das man über den von LIRC zur Verfügung gestellten TCP Listener nur Infrarot Anfragen verarbeiten kann. Warum also nicht einen eigenen kleinen TCP Server programmieren der je nach Wunsch entsprechende Funktionen ausführt. Dabei denke ich zum Beispiel an Funk Befehle für einen angeschlossenen 433 Mhz Sender oder Informationen die man eventuell in eine Datenbank speichert um sie zu gewünschtem Zeitpunkt auszuführen (Schalte das Aquarium Licht jeden Tag um 20 Uhr aus). Ich habe am Anfang einen Python Server programmiert der bei mir aber nicht ganz stabil lief. Danach bin ich auf Java umgestiegen. Da auch unsere APP in Java programmiert ist passt das ja ganz gut. Also wie fangen wir an?

Inhaltsverzeichnis

  1. JavaSE auf dem RaspberryPI installieren und testen
  2. Java TCP Server in Eclipse erstellen
  3. Java Server als Dienst (Autostart) auf dem RaspberryPI erstellen
  4. LIRC APP anpassen

JavaSE RaspberryPI Installation

Für das Ausführen von *.jar Dateien brauchen wir die entsprechende Installation von der Java Standard Edition. Für den Raspberry gibt es die in der Version 7, deshalb sollte man Projekte nur höchstens für diese Version erstellen. Für die Installation einfach folgendes in die Konsole schreiben:

>sudo apt-get update && sudo apt-get install oracle-java7-jdk

Solltet ihr gerade eben apt-get update ausgeführt haben könnt ihr es auch weglassen. Nach der Installation kann man die von Eclipse erstellen jar Dateien mit folgendem Kommando ausführen:

>sudo java -jar <DateiName>.jar

Zum testen kann man ein simples Projekt mit einer Konsolen Ausgabe in Eclipse erstellen und es dann als ausführbare JAR Datei exportieren und auf dem RaspberryPI starten:

public class Main {

     public static void main(String[] args) {
          System.out.println("Hallo hier läuft Java " + 
               System.getProperty("java.version") + " auf dem RaspberryPI...");
     }
}

JS_1

 

 

Java TCP Server

Nachdem wir nun also Java erfolgreich auf dem RaspberryPI getestet haben, geht’s weiter mit der Programmierung des Servers. In Eclipse einfach ein neues Java Projekt erstellen (ich habe meins TCPServer genannt). In dem MainThread können wir nicht so einfach TCP Verbindungen bereitstellen und verwalten ähnlich dem MainThread und der AsyncTask Klasse aus dem Android Projekt. In diesem Fall werden wir pro eingehender Verbindung einen neuen Thread erstellen. Somit können auch mehrere Clients an den Server dran. Fangen wir also an:

In der erstellen Klasse (bei mir einfach Main) in der Methode main brauchen wir zunächst einen ServerSocket:

public class Main {
     public static void main(String[] args) throws IOException {
          ServerSocket socket = new ServerSocket(5010);
          System.out.println("Socket open on port 5010");
          while (true){
               new TCPThread(socket.accept());
          }
     }
}

Ich habe Port 5010 gewählt aber es steht euch natürlich frei welchen Port ihr benutzt (Hauptsache er ist frei). Die Konsolen-Ausgaben habe ich bewusst eingebaut um beim Tests den Ablauf besser verfolgen zu können. In der while Schleife wird ein Objekt der Klasse TCPThread erstellt. Dem Konstruktor übergeben wir die Socket Verbindung zwischen dem Client und Server. Im Grunde war das alles. Kümmern wir uns nun um die TCPThread Klasse. Diese müssen wie erst um die Klasse Thread erweitern. Ein Thread wird mit der Methode start() gestartet welche dabei die Methode run() ausführt. Also würde der einfache Aufbau der Klasse so aussehen:

public class TCPThread extends Thread{
     
     private Socket socket = null;

     public TCPThread(Socket socket) {
          this.socket = socket;
          start();
     }
 
     public void run(){
     }
}

Ihr sieht es wird ein neuer Socket initialisiert. Im Konstruktor übergibt man den Socket aus der main Methode und startet den Thread. Unten ist die run() Methode die dadurch ausgeführt wird.  Zusätzlich zu dem Socket brauchen wir noch drei weitere Variablen. Wir brauchen einen BufferedReader für die eingehende Nachrichten, einen PrintWriter für die ausgehenden Nachrichten und ein String der ein Ende des zu übertragenen Strings kennzeichnet. Sehen wir uns das mal an:

public class TCPThread extends Thread{

     private Socket socket = null;
     private PrintWriter out = null;
     private BufferedReader in = null;
     private String sEnd = "#END";
 
     public TCPThread(Socket socket) {
          this.socket = socket;
          start();
     }
 
     public void run(){
          try {
               System.out.println("Client connect to Server: " + 
                    socket.getInetAddress().getHostName());
 
          out = new PrintWriter(socket.getOutputStream(), true);
          in = new BufferedReader(
                    new InputStreamReader(socket.getInputStream()));
 
          } catch (IOException e) {
               e.printStackTrace();
          } finally {
               out.close();
               try {
                    in.close();
                    socket.close();
                    System.out.println("Connection closed");
               } catch (IOException e) {
                    e.printStackTrace();
               }
          }
     }
}

Dem PrintWriter übergeben wir den Outputstream vom Socket. Dem BufferedReader den InputStream. Das alles verpackt in try catch Klausel die am Ende (finally) die Objekte und den Socket schließt. Als erstes kümmern wir uns um die eingehenden Nachrichten vom Client.Dafür brauchen wir zwei weitere Strings die wir aber direkt in der Methode deklarieren:

public class TCPThread extends Thread{

     private Socket socket = null;
     private PrintWriter out = null;
     private BufferedReader in = null;
     private String sEnd = "#END";
 
     public TCPThread(Socket socket) {
          this.socket = socket;
          start();
     }
 
     public void run(){
          String sData = "";
          String input;
          try {
               System.out.println("Client connect to Server: " + 
                    socket.getInetAddress().getHostName());
 
          out = new PrintWriter(socket.getOutputStream(), true);
          in = new BufferedReader(
                    new InputStreamReader(socket.getInputStream()));
          
          while((input = in.readLine()) != null){
               sData += input;
               if (input.endsWith(sEnd)) break;
          }
          System.out.println("Input from Client:" + sData);
          } catch (IOException e) {
               e.printStackTrace();
          } finally {
               out.close();
               try {
                    in.close();
                    socket.close();
                    System.out.println("Connection closed");
               } catch (IOException e) {
                    e.printStackTrace();
               }
          }
     }
}

Der String input wird in der while Schleife mit der Methode readLine() vom BufferedReader so lange gefüttert bis dieser null ist. Da aber der InputStream erst dann abbricht wenn der Socket geschlossen wird kann die while Schleife nicht so einfach beendet werden. Dafür aber haben wir die IF Bedienung die besagt das wenn am Ende der Zeile ein #END vorhanden ist die Schleife beendet wird. Das setzt natürlich voraus das die Nachricht vom Client so ein Erkennung-String mitliefert. Der String sData beinhaltet am Ende die ganze Nachricht und wird in der Konsole ausgegeben. Eine Nachricht vom Client würde zum Beispiel so aussehen:

INF#irsend MUSIK_ANLAGE SEND_ONCE KEY_POWER\nMusik Anlage wird eingeschaltet#END

Die Konsolen Ausgabe auf dem Server:

>INF#irsend MUSIK_ANLAGE SEND_ONCE KEY_POWER
>Musik Anlage wird eingeschaltet#END

Wie ihr sieht habe ich am Anfang der Nachricht eine INF# Zeichenfolge gesetzt. Die wird bei mir als Erkennungszeichen für Infrarot (LIRC) Befehle benutzt. Ich empfehle euch auch sich sowas auszudenken. Aber wie verarbeiten wir nun die Daten? Dafür machen wir uns eine eigene Methode die uns auch eine Antwort zum Client liefern wird. Diese Methode habe ich executeCommand genannt. Ihr wird sData übergeben und die Methode selber liefert ein String zurück. Zusätzlich brauchen wir noch zwei weitere Strings. Schauen wir uns das mal an:

private String executeCommand(String data) {
     String response = null;
     String command = data.substring(0,4);
     String command_data = data.substring(4).replace(sEnd,"");
 
     switch (command){
     case "CHK#":
          System.out.println("Check Connection");
          response = "Verbindung zum Server erfolgreich";
          break;
     case "INF#":
          System.out.println("Infrarot:" + command_data);
          try {
               Runtime.getRuntime().exec(command_data);
          } catch (IOException e) {
               response = e.toString();
          }
          break;
     case "FUN#":
          System.out.println("Funk:" + command_data);
          try {
               Runtime.getRuntime().exec("sudo /home/pi/rcswitch-pi/send "
                    + command_data);
          } catch (IOException e) {
               response = e.toString();
          }
          break;
     default:
          System.out.println("Unbekanntes Kommando:" + command);
          break;
     }
     System.out.println("Response:" + response);
     return response;
 }

So schauen wir uns mal die Methode genauer an. Wie gesagt der Methode wird der String ’sData‘ übergeben in diesem Fall dann ‚data‘. Von diesem String werden die ersten vier Zeichen in der Variable ‚command‘ gespeichert. Ab dem viertem Zeichen und ohne das ‚#END‘ wir der Rest der Variable ‚command_data‘ zugewiesen. Zusätzlich haben wir eine null String Variable mit dem Namen ‚response‘. Danach folgt eine Switch Case Abfrage die das Kommando entsprechend behandelt. Für diesen Beispiel habe ich mir drei Möglichkeiten ausgedacht:

>#CHK
Steht für Check und soll als Antwort die erfolgreiche Verbindung zum Server liefern.
>#INF
Steht für Infrarot und verarbeitet die Infrarot Befehle.
>#FUN
Steht für Funk und verarbeitet die 433Mhz Signale.

Bei einer #CKH Anfrage vom Client wird nur der ‚response‘ String mit der Meldung gefüttert und von der Methode zurückgeliefert. Bei Infrarot und Funk Anfragen wird in meinem Fall keine Antwort vom Server erwartet hier werden nur mithilfe der Runtime Klasse die entsprechenden Kommandos ausgeführt. Beim LIRC reicht es aus den String den man bekommt direkt auszuführen. Für meinen 433Mhz Sender verwende ich aber die Software rcswitch welches kein Dienst mitliefert. Hier setzte ich also vor dem Kommando den Pfad zu der Software. Der String vom Client liefert dann die restlichen Informationen. Bei möglichen Fehlern aber wird der ‚response‘ String mit der Exception gesetzt und zurückgeliefert. Beim unbekannten Kommandos passiert nichts. Am Ende wird dann eben ‚response‘ zurückgeliefert entweder als null oder mit einem Wert. Diese Methode müssen wir dann nur noch im Thread ausführen. Am Ende sieht alles so aus:

public class TCPThread extends Thread{

     private Socket socket = null;
     private PrintWriter out = null;
     private BufferedReader in = null;
     private String sEnd = "#END";
 
     public TCPThread(Socket socket) {
          this.socket = socket;
          start();
     }
 
     public void run(){
          String sData = "";
          String input, output;
          try {
               System.out.println("Client connect to Server: " + 
                    socket.getInetAddress().getHostName());
 
               out = new PrintWriter(socket.getOutputStream(), true);
               in = new BufferedReader(
                    new InputStreamReader(socket.getInputStream()));
          
               while((input = in.readLine()) != null){
                   sData += input;
                   if (input.endsWith(sEnd)) break;
               }
               System.out.println("Input from Client:" + sData);
               output = executeCommand(sData);
               if (output != null){
                    out.println(output + sEnd);
               }
          } catch (IOException e) {
               e.printStackTrace();
          } finally {
               out.close();
               try {
                    in.close();
                    socket.close();
                    System.out.println("Connection closed");
               } catch (IOException e) {
                    e.printStackTrace();
               }
          }
     }

     private String executeCommand(String data) {
          String response = null;
          String command = data.substring(0,4);
          String command_data = data.substring(4).replace(sEnd,"");
 
          switch (command){
          case "CHK#":
               System.out.println("Check Connection");
               response = "Verbindung zum Server erfolgreich";
               break;
          case "INF#":
               System.out.println("Infrarot:" + command_data);
               try {
                    Runtime.getRuntime().exec(command_data);
               } catch (IOException e) {
                    response = e.toString();
               }
               break;
          case "FUN#":
               System.out.println("Funk:" + command_data);
               try {
                    Runtime.getRuntime().exec("sudo /home/pi/rcswitch-pi/send "
                         + command_data);
               } catch (IOException e) {
                    response = e.toString();
               }
               break;
          default:
               System.out.println("Unbekanntes Kommando:" + command);
               break;
          }
          System.out.println("Response:" + response);
          return response;
      }
}

Was wurde noch gemacht? Nun wir haben zu der bereits bestehenden ‚input‘ Variable eine neue String Variable erstellt ‚output‘. Diese speichert die Informationen welche die Methode executeCommand liefert. Sollten diese ungleich null sein werden die an den Client weiter geleitet. Wie sieht nun eine fertige Konsolen Ausgabe im RaspberryPI aus schauen wir und das mal an:
JS_2

 

 

 

Java Server als Dienst

Damit unsere Anfragen nicht jedesmal nur dann verarbeitet werden wenn wir eingeloggt in der Konsole den Server manuell gestartet haben, müssen wir die JAR Datei als ein Dienst registrieren. Zusätzlich wäre es vom Vorteil wenn der Dienst beim hochfahren automatisch gestartet wird. Ich persönlich kenne mich wenig mit Linux aus. Ich habe im Internet gesucht und paar passende Beispiele gefunden. Fangen wir also an. Zuerst wechseln wir in das init.d Verzeichnis wo sich alle Dienste befinden:

>cd /etc/init.d

Danach erstellen wir eine Datei und nennen sie zum Beispiel JAVA-TCP:

>sudo nano JAVA-TCP

In der Datei schreiben wir folgendes hinein:

#! /bin/sh
# /etc/init.d/example

case "$1" in
start)
echo "Starting Java TCPServer"
# run application you want to start
java -jar /home/pi/java_bobek/TCPServer_Java.jar &
;;
stop)
echo "Stopping Java TCPServer"
# kill application you want to stop
killall java
;;
*)
echo "Usage: /etc/init.d/TCPServer{start|stop}"
exit 1
;;
esac
exit 0

Im Groben gesagt werden hier zwei mögliche Parameter behandelt. Zum einen ’start‘:

>sudo /etc/init.d/JAVA-TCP start

Hier wird eben die JAR Datei ausgeführt. Ihr müsst den Pfad dann entsprechend anpassen 😉 Der andere Parameter ist ’stop‘:

>sudo /etc/init.d/JAVA-TCP stop

Hier werden alle Java Prozesse beendet. Da bei mir momentan nur der Server auf JAVA Basis läuft ist das nicht so schlimm solltet ihr mehr JAVA Anwendungen haben die im Hintergrund laufen so könnt ihr hier auch den Prozess angeben. Habe im Internet folgendes gefunden aber noch nicht getestet: >pgrep -if ‚java .*-jar‘.

Nun muss die Datei noch ausführbar gemacht werden:

>chmod 755 /etc/init.d/JAVA-TCP

Für den Autostart beim hochfahren muss die Datei einen Runlevel hinzugefügt werden:

>update-rc.d JAVA-TCP defaults

Danach hat bei mir alles funktioniert. Diese Erklärung habe ich hier gelesen:
http://www.schnatterente.net/technik/raspberry-pi-autostart-skript-erstellen

LIRC APP anpassen

Am Ende noch kurze Info an die Leute die auch die anderen Beiträge verfolgt haben. Mit diesem Java Server muss unsere Klasse in der APP noch angepasst werden. Am wichtigsten ist der #END String am Ende und das Kommando am Anfang. Das Kommando liefert bei mir die entsprechende Klasse.Das heißt die muss sich um die ersten vier Zeichen kümmern ‚#INF‘ usw. Der #END String wird einfach dem String angehängt der von anderen Klassen angekommen ist.Für die Antwort vom Server brauchen wir auch in der Android APP einen BufferedReader.Am Ende sieht es so aus:

public class ExecuteCommand extends AsyncTask<String,Void,String>{
 
     private Socket socket = null;
     private PrintWriter out = null;
     private BufferedReader in = null;
 
     private String ip;
     private int port;
     private String response = "", TCPresponse = "";
     private String sEnd = "#END";
     @Override
     protected void onPreExecute() {
          ip = Config.getIp();
          port = Config.getPort();
     }
     @Override
         protected String doInBackground(String...Command) {
         
              String command = Command[0].toString() + sEnd;
              try { 
                   socket = new Socket(ip,port);
              } catch (IOException e) {
                   return response = "Fehlgeschlagen! " + e.toString();
              }
              try{
                   out = new PrintWriter(socket.getOutputStream(), true);
                   out.println(command);
 
                   in = new BufferedReader(
                        new InputStreamReader(socket.getInputStream()));
                   while((TCPresponse = in.readLine()) != null){
                        response += TCPresponse;
                        if (TCPresponse.endsWith("#END")) break;
                   }
               } catch (IOException e) { 
                    e.printStackTrace();
               } finally {
                    out.close();
                    try {
                         in.close();
                         socket.close();
                    } catch (IOException e) {
                         e.printStackTrace();
                    }
               }
               return response.replace(sEnd,"");
         } 
}

Im Grunde sieht die Client Seite nicht viel anders aus als der Server. Zu dem PrintWriter ist eben noch der BufferedReader mit der while Schleife dazu gekommen. Am Ende liefert die Methode die Antwort vom Server (‚response‘) zurück.

10 Gedanken zu „Android (LIRC) Java TCP Server on RaspberryPi

  1. Jan

    Vielen Dank erstmal!
    Mir ist noch nicht ganz klar, wie man gleichzeitig einen Infrarot- und einen Funksender steuern kann. Man kann doch in Lirc nur einen Ausgang einstellen, eigentlich möchte ich aber, dass je nach Befehl entweder der eine oder der andere Sender sendet. Oder habe ich irgendwas nicht richtig mitbekommen?

    Viele Grüße Jan

    Antworten
    1. BoBek Beitragsautor

      Hallo Jan,

      genau diese Unterteilung muss eben der TCP Server übernehmen je nachdem was der Client zugeschickt hat. Was meinst du denn mit dem Ausgang? LIRC ist eine Anwendung die nur die Infrarot Anfragen verarbeiten kann. Für die Funk Befehle brauchst du eine entsprechende Software (bei mir benutze ich rcswitch oder 433Utilis und natürlich einen entsprechenden Funksender). Im Endeffekt entscheidet der TCP Server in der Methode „executeCommand“ was der Raspberry Ausführen muss. Eine Infrarot Anfrage vom Client sieht zum Beispiel so aus:
      „INF#irsend SEND_ONCE LED KEY_POWER#END“
      Der Server nehmt diese Daten entgegen sieht durch INF das es sich um ein Infrarot-Befehl handelt und führt diesen String „irsend SEND_ONCE LED KEY_POWER“ direkt im Terminal aus, weil der Raspberry das direkt verarbeiten kann. Ein Funk-Befehl vom Client, sieht dagegen bei mir so aus:
      „FUN#11111 1 0#END“
      Der Server erkennt hier „aha es ist eine Funk Anfrage“ also entsprechend behandeln. Da die Funk Anwendungen bei mir nicht als Dienst laufen wird im Endeffekt folgendes vom Server im Terminal ausgeführt:
      „sudo /home/pi/rcswitch-pi/send 11111 1 0“
      In beiden Fällen werden die Befehle über die „exec“ Methode auf dem System ausgeführt.Wenn du noch weitere Fragen hast dann nur zu 😀

      Antworten
      1. Jan

        Ach, verstehe!! Bin auf dem Gebiet noch neu 😉 Danke!
        Ich habe das jetzt versucht umzusetzen, jedoch klappt das noch nicht ganz. Wenn ich die jar Datei starte bekomme ich lediglich den Output, dass ein Socket auf Port 5015 (oder welcher auch immer) geöffnet wurde, mehr aber nicht. Anfragen aus der App werden ignoriert (das hat mit dem Lirc-Tcp-Listener noch funktioniert), auch in eclipse-Konsole wird mir genau dasselbe angezeigt. Wenn ich in eclipse nach einem run nochmals auf run klicke, bekomme ich auch eine Exception, weil der Socket noch geöffnet ist.
        Ich habe den Eindruck, dass die run Methode der TCP-Thread-Klasse nie ausgeführt wird und der Socket immer offen bleibt.
        Eigentlich habe ich den Quellcode 1:1 abgeschrieben, besser gesagt ctrl c&v, aber auch damit funktioniert es nicht. Oder muss am Quellcode evtl. doch was anders sein? Ich habe mal die Quellcodes der beiden Klassen in Txt-Dateien gespeichert und in meine Dropbox geladen. Ist der Quellcode so vollständig?
        https://www.dropbox.com/sh/9n7zpvsmy9msdlx/AAAYN28hKAvuVmHOJPlyPg5Ja?dl=0

        Vielen Dank im Vorraus!

        Antworten
        1. BoBek Beitragsautor

          Der Server Socket ist auch immer geöffnet (Ansonsten könnte sich kein Client verbindet). Deshalb die Exception wenn du das Programm nochmal ausführt, weil ja der Port belegt ist.In diesem Fall beendest du erst über Eclipse das Programm bevor du es neu startest oder du beendet den Java Prozess. Was mir aufgefallen ist du hast die While Schleife auskommentiert im Main Thread. Ansonsten wenn du copy und paste gemacht hast müsste es funktionieren. Du könntest mir noch helfen indem du mir deine Android Klasse zeigst welche die Verbindung zum Server aufbaut. Ich schreibe gerade vom Handy und kann mir es nicht genauer angucken. Ich meld mich später nochmal…

          Antworten
          1. Jan

            Stimmt, habe die Schleife zwischendurch testweise auskommentiert, ging aber auch davor nicht…

            Meine komplette Android Datei befindet sich jetzt ebenfalls in der Dropbox, ist denke ich übersichtlicher so. Ist alles mit Android Studio gemacht. Die einzige Klasse, in der aktuell ein Befehl gesendet wird, ist „Schildkröten“. In den anderen Klassen liegen nur Leichen… Außer Connection, Config, Startup und Main natürlich. Wobei das mit den shared Preferences auch noch nicht so läuft, wie ich es letzendlich haben will, aber das kriege ich hin… denke ich 😀

          2. BoBek Beitragsautor

            Hallo Jan,

            schau doch mal bitte ob der Client überhaupt die richtige IP Adresse und Port Nummer vom Server hat. Zum einem hast du selber gesagt das es mit speichern der Einstellungen noch nicht so richtig klappt zum anderen wird der Port 5017 (und nicht 5018 wie in der Server Klasse) als Default Port geladen. Der Server an sich funktioniert bei mir Problemlos. Also was muss gemacht werden:
            In der Connection Klasse in der Methode onPreExecute() bitte einmal die IP Adresse und Port fest setzten:
            @Override
            protected void onPreExecute() {
            IP = „192.168.178.23“;
            Port = 5018;
            }
            Danach gucken ob es mit der Verbindung klappt. Eins ist mir noch aufgefallen in der Klasse Schlidkröten muss du eben aufpassen wie die Strings aufgebaut sind.Button 9 verschickt den Endstring mit, braucht der aber nicht, weil die Connection Klasse den schon anhängt. Also kommt am Server #END #END an. Button 10 dagegen schickt kein #INF mit. Aber ich vermute du bist du noch in der Programmierphase und alles ist noch bisschen chaotisch aufgebaut. Wenn du die SharedPreferences in der Startup Klasse speicherst (die Methode onDestroy) dann brauchst du die Methode nicht noch zusätzlich in der Main Klasse.Ansonsten kann ich auf dem ersten Blick nicht erkennen warum die eingestellten Einstellungen nicht geladen werden (Sollte eig. funktionieren). Ich halte dich auf dem laufenden…

          3. BoBek Beitragsautor

            Die finish() Methode der Activity Klasse die du jedesmal nach dem Aufruf einer neuen Activity startest kannst du dir eig. sparen außer du willst wirklich das die Activity zerstört wird. Lässt du es weg dann wird die Activity nur gestoppt und ggf. neu aufgerufen. Mir ist das nur aufgefallen, weil du es so nach jedem Aufruf einer neuen Activity aufrufst.

          4. Jan

            Einige Stunden später ist mir dann auch mal aufgefallen, dass ich vergessen habe, die Buttons zu initialisieren…
            Jetzt, mit vorgegebener IP & Port funktioniert alles. Dass der Server okay ist konnte ich auch zuvor schon mit Putty (SLH-Client) nachweisen: Einfach eine Raw-Verbindung herstellen und gucken, ob alles wie gewünscht funktioniert. Dem war so.
            Aktuell bekomme ich zwar nach jedem Befehl die response 0 und der Socket schließt sich, aber damit werde ich mich morgen auseinander setzen. Habe die jar Datei auch noch nicht als Dienst eingerichtet.

            Ein großes Probleme habe ich aber noch, wobei ich nicht glaube, dass man mir aktuell dabei helfen kann: Wenn ich einen IR-Befehl absetzte, lassen sich keine Geräte schalten. Ich habe statt der IR-Diode eine normale LED eingesetzt, um zu testen, ob diese aufleuchtet, wenn ich einen Befehl sende – positiv.
            Meine IR-Diode ist auch in Ordnung, sendet auch (mit Handy-Kamera überprüft), habe sie aber auch 2x ausgetauscht, um sie als Fehlerquelle auszuschließen. Habe sie direkt vor verschiedene Geräte gehalten mit jeweils selbst angelernten Befehlen. Die angelernten Befehle scheinen auch zu passen, habe zumindest beim BD-Spieler eine übereinstimmende Aufnahme der Befehle im Netz gefunden…

            Ich habe einen Rasp. 2, also einen von den ganz neuen. Ich habe so das Gefühl, dass bei den GPIOs mit dem Timing irgendwas nicht richtig hin haut… Ob das mit Funk klappt werde ich nächste Woche sehen, wenn die bestellten Funksteckdosen da sind.

            Auf jeden Fall vielen Dank für deine Mühe & Hilfe!!

          5. BoBek Beitragsautor

            Das mit Putty ist klar dein Handy macht im Grunde auch nichts anderes. Das mit Response 0 ist auf welcher Seite? Server oder Client? Wenn der Client keine Antwort vom Server bekommt dann ist das im Fall von einer Infrarot Abfrage richtig. Willst du eine Antwort abschicken dann muss du auf der Server Seite in der Methode executeCommand in der Case Abzweigung INF und in der Variable response den gewünschten Wert speichern (zB. „Infrarot Abfrage ausgeführt“). Momentan wird bei INF die Variable response nur dann gefüllt wenn es ein Fehler beim Ausführen des Befehls gab. Der Socket wird deshalb geschlossen weil du bestimmt die while Schleife noch in Kommis hast. Nehm die Kommentare weg und ich sag’s dir es wird funktionieren. Zu deinem LIRC Problem…Spuckt LIRC eine Fehlermeldung aus wenn du irsend Befehle ausführst?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.