only used for debugging
//-----------------------------------------------------
function str2Hex($string)
{
$hex='';
for ($i=0; $i < strlen($string); $i++)
{
$hex .= dechex(ord($string[$i])).' ';
}
return $hex;
}
//-----------------------------------------------------
// Open connection
// klf200 uses a self signed cert with TLS. Does this make sense?
// It takes around 5!!! secs to establish a connection!
//-----------------------------------------------------
function socketOpen($url)
{
$stream_context = stream_context_create([ 'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true,
]]);
$fp = stream_socket_client('ssl://'.$url.':51200',$errno, $errstr, 10, STREAM_CLIENT_CONNECT, $stream_context);
return $fp;
}
//-----------------------------------------------------
// Send a command and get a response
//-----------------------------------------------------
function socketSend($fp,$payload)
{
$resp = '';
if ($fp)
{
fwrite($fp, $payload);
//echo 'tx:'.str2Hex($payload).'
';
$resp = fread($fp, 255);
//echo 'rx:'.str2Hex($resp).'
';
}
return $resp;
}
//-----------------------------------------------------
// Close connection
//-----------------------------------------------------
function socketClose($fp)
{
fclose($fp);
}
//-----------------------------------------------------
// Wrap with slip
//-----------------------------------------------------
function slip_pack($data)
{
$data = str_replace(SLIP_ESC,SLIP_ESC.SLIP_ESC_ESC,$data);
$data = str_replace(SLIP_END,SLIP_ESC.SLIP_ESC_END,$data);
return (SLIP_END.$data.SLIP_END);
}
//-----------------------------------------------------
// Unwrap from slip
//-----------------------------------------------------
function slip_unpack($data)
{
if (substr($data,-1) == SLIP_END)
$data = substr_replace($data ,"",-1);
if (substr($data, 0, 1) == SLIP_END)
$data = substr($data ,1);
$data = str_replace(SLIP_ESC.SLIP_ESC_END,SLIP_END,$data);
$data = str_replace(SLIP_ESC.SLIP_ESC_ESC,SLIP_ESC,$data);
return $data;
}
//-----------------------------------------------------
// Add the xor checksum
//-----------------------------------------------------
function calc_checksum($data)
{
$chk = 0;
for ($i=0; $i < strlen($data); $i++)
{
$chk = $chk ^ ord($data[$i]);
}
return $chk;
}
//-----------------------------------------------------
// Build the command with checksum and slip
//-----------------------------------------------------
function build_cmd_str($cmd,$param)
{
$data = $cmd.$param;
$data = chr(strlen($data)+1).$data; // add length
$data = chr(0x00).$data.chr(calc_checksum($data)); // add protocol id and checksum
return slip_pack($data); // add slip
}
//-----------------------------------------------------
// Select a scene from the KLF200
//-----------------------------------------------------
function klf_scene($val)
{
// Open connection (takes around 5secs!!!)
$sock = socketOpen(KLF_IP);
if (!$sock) return 'nOpen';
// Send Password (takes a few ms)
$cmd = build_cmd_str(GW_PASSWORD_ENTER_REQ,KLF_PW);
$resp = socketSend($sock,$cmd);
// Send scene selection (takes a few tens of ms)
$param = chr(19).chr($val); // SessionID, we use scene number here to differentiate interleaving calls
$param = $param.chr(01); // Command Originator = user
$param = $param.chr(03); // PriorityLevel = User2
$param = $param.chr($val); // SceneID
$param = $param.chr(00); // Velocity = Default
$cmd = build_cmd_str(GW_ACTIVATE_SCENE_REQ,$param);
$resp = socketSend($sock,$cmd);
// Close connection
socketClose($sock);
return 'ok';
}
//-----------------------------------------------------
// main
//-----------------------------------------------------
// For testing
if (!isset($_GET["cmd"])
$_GET["cmd"] = '4close';
// Check the GET Parameter
$res = '???';
if (isset($_GET["cmd"]))
{
switch (htmlspecialchars($_GET["cmd"]))
{
case '4close':
$res = klf_scene(0); // 4OG Close
break;
case '4open':
$res = klf_scene(1); // 4OG Open
break;
case '5close':
$res = klf_scene(2); // 5OG Open
break;
case '5open':
$res = klf_scene(3); // 5OG Open
break;
}
}
echo $res;
?>