git 6 роки тому
батько
коміт
6fa2f4afad

+ 2 - 0
Home/Common/common.php

@@ -0,0 +1,2 @@
+<?php
+require_once(COMMON_PATH . 'func.php');

+ 611 - 0
Home/Common/func.php

@@ -0,0 +1,611 @@
+<?php
+
+ 
+	function log_debug( $msg ){
+		if (!APP_DEBUG) 
+			return;
+		$logger = \Jiaruan\FileLogger::getInstance(SOLUTION_LOG_PATH . '/zndp/');
+		$logger->log('',\Jiaruan\FileLogger::DEBUG,$msg);
+		
+	}
+	
+ 
+	function log_error( $msg ){
+		$logger = \Jiaruan\FileLogger::getInstance(SOLUTION_LOG_PATH . '/zndp/');
+		$logger->log('',\Jiaruan\FileLogger::ERROR,$msg);
+	}
+	
+ 
+	function log_info( $msg ){
+		if (!APP_DEBUG) 
+			return;
+		$logger = \Jiaruan\FileLogger::getInstance(SOLUTION_LOG_PATH . '/zndp/');
+		$logger->log('',\Jiaruan\FileLogger::INFO,$msg);
+	}
+	
+ 
+	function saveDeviceInfo_old( $imei, $versionname, $addr, $iccid = '', $cellphone = '' ){
+		$cond = array('DeviceImei'=>$imei);
+		$is_exists = MM('dpsb_device')->where($cond)->getField('ID');
+		if($is_exists){
+			$where = array('ID'=>$is_exists);
+			$data = array(
+				'VersionName'=>$versionname,
+				'DeviceAddr' => $addr,
+				'IccId'=>$iccid,
+				'CellPhone'=>$cellphone,
+			);
+			$res = MM('dpsb_device')->createSave($where,$data);
+			if(!$res)
+				json_fail('设备版本号添加到设备表失败!');
+			return $is_exists;
+		}else{
+			$data = array(
+				'DeviceImei'=>$imei,
+				'DeviceAddr' => $addr,
+				'IccId'=>$iccid,
+				'CellPhone'=>$cellphone,
+				'AddTime'=>date("Y-m-d H:i:s"),
+				'VersionName'=>$versionname
+			);
+			$id = MM('dpsb_device')->createAdd($data);
+			if(!$id)
+				json_fail('设备IMEI添加到设备表失败!');
+			return $id;	
+		}
+	}
+	
+ 
+	function saveChannel( $device_id, $data ){
+		$model = MM('dpsb_channel');
+		$where = array('DeviceId'=>$device_id);
+		// 获取该设备下目前已有的通道
+		$addr = MM('dpsb_device')->where(array('ID'=>$device_id))->getField('DeviceAddr');
+		$channel_list = $model->where($where)->field('ChNumber')->select();
+		$channel_arr = array();
+		if($channel_list){
+			foreach($channel_list as $channel){
+				array_push($channel_arr,$channel['ChNumber']);
+			}
+		}
+		//对象转数组
+		$data = json_decode(json_encode($data),TRUE);
+		// 获取通道名称
+		$display_name = new \Zndp\Device\ChannelType;
+		foreach($data as $v){
+			if( in_array($v['Column'],$channel_arr) ){
+				$where['ChNumber'] = $v['Column'];
+				$saveData = array(
+					'ChGroup'=>$v['Group'],
+					'ChType'=>$v['Type'],
+					'DisplayName'=>$display_name->getDisplayName($v['Type'],$v['Group'],$v['Column']),
+				);
+				$result = $model->createSave($where,$saveData);
+				if(!$result){
+					return 'update channel fail';
+				}
+			}else{
+				$saveData = array(
+					'ChGroup'=>$v['Group'],
+					'ChNumber'=>$v['Column'],
+					'ChNumberText'=>'column_'.$v['Column'],
+					'DisplayName'=>$display_name->getDisplayName($v['Type'],$v['Group'],$v['Column']),
+					'DeviceId'=>$device_id,
+					'ChType'=>$v['Type'],
+				);
+				$result = $model->createAdd($saveData);
+				if(!$result){
+					return 'add channel fail';
+				}
+			}
+		}
+	}
+	
+ 
+	function saveToChannel( $device_id, $data, $gathertime ){
+		$cond = array('DeviceId'=>$device_id);
+		// 获取该设备下目前已有的通道
+		$channel_list = MM('dpsb_channel')->where($cond)->field('ChNumber')->select();
+		$channel_arr = array();
+		if($channel_list){
+			foreach($channel_list as $channel){
+				array_push($channel_arr,$channel['ChNumber']);
+			}
+		}
+		//var_dump($channel_arr);
+		//对象转数组	
+		$data = json_decode(json_encode($data),TRUE);
+		// 获取通道名称
+		$display_name = new \Zndp\Device\ChannelType;
+		foreach($data as $v){
+			if( in_array($v['column'],$channel_arr) ){
+				$where = array(
+					'DeviceId' => $device_id,
+					'ChNumber' => $v['column'],
+				);
+				//检测通道类型
+				$channeltype = MM('dpsb_channel')->where($where)->getField('ChType');
+				if($channeltype != $v['type']){
+					return 'type inconsistency';
+				}
+				if($v['type'] == \Zndp\Device\ChannelType::ILLINATIONUM){ //修改光照值
+					$v['value'] = round( $v['value']/1000,1 );
+				}
+				$saveData = array(
+					'ChValue'=>floatval($v['value']),
+					'GatherTime'=>$gathertime,
+				);
+				
+				$result = MM('dpsb_channel')->createSave($where,$saveData);
+				if(!$result){
+					return 'update channeldata fail';
+				}
+			}else{
+				return 'no channeldata updata';
+			}
+		}
+	}
+	
+ 
+	function saveToChannelData( $device_id, $data, $gathertime ){
+		//对象转数组
+		$data = json_decode(json_encode($data),TRUE);
+		// 获取通道名称
+		$display_name = new \Zndp\Device\ChannelType;
+		foreach($data as $v){
+			$device_data_id = MM('dpsj_device')->where(array('DeviceId'=>$device_id))->order('ID desc')->getField('ID');
+			$group = MM('dpsb_channel')->where(array('ChNumber'=>$v['column'],'DeviceId'=>$device_id))->getField('ChGroup');
+			if($v['type'] == \Zndp\Device\ChannelType::ILLINATIONUM){ //修改光照值
+				$v['value'] = round( $v['value']/1000,1 );
+			}
+			$addData = array(
+				'DeviceDataId'=>$device_data_id,
+				'ChNumber'=>$v['column'],
+				'DisplayName'=>$display_name->getDisplayName($v['type'],$group,$v['column']),
+				'DeviceId'=>$device_id,
+				'ChValue'=>floatval($v['value']),
+				'ChType'=>$v['type'],
+				'GatherTime'=>$gathertime,
+			);
+			$result = MM('dpsj_channel')->createAdd($addData);
+			if(!$result){
+				return 'add channeldata fail';
+			}
+		}
+	}
+	
+ 
+	function saveToDevice( $device_id, $dedata, $gathertime ){
+		$data = json_decode(json_encode($dedata),TRUE);
+		// 获取通道名称
+		$addData = array(
+			'ID'=>create_guid(),
+			'DeviceId'=>$device_id,
+			'GatherTime'=>$gathertime,
+			'Signal'=>$data['Signal'],
+			'PwrState'=>$data['PwrState']
+		);
+		if(is_numeric($data['Voltage'])){
+			$addData['Voltage'] = $data['Voltage'];
+		}
+		if(is_numeric($data['WorkTemp'])){
+			$addData['WorkTemp'] = $data['WorkTemp'];
+		}
+		$result = MM('dpsj_device')->createAdd($addData);
+		if(!$result){
+			return 'add devicedata fail';
+		}
+		$saveDate = array(
+			'GatherTime'=>$gathertime,
+			'OnlineTime'=>date('Y-m-d H:i:s'),
+			'Signal'=>$data['Signal'],
+			'PwrState'=>$data['PwrState']
+		);
+		if(is_numeric($data['Voltage'])){
+			$saveDate['Voltage'] = $data['Voltage'];
+		}
+		if(is_numeric($data['WorkTemp'])){
+			$saveDate['WorkTemp'] = $data['WorkTemp'];
+		}
+		$where = array(
+			'ID'=>$device_id,
+		);
+		$res = MM('dpsb_device')->createSave($where,$saveDate);
+		if(!$res){
+			return 'update onlinetime fail';
+		}
+		
+	}
+	
+ 
+	function isDeviceDataInvalid( $data ){
+		//对象转数组
+		$data_arr = json_decode(json_encode($data),TRUE);
+		foreach($data_arr as $channel){
+			
+			if( $channel['value'] == '-' ){
+				return true;
+			}
+			
+		}
+		return false;
+	}
+	
+ 
+	function send_nongke( $addr, $data, $gathertime ){
+		//对象转数组
+		$data = json_decode(json_encode($data),TRUE);
+		$value_list1 = array();
+		$value_list2 = array();
+		$value_list3 = array();
+		$value_list4 = array();
+		$array1 = array(2,3,4);
+		$array2 = array(7,8,9);
+		$array3 = array(12,13,14);
+		$array4 = array(17,18,19);
+		foreach($data as $v){
+			if(in_array($v['column'],$array1)){
+				if($v['type'] == \Zndp\Device\ChannelType::ILLINATIONUM){ //修改光照值
+					$v['value'] = round( $v['value']/1000,1 );
+					$value_list1['gz'] = $v['value'];
+				}
+				if($v['type'] == \Zndp\Device\ChannelType::TEMPERATURE){ 
+					$value_list1['wd'] = $v['value'];
+				}
+				if($v['type'] == \Zndp\Device\ChannelType::HUMIDITY){
+					$value_list1['sd'] = $v['value'];
+				}
+			}
+			if(in_array($v['column'],$array2)){
+				if($v['type'] == \Zndp\Device\ChannelType::ILLINATIONUM){ //修改光照值
+					$v['value'] = round( $v['value']/1000,1 );
+					$value_list2['gz'] = $v['value'];
+				}
+				if($v['type'] == \Zndp\Device\ChannelType::TEMPERATURE){ 
+					$value_list2['wd'] = $v['value'];
+				}
+				if($v['type'] == \Zndp\Device\ChannelType::HUMIDITY){
+					$value_list2['sd'] = $v['value'];
+				}
+			}
+			if(in_array($v['column'],$array3)){
+				if($v['type'] == \Zndp\Device\ChannelType::ILLINATIONUM){ //修改光照值
+					$v['value'] = round( $v['value']/1000,1 );
+					$value_list3['gz'] = $v['value'];
+				}
+				if($v['type'] == \Zndp\Device\ChannelType::TEMPERATURE){ 
+					$value_list3['wd'] = $v['value'];
+				}
+				if($v['type'] == \Zndp\Device\ChannelType::HUMIDITY){
+					$value_list3['sd'] = $v['value'];
+				}
+			}
+			if(in_array($v['column'],$array4)){
+				if($v['type'] == \Zndp\Device\ChannelType::ILLINATIONUM){ //修改光照值
+					$v['value'] = round( $v['value']/1000,1 );
+					$value_list4['gz'] = $v['value'];
+				}
+				if($v['type'] == \Zndp\Device\ChannelType::TEMPERATURE){ 
+					$value_list4['wd'] = $v['value'];
+				}
+				if($v['type'] == \Zndp\Device\ChannelType::HUMIDITY){
+					$value_list4['sd'] = $v['value'];
+				}
+			}
+		}
+		//传到农科院设备
+		$channel_data1 = array($value_list1['wd'],$value_list1['sd'],$value_list1['gz']);
+		$channel_data2 = array($value_list2['wd'],$value_list2['sd'],$value_list2['gz']);
+		$channel_data3 = array($value_list3['wd'],$value_list3['sd'],$value_list3['gz']);
+		$channel_data4 = array($value_list4['wd'],$value_list4['sd'],$value_list4['gz']);
+		$channel_list = array();
+		if($value_list1['wd']){
+			$channel_list1 = array('addr'=>"1",'value'=>$channel_data1);
+			array_push($channel_list,$channel_list1);
+		}
+		if($value_list2['wd']){
+			$channel_list2 = array('addr'=>2,'value'=>$channel_data2);
+			array_push($channel_list,$channel_list2);
+		}
+		if($value_list3['wd']){
+			$channel_list3 = array('addr'=>3,'value'=>$channel_data3);
+			array_push($channel_list,$channel_list3);
+		}
+		if($value_list4['wd']){
+			$channel_list4 = array('addr'=>4,'value'=>$channel_data4);
+			array_push($channel_list,$channel_list4);
+		}
+		$data = array(
+			"gatewayid" => $addr,
+			"data" => $channel_list,
+			"sessionkey" => 123456,
+		);
+		$dataurl = urlencode(json_encode($data));
+		//$url = "http://210.12.220.220:8888/dataswitch-inner-http/inner/send/gateway.html?req=".$dataurl;
+		$url = "http://218.22.201.174:8083/dataswitch-inner-http/inner/send/gateway.html?req=".$dataurl;
+		//$last_time = S('nongke_last_time');
+		$dpsb_device = MM('dpsb_device');
+		$where = array('DeviceAddr'=>$addr);
+		$dpsb_device_info = $dpsb_device->where($where)->find();
+		$send_time = $dpsb_device_info['NkSendTime'];
+		if( (strtotime($gathertime) - strtotime($send_time)) >= 600){
+			$res = curl_json_post($url,array());
+			//$where = array('DeviceAddr'=>$addr);
+			$nkdata = array('NkSengResult'=>$res['status'], 'NkMessage'=>$res['msg'], 'NkSendTime'=>$gathertime);
+			$nkres = $dpsb_device->createSave($where,$nkdata);
+			if(!$nkres){
+				log_debug('保存农科发送数据失败');
+			}
+			if($res['status']){
+				log_debug($res['msg']);
+				//S('nongke_last_time',strtotime($gathertime));
+			}else{
+				log_info($res['msg'].': '.json_encode($channel_list));	
+				//S('nongke_last_time',strtotime($gathertime));
+			}
+		}
+	}
+	
+ 
+	function send_single_nongke( $addr, $data, $gathertime ){
+		//对象转数组
+		$data = json_decode(json_encode($data),TRUE);
+		$value_list = array();
+		foreach($data as $v){
+			if($v['type'] == \Zndp\Device\ChannelType::ILLINATIONUM){ //修改光照值
+				$v['value'] = round( $v['value']/1000,1 );
+				$value_list['gz'] = $v['value'];
+			}
+			if($v['type'] == \Zndp\Device\ChannelType::TEMPERATURE){ 
+				$value_list['wd'] = $v['value'];
+			}
+			if($v['type'] == \Zndp\Device\ChannelType::HUMIDITY){
+				$value_list['sd'] = $v['value'];
+			}
+		}
+		//传到农科院设备
+		$channel_data = array($value_list['wd'],$value_list['sd'],$value_list['gz']);
+		$data = array(
+			"deviceid" => "617261",
+			"data" => $channel_data,
+			"sessionkey" => 123456,
+		);
+		$dataurl = urlencode(json_encode($data));
+		$url = "http://218.22.201.174:8083/dataswitch-inner-http/inner/send/single.html?req=".$dataurl;
+		/*$last_time = S('nongke_last_time');
+		if( strtotime($gathertime) - $last_time >= 600){
+			$res = curl_json_post($url,array());
+			S('nongke_last_time',strtotime($gathertime));
+			if(isset($res['success']) && !$res['success']){
+				log_error($res['message']);
+				return;
+			}
+			if($res['status']){
+				log_error($res['msg']);
+			}else{
+				log_info($res['msg'].': '.json_encode($channel_data));	
+			}
+		}*/
+		$last_time = S('nongke_last_time');
+		if( strtotime($gathertime) - $last_time >= 600){
+			$res = curl_json_post($url,array());
+			if($res['status']){
+				S('nongke_last_time',strtotime($gathertime));
+				log_debug($res['msg']);
+			}else{
+				S('nongke_last_time',strtotime($gathertime));
+				log_info($res['msg'].': '.json_encode($channel_data));	
+			}
+		}
+	}
+	
+ 
+	function saveChgroup( $device_id, $data ){
+		$chgroup = MM('dpsb_chgroup');
+		// 为了方便设备接入后可以直接绑定大棚,不用等所有通道组都上报数据,2019年3月12日15:36:57
+		for( $i=0; $i<=1; $i++ ){
+			$where = array( 'DeviceId'=> $device_id,'ChGroup' => $i );
+			$count = $chgroup->where($where)->count();
+			if($count > 0){ //通道组存在,跳过
+				continue;
+			}
+			//保存通道组信息
+			$save_data = array(
+					'ID' => create_guid(),
+					'DeviceId' => $device_id,
+					'ChGroup' => $i
+			);
+			$result = $chgroup->createAdd($save_data);
+			if( $result === false ){
+				return 'add channel group failed';
+			}
+		}
+		
+		
+		
+		/*
+		foreach($data as $ch){ //遍历通道数据,获取通道组信息
+			$where = array( 'DeviceId'=> $device_id,'ChGroup' => $ch->Group );
+			$count = $chgroup->where($where)->count();
+			if($count > 0){ //通道组存在,跳过
+				continue;
+			}
+			//保存通道组信息
+			$save_data = array(
+					'ID' => create_guid(),
+					'DeviceId' => $device_id,
+					'ChGroup' => $ch->Group
+			);
+			$result = $chgroup->createAdd($save_data);
+			if(!$result){
+				return 'add channel group failed';
+			}
+		}
+		*/
+	}
+	
+ 
+	function pushAlarmToRedis( $device_id, $data, $gathertime ){
+		$path = SOLUTION_LOG_PATH . 'push_alarm_to_redis.log';
+		if(!$device_id || !$gathertime || empty($data)){ //缺少参数或没数据
+			$msg = '['.date('Y-m-d H:i:s').'] DeviceId:'.$device_id.',GatherTime:'.$gathertime.',Data:'.$data .PHP_EOL;
+			file_put_contents($path,$msg,FILE_APPEND);
+		}
+		$redis_chgroup = Redis('dpxf_chgroup','hash');    // 查通道组
+		$redis_farmland_list = Redis("dpsb_farmland_list","hash"); // 查大棚id
+		$redis_alarm_set = Redis('dpyh_alarm_set','hash');  // 查告警设置
+		$redis_alarm_list = Redis('dpxf_alarm_list','list'); // 告警列表
+		$dpyh_farmland = MM('dpyh_farmland');
+		foreach($data as $ch){//遍历通道数据
+			$key = 'DeviceId-'.$device_id .'-ChNumber-'.$ch->column;
+			$chgroup = $redis_chgroup->get($key); //查出通道组
+			if($chgroup === false){ //不存在的
+				continue;
+			}
+			$key = 'DeviceId-'.$device_id .'-ChGroup-'.$chgroup;
+			$farmland_id = $redis_farmland_list->get($key);
+			if( !$farmland_id){//没有大棚id记录
+				continue;
+			}
+			// 获取告警设置信息
+			$key = 'FarmlandId-'.$farmland_id;
+			$alarm_data = $redis_alarm_set->get($key);
+			if(!$alarm_data){//没有设置信息
+				continue;
+			}
+			$alarm_data = json_decode($alarm_data,true);
+			if( $alarm_data['IsUseTempLimit'] == 0){ //没有启用告警
+				continue;
+			}
+			// 判断是否达到设定温度告警阈值
+			if( $ch->type == \Zndp\Device\ChannelType::TEMPERATURE ){ // 温度类传感器
+				$result = false;
+				$key = $alarm_data['FarmId'];
+				$val = pushTempAlarm($ch, $alarm_data, $dpyh_farmland, $farmland_id, $gathertime);
+				if($val['success']){ // 有值推送到redis
+					$list = array($key => $val);
+					$result = $redis_alarm_list->lpush($list);
+				}
+				if( !$result ){
+					$msg = '[failed]['.date('Y-m-d H:i:s').']Input to dpxf_alarm_list : DeviceId-'.$device_id .'-ChNumber-'. $ch->column .' => '. $val['message'] .PHP_EOL;
+					file_put_contents($path,$msg,FILE_APPEND);
+				}
+			}
+			
+		}
+		
+	}
+	
+ 
+	function addChgroupToRedis( $device_id, $data ){
+		$redis = Redis("dpxf_chgroup","hash");
+		foreach($data as $ch){
+			// 保存每个通道对应的通道组
+			$key = 'DeviceId-'.$device_id .'-ChNumber-'.$ch->Column;
+			$val = $ch->Group;
+			$hash = array($key => $val );
+			$result = $redis->add($hash);
+			if(!$result){
+				$path = SOLUTION_LOG_PATH . 'add_chgroup_to_redis.log';
+				$msg = '['.date('Y-m-d H:i:s').']DeviceId-'.$device_id .'-ChNumber-'.$ch->Column.'添加Redis表dpxf_chgroup失败'.PHP_EOL;
+				file_put_contents($path,$msg,FILE_APPEND);
+			}
+		}
+	}
+	
+ 
+	function pushTempAlarm( $ch, $alarm_data, $dpyh_farmland, $farmland_id, $gathertime ){
+		if(!$ch || !$alarm_data || !$dpyh_farmland || !$farmland_id || !$gathertime){
+			return array(
+						'success' => false,
+						'message' => '缺少参数',
+			);
+		}
+		if(!is_numeric($ch->value)){ //非数字
+			return array(
+						'success' => false,
+						'message' => "非数字值:".$ch->value,
+			);
+		}
+		if( $ch->value < $alarm_data['HighTempLimit'] && $ch->value > $alarm_data['LowTempLimit'] ){ // 判断是否恢复正常,状态 0
+			$where = array('ID'=>$farmland_id);
+			$alarm_state = $dpyh_farmland->where($where)->getField('AlarmState');
+			if( $alarm_state == 0 ){ //当前告警状态为0,表示之前未报警,跳过
+				return array(
+					'success' => false,
+					'message' => '温度正常',
+				);
+			}
+			$content = $alarm_data['FarmlandName'].'育苗大棚温度恢复正常,实际温度:'.$ch->value.'℃';
+			$val = array(
+				'alarm_state' => 0,
+				'content' => $content,
+				'farmland_id' => $farmland_id,
+				'gathertime' => $gathertime,
+			);
+		}
+		elseif(  $ch->value >= $alarm_data['MaxTempExceed'] || $ch->value <= $alarm_data['LowTempExceed'] ){ // 判断有没有超过极限温度,状态 2
+			$content = $alarm_data['FarmlandName'].'育苗大棚温度已达到极限阈值,实际温度:'.$ch->value .'℃,请立即前往排查。';
+			$val = array(
+				'alarm_state' => 2,
+				'content' => $content,
+				'farmland_id' => $farmland_id,
+				'gathertime' => $gathertime,
+			);
+		}
+		else{	// 超过上下限,状态 1
+			$content = $alarm_data['FarmlandName'].'育苗大棚温度异常,实际温度:'.$ch->value .'℃,请立即前往排查。';
+			$val = array(
+				'alarm_state' => 1,
+				'content' => $content,
+				'farmland_id' => $farmland_id,
+				'gathertime' => $gathertime,
+			);
+		}
+		return array(
+						'success' => true,
+						'message' => 'success',
+						'data' => $val
+			);
+	}
+	
+ 
+	function saveDeviceInfo( $proto ){
+		$cond = array('DeviceImei'=>$proto->imei);
+		$device_id = MM('dpsb_device')->where($cond)->getField('ID');
+		// 根据传过来的设备型号,到型号表里去查,有则添加 DeviceTypeId 
+		$cond = array('DeviceModel'=>$proto->model);
+		$type_id = ( MM('dpsb_type')->where($cond)->getField('ID') ) ? : '';
+		if($device_id){ // 已经保存过了,更新可能会变更的信息
+			$where = array('ID'=>$device_id);
+			$data = array(
+				'VersionName' => $proto->versionName,
+				'DeviceTypeId' => $type_id,
+				'DeviceAddr' => $proto->addr,
+				'IccId' => $proto->iccid,
+				'CellPhone' => $proto->cellphone,
+			);
+			$res = MM('dpsb_device')->createSave($where,$data);
+			if(!$res){
+				json_fail('设备版本号添加到设备表失败!');
+			}
+			return $device_id;
+		}else{ // 不存在,保存所有信息
+			$data = array(
+				'DeviceImei' => $proto->imei,
+				'DeviceAddr' => $proto->addr,
+				'DeviceTypeId' => $type_id,
+				'IccId' => $proto->iccid,
+				'CellPhone' => $proto->cellphone,
+				'AddTime' => date("Y-m-d H:i:s"),
+				'VersionName' => $proto->versionName,
+			);
+			$device_id = MM('dpsb_device')->createAdd($data);
+			if(!$device_id){
+				json_fail('设备IMEI添加到设备表失败!');
+			}
+			return $device_id;	
+		}
+	}
+	
+

