Skip to content

Commit

Permalink
Version 1.02
Browse files Browse the repository at this point in the history
  • Loading branch information
Nall-chan committed Jan 16, 2024
1 parent 3a6c38f commit efca449
Show file tree
Hide file tree
Showing 14 changed files with 164 additions and 323 deletions.
152 changes: 52 additions & 100 deletions KLF200Gateway/module.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
* @property int $ParentID
* @property string $Host
* @property string $ReceiveBuffer
* @property \KLF200\APIData $ReceiveAPIData
* @property \KLF200\APIData[][] $ReplyAPIData
* @property \KLF200\APIData $ReplyAPIData
* @property int $WaitForNodes
* @property bool $GetNodeInfoIsRunning
* @property bool $GetSceneInfoIsRunning
Expand Down Expand Up @@ -60,6 +59,7 @@ public function Create()
$this->Host = '';
$this->ParentID = 0;
$this->ReceiveBuffer = '';
$this->ReplyAPIData = null;
$this->ReplyAPIData = [];
$this->GetNodeInfoIsRunning = false;
$this->GetSceneInfoIsRunning = false;
Expand Down Expand Up @@ -94,25 +94,11 @@ public function RequestAction($Ident, $Value)
}
switch ($Ident) {
case 'GetAllNodesInformation':
if ($Value) {
if ($this->GetAllNodesInformation()) {
while ($this->GetNodeInfoIsRunning) {
IPS_Sleep(10);
}
return true;
}
}
return $this->GetAllNodesInformation();
$this->GetAllNodesInformation();
return;
case 'GetAllSceneInformation':
if ($Value) {
if ($this->GetAllSceneInformation()) {
while ($this->GetSceneInfoIsRunning) {
IPS_Sleep(10);
}
return true;
}
}
return $this->GetAllSceneInformation();
$this->GetAllSceneInformation();
return;
}
return false;
}
Expand Down Expand Up @@ -143,8 +129,7 @@ public function ApplyChanges()
$this->RegisterVariableInteger('HardwareVersion', $this->Translate('Hardware Version'), '', 0);
$this->RegisterVariableString('ProtocolVersion', $this->Translate('Protocol Version'), '', 0);
$this->ReceiveBuffer = '';
$this->ReplyAPIData = [];

