<?php
namespace Electronic;
use think\facade\Cache;
/**
* 曼顿设备
*/
class Mandun{
    //配置
    public $config;

    //接口URL
    protected $api_url='https://open.snd02.com';

    protected $api_router_url="https://open.snd02.com:443/invoke/router.as";

    protected $QyAppKey="O000008102";
    protected $QyUrl='https://chashi.youdiy.cn/mandun/index.php';
    public function __construct($config=[]){
        // $config=[
        //  'appKey'=>'O000008102',
        //  'appSecret'=>'87927BA90EEFB027EE7298B139C9AACF',
        //  'uname'=>'qlgcs01',
        //  'passwd'=>'qlg888',
        //  'projectCode'=>'P00000016937',
  //           'api_url'=>'https://open.snd02.com',
        // ];
        $data=[
            'appKey'=>isset($config['appKey'])?$config['appKey']:'',
            'appSecret'=>isset($config['appSecret'])?$config['appSecret']:'',
            'uname'=>isset($config['uname'])?$config['uname']:'',
            'passwd'=>isset($config['passwd'])?$config['passwd']:'',
            'projectCode'=>isset($config['projectCode'])?$config['projectCode']:'',
            'api_url'=>isset($config['api_url'])?$config['api_url']:'',
        ];      
        $this->config = (object)$data;
        $this->api_url="http://".$data['api_url'];
        $this->api_router_url="https://".$data['api_url'].":443/invoke/router.as";
    }
    //获取验证码
    public function getCode(){
        $action="/oauth/authverify2.as";
        $url=$this->api_url.$action;
        $post['redirect_uri']=$this->api_url."/demo.jsp";
        $post['response_type']="code";
        $post['uname']=$this->config->uname;
        $post['passwd']=$this->config->passwd;
        $post['client_id']=$this->config->appKey;
        $res=self::httpRequest($url,"POST",$post);
        if($res['code']!=1){
            return ['code'=>0,'data'=>$res['code']];
        }else{
            return ['code'=>1,'msg'=>'获取码错误'];
        }
    }
    //获取项目信息
    public function getProjectInfo(){
        $url=$this->api_router_url;
        $param['method']="GET_PROJECT_INFO";
        $param['projectCode']=$this->config->projectCode;
        $param=self::getParam($param);
        $res=self::httpRequest($url,"POST",$param);
        return $res;
    }
    //获取项目内的所有设备
    public function getBoxes(){
        $url=$this->api_router_url;
        $param['method']="GET_BOXES";
        $param['projectCode']=$this->config->projectCode;
        $param=self::getParam($param);
        $res=self::httpRequest($url,"POST",$param);
        return $res;
    }
    //获取项目内的所有设备
    public function getBox($data=[]){
        $url=$this->api_router_url;
        $param['method']="GET_BOX";
        $param['mac']=$data['mac'];
        $param=self::getParam($param);
        $res=self::httpRequest($url,"POST",$param);
        return $res;
    }
    //获取设备实时状态数据
    public function getBoxchannelsRealtime($mac=''){
        $url=$this->api_router_url;
        $param['method']="GET_BOX_CHANNELS_REALTIME";
        $param['projectCode']=$this->config->projectCode;
        $param['mac']=$mac;
        $param=self::getParam($param);
        $res=self::httpRequest($url,"POST",$param);
        return $res;
    }
    //设备控制接口
    public function putBoxControl($data=[]){
        $url=$this->api_router_url;
        $param['method']="PUT_BOX_CONTROL";
        $param['mac']=$data['mac'];
        $param['projectCode']=$this->config->projectCode;
        $param=self::getParam($param);
        $res=self::httpRequest($url,"POST",$param);
        return $res;
    }
    //公共参数
    public function createSign($param=[]){
        ksort($param);
        $sign='';
        foreach ($param as $k => $v)
        {
            $sign.=$v;
        }
        return md5($sign.$this->config->appSecret);
    }
    //获得参数-传递的参数与公共参数进行组合
    public function getParam($param=[]){
        $param['client_id']=$this->config->appKey;
        $getAccessToken=self::getAccessToken();
        if($getAccessToken['code']!=0){
            return $getAccessToken;
        }
        $param['access_token']=$getAccessToken['data'];
        $param['timestamp']=time();
        $param['sign']=self::createSign($param);
        return $param;
    }
    //项目的定时场景接口-场景添加
    public function sceneServiceAdd($mac=''){
        $url=$this->api_router_url;
        $post['method']="SCENE_SERVICE";
        $post['cmd']='SCENE_ADD';
        $post['projectCode']=$this->config->projectCode;
        $post['sceneName']="QYCS_".$mac;
        $post['remark']="福州芊雅软件技术-技术支持";
        $param=self::getParam($post);
        $res=self::httpRequest($url,"POST",$param);
        if($res['code']==0){
            return ['code'=>0,'data'=>$res['data']['sceneId']];
        }else{
            return ['code'=>1,'msg'=>$res['message']];
        }
    }
    //项目的定时场景接口-场景删除
    public function sceneServiceDel($sceneId=''){
        $url=$this->api_router_url;
        $post['method']="SCENE_SERVICE";
        $post['cmd']='SCENE_DEL';
        $post['sceneId']=$sceneId;
        $post['projectCode']=$this->config->projectCode;
        $param=self::getParam($post);
        $res=self::httpRequest($url,"POST",$param);
        if($res['code']==0){
            return ['code'=>0,'msg'=>$res['message']];
        }else{
            return ['code'=>1,'msg'=>$res['message']];
        }
    }
    //新增场景中的设备线路(可多个线路地址)
    public function sceneServiceChnlAdd($sceneId='',$mac='',$addr=''){
        $url=$this->api_router_url;
        $post['method']="SCENE_SERVICE";
        $post['cmd']='SCENE_CHNL_ADD';
        $post['sceneId']=$sceneId;
        $post['projectCode']=$this->config->projectCode;
        $post['mac']=$mac;
        $post['addr']=$addr;
        $param=self::getParam($post);
        $res=self::httpRequest($url,"POST",$param);
        if($res['code']==0){
            return ['code'=>0,'msg'=>$res['message']];
        }else{
            return ['code'=>1,'msg'=>$res['message']];
        }
    }
    //项目的定时场景接口-场景列表
    public function sceneServiceChnlQuery($sceneId=''){
        $url=$this->api_router_url;
        $post['method']="SCENE_SERVICE";
        $post['cmd']='SCENE_CHNL_QUERY';
        $post['sceneId']=$sceneId;
        $post['projectCode']=$this->config->projectCode;
        
        $param=self::getParam($post);
        $res=self::httpRequest($url,"POST",$param);
        if($res['code']==0){
            return ['code'=>0,'msg'=>$res['message'],'data'=>$res['data']];
        }else{
            return ['code'=>1,'msg'=>$res['message']];
        }
    }
    
