绿色建筑开发--各类传感器的接入

本次绿色建筑开发主要是对传感器的接入和数据处理:
传感器包括:风速、风向、温度、tvoc、二氧化碳、一氧化碳、PM0.3到PM100、光照,风力,危险气体等二十多种传感器进行接入

通信方式: 各个传感器使用5G模块,将信息通过TCP的方式传给服务端,modbos协议

过程

  1. 服务端在接收到数据后第一步进行CRC校验,验证数据的正确性
  2. 将16进制数据进行解析
  3. 解析后的数据分成两路,一路通过websocket发送给客户端用于显示实时数据,另外一路则进行数据库入库处理

代码附上

<?php

namespace app\worker\controller;

use GatewayClient\GatewayProtocol;
use think\worker\Server;
use GatewayClient\Gateway;
use Workerman\Connection\AsyncTcpConnection;
use Workerman\Lib\Timer;
use Workerman\Protocols\Ws;

date_default_timezone_set("PRC");

class Worker extends Server
{

    protected $socket = 'tcp://0.0.0.0:25001';

    protected $processes = 1;

    public $ws_server;

    protected static $heartbeat_time    =   30;


    /**
     * 收到信息
     * @param $connection
     * @param $data
     */
    public function onMessage($connection, $data)
    {
        $connection->lastMessageTime = time();

        //原始数据 16进制
        $array = getBytes($data);
        #十进制
        $dataStr = strToHex($data);

        #CRC校验码----start----
        $length = strlen($dataStr); // 获取字符串长度
        $subStrLength = $length - 4; // 计算需要截取的子字符串长度(不包括最后4位)
        $crc16_str = substr($dataStr, 0, $subStrLength); // 使用substr函数进行截取操作
        $crc16_end= substr($dataStr,-4);
        $crc16_str_pack = pack('H*',$crc16_str);
        $crc16_str_pack_t = crc16($crc16_str_pack);
        $crc16_str_crc16=unpack("H*",$crc16_str_pack_t);
        $crc16_end_cc = $crc16_str_crc16[1];//CRC校验码
        dump_log('收到消息了:'.json_encode($dataStr));
        dump_log('CRC校验码:'.json_encode($crc16_end_cc));
        #十六进制数组
        $array_16 = strToArray($dataStr);
        $device_id = substr($dataStr,0,2);
        $ws_data = '';
        #空气检测传感器 --已完成
        
        if ($array_16 && (hexdec($crc16_end) == hexdec($crc16_end_cc))){
            #序号---预留的参数
            $number = $array_16[0];
            $ch4 = hexdec($array_16[1]).hexdec($array_16[2]);
            $co = hexdec($array_16[3]).hexdec($array_16[4]);
            $o2 = hexdec($array_16[5]).hexdec($array_16[6]);
            $h2s = hexdec($array_16[7]).hexdec($array_16[8]);
            #温度数据
            $temperature = hexdec($array_16[9] . $array_16[10]);
            #湿度数据
            $humidity = hexdec($array_16[11] . $array_16[12]);
            #pm2.5
            $pm2_5 = hexdec($array_16[13] . $array_16[14]);
            #pm10
            $pm10 = hexdec($array_16[15] . $array_16[16]);

            $gas_data = $ws_data = [
                'ch4'         => $ch4,
                'co'          => $co,
                'o2'          => $o2,
                'h2s'         => $h2s,
                'temperature' => $temperature,
                'humidity'    => $humidity,
                'pm2_5'       => $pm2_5,
                'pm10'        => $pm10
            ];
            Workerbase::data_db($gas_data, $device_id);

        }elseif ($array_16 && (hexdec($crc16_end)!= hexdec($crc16_end_cc))){
            dump_log('CRC校验码错误');
        }else{
            dump_log('数据格式错误');
        }

        #转发websocket数据
        if ($ws_data){
            $ws_arr = [
                'code' => 1,
                'msg'  => 'ok',
                'time' => time(),
                'data' => $ws_data
            ];
            $this->ws_server->send(json_encode($ws_arr, 256) . "\r\n");
            dump_log("转发websocket成功!");
        }

        #回复消息
        $connection->lastMessageTime = time();
        $connection->send(json_encode('获得成功'));


    }

    /**
     * 当连接建立时触发的回调函数
     * @param $connection
     */
    public function onConnect($connection)
    {

        dump_log("连接 建立" . $connection->getRemoteIp() . ":". $connection->getRemotePort());
        $connection->send(json_encode('connect success'));
    }

    /**
     * 当连接断开时触发的回调函数
     * @param $connection
     */
    public function onClose($connection)
    {
        dump_log("连接 关闭");
        #断线1秒后重新连接
        $connection->reConnect(1);
    }

    /**
     * 当客户端的连接上发生错误时触发
     * @param $connection
     * @param $code
     * @param $msg
     */
    public function onError($connection, $code, $msg)
    {
        dump_log("错误: $code $msg");
    }

    /**
     * 每个进程启动
     * @param $worker
     */
    public function onWorkerStart($worker)
    {
        dump_log("TCP服务启动了");

        // 以websocket协议连接远程websocket服务器
//        $ws_connection = new AsyncTcpConnection("ws://127.0.0.1:22001");
        $ws_connection = new AsyncTcpConnection("ws://域名或IP:22001");
        $ws_connection->transport = 'ssl';
//        $ws_connection->websocketClientProtocol = 'binary';
        // 每隔55秒向服务端发送一个opcode为0x9的websocket心跳(可选)
        $ws_connection->websocketPingInterval = 30;
        // 远程websocket服务器发来消息时
        $ws_connection->onMessage = function($connection, $data){
            dump_log("来自websocket服务器的消息: $data");
        };
        // 连接上发生错误时,一般是连接远程websocket服务器失败错误(可选)
        $ws_connection->onError = function($connection, $code, $msg){
            dump_log("错误: $msg");
        };
        // 当连接远程websocket服务器的连接断开时(可选,建议加上重连)
        $ws_connection->onClose = function($connection){
            dump_log("连接已关闭并尝试重新连接");
            // 如果连接断开,1秒后重连
            $connection->reConnect(1);
        };
        // 设置好以上各种回调后,执行连接操作
        $ws_connection->connect();

        $this->ws_server =  $ws_connection;

        Timer::add(30, function()use($ws_connection){
            $ws_connection->send('来自tcp客户端的心跳:heartbeat---');
        });
    }

    /**
     * 重启进程
     * @param $worker
     * @return void
     */
    public function onWorkerReload($worker)
    {
        foreach($worker->connections as $connection)
        {
            $connection->send('worker reloading');
        }
    }
}

😊😊😊抱拳

  • 15
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

炼气三千年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值