$this->ReplyAPIData = null;
if (IPS_GetKernelRunlevel() == KR_READY) {
$this->RegisterParent();
if ($this->HasActiveParent()) {
Expand Down Expand Up @@ -291,7 +276,7 @@ public function RebootGateway()
protected function KernelReady()
{
$this->ReceiveBuffer = '';
$this->ReplyAPIData = [];
$this->ReplyAPIData = null;
$this->RegisterParent();
if ($this->HasActiveParent()) {
$this->IOChangeState(IS_ACTIVE);
Expand Down Expand Up @@ -356,6 +341,8 @@ protected function IOChangeState($State)
{
if ($State == IS_ACTIVE) {
if ($this->Connect()) {
$this->GetNodeInfoIsRunning = false;
$this->GetSceneInfoIsRunning = false;
$this->SetTimerInterval(\KLF200\Gateway\Timer::KeepAlive, 300000);
$this->LogMessage($this->Translate('Successfully connected to KLF200.'), KL_NOTIFY);
$this->RequestProtocolVersion();
Expand Down Expand Up @@ -394,23 +381,33 @@ protected function SendDebug($Message, $Data, $Format)

private function GetAllSceneInformation()
{
if ($this->GetSceneInfoIsRunning) {
return true;
}
$this->GetSceneInfoIsRunning = true;
$APIData = new \KLF200\APIData(\KLF200\APICommand::GET_SCENE_LIST_REQ);
$ResultAPIData = $this->SendAPIData($APIData);
if ($ResultAPIData->isError()) {
return false;
}
$this->GetSceneInfoIsRunning = true;
return ord($ResultAPIData->Data[0]) == 1;
$NumberOfSceneObject = ord($ResultAPIData->Data[0]);
if ($NumberOfSceneObject == 0) {
$this->GetSceneInfoIsRunning = false;
}
return $NumberOfSceneObject != 0;
}

private function GetAllNodesInformation()
{
if ($this->GetNodeInfoIsRunning) {
return true;
}
$this->GetNodeInfoIsRunning = true;
$APIData = new \KLF200\APIData(\KLF200\APICommand::GET_ALL_NODES_INFORMATION_REQ);
$ResultAPIData = $this->SendAPIData($APIData);
if ($ResultAPIData->isError()) {
return false;
}
$this->GetNodeInfoIsRunning = true;
return ord($ResultAPIData->Data[0]) == 1;
}

Expand Down Expand Up @@ -446,7 +443,11 @@ private function ReceiveEvent(\KLF200\APIData $APIData)
if (!$this->GetSceneInfoIsRunning) {
IPS_RunScriptText('IPS_RequestAction(' . $this->InstanceID . ',"GetAllSceneInformation",false);');
}

break;
case \KLF200\APICommand::GET_SCENE_LIST_NTF:
if (ord(substr($APIData->Data, -1, 1)) == 0) {
$this->GetSceneInfoIsRunning = false;
}
break;
}
$this->SendAPIDataToChildren($APIData);
Expand Down Expand Up @@ -536,18 +537,36 @@ private function DecodeSLIPData($SLIPData)
$Command = unpack('n', substr($TransportData, 2, 2))[1];
$Data = substr($TransportData, 4, $len - 5);
$APIData = new \KLF200\APIData($Command, $Data);
$this->SendDebug('test', $APIData, 1);
if ($APIData->isEvent()) {
$this->SendDebug('Event', $APIData, 1);
$this->ReceiveEvent($APIData);
} else {
$this->SendQueueUpdate($APIData);
$this->ReplyAPIData = $APIData;
}
if (strpos($Tail, chr(0xc0)) !== false) {
$this->SendDebug('Tail hast Start Marker', '', 0);
$this->DecodeSLIPData('');
}
} // SendQueue wieder rauswerfen.... Wartezeit hochsetzen auf 7 Sekunden
}

/**
* Wartet auf eine Antwort einer Anfrage an den LMS.
*
* @param string $APICommand
* @return ?\KLF200\APIData
*/
private function ReadReplyAPIData()
{
for ($i = 0; $i < 2000; $i++) {
$Buffer = $this->ReplyAPIData;
if (!is_null($Buffer)) {
$this->ReplyAPIData = null;
return $Buffer;
}
IPS_Sleep(5);
}
return null;
}

/**
* SendAPIData
Expand All @@ -559,6 +578,7 @@ private function DecodeSLIPData($SLIPData)
private function SendAPIData(\KLF200\APIData $APIData, bool $SetState = true)
{
try {
$this->SendDebug('Wait to send', $APIData, 1);
$time = microtime(true);
while (true) {
if ($this->lock('SendAPIData')) {
Expand All @@ -574,14 +594,13 @@ private function SendAPIData(\KLF200\APIData $APIData, bool $SetState = true)
}
$Data = $APIData->GetSLIPData();
$this->SendDebug('Send', $APIData, 1);
//$this->SendDebug('Send SLIP Data', $Data, 1);
$JSON['DataID'] = \KLF200\GUID::ToClientSocket;
$JSON['Buffer'] = utf8_encode($Data);
$JsonString = json_encode($JSON);
$this->SendQueueAdd($APIData->Command, $APIData->NodeID);
$this->ReplyAPIData = null;
parent::SendDataToParent($JsonString);
$ResponseAPIData = $this->ReadReplyAPIData();
$this->unlock('SendAPIData');
$ResponseAPIData = $this->SendQueueWaitForResponse($APIData->Command, $APIData->NodeID);
if ($ResponseAPIData === null) {
throw new Exception($this->Translate('Timeout.'), E_USER_NOTICE);
}
Expand All @@ -601,71 +620,4 @@ private function SendAPIData(\KLF200\APIData $APIData, bool $SetState = true)
}
return $ResponseAPIData;
}

//################# SendQueue
private function SendQueueAdd(int $APIDataCommand, int $NodeId)
{
$APIDataCommand++;
$this->lock('ReplyAPIData');
$ReplyAPIData = $this->ReplyAPIData;
$ReplyAPIData[$APIDataCommand][$NodeId] = null;
$this->ReplyAPIData = $ReplyAPIData;
$this->unlock('ReplyAPIData');
}

private function SendQueueUpdate(\KLF200\APIData $APIData)
{
$this->lock('ReplyAPIData');
$ReplyAPIData = $this->ReplyAPIData;
if (!array_key_exists($APIData->Command, $ReplyAPIData)) {
$this->unlock('ReplyAPIData');
return false;
}
if (!array_key_exists($APIData->NodeID, $ReplyAPIData[$APIData->Command])) {
$this->unlock('ReplyAPIData');
return false;
}
$ReplyAPIData[$APIData->Command][$APIData->NodeID] = $APIData;
$this->ReplyAPIData = $ReplyAPIData;
$this->unlock('ReplyAPIData');
return true;
}

private function SendQueueWaitForResponse(int $APIDataCommand, int $NodeId)
{
$APIDataCommand++;
for ($i = 0; $i < 1200; $i++) {
$this->lock('ReplyAPIData');
$ReplyAPIData = $this->ReplyAPIData;
$this->unlock('ReplyAPIData');
if (!array_key_exists($APIDataCommand, $ReplyAPIData)) {
$this->SendDebug('Error in SendQueueWait', \KLF200\APICommand::ToString($APIDataCommand), 0);
return null;
}
if (!array_key_exists($NodeId, $ReplyAPIData[$APIDataCommand])) {
$this->SendDebug('Error in SendQueueWait', \KLF200\APICommand::ToString($APIDataCommand), 0);
return null;
}
if (is_a($ReplyAPIData[$APIDataCommand][$NodeId], '\\KLF200\\APIData')) {
$this->SendQueueRemove($APIDataCommand, $NodeId);
return $ReplyAPIData[$APIDataCommand][$NodeId];
}
IPS_Sleep(5);
}
$this->SendQueueRemove($APIDataCommand, $NodeId);
return null;
}

private function SendQueueRemove(int $APIDataCommand, $NodeID)
{
$this->lock('ReplyAPIData');
$ReplyAPIData = $this->ReplyAPIData;
if (array_key_exists($APIDataCommand, $ReplyAPIData)) {
if (array_key_exists($NodeID, $ReplyAPIData[$APIDataCommand])) {
unset($ReplyAPIData[$APIDataCommand][$NodeID]);
$this->ReplyAPIData = $ReplyAPIData;
}
}
$this->unlock('ReplyAPIData');
}
}
7 changes: 7 additions & 0 deletions KLF200Gateway/module.php.rej
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
diff a/KLF200Gateway/module.php b/KLF200Gateway/module.php (rejected hunks)
@@ -30,4 +30,5 @@
* @property \KLF200\APIData $ReceiveAPIData
+ * @property \KLF200\APIData[][] $ReplyAPIData
* @property int $WaitForNodes
* @property bool $GetNodeInfoIsRunning
* @property bool $GetSceneInfoIsRunning
2 changes: 2 additions & 0 deletions KLF200Node/locale.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@
"Closed": "Geschlossen",
"Instance does not implement this function": "Instanz unterstützt diese Funktion nicht",
"Invalid Ident": "Ungültiger Ident",
"Request accepted": "Anfrage angenommen",
"Invalid Parameters": "Ungültige Parameter",
"Request rejected": "Anfrage abgelehnt",
"Invalid node index": "Ungültiger Node-Eintrag",
"Instance has no active parent.": "Instanz hat keinen aktiven Parent.",
Expand Down
15 changes: 9 additions & 6 deletions KLF200Node/module.php
Original file line number Diff line number Diff line change
Expand Up @@ -902,14 +902,17 @@ private function SendAPIData(\KLF200\APIData $APIData, int $SessionId = -1)
if ($SessionId == -1) {
return $ResponseAPIData;
}
$ResultStatus = (ord($ResponseAPIData->Data[0]) == 0);
if (!$ResultStatus) {
$this->SessionQueueRemove($SessionId);
trigger_error($this->Translate('Command is rejected'), E_USER_NOTICE);
return false;
$ResultStatus = ord($ResponseAPIData->Data[0]);
switch ($ResultStatus) {
case \KLF200\Status::INVALID_PARAMETERS:
case \KLF200\Status::REQUEST_REJECTED:
$this->SessionQueueRemove($SessionId);
trigger_error($this->Translate(\KLF200\State::ToString($ResultStatus)), E_USER_NOTICE);
return false;
break;
}
if (!$this->ReadPropertyBoolean(\KLF200\Node\Property::WaitForFinishSession)) {
return $ResultStatus;
return true;
}
$SessionStatus = $this->SessionQueueWaitForFinish($SessionId);
if ($SessionStatus['RunStatus'] == \KLF200\RunStatus::EXECUTION_FAILED) {
Expand Down
Loading

0 comments on commit efca449

Please sign in to comment.