+ Antworten
Ergebnis 1 bis 8 von 8
  1. #1
    Registriert seit
    Oct 2008
    Beiträge
    25

    Post Remote Keyboard Server

    Im IPS 2.0 gibt es ja leider keine Möglichkeit, Eingaben auf der Computertastatur auszuwerten. Darum habe ich einen kleinen "Remote Keyboard Server" geschrieben, der das erledigt.

    Das Prinzip basiert auf einer Socket-Kommunikation mittels Telnet. Der Vorteil ist, dass man die Tastatur von irgendeinem PC (nicht nur vom IPS-Server) übertragen kann. Das passt besser zur neuen Client-Server Architektur als eine lokale Tastaturabfrage am IPS-Server.

    Als kleines Nikolausgeschenk habe ich das Skript hier eingestellt. Einfach in das IPS-Verzeichnis kopieren und manuell ausführen. Es installiert selbst die benötigten Instanzen und Variablen. Für weitere Erklärungen schaut in die Kommentare im Code.

    Getestet habe ich es mit Windows XP Telnet Client. Hoffentlich funktioniert es bei euch. Garantie übernehme ich nicht

    Als Rückmeldung kriegt man übrigens auf dem Telnet-Client ein IPS-Prompt und ein Echo der gedrückten Taste. Da das IPS Server Socket Modul erst beim ersten Tastendruck das Skript triggert (ein Triggern beim Öffnen der Verbindung ist noch auf meinem Wunschzettel an paresy), kommt das Prompt erst nach der ersten Taste.

    Das Skript war zu groß, um hier eingefügt zu werden. Darum findet ihr es zwei Beiträge weiter unten.
    Viele Grüße
    <ursprünglichen Anhang habe ich wieder entfernt>
    Geändert von docM (06.12.08 um 20:09 Uhr) Grund: Aufräumarbeiten

  2. #2
    Registriert seit
    Jul 2006
    Ort
    Butzbach, die schöne Wetterau
    Beiträge
    1,475

    Hier können normale Benutzer wie wir keine Anhänge runterladen.
    Gruß Uwe
    (bmwm3)


  3. #3
    Registriert seit
    Oct 2008
    Beiträge
    25

    Arrow Jetzt im Klartext

    Wollte das Skript ursprünglich im Klartext einfügen, aber die Maximallänge des Postings lag mit 10607 Zeichen knapp über der maximal erlaubten Länge von 10000 Zeichen

    Ich hab es ein wenig gekürzt, nun passt es gerade so.
    PHP-Code:
    <?
    /* Remote Keyboard-Server von docM
        Dieses Skript ermöglicht die Auswertung einer PC-Tastatur in IPS V2.0
        Hierzu wird Telnet verwendet. Der Remote Keyboard Server imitiert
        einen Telnet Server (Port 23).
        
        Auf dem PC, der zur Steuerung verwendet werden soll, startet man einen
        Telnet-Client im ANSI-Modus und verbindet ihn mit dem IPS Server. Unter
        Windows-XP geht das einfach mit dem Befehl

        telnet <ip-Adresse oder Computername des IPS-Servers>
        
        in der Kommandozeile.
        
        Wenn man jetzt im Telnet-Client eine Taste drückt, so wird das zugehörige
        Zeichen an den Keyboard-Server geschickt und daraufhin automatisch
        dieses Skript hier aktiviert.
        
        Ganz am Ende des Skripts sind zwei Funktionen, die man auf seine eigenen
        Bedürfnisse anpassen muss.
        pressedNormalKey() wird beim Druck auf eine normale Taste,
        pressedSpecialKey() beim Druck auf eine Sondertaste aufgerufen.
        Hier kann man nun auf die Zeichen reagieren.
        
        Die Installation des Servers geschieht wie folgt. Einfach dieses Skript in
        den Objektbaum kopieren und manuell ausführen.
        Nicht wundern, wenn es anschließend nicht mehr an der alten Position im
        Objektbaum zu finden ist.
        Bei der Installation passiert folgendes
        - Es wird unter I/O Instanzen ein Server Socket mit Namen
         'Remote Keyboard Server' angelegt
        - Darunter wird eine Register-Variable mit Namen 'Weiterleitung' erzeugt.
        - Dieses Skript wird automatisch im Objektbaum unter den Keyboard Server
          verschoben und erhält den Namen 'Verarbeitung'
        - Es wird unterhalb des Keyboard Servers noch eine String Variable
          'letzte ASCII-Codes' angelegt. Sie zeigt (in Hex) die Codes der letzten
          Taste an.
    */

    function GetModuleId($moduleName)
    // Hilfsfunktion, benötigt beim automatischen Anlegen der Instanzen
    {
        foreach (
    IPS_GetModuleList() as $moduleId)
        {
            
    $module IPS_GetModule($moduleId);
            if (
    $module['ModuleName']==$moduleName) return $moduleId;
        }
        return 
    '';
    }

    function 
    echoTerminal($text)
    {
    // Ausgabe eines Textes auf dem Telnet-Client
        
    global $IPS_SELF;
        
    $scriptObject =IPS_GetObject($IPS_SELF);
        
    SSCK_SendText($scriptObject['ParentID'],$text);
    }

    function 
    parseKeys($keys)
    {
    // Diese Funktion wird immer dann aufgerufen, wenn der Remote Keyboard Server
    // Zeichen empfangen hat.
    // Sondertasten
        
    $ansispecialkeys = array(
            
    'F1'       => chr(0x1B).chr(0x4F).chr(0x50),
            
    'F2'       => chr(0x1B).chr(0x4F).chr(0x51),
            
    'F3'       => chr(0x1B).chr(0x4F).chr(0x52),
            
    'F4'       => chr(0x1B).chr(0x4F).chr(0x53),
            
    'F5'       => chr(0x1B).chr(0x5B).chr(0x31).chr(0x35).chr(0x7E),
            
    'F6'       => chr(0x1B).chr(0x5B).chr(0x31).chr(0x37).chr(0x7E),
            
    'F7'       => chr(0x1B).chr(0x5B).chr(0x31).chr(0x38).chr(0x7E),
            
    'F8'       => chr(0x1B).chr(0x5B).chr(0x31).chr(0x39).chr(0x7E),
            
    'F9'       => chr(0x1B).chr(0x5B).chr(0x32).chr(0x30).chr(0x7E),
            
    'F10'      => chr(0x1B).chr(0x5B).chr(0x32).chr(0x31).chr(0x7E),
            
    'F11'      => chr(0x1B).chr(0x5B).chr(0x32).chr(0x33).chr(0x7E),
            
    'F12'      => chr(0x1B).chr(0x5B).chr(0x32).chr(0x34).chr(0x7E),
            
    'UP'       => chr(0x1B).chr(0x5B).chr(0x41),
            
    'DOWN'     => chr(0x1B).chr(0x5B).chr(0x42),
            
    'RIGHT'    => chr(0x1B).chr(0x5B).chr(0x43),
            
    'LEFT'     => chr(0x1B).chr(0x5B).chr(0x44),
            
    'PG-UP'    => chr(0x1B).chr(0x5B).chr(0x35).chr(0x7E),
            
    'PG-DOWN'  => chr(0x1B).chr(0x5B).chr(0x36).chr(0x7E),
            
    'POS1'     => chr(0x1B).chr(0x5B).chr(0x31).chr(0x7E),
            
    'ENDE'     => chr(0x1B).chr(0x5B).chr(0x34).chr(0x7E),
            
    'ENTER'    => chr(0x0D).chr(0x0A),
            
    'BS'       => chr(0x08),
            
    'ENTF'     => chr(0x7F),
            
    'STRG-A'   => chr(0x01),
            
    'STRG-B'   => chr(0x02),
            
    'STRG-C'   => chr(0x03),
            
    'STRG-D'   => chr(0x04),
            
    'STRG-E'   => chr(0x05),
            
    'STRG-F'   => chr(0x06),
            
    'STRG-G'   => chr(0x07),
            
    'STRG-H'   => chr(0x08),
            
    'STRG-I'   => chr(0x09),
            
    'STRG-J'   => chr(0x0A),
            
    'STRG-K'   => chr(0x0B),
            
    'STRG-L'   => chr(0x0C),
            
    'STRG-N'   => chr(0x0E),
            
    'STRG-O'   => chr(0x0F),
            
    'STRG-P'   => chr(0x10),
            
    'STRG-Q'   => chr(0x11),
            
    'STRG-R'   => chr(0x12),
            
    'STRG-S'   => chr(0x13),
            
    'STRG-T'   => chr(0x14),
            
    'STRG-U'   => chr(0x15),
            
    'STRG-V'   => chr(0x16),
            
    'STRG-W'   => chr(0x17),
            
    'STRG-X'   => chr(0x18),
            
    'STRG-Y'   => chr(0x19),
            
    'STRG-Z'   => chr(0x1A),
            
    'ESC'      => chr(0x1B)
    // wichtig, dass der "nackte" ESC am Ende der Liste steht. Sonst werden beim
    // Parsen die ESC-Sequenzen nicht erkannt.
        
    );
        for (
    $keyslen strlen($keys);$keyslen>0;$keyslen-=$cutoff)
        {
            
    $cutoff=1;
    // Telnet Kommandos unterdrücken. Sie beginnen immer mit IAC=0xFF und sind 3
    // Zeichen lang.
            
    if (($keys[0]==chr(0xFF)) && ($keyslen>2))
            {
                
    $cutoff=3;
            }
    // Sondertastenverarbeitung
            
    elseif (($keys[0]<=chr(0x21)) || ($keys[0]==chr(0x7F)))
            {
                foreach(
    $ansispecialkeys as $code =>$sequence)
                {
                    
    $seqlen strlen($sequence);
                    if (
    $seqlen>$keyslen) continue;
                    if(
    substr_compare($keys,$sequence,0,$seqlen)==0)
                    {
    // Benutzerfunktion aufrufen
                        
    pressedSpecialKey($code);
    // Echo auf dem Terminal
                        
    echoTerminal($code.chr(0x0D).chr(0x0A).chr(0xFF).chr(0xFB).chr(0x01).'IPS>');
                        
    $cutoff=$seqlen;
                        break;
                    }
                }
            }
            else
            {
                
    pressedNormalKey($keys[0]);
                
    echoTerminal($keys[0].chr(0x0D).chr(0x0A).chr(0xFF).chr(0xFB).chr(0x01).'IPS>');
            }
            
    $keys=substr($keys,$cutoff);
        }
    }

    // Hauptprogramm startet hier!
    if ($IPS_SENDER == 'RegisterVariable')
    // Der Keyboard-Server hat Zeichen empfangen
    {
        
    $scriptObject =IPS_GetObject($IPS_SELF);
        
    $keys$IPS_VALUE;

    // Schreibe die letzten ASCII-Codes in die Variable
        
    $result "";
        for(
    $i=0;$i<strlen($keys);$i++)
        {
            
    $result.= sprintf('0x%02X ',ord($keys[$i])); // HEX format
        
    }
        
    $asciiAusgabe IPS_GetVariableIDByName('Letzte ASCII-Codes',$scriptObject['ParentID']);
        
    SetValueString($asciiAusgabe,$result);

    // Wenn es was zu tun gibt, rufe die Benutzerfunktion zur Auswertung auf
         
    ($keys != ''ParseKeys($keys);
    }
    elseif (
    $IPS_SENDER=='TimerEvent')
    // Dies ist der zweite Durchlauf der Installation.
    // Zwei Durchläufe sind erforderlich, damit IPS seine ScriptEngine aktualisieren
    // kann. Sonst sind die Funktionen SSCK_ und RegVar_ möglicherweise nicht
    // definiert und das Skript endet im Fatal Error.
    {
    // lösche den Timer, er diente nur zum Zweck diesen Durchlauf zu triggern.
        
    IPS_SetScriptTimer($IPS_SELF,0);
        
    $timer IPS_GetEventIDByName('ScriptTimer',$IPS_SELF);
        
    IPS_DeleteEvent($timer);
        
        
    $scriptObject =IPS_GetObject($IPS_SELF);

    // konfiguriere den Server Socket
        
    $socketServer $scriptObject['ParentID'];
         
    SSCK_SetPort($socketServer,23); // default Telnet Port
        
    SSCK_SetLimit($socketServer,1); // maximal 1 Client gleichzeitig
        
    SSCK_SetOpen($socketServer,true); // Port öffnen
        
    IPS_ApplyChanges($socketServer);

    // konfiguriere die Register Variable
        
    $registerVariable IPS_GetInstanceIDByName('Weiterleitung',$socketServer);
        
    RegVar_SetRXEnabled($registerVariable,true);
        
    IPS_ConnectInstance($registerVariable,$socketServer);
        
    RegVar_SetRXTarget($registerVariable,1);
        
    RegVar_SetRXObjectID($registerVariable,$IPS_SELF);
        
    IPS_ApplyChanges($registerVariable);

    // fertig
        
    echo 'Installation erfolgreich';
    }
    else
    {
    // interaktives Ausführen: Erster Durchlauf der Installation.
        
    $scriptObject =IPS_GetObject($IPS_SELF);

    // prüfe, ob wir schon installiert sind
        
    $parentObject IPS_GetObject($scriptObject['ParentID']);
        if (
    $parentObject['ObjectType']==1)
        {
            
    $parentObject IPS_GetInstance($scriptObject['ParentID']);
            if (
    $parentObject['ModuleInfo']['ModuleName']=='Server Socket')
            {
                echo 
    'Skript ist bereits installiert.';
                return;
            }
        }
    // erzeuge den Server Socket
        
    $socketServer IPS_CreateInstance(GetModuleId("Server Socket"));
        
    IPS_SetName($socketServer,'Remote Keyboard Server');

    // erzeuge die Register Variable
        
    $registerVariable IPS_CreateInstance(GetModuleId("Register Variable"));
        
    IPS_SetName($registerVariable,'Weiterleitung');
        
    IPS_SetParent($registerVariable,$socketServer);

    // benenne mich selbst um und verschiebe mich im Objektbaum
        
    IPS_SetParent($IPS_SELF,$socketServer);
        
    IPS_SetName($IPS_SELF,'Verarbeitung');

    // erzeuge die Variable zur Ausgabe der ASCII-Codes
        
    $asciiAusgabe IPS_CreateVariable(3);
        
    IPS_SetName($asciiAusgabe,'Letzte ASCII-Codes');
        
    IPS_SetParent($asciiAusgabe$socketServer);
    // starte einen Timer, der dieses Skript nach einer Sekunde für den
    // zweiten Durlauf neu startet. Das ermöglicht IPS seine ScriptEngine zu
    // aktualisieren.
        
    echo 'starte 2. Durchlauf';
        
    IPS_SetScriptTimer($IPS_SELF,1);
    }

    function 
    pressedSpecialKey($key)
    {
    // hier festlegen, was beim Druck auf eine Sondertaste geschehen soll
        
    switch ($key)
        {
            case 
    'ENTER':
                echo (
    'Es wurde "ENTER" gedrückt.');
                break;
            case 
    'F5':
                echo (
    'Es wurde "F5" gedrückt.');
                break;
            case 
    'STRG-B':
                echo (
    'Und jetzt "STRG-B".');
    // usw. nach Belieben
        
    }
    }

    function 
    pressedNormalKey($key)
    {
    // hier festlegen, was beim Druck auf eine normale Taste geschehen soll
        
    switch ($key)
        {
            case 
    'a':
                echo (
    'Es wurde das "A" gedrückt.');
                break;
            case 
    'A':
                echo (
    'Es wurde "SHIFT-A" gedrückt.');
                break;
    // usw. nach Belieben
        
    }
    }
    ?>

  4. #4
    Registriert seit
    Dec 2006
    Ort
    Neutraubling
    Beiträge
    32

    Cool das Nikolaus Geschenk habe ich gleich getestet .. wie wars anders zu erwarten? .. es FUNKTIONIERT..

    Danke
    bye

    HaSc
    -------------------
    Der Kluge lernt aus allem und von jedem, der Normale aus seinen Erfahrungen und der Dumme weiß alles besser. -Sokrates-

  5. #5
    Registriert seit
    Aug 2005
    Ort
    Fürstenfeldbruck-Aich (Bayern)
    Beiträge
    4,051

    Hallo docM,

    was mich interessieren würde...

    ... welche Anwendungen möchtest Du damit realisieren.

    Die Möglichkeiten sind ja riesig. Von einer Fernbedienung via Taster, egal ob lokal oder remote, bis zu weiteren Webanwendungen die eine Telnetsession steuern.

    Kannst Du uns mitteilen was Du selbst damit vor hast.
    Gruß
    Werner

    Komponenten:: Homematic(CCU) 250DP, EATON-MOELLER, 1-Wire, WMRS200, 15" Touchdisplay
    Software::
    IPS V4.x, iMobile, WebFront, Logitech Media Server 7.8.x, SONOS
    Hardware:: IPS-Server: ESXi 6.x, Windows 10 Ent, 4 Kerne, 8GB RAM

  6. #6
    Registriert seit
    Oct 2008
    Beiträge
    25

    Standard wozu das ganze

    Also, motiviert wurde ich durch die Diskussion hier. Da dachte ich mir, es müsste über Telnet eigentlich ganz einfach gehen. Der Kern des Skripts war nach einer Stunde fertig. Aber was es dann wirklich aufwändig gemacht hat, waren Wünsche wie
    - automatische Erzeugung der Instanzen
    - Behandlung von Sondertasten
    - Echo auf dem Telnet-Client steuern
    also wie so oft, das ganze drum herum für den Komfort.

    Ich verwende es erstmal ganz geradeaus zur Steuerung per Tastatur. Vielleicht könte es auch ein Weg sein, um ein einfaches WLAN-Mobilgerät als "Fernbedienung" einzubinden. Aber das geht natürlich auch über das Webfrontend.

    Die Integration von IPS mit anderen Systemen interessiert mich sehr. So will ich z.B. noch eine Überwachungskamera installieren, deren Aufzeichnung automatisch startet, wenn mein FS20-Bewegungsmelder anschlägt. Für solche Sachen, dürfte aber das SOAP Interface besser sein.

    Viele Grüße und noch viel Spaß mit dem Remote Keyboard Server.

  7. #7
    Registriert seit
    Sep 2008
    Beiträge
    118

    Hallo,

    eine Frage hierzu:

    Ich habe einen Client mit Touchscreen und darauf den Designer laufen, jetzt möchte ich mit der Tastatur an diesem Client Befehle zu IPS schicken, geht das auch, wenn ich das Telnet-Fenster nicht aktiviert habe bzw. wenn der Designer aktiv ist und das Telnet-Fenster nur im Hintergrund läuft?

    Wenn das geht wäre das wirklich klasse!

    Wenn nicht, gibt es eine alternative?

    Grüße

    ASICS
    HomeMatic im ganzen Haus:
    Zentrale, Lichter, Jalousien, Steckdosen, Schalter, Heizung, Gartenbewässerung, 17" Touchscreen in der Wand. PV-Anlagenüberwachung, Aquariumüberwachung und Steuerung, Alarmanlage und vieles vieles mehr...

  8. #8
    Registriert seit
    Mar 2009
    Ort
    Bad Zell / Austria
    Beiträge
    262

    Hallo,
    hab mal das Script von docM für IPS2.2 angepasst

    tgusi74

Ähnliche Themen

  1. Socket Server Problem
    Von docM im Forum Allgemeine Diskussion (2.x/3.x)
    Antworten: 8
    Letzter Beitrag: 05.12.08, 21:22
  2. stromsparen und server vertragen sich nicht ?
    Von hmpf99 im Forum Alles rund um den PC
    Antworten: 19
    Letzter Beitrag: 03.11.07, 12:31
  3. On Screen Keyboard
    Von guyabano im Forum Dashboard
    Antworten: 4
    Letzter Beitrag: 27.01.06, 13:29