+ 20 - 0
Home/Lib/Action/DpxfCronAction.class.php

@@ -0,0 +1,20 @@
+<?php
+
+
+
+class DpxfCronAction extends Action {
+			
+
+
+ 
+	public  function restart_workerman(  ){
+		if(PHP_SAPI != 'cli'){
+			exit('please use cli run');
+		}
+		$cwd = getcwd();
+		$cmd = 'cd ' .$cwd.' && php index.php start -d dpxf_index/index';
+		exec($cmd);
+	}
+	
+
+}

+ 351 - 0
Home/Lib/Action/DpxfIndex1Action.class.php

@@ -0,0 +1,351 @@
+<?php
+class DpxfIndex1Action extends \Jms\Network\WorkermanServerAction {
+	/*
+
+	*/
+	public function index(){
+		$this->start("jsontext",10240,1);
+	}
+	/*
+	参数说明:
+		connection: 
+		proto: 
+
+	*/
+	protected function onAppLogin($connection, $proto){
+		//检查imei地址
+		if(!$proto->imei){
+		    $this->respError($connection,'imei is empty ',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+		    return;
+		}
+		
+		$addr = MM('dpsb_device')->where(array('DeviceImei'=>$proto->imei))->getField('DeviceAddr');
+		if(!$addr){
+		    $this->respError($connection,'addr is empty ',$proto);
+		    return;
+		}
+		//通过登录验证,加入连接池
+		$connection->imei = $proto->imei;
+		$connection->addr = $addr;
+		$this->addToPool($addr,$connection);
+		$this->logDebug('login success. should put into connection pool. imei = ' . $proto->imei);
+		
+		// 将数据更新到数据表中
+		$device_id = saveDeviceInfo($proto->imei,$addr);
+		if(!$device_id){
+		    $this->respError($connection,'device_id is empty ',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+		    return;
+		}
+		if(!$proto->channel){
+		    $this->respError($connection,'channeldata is empty ',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+		    return;
+		}
+		$errmsg = saveChannel($device_id,$proto->channel);
+		if($errmsg){
+		    $this->respError($connection,$errmsg,$proto,\Zndp\Api\ResponseCode::DEVICE_LOST_CONNECTION);
+		    return;
+		}
+		$arr = array(
+		    'method' => $proto->method.'Resp',
+		    'Addr' => $addr
+		);
+		$connection->send($arr);
+	}
+	/*
+	参数说明:
+		connection: 
+		message: 
+		proto: 
+		data: 
+
+	*/
+	private function respError($connection, $message, $proto, $data){
+		//判断$proto是否为字符串
+		if(!is_string($proto)){
+			$protostr = json_encode($proto);
+		}else{
+			$protostr = $proto;
+		}
+		log_error($message.' proto = '.$protostr);
+		$array = array(
+			'success' => false,
+			'message' => $message,
+			'data' => $data,
+		);
+		//判断是否存在method
+		if($proto->method){
+			$array['method'] = $proto->method . 'Resp';
+		}
+		
+		$connection->send($array);
+		$connection->close();
+	}
+	/*
+	参数说明:
+		connection: 
+		proto: 
+
+	*/
+	protected function onApiSendControl($connection, $proto){
+		/*返回结果: 
+		  1.失败,手动控制命令发送失败,地址码未设置
+		  2.失败,手动控制命令发送失败,手动控制命令格式错误
+		  3.失败,手动控制命令发送失败,设备未在线
+		  4.失败,手动控制命令发送失败,可能设备掉线
+		  5.失败,手动控制命令发送成功,但是设备回应超时
+		  6.失败,手动控制命令发送成功,但是设备回应格式错误
+		  7.失败,手动控制命令发送成功,但是设备回应错误信息
+		  8.成功
+		*/
+		//检查addr
+		if(!$proto->Addr){
+			$this->respError($connection,'addr is empty ',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			return;
+		}
+		
+		//给控制app终端发送手动控制信号,并等待回应
+		$arr = array(
+			"method"=> $proto->method,
+			"Addr"=>$proto->Addr,
+			"channelNumber"=>$proto->channelNumber,
+			"status"=>$proto->status
+		);
+		$callback = function($errno,$resp) use ($connection){
+			if($errno == \Zndp\Api\ResponseCode::SEND_SUCCESS){
+				if(is_object($resp)){
+					$res = $connection->send($resp);
+					$connection->close();
+				}
+				else
+					$this->respError($connection,$errno,$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			}
+			else{
+				$this->respError($connection,$errno,$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			}
+		};
+		$this->sendWait($proto->Addr,$arr,'appSendControlResp',$callback,3);
+	}
+	/*
+	参数说明:
+		connection: 
+		proto: 
+
+	*/
+	protected function onApiModifyAutoControlInfo($connection, $proto){
+		//检查addr是否为空
+		if(!$proto->Addr){
+			$this->respError($connection,'addr is empty',$proto,\Zndp\Api\ResponseCode::NOT_AUTH_DEVICE);
+			return;
+		}
+		//检查channelNumber是否为空
+		if(!$proto->channelNumber){
+			$this->respError($connection,'channelNumber empty',$proto,\Zndp\Api\ResponseCode::DEVICE_LOST_CONNECTION);
+			return;
+		}
+		//检查channelNumber是否存在
+		$device_id = MM('dpsb_device')->where(array('DeviceAddr'=>$proto->Addr))->getField('ID');
+		$cond = array(
+			'DeviceId'=>$device_id,
+			'ChNumber'=>$proto->channelNumber,
+		);
+		$result = MM('dpsb_channel')->where($cond)->find();
+		if(!$result){
+			$this->respError($connection,'channelNumber inexistence',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			return;
+		}
+		
+		//给app转发自动控制命令
+		$arr = array(
+			'method'=>$proto->method,
+			'Addr'=>$proto->Addr,
+			'channelNumber'=>$proto->channelNumber,
+			'man'=>$proto->man,
+			'refChannel'=>$proto->refChannel,
+			'TimeEn'=>$proto->TimeEn,
+			'UpperLimit_Value'=>$proto->UpperLimit_Value,
+			'UpperLimit_State'=>$proto->UpperLimit_State,
+			'LowerLimit_Value'=>$proto->LowerLimit_Value,
+			'LowerLimit_State'=>$proto->LowerLimit_State,
+			'OnTime1'=>$proto->OnTime1,
+			'OffTime1'=>$proto->OffTime1,
+			'OnTime2'=>$proto->OnTime2,
+			'OffTime2'=>$proto->OffTime2,
+			'OnTime3'=>$proto->OnTime3,
+			'OffTime3'=>$proto->OffTime3,
+			'OnTime4'=>$proto->OnTime4,
+			'OffTime4'=>$proto->OffTime4,
+			'OnTime5'=>$proto->OnTime5,
+			'OffTime5'=>$proto->OffTime5,
+		);
+		$callback = function($errno,$resp) use ($connection){
+			if($errno == \Zndp\Api\ResponseCode::SEND_SUCCESS){
+				if(is_object($resp)){
+					$connection->send($resp);
+					$this->saveModifyAutoData($device_id,$proto,\Zndp\Api\ResponseCode::SEND_SUCCESS);
+					$connection->close();
+				}
+				else{
+					$this->respError($connection,$errno,$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+					$this->saveModifyAutoData($device_id,$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);		
+				}
+			}
+			else{
+				$this->respError($connection,$errno,$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+				$this->saveModifyAutoData($device_id,$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			}
+		};
+		$this->sendWait($proto->Addr,$arr,'AppModifyAutoControlInfoResp',$callback,3);
+		
+		
+	}
+	/*
+	参数说明:
+		device_id: 
+		proto: 
+		connection: 
+		msg: 
+
+	*/
+	private function saveModifyAutoData($device_id, $proto, $connection, $msg){
+		$where = array(
+			'DeviceId'=> $device_id,
+			'Channel'=>$proto->channelNumber,
+		);
+		$res = MM('dpsb_policy')->where($where)->find();
+		if($res){
+			$saveData = array(
+				'Man'=> $proto->man,
+				'RefChannel'=> $proto->refChannel,
+				'IsTime'=> $proto->TimeEn,
+				'UpperLimitValue'=> $proto->UpperLimit_Value,
+				'UpperLimitState'=> $proto->UpperLimit_State,
+				'LowerLimitValue'=> $proto->LowerLimit_Value,
+				'LowerLimitState'=> $proto->LowerLimit_State,
+				'OnTime1'=> $proto->OnTime1,
+				'OffTime1'=> $proto->OffTime1,
+				'OnTime2'=> $proto->OnTime2,
+				'OffTime2'=> $proto->OffTime2,
+				'OnTime3'=> $proto->OnTime3,
+				'OffTime3'=> $proto->OffTime3,
+				'OnTime4'=> $proto->OnTime4,
+				'OffTime4'=> $proto->OffTime4,
+				'OnTime5'=> $proto->OnTime5,
+				'OffTime5'=> $proto->OffTime5,
+				'SendTime'=> date('Y-m-d H:i:s'),
+				'SendResult'=> $msg
+			);
+			$result = MM('dpsb_policy')->createSave($where,$saveData);
+		}else{
+			$addData = array(
+				'DeviceId'=> $device_id,
+				'Channel'=>$proto->channelNumber,
+				'Man'=> $proto->man,
+				'RefChannel'=> $proto->refChannel,
+				'IsTime'=> $proto->TimeEn,
+				'UpperLimitValue'=> $proto->UpperLimit_Value,
+				'UpperLimitState'=> $proto->UpperLimit_State,
+				'LowerLimitValue'=> $proto->LowerLimit_Value,
+				'LowerLimitState'=> $proto->LowerLimit_State,
+				'OnTime1'=> $proto->OnTime1,
+				'OffTime1'=> $proto->OffTime1,
+				'OnTime2'=> $proto->OnTime2,
+				'OffTime2'=> $proto->OffTime2,
+				'OnTime3'=> $proto->OnTime3,
+				'OffTime3'=> $proto->OffTime3,
+				'OnTime4'=> $proto->OnTime4,
+				'OffTime4'=> $proto->OffTime4,
+				'OnTime5'=> $proto->OnTime5,
+				'OffTime5'=> $proto->OffTime5,
+				'SendTime'=> date('Y-m-d H:i:s'),
+				'SendResult'=> $msg
+			);
+			$result = MM('dpsb_policy')->createAdd($addData);
+		}
+		if(!$result){
+			$this->respError($connection,'channelNumber inexistence',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			return;
+		}
+	}
+	/*
+	参数说明:
+		connection: 
+		proto: 
+
+	*/
+	protected function onAppSendRealTimeDeviceData($connection, $proto){
+		//检查imei地址
+		if(!$proto->imei){
+			$this->respError($connection,'imei is empty ',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			return;
+		}
+		if(!$connection->addr){
+			$this->respError($connection,'addr is empty ',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			return;
+		}
+		
+		// 将数据更新到数据表中
+		$data = $proto->data;
+		$gathertime = date('Y-m-d H:i:s',$proto->gathertime);
+		$device_id = saveDeviceInfo($proto->imei,$connection->addr);
+		if(!$device_id){
+			$this->respError($connection,'device_id is empty ',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			return;
+		}
+		if(!$proto->data){
+			$this->respError($connection,'data is empty ',$proto,\Zndp\Api\ResponseCode::NO_DATA);
+			return;
+		}
+		if(!$proto->gathertime){
+			$this->respError($connection,'gathertime is empty ',$proto,\Zndp\Api\ResponseCode::NO_DATA);
+			return;
+		}
+		$errmsg1 = saveToDevice($device_id,$gathertime);
+		if($errmsg1){
+			$this->respError($connection,$errmsg1,$proto,\Zndp\Api\ResponseCode::DEVICE_OPRATE_DISALLOWED);
+			return;
+		}
+		$errmsg2 = saveToChannel($device_id,$data,$gathertime);
+		if($errmsg2){
+			$this->respError($connection,$errmsg2,$proto,\Zndp\Api\ResponseCode::DEVICE_OPRATE_DISALLOWED);
+			return;
+		}
+		$errmsg3 = saveToChannelData($device_id,$data,$gathertime);
+		if($errmsg3){
+			$this->respError($connection,$errmsg3,$proto,\Zndp\Api\ResponseCode::DEVICE_OPRATE_DISALLOWED);
+			return;
+		}
+		$arr = array(
+			'method' => $proto->method.'Resp',
+			"success"=>true,
+			"message"=>"ok",
+			"addtime"=>time(),
+		);
+		$connection->send($arr);
+	}
+	/*
+	参数说明:
+		connection: 
+		proto: 
+
+	*/
+	protected function onAppHeartbeat($connection, $proto){
+		//直接返回心跳
+		$arr = array(
+			'success'=>true
+		);
+		$connection->send($arr);
+	}
+	/*
+
+	*/
+	protected function onAppSendControlResp(){
+		
+	}
+	/*
+
+	*/
+	protected function onAppModifyAutoControlInfoResp(){
+		
+	}
+
+}

+ 627 - 0
Home/Lib/Action/DpxfIndexAction.class.php

@@ -0,0 +1,627 @@
+<?php
+
+
+
+class DpxfIndexAction extends \Jms\Network\WorkermanServerAction {
+			
+
+
+ 
+	public  function index(  ){
+		$this->start("jsontext",10240,1);
+	}
+	
+ 
+	protected  function onAppLogin( $connection, $proto ){
+		//检查imei地址
+		if(!$proto->imei){
+		    $this->respError($connection,'imei is empty ',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+		    return;
+		}
+		if( $proto->addr ){ //设备序列号在控制台操作添加,会直接上报,2019年3月14日09:29:57
+			$addr = $proto->addr;
+		}else{
+			$addr = MM('dpsb_device')->where(array('DeviceImei'=>$proto->imei))->getField('DeviceAddr');
+		}
+		if(!$addr){
+			$device_id = saveDeviceInfo($proto);
+		    $this->respError($connection,'addr is empty ',$proto);
+		    return;
+		}else{ //保存到设备表
+			$device_id = saveDeviceInfo($proto);
+		}
+		
+		//通过登录验证,加入连接池
+		$connection->imei = $proto->imei;
+		$connection->addr = $addr;
+		$this->addToPool($addr,$connection);
+		$this->logDebug('login success. should put into connection pool. imei = ' . $proto->imei);
+		
+		// 将数据更新到数据表中
+		//$device_id = saveDeviceInfo($proto->imei,$proto->versionName,$addr,$proto->iccid,$proto->cellphone);
+		if(!$device_id){
+		    $this->respError($connection,'device_id is empty ',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+		    return;
+		}
+		/*
+		if(!$proto->channel){
+		    $this->respError($connection,'channeldata is empty ',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+		    return;
+		}*/
+		$errmsg = saveChannel($device_id,$proto->channel);
+		if($errmsg){
+		    $this->respError($connection,$errmsg,$proto,\Zndp\Api\ResponseCode::DEVICE_LOST_CONNECTION);
+		    return;
+		}
+		// 新增:保存通道组信息 2019年1月8日11:46:49
+		$result = saveChgroup($device_id,$proto->channel);
+		if($result){
+			$this->respError($connection,$errmsg,$proto,\Zndp\Api\ResponseCode::DEVICE_LOST_CONNECTION);
+		   return;
+		}
+		// 以设备id-通道号为key,通道组号为值存入redis 2019年1月28日13:44:37
+		addChgroupToRedis($device_id,$proto->channel);
+		
+		$where = array('DeviceAddr'=>$addr);
+		$field = "Mobiles,ExceptContent,SmsInterval,HighTemp,IsUseHT,LowTemp,IsUseLT,SoundLightAlarmInterval,SoundLightDuration,SeveralExceptions,WorkUnitName";
+		$result = M('dpsb_device')->where($where)->field($field)->find();
+		$name = $result['WorkUnitName'];
+		unset($result['WorkUnitName']);
+		if(!$result){ //设备不存在
+			json_fail('DeviceAddr not exists!');
+		}
+		
+		$arr = array(
+		    'method' => $proto->method.'Resp',
+		    'Addr' => $addr,
+			 'WorkUnitName' => $name,
+			 'timestamp'=>time(date('Y-m-d H:i:s')),
+			 'alarm'=>$result,
+		);
+		$connection->send($arr);
+	}
+	
+ 
+	private  function respError( $connection, $message, $proto, $data ){
+		//判断$proto是否为字符串
+		if(!is_string($proto)){
+			$protostr = json_encode($proto);
+		}else{
+			$protostr = $proto;
+		}
+		log_error($message.' proto = '.$protostr);
+		$array = array(
+			'success' => false,
+			'message' => $message,
+			'data' => $data,
+		);
+		//判断是否存在method
+		if($proto->method){
+			$array['method'] = $proto->method . 'Resp';
+		}
+		
+		$connection->send($array);
+		$connection->close();
+	}
+	
+ 
+	protected  function onApiSendControl( $connection, $proto ){
+		/*返回结果: 
+		  1.失败,手动控制命令发送失败,地址码未设置
+		  2.失败,手动控制命令发送失败,手动控制命令格式错误
+		  3.失败,手动控制命令发送失败,设备未在线
+		  4.失败,手动控制命令发送失败,可能设备掉线
+		  5.失败,手动控制命令发送成功,但是设备回应超时
+		  6.失败,手动控制命令发送成功,但是设备回应格式错误
+		  7.失败,手动控制命令发送成功,但是设备回应错误信息
+		  8.成功
+		*/
+		//检查addr
+		if(!$proto->Addr){
+			$this->respError($connection,'失败,手动控制命令发送失败,地址码未设置',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			return;
+		}
+		
+		//给控制app终端发送手动控制信号,并等待回应
+		$arr = array(
+			"method"=> $proto->method,
+			"Addr"=>$proto->Addr,
+			"channelNumber"=>$proto->channelNumber,
+			"status"=>$proto->status
+		);
+		$callback = function($errno,$resp) use ($connection){
+			if($errno == self::ERRNO_SUCCESS){
+				if(is_object($resp)){
+					$res = $connection->send($resp);
+					$connection->close();
+				}
+				else
+					$this->respError($connection,'失败,手动控制命令发送成功,但是设备回应格式错误',$proto,\Zndp\Api\ResponseCode::OTHER_SERVER_ERROR);
+			}
+			else{
+				$this->respError($connection,'失败,手动控制命令发送失败,'.$this->getErrnoText($errno),$proto,\Zndp\Api\ResponseCode::OTHER_SERVER_ERROR);
+			}
+		};
+		$this->sendWait($proto->Addr,$arr,'appSendControlResp',$callback,10);
+	}
+	
+ 
+	protected  function onApiModifyAutoControlInfo( $connection, $proto ){
+		//检查addr是否为空
+		if(!$proto->Addr){
+			$this->respError($connection,'发送失败,地址码未设置',$proto,\Zndp\Api\ResponseCode::NOT_AUTH_DEVICE);
+			return;
+		}
+		//检查channelNumber是否为空
+		if(!$proto->channelNumber){
+			$this->respError($connection,'发送失败,设备通道查询不到',$proto,\Zndp\Api\ResponseCode::DEVICE_LOST_CONNECTION);
+			return;
+		}
+		//检查channelNumber是否存在
+		$device_id = MM('dpsb_device')->where(array('DeviceAddr'=>$proto->Addr))->getField('ID');
+		$cond = array(
+			'DeviceId'=>$device_id,
+			'ChNumber'=>$proto->channelNumber,
+		);
+		$result = MM('dpsb_channel')->where($cond)->find();
+		if(!$result){
+			$this->respError($connection,'发送失败,设备通道未设置',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			return;
+		}
+		
+		//给app转发自动控制命令
+		$arr = array(
+			'method'=>$proto->method,
+			'Addr'=>$proto->Addr,
+			'channelNumber'=>$proto->channelNumber,
+			'man'=>$proto->man,
+			'refChannel'=>$proto->refChannel,
+			'TimeEn'=>$proto->TimeEn,
+			'UpperLimit_Value'=>$proto->UpperLimit_Value,
+			'UpperLimit_State'=>$proto->UpperLimit_State,
+			'LowerLimit_Value'=>$proto->LowerLimit_Value,
+			'LowerLimit_State'=>$proto->LowerLimit_State,
+			'OnTime1'=>$proto->OnTime1,
+			'OffTime1'=>$proto->OffTime1,
+			'OnTime2'=>$proto->OnTime2,
+			'OffTime2'=>$proto->OffTime2,
+			'OnTime3'=>$proto->OnTime3,
+			'OffTime3'=>$proto->OffTime3,
+			'OnTime4'=>$proto->OnTime4,
+			'OffTime4'=>$proto->OffTime4,
+			'OnTime5'=>$proto->OnTime5,
+			'OffTime5'=>$proto->OffTime5,
+			'IssueTime'=>(int)$proto->IssueTime,
+		);
+		$callback = function($errno,$resp) use ($connection,$proto,$device_id){
+			if($errno == \Zndp\Api\ResponseCode::SEND_SUCCESS){
+				if(is_object($resp)){
+					$connection->send($resp);
+					$this->saveModifyAutoData($device_id,$proto,\Zndp\Api\ResponseCode::SEND_SUCCESS);
+					$connection->close();
+				}
+				else{
+					$this->respError($connection,'失败,自动控制命令发送成功,但是设备回应格式错误',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+					$this->saveModifyAutoData($device_id,$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);		
+				}
+			}
+			else{
+				$this->respError($connection,'失败,自动控制命令发送失败,'.$this->getErrnoText($errno),$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+				$this->saveModifyAutoData($device_id,$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			}
+		};
+		$this->sendWait($proto->Addr,$arr,'appModifyAutoControlInfoResp',$callback,10);
+		
+		
+	}
+	
+ 
+	private  function saveModifyAutoData( $device_id, $proto, $connection, $msg ){
+		$where = array(
+			'DeviceId'=> $device_id,
+			'Channel'=>$proto->channelNumber,
+		);
+		$res = MM('dpsb_policy')->where($where)->find();
+		if($res){
+			$saveData = array(
+				'Man'=> $proto->man,
+				'RefChannel'=> $proto->refChannel,
+				'IsTime'=> $proto->TimeEn,
+				'UpperLimitValue'=> $proto->UpperLimit_Value,
+				'UpperLimitState'=> $proto->UpperLimit_State,
+				'LowerLimitValue'=> $proto->LowerLimit_Value,
+				'LowerLimitState'=> $proto->LowerLimit_State,
+				'OnTime1'=> $proto->OnTime1,
+				'OffTime1'=> $proto->OffTime1,
+				'OnTime2'=> $proto->OnTime2,
+				'OffTime2'=> $proto->OffTime2,
+				'OnTime3'=> $proto->OnTime3,
+				'OffTime3'=> $proto->OffTime3,
+				'OnTime4'=> $proto->OnTime4,
+				'OffTime4'=> $proto->OffTime4,
+				'OnTime5'=> $proto->OnTime5,
+				'OffTime5'=> $proto->OffTime5,
+				'SendTime'=> date('Y-m-d H:i:s'),
+				'SendResult'=> $msg
+			);
+			$result = MM('dpsb_policy')->createSave($where,$saveData);
+			
+		}else{
+			$addData = array(
+				'DeviceId'=> $device_id,
+				'Channel'=>$proto->channelNumber,
+				'Man'=> $proto->man,
+				'RefChannel'=> $proto->refChannel,
+				'IsTime'=> $proto->TimeEn,
+				'UpperLimitValue'=> $proto->UpperLimit_Value,
+				'UpperLimitState'=> $proto->UpperLimit_State,
+				'LowerLimitValue'=> $proto->LowerLimit_Value,
+				'LowerLimitState'=> $proto->LowerLimit_State,
+				'OnTime1'=> $proto->OnTime1,
+				'OffTime1'=> $proto->OffTime1,
+				'OnTime2'=> $proto->OnTime2,
+				'OffTime2'=> $proto->OffTime2,
+				'OnTime3'=> $proto->OnTime3,
+				'OffTime3'=> $proto->OffTime3,
+				'OnTime4'=> $proto->OnTime4,
+				'OffTime4'=> $proto->OffTime4,
+				'OnTime5'=> $proto->OnTime5,
+				'OffTime5'=> $proto->OffTime5,
+				'SendTime'=> date('Y-m-d H:i:s'),
+				'SendResult'=> $msg
+			);
+			$result = MM('dpsb_policy')->createAdd($addData);
+		}
+		if(!$result){
+			$this->respError($connection,'channelNumber inexistence',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			return;
+		}
+	}
+	
+ 
+	protected  function onAppSendRealTimeDeviceData( $connection, $proto ){
+		//检查imei地址
+		if(!$proto->imei){
+			$this->respError($connection,'imei is empty ',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			return;
+		}
+		if(!$connection->addr){
+			$this->respError($connection,'addr is empty ',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			return;
+		}
+		
+		//检查连接池中是否存在addr,不存在添加回去
+		if(!$this->getFromPool($connection->addr)){
+			$connection->imei = $proto->imei;
+			$this->addToPool($connection->addr,$connection);
+			$this->logDebug('pool loss,reattach pool,imei = ' . $proto->imei);
+			//log_debug('Data abnormal');
+			echo 'Data abnormal'.PHP_EOL;
+		}
+		
+		
+		// 将数据更新到数据表中
+		/*
+		$data = $proto->data;
+		$fix_device_info = MM('dpsb_device')->where(array('DeviceImei'=>$proto->imei))->select();
+		$device_id = saveDeviceInfo($proto);
+		//$device_id = saveDeviceInfo($proto->imei,$fix_device_info[0]['VersionName'],$connection->addr,$fix_device_info[0]['IccId'],$fix_device_info[0]['CellPhone']);
+		*/
+		$device_id = MM('dpsb_device')->where(array('DeviceImei'=>$proto->imei))->getField('ID');
+		if(!$device_id){
+			$this->respError($connection,'device_id is empty ',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			return;
+		}
+		if(!$proto->data){
+			//$this->respError($connection,'data is empty ',$proto,\Zndp\Api\ResponseCode::NO_DATA);
+			//log_debug('Data is empty');
+			echo 'Data is empty'.PHP_EOL;
+		}
+		
+		if(!$proto->gathertime){
+			$this->respError($connection,'gathertime is empty ',$proto,\Zndp\Api\ResponseCode::NO_DATA);
+			return;
+		}
+		
+		$gathertime = date('Y-m-d H:i:s',$proto->gathertime);
+		//检查数据是否无效
+		if(isDeviceDataInvalid($proto->data)){
+			//保存到无效数据表
+			$device_data = array();
+			$device_data['Addr'] = $connection->addr;
+			$device_data['DeviceData'] = json_encode($proto->data);
+			$device_data['GatherTime'] = $gathertime;
+			$device_data['AddTime'] = date('Y-m-d H:i:s');
+			MM('dpsj_invalid')->createAdd($device_data);
+			//$this->respError($connection,'data invelid',$proto,\Zndp\Api\ResponseCode::NO_DATA);
+			//return;
+		}
+		
+		//保存到通道表
+		$errmsg2 = saveToChannel($device_id,$proto->data,$gathertime);
+		if($errmsg2){
+			$this->respError($connection,$errmsg2,$proto,\Zndp\Api\ResponseCode::DEVICE_OPRATE_DISALLOWED);
+			return;
+		}
+		//保存数据到设备数据表
+		if(!$proto->Dedata){
+			//log_debug('Dedata is empty');
+			echo 'Dedata is empty'.PHP_EOL;
+			//$this->respError($connection,'Dedata is empty ',$proto,\Zndp\Api\ResponseCode::NO_DATA);
+			//return;
+		}
+		$dedata = $proto->Dedata;
+		$errmsg1 = saveToDevice($device_id,$dedata,$gathertime);
+		if($errmsg1){
+			$this->respError($connection,$errmsg1,$proto,\Zndp\Api\ResponseCode::DEVICE_OPRATE_DISALLOWED);
+			return;
+		}
+		//保存到通道数据表
+		$errmsg3 = saveToChannelData($device_id,$proto->data,$gathertime);
+		if($errmsg3){
+			$this->respError($connection,$errmsg3,$proto,\Zndp\Api\ResponseCode::DEVICE_OPRATE_DISALLOWED);
+			return;
+		}
+		// 检查告警,并推送到Redis 2019年1月29日10:09:59
+		pushAlarmToRedis($device_id,$proto->data,$gathertime);
+		
+		// 推送数据到农科院
+		$res = send_nongke($connection->addr,$proto->data,$gathertime);
+		//$res = send_single_nongke($connection->addr,$data,$gathertime);
+		
+		
+		$arr = array(
+			'method' => $proto->method.'Resp',
+			"success"=>true,
+			"message"=>"ok",
+			"addtime"=>time(),
+		);
+		$connection->send($arr);
+	}
+	
+ 
+	protected  function onAppHeartbeat( $connection, $proto ){
+		//直接返回心跳
+		$arr = array(
+			'success'=>true
+		);
+		$connection->send($arr);
+	}
+	
+ 
+	protected  function onAppSendControlResp(  ){
+		
+	}
+	
+ 
+	protected  function onAppModifyAutoControlInfoResp(  ){
+		
+	}
+	
+ 
+	protected  function onApiUploadDebug( $connection, $proto ){
+		
+		if(!$proto->Addr){
+			$this->respError($connection,'失败,地址码未设置',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			return;
+		}
+		
+		//给控制app终端发送手动控制信号,并等待回应
+		$arr = array(
+			"method"=> $proto->method,
+			"Addr"=>$proto->Addr,
+		);
+		$callback = function($errno,$resp) use ($connection){
+			if($errno == self::ERRNO_SUCCESS){
+				if(is_object($resp)){
+					$res = $connection->send($resp);
+					$connection->close();
+				}
+				else
+					$this->respError($connection,'失败,调试不存在',$proto,\Zndp\Api\ResponseCode::OTHER_SERVER_ERROR);
+			}
+			else{
+				$this->respError($connection,'失败,调试发送失败'.$this->getErrnoText($errno),$proto,\Zndp\Api\ResponseCode::OTHER_SERVER_ERROR);
+			}
+		};
+		$this->sendWait($proto->Addr,$arr,'appUploadDebugResp',$callback,10);
+	}
+	
+ 
+	protected  function onAppUploadDebugResp(  ){
+		
+	}
+	
+ 
+	protected  function onApiReboot( $connection, $proto ){
+		
+		if(!$proto->Addr){
+			$this->respError($connection,'失败,地址码未设置',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			return;
+		}
+		
+		//给控制app终端发送手动控制信号,并等待回应
+		$arr = array(
+			"method"=> $proto->method,
+			"Addr"=>$proto->Addr,
+		);
+		$callback = function($errno,$resp) use ($connection){
+			if($errno == self::ERRNO_SUCCESS){
+				if(is_object($resp)){
+					$res = $connection->send($resp);
+					$connection->close();
+				}
+				else
+					$this->respError($connection,'失败,重启不存在',$proto,\Zndp\Api\ResponseCode::OTHER_SERVER_ERROR);
+			}
+			else{
+				$this->respError($connection,'失败,重启发送失败'.$this->getErrnoText($errno),$proto,\Zndp\Api\ResponseCode::OTHER_SERVER_ERROR);
+			}
+		};
+		$this->sendWait($proto->Addr,$arr,'appRebootResp',$callback,10);
+	}
+	
+ 
+	protected  function onApiUpgrade( $connection, $proto ){
+		
+		if(!$proto->Addr){
+			$this->respError($connection,'失败,地址码未设置',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			return;
+		}
+		
+		//给控制app终端发送手动控制信号,并等待回应
+		$arr = array(
+			"method"=> $proto->method,
+			"Addr"=>$proto->Addr,
+		);
+		$callback = function($errno,$resp) use ($connection){
+			if($errno == self::ERRNO_SUCCESS){
+				if(is_object($resp)){
+					$res = $connection->send($resp);
+					$connection->close();
+				}
+				else
+					$this->respError($connection,'失败,升级不存在',$proto,\Zndp\Api\ResponseCode::OTHER_SERVER_ERROR);
+			}
+			else{
+				$this->respError($connection,'失败,升级发送失败'.$this->getErrnoText($errno),$proto,\Zndp\Api\ResponseCode::OTHER_SERVER_ERROR);
+			}
+		};
+		$this->sendWait($proto->Addr,$arr,'appUpgradeResp',$callback,10);
+	}
+	
+ 
+	protected  function onAppUpgradeResp(  ){
+		
+	}
+	
+ 
+	protected  function onAppRebootResp(  ){
+		
+	}
+	
+ 
+	protected  function onApiSysReboot( $connection, $proto ){
+		if(!$proto->Addr){
+			$this->respError($connection,'失败,地址码未设置',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			return;
+		}
+		
+		//给控制app终端发送手动控制信号,并等待回应
+		$arr = array(
+			"method"=> $proto->method,
+			"Addr"=>$proto->Addr,
+		);
+		$callback = function($errno,$resp) use ($connection){
+			if($errno == self::ERRNO_SUCCESS){
+				if(is_object($resp)){
+					$res = $connection->send($resp);
+					$connection->close();
+				}
+				else
+					$this->respError($connection,'失败,系统重启不存在',$proto,\Zndp\Api\ResponseCode::OTHER_SERVER_ERROR);
+			}
+			else{
+				$this->respError($connection,'失败,系统重启发送失败'.$this->getErrnoText($errno),$proto,\Zndp\Api\ResponseCode::OTHER_SERVER_ERROR);
+			}
+		};
+		$this->sendWait($proto->Addr,$arr,'appSysReboot',$callback,10);
+	}
+	
+ 
+	public  function onAppSysRebootResp(  ){
+		
+	}
+	
+ 
+	protected  function onFarmlandNum( $connection, $proto ){
+		if( !$proto->addr ){
+			$this->respError($connection,'失败,设置大棚编号命令发送失败,地址码未设置',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			return;
+		}
+		if( $proto->channelGroup === ''){ 
+			$this->respError($connection,'失败,设置大棚编号命令发送失败,通道组未设置',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+			return;
+		}
+		//给控制app终端发送大棚编号,并等待回应
+		$arr = array(
+			"method"	 	=> $proto->method,
+			"channelGroup"  => (int)$proto->channelGroup,
+			"number"		=> $proto->number
+		);
+		$callback = function($errno,$resp) use ($connection){
+			if($errno == self::ERRNO_SUCCESS){
+				if(is_object($resp)){
+					$res = $connection->send($resp);
+					$connection->close();
+				}else{
+					$this->respError($connection,'失败,设置大棚编号命令发送成功,但是设备回应格式错误',$proto,\Zndp\Api\ResponseCode::OTHER_SERVER_ERROR);			
+				}
+			}else{
+				$this->respError($connection,'失败,设置大棚编号命令发送失败,'.$this->getErrnoText($errno),$proto,\Zndp\Api\ResponseCode::OTHER_SERVER_ERROR);
+			}
+		};
+		$this->sendWait($proto->addr,$arr,'farmlandNumResp',$callback,10);
+	}
+	
+ 
+	protected  function onFarmlandNumResp( $connection, $resp ){
+		//var_dump($connection);
+		var_dump($resp);
+	}
+	
+ 
+	protected  function onControlFinish( $connection, $proto ){
+		/*
+		{
+			"method" : "controlFinish",
+			"channelGroup" : 0, // 设备通道组
+			"channelNum" : 1, // 卷膜机左/右
+			"success" : true, // 操作成功,失败
+			"isman" : 0, // 操作类型:(自动-0,手动-1) 
+			"operatTime" : 1552353910, // 操作时间戳
+			"operat" : 1, // 当前操作,停止-0,打开-1,关闭-2,全打开-3,全关闭-4
+		}
+		*/ 
+		// 保存操作日志
+		// 获取设备id
+		$where = array('DeviceAddr' => $connection->addr);
+		$device_id = MM('dpsb_device')->where($where)->getField('ID');
+		if(!$device_id){
+		    $this->respError($connection,'device_id is empty ',$proto,\Zndp\Api\ResponseCode::DEVICE_NOT_EXISTS);
+		    return;
+		}
+		// 获取大棚id
+		$where = array('DeviceId'=>$device_id,'ChGroup'=>$proto->channelGroup);
+		$farmland_id = MM('dpsb_chgroup')->where($where)->getField('FarmlandId');
+		// 操作描述
+		$control_status = array('自动控制','手动控制');
+		$operat_status = array('停止','打开','关闭','全打开','全关闭');
+		$operat_content = $control_status[$proto->isman] .'-'. $operat_status[$proto->operat];
+		$log_data = array(
+			'ID' => create_guid(),
+			'IsMan' => $proto->isman,
+			'AddTime' => date('Y-m-d H:i:s',$proto->operatTime),
+			'DeviceId' => $device_id,
+			'FarmlandId' => $farmland_id,
+			'ChannelNumber' => $proto->channelNum,
+			'LogContent' => $operat_content,
+			'OperResult' => $proto->success ? '成功':'失败',
+		);
+		// 如果是控制台手动操作的,记录操作用户
+		if( $proto->userName ){
+			//获取UserId
+			$where = array('UserName'=>$proto->userName);
+			$log_data['UserId'] = MM('uc_user')->where($where)->getField('ID');
+		}
+		$result = MM('dpsj_oplog')->createAdd($log_data);
+		$arr = array(
+		    'method' => $proto->method.'Resp',
+			 'message' => $result ? 'success':'fail',
+		    'success' => (bool)$result
+		);
+		$connection->send($arr);
+	}
+	
+
+}

+ 178 - 0
Home/Lib/Action/DpxfTestAction.class.php

@@ -0,0 +1,178 @@
+<?php
+class DpxfTestAction extends Action {
+	/*
+
+	*/
+	public function client(){
+		ini_set('display_errors',1); 
+		
+		
+		// error_reporting(E_ALL);
+		//  include 'ClientSend.php';
+		//  $cs = new ClientSend("47.94.46.33", 20161);
+		//  print_r($cs->send('{"type":1003,"cityid":10,"station_number":"000000000003","version":"WF-200ATV100R003C06B006","ftpip":"139.224.210.194","ftpport":"21","name":"cf-yy","password":"icg18000","filename":"\/WF-200ATV100R003C06B006.bin","filesize":"7864432","sign":"1E80F173C3938942F12109BB8B287D12"}'));
+		//  die;
+		$isWaitRecv = false;
+		if ($argc == 2 && $argv[1] == "wait")
+		    $isWaitRecv = true;
+		      
+		$this->conn($host, $port, $socket);
+		$this->wri($socket, $msg, $length);
+		$this->decodeUnicode($str);
+		if(!function_exists("readline")) {
+		    $this->readline( $prompt = '' );
+		}
+		$this->red($socket);
+		
+		$service_port = 10240;  
+		 $address = '116.62.201.137'; //测试服务器 admin
+		$address = '116.62.220.88'; //测试服务器(新) develop
+		//$address = '47.94.46.33';//代码服务器
+		// $address = '116.62.211.6';//江苏乘风
+		// $address = '192.168.1.63';
+		$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
+		
+		// print_r(socket_get_option($socket, SOL_SOCKET, SO_SNDTIMEO));
+		// print_r(socket_get_option($socket, SOL_SOCKET, SO_RCVTIMEO));
+		// die;
+		
+		if ($socket === FALSE) {  
+		    echo "socket创建失败原因: " . socket_strerror(socket_last_error()) . "\n";  
+		    return;
+		} else {  
+		    echo "socket创建成功\n";  
+		}
+		
+		socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, array('sec' => 1, 'usec' => 0));
+		
+		if (!$isWaitRecv)
+		    socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 0, 'usec' => 300 * 1000/*微妙*/));
+		
+		conn($address, $service_port, $socket);
+		
+		$j = 0;
+		while (true)
+		{
+		//     echo $j;
+		
+		    $in = readline("输入发送内容:");
+		
+		//     if ($j == 0) {
+		//         $in = '{"type":"1","msgid":0,"model":"CFWF-200AT","sn":"02050172D12C000001","mac":"000000000003","version":"V100R003C06B006","wip":"192.168.1.11","nmode":0,"rssi":0,"serialnum":"","uptime":"246.91","sign":"989D62CFB2635DE9ACD889ACCD7EED42"}';
+		//     } else {
+		//         $in = '{"type":3,"msgid":6,"mac":"000000000003","realtime":1507876879}';
+		//     }
+		    
+		    if ($in == "quit") break;
+		    wri($socket, $in, strlen($in));
+		    wri($socket, pack('C','\0'), 1);
+		    red($socket);
+		    $j++;
+		}
+		
+		socket_close($socket);
+		
+	}
+	/*
+	参数说明:
+		host: 
+		port: 
+		socket: 
+
+	*/
+	private function conn($host, $port, $socket){
+		$timeout = 5;
+		socket_set_nonblock($socket);
+		$time = time();
+		while (!@socket_connect($socket, $host, $port)) {
+			$err = socket_last_error($socket);
+			if($err === 56) {
+				print('connected ok');
+				break;
+			}
+			if ((time() - $time) >= $timeout) {
+				socket_close($socket);
+				print('连接超时');
+				exit();
+			}
+			usleep(250000);
+		}
+		echo "socket连接成功\n";
+		socket_set_block($socket);
+	}
+	/*
+	参数说明:
+		socket: 
+		msg: 
+		length: 
+
+	*/
+	private function wri($socket, $msg, $length){
+		while(true) {
+			$sent = socket_write($socket, $msg, $length);
+			if($sent === false) {
+				echo "发送失败" . socket_strerror(socket_last_error());
+				return false;
+			}
+			if($sent < $length) {
+				$msg = substr($msg, $sent);
+				$length -= $sent;
+				echo "这些字节没法送 :$msg:重新发送";
+				return false;
+			} else {
+				return true;
+			}
+		} 
+	}
+	/*
+	参数说明:
+		str: 
+
+	*/
+	private function decodeUnicode($str){
+		return preg_replace_callback('/\\\\u([0-9a-f]{4})/i',
+									 create_function(
+										 '$matches',
+										 'return mb_convert_encoding(pack("H*", $matches[1]), "UTF-8", "UCS-2BE");'
+									 ),
+									 $str);
+	}
+	/*
+	参数说明:
+		prompt: 
+
+	*/
+	private function readline($prompt){
+		echo $prompt;
+		return rtrim( fgets( STDIN ), "\n" );
+	}
+	/*
+	参数说明:
+		socket: 
+
+	*/
+	private function red($socket){
+		//socket_set_nonblock($socket);
+		socket_clear_error();
+		while (true) {
+			$out = socket_read($socket, 2048);
+			if ($out == false)//if ($out === false || $out === "")//无更多数据可读
+				break;
+			echo "获取返回数据:" . decodeUnicode($out);
+		} 
+		$errorCode = socket_last_error($socket);
+		if ($errorCode == 115 || $errorCode == 104 || $errorCode == 114) {
+			echo "\n连接关闭\n";
+			exit();
+		} else if ($errorCode == 11) //读取超时
+			echo "读取超时\n\n";
+			else
+			echo "\n读取失败:" . $errorCode . socket_strerror($errorCode) . "\n";
+		
+			//         sleep(15);
+			//     socket_clear_error();
+			//         $out = socket_read($socket, 2048);
+			//         echo "\n读取失败:" .socket_last_error($socket).socket_strerror(socket_last_error($socket)) . "\n";
+	}
+
+}

+ 192 - 0
Home/Lib/Action/IndexAction.class.php

@@ -0,0 +1,192 @@
+<?php
+class IndexAction extends Action {
+	private $connpool;
+	/*
+	参数说明:
+		connection: 
+
+	*/
+	private function onClose($connection){
+		log_debug('onClose:' . $connection->imei. ' closed');
+		//移除长连接
+		$this->removePool($connection);
+	}
+	/*
+	参数说明:
+		connection: 
+
+	*/
+	private function onConnect($connection){
+		log_debug($connection->imei . ' connected');
+		$connection->m_packet = '';
+	}
+	/*
+	参数说明:
+		connection: 
+		data: 
+
+	*/
+	private function onMessage($connection, $data){
+		log_debug("raw:" . bin2hex($data));
+		$connection->m_packet .= $data;
+		
+		
+		//检查\0结束符,检查到就是一段命令结束
+		$lastchar = substr($data,-1);
+		if( ord($lastchar) != 0 ){
+			return;
+		}
+		$packet = trim($connection->m_packet);
+		$connection->m_packet = '';  //长连接,必须清空字符串
+		
+		//解码请求消息
+		log_debug('packet: '. $packet);
+		$req = json_decode( trim($packet));
+		
+		
+		
+		if(!$req){
+			log_error('decode failed ' . $packet);
+			$connection->close();
+			return;
+		}
+		log_debug('decode success - ' . $packet);
+		
+		//处理不同的协议
+		if($req->method == "appLogin"){ //app请求登录
+			$this->onAppLogin($req,$connection);
+			$connection->request = $req;
+		}else if($req->method == "heartBeat"){ //长链接时要检查心跳
+			$this->onProtoHeartbeat($req,$connection);
+			$connection->request->msgid = $req->msgid;
+		}else if($req->method == "appSendRealTimeDeviceData"){ //app发送实时数据
+		
+		}else if($req->method == "sendControl"){ //手动控制
+		
+		}else if($req->method == "ModifyAutoControlInfo"){ //自动控制
+		
+		}else{
+			log_error('unknown req method ' . $req->method);
+		}
+	}
+	/*
+
+	*/
+	public function index(){
+		Vendor('Workerman.Autoloader');
+		$worker = new Workerman\Worker("tcp://0.0.0.0:1024");
+		//$worker->count = 4;
+		$worker->onWorkerStart  = function($worker){
+			//$this->onWorkerStart($worker);
+		};
+		$worker->onWorkerStop = function($worker) {
+		    $this->onWorkerStop($worker);
+		};
+		$worker->onConnect = function($connection){
+			//$this->onConnect($connection);
+		};
+		$worker->onMessage = function($connection,$data){
+			$this->onMessage($connection,$data);
+		};
+		$worker->onClose = function($connection){
+			$this->onClose($connection);
+		};
+		$worker->onBufferFull = function($connection){
+			//$this->onBufferFull($connection);
+		};
+		$worker->onBufferDrain = function($connection){
+			//$this->onBufferDrain($connection);
+		};
+		$worker->onError = function($connection, $code, $msg){
+			$this->onError($connection, $code, $msg);
+		};
+		Workerman\Worker::runAll();
+		
+	}
+	/*
+	参数说明:
+		req: 
+		connection: 
+
+	*/
+	private function onAppLogin($req, $connection){
+		//检查imei地址
+		if(!$req->imei){
+			log_error('$req->imei is empty. ' . json_encode($req));
+			$connection->close();
+			return;
+		}
+		
+		//通过登录验证,加入连接池
+		$this->addPool($req->imei,$connection);
+		log_debug('login success. should put into connection pool. imei = ' . $req->imei);
+		
+		// 将数据更新到数据表中
+		$data = $req->channel;
+		$device_id = inputDeviceInfo($req->imei);
+		$channel = inputChannel($device_id,$data);
+	}
+	/*
+	参数说明:
+		req: 
+		connection: 
+
+	*/
+	private function onProtoHeartbeat($req, $connection){
+		
+	}
+	/*
+	参数说明:
+		connection: 
+		code: 
+		msg: 
+
+	*/
+	private function onError($connection, $code, $msg){
+		log_error("onError:" . $connection->imei . $msg);
+	}
+	/*
+	参数说明:
+		worker: 
+
+	*/
+	private function onWorkerStop($worker){
+		
+	}
+	/*
+
+	*/
+	public function test(){
+		$i = 0;
+		while (1) {
+			$model = M("jzgl_station");
+			$model->count() . "\n";
+			echo memory_get_usage() . "\n";
+			$i++;
+			if ($i > 10) break;
+		}
+	}
+	/*
+	参数说明:
+		imei:设备imei 
+		connection:链接 
+
+	*/
+	private function addPool($imei, $connection){
+		$connection->imei = $imei;
+		$this->connections[$imei] = $connection;
+	}
+	/*
+	参数说明:
+		connection: 
+
+	*/
+	private function removePool($connection){
+		//获取连接
+		$imei = $connection->imei;
+		
+		//从所有连接中移除连接
+		unset( $this->connections[$imei]);
+	}
+
+}

+ 19 - 3
README.md

@@ -1,3 +1,19 @@
-# dpfw
-
-大棚信号服务
+//登录
+{"method":"appLogin","imei":"86718403901828","channel":[{"Group":1,"Type":10,"Column":1},{"Group":1,"Type":11,"Column":2},{"Group":1,"Type":12,"Column":3},{"Group":1,"Type":13,"Column":4},{"Group":2,"Type":14,"Column":5}]}
+//实时数据
+{"method":"appSendRealTimeDeviceData","Imei":xxxx,"Gathertime":xxxx,"Devalue":{"Column":xxxx,"Value":xxxx,"Type":xxxx}}
+//手动控制
+发送  {"method":"apiSendControl","Addr":"12345678","channelNumber":"5","status":"1"}
+回应  {"method":"appSendControlResp","Addr":"12345678","success":false,"message":"发送错误"}
+//自动控制
+回应  {"method":"appModifyAutoControlInfoResp","Addr":"12345678","success":false,"message":"发送错误"}
+//启动服务器
+develop.rltest.cn
+/data/wwwroot/zndp.rltest.cn/
+php index.php start dpxf_index/index
+//启动控制器
+telnet 116.62.220.88 10240
+//或者
+admin.rltest.cn
+/alidata/www/admin.rltest.cn/1.2.0/fdlc/
+php client.php

+ 6 - 0
index.php

@@ -0,0 +1,6 @@
+<?php
+define('SCRIPT_FILENAME', __FILE__);
+//插件信息
+require  __DIR__ . '/stub.php';
+//TP入口
+require( dirname(__DIR__) . '/jrtp/stub.php');

+ 43 - 0
plugin.json

@@ -0,0 +1,43 @@
+{
+  "id": "b4b2a3beabc9d228f24c34ddb08b0bbe",
+  "name": "dpxf",
+  "title": "大棚信号服务",
+  "prefix": "dpxf",
+  "version": "1.0.3",
+  "icon": "",
+  "description": "大棚信号服务",
+  "homepage": "",
+  "license": "",
+  "repository": {
+    "type": "git",
+    "url": ""
+  },
+  "author": {
+    "name": "elviss",
+	"mobile": "", 
+    "email": "elvisszhang@icloud.com",
+	"company": ""
+  },
+  "dependencies": {
+    
+  },
+  "devDependencies": {
+    "thinkphp": "3.1.3"
+  },
+  "environment":[
+    {
+        "name":"DB_DSN",
+        "title":"MySQL数据库配置",
+        "description":"",
+        "type":"text"
+    }
+  ],
+  "daemon":[
+    {
+        "name":"start_dpxf",
+        "title":"启动信号服务",
+        "description":"监听设备每分钟上报数据包",
+        "startcmd":"{php} {plugin.dir}/index.php start -d dpxf_index/index"
+    }
+  ]
+}

+ 9 - 0
stub.php

@@ -0,0 +1,9 @@
+<?php
+//插件或者工程ID
+define('APP_ID','b4b2a3beabc9d228f24c34ddb08b0bbe');
+//插件前缀
+define('APP_PREFIX','dpxf');
+//插件版本
+define('APP_VERSION','1.0.3');
+//入口文件路径
+define('APP_FILENAME', __FILE__);

+ 1 - 0
workerman.pid

@@ -0,0 +1 @@
+3480