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; } }