Universelles Protokoll zur Beameransteuerung - PJLINK

so jetzt zum Beamer:

hier meine function:

<?php

//******************************************************************************
// PJLink ausführen
// include '37077.ips.php';
// aufrufen z.B. mit: $return = PJLink(array('%1ERST ?', '%1POWR ?'));
//******************************************************************************

function PJLink($array)
{
	$ID_socket	= 56275;

	IPS_SetProperty ($ID_socket, "Open", true);
	IPS_ApplyChanges($ID_socket);
	IPS_Sleep(500);

	for ( $x = 0; $x < count ( $array ); $x++ )
	{
		CSCK_SendText ($ID_socket, $array[$x].CHR(0x0D));
		IPS_Sleep(200);
	}

	IPS_Sleep(500);
	IPS_SetProperty ($ID_socket, "Open", false);
	IPS_ApplyChanges($ID_socket);
}

hier der Objektbaum:

und hier die Auswertung der Registervariable:

<?php

//******************************************************************************
// 49463
//******************************************************************************
// 
//echo "REG-Var = ".$_IPS['VALUE'];

include '17825.ips.php';    // Funktionen Meldungsausgabe
$prio		= 0;
$laut		= 20;

$ID_power	= 39302;
$ID_eingang	= 15382;
$ID_Lzeit	= 28248;
$ID_Lstatus	= 51852;
$ID_fehler	= 19388;
$ID_hw		= 36838;
$ID_Ltyp	= 30898;
$ID_sec		= 50233;

$command	= substr($_IPS['VALUE'],2,4);
$result		= "Fehler";
$meldung	= "";


//******************************************************************************
// Befehl oder Abfrage ist fehlgeschlagen
//******************************************************************************
IF(substr($_IPS['VALUE'],7,3) == "ERR")
{
	$array		= array("Undefined command", "Out of parameter", "Unavailable time", "Projector/Display failure");
	$fehler		= (int) substr($_IPS['VALUE'],10,1);
	$meldung	.= "Fehler ".$command." : ".$array[$fehler];
	$command	= "";
} 
SetValueString($ID_fehler,$meldung);


//******************************************************************************
// Befehl wurde ausgeführt
//******************************************************************************

IF(substr($_IPS['VALUE'],7,2) == "OK")
{
	$meldung	.= $_IPS['VALUE'];
	$command	= "";
}


//******************************************************************************
// Ergebnis Abfrage auswerten
//******************************************************************************

switch ($command)
{
	case "":			// schon abgefragt ERR oder OK
	break;

	case "ERST":		// Abfrage Hardware
		$result		= substr($_IPS['VALUE'],7,6);
		$meldung	.= "OK";
		if($result <> "000000")	
		{
			$meldung = "";
			$array		= array('OK','Fan error', 'Lamp error', 'Temperature error', 'Cover open error', 'Filter error', 'Other errors');
			$x = 0;
			while ( $x < 7 )
			{
  				$code	= substr($result,$x,1);
				if($code == 1)	$meldung .= "Warning ".$array[$x+1]."\n";
				if($code == 2)	$meldung .= "Error ".$array[$x+1]."\n";
				$x++;
			}
		}
		SetValueString($ID_hw, $meldung);
	break;

	case "POWR":		// Abfrage POWER
		$result		= (int) substr($_IPS['VALUE'],7,1);
		SetValueInteger($ID_power,$result);
	break;

	case "INPT":		// Abfrage EINGANG
		$result		= (int) substr($_IPS['VALUE'],7,2);
		SetValueInteger($ID_eingang,$result);
	break;

	case "LAMP":		// Abfrage EINGANG $result = %1LAMP=34 0 = 34 Std. Lampe ist aus
			$result		= substr($_IPS['VALUE'],7,6);
			$array		= explode(" ", $result);
			SetValueInteger($ID_Lzeit, $array[0]);
			SetValueBoolean($ID_Lstatus, $array[1]);
	break;

	case "RLMP":		// Abfrage Lampentypen für Ersatzlampe
			$result		= substr($_IPS['VALUE'],7,128);
			SetValueString($ID_Ltyp, $result);
	break;

	case "LINK":		// Security-Status
			$result		= (int)substr($_IPS['VALUE'],7,1);
			SetValueInteger($ID_sec, $result);
	break;

	default:
    	echo 'nicht unterstützt: '.$_IPS['VALUE'];
	break;
}

