reine PHP-Steuerung für EZcontrol T-10

Hallo zusammen,
ich habe mal ein Demo-Script gebaut, was rein über PHP an den T-10 angeschlossene Geräte im Preset-Modus steuern und Auslesen kann.
Für PHP-Anfänger sind vieleicht die Funktionen zur Nutzung von UDP-Sockets oder der C-Strukturen interessant.

Have Fun!

Tommi


<?
/*
	EZConsole.php
	PHP-demo functions to set and get status of EZcontrolT-10 controlled devices
	(C) 2006 Thomas Dreßler
	
	development has been guided by the following code 	:
	(taken from http://www.ezcontrol.de)	
*  ezcontrol.c - UDP control program for EZcontrol T-10 
*  actorpoll.c - UDP actor poll program for EZcontrol T-10 
*  Copyright (c) 2005 Rose + Herleth GbR. All rights reserved. 
*  Conditions of Use:
*  For free use in commercial and non-commercial software but only
*  to communicate with Rose+Herleth GbR EZcontrol devices.
*  Use in firmware of third-party hardware only with written approval
*  of Rose+Herleth GbR.

structure definitions used:
 
struct config_pakets {
  uint16_t teletype;
  uint16_t type;  // Aktor, Sensor, Script
  uint16_t n; // Speicherplatznr.
  char descr[32];
  uint16_t reserved1[7];
  uint16_t system;
  uint16_t hc;
  uint16_t hc2;
  uint16_t address;
  int16_t value1;
  int16_t value2;
  int16_t value3;
  int16_t value4; // zustand des aktors
  float   fvalue1;
  float   fvalue2;
  float   fvalue3;
  float   fvalue4;
  uint16_t astype; // art des sensors/aktors
  uint16_t status;
  uint16_t reserved2[3];
  uint16_t reserved3[129];
};

  typedef struct
  {
    u16_t crc;
    u16_t type;
    u16_t errortype;
  } frame_error;

  typedef struct
  {
    u16_t crc;
    u16_t type;
    u16_t switchno;
    u16_t value;
  } frame_use_preset;
      
 */



