modbustcp封装使用获取设备数据示例

news/2024/7/20 1:23:25 标签: 小程序, 公众号

//接受数据请求
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;
    }



}

 


http://www.niftyadmin.cn/n/563940.html

相关文章

Vue----品牌列表案例

效果图 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><!-- 最新版…

服务器超时设置_小程序_和智聚成网络

本文介绍nginx出现504 Gateway Time-out问题的原因&#xff0c;分析问题并提供解决方法。 (主要看2) 1.问题分析 nginx访问出现504 Gateway Time-out&#xff0c;一般是由于程序执行时间过长导致响应超时&#xff0c;例如程序需要执行90秒&#xff0c;而nginx最大响应等待时间…

VUE学习笔记--过滤器

文章目录过滤器过滤器实例私有过滤器和全局过滤器过滤器注意点时间格式化连续调用多个过滤器过滤器的兼容性过滤器 过滤器实例 将英文字符串的第一个字母转为大写 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"…

PHP异步进程async-helper实例详解

PHP异步进程async-helper实例详解 PHP 的异步进程助手&#xff0c;借助于 AMQP 实现异步执行 PHP 的方法&#xff0c;将一些很耗时、追求高可用、需要重试机制的操作放到异步进程中去执行&#xff0c;将你的 HTTP 服务从繁重的业务逻辑中解脱出来。以一个较低的成本将传统 PHP…

VUE学习笔记--侦听器

文章目录watch侦听器侦听器注意点对象格式的侦听器深度侦听watch侦听器 watch侦听器允许开发者监视数据的变化&#xff0c;从而针对数据的变化做特定的操作 语法格式&#xff1a; const v new Vue({el: "#app",data: {username: },watch: {//监听username的变化// …

云锁卸载

Wdcp后台卸载云锁&#xff0c;或者卸载云锁再次安装&#xff0c;会出现以下两种情况报错: 错&#xff0c;是因为之前已经在wdcp面板安装过云锁&#xff0c;再次手动安装提示已经安装&#xff1b; 解决方法&#xff1a; 1.如果已经安装云锁&#xff0c;并且云锁的主进程都在&a…

洛谷刷题题解笔记----UVA11292 Dragon of Loowater

目录题目链接解题思路解题代码题目链接 题目链接 解题思路 每组输入后对龙脖子的直径和骑士的能力值进行从小到大排序&#xff0c;外加一个判断数组判断该骑士是否被雇佣 然后遍历每个龙&#xff0c;看没有雇佣过的骑士是否可以杀死&#xff0c;因为已经从小到大排序&#x…

深入了解直播

视频直播的流程可以分为如下几步&#xff1a; 采集 —>处理—>编码和封装—>推流到服务器—>服务器流分发—>播放器流播放 1.采集 采集是整个视频推流过程中的第一个环节&#xff0c;它从系统的采集设备中获取原始视频数据&#xff0c;将其输出到下一个环节。…