342 lines
10 KiB
PHP
342 lines
10 KiB
PHP
<?php
|
|
|
|
// Configuration
|
|
// SERVER root to Domoticz
|
|
$domoticz_server = 'http://localhost:8080';
|
|
|
|
// PLUGS
|
|
// mac (without special chars and lowercase) = IDX
|
|
// change next arrays and add / remove lines to add / remove plugs
|
|
$mienchufe['accf23514ddd'] = '106'; // Description
|
|
$mienchufe['accf23514eee'] = '107'; // Description
|
|
|
|
|
|
// Do NOT change these
|
|
$orvibo['ip'] = "0.0.0.0";
|
|
$orvibo['port'] = 10000;
|
|
$orvibo['NEED_DISCOVER'] = 1;
|
|
|
|
|
|
function makePayload($data) {
|
|
$res='';
|
|
foreach($data as $v) {
|
|
$res.=chr($v);
|
|
}
|
|
return $res;
|
|
}
|
|
|
|
function HexStringToArray($buf) {
|
|
$res=array();
|
|
for($i=0;$i<strlen($buf)-1;$i+=2) {
|
|
$res[]=(hexdec($buf[$i].$buf[$i+1]));
|
|
}
|
|
return $res;
|
|
}
|
|
|
|
function HexStringToString($buf) {
|
|
$res='';
|
|
for($i=0;$i<strlen($buf)-1;$i+=2) {
|
|
$res.=chr(hexdec($buf[$i].$buf[$i+1]));
|
|
}
|
|
return $res;
|
|
}
|
|
|
|
|
|
function binaryToString($buf) {
|
|
$res='';
|
|
for($i=0;$i<strlen($buf);$i++) {
|
|
$num=dechex(ord($buf[$i]));
|
|
if (strlen($num)==1) {
|
|
$num='0'.$num;
|
|
}
|
|
$res.=$num;
|
|
}
|
|
return $res;
|
|
}
|
|
|
|
|
|
//Create a UDP socket
|
|
if(!($sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)))
|
|
{
|
|
$errorcode = socket_last_error();
|
|
$errormsg = socket_strerror($errorcode);
|
|
|
|
die("Couldn't create socket: [$errorcode] $errormsg \n");
|
|
}
|
|
|
|
echo "Socket created \n";
|
|
|
|
// Bind the source address
|
|
if( !socket_bind($sock, $orvibo['ip'] , $orvibo['port']) )
|
|
{
|
|
$errorcode = socket_last_error();
|
|
$errormsg = socket_strerror($errorcode);
|
|
|
|
die("Could not bind socket : [$errorcode] $errormsg \n");
|
|
}
|
|
|
|
echo "Socket bind (".$orvibo['ip'].":".$orvibo['port'].") OK \n";
|
|
|
|
socket_set_option($sock, SOL_SOCKET, SO_BROADCAST, 1);
|
|
|
|
$discover=1;
|
|
|
|
|
|
$latest_config_read=time();
|
|
$tiempo_ejecucion=time();
|
|
$subscribed=array();
|
|
$ahora = time()+20;
|
|
|
|
//Do some communication, this loop can handle multiple clients
|
|
while(1)
|
|
{
|
|
|
|
// setGlobal((str_replace('.php', '', basename(__FILE__))).'Run', time(), 1);
|
|
|
|
if ((time()-$latest_config_read)>10) {
|
|
$latest_config_read=time();
|
|
|
|
if ($orvibo['NEED_DISCOVER']) {
|
|
echo date('H:i:s')." Need discover flag set ... \n";
|
|
$discover=1;
|
|
$orvibo['NEED_DISCOVER']=0;
|
|
}
|
|
}
|
|
|
|
if ((time()-$latest_discover)>5*60) {
|
|
echo date('H:i:s')." Discover timeout, rediscovering ... \n";
|
|
$discover=1;
|
|
}
|
|
|
|
if ($discover) {
|
|
echo date('H:i:s')." Discovering ... \n";
|
|
|
|
$payload = makePayload(array(0x68, 0x64, 0x00, 0x06, 0x71, 0x61));
|
|
echo date('H:i:s')." Sending multicast: ".binaryToString($payload)."\n";
|
|
socket_sendto($sock, $payload, strlen($payload), 0, '255.255.255.255', $orvibo['port']);
|
|
|
|
$latest_discover=time();
|
|
$discover=0;
|
|
}
|
|
|
|
echo date('H:i:s')." Waiting for data ... \n";
|
|
|
|
//Receive some data
|
|
socket_set_option($sock,SOL_SOCKET,SO_RCVTIMEO,array("sec"=>10,"usec"=>0));
|
|
$buf='';
|
|
@$r = socket_recvfrom($sock, $buf, 512, 0, $remote_ip, $remote_port);
|
|
if ($remote_ip!=$orvibo['ip'] && $buf!='') {
|
|
processMessage($buf, $remote_ip, $sock);
|
|
}
|
|
$ahora2 = time();
|
|
// if (file_exists('./reboot') || IsSet($_GET['onetime']) || $ahora2 < $ahora)
|
|
if (file_exists('./reboot') || IsSet($_GET['onetime']) || $contador > 12 )
|
|
{
|
|
print_r($enchufe);
|
|
|
|
// MENSAJE
|
|
//json.htm?type=command¶m=addlogmessage&message=MESSAGE
|
|
// Initiate curl
|
|
//$mensaje = urlencode("Mensaje de prueba en LOG");
|
|
//$url = $domoticz_server.'/json.htm?type=command¶m=addlogmessage&message='.$mensaje;
|
|
//$respuesta = send_url($url);
|
|
//$result = file_get_contents($url);
|
|
|
|
// Will dump a beauty json :3
|
|
// var_dump(json_decode($result, true));
|
|
foreach($enchufe as $k => $v) {
|
|
if ( $mienchufe[$k] ) {
|
|
|
|
$switchcmd = '';
|
|
if ( $v == "1" ) {
|
|
$switchcmd = 'On';
|
|
} elseif ( $v == "0" ) {
|
|
$switchcmd = 'Off';
|
|
}
|
|
|
|
if ( $switchcmd != '' ) {
|
|
$url = $domoticz_server.'/json.htm?type=command¶m=switchlight&idx='.$mienchufe[$k].'&switchcmd='.$switchcmd;
|
|
$respuesta = send_url($url);
|
|
$respuesta_json = json_decode($respuesta, true);
|
|
print_r($respuesta_json);
|
|
$mensaje = urlencode("Orvibo S20 - idx: ".$mienchufe[$k]." - mac: ".$k." - status: ".$switchcmd." - response: ".$respuesta_json['status']);
|
|
$url = $domoticz_server.'/json.htm?type=command¶m=addlogmessage&message='.$mensaje;
|
|
$respuesta = send_url($url);
|
|
|
|
}
|
|
}
|
|
|
|
//$mensaje = urlencode("Mensaje de prueba en LOG");
|
|
//$url = $domoticz_server.'/json.htm?type=command¶m=addlogmessage&message='.$mensaje;
|
|
//$respuesta = send_url($url);
|
|
|
|
}
|
|
// TURN ON / OFF
|
|
//
|
|
|
|
socket_close($sock);
|
|
// $db->Disconnect();
|
|
exit;
|
|
}
|
|
|
|
$contador++;
|
|
|
|
}
|
|
|
|
socket_close($sock);
|
|
|
|
|
|
function send_url($url) {
|
|
$ch = curl_init();
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_URL,$url);
|
|
$result=curl_exec($ch);
|
|
curl_close($ch);
|
|
return($result);
|
|
}
|
|
|
|
|
|
|
|
function processMessage($buf, $remote_ip, $sock) {
|
|
global $subscribed,$enchufe;
|
|
|
|
echo date('H:i:s')." $remote_ip : " . binaryToString($buf)."\n";
|
|
$twenties=array(0x20, 0x20, 0x20, 0x20, 0x20, 0x20);
|
|
|
|
$message=binaryToString($buf);
|
|
$macAddress = '';
|
|
if (is_integer(strpos($message, 'accf'))) {
|
|
$macAddress = substr($message, strpos($message, 'accf'),12);
|
|
}
|
|
if (!$macAddress) {
|
|
return;
|
|
}
|
|
|
|
echo date('H:i:s')." MAC: ".$macAddress."\n";
|
|
$command=substr($message, 8,4);
|
|
echo "Command: $command \n";
|
|
// $rec=SQLSelectOne("SELECT * FROM orvibodevices WHERE MAC LIKE '".DBSafe($macAddress)."'");
|
|
if (!$rec['ID'] && $command!='7161') {
|
|
echo date('H:i:s')." Unknown device.";
|
|
return;
|
|
}
|
|
if ($command=='7161') { // We've asked for all sockets on the network, and smoeone has replied!
|
|
echo date('H:i:s')." Discover reply from $macAddress\n";
|
|
if (is_integer(strpos($message, '4952443030'))) { //from a known AllOne (because IR00 appears in the packet)
|
|
$rec['TYPE']=1;
|
|
if (!$rec['TITLE']) {
|
|
$rec['TITLE']='AllOne - '.$macAddress;
|
|
}
|
|
} elseif (is_integer(strpos($message, '534f433030'))) { //socket
|
|
$rec['TYPE']=0;
|
|
if (!$rec['TITLE']) {
|
|
$rec['TITLE']='Socket - '.$macAddress;
|
|
}
|
|
} else {
|
|
$rec['TYPE']=1;
|
|
if (!$rec['TITLE']) {
|
|
$rec['TITLE']='Unknown - '.$macAddress;
|
|
}
|
|
}
|
|
echo $rec['TITLE']."\n";
|
|
$rec['MAC']=$macAddress;
|
|
$rec['IP']=$remote_ip;
|
|
$rec['UPDATED']=date('Y-m-d H:i:s');
|
|
$rec['status']=substr($message,-1);
|
|
// AQUI ACTUALIZAMOS
|
|
$enchufe[$macAddress] = $rec['status'];
|
|
|
|
if ($rec['ID']) {
|
|
// SQLUpdate('orvibodevices', $rec);
|
|
} else {
|
|
// SQLInsert('orvibodevices', $rec);
|
|
}
|
|
|
|
//subscribe to it
|
|
//if (!$this->subscribed[$rec['MAC']] || ((time()-$this->subscribed[$rec['MAC']])>30)) {
|
|
$macReversed=array_reverse(HexStringToArray($rec['MAC']));
|
|
$payload = makePayload(array(0x68, 0x64, 0x00, 0x1e, 0x63, 0x6c)).makePayload(HexStringToArray($rec['MAC'])).makePayload($twenties).makePayload($macReversed).makePayload($twenties);
|
|
echo date('H:i:s')." Sending subscribe request: ".binaryToString($payload)."\n";
|
|
socket_sendto($sock, $payload, strlen($payload), 0, $rec['IP'], $orvibo['port']);
|
|
$subscribed[$rec['MAC']]=time();
|
|
//query for name (optional)
|
|
/*
|
|
$payload = $this->makePayload(array(0x68, 0x64, 0x00, 0x1d, 0x72, 0x74));
|
|
$payload.=$this->makePayload($this->HexStringToArray($rec['MAC']));
|
|
$payload.=$this->makePayload($twenties);
|
|
$payload.=$this->makePayload(array(0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00));
|
|
echo date('H:i:s')." Sending name request: ".$this->binaryToString($payload)."\n";
|
|
socket_sendto($sock, $payload, strlen($payload), 0, $rec['IP'], $this->port);
|
|
*/
|
|
//}
|
|
|
|
|
|
} elseif ($command=='7274') { // We've queried the socket for the name, and we've got data coming back
|
|
echo date('H:i:s')." Name reply from $macAddress\n";
|
|
$tmp=explode('202020202020', $message);
|
|
$strName=$tmp[4];
|
|
if(strName == "ffffffffffffffffffffffffffffffff") {
|
|
$strName='Orvibo '.$rec['MAC'];
|
|
if ($rec['TYPE']==0) {
|
|
$strName.=" (socket)";
|
|
}
|
|
} else {
|
|
$strName=trim(HexStringToString($strName));
|
|
}
|
|
if (!$rec['TITLE']) {
|
|
$rec['TITLE']=$strName;
|
|
// SQLUpdate('orvibodevices', $rec);
|
|
}
|
|
|
|
} elseif ($command=='636c') { // We've asked to subscribe to an AllOne, and this is confirmation.
|
|
echo date('H:i:s')." Subscription reply from $macAddress\n";
|
|
} elseif ($command=='6463') { // We've asked to change our state, and it's happened
|
|
echo date('H:i:s')." State change reply from $macAddress\n";
|
|
} elseif ($command=='6469') { // Possible button press, or just a ping thing?
|
|
echo date('H:i:s')." Button pressed from $macAddress\n";
|
|
if ($rec['LINKED_OBJECT'] && $rec['LINKED_METHOD_BUTTON']) {
|
|
$params=array();
|
|
$params['VALUE']=$rec['VALUE_IR'];
|
|
callMethod($rec['LINKED_OBJECT'].'.'.$rec['LINKED_METHOD_BUTTON'], $params);
|
|
}
|
|
} elseif ($command=='7366') { // Something has changed our socket state externally
|
|
echo date('H:i:s')." Socket state changed from $macAddress\n";
|
|
if ($rec['TYPE']==0) {
|
|
$state=substr($message, strlen($message)-1, 1);
|
|
$this->statusChanged($rec['ID'], (int)$state);
|
|
}
|
|
} elseif ($command=='6963') { // We've asked to emit some IR and it's been done.
|
|
echo date('H:i:s')." Emit IR done from $macAddress\n";
|
|
} elseif ($command=='6c73') { // We're in learning mode, and we've got some IR back!
|
|
echo date('H:i:s')." IR learning mode done from $macAddress\n";
|
|
if (substr($message, 4, 4)!='0018') {
|
|
$code=substr($message, 52);
|
|
echo date('H:i:s')." Code: ".$code."\n";
|
|
$rec['VALUE_IR']=$code;
|
|
$rec['UPDATED']=date('Y-m-d H:i:s');
|
|
SQLUpdate('orvibodevices', $rec);
|
|
|
|
if ($rec['LINKED_OBJECT'] && $rec['LINKED_PROPERTY']) {
|
|
setGlobal($rec['LINKED_OBJECT'].'.'.$rec['LINKED_PROPERTY'], $rec['VALUE_IR'], array($this->name=>'0'));
|
|
}
|
|
|
|
if ($rec['LINKED_OBJECT'] && $rec['LINKED_METHOD']) {
|
|
$params=array();
|
|
$params['VALUE']=$rec['VALUE_IR'];
|
|
callMethod($rec['LINKED_OBJECT'].'.'.$rec['LINKED_METHOD'], $params);
|
|
}
|
|
|
|
|
|
} else {
|
|
echo date('H:i:s')." Ignoring result\n";
|
|
}
|
|
} else {
|
|
echo date('H:i:s')." Unknown command: $command \n";
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|