<?php
define("WNMP_PATH", realpath(dirname(__FILE__) . '/../../../../../'));

$str = $argv[1];

$arrData = array();
$arrTmp = explode(',', $str);
for ($i = 0; $i < sizeof($arrTmp); $i = $i + 2) {
	$arrData[$arrTmp[$i]] = $arrTmp[$i + 1];
}

// memcached
$mip = $arrData['mip'];
$mport = $arrData['mport'];
$mexpire = $arrData['mexpire'];

// 日志路径
$log_part = $arrData['log_part'];

// 版本号
$v = $arrData['v'];

$memcache = new Memcache();
$memcache->connect($mip, $mport);

setLog('start:' . $arrData['id']);

declare(ticks = 1);
$is_end = false;

function catch_error()
{
	global $is_end;
	$time = date('Y-m-d H:i:s');
	$error = error_get_last();
	$msg = "$time [error]";
	if ($is_end) {
		$msg .= "is_end[yes]";
	} else {
		$msg .= "is_end[no]";
	}
	if ($error) {
		$msg .= var_export($error, 1);
	}
	setLog($msg);
}
register_shutdown_function("catch_error");

function sig_handler($signo)
{
	$time = date('Y-m-d H:i:s');
	if ($signo == 14) {
		// 忽略alarm信号
		setLog($time . " ignore alarm signo[{$signo}]");
	} else {
		setLog($time . " exit  signo[{$signo}]");
		exit("");
	}
}
/*
 * pcntl_signal(SIGTERM, "sig_handler");
 * pcntl_signal(SIGHUP, "sig_handler");
 * pcntl_signal(SIGINT, "sig_handler");
 * pcntl_signal(SIGQUIT, "sig_handler");
 * pcntl_signal(SIGILL, "sig_handler");
 * pcntl_signal(SIGPIPE, "sig_handler");
 * pcntl_signal(SIGALRM, "sig_handler");
 */

$arrTmpInfo = array(
	'state' => '1',
	'pid' => getmypid()
);
$arrEqControl = array();
$interval = 900;
$controlInterval = 0;

while (1) {
	$memcache->set($v . "LINKAGE-INFO-" . $arrData['id'], $arrTmpInfo, 0, $mexpire);
	
	$keyName = $v . "LINKAGE";
	$arr = $memcache->get($keyName) === false ? array() : $memcache->get($keyName);
	
	foreach ($arr as $key => $value) {
		if ($value['ID'] == $arrData['id']) {
			// 联动
			switch ($value['type']) {
				case 0:
					// 温度联动(1792)
					linkageTem($arrData['id'], $value);
					break;
				case 1:
					// 湿度联动(5000)
					linkageHum($arrData['id'], $value);
					break;
				default:
			}
			break;
		}
	}
	
	sleep(5);
}

setLog('end:' . $arrData['id']);

/**
 * 检查控制(手动自动)
 *
 * @return boolean
 */
function checkControl($eq_sn, $eq_no)
{
	global $memcache;
	global $v;
	
	$bool = true;
	
	// 获取参数设置
	$keyName = $v . "PARAMETERS";
	$info = $memcache->get($keyName);
	if ($info === false) {
		return false;
	}
	
	$keyName = $v . "EQUIPMENTS";
	$arrMemcacheEquipments = $memcache->get($keyName) === false ? array() : $memcache->get($keyName);
	
	foreach ($arrMemcacheEquipments as $key => $value) {
		if ($value['eq_sn'] == $eq_sn && $value['eq_no'] == $eq_no) {
			$arrItem = explode("\n", $value['control_opt']);
			foreach ($arrItem as $k => $val) {
				if (strpos($val, 'sctrl') !== false) {
					$pname = "sctrl_" . $eq_sn . "_" . $eq_no;
					if (empty($info[$pname])) {
						$bool = false;
						break 2;
					}
				}
			}
		}
	}
	
	return $bool;
}