hoffentlich hilft es dir weiter.

Grüße, Peter

Vielen Dank für die ausführliche Rückmeldung! :slight_smile:

Ich habe mir jetzt einen Testbefehl zusammengebaut um die Lampenbrenndauer auszulesen:

$wert = CSCK_SendText(47390, "%1LAMP ?".CHR(0x0D));
echo $wert;

Verständnisfrage:

  1. Für was steht das %1 im Befehl?
  2. CHR(0x0D), was sagt das genau aus bzw. was passiert hier / wird hier angefragt?

Hier bekomme ich noch keine Rückmeldung aktuell.
Socket ist geöffnet und erfolgreich verbunden.

hier findest du eine Beschreibung: https://pjlink.jbmia.or.jp/english/data_cl2/PJLink_5-1.pdf

Was bekommst du in $wert? Sollte „OK“ sein.
Die weiteren Daten liefert die Register-Variable.

1 „Gefällt mir“

Danke dir für den Link bzw. die Dokumentation.
Das schaue ich mir an.

Aktuell liefert $wert 1.

Sende nur etwas, da gibt es gar keine Rückmeldung außer true (gesendet) / false (fehler).
Empfangen musst du mit einer RegisterVariable (Doku: Klick) und einem entsprechendem Script.

Du kannst auch CSCK_SendText gleich weglassen und einfach RegVar_SendText nutzen, dann hast du im Script nur mit der RegisterVariable zu tun. Egal was „dahinter“ hängt.

Michael

1 „Gefällt mir“

Danke euch beiden, damit komme ich erstmal weiter.
Jetzt geht auch das anschalten des Beamers, hier war noch der falsche Port hinterlegt.
Den korrekten Port konnte ich in der oben verlinkten Doku finden.

Jetzt werde ich mir das Thema mit den Betriebsstunden der Lampe ansehen.

Falls du bisher wenig mit der RegisterVariable gearbeitet hast, der Debug (Käfer rechts oben) der Variable hilft auch ganz gut.

Ich habe aktuell noch ein Verständnisproblem in Bezug auf „Registervariable“ und "$_IPS[‚VALUE‘] ".

Zum Thema Registervariable habe ich mir bereits folgenden Thread angesehen:

Zum Thema $_IPS[‚VALUE‘]:
Wie muss ich das Skript aufrufen, damit die Systemvariable mit Werten gefüllt wird?
Die Ausführung direkt im Skript via „Ausführen“ ist ja nicht möglich.

Wenn ich als Beispiel die Befehle nehme die weiter oben im Thread gepostet wurden:

#Anfrage Skript
CSCK_SendText(17889, "%1POWR ?".CHR(0x0D));

#Auswertung
if($_IPS['VALUE'] == "%1POWR=0".chr(0x0d)) SetValue(22402, 0);
else if($_IPS['VALUE'] == "%1POWR=1".chr(0x0d)) SetValue(22402, 1);
else if($_IPS['VALUE'] == "%1POWR=2".chr(0x0d)) SetValue(22402, 2);

In Bezug auf mein Verständnis bisher:
Mit dem Befehl „CSCK_SendText(17889, „%1POWR ?“.CHR(0x0D));“ bekomme ich vom Beamer nur eine Rückmeldung ob der Befehl erfolgreich angenommen worden ist, in meinem Fall eine 1.
(Was ich aber komisch finde warum ich hier eine 1 Rückgemeldet bekomme, da im Debug gar nicht angezeigt wird das ich eine eingehen Rückmeldung erhalte)

