modbustcp封裝使用獲取設備數據示例


//接受數據請求
public function client($pz){
    //參數1是:網絡協議,
    //AF_INET:     IPv4 網絡協議。TCP 和 UDP 都可使用此協議。一般都用這個,你懂的。
    //AF_INET6:    IPv6 網絡協議。TCP 和 UDP 都可使用此協議。
    //AF_UNIX:      本地通訊協議。具有高性能和低成本的 IPC(進程間通訊)。

    //參數2是:套接字流,選項有:
    //SOCK_STREAM  TCP 協議套接字。
    //SOCK_DGRAM   UDP協議套接字。

    //參數3:protocol協議,選項有:
    //SOL_TCP:  TCP 協議。
    //SOL_UDP:  UDP協議。
    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);



    //統一配置
    $xgcs=array(
        'surface'=>'equipment_config_'.$pz['surface'],//表名
    );
    $biao=db($xgcs['surface'])->where(array('id'=>1))->find();
    $xgcs=array(
        'identification'=>$pz['surface'],//唯一標識
        'ip'=>$biao['ip'],//ip地址
        'port'=>$biao['port'],//端口
        'surface'=>'equipment_config_'.$pz['surface'],//表名
    );
    //獲取數據字段表
    $data_cxzd=array(

        array('name'=>'tem_sub1_t3'),//二次供水溫度,513,3
        array('name'=>'tem_sub1_t4'),//二次回水溫度,516,3
        array('name'=>'pre_sub1_p3'),//二次供水壓力,507,3
        array('name'=>'pre_sub1_p4'),//二次回水壓力,508,3
        array('name'=>'pre_sub1_p1'),//一次供水壓力,505,3
        array('name'=>'pre_sub1_p2'),//一次回水壓力,506,3
        array('name'=>'valve_sub1_tcal'),//二次供水溫度設定值,519,3
        array('name'=>'tem_sub1_t1'),//一次供水溫度,511,3
        array('name'=>'tem_sub1_t2'),//一次回水溫度,512,3
        array('name'=>'tem_tout'),//室外溫度,517,3
        array('name'=>'valve_sub1_feedback'),//調節閥1閥位,518,3
        array('name'=>'valve_sub1_controlmode'),//控制方式,22,1

        array('name'=>'tem_sub1_t3hset'),//二次最大供水溫度,514,3
        array('name'=>'tem_sub1_t3lset'),//二次最小供水溫度,515,3
        array('name'=>'heatmeter_pri_power'),//總熱功率,834,3
        array('name'=>'heatmeter_pri_energy'),//總熱耗,836,3
        array('name'=>'heatmeter_pri_flow'),//一次側流量,830,3
        array('name'=>'cp_sub1_cp1frequency'),//循環泵1頻率,502,3
        array('name'=>'cp_sub1_cp2frequency'),//循環泵2頻率,490,3
        array('name'=>'heatmeter_sub1_flow'),//二次側流量,530,3
        array('name'=>'mp_sub1_mp1frequency'),//1號補水泵頻率反饋,504,3
        array('name'=>'mp_sub1_mp2frequency'),//2號補水泵頻率反饋,592,3
        array('name'=>'hmeter_ref_volume'),//補水累計流量,632,3
        array('name'=>'heatmeter_pri_volume'),//一次網累計流量,832,3
        array('name'=>'heatmeter_pri_flow'),//一次網瞬時流量,830,3



    );
    //獲取的數據
    $datas=array();

    //轉換參數(字段名、類型:bit則為線圈寄存器,其余則為保持寄存器、轉換參數、寄存器地址)
    $data_zhcs = db(\tname::register_relationship)->where(array('identification'=>$xgcs['identification']))->column('variable_name,variable_type,conversion_coefficient,register_address');
    //建立鏈接
    $con=socket_connect($socket,$xgcs['ip'],$xgcs['port']);


    foreach ($data_cxzd as $k_1 => $value) {
        //定義標識符
        //轉16進制
        $value['qian4']=dechex($k_1);
        //獲取長度
        $value['chang4']=strlen($value['qian4']);
        //判斷長度
        if($value['chang4']==1){
            $value['zu1_5']='00 0'.$value['qian4'];
        }elseif($value['chang4']==2){
            $value['zu1_5']='00 '.$value['qian4'];
        }elseif($value['chang4']==3){
            $value['zu1_5']='0'.substr($value['qian4'],0,1).' '.substr($value['qian4'],1,2);
        }elseif($value['chang4']==4){
            $value['zu1_5']=substr($value['qian4'],0,2).' '.substr($value['qian4'],2,2);
        }
        $value['zu6_21']=' 00 00 00 06 15 ';
        //類型獲取bit為線圈寄存器,其余為保持寄存器
        $value['type']=$data_zhcs[$value['name']]['variable_type'];
        if($value['type']=='bit'){
            $value['zu22_23']='01';
        }else{
            $value['zu22_23']='03';
        }
        //獲取10進制的寄存器
        $value['jcq_10']=$data_zhcs[$value['name']]['register_address']-1;
        //轉16進制的寄存器
        $value['jcq_16']=dechex($value['jcq_10']);
        //獲取16進制的寄存器長度
        $value['chang_jcq']=strlen($value['jcq_16']);
        //判斷16進制的寄存器長度
        if($value['chang_jcq']==1){
            $value['zu24_29']=' 00 0'.$value['jcq_16'];
        }elseif($value['chang_jcq']==2){
            $value['zu24_29']=' 00 '.$value['jcq_16'];
        }elseif($value['chang_jcq']==3){
            $value['zu24_29']=' 0'.substr($value['jcq_16'],0,1).' '.substr($value['jcq_16'],1,2);
        }elseif($value['chang_jcq']==4){
            $value['zu24_29']=' '.substr($value['jcq_16'],0,2).' '.substr($value['jcq_16'],2,2);
        }
        //獲取個數(這個基本不會改變,如若改變則接收要全改)
        //判斷是32位的變為02
        if($value['type']=='int32'){
            $value['zu30_35']=' 00 02';
        }else{
            $value['zu30_35']=' 00 01';
        }
        $value['zu']=$value['zu1_5'].$value['zu6_21'].$value['zu22_23'].$value['zu24_29'].$value['zu30_35'];
        $sendStrArray[$k_1] = str_split(str_replace(' ', '', $value['zu']), 2);  // 將16進制數據轉換成兩個一組的數組
        for ($j = 0; $j < count($sendStrArray[$k_1]); $j++) {

            socket_write($socket, chr(hexdec($sendStrArray[$k_1][$j])));  // 逐組數據發送
        }
        $receiveStr[$k_1] = "";
        $receiveStr[$k_1] = socket_read($socket, 1024, PHP_BINARY_READ);  // 采用2進制方式接收數據
        $receiveStrHex[$k_1] = bin2hex($receiveStr[$k_1]);  // 將2進制數據轉換成16進制
        //響應狀態
        $value['xyzt']=substr($receiveStrHex[$k_1],14,2);
        //如果返回成功
        if($value['xyzt']==$value['zu22_23']){
            //返回參數(16進制)
            $value['fhcs_16']=substr($receiveStrHex[$k_1],18);//截取數據
            //轉為10進制
            $value['fhcs_10']=hexdec($value['fhcs_16']);
            //進行換算
            $value['value']=$value['fhcs_10']*$data_zhcs[$value['name']]['conversion_coefficient'];
            //鍵入到修改數組
            $datas[$value['name']]=$value['value'];
        }
    }

    //斷開鏈接
    socket_shutdown($socket);
    socket_close($socket);
    $cc=db($xgcs['surface'])->where(array('id'=>1))->update($datas);
    return $datas;
    if($cc){
        return 1;
    }else{
        return 0;
    }



}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM