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.
<?
/* 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
f ($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
}
}
?>