Der Befehl, liefert aber noch weitere Daten, um diese abzufangen benötigt ich die sogenannte Registervariable. Somit würde ich den Befehl wie folgt umbauen:

$_IPS['VALUE']  = CSCK_SendText(17889, "%1POWR ?".CHR(0x0D));

Mit dem Code für die Auswertung, kann ich dann den aktuellen Zustand auslesen:

if($_IPS['VALUE'] == "%1POWR=0".chr(0x0d)) SetValue(22402, 0);
else if($_IPS['VALUE'] == "%1POWR=1".chr(0x0d)) SetValue(22402, 1);
else if($_IPS['VALUE'] == "%1POWR=2".chr(0x0d)) SetValue(22402, 2);

Kommt das so hin in Bezug auf mein Verständnis oder habe ich das ganze Missverstanden?

Nein, du bekommst ein true zurück. Aber ein Echo macht daraus einen String und das ist dann eine 1.

Nein, tut er nicht.
Die RegisterVariable ist der empfangene Teil.

Völlig falsch, gleich vergessen.

Du musst in der RegisterVariable ein Script angeben, welches beim Empfang von Daten ausgeführt wird.
Dadurch enthält auch die Systemvariable $_IPS[‚VALUE‘] gleich die empfangenen Daten.

Aus dem Grund sind oben auch zwei Scripte.
Eines was die Anfragen sendet.
Und eines was über die RegisterVariable die empfangenen Daten verarbeitet.
Einfach zusammenkopieren geht so nicht. (Geht schon, aber halt nicht einfach und nicht wenn die Grundlagen noch fehlen. Bevor wieder jemand sagt, ja klar geht das :wink:)
Michael

Verstanden, danke dir!
Ich hatte die ganze Zeit keine Registervariable angelegt und ohne diese getestet, da ich nicht gewusst habe, das man diese als neue Instanz anlegen muss. :roll_eyes:

Einen Hinweis hierzu habe ich auch in folgendem Thread gefunden:

Aktuell sieht es so aus:

  1. Ich habe einen Button der folgendes Script ausführt um eine Anfrage an den Beamer zu senden:
    CSCK_SendText(47390, "%1POWR ?".CHR(0x0D));

    Im Debug-Log, kann ich die Rückmeldung vom Beaher sehen: (Rohtext)
    23.10.2024, 23:05:29 | PROCESSED | %1POWR=0

  2. Anschließend habe ich eine Registervariable angelegt und dieser als Gateway die Schnittstelle
    zum Beamer zugewiesen.

  3. Als Ziel für die angelegt Registervariable, habe ich ein zweites Script angegeben, mit dem dann
    die Rückmeldung des Beamers ausgewertet wird. Anschließen wird der passende Status in eine
    Statusvariable für das Frontend geschrieben.

if($_IPS['VALUE'] == "%1POWR=0")
{
    SetValueInteger(42686, 0);
}
else if($_IPS['VALUE'] == "%1POWR=1") 
{
    SetValueInteger(42686, 1);
}
else if($_IPS['VALUE'] == "%1POWR=2") 
{
    SetValueInteger(42686, 2);
}
else if($_IPS['VALUE'] == "%1POWR=3") 
{
    SetValueInteger(42686, 3);
}

Aktuell geht das auslesen und setzten des aktuellen Wertes mit dem Skript noch nicht.
Irgendwo hier habe ich noch einen Fehler drinnen, bin noch auf Fehlersuche.
Vielleicht seht ihr auf Anhieb was nicht passt.

Hast du den Debug der Registervariable mal geöffnet und siehst dort Daten kommen?

Im RegisterVariablen-Script kann man auch mal ein simples

IPS_LogMessage('Beamer RegisterVar', 'ich lebe!!');

eintragen.
Nachtrag, sollte das später mal wer finden: Gemeint war hiermit die Querkontrolle im Meldungs-Fenster, ob das Script überhaupt bis zu der entsprechenden Stelle durchläuft.