function chksum($data)
{ 
	$sum = 0;
	
  foreach ($data as $d) {
    $sum += $d;
    if($sum < $d) {
      $sum++;
    }
  }
  return $sum;
}
function print_packet($text,$len) {
	$tbuffer="";
	for($i=0;$i<$len;$i++) {
		$tbuffer.=" ".sprintf("%02x",ord($text[$i]));
	}
	return $tbuffer;
}
 

 
function set_status($host,$device,$status){

	$value=$status?255:0; //on/off translate to 0/255 
	
	//defines
	$error_format="v3val";//(crc),type,errortype
 	$preset_format="vvvv";//(crc),type,switch-1,value(0=aus oder 255=ein)
 	$preset=0xab01;
 	$port=7042;
 	$timeout=3;
 	$buffersize=1500;
 	
 	//prepare buffer
 	$buffer=str_pad ('', $buffersize,chr(0));
 	
 	// create the socket 
	$socket = socket_create(AF_INET, SOCK_DGRAM,SOL_UDP);
   // set socket receive timeout to $timeout seconds
	socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => $timeout, "usec" => 0));
	
	//prepare packet structure
	$frame[0]=$preset;
	$frame[1]=$device-1;
	$frame[2]=$value;
	$crc=chksum($frame);
	$packet=pack($preset_format,$crc,$frame[0],$frame[1],$frame[2]);
	$len=strlen($packet);
	$x=print_packet($packet,$len);
	//send the packet without connection
	socket_sendto($socket,$packet,$len,0,$host,$port);
	
	//prepare reading answer
	$read=array($socket);
	$i=0;
	do {
    	$i++;
    	//send the packet without connection
		$r=socket_sendto($socket,$packet,$len,0,$host,$port);
		if($r===false) {
      		printf("sendto error
");
      		socket_close($socket);
      		exit;
    	}
    	$r=socket_select($read, $write = NULL, $except = NULL, 0);
  	} while(($i<4)&&($r===false));
  	if($i<4) {	
		// get the UDPdata with the sender's IP/port
		$len = socket_recvfrom($socket, $buffer, $buffersize, 0,$host, $port);
		if($len<0) {
      		printf("recvfrom error
");
      		socket_close($socket);
      		exit;
    	} else {
    		//unpack packet structur frame_error
			$y= print_packet($buffer,strlen($buffer));
			$frame=unpack($error_format,$buffer);
			$crc=$frame['val1'];
			array_shift($frame);
			$type=$frame['val2'];
			$errortype=$frame['val3'];
			//echo "Send:$x
";
			//echo "Receive:$y
";
			if ( ($crc==chksum($frame)) && ($errortype==0)) {
				echo "Ezcontrol accept Command!
";
				}else {
					echo "Command or checksum error!
";
			}		
    	}
	} else {
  		printf("No answer, max tries exeeded...
");
    	socket_close($socket);
     	exit;
  	}
	socket_close($socket);
}

function get_status($host,$device) {
 	//defines
	$GET_PORT=7044;
 	$GET_KEY=0x6711;
 	$GET_SENSOR=0x1;
 	$GET_ACTOR=0x2;
 	$timeout=3;
	$buffersize=1500;
	
	//prepare packet structure config_pakets
 	$buffer=str_pad ('', $buffersize,chr(0));
	$size=352; //packet size structure config_pakets
	$tt=$GET_KEY;
	$type=$GET_ACTOR;
	$header=pack("vvv",$GET_KEY,$GET_ACTOR,$device-1);
	$packet=str_pad($header,$size-6,chr(0)).pack("vvv",0xffff,0,0);
	//echo "Send2:".print_packet($packet,$size)."
";
	
	 // create the socket
	$socket = socket_create(AF_INET, SOCK_DGRAM,SOL_UDP);   
   // set socket receive timeout to 3 second */
	socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => $timeout, "usec" => 0));
	//prepare reading answer
	$read=array($socket); 
	//4 trys to send and ask for answer packet
	$i=0;
	do {
    	$i++;
    	$r=socket_sendto($socket,$packet,$size,0,$host,$GET_PORT);
    	if($r===false) {
      		printf("sendto error
");
      		socket_close($socket);
      		exit;
    	}
    	$r=socket_select($read, $write = NULL, $except = NULL, 0);
  	} while(($i<4)&&($r===false));

  	if($i<4) {
  		//answer packet avaiable, read it
    	$len=socket_recvfrom($socket, $buffer, $buffersize, 0,$host,$GET_PORT);
    	if($len<0) {
      		printf("recvfrom error
");
      		socket_close($socket);
      		exit;
    	} else {
    		//packet received, now decoding structure config_packets
    		//echo "rec2:".print_packet($buffer,$size)."
";
      		$frame=unpack("v3sys/a32char/v15val",substr($buffer,0,68));
      		$desc=$frame['char'];
      		$system=$frame['val8'];
      		$hc1=$frame['val9'];
      		$hc2=$frame['val10'];
      		$addr=$frame['val11'];
      		$value1=$frame['val12'];
      		$value4=$frame['val15'];
      		$extra=unpack("f4fval/v2val",substr($buffer,68,20));
      		
      		//print it
      		printf("Answer: TeleType %d, Type %d, Speicher %d
", $frame['sys1'],$frame['sys2'],$frame['sys3']);
      		printf("Description: %s System %d, hc1 %d, hc2 %d, adr %d, Status %d
", $desc, $system, $hc1, $hc2, $addr, $value4);   		
	  		printf("fvalue1-4: %f, %f, %f, %f   astype %d, Status %d
", $extra['fval1'],$extra['fval2'],$extra['fval3'],$extra['fval4'],$extra['val1'],$extra['val2']);
    	}
  	} else {
  		printf("No answer, max tries exeeded...
");
    	socket_close($socket);
     	exit;
  	}
  	socket_close($socket);
}

//main program (demo)
 $host="ezcontrol"; //or ip-address
 $device=7; //preset device number
 $value=false; //on/off
 
 set_status($host,$device,$value);
 sleep(2);
 get_status($host,$device);
 
?>