SouhuanAnalysis.php 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161
  1. <?php
  2. namespace app\common\server;
  3. use app\common\model\Devicelistmodel;
  4. use app\common\model\FacilityModel;
  5. use app\common\model\ShalarmlistModel;
  6. use app\common\model\ShinfoModel;
  7. use app\common\model\ShreceivequeueModel;
  8. use app\common\model\ShreceiveredocdeModel;
  9. use app\common\model\ShsendlistModel;
  10. use app\common\model\ShsendqueueModel;
  11. use think\facade\Log;
  12. /**
  13. * 手环字符串解析
  14. * 解析命令 发送命令
  15. *
  16. * @author wj
  17. * @date 2023-08-11
  18. */
  19. class SouhuanAnalysis
  20. {
  21. /**
  22. * 校验长度
  23. *
  24. * @return void
  25. * @author wj
  26. * @date 2023-08-11
  27. */
  28. public function checklen($len, $str)
  29. {
  30. $strlen = mb_strlen($str);
  31. if ($len != $strlen) {
  32. Log::write("长度校验失败: len:" . $len . " str:" . $str, 'shouhuan');
  33. return false;
  34. }
  35. return true;
  36. }
  37. /**
  38. * 获取信息 整个信息解析
  39. * 并验证是否可解析 无解析命令配置 不报错
  40. *
  41. * @return void
  42. * @author wj
  43. * @date 2023-08-11
  44. */
  45. public function getline($str, $field = null, $checkconfig = true)
  46. {
  47. //[厂商*设备 ID*内容长度*内容]
  48. $preg = "/^\[(.*)\*(.*)\*(.*)\*(.*)\]$/";
  49. preg_match($preg, $str, $match);
  50. if (empty($match)) {
  51. Log::write("解析失败:" . $str, 'shouhuan');
  52. throw new \Exception('解析失败:' . $str);
  53. }
  54. unset($match[0]);
  55. $data = array_values($match);
  56. $sandom_string = $data[0]; //厂商 随机字符串
  57. $device_id_code = $data[1]; //设置id编码
  58. $content_len = $data[2]; //内容长度
  59. $content_str = $data[3]; //内容字符串
  60. $content_len = $this->analysislen($content_len);
  61. $result = $this->checklen($content_len, $content_str);
  62. if (empty($result)) {
  63. $errmsg = '内容位数错误';
  64. Log::write($errmsg . ":" . $str, 'shouhuan');
  65. throw new \Exception($errmsg);
  66. }
  67. //验证设备状态
  68. $fid = $this->getfacilityid($device_id_code);
  69. if ($fid) {
  70. //改设备接收信息时间
  71. $time = date('Y-m-d H:i:s');
  72. $shupdateData = ['receive_time' => $time];
  73. $shupdateWhere = ['facility_id' => $fid];
  74. $m_sh = new ShinfoModel();
  75. $row = $m_sh->updateinfo($shupdateWhere, $shupdateData);
  76. if (empty($row)) {
  77. $errmsg = '设备:' . $device_id_code . " receive_time 修改失败";
  78. Log::write($errmsg, 'shouhuan');
  79. }
  80. }
  81. $data = [
  82. 'device_id_code' => $device_id_code,
  83. 'content_len' => $content_len,
  84. 'content_str' => $content_str,
  85. ];
  86. $contentarr = $this->getcommandcontent($content_str);
  87. $command = $contentarr['command'];
  88. $data['command'] = $command;
  89. $data['content_arr'] = $contentarr['content'];
  90. if ($checkconfig) {
  91. $config = $this->getreceivecommandinfo($command);
  92. $data['config'] = $config;
  93. if (!$config) {
  94. $errmsg = '命令无解析配置 command:' . $command;
  95. Log::write($errmsg, 'shouhuan');
  96. //return false;
  97. }
  98. //else {
  99. // $data['config'] = [];
  100. // }
  101. }
  102. if (isset($field)) {
  103. return $data[$field];
  104. }
  105. return $data;
  106. }
  107. /**
  108. * 解析UD命令
  109. *
  110. * @param [type] $str
  111. * @return void
  112. * @author wj
  113. * @date 2023-08-23
  114. */
  115. public function getmacforUD($str, $device_id_code)
  116. {
  117. Log::write($str, 'shouhuan');
  118. $data = explode(",", $str);
  119. $is_gps = $data[3];
  120. $is_success = false;
  121. $accesstype = -1;
  122. $apikey = "67019de565fb4aa2a0e101b70ae3fd91";
  123. if ('V' == $is_gps) {
  124. $jzcount = $data['17'];
  125. $jzlist = [];
  126. $mcc = $data['19'];
  127. $mnc = $data['20'];
  128. $jzindex = 21;
  129. for ($i = 0; $i < $jzcount; $i++) {
  130. $item = [
  131. 'area_code' => $data[$jzindex],
  132. 'jz_code' => $data[$jzindex + 1],
  133. 'signal_strength' => $data[$jzindex + 2],
  134. ];
  135. $jzindex += 3;
  136. $jzlist[] = $item;
  137. }
  138. $wificount = $data[$jzindex];
  139. $wifiindex = $jzindex + 1;
  140. $wifilist = [];
  141. for ($i = 0; $i < $wificount; $i++) {
  142. $item = [
  143. 'name' => $data[$wifiindex],
  144. 'mac' => $data[$wifiindex + 1],
  145. 'signal_strength' => $data[$wifiindex + 2],
  146. ];
  147. $wifiindex += 3;
  148. $wifilist[] = $item;
  149. }
  150. $bts = "";
  151. $nearbts_arr = [];
  152. $nearbts = "";
  153. $macs_arr = [];
  154. $macs = "";
  155. foreach ($jzlist as $key => $value) {
  156. if ($key === 0) {
  157. $bts = $mcc . "," . $mnc . "," . $value['area_code'] . "," . $value['jz_code'] . "," . $value['signal_strength'];
  158. } else {
  159. $nearbts_arr[] = $mcc . "," . $mnc . "," . $value['area_code'] . "," . $value['jz_code'] . "," . $value['signal_strength'];
  160. }
  161. }
  162. $nearbts = join("|", $nearbts_arr);
  163. foreach ($wifilist as $key => $value) {
  164. $macs_arr[] = $value['mac'] . "," . $value['signal_strength'];
  165. }
  166. $macs = join("|", $macs_arr);
  167. $accesstype = 1;
  168. $url = "http://apilocate.amap.com/position?macs=" . $macs . "&bts=" . $bts . "&nearbts=" . $nearbts . "&network=GSM&cdma=0&accesstype=" . $accesstype . "&output=json&key=" . $apikey;
  169. Log::write($url, 'shouhuan');
  170. $result = curl_request($url);
  171. Log::write($result, 'shouhuan');
  172. if ('10000' === $result['infocode']) {
  173. $resultdata = $result['result'];
  174. if (isset($resultdata['location'])) {
  175. $locations = explode(",", $resultdata['location']);
  176. $use_gps_long = $locations[0];
  177. $use_gps_lat = $locations[1];
  178. $address_desc = $resultdata['desc'];
  179. $accesstype = 2;
  180. $is_success = true;
  181. }else{
  182. Log::write($url, 'shouhuan');
  183. Log::write($result, 'shouhuan');
  184. $accesstype = -2;
  185. }
  186. } else {
  187. Log::write($url, 'shouhuan');
  188. Log::write($result, 'shouhuan');
  189. $accesstype = -2;
  190. }
  191. }
  192. if (!$is_success) {
  193. $use_gps_long = $data[6];
  194. $use_gps_lat = $data[4];
  195. $gps_str = $use_gps_long . "," . $use_gps_lat;
  196. $url = "https://restapi.amap.com/v3/assistant/coordinate/convert?locations=" . $gps_str . "&coordsys=gps&output=JSON&key=" . $apikey;
  197. $result = curl_request($url);
  198. Log::write($url, 'shouhuan');
  199. Log::write($result, 'shouhuan');
  200. if ('10000' == $result['infocode']) {
  201. $locations = $result['locations'];
  202. $url = "https://restapi.amap.com/v3/geocode/regeo?location=" . $locations . "&key=" . $apikey;
  203. $result = curl_request($url);
  204. Log::write($url, 'shouhuan');
  205. Log::write($result, 'shouhuan');
  206. if ('10000' == $result['infocode']) {
  207. $address_desc = $result['regeocode']['formatted_address'];
  208. $is_success = true;
  209. $accesstype = 0; //未接入智能硬件定位
  210. } else {
  211. Log::write($url, 'shouhuan');
  212. Log::write($result, 'shouhuan');
  213. }
  214. } else {
  215. Log::write($url, 'shouhuan');
  216. Log::write($result, 'shouhuan');
  217. }
  218. }
  219. if (!$is_success) {
  220. $accesstype = -2;
  221. $use_gps_long = $data[6];
  222. $use_gps_lat = $data[4];
  223. $address_desc = "";
  224. }
  225. $data = [
  226. 'is_gps' => $is_gps == "A" ? 1 : 0,
  227. 'address_desc' => $address_desc,
  228. 'accesstype' => $accesstype,
  229. 'use_gps_long' => $use_gps_long,
  230. 'use_gps_lat' => $use_gps_lat,
  231. ];
  232. return $data;
  233. }
  234. /**
  235. * 内容解析
  236. *
  237. * @param [type] $content_str
  238. * @return void
  239. * @author wj
  240. * @date 2023-08-19
  241. */
  242. public function getcommandcontent($content_str)
  243. {
  244. $content = explode(',', $content_str);
  245. $command = $content[0];
  246. unset($content[0]);
  247. $data = [
  248. 'command' => $command,
  249. 'content' => $content,
  250. ];
  251. return $data;
  252. }
  253. /**
  254. * 解析终端发送命令长度
  255. *
  256. * @param [type] $len
  257. * @return void
  258. * @author wj
  259. * @date 2023-08-18
  260. */
  261. public function analysislen($len)
  262. {
  263. $len = base_convert($len, 16, 10);
  264. return $len;
  265. }
  266. /**
  267. * 设置可解析数据 终端发送信息解析
  268. *
  269. * @param [type] $command
  270. * @return void
  271. * @author wj
  272. * @date 2023-08-18
  273. * analysis_digit 解析位数
  274. * content 解析对应字段
  275. * kind 类型 tsend 平台发送 tback平台回复
  276. * need_back 是否需回复 1是 0否 没设置为0
  277. * command 未设置则和键值相同
  278. */
  279. public function getreceivecommandinfo($command)
  280. {
  281. $command = strtoupper($command);
  282. $data = [
  283. 'UD' => [
  284. 'analysis_digit' => [1, 2, 4, 6, 8, 9, 10, 13, 14, 15, 16],
  285. 'content' => [
  286. 'date',
  287. 'time',
  288. 'gps_lat',
  289. 'gps_long',
  290. 'speed',
  291. 'direction',
  292. 'poster',
  293. 'electric_quantity',
  294. 'step_number',
  295. 'roll_number',
  296. 'terminal_status',
  297. ],
  298. 'kind' => 'tsend',
  299. 'need_back' => 0,
  300. ],
  301. 'AL' => [
  302. 'analysis_digit' => [1, 2, 4, 6, 8, 9, 10, 13, 14, 15, 16],
  303. 'content' => [
  304. 'date',
  305. 'time',
  306. 'gps_lat',
  307. 'gps_long',
  308. 'speed',
  309. 'direction',
  310. 'poster',
  311. 'electric_quantity',
  312. 'step_number',
  313. 'roll_number',
  314. 'terminal_status',
  315. ],
  316. 'kind' => 'tsend',
  317. 'need_back' => 0,
  318. ],
  319. 'KA' => [
  320. 'analysis_digit' => [1, 2, 3, 4],
  321. 'content' => [
  322. 'date',
  323. 'step_number',
  324. 'roll_number',
  325. 'electric_quantity',
  326. ],
  327. 'kind' => 'tsend',
  328. 'need_back' => 1,
  329. ],
  330. 'LK' => [
  331. 'analysis_digit' => null,
  332. 'content' => null,
  333. 'kind' => 'tsend',
  334. 'need_back' => 1,
  335. ],
  336. 'BPHRT' => [
  337. 'analysis_digit' => [1, 2, 3],
  338. 'content' => [
  339. 'blood_height_pressure',
  340. 'blood_low_pressure',
  341. 'heart_rate',
  342. ],
  343. 'kind' => 'tsend',
  344. 'need_back' => 1,
  345. 'command' => 'bphrt',
  346. ],
  347. 'TEMP' => [
  348. 'analysis_digit' => [1],
  349. 'content' => [
  350. 'temp',
  351. ],
  352. 'kind' => 'tsend',
  353. 'need_back' => 1,
  354. 'command' => 'temp',
  355. ],
  356. 'HEART' => [
  357. 'analysis_digit' => [1],
  358. 'content' => [
  359. 'heart_rate',
  360. ],
  361. 'kind' => 'tsend',
  362. 'need_back' => 1,
  363. 'command' => 'heart',
  364. ],
  365. 'BLOOD' => [
  366. 'analysis_digit' => [1, 2],
  367. 'content' => [
  368. 'blood_height_pressure',
  369. 'blood_low_pressure',
  370. ],
  371. 'kind' => 'tsend',
  372. 'need_back' => 1,
  373. 'command' => 'blood',
  374. ],
  375. 'OXYGEN' => [
  376. 'analysis_digit' => [1],
  377. 'content' => [
  378. 'oxygen',
  379. ],
  380. 'kind' => 'tsend',
  381. 'need_back' => 1,
  382. 'command' => 'oxygen',
  383. ],
  384. 'TKQ' => [
  385. 'analysis_digit' => null,
  386. 'content' => null,
  387. 'kind' => 'tsend',
  388. 'need_back' => 1,
  389. ],
  390. 'TKQ' => [
  391. 'analysis_digit' => null,
  392. 'content' => null,
  393. 'kind' => 'tsend',
  394. 'need_back' => 1,
  395. ],
  396. 'WG' => [
  397. 'analysis_digit' => null,
  398. 'content' => null,
  399. 'kind' => 'tsend',
  400. 'need_back' => 1,
  401. ],
  402. //终端回复
  403. //ZONE UPLOAD CR SLEEPTIME FALLDOWN FACTORY SOS VERNO LOWBAT
  404. //POWEROFF LSSET PEDO PHL REMIND SILENCETIME2 BOOTOFF REMOVE
  405. 'ZONE' => [
  406. 'analysis_digit' => null,
  407. 'content' => null,
  408. 'kind' => 'tback',
  409. ],
  410. 'UPLOAD' => [
  411. 'analysis_digit' => null,
  412. 'content' => null,
  413. 'kind' => 'tback',
  414. ],
  415. 'HRTSART' => [
  416. 'analysis_digit' => null,
  417. 'content' => null,
  418. 'kind' => 'tback',
  419. ],
  420. 'WDSTART' => [
  421. 'analysis_digit' => null,
  422. 'content' => null,
  423. 'kind' => 'tback',
  424. ],
  425. 'BLDSTART' => [
  426. 'analysis_digit' => null,
  427. 'content' => null,
  428. 'kind' => 'tback',
  429. ],
  430. 'OXSTART' => [
  431. 'analysis_digit' => null,
  432. 'content' => null,
  433. 'kind' => 'tback',
  434. ],
  435. 'CR' => [
  436. 'analysis_digit' => null,
  437. 'content' => null,
  438. 'kind' => 'tback',
  439. ],
  440. 'SLEEPTIME' => [
  441. 'analysis_digit' => null,
  442. 'content' => null,
  443. 'kind' => 'tback',
  444. ],
  445. 'FALLDOWN' => [
  446. 'analysis_digit' => null,
  447. 'content' => null,
  448. 'kind' => 'tback',
  449. ],
  450. 'SOS' => [
  451. 'analysis_digit' => null,
  452. 'content' => null,
  453. 'kind' => 'tback',
  454. ],
  455. 'VERNO' => [
  456. 'analysis_digit' => [1],
  457. 'content' => ['version'],
  458. 'kind' => 'tback',
  459. ],
  460. 'LOWBAT' => [
  461. 'analysis_digit' => null,
  462. 'content' => null,
  463. 'kind' => 'tback',
  464. ],
  465. 'POWEROFF' => [
  466. 'analysis_digit' => null,
  467. 'content' => null,
  468. 'kind' => 'tback',
  469. ],
  470. 'LSSET' => [
  471. 'analysis_digit' => null,
  472. 'content' => null,
  473. 'kind' => 'tback',
  474. ],
  475. 'PEDO' => [
  476. 'analysis_digit' => null,
  477. 'content' => null,
  478. 'kind' => 'tback',
  479. ],
  480. 'PHL' => [
  481. 'analysis_digit' => null,
  482. 'content' => null,
  483. 'kind' => 'tback',
  484. ],
  485. 'REMIND' => [
  486. 'analysis_digit' => null,
  487. 'content' => null,
  488. 'kind' => 'tback',
  489. ],
  490. 'SILENCETIME2' => [
  491. 'analysis_digit' => null,
  492. 'content' => null,
  493. 'kind' => 'tback',
  494. ],
  495. 'BOOTOFF' => [
  496. 'analysis_digit' => null,
  497. 'content' => null,
  498. 'kind' => 'tback',
  499. ],
  500. 'REMOVE' => [
  501. 'analysis_digit' => null,
  502. 'content' => null,
  503. 'kind' => 'tback',
  504. ],
  505. 'CALL' => [
  506. 'analysis_digit' => null,
  507. 'content' => null,
  508. 'kind' => 'tback',
  509. ],
  510. 'KEYBRD' => [
  511. 'analysis_digit' => null,
  512. 'content' => null,
  513. 'kind' => 'tback',
  514. ],
  515. ];
  516. if (!isset($data[$command])) {
  517. return false;
  518. }
  519. return $data[$command];
  520. }
  521. /**
  522. * 获取数据值
  523. *
  524. * @param [type] $data
  525. * @param [type] $command
  526. * @return void
  527. * @author wj
  528. * @date 2023-08-14
  529. */
  530. public function getdata($config, $content_arr)
  531. {
  532. $analysis_digit = $config['analysis_digit'];
  533. $config_content = $config['content'];
  534. $data = [];
  535. if (is_array($analysis_digit)) {
  536. foreach ($analysis_digit as $key => $value) {
  537. if (isset($content_arr[$value])) {
  538. if (isset($config_content[$key])) {
  539. $item_key = $config_content[$key];
  540. $item_value = $content_arr[$value];
  541. $data[$item_key] = $item_value;
  542. }
  543. }
  544. }
  545. }
  546. if (isset($data['time'])) {
  547. $time = $data['time'];
  548. $data['time'] = $this->gettime($time);
  549. }
  550. if (isset($data['date'])) {
  551. $date = $data['date'];
  552. $data['date'] = $this->getdate($date);
  553. }
  554. if (isset($data['terminal_status'])) {
  555. $terminalstatus = $data['terminal_status'];
  556. $terminal_status_arr = $this->getterminalstatus($terminalstatus);
  557. //unset($data['terminal_status']);
  558. $data['status_type'] = $terminal_status_arr['status_type'];
  559. $data['alarm_type'] = $terminal_status_arr['alarm_type'];
  560. }
  561. return $data;
  562. }
  563. /**
  564. * 时间解析
  565. *
  566. * @param [type] $time
  567. * @return void
  568. * @author wj
  569. * @date 2023-08-19
  570. */
  571. public function gettime($time)
  572. {
  573. $hour = substr($time, 0, 2);
  574. $minute = substr($time, 2, 2);
  575. $second = substr($time, 4, 2);
  576. $time = $hour . ':' . $minute . ':' . $second;
  577. return $time;
  578. }
  579. /**
  580. * 日期解析
  581. *
  582. * @return void
  583. * @author wj
  584. * @date 2023-08-15
  585. */
  586. public function getdate($date)
  587. {
  588. $day = substr($date, 0, 2);
  589. $month = substr($date, 2, 2);
  590. $year = substr($date, 4, 2);
  591. $year1 = date('Y');
  592. $year2 = substr($year1, 0, 2);
  593. $year = $year2 . $year;
  594. if ($year != $year1) {
  595. $day = date('Y-m-d');
  596. } else {
  597. $day = $year . '-' . $month . '-' . $day;
  598. }
  599. return $day;
  600. }
  601. /**
  602. * 解析终端状态
  603. *
  604. * @param [type] $terminal_status
  605. * @return void
  606. * @author wj
  607. * @date 2023-08-19
  608. */
  609. public function getterminalstatus($terminal_status)
  610. {
  611. $terminal_status = str_split($terminal_status);
  612. foreach ($terminal_status as $key => $value) {
  613. $value = base_convert($value, 16, 2);
  614. $value = str_pad($value, 4, "0", STR_PAD_LEFT);
  615. $terminal_status[$key] = $value;
  616. }
  617. $terminal_status_str = implode("", $terminal_status);
  618. $mid = mb_strlen($terminal_status_str) / 2;
  619. $alarm = substr($terminal_status_str, 0, $mid);
  620. $first_num = strpos($alarm, '1');
  621. $end_num = strrpos($alarm, '1');
  622. if ($first_num != $end_num) {
  623. Log::write("状态解析错误:报警:" . $terminal_status . " " . $terminal_status_str, 'shouhuan');
  624. }
  625. if ($first_num) {
  626. //16:SOS报警;17:低电报警;20:手环拆除报警;21:跌倒报警;22:心率异常报警
  627. $first_num = $mid - $first_num + ($mid - 1);
  628. $alarm_type = $first_num;
  629. }
  630. $status = substr($terminal_status_str, $mid);
  631. $first_num = strpos($status, '1');
  632. $end_num = strrpos($status, '1');
  633. if ($first_num != $end_num) {
  634. Log::write("状态解析错误:状态:" . $terminal_status . " " . $terminal_status_str, 'shouhuan');
  635. }
  636. if ($first_num) {
  637. $first_num = $mid - 1 - $first_num;
  638. //1:低电状态;2:出围栏状态;3:进围栏状态;4:手环戴上取下状态;5:手表运行静止状态
  639. $status_type = $first_num + 1;
  640. }
  641. $data = [
  642. 'alarm_type' => isset($alarm_type) ? $alarm_type : false,
  643. 'status_type' => isset($status_type) ? $status_type : false,
  644. ];
  645. return $data;
  646. }
  647. // /**
  648. // * 解析报警
  649. // *
  650. // * @param [type] $first_num
  651. // * @return void
  652. // * @author wj
  653. // * @date 2023-08-19
  654. // */
  655. // public function getalarm($first_num)
  656. // {
  657. // $data = [
  658. // 16 => 'SOS报警',
  659. // 17 => '低电报警',
  660. // 18 => '出围栏报警',
  661. // 19 => '进围栏报警',
  662. // 20 => '手环拆除报警',
  663. // 21 => '跌倒报警',
  664. // 22 => '心率异常报警',
  665. // ];
  666. // if (isset($data[$first_num])) {
  667. // return $data[$first_num];
  668. // }
  669. // return false;
  670. // }
  671. // /**
  672. // * 解析状态
  673. // *
  674. // * @param [type] $first_num
  675. // * @return void
  676. // * @author wj
  677. // * @date 2023-08-19
  678. // */
  679. // public function getstatus($first_num)
  680. // {
  681. // $data = [
  682. // 0 => '低电状态',
  683. // 1 => '出围栏状态',
  684. // 2 => '进围栏状态',
  685. // 3 => '手环戴上取下状态',
  686. // 4 => '手表运行静止状态',
  687. // ];
  688. // if (isset($data[$first_num])) {
  689. // return $data[$first_num];
  690. // }
  691. // return false;
  692. // }
  693. // ̄へ ̄-----------内容解析结束---------------- ̄へ ̄
  694. // ̄へ ̄-----------业务处理开始---------------- ̄へ ̄
  695. /**
  696. * 获取设别表id
  697. *
  698. * @return void
  699. * @author wj
  700. * @date 2023-08-11
  701. */
  702. public function getfacilityid($device_id_code)
  703. {
  704. $m_f = new FacilityModel();
  705. $where = ['code' => $device_id_code, 'status' => 1];
  706. $finfo = $m_f->getInfo($where, ['id']);
  707. if (empty($finfo)) {
  708. throw new \Exception("设备信息错误:" . $device_id_code);
  709. return false;
  710. }
  711. $id = $finfo['id'];
  712. return $id;
  713. }
  714. public function geshinfoid($device_id_code)
  715. {
  716. $m_si = new ShinfoModel();
  717. $where = ['device_id_code' => $device_id_code];
  718. $siinfo = $m_si->getInfo($where, ['id']);
  719. if (empty($siinfo)) {
  720. throw new \Exception("设备信息错误:" . $device_id_code);
  721. return false;
  722. }
  723. $id = $siinfo['id'];
  724. return $id;
  725. }
  726. /**
  727. * 保存接收信息队列
  728. *
  729. * @param [type] $data
  730. * @return void
  731. * @author wj
  732. * @date 2023-08-14
  733. */
  734. public function savereceivequeue($data, $device_id_code)
  735. {
  736. $m_srq = new ShreceivequeueModel();
  737. $facility_id = $this->getfacilityid($device_id_code);
  738. $data = [
  739. 'msg' => $data,
  740. 'createtime' => date('Y-m-d H:i:s'),
  741. 'device_id_code' => $device_id_code,
  742. 'facility_id' => $facility_id,
  743. ];
  744. $id = $m_srq->insertData($data);
  745. if (empty($id)) {
  746. return false;
  747. }
  748. return true;
  749. }
  750. /**
  751. * 获取接收信息队列列表
  752. *
  753. * @param [type] $page
  754. * @param [type] $size
  755. * @return void
  756. * @author wj
  757. * @date 2023-08-14
  758. */
  759. public function getreceivequeuelist($page = null, $size = null)
  760. {
  761. $m_srq = new ShreceivequeueModel();
  762. $where = ['status' => 0];
  763. $size = empty($size) ? 20 : $size;
  764. if (empty($page)) {
  765. $count = $m_srq->getList($where, 'count');
  766. $totalpage = ceil($count / $size);
  767. $data = ['totalpage' => $totalpage, 'size' => $size];
  768. return $data;
  769. } else {
  770. $list = $m_srq->getList($where, '*', $page, $size, 'id asc');
  771. if (empty($list)) {
  772. //Log::write("手环接收信息队列-无数据", 'shouhuan');
  773. return false;
  774. }
  775. $list = $list->toArray();
  776. foreach ($list as $key => $value) {
  777. $id = $value['id'];
  778. if (1 != $value['status']) {
  779. $row = $m_srq->updateinfo(['id' => $id], ['status' => 1]);
  780. if (1 != $row) {
  781. $msg = "Shreceivequeue id:" . $id . " 修改失败";
  782. Log::write($msg, 'shouhuan');
  783. unset($list[$key]);
  784. }
  785. }
  786. }
  787. return $list;
  788. }
  789. }
  790. /**
  791. * 获取发送信息队列列表
  792. *
  793. * @param [type] $page
  794. * @param [type] $size
  795. * @return void
  796. * @author wj
  797. * @date 2023-08-14
  798. */
  799. public function getsendqueuelist($device_id_code, $page = null, $size = null)
  800. {
  801. $m_ssq = new ShsendqueueModel();
  802. $where = ['status' => 0, 'device_id_code' => $device_id_code];
  803. $size = empty($size) ? 20 : $size;
  804. if (empty($page)) {
  805. $count = $m_ssq->getList($where, 'count');
  806. $totalpage = ceil($count / $size);
  807. $data = ['totalpage' => $totalpage, 'size' => $size];
  808. return $data;
  809. } else {
  810. $list = $m_ssq->getList($where, '*', $page, $size, 'id asc,weight desc');
  811. if (empty($list)) {
  812. Log::write("手环发送信息队列-无数据", 'shouhuan');
  813. return false;
  814. }
  815. $list = $list->toArray();
  816. foreach ($list as $key => $value) {
  817. $id = $value['id'];
  818. if (1 != $value['status']) {
  819. $row = $m_ssq->updateinfo(['id' => $id], ['status' => 1]);
  820. if (1 != $row) {
  821. $msg = "Shsendqueue id:" . $id . " 修改失败";
  822. Log::write($msg, 'shouhuan');
  823. unset($list[$key]);
  824. }
  825. }
  826. }
  827. return $list;
  828. }
  829. }
  830. /**
  831. * 保存手环信息
  832. *
  833. * @return void
  834. * @author wj
  835. * @date 2023-08-14
  836. */
  837. public function saveshinfo($facility_id, $device_id_code, $data, $queue_data)
  838. {
  839. $original_str = $queue_data['msg'];
  840. $command = $data['command'];
  841. $content_arr = $data['content_arr'];
  842. $config = $data['config'];
  843. $data = $this->getdata($config, $content_arr);
  844. $m_sri = new ShinfoModel();
  845. $m_srir = new ShreceiveredocdeModel();
  846. $m_sa = new ShalarmlistModel();
  847. if ('AL' == $command) {
  848. //手环警报信息
  849. $data['alarm_from_type'] = 1;
  850. $data['device_id_code'] = $device_id_code;
  851. $sshinfo_id = $this->geshinfoid($device_id_code);
  852. $data['shinfo_id'] = $sshinfo_id;
  853. $data['facility_id'] = $facility_id;
  854. $data['createtime'] = date('Y-m-d H:i:s');
  855. $result = $this->getmacforUD($original_str, $device_id_code);
  856. $data['use_gps_long'] = $result['use_gps_long'];
  857. $data['use_gps_lat'] = $result['use_gps_lat'];
  858. $data['location'] = $result['address_desc'];
  859. $m_dl = new Devicelistmodel();
  860. $uid = $m_dl->getuidbydeviceid($device_id_code);
  861. $uid = empty($uid) ? 0 : $uid;
  862. $data['user_id'] = $uid;
  863. $said = $m_sa->insertData($data);
  864. if (empty($said)) {
  865. $msg = "报警信息添加失败:" . $original_str;
  866. Log::write($msg, 'shouhuan');
  867. throw new \Exception($msg);
  868. }
  869. } else {
  870. //手环基础信息修改
  871. $sriData = $data;
  872. if ($command == "UD") {
  873. $uddata = $this->getmacforUD($original_str, $device_id_code);
  874. if ($uddata) {
  875. $sriData = array_merge($sriData, $uddata);
  876. }
  877. }
  878. $sriwhere = [
  879. 'facility_id' => $facility_id,
  880. 'device_id_code' => $device_id_code,
  881. ];
  882. $sriinfo = $m_sri->getInfo($sriwhere);
  883. if (empty($sriinfo)) {
  884. $sriData['device_id_code'] = $device_id_code;
  885. $sriData['facility_id'] = $facility_id;
  886. $sriData['online_statis'] = 1;
  887. $sriinsertData = $sriData;
  888. $sriinsertData['createtime'] = date('Y-m-d H:i:s');
  889. $sriinsertData['updatetime'] = date('Y-m-d H:i:s');
  890. $sriinsertData = $m_sri->formatinfo($sriinsertData);
  891. $sriid = $m_sri->insertData($sriinsertData);
  892. if (empty($sriid)) {
  893. throw new \Exception("设备信息添加失败:" . $device_id_code);
  894. }
  895. } else {
  896. $sriinfo = $sriinfo->toArray();
  897. $sriid = $sriinfo['id'];
  898. $sriupdateData = (array) $sriData;
  899. foreach ($sriupdateData as $key => $value) {
  900. if (in_array($key, array_keys($sriinfo))) {
  901. if ($sriinfo[$key] == $value) {
  902. unset($sriupdateData[$key]);
  903. }
  904. } else {
  905. unset($sriupdateData[$key]);
  906. }
  907. }
  908. if (count($sriupdateData) > 0) {
  909. $sriupdateData['updatetime'] = date('Y-m-d H:i:s');
  910. $sriupdateData = $m_sri->formatinfo($sriupdateData);
  911. $row = $m_sri->updateinfo(['id' => $sriid], $sriupdateData);
  912. if (empty($row)) {
  913. $errmsg = "设备信息修改失败:" . $device_id_code;
  914. Log::write($errmsg);
  915. Log::write($sriupdateData, 'shouhuan');
  916. throw new \Exception($errmsg);
  917. }
  918. }
  919. }
  920. }
  921. //接收信息历史添加
  922. $sririnsertData['facility_id'] = $facility_id;
  923. $sririnsertData['device_id_code'] = $device_id_code;
  924. $sririnsertData['original_str'] = $original_str;
  925. $sririnsertData['content'] = json_encode($data);
  926. if (isset($data['date'])) {
  927. $sririnsertData['date'] = $data['date'];
  928. }
  929. if (isset($data['time'])) {
  930. $sririnsertData['time'] = $data['time'];
  931. }
  932. $sririnsertData['command'] = $command;
  933. $sririnsertData['createtime'] = date('Y-m-d H:i:s');
  934. $sririnsertData['receive_time'] = $queue_data['createtime'];
  935. if ('tback' == $config['kind']) {
  936. $is_back_msg = true;
  937. $sririnsertData['is_back_msg'] = 0;
  938. } else {
  939. $is_back_msg = false;
  940. $sririnsertData['is_back_msg'] = 1;
  941. }
  942. $sririd = $m_srir->insertData($sririnsertData);
  943. if (empty($sririd)) {
  944. throw new \Exception("设备历史信息添加失败:" . $device_id_code);
  945. }
  946. if ($is_back_msg) {
  947. //处理回复信息
  948. $m_ssl = new ShsendlistModel();
  949. $where = [
  950. 'is_success' => 0,
  951. 'is_send' => 1,
  952. 'command' => $command,
  953. ];
  954. $sslinfo = $m_ssl->getInfo($where);
  955. if ($sslinfo) {
  956. //发送成功状态回写
  957. $sslid = $sslinfo['id'];
  958. $sslupdateData = ['is_success' => 1];
  959. $m_ssl->updateinfo(['id' => $sslid], $sslupdateData);
  960. $srirupdateData = ['send_list_id' => $sslid];
  961. $m_srir->updateinfo(['id' => $sririd], $srirupdateData);
  962. }
  963. }
  964. return true;
  965. }
  966. //发送完处理
  967. /**
  968. * 发送成功 删除发送数据
  969. *
  970. * @param [type] $item
  971. * @return void
  972. * @author wj
  973. * @date 2023-08-21
  974. */
  975. public function sendmsgsuccess($item)
  976. {
  977. $m_ssq = new ShsendqueueModel();
  978. $m_ssl = new ShsendlistModel();
  979. $m_sal = new ShalarmlistModel();
  980. $ssqid = $item['id'];
  981. if (0 === $item['msg_type']) {
  982. //普通信息
  983. if ($item['send_list_id']) {
  984. $list_id = $item['send_list_id'];
  985. $sslwhere = ['id' => $list_id, 'is_send' => 0];
  986. $sslinfo = $m_ssl->getInfo($sslwhere);
  987. if ($sslinfo) {
  988. $row = $m_ssl->updateinfo(['id' => $sslinfo['id']], ['is_send' => 1, 'send_time' => date('Y-m-d H:i:s')]);
  989. }
  990. }
  991. }
  992. if (1 === $item['msg_type']) {
  993. //报警信息
  994. if ($item['send_list_id']) {
  995. $list_id = $item['send_list_id'];
  996. $salwhere = ['id' => $list_id, 'is_send' => 0];
  997. $salinfo = $m_sal->getInfo($salwhere);
  998. if ($salinfo) {
  999. $row = $m_sal->updateinfo(['id' => $salinfo['id']], ['is_send' => 1, 'send_time' => date('Y-m-d H:i:s')]);
  1000. }
  1001. }
  1002. }
  1003. $ssqwhere = ['id' => $ssqid];
  1004. $ssqinfo = $m_ssq->getInfo($ssqwhere);
  1005. if ($ssqinfo) {
  1006. $m_ssq->deleteinfobyid($ssqid);
  1007. }
  1008. }
  1009. /**
  1010. * 解析成功 删除接收数据
  1011. *
  1012. * @param [type] $item
  1013. * @return void
  1014. * @author wj
  1015. * @date 2023-08-21
  1016. */
  1017. public function receivemsgsuccess($item)
  1018. {
  1019. $m_srq = new ShreceivequeueModel();
  1020. $srqid = $item['id'];
  1021. $srqwhere = ['id' => $srqid, 'status' => 1];
  1022. $srqinfo = $m_srq->getInfo($srqwhere);
  1023. if ($srqinfo) {
  1024. $m_srq->deleteinfobyid($srqid);
  1025. }
  1026. }
  1027. /**
  1028. * 初始化手环接收信息解析
  1029. *
  1030. * @return void
  1031. * @author wj
  1032. * @date 2023-08-15
  1033. */
  1034. public function initanalysisShoneReceiveMsg()
  1035. {
  1036. $m_srq = new ShreceivequeueModel();
  1037. $where = ['status' => 1];
  1038. $m_srq->updateinfo($where, ['status' => 0]);
  1039. }
  1040. /**
  1041. * 测试使用
  1042. *
  1043. * @param [type] $data
  1044. * @return void
  1045. * @author wj
  1046. * @date 2023-08-21
  1047. */
  1048. public function showfortest($data)
  1049. {
  1050. $strdata = $this->getline($data, null, false);
  1051. if (!is_array($strdata)) {
  1052. Log::write($data, 'shouhuan');
  1053. return false;
  1054. }
  1055. $command = strtoupper($strdata['command']);
  1056. $showcommands = [
  1057. 'SOS', 'CR', 'UPLOAD', 'SLEEPTIME', 'ZONE', 'FALLDOWN',
  1058. 'APPLOCK', 'FACTORY', 'VERNO', 'LOWBAT', 'UD', 'POWEROFF', 'MESSAGE',
  1059. 'WALKTIME', 'PEDO', 'PHB', 'PHL', 'REMIND', 'SILENCETIME2', 'BOOTOFF',
  1060. 'REMOVE', 'INFO', 'AL', 'LSSET', 'BTWARNSET', 'KEYBRD',
  1061. ];
  1062. if (in_array($command, $showcommands)) {
  1063. var_dump(date('Y-m-d H:i:s'));
  1064. var_dump($data);
  1065. }
  1066. }
  1067. /**
  1068. * 设置设备上线
  1069. *
  1070. * @return void
  1071. * @author wj
  1072. * @date 2023-08-21
  1073. */
  1074. public function setonlineinfo($device_id_code)
  1075. {
  1076. $m_si = new ShinfoModel();
  1077. $where = ['device_id_code' => $device_id_code, 'online_statis' => 0];
  1078. $finfo = $m_si->getInfo($where, ['id', 'online_statis']);
  1079. if ($finfo) {
  1080. $facility_id = $finfo['id'];
  1081. $m_si->setonlineinfobyid($facility_id);
  1082. }
  1083. }
  1084. /**
  1085. * 设置设备下线
  1086. *
  1087. * @return void
  1088. * @author wj
  1089. * @date 2023-08-21
  1090. */
  1091. public function setofflineinfo()
  1092. {
  1093. $m_si = new ShinfoModel();
  1094. $list = $m_si->getcheckupdatetimelist();
  1095. $list = (array) $list;
  1096. if (!empty($list)) {
  1097. $facility_ids = array_column($list, 'id');
  1098. $m_si->setofflineinfobyids($facility_ids);
  1099. }
  1100. }
  1101. //工具方法
  1102. /**
  1103. * unicode 解码
  1104. *
  1105. * @param [type] $str
  1106. * @return void
  1107. * @author wj
  1108. * @date 2023-08-21
  1109. */
  1110. public function unicodeToChn($str)
  1111. {
  1112. $arr = str_split($str);
  1113. $items = [];
  1114. $item = "";
  1115. foreach ($arr as $key => $value) {
  1116. $index = $key + 1;
  1117. if (0 != $index % 4) {
  1118. $item .= $value;
  1119. } else {
  1120. $item = "";
  1121. $items[] = $item;
  1122. }
  1123. }
  1124. foreach ($items as $key => $value) {
  1125. $char = hex2bin($value);
  1126. $char = iconv('UCS-2BE', 'UTF-8', $char);
  1127. $items[$key] = $char;
  1128. }
  1129. $info = implode("", $items);
  1130. return $info;
  1131. }
  1132. /**
  1133. * 拆包
  1134. *
  1135. * @return void
  1136. * @author wj
  1137. * @date 2023-08-15
  1138. */
  1139. public function unpack($data)
  1140. {
  1141. $arr = explode("][", $data);
  1142. foreach ($arr as $key => $value) {
  1143. if ($value[0] !== "[") {
  1144. $arr[$key] = '[' . $value;
  1145. }
  1146. if ($value[mb_strlen($value) - 1] !== "]") {
  1147. $arr[$key] .= "]";
  1148. }
  1149. }
  1150. return $arr;
  1151. }
  1152. }