Ist die RegisterVariable dem richtigen Client-Socket I/O zugeordnet? (oben in der Leiste: Gateway ändern)

Deine Behandlung der Rückmeldung ist irgendwie nicht richtig bzw. etwas speziell.
Schau dir nochmal mein Beispielscript an (49463 Auswertung Registervariable).

@tobiasr
Den Befehl habe ich ausgeführt + Debug der Registervariable geprüft, hier sehe ich keine Debugeintrag mit dem genannten Output aus dem Befehl.

In meinem Fall sieht der Befehl wie folgt aus:
(14591 = ID der angelegten Registervariable)

IPS_LogMessage(14591, 'ich lebe!!');

@pitty
Ich habe mir meinen Code und deine Auswertung noch einmal angesehen, soweit ich sehe solle mein Code aber auch funktionieren.

Ich habe mal überprüft, welchen Wert meine $_IPS[‚VALUE‘] Variable enthält, indem ich den Inhalt in einen String geschrieben habe:

SetValueString(37071, $_IPS['VALUE']);

Inhalt des Strings:
%1POWR=0

Hier müsste die Abfrage eigentlich funktionieren und den Wert setzen:

if($_IPS['VALUE'] == "%1POWR=0")
{
    SetValueInteger(42686, 55);
}

Fehler gefunden, es lag wie es aussieht am %-Zeichen in dem String der zum Vergleich verwendet wird, ich habe den Code wie folgt umgeschrieben, hiermit funktioniert es:

$content = $_IPS['VALUE'];

if(strpos($content, '1POWR=0') !== false)
{
    SetValueInteger(42686, 0);
}
else if(strpos($content, '1POWR=1') !== false) 
{
    SetValueInteger(42686, 1);
}
else if(strpos($content, '1POWR=2') !== false) 
{
    SetValueInteger(42686, 2);
}
else if(strpos($content, '1POWR=3') !== false) 
{
    SetValueInteger(42686, 3);
}

Zwei Sachen würden mich noch interessieren:

  1. Warm der Befehl: IPS_LogMessage(14591, ‚ich lebe!!‘); nicht funktioniert und ich keinen Eintrag im Debug-Log der Registervariable sehe.
  2. Das %-Zeichen dürfte doch kein Problem verursachen, als Bestandteil vom String in Klammern: if($_IPS[‚VALUE‘] == „%1POWR=0“)

Weil der Befehl so falsch ist, da gehört keine InstanzID rein. Außerdem schreibt der Befehl in das LogFile/Meldungsfenster.
Auch ganze ohne Script, sollten im Debug der RegisterVariable und auch im Client Socket Empfangende Daten auftauchen.

Eigentlich nicht… Aber… doppelte und einfache Anführungszeichen sind da wichtig.
Einfache Anführungszeichen sind nur ein String. Bei doppelten werden u.a. auch PHP-Variablen oder Steuerzeichen in so einem String aufgelöst. Darum nach Möglichkeit einfache Anführungszeichen nutzen.

Außerdem kann es sein, dass nicht sichtbare Zeichen in den empfangenen Daten sind, darum wäre das Debug wichtig zur Kontrolle.
Da wird dann dein einfacher Vergleich mit == nicht funktionieren, wenn du z.b. Steuerzeichen nicht berücksichtigt hast. Hier wären dann doppelte Anführungszeichen korrekt und natürlich die Steuerzeichen.
Mit strpos hast du das alles allerdings umgangen.
Michael

Ich nutzte PJLink ein paar Jahre.
Nach längerer Pause durch Beamerausfall etc. wollte ich es wieder aktivieren.

  • Leider aktualisiert es nur noch, wenn ich auf „Änderungen Übernehmen“ klicke. Und dann kommt der gelbe Balken auch gleich wieder, obwohl ich doch gerade erst gespeichert hatte.
  • „Änderungen Übernehmen“ kommt auch, wenn ich das Modul nur öffne, ohne etwas geändert zu haben.

Woran könnte das liegen?