1. 程式人生 > >modbustcp封裝使用獲取設備數據示例

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

標識 ont 控制 個數 ria 接受 接收數據 通訊協議 fig

//接受數據請求
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;
}



}

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