// 温度联动(1792)
function linkageTem($id, $arr)
{
	global $memcache;
	global $mexpire;
	global $arrTmpInfo;
	global $v;
	global $arrEqControl;
	global $interval;
	global $controlInterval;
	$b = false;
	
	$arrData = json_decode($arr['data'], true);
	
	// 获取平均温度值
	$avg = "0";
	$num = "0";
	$arrTmpSn = explode(',', $arr['eq_sn_m']);
	$arrTmpNo = explode(',', $arr['eq_no_m']);
	foreach ($arrTmpSn as $key => $value) {
		$keyName = $v . "EQUIP-LATEST-" . $arrTmpSn[$key] . "-" . $arrTmpNo[$key];
		$current_value = !isset($memcache->get($keyName)['Tem']) ? null : $memcache->get($keyName)['Tem'];
		if ($current_value === null) {
			setLog("error($id):获取温度失败,sn($arrTmpSn[$key]),no($arrTmpNo[$key])");
			continue;
		}
		$avg += $current_value;
		$num ++;
	}
	$avg = empty($num) ? $avg : $avg / $num;
	
	// 检查获取温度设备数量
	if (empty($num)) {
		setLog("error($id):获取平均温度失败");
		return false;
	}
	
	$keyName = $v . "EQUIPMENTS";
	$arrMemcacheEquipments = $memcache->get($keyName) === false ? array() : $memcache->get($keyName);
	
	$arrEqControl = array();
	$arrTmpSn = explode(',', $arr['eq_sn_l']);
	$arrTmpNo = explode(',', $arr['eq_no_l']);
	// 获取联动设备信息
	foreach ($arrTmpSn as $key => $value) {
		foreach ($arrMemcacheEquipments as $k => $val) {
			if ($val['eq_sn'] == $arrTmpSn[$key] && $val['eq_no'] == $arrTmpNo[$key]) {
				$properties = json_decode($val['properties'], true);
				$arrEqControl[] = array(
					'eq_sn' => $arrTmpSn[$key],
					'eq_no' => $arrTmpNo[$key],
					'properties' => $properties
				);
			}
		}
	}
	
	if (isset($arrData[0]) && $controlInterval < time()) {
		if (checkAlertRules($avg, $arrData[0]['vtype'], $arrData[0]['min_value'], $arrData[0]['max_value'], $arrData[0]['xor_value'])) {
			// 进行联动操作
			foreach ($arrEqControl as $key => $value) {
				$tmp = sendControl_1792($id, $value['eq_sn'], $value['eq_no'], $arrData[0]['control'], $value['properties']);
				if (! $tmp) {
					setLog("error($id):控制开启失败,sn(" . $value['eq_sn'] . "),no(" . $value['eq_no'] . ")");
				} else {
					$b = true;
				}
			}
		}
	}
	
	if (isset($arrData[1]) && $controlInterval < time()) {
		// 关闭操作
		if (checkAlertRules($avg, $arrData[1]['vtype'], $arrData[1]['min_value'], $arrData[1]['max_value'], $arrData[1]['xor_value'])) {
			// 进行联动操作
			foreach ($arrEqControl as $key => $value) {
				$tmp = sendControl_1792($id, $value['eq_sn'], $value['eq_no'], 0, $value['properties']);
				if (! $tmp) {
					setLog("error($id):控制关闭失败,sn(" . $value['eq_sn'] . "),no(" . $value['eq_no'] . ")");
				} else {
					$b = true;
				}
			}
		}
	}
	
	if ($b) {
		$controlInterval = time() + $interval;
		$b = false;
	}
}

