Verschiedene Befehle mt unterschiedlicher Antwort von Client Socket auswerten

Hallo zusammen,

ich haben einen Client Socket eingerichtet, der mir über eine IP:Port Daten von einem Gerät liefert. Diese Daten bekomme ich von einer Regster Variablen, die an den Client Socket gebunden ist. Um Daten von dem Socket zu bekommen, muss ich immer erst einen Befehl via CSCK_SendText aus einem Skript senden. Nach einem solchen Befehl liefert das Gerät eine Antwort. Soweit ist das kein Problem, aber wenn ich einen anderen Befehl an das Gerät sende, kommt auch eine andere Antwort.

Leider habe ich noch nicht herausgefunden, wie ich die verschiedenen Antworten, getriggert von verschiedenen Scripten, in unterschiedliche Ziel-Variablen schreiben kann. Im Moment überschreibe ich immer ein und dieselbe Variable, die ich mit dem Script anspreche, welches an die Register Variable gebunden ist.

Beispiel:

Skript mit dem Kommando

CSCK_SendText(41936, "Command 1");

triggert die Antwort „100,000“

Skript mit dem Kommando

CSCK_SendText(41936, "Command 2");

triggert die Antwort „200,000“

Im Skript von meiner Register Variablen steht das hier:


<?
if ($_IPS['SENDER'] == "RegisterVariable")
{
    $data=  $_IPS['VALUE']; // neuen Wert hinzufügen
    SetValue(43801,$_IPS['VALUE']);
}
?>

Somit überschreibe ich immer die gleiche Ziel Variable, obwohl ich verschiedene Werte aus dem Gerät angefragt habe. Die Antwort des Gerätes gibt leider nicht die Info zurück, von welchen Kommando es angefragt wurde.

Was gibt es denn hier für Möglichkeiten diese Problem zu lösen?

Marc

Wenn das Gerät keine eindeutig zu einem Befehl zu indentifizierende Antwort gibt, bleibt nur die Möglichkeit das zu lösen, indem immer nur ein Befehl geschickt wird und erst nachdem die Antwort ausgewertet wurde dann der nächste Befehl abgesetzt wird.

Dazu legt man man ein Hilfsvariable vom Typ Integer an, die als Buffer dient und ein Skript was zum verschicken der Befehle dient.

Das Skript zum Senden sieht so aus:


$object_id = $_IPS['object_id']; // übergebene Objekt ID der zu beschreibenden Variable
$command = $_IPS['command']; // zu sendender Befehl
SetValue(12345, $object_id); // Schreibt die Objekt ID in einer Hilfvariable mit der ObjektID 12345
CSCK_SendText(41936, $command); 

Der eigentliche Befehl wird dann verschickt durch jeweils ein aufrufendes Skript mit IPS_RunScriptEx


IPS_RunScriptEx(34567, Array("object_id" => 23456, "command" => "Command 1")); // 34567 ist das Zeilskript s.o

Wenn der Antwort dann im Skript das an der Registervariable hängt ankommt kann der Wert in die passende Variable geschrieben werden, indem der Wert aus der Hilfsvariable ausgelesen wird.


if ($_IPS['SENDER'] == "RegisterVariable") 
{ 
    $object_id = GetValue(12345); // Objekt ID aus der Hilfvariable auslesen 
    SetValue($object_id, $_IPS['VALUE']); // Antwort in passende Variable schreiben
} 

Das funktioniert so lange immer erst dann ein neuer Befehl geschickt wird nachdem die Antwort angekommen ist. Sollte man nicht sicher sein ob z.B. mehrere Skript auch zeitgleich aufgerufen werden muss man mit einem Semaphore verhindern dass ein zweites Skript etwas sendet, bevor die Antwort erhalten wurde. Dann würde man mit IPS_SemaphoreEnter den Semaphore auslösen, in dem Skript der Registervariable muss dann der Semaphore mit IPS_SemaphoreLeave wieder freigegeben werden, erst dann kann das nächste Skript senden.

Hallo,

ja, das hat einwandfrei funktioniert. Vielen Dank.

Marc

Kleine Ergänzung hierzu:

Dafür nutzt man den Buffer der RegisterVariable.
Ebenso ist es sinnvoll das Senden an den ClientSocket über die RegisterVariable zu führen.
Dann braucht man nur diese eine InstanzID und arbeitet mit RegVar_SendText, RegVar_SetBuffer und RegVar_GetBuffer.
Schönes Beispiel dazu war das alte Script von Tommi für die APCUPS, welches ich gerade nicht finde :o
Michael

Hier ist der relevante Ausschnitt

 
/*
$regvars=array(<Liste der Regoistervariablen, die abgefragt werden sollen>);
$reg=<InstanceID Registervariable>;
$id=<InstanceID Socket>;
*/
if ($IPS_SENDER == "RegisterVariable")
{
// Antwort Puffern
	$reg=$IPS_INSTANCE;
   // bereits im Puffer der Instanz vorhandene Daten in $data kopieren
  	$data  = RegVar_GetBuffer($reg);
  	// neu empfangene Daten an $data anhängen
  	$data .= $IPS_VALUE;
  	RegVar_SetBuffer($reg, $data);
}else{
//Abfrage
	foreach($regvars as $reg)
	{
		$in=null;
		 $id=IPS_GetParent($reg);
	//Nicht registervariable, also manuell
	//socket öffnen
		CSCK_SetOpen($id,true);
		IPS_ApplyChanges($id);
	//befehl senden
		RegVar_SendText($reg,chr(0).chr(6)."status");
	//warten
		sleep (1);
	//Socket schliessen
		CSCK_SetOpen($id,false);
		IPS_ApplyChanges($id);
	//Rückgabe abholen
		$in  = RegVar_GetBuffer($reg);
	//RegVar bereinigen
		RegVar_SetBuffer($reg, "");
	//Ausgabe in Array wandeln
	   $apc=format_data($in);
	//loggen
		logge($logfile,$apc);
	//parsen
	   if (isset($apc['APC']) && preg_match("/^(\d+),(\d+),(\d+)/",$apc['APC'])) {
			parse_apc($apc);
		}else {
		   $msg='no valid data';
			if (isset($apc['APC'])) ':'.$msg.$apc['APC'];
			ips_logmessage('APC',$msg);
		}
	}
}