    //新增/修改场景定时
    public function sceneServiceTimeMod($sceneId='',$time='',$status="false"){

        $url=$this->api_router_url;
        $post['method']="SCENE_SERVICE";
        $post['cmd']='SCENE_TIMER_MOD';
        $post['sceneId']=$sceneId;
        $post['projectCode']=$this->config->projectCode;
        $post['time']=$time;
        $post['status']=$status;
        $param=self::getParam($post);
        $res=self::httpRequest($url,"POST",$param);
        if($res['code']==0){
            return ['code'=>0,'msg'=>$res['message']];
        }else{
            return ['code'=>1,'msg'=>$res['message']];
        }
    }
    public function sceneServicePuls($mac='',$addr='',$status=1){
        $url=$this->api_router_url;
        $post['method']="PUT_BOX_CONTROL";
        $post['cmd']='OCSWITCH';
        $post['mac']=$mac;
        $post['projectCode']=$this->config->projectCode;
        $post['value1']=$status==1?"open":"close";
        $post['value2']=$addr;
        $param=self::getParam($post);
        //开电
        $res=self::httpRequest($url,"POST",$param);
        if($res['code']==0){
            return ['code'=>0,'msg'=>$res['message']];
        }else{
            return ['code'=>1,'msg'=>$res['message']];
        }
    }
    //项目的定时场景接口-添加场景
    //mac  物理地址
    //addr 线路
    //start_time 开电时间
    //end_time 关电时间
    public function sceneService($mac='',$addr='',$start_time="",$end_time="",$status=1){
         set_time_limit(0);
        $url=$this->api_router_url;
        $post['method']="SCENE_SERVICE";
        $post['cmd']='SCENE_QUERY';
        $post['projectCode']=$this->config->projectCode;
        $param=self::getParam($post);
        $res=self::httpRequest($url,"POST",$param);
        if($res['code']==0){
            //获取场景ID
            $sceneId="";
            if(count($res['data']['scenes'])>0){
                foreach ($res['data']['scenes'] as $key => $value) {
                    if($value['sceneName']=="QYCS_".$mac.$addr){
                        $sceneId=$value['sceneId'];
                        if($sceneId){
                            break;
                        }
                    }
                }
                if(!$sceneId){
                    //新增场景
                    $addRes=self::sceneServiceAdd($mac.$addr);
                    if($addRes['code']!=0){
                        return $addRes;
                    }else{
                        $sceneId=$addRes['data'];
                    }
                }
            }else{
                //新增场景
                $addRes=self::sceneServiceAdd($mac.$addr);
                if($addRes['code']!=0){
                    return $addRes;
                }else{
                    $sceneId=$addRes['data'];
                }
            }

            $sceneTimerQuery=self::sceneTimerQuery($sceneId);
            if($sceneTimerQuery['code']==1){
                return $sceneTimerQuery;
            }
            foreach ($sceneTimerQuery['data']['sceneTimers'] as $key => $value) {
                self::sceneTimerDel($sceneId,$value['timerId']);
            }
            
            //新增场景中的设备线路(可多个线路地址)
            $chnlres=self::sceneServiceChnlAdd($sceneId,$mac,$addr);
            if($chnlres['code']!=0){
                return $chnlres;
            }
            //场景定时
            if(strtotime($start_time)<time()){
                $start_time=date('Y-m-d H:i:s');
            }
            if($status==1){
                //场景定时
                $resStart=self::sceneServiceTimeMod($sceneId,$start_time,"true");
                if($resStart['code']!=0){
                    return $resStart;
                }
                $resEnd=self::sceneServiceTimeMod($sceneId,$end_time,"false");
                if($resEnd['code']!=0){
                    return $resEnd;
                }
            }else{
                //场景定时
                $resStart=self::sceneServiceTimeMod($sceneId,$start_time,"false");
                if($resStart['code']!=0){
                    return $resStart;
                }
                $resEnd=self::sceneServiceTimeMod($sceneId,$end_time,"true");
                if($resEnd['code']!=0){
                    return $resEnd;
                }
            }
            return ['code'=>0,'msg'=>'定时成功'];
        }else{
            return ['code'=>1,'msg'=>$res['message']];
        }
        return $res;
    }
    public function getBoxchannelsOc($mac,$addr=0){

        $url=$this->api_router_url;
        $post['method']="GET_BOX_CHANNELS_OC";
        $post['mac']=$mac;
        if($addr){
            $post['addr']=$addr;
        }
        $post['projectCode']=$this->config->projectCode;
        $param=self::getParam($post);
        $res=self::httpRequest($url,"POST",$param);
        if($res['code']==0){
            return ['code'=>0,'msg'=>$res['message'],'data'=>$res['data']];
        }else{
            return ['code'=>1,'msg'=>$res['message']];
        }


    }
    //查询场景中的定时列表
    public function sceneTimerQuery($sceneId){
        $url=$this->api_router_url;
        $post['method']="SCENE_SERVICE";
        $post['cmd']='SCENE_TIMER_QUERY';
        $post['sceneId']=$sceneId;
        $post['projectCode']=$this->config->projectCode;
        $param=self::getParam($post);
        $res=self::httpRequest($url,"POST",$param);
        if($res['code']==0){
            return ['code'=>0,'msg'=>$res['message'],'data'=>$res['data']];
        }else{
            return ['code'=>1,'msg'=>$res['message']];
        }
    }  
    public function sceneTimerDel($sceneId='',$timesId=''){
        $url=$this->api_router_url;
        $post['method']="SCENE_SERVICE";
        $post['cmd']='SCENE_TIMER_DEL';
        $post['sceneId']=$sceneId;
        $post['timerId']=$timesId;
        $post['projectCode']=$this->config->projectCode;
        $param=self::getParam($post);
        $res=self::httpRequest($url,"POST",$param);
        if($res['code']==0){
            return ['code'=>0,'msg'=>$res['message'],'data'=>$res['data']];
        }else{
            return ['code'=>1,'msg'=>$res['message']];
        }
    }  
    //获取AccessToken
    public function getAccessToken(){
        if($this->QyAppKey==$this->config->appKey){
            $res=self::httpRequest($this->QyUrl);
            if(isset($res['code'])){
                if($res['code']==0){
                    return ['code'=>0,'data'=>$res['data']];
                }else{
                    return $res;
                }
            }else{
                return ['code'=>1,'msg'=>'公共服务获取令牌错误'];
            }
        }
        $access_token=Cache::get('MANDUN_TOEKN'.$this->config->appKey);
        if($access_token){
         return ['code'=>0,'data'=>$access_token];
        }
        $action="/oauth/token.as";
        $url=$this->api_url.$action;
        $resCode=self::getCode();
        if($resCode['code']!=0){
            return $resCode;
        }
        $post['client_id']=$this->config->appKey;
        $post['grant_type']="authorization_code";
        $post['redirect_uri']="http://open.snd02.com/demo.jsp";
        $post['code']=$resCode['data'];
        $post['client_secret']=md5($this->config->appKey.'authorization_code'.$post['redirect_uri'].$post['code'].$this->config->appSecret);
        $res=self::httpRequest($url,"POST",$post);
        if($res['code']==0){
            Cache::set('MANDUN_TOEKN'.$this->config->appKey,$res['data']['accessToken'],1800);
            return ['code'=>0,'data'=>$res['data']['accessToken']];
        }else{
            return ['code'=>1,'data'=>$res['message']];
        }
    }
    public function httpRequest($url="",$method="POST",$request=[],$header=["Content-Type: application/json","cache-control: no-cache"]){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt_array($curl, array(
          CURLOPT_URL => $url,
          CURLOPT_RETURNTRANSFER => true,
          CURLOPT_ENCODING => "",
          CURLOPT_MAXREDIRS => 10,
          CURLOPT_TIMEOUT => 30,
          CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
          CURLOPT_CUSTOMREQUEST => $method,
          CURLOPT_POSTFIELDS => json_encode($request),
          CURLOPT_HTTPHEADER => $header,
        ));
        $response = curl_exec($curl);
        $err = curl_error($curl);
        curl_close($curl);
        if ($err) {
          return ['code'=>1,'msg'=>"cURL Error #:" . $err];
        } else {
          return json_decode($response,1);
        }
    }
}