// 湿度联动(5000)
function linkageHum($id, $arr)
{
	global $memcache;
	global $mexpire;
	global $arrTmpInfo;
	global $v;
	global $arrEqControl;
	global $interval;
	global $controlInterval;
	$b = false;
	
	$arrData = json_decode($arr['data'], true);
	
	// 获取平均湿度值
	$avg = "0";
	$num = "0";
	$arrTmpSn = explode(',', $arr['eq_sn_m']);
	$arrTmpNo = explode(',', $arr['eq_no_m']);
	foreach ($arrTmpSn as $key => $value) {
		$keyName = $v . "EQUIP-LATEST-" . $arrTmpSn[$key] . "-" . $arrTmpNo[$key];
		$current_value = !isset($memcache->get($keyName)['Hum']) ? null : $memcache->get($keyName)['Hum'];
		if ($current_value === null) {
			setLog("error($id):获取湿度失败,sn($arrTmpSn[$key]),no($arrTmpNo[$key])");
			continue;
		}
		$avg += $current_value;
		$num ++;
	}
	$avg = empty($num) ? $avg : $avg / $num;
	
	// 检查获取湿度设备数量
	if (empty($num)) {
		setLog("error($id):获取平均湿度失败");
		return false;
	}
	
	$keyName = $v . "EQUIPMENTS";
	$arrMemcacheEquipments = $memcache->get($keyName) === false ? array() : $memcache->get($keyName);
	
	$arrEqControl = array();
	$arrTmpSn = explode(',', $arr['eq_sn_l']);
	$arrTmpNo = explode(',', $arr['eq_no_l']);
	// 获取联动设备信息
	foreach ($arrTmpSn as $key => $value) {
		foreach ($arrMemcacheEquipments as $k => $val) {
			if ($val['eq_sn'] == $arrTmpSn[$key] && $val['eq_no'] == $arrTmpNo[$key]) {
				$properties = json_decode($val['properties'], true);
				$arrEqControl[] = array(
					'eq_sn' => $arrTmpSn[$key],
					'eq_no' => $arrTmpNo[$key],
					'properties' => $properties
				);
			}
		}
	}
	
	if (isset($arrData[0]) && $controlInterval < time()) {
		if (checkAlertRules($avg, $arrData[0]['vtype'], $arrData[0]['min_value'], $arrData[0]['max_value'], $arrData[0]['xor_value'])) {
			// 进行联动操作
			foreach ($arrEqControl as $key => $value) {
				$tmp = sendControl_1792($id, $value['eq_sn'], $value['eq_no'], $arrData[0]['control'], $value['properties']);
				if (! $tmp) {
					setLog("error($id):控制开启失败,sn(" . $value['eq_sn'] . "),no(" . $value['eq_no'] . ")");
				} else {
					$b = true;
				}
			}
		}
	}
	
	if (isset($arrData[1]) && $controlInterval < time()) {
		// 关闭操作
		if (checkAlertRules($avg, $arrData[1]['vtype'], $arrData[1]['min_value'], $arrData[1]['max_value'], $arrData[1]['xor_value'])) {
			// 进行联动操作
			foreach ($arrEqControl as $key => $value) {
				$tmp = sendControl_5000($id, $value['eq_sn'], $value['eq_no'], 0, $value['properties']);
				if (! $tmp) {
					setLog("error($id):控制关闭失败,sn(" . $value['eq_sn'] . "),no(" . $value['eq_no'] . ")");
				} else {
					$b = true;
				}
			}
		}
	}
	
	if ($b) {
		$controlInterval = time() + $interval;
		$b = false;
	}
}

/**
 * 检查报警规则
 *
 * @param string $value
 *        	当前值
 * @param string $vtype
 *        	检查类型
 * @param string $min_value
 *        	最小值
 * @param string $max_value
 *        	最大值
 * @param string $xor_value
 *        	等于值
 * @return boolean
 */
function checkAlertRules($value, $vtype, $min_value, $max_value, $xor_value, &$iDescribe = 0, &$threshold = '')
{
	switch ($vtype) {
		case '0':
			// 范围内
			$threshold = "$min_value ~ $max_value";
			if ($min_value <= $value and $value <= $max_value) {
				return true;
			} else {
				$iDescribe = $value < $min_value ? 0 : 1;
				return false;
			}
			break;
		case '1':
			// 范围外
			$threshold = "~ $min_value || $max_value ~";
			if ($value < $min_value or $max_value < $value) {
				return true;
			} else {
				return false;
			}
			break;
		case '2':
			// 小于小值
			$threshold = "~ $min_value";
			if ($value < $min_value) {
				return true;
			} else {
				return false;
			}
			break;
		case '3':
			// 大于大值
			$threshold = "$max_value ~";
			if ($max_value < $value) {
				return true;
			} else {
				return false;
			}
			break;
		case '4':
			// 通路检测
			$threshold = "$xor_value";
			if ($xor_value == $value) {
				return true;
			} else {
				return false;
			}
			break;
		default:
	}
	
	return true;
}

/**
 * 发送控制命令-4944
 *
 * @return void
 *
 */
function sendControl_4944($id, $sn, $no, $cmdid, $arrProperties)
{
	if (empty($arrProperties)) {
		setLog("4944-error($id):获取联动设备数据失败");
		return false;
	}
	
	$cip = $arrProperties['cip'];
	$sid = $no;
	$url = "http://$cip/action/doctrl";
	
	// 制冷开机、制热开机、关机
	$data = array(
		'op' => ($cmdid & 0xffff),
		'value' => ($sid << 16) | (0 & 0xFFFF)
	);
	
	setLog("4944-send($id):" . $url);
	setLog("4944-data($id):" . json_encode($data, JSON_UNESCAPED_UNICODE));
	$result = curl_request($url, $data);
	setLog("4944-back($id):" . $result);
	
	$arrTmp = json_decode($result, true);
	if (! empty($result) and ($result == 'ok' || (isset($arrTmp['op']) && $arrTmp['op'] == 'ok'))) {
		return true;
	}
	
	return false;
}

/**
 * 发送控制命令-5000
 *
 * @return void
 *
 */
