<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          php workerman對接部標808協(xié)議

          共 18018字,需瀏覽 37分鐘

           ·

          2021-08-12 03:55

          公司業(yè)務需求,這幾天一直對著機器對接,整理出以下算法,實現(xiàn)對設備的交互。


          服務端:

          <?phpnamespace app\server\controller;use Workerman\Worker;use Workerman\Lib\Timer;use Workerman\Connection\AsyncTcpConnection;use app\server\controller\JT808;use think\Db;$socket = new Worker('websocket://0.0.0.0:2346');// 設置transport開啟ssl,websocket+ssl即wss//$socket->transport = 'ssl';// 啟動1個進程對外提供服務$socket->count = 1;global $tcp;//下面換成自己的端口   $tcp = new Worker('tcp://0.0.0.0:1234');
          $tcp->onMessage = function($connection, $data)use($tcp) { $JT808 = new JT808(); //16進制數(shù)據(jù) $data16Arrays = $JT808->getTo16Bytes($data); //var_dump($data16Arrays); foreach ($data16Arrays as $key => $data16Array) { //獲取消息id $MessageId = $JT808->getMessageIdNumber($data16Array); //設備號 $equipmentNumber = $JT808->getEquipmentNumber($data16Array); $equipmentNumber = '86339'.substr($equipmentNumber, 2); //位置信息上報獲取 if ($MessageId == '0200' && $equipmentNumber) { //報警信息 $AlarmMessage = $JT808->getAlarmMessage($data16Array, 13); //狀態(tài) $status = $JT808->getPositionStatus($data16Array, 17); //經(jīng)度 $Latitude = $JT808->getLatitude($data16Array, 21, 'f'); //緯度 $Longitude = $JT808->getLongitude($data16Array, 25, 'f'); //高度 $Height = $JT808->getHeight($data16Array, 29); //速度 $Speed = $JT808->getSpeed($data16Array, 31); //方向 $Direction = $JT808->getDirection($data16Array, 33); //時間 $Datetime = $JT808->getDatetime($data16Array, 35); if ($Latitude && $Longitude) { //執(zhí)行你的邏輯 var_dump($Latitude); var_dump($Longitude); } } //發(fā)送給客戶端 $sendClientData = $JT808->getVerifyNumberArray($data16Array); $connection->send($sendClientData); } };

          // 運行workerWorker::runAll();


          JT808.php

          數(shù)據(jù)解析算法

          <?phpnamespace app\server\controller;class JT808 {  public static $sequenceNumber = 0; //流水號初始值  /**   * description  轉成10進制字符串數(shù)組   * @param $string 16進制字符串   * @return array   10進制數(shù)組   */  public function get10Bytes($string) {    $bytes = array();    $len = strlen($string);    for ($i = 0; $i < $len; $i++) {      array_push($bytes, ord($string[$i]));    }    return $bytes;  }
          /** * description 10進制字符串數(shù)組轉成16進制字符串數(shù)組 * @param $data 10進制字符串數(shù)組 * @return mixed 16進制字符串數(shù)組 */ public function getTo16Bytes($data) { //$get10Bytes = $this->get10Bytes($data); $content = bin2hex($data); $res = explode('7e7e', $content); $array = []; //解決粘包 if (count($res) > 1) { foreach ($res as $k => $v) { if ($k == reset($res)) { $array[$k] = str_split($v . '7e', 2); } else if ($k == end($res)) { $array[$k] = str_split('7e' . $v, 2); } else { $array[$k] = str_split('7e' . $v . '7e', 2); } } } else { $array[] = str_split($res[0], 2); } return $array;
          /*$array = []; foreach ($get10Bytes as $k => $v) { $array[$k] = base_convert($v, 10, 16); } */ //return $array; }
          /** * description 接受到的16進制字符補0 例如:01=>0x01 * @param $data 16進制數(shù)組 * @return array 補0之后的16進制數(shù)組 */ public function supplementZero($data) { $len = count($data); $res = []; for ($j = 0; $j < $len; $j++) { if (strlen($data[$j]) == 1) { $res[$j] = "0x" . "0" . $data[$j]; } else { $res[$j] = "0x" . $data[$j]; } } return $res; }
          /** * description 把一個4位的數(shù)組轉化位整形 * @param array 接受數(shù)組 * @return int 返回int */ public function bytesToInt($data) { $res = []; foreach ($data as $k => $v) { $res[$k] = intval(base_convert($v, 16, 10)); } $temp0 = $res[0] & 0xFF; $temp1 = $res[1] & 0xFF; $temp2 = $res[2] & 0xFF; $temp3 = $res[3] & 0xFF; return (($temp0 << 24) + ($temp1 << 16) + ($temp2 << 8) + $temp3); }
          /** * description BCD碼轉字符串 * @param array 數(shù)組 * @return bool|string 返回字符串 */ public function bcdToString($data) { $len = count($data); $temp = ""; for ($i = 0; $i < $len; $i++) { // 高四位 $temp .= (($data[$i] & 0xf0) >> 4); // 低四位 $temp .= ($data[$i] & 0x0f); } return (substr($temp, 0, 1) == 0) ? substr($temp, 1) : $temp; }
          /** * description 從接受到的16進制數(shù)組中獲取設備號數(shù)組 * @param $data 接受到的16進制數(shù)組 * @return string 設備號id */ public function getSensorId($data) { $sensorArray = array_slice($data, 3, 6); $sensorArrayZero = $this->supplementZero($sensorArray); $res = []; foreach ($sensorArrayZero as $k => $v) { $res[$k] = intval(base_convert($v, 16, 10)); } $string = $this->bcdToString($res); return $string; }
          /** * description 把一個二字節(jié)數(shù)組轉化成整型 * @param $data 二字節(jié)數(shù)組 * @return int 整型 */ public function twoBytesToInteger($data) { $res = []; foreach ($data as $k => $v) { $res[$k] = intval(base_convert($v, 16, 10)); } $temp0 = $res[0] & 0xFF; $temp1 = $res[1] & 0xFF; return (($temp0 << 8) + $temp1); }
          /** * description 接受內容中4字節(jié)數(shù)組轉成int * @param $data 16進制字節(jié)數(shù)組 * @param int $a 開始位 * @return int int值 */ public function getNum($data, $a = 0) { $numArray = array_slice($data, $a, 4); $res = $this->bytesToInt($numArray); return $res; }
          /** * description 按位異或 * @param $data * @return int */ public function getEveryXor($data) { $len = count($data); $rew = 0; for ($i = 1; $i < $len; $i++) { $rew = $rew ^ $data[$i]; } return $rew; } /** * [checkCode 生成驗證碼帶開頭7e] * @author [email protected] * @DateTime 2020-05-01T00:19:06+0800 * @param [array] $data [數(shù)組] * @return [array] [返回2位數(shù)數(shù)組] */ public function checkCode($data) { $sum = 0; //去掉開頭的7e unset($data[0]); //for ($i = 0; $i < count($arr); $i++) { foreach ($data as $k => $v) { $sum = $sum ^ hexdec($v); } return str_pad(dechex($sum), 2, "0", STR_PAD_LEFT); } /** * description 將字節(jié)數(shù)組轉為字符串 * @param array 字節(jié)數(shù)組 * @return string 返回字符串 */ public function bytesArrayToString($data) { $str = ''; foreach ($data as $ch) { $str .= chr($ch); } return $str; } /** * [arrayToBytes 返回二進制內容] * @author [email protected] * @DateTime 2020-05-01T00:34:33+0800 * @param [type] $data [數(shù)組] * @return [type] [二進制內容] */ public function arrayToBytes($data) { $ret = implode($data); return hex2bin($ret); } /** * description 拼接字符串 * @param $str * @param int $n * @param string $char * @return string */ public function getTurnStr($str, $n = 1, $char = '0') { for ($i = 0; $i < $n; $i++) { $str = $char . $str; } return $str;
          //return str_pad($str, $n, $char, STR_PAD_LEFT); }
          /** * description 轉成二進制字符串 * @param $data array 16進制數(shù)組 * @return string 字符串 */ public function getTwoStr($data) { //轉成2進制 $str = array(); $req = array(); foreach ($data as $key => $value) { $str[$key] = base_convert($data[$key], 16, 2); $leng = 8 - strlen($str[$key]); $req[] = $this->getTurnStr($str[$key], $leng, "0"); } //拼接字符串 $rtq = implode("", $req); return $rtq; } /** * description 獲取設備號 * @param $data array 16進制數(shù)組 * @param $length num 補全長度 * @return bool|string 返回字符串設備號 */ public function getEquipmentNumber($data, $length = 12) { $equipmentArray = array_slice($data, 5, 6); $res = []; foreach ($equipmentArray as $k => $v) { $res[$k] = base_convert($v, 16, 10); } $equipmentNumber = $this->bcdToString($res); return str_pad($equipmentNumber, $length, "0", STR_PAD_LEFT); } /** * description 獲取16進制數(shù)組來計算出設備號 * @param $data 16進制數(shù)組 * @return array 返回設備號數(shù)組 */ public function getEquipmentNumberArray($data) { $num_array = array_slice($data, 5, 6); /*$res = []; foreach ($num_array as $k => $v) { $res[$k] = base_convert($v, 16, 10); } */ return $num_array; } /** * description 獲取報警信息 * @param $data array 16進制數(shù)組 * @param $index 數(shù)組索引13 * @return int 返回數(shù)字代表報警信息 */ public function getAlarmMessage($data, $index, $type = false) { $alarmArray = $this->getTwoStr(array_slice($data, $index, 4)); if ($type == true) { if (substr($alarmArray, -8, 1) == 1) { //主電源斷電 $alarm = "主電源斷電"; } elseif (substr($alarmArray, -30, 1) == 1) { //碰撞預警 $alarm = "碰撞預警"; } elseif (substr($alarmArray, -31, 1) == 1) { //側翻預警 $alarm = "側翻預警"; }// elseif (substr($alarmArray, -26, 1) == 1) { // //脫落(光感)報警 // $alarm = 4; // } else { //正常 $alarm = "一切正常"; } } // return $alarm; return $alarmArray; }
          /** * description 獲取狀態(tài)信息 * @param $data array 16進制數(shù)組 * @param $index 數(shù)組索引 * @param $type 返回數(shù)據(jù)還是原本信息 * @return array 狀態(tài)信息數(shù)組 */ public function getPositionStatus($data, $index, $type = false) { $positionArray = $this->getTwoStr(array_slice($data, $index, 4)); if ($type == true) { //判斷是否定位,0定位,1未定位 $isPosition = substr($positionArray, -2, 1) == 0 ? $isPosition = "未定位" : $isPosition = "定位"; //判斷南北緯,0北緯,1南緯 $isNorSou = substr($positionArray, -3, 1) == 0 ? $isNorSou = "北緯" : $isNorSou = "南緯"; //判斷東西經(jīng),0東經(jīng),1西經(jīng) $isEasWes = substr($positionArray, -4, 1) == 0 ? $isEasWes = "東經(jīng)" : $isEasWes = "西經(jīng)"; //判斷定位方式 if (substr($positionArray, -19, 1) == 1 && substr($positionArray, -20, 1) == 0) { //北斗定位 $positionMethod = "北斗定位"; } elseif (substr($positionArray, -19, 1) == 0 && substr($positionArray, -20, 1) == 1) { //GPS定位 $positionMethod = "GPS定位"; } elseif (substr($positionArray, -19, 1) == 1 && substr($positionArray, -20, 1) == 1) { //北斗GPS雙定位 $positionMethod = "北斗GPS雙定位"; } else { //北斗GPS都未定位 $positionMethod = "北斗GPS都未定位"; } $positionStatusArray = array( 'position' => $isPosition, 'ns' => $isNorSou, 'ew' => $isEasWes, 'gps' => $positionMethod, ); return $positionStatusArray; } else { return $positionArray; } }
          /** * description 獲取緯度 * @param $data array 16進制數(shù)組 * @param $index 數(shù)組索引 * @param $type 返回字符類型 i整形 f浮點形 * @return float|int 緯度 */ public function getLatitude($data, $index, $type = 'f') { $latitudeBytes = array_slice($data, $index, 4); $latitude = $this->bytesToInt($latitudeBytes); if ($type == 'f') { $number = $latitude / pow(10, 6); } if ($type == 'i') { $number = $latitude; } return $number; }
          /** * description 獲取經(jīng)度 * @param $data array 16進制數(shù)組 * @param $index 數(shù)組索引 * @param $type 返回字符類型 i整形 f浮點形 * @return float|int 經(jīng)度 */ public function getLongitude($data, $index, $type = 'f') { $longitudeBytes = array_slice($data, $index, 4); $longitude = $this->bytesToInt($longitudeBytes); if ($type == 'f') { $number = $longitude / pow(10, 6); } if ($type == 'i') { $number = $longitude; } return $number; } /** * [getHeight 獲取高度] * @author [email protected] * @DateTime 2020-04-30T14:12:30+0800 * @param [type] $data [16進制數(shù)組] * @param [type] $index [數(shù)組索引29] * @return [type] [高度] */ public function getHeight($data, $index) { $heightBytes = array_slice($data, $index, 2); $height = $this->twoBytesToInteger($heightBytes); return $height; } /** * [getSpeed 獲取速度] * @author [email protected] * @DateTime 2020-04-30T14:14:55+0800 * @param [type] $data [16進制數(shù)組] * @param [type] $index [數(shù)組索引31] * @return [type] [速度] */ public function getSpeed($data, $index) { $speedBytes = array_slice($data, $index, 2); $speed = $this->twoBytesToInteger($speedBytes); return $speed; } /** * [getDirection 獲取方向] * @author [email protected] * @DateTime 2020-04-30T14:15:33+0800 * @param [type] $data [16進制數(shù)組] * @param [type] $index [數(shù)組索引33] * @return [type] [方向] */ public function getDirection($data, $index) { $directionBytes = array_slice($data, $index, 2); $direction = $this->twoBytesToInteger($directionBytes); return $direction; } /** * description 獲取日期時間 * @param $data array 16進制數(shù)組 * @param $index 數(shù)組索引35 * @return string 日期時間字符串 */ public function getDatetime($data, $index) { $datetimeArray = array_slice($data, $index, 6); $res = []; foreach ($datetimeArray as $k => $v) { $res[$k] = base_convert($v, 16, 10); } $datetime = $this->bcdToString($res); $datetimeStr = "20" . substr($datetime, 0, 2) . "-" . substr($datetime, 2, 2) . "-" . substr($datetime, 4, 2) . " " . substr($datetime, 6, 2) . ":" . substr($datetime, 8, 2) . ":" . substr($datetime, 10, 2); return $datetimeStr; }
          /** * description 獲取平臺流水號 * @return array 返回流水號數(shù)組 */ public function getSequenceNumberArray() { //計算流水號 $number = $this->$sequenceNumber++; if ($number > 65025) { // 255 * 255 -1 $number = 1; } //將十進制流水號換算成16進制流水號 $get16Number = base_convert($number, 10, 16); $af = substr($get16Number, 0, 2); $bf = substr($get16Number, 2); $systemNumber = []; //判斷 if ($number > 0xff) { $systemNumber = array('0x' . $af, '0x' . $bf); } else { $systemNumber = array('0x00', '0x' . $get16Number); } foreach ($systemNumber as $k => $v) { $systemNumber[$k] = intval(base_convert($v, 16, 10)); } return $systemNumber; }
          /** * description 獲取消息流水號 * @param $data 16進制數(shù)組 * @return array 消息流水號數(shù)組 */ public function getMessageNumberArray($data) { $messageNumber = array_slice($data, 11, 2); //$messageNumber = $this->supplementZero($messageNumber); return $messageNumber; }
          /** * description 獲取消息id * @param $data 16進制數(shù)組 * @return array 消息id數(shù)組 */ public function getMessageIdArray($data) { $messageId = array_slice($data, 1, 2); //$messageId = $this->supplementZero($messageId); return $messageId; } /** * description 獲取消息id * @param $data array 16進制數(shù)組 * @param $length num 消息體長度 前位補0 * @return bool|string 消息id字符串 */ public function getMessageIdNumber($data, $length = 4) { $messageArray = array_slice($data, 1, 2); $res = []; foreach ($messageArray as $k => $v) { $res[$k] = base_convert($v, 16, 10); } $messageNumber = $this->bcdToString($res); return str_pad($messageNumber, $length, "0", STR_PAD_LEFT); } /** * description 獲取消息體 * @param $data 16進制數(shù)組 * @return array 消息體數(shù)組 */ public function getMessageBodyArray($data) { //消息體 = 消息流水號 + 消息id $messageNumber = $this->getMessageNumberArray($data); //$messageId = $this->getMessageIdArray($data); //$messageBody = array_merge($messageNumber, $messageId); /*foreach ($messageBody as $k => $v) { $res[$k] = intval(base_convert($v, 16, 10)); } */ return $messageNumber; }
          /** * description 發(fā)送給客戶端的回傳數(shù)據(jù) * @param $data 16進制數(shù)組 * @return string 返回客戶端字符串 */ public function getVerifyNumberArray($data, $auth = '31313131') { //數(shù)組開始五位 //$arrayStartFiveBytes = array('7E', '80', '01'); //注冊應答結果0 $ret = array('00'); //消息ID $messageId = $this->getMessageIdArray($data); $messageid = implode($messageId); //消息體 $messageBody = $this->getMessageBodyArray($data); if ($messageid == '0100') { $arrayStartFiveBytes = array('7E', '81', '00'); $jianquan = str_split($auth, 2); $messageBody = array_merge($messageBody, $ret, $jianquan); } else { $arrayStartFiveBytes = array('7E', '80', '01'); $jianquan = []; $messageBody = array_merge($messageBody, $messageId, $ret, $jianquan); } //設備號 $equipmentNumber = $this->getEquipmentNumberArray($data); //平臺流水號 //$systemNumber = $this->getSequenceNumberArray(); $systemNumbers = $this->getMessageNumberArray($data); //消息體長度 /*if ($messageid == '0100') { $msglength = count(array_merge($systemNumbers, $messageId, $ret, $jianquan)); } else { $msglength = count(array_merge($systemNumbers, $messageId, $ret)); }*/ if($messageid == '0100'){ $msglength = count(array_merge($jianquan))+3; }else{ $msglength = count(array_merge($systemNumbers, $messageId, $ret)); } $msglength = decbin($msglength); //補齊16位,不加密,無版本號 $attr = sprintf("%016d", $msglength); //消息體屬性 //前置補0 $attr_str = str_pad(dechex(bindec($attr)), 4, '0', STR_PAD_LEFT); //$attr_str = dechex(bindec($attr)); //分割字符 $attrarray = str_split($attr_str, 2); //與消息體合并 $array_attr = array_merge($arrayStartFiveBytes, $attrarray); //數(shù)組開始5位和設備號合并 $arrayStartAndEquipmentNumber = array_merge($array_attr, $equipmentNumber); //接上一步繼續(xù)與平臺流水號合并 $startEquipmentAndSystemNumber = array_merge($arrayStartAndEquipmentNumber, $systemNumbers); //接上一步繼續(xù)與消息體合并 $startEquipmentSystemAndMessageBody = array_merge($startEquipmentAndSystemNumber, $messageBody); //接上一步應答結果 //$dataAndRet = array_merge($startEquipmentSystemAndMessageBody, $ret); $dataAndRet = $startEquipmentSystemAndMessageBody; //生成校驗碼 ////$dataAndRetXor = $this->getEveryXor($dataAndRet); $dataAndRetXor = $this->checkCode($dataAndRet); ////var_dump($dataAndRetXor); //數(shù)組末尾兩位 $arrayEndTwoBytes = array($dataAndRetXor, '7E'); //整個數(shù)組 $completeArray = array_merge($dataAndRet, $arrayEndTwoBytes); //發(fā)送給客戶端的字符串 $sendClientStr = $this->arrayToBytes($completeArray);
          return $sendClientStr; }}?>


          可以根據(jù)自己的需求去更改部分算法



          瀏覽 129
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  www.一级片 | 欧美午夜爱爱视频 | 亚洲黄色小电影 | 国产白丝精品91 | 四虎久久 |