Ich habe jetzt das umgestellt habe aber leider immer noch Probleme mit der Abarbeitung des Scripts.
Wenn ich wenige Befehle schicke, der Array also klein ist funktioniert es.
Dann bekomme ich z.B.:
string(11) "PSMULTEQ: ?"
Var Update um: 09:57:19 Uhr
string(3) "Off"
string(9) "PSMODE: ?"
Var Update um: 09:57:20 Uhr
string(6) "Cinema"
Es braucht also in der Regel eine Sekunde zwischen dem Absenden des Befehls und der Änderung der Variable in IPS durch den Response.
Sobald der Array jetzt aber größerer wird hängt das Script. Der Semaphore ist blockiert und das Skript hängt dauerhaft unter den PHP Threads.
Das Test Script sieht so aus:
$AVRCommands = array(
//"51885" => "PSCEN",
//"44694" => "PSDIM",
//"24914" => "VSAUDIO",
"38534" => "PSMULTEQ",
//"37854" => "PSPHG",
//"12262" => "PSREFLEV",
//"39670" => "PSRSZ",
//"33661" => "PSSTW",
//"54742" => "PSSTH",
//"33941" => "PSSB",
//"29885" => "PSMODE",
//"57450" => "VSVST",
//"50103" => "SV",
//"31051" => "PVCN",
//"33661" => "PSSTW",
//"54742" => "PSSTH",
"29885" => "PSMODE"
);
foreach ($AVRCommands as $ObjektID => $Ident)
{
$timestamp = time();
$state = updatestates($timestamp, $ObjektID, $Ident);
var_dump($state);
}
function updatestates($timestamp, $ObjektID, $Ident)
{
if ($Ident == "CVFL" || $Ident == "CVFR" || $Ident == "CVC" || $Ident == "CVSW" || $Ident == "CVSL" || $Ident == "CVSR")
{
$Command = "CV";
}
elseif($Ident == "PSDYNVOL")//Dynamic Volume
{
$Command = "PSDYNVOL ";
}
elseif($Ident == "PSVOLLEV")//Dolby Volume Leveler
{
$Command = "PSVOLLEV ";
}
elseif($Ident == "PSVOLMOD")//Dolby Volume Modeler
{
$Command = "PSVOLMOD ";
}
elseif($Ident == "PSDOLVOL")//Dolby Volume
{
$Command = "PSDOLVOL ";
}
elseif($Ident == "PSPAN")//Panorama
{
$Command = "PSPAN ";
}
elseif($Ident == "PSMULTEQ")//PSMULTEQ
{
$Command = "PSMULTEQ: ";
}
elseif($Ident == "PVCM")//Chroma Level
{
$Command = "PVCM ";
}
elseif($Ident == "PSSWR")//Subwoofer
{
$Command = "PSSWR ";
}
elseif($Ident == "PSEFF")//Effekt
{
$Command = "PSEFF ";
}
elseif($Ident == "PVCN")//Contrast
{
$Command = "PVCN ";
}
elseif($Ident == "PVENH")//Enhancer
{
$Command = "PVENH ";
}
elseif($Ident == "PSSWR")//Subwoofer
{
$Command = "PSSWR ";
}
elseif($Ident == "PSEFF") //Effekt Level
{
$Command = "PSEFF ";
}
elseif($Ident == "VSVST") //Vertical Stretch
{
$Command = "VSVST ";
}
elseif($Ident == "PSRSZ") //Room Size
{
$Command = "PSRSZ ";
}
elseif($Ident == "PSCINEMA_EQ") //Cinema EQ
{
$Command = "PSCINEMA EQ. ";
}
elseif($Ident == "PSCINEMA_EQ") //Tone CTRL
{
$Command = "PSCINEMA EQ. ";
}
elseif($Ident == "PSDELAY") //Audio Delay
{
$Command = "PSDELAY ";
}
elseif($Ident == "MSQUICK") //MSQUICK
{
$Command = "MSQUICK ";
}
elseif($Ident == "PSSB") //Surround Back Mode
{
$Command = "PSSB: ";
}
elseif($Ident == "PVBR") //Brightness
{
$Command = "PVBR ";
}
elseif($Ident == "PVHUE") //Hue
{
$Command = "PVHUE ";
}
elseif($Ident == "PSATT") //Subwoofer ATT
{
$Command = "PSATT ";
}
elseif($Ident == "PSSTW") //Stage Width
{
$Command = "PSSTW ";
}
elseif($Ident == "PSSTH") //Stage Height
{
$Command = "PSSTH ";
}
elseif($Ident == "PSMODE") //Surround Play Mode
{
$Command = "PSMODE: ";
}
elseif($Ident == "PSAFD") //AFDM
{
$Command = "PSAFD ";
}
elseif($Ident == "PSSP") // Speaker Output Front
{
$Command = "PSSP".chr(58).chr(32);
}
elseif($Ident == "VSASP") //ASP
{
$Command = "VSASP ";
}
elseif($Ident == "PSCEI") //Center Image
{
$Command = "PSCEI ";
}
elseif($Ident == "PVCN") //Contrast
{
$Command = "PVCN ";
}
elseif($Ident == "PSREFLEV") //Reference Level
{
$Command = "PSREFLEV ";
}
elseif($Ident == "VSSC") //Resolution
{
$Command = "VSSC ";
}
elseif($Ident == "VSSCH") //Resolution HDMI
{
$Command = "VSSCH ";
}
elseif($Ident == "VSAUDIO") //HDMI Audio Output
{
$Command = "VSAUDIO ";
}
elseif($Ident == "PSEFF") //Effect Level
{
$Command = "PSEFF ";
}
elseif($Ident == "PSEFF_O") //Effect
{
$Command = "PSEFF ";
}
elseif($Ident == "PSDSX") //Audyssey DSX
{
$Command = "PSDSX ";
}
elseif($Ident == "PSDYNEQ") //Dynamic EQ
{
$Command = "PSDYNEQ ";
}
elseif($Ident == "PSFH") //Front Hight
{
$Command = "PSFH: ";
}
elseif($Ident == "PSCEN") //Center Width
{
$Command = "PSCEN ";
}
elseif($Ident == "PSDIM") //Dimension
{
$Command = "PSDIM ";
}
elseif($Ident == "PSPHG") //PLIIZ Height Gain
{
$Command = "PSPHG ";
}
elseif($Ident == "PSBAS") //Bass Level
{
$Command = "PSBAS ";
}
elseif($Ident == "PSTRE") //Treble Level
{
$Command = "PSTRE ";
}
elseif($Ident == "PSLFE") //LFE Level
{
$Command = "PSLFE ";
}
elseif($Ident == "PVDNR") //Digital Noise Reduction
{
$Command = "PVDNR ";
}
elseif($Ident == "VSMONI") //HDMI Monitor
{
$Command = "VSMONI ";
}
elseif($Ident == "VSVPM") //Video Processing Mode
{
$Command = "VSVPM ";
}
else
{
$Command = $Ident;
}
$request = $Command.chr(63);
var_dump($request);
//Semaphore setzen
if (lock("StatusUpdate"))
{
// Daten senden
try
{
if ($Ident !== "PSEFF_O")
{
DAVRT_SendCommand(34489 /*[Modultest\Denon AV Receiver Telnet Control]*/, $request);
}
elseif($Ident == "PSEFF_O")
{
$request = "PSEFF".chr(63);
DAVRT_SendCommand(34489 /*[Modultest\Denon AV Receiver Telnet Control]*/, $request);
}
}
catch (Exception $exc)
{
// Senden fehlgeschlagen
$this->unlock("StatusUpdate");
throw new Exception($exc);
}
unlock("StatusUpdate");
}
else
{
echo "Can not send to parent
";
unlock("StatusUpdate");
//throw new Exception("Can not send to parent",E_USER_NOTICE);
}
// Response abholen
if (lock("StatusUpdate"))
{
try
{
$state = getresponse ($ObjektID, $timestamp);
}
catch (Exception $exc)
{
// Senden fehlgeschlagen
unlock("StatusUpdate");
throw new Exception($exc);
}
unlock("StatusUpdate");
return $state;
}
else
{
echo "Can not get response
";
unlock("StatusUpdate");
//throw new Exception("Can not get response",E_USER_NOTICE);
}
}
function getresponse ($ObjektID, $timestamp)
{
$Ident = IPS_GetObject($ObjektID)["ObjectIdent"];
if ($Ident !== "PSEFF_O")
{
$i = 0;
do
{
IPS_Sleep(50);
$updatetimestamp = IPS_GetVariable($ObjektID)["VariableUpdated"];
//echo $i."
";
$i++;
}
while($updatetimestamp <= $timestamp);
$lastupdate = date("H:i:s", $updatetimestamp);
echo "Var Update um: ".$lastupdate." Uhr
";
$state = GetValueFormatted($ObjektID);
return $state;
}
elseif ($Ident == "PSEFF_O")
{
$i = 0;
do
{
IPS_Sleep(50);
$idPSEFF = IPS_GetObjectIDByIdent("PSEFF", 34489 /*[Modultest\Denon AV Receiver Telnet Control]*/);
$updatetimestamp = IPS_GetVariable($idPSEFF)["VariableUpdated"];
$i++;
}
while($updatetimestamp <= $timestamp);
$lastupdate = date("H:i:s", $updatetimestamp);
echo "Var Update um: ".$lastupdate." Uhr
";
$state = GetValue($idPSEFF);
if ($state == 0.0)
{
$state = false;
}
else
{
$state = true;
}
return $state;
}
}
################## SEMAPHOREN Helper - private
function lock($ident)
{
for ($i = 0; $i < 3000; $i++)
{
if (IPS_SemaphoreEnter("DENONAVRT_" . (string) $ident, 1))
//if (IPS_SemaphoreEnter("DENONAVRT_" . (string) $this->InstanceID . (string) $ident, 1))
{
return true;
}
else
{
IPS_Sleep(mt_rand(1, 5));
}
}
return false;
}
function unlock($ident)
{
IPS_SemaphoreLeave("DENONAVRT_" . (string) $ident);
//IPS_SemaphoreLeave("DENONAVRT_" . (string) $this->InstanceID . (string) $ident);
}
Hat jemand eine Idee warum das Script hängt?
Kann ich einen hängenden PHP Thread über die ThreadID einzeln killen bzw. beenden ohne IPS komplett schießen zu müssen?
Desweiteren bekomme ich wohl auch ein Problem bei vielen Variablen mit dem Timeout wenn es 1 Sekunde braucht bis jeweils der aktuelle Status in IPS in der Variable gesetzt wird. Ich müsste initial nach dem Starten des Moduls einmal für alle angelegten Variablen den Status abfragen. Hat irgendjemand eine Idee wie man dies am besten macht ohne ein Timeout Problem zu bekommen?