function sendControl_5000($id, $sn, $no, $cmdid, $arrProperties)
{
	if (empty($arrProperties)) {
		setLog("5000-error($id):获取联动设备数据失败");
		return false;
	}
	
	$cip = $arrProperties['cip'];
	$sid = $no;
	$url = "http://$cip/action/doctrl";
	
	// 制冷开机、制热开机、关机
	$ival = $cmdid == 1 ? 16 : 128;
	$data = array(
		'op' => (6 << 16) | (20 & 0xFFFF),
		'value' => ($sid << 16) | ($ival & 0xFFFF)
	);
	
	setLog("5000-send($id):" . $url);
	setLog("5000-data($id):" . json_encode($data, JSON_UNESCAPED_UNICODE));
	$result = curl_request($url, $data);
	setLog("5000-back($id):" . $result);
	
	$arrTmp = json_decode($result, true);
	if (! empty($result) and ($result == 'ok' || (isset($arrTmp['op']) && $arrTmp['op'] == 'ok'))) {
		return true;
	}
	
	return false;
}

/**
 * 发送控制命令-1792
 *
 * @return void
 *
 */
function sendControl_1792($id, $sn, $no, $cmdid, $arrProperties)
{
	if (empty($arrProperties)) {
		setLog("1792-error($id):获取联动设备数据失败");
		return false;
	}
	
	$mode = '';
	$ext3 = '';
	switch ($cmdid) {
		case '0':
			// 关机
			$mode = '1';
			$ext3 = '0';
			break;
		case '3':
			// 制冷开机
			$mode = '1';
			$ext3 = '1';
			break;
		case '4':
			// 制热开机
			$mode = '2';
			$ext3 = '1';
			break;
		default:
	}
	
	$cip = $arrProperties['cip'];
	$sid = $no;
	$url = "http://$cip/action/aircdas";
	
	$data = array(
		'op' => '1000',
		'value' => (($sid << 16) | 42),
		'ext' => '1',
		'ext2' => $mode,
		'ext3' => $ext3,
		'name' => ''
	);
	
	setLog("1792-send($id):" . $url);
	setLog("1792-data($id):" . json_encode($data, JSON_UNESCAPED_UNICODE));
	$result = curl_request($url, $data);
	setLog("1792-back($id):" . $result);
	
	$arrTmp = json_decode($result, true);
	if (! empty($result) and ($result == 'ok' || (isset($arrTmp['op']) && $arrTmp['op'] == 'ok'))) {
		return true;
	}
	
	return false;
}

/**
 * 通过php的curl库获取ajax的返回值
 *
 * @param $url 请求地址        	
 * @param $post post数据(不填则为GET)        	
 * @param $cookie 提交的$cookies        	
 * @param $returnCookie 是否返回$cookies        	
 * @return true/false
 *
 */
function curl_request($url, $post = '', $cookie = '', $returnCookie = 0, $proxy = '')
{
	$url = empty($url) ? $this->url : $url;
	
	$curl = curl_init();
	if ($proxy) {
		curl_setopt($curl, CURLOPT_PROXY, $proxy);
	}
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)');
	curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
	curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
	// ******************取消ssl双向认证****************//
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
	curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
	// *************************************************//
	curl_setopt($curl, CURLOPT_REFERER, "http://www.vencs.com/");
	if ($post) {
		curl_setopt($curl, CURLOPT_POST, 1);
		curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post));
	}
	if ($cookie) {
		curl_setopt($curl, CURLOPT_COOKIE, $cookie);
	}
	curl_setopt($curl, CURLOPT_HEADER, $returnCookie);
	curl_setopt($curl, CURLOPT_TIMEOUT, 10);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
	$data = curl_exec($curl);
	if (curl_errno($curl)) {
		return curl_error($curl);
	}
	curl_close($curl);
	if ($returnCookie) {
		list ($header, $body) = explode("\r\n\r\n", $data, 2);
		preg_match_all("/Set\-Cookie:([^;]*);/", $header, $matches);
		$info['cookie'] = substr($matches[1][0], 1);
		$info['content'] = $body;
		return $info;
	} else {
		return $data;
	}
}

/**
 * 记录日志
 *
 * @param string $str
 *        	内容
 * @param string $filename
 *        	可选，文件名，默认'Linkage'
 */
function setLog($str, $filename = 'Linkage')
{
	global $log_part;
	
	file_put_contents($log_part . $filename . "_" . date('Y-m-d') . ".log", '[' . date('Y-m-d H:i:s') . ']' . $str . PHP_EOL, FILE_APPEND);
}