RcgjfwDecodeAction.class.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. <?php
  2. class RcgjfwDecodeAction extends Action {
  3. /*
  4. 参数说明:
  5. packet:
  6. packet_text:带空格16进制文本
  7. */
  8. private function import($packet, $packet_text){
  9. //解析消息体
  10. $result = $this->rfid_proto->tcp_unpack_msg($packet);
  11. if(! $result['Success'] ){
  12. $this->rfid_proto->decode_error_log('unpack_fail','unpack packet failed ,result : '.json_encode($result));
  13. return;
  14. }
  15. //记录从redis获取到的基站数据包
  16. $this->rfid_proto->decode_packet_log($result['StationCode'],$result['StationCode'].' => '.$packet_text);
  17. //获取一条车辆标签(电子标签编码)
  18. $FirstLabelNumber = $result['VehicleList'][0]['VehicleNumber'];
  19. //tcp_log('tcp packet received. station code= ' . $result['StationCode'] . ', label_number= ' . $FirstLabelNumber);
  20. //未入库基站,缓存命中,直接返回
  21. $not_exit_station_key = 'not_exit_station_'.$result['StationCode'];
  22. $not_exit_station = \Jiaruan\StaticCache::get($not_exit_station_key);
  23. if( \Jiaruan\StaticCache::ishit($not_exit_station) ){
  24. decode_error_log('not_existed_station', 'station not existed,cath is hit, station_code = ' . $result['StationCode']);
  25. return;
  26. }
  27. //已开局基站,缓存一小时基站信息,避免频繁查询
  28. $station_key = 'station_info_'.$result['StationCode'];
  29. $station_info = \Jiaruan\StaticCache::get($station_key);
  30. if( !\Jiaruan\StaticCache::ishit($station_info) ){
  31. try{
  32. //获取基站信息
  33. $cond = array('DeviceCode' => $result['StationCode']);
  34. //排除指定字段,防止旧系统查询不存在的字段时报错
  35. $station_info = M('jms_station')->where($cond)->field('IsDuplicate,ChargerId,PhotoUrl,SimCardNo,DeviceType,AddTime,InstallationTime,OpenSucessTime,OnlineTime,Comment,IsRecycled,PoliceId,MoveStationLeader,MoveStationPhone,ManufactType',true)->find();
  36. //$station_info = M('jms_station')->where($cond)->field('ID,StationNumericId,FirstLabelNumber,InstallationStatus,CityId,Longitude,Latitude,Address,StationType,DeviceNumber,DeviceName,')->find();
  37. }catch (Exception $e){
  38. $msg = 'get_station_info ,cach exception!! error_code = '.$e->getCode().', error_msg = '.$e->getMessage().', station_code = '.$result['StationCode'];
  39. decode_error_log('get_station_conn_mysql_exception',$msg);
  40. }
  41. //不存在的基站,缓存十分钟,并返回
  42. if(!$station_info){
  43. decode_error_log('not_existed_station', 'station not existed, station_code = ' . $result['StationCode']);
  44. \Jiaruan\StaticCache::set($not_exit_station_key,true,600);
  45. return;
  46. }
  47. if ( $station_info['InstallationStatus'] == C('开局状态_已成功') ){
  48. \Jiaruan\StaticCache::set($station_key,$station_info,3600);
  49. }
  50. }
  51. //对数据包进行日志记录
  52. /*
  53. $data = array(
  54. 'StationId' => $station_info['ID'] ? : 0,
  55. 'StationCode' => $result['StationCode'],
  56. 'PacketData' => $packet_text,
  57. 'AddTime' => date('Y-m-d H:i:s')
  58. );
  59. */
  60. $data = array(
  61. 'StationId' => $station_info['StationNumericId'] ? : ($station_info['ID']?:0),//兼容旧版本
  62. 'StationCode' => $result['StationCode'],
  63. 'PacketData' => $packet_text,
  64. 'AddTime' => date('Y-m-d H:i:s')
  65. );
  66. //原始包存到表格存储
  67. $rawData = $data;//tablestore
  68. $rawData['StationCode'] = $station_info['DeviceNumber'];//tablestore
  69. $this->routeStore->addRawPacket($station_info['CityId'], $rawData);
  70. //移动基站,过大的数据包,跳过处理
  71. if($station_info['StationType']==C('基站类型_移动基站')&&$result['body_length']>1000){
  72. decode_error_log('too_big_packet_move_station','move_station packet too big, skip decode; station_code => '.$result['StationCode']);
  73. return;
  74. }
  75. //普通基站,过大的数据包,记录一下,但继续处理
  76. if($station_info['StationType']==C('基站类型_普通基站')&&$result['body_length']>1000){
  77. decode_error_log('too_big_packet_normal_station','normal_station packet too big, station_code => '.$result['StationCode']);
  78. }
  79. /*
  80. $start = microtime(true);
  81. if( ! M('jms_rpacket')->createAdd($data) ){
  82. decode_error_log('add_rpacket_fail','add rpacket to jms_rpacket fail, error_message:'.M('jms_rpacket')->getLastSql().', data: '.json_encode($data));
  83. return;
  84. }
  85. echo '************time0: '.use_microtime($start).PHP_EOL;
  86. */
  87. //更新基站信息(已开局基站,间隔一分钟更新一次,避免频繁更新)
  88. $station_key_update_time = 'station_key_update_time_'. $result['StationCode'];
  89. $station_update_time = \Jiaruan\StaticCache::get($station_key_update_time);
  90. if( !\Jiaruan\StaticCache::ishit($station_update_time) && $FirstLabelNumber && !is_mock_route($FirstLabelNumber) ){
  91. $data = array();
  92. if(!$station_info['FirstLabelNumber'] && $FirstLabelNumber)
  93. $data['FirstLabelNumber'] = $FirstLabelNumber;
  94. if( $station_info['InstallationStatus'] == C('开局状态_开局中') ){
  95. $data['InstallationStatus'] = C('开局状态_已成功');
  96. $data['OpenSucessTime'] = date('Y-m-d H:i:s');
  97. }
  98. //异常基站跳过更新基站状态
  99. $cond = array('DeviceCode' => $result['StationCode']);
  100. $station_status = M('jms_station')->where($cond)->getField('DeviceStatus');
  101. if($station_status != C('基站状态_异常')){
  102. $data['DeviceStatus'] = C('基站状态_在线');
  103. }
  104. $data['OnlineTime'] = date('Y-m-d H:i:s');
  105. $start = microtime(true);
  106. try{
  107. $cond = array('ID'=>$station_info['ID']);
  108. if(! M('jms_station')->where($cond)->save($data) ){
  109. decode_error_log('update_station_info',"update station info failed. sql = " . M('jms_station')->getLastSql().',db_error = '. M('jms_station')->getDbError());
  110. }
  111. }catch (Exception $e) {
  112. $msg = 'update_station_info ,cach exception!! error_code = '.$e->getCode().', error_msg = '.$e->getMessage().', station_code = '.$result['StationCode'];
  113. decode_error_log('update_station_conn_mysql_exception',$msg);
  114. }
  115. echo '************time1:'.use_microtime($start).PHP_EOL;
  116. //已开局基站,缓存更新时间
  117. if( $station_info['InstallationStatus'] == C('开局状态_已成功') ){
  118. \Jiaruan\StaticCache::set($station_key_update_time,time(),60);
  119. }
  120. }
  121. //还没有指定城市,跳过
  122. if(! $station_info['CityId'] ){
  123. decode_error_log('cityid_empty','station cityid not existed, station_code: '.$result['StationCode']);
  124. return;
  125. }
  126. //还没有开局成功,跳过
  127. if($station_info['InstallationStatus'] != C('开局状态_已成功') ){
  128. decode_error_log('not_kaiju','station not kaiju, station_code: '.$result['StationCode']);
  129. return;
  130. }
  131. /*
  132. //检测基站近一分钟内是否更新过,更新过的跳过
  133. if($this->check_station_is_cathed($station_info['DeviceNumber'])){
  134. echo 'skip update station vehicle route;station_code: '.$station_info['DeviceCode'].PHP_EOL;
  135. return;
  136. }*/
  137. //保存到车辆表
  138. foreach($result['VehicleList'] as $key=>$row){
  139. $result['VehicleList'][$key]['StationCode'] = $result['StationCode'];
  140. $result['VehicleList'][$key]['CityId'] = $station_info['CityId'];
  141. $start = microtime(true);
  142. $not_exist_key = 'not_exist_key_'.$row['VehicleNumber'];
  143. $not_exist = \Jiaruan\StaticCache::get($not_exist_key);
  144. // 未入库的标签缓存命中就跳过
  145. if( \Jiaruan\StaticCache::ishit($not_exist) ){
  146. continue;
  147. }
  148. try{
  149. $cond = array('DeviceNumber'=> $row['VehicleNumber'] );
  150. $vehicle_info = M('jms_vehicle')->where($cond)->field('ID,VehicleNumericId,UserId,StationCode,DeviceStatus,LicensePlate')->find();
  151. }catch (Exception $e){
  152. $msg = 'get_vehicle_info ,cach exception!! error_code = '.$e->getCode().', error_msg = '.$e->getMessage().', vehicle_no = '.$row['VehicleNumber'];
  153. decode_error_log('get_vehicle_conn_mysql_exception',$msg);
  154. continue;
  155. }
  156. //获取未入库标签,缓存十分钟,避免频繁查询
  157. if(!$vehicle_info){
  158. $result['VehicleList'][$key]['VehicleId'] = 0;
  159. $result['VehicleList'][$key]['VehicleStatus'] = -1; //-1表示不存在的车辆标签
  160. //tcp_log( 'skip save vehicle (not exists) '. $row['VehicleNumber'] );
  161. decode_error_log('not_exist_vehicles','skip save vehicle (not exists) '. $row['VehicleNumber'].',station_code:'.$result['StationCode']);
  162. \Jiaruan\StaticCache::get($not_exist_key,true,600);
  163. continue;
  164. }
  165. $row['StationCode'] = $result['StationCode'];
  166. $row['Longitude'] = $station_info['Longitude'];
  167. $row['Latitude'] = $station_info['Latitude'];
  168. $row['Address'] = $station_info['Address'];
  169. $start = microtime(true);
  170. $result['VehicleList'][$key]['VehicleId'] = $vehicle_info['VehicleNumericId'] ? : ($vehicle_info['ID']?:0);//兼容旧版本
  171. $result['VehicleList'][$key]['LastStationCode'] = $vehicle_info['StationCode'];
  172. $result['VehicleList'][$key]['VehicleStatus'] = $vehicle_info['DeviceStatus'];
  173. $result['VehicleList'][$key]['LicensePlate'] = $vehicle_info['LicensePlate'];
  174. $notkaihu_key = 'cach_notkaihu_'.$row['VehicleNumber'];
  175. $not_kaihu = \Jiaruan\StaticCache::get($notkaihu_key);
  176. //获取未开户标签缓存命中,跳过
  177. if( \Jiaruan\StaticCache::ishit($not_kaihu) ){
  178. echo 'no kaihu , cach is hit, skip,vehicle_no = '.$row['VehicleNumber'].PHP_EOL;
  179. continue;
  180. }
  181. //模拟轨迹数据,跳过更新车辆信息
  182. if(is_mock_route($row['VehicleNumber'])){
  183. echo 'mock_route,skip update jms_vehicle'.PHP_EOL;
  184. continue;
  185. }
  186. //未开户车辆,缓存十分钟,避免频繁查询
  187. if(!$vehicle_info['UserId']){
  188. echo 'no kaihu skip '.PHP_EOL;
  189. echo '************time: '.use_microtime($start).PHP_EOL;
  190. \Jiaruan\StaticCache::set($notkaihu_key,true,600);
  191. continue;
  192. }
  193. //移动基站跳过更新
  194. if($station_info['StationType']==C('基站类型_移动基站')){
  195. echo 'skip move station route '.PHP_EOL;
  196. continue;
  197. }
  198. try{
  199. if( M('jms_vehicle')->createSave($cond,$row) ){
  200. decode_log( 'save vehicle ok '. $row['VehicleNumber'] );
  201. echo '************time2:'.use_microtime($start).PHP_EOL;
  202. }else{
  203. decode_error_log( 'update_vehicle_info ', 'update_vehicle_info failed,vehicle_no = '. $row['VehicleNumber'] . ', sql = ' .M('jms_vehicle')->getLastSql().',db_error = '. M('jms_vehicle')->getDbError() );
  204. }
  205. }catch (Exception $e) {
  206. $msg = 'update_vehicle_info ,cach exception!! error_code = '.$e->getCode().', error_msg = '.$e->getMessage().', vehicle_no = '.$row['VehicleNumber'];
  207. decode_error_log('update_vehicle_conn_mysql_exception',$msg);
  208. }
  209. }
  210. /*
  211. //如果是移动基站,轨迹保存到临时监控轨迹表中
  212. if($station_info['StationType']==C('基站类型_移动基站')){
  213. $this->add_monitor_sroute($result,$station_info);
  214. }else{
  215. $this->add_normal_sroute($result,$station_info);
  216. }
  217. */
  218. //添加解包日志
  219. vehicle_route_log('decode',$result);
  220. station_route_log('decode',$result);
  221. //推送车辆轨迹信号到redis
  222. $this->push_redis_vsignal($result['VehicleList']);
  223. // tablestore
  224. if (C("是否支持表格存储")) {
  225. //if (!in_array($station_info['CityId'], [1, 28])) {//28义乌 1鹿邑
  226. // return;
  227. //}
  228. //$this->TsAddRawPacket($station_info['CityId'], $rawData);
  229. if ($station_info['StationType'] == C('基站类型_移动基站')) {
  230. $this->add_monitor_tablestore_sroute($result, $station_info);
  231. } else {
  232. $this->add_normal_tablsestore_sroute($result, $station_info);
  233. }
  234. }
  235. }
  236. /*
  237. */
  238. public function index(){
  239. $redis_raw_packet = Redis("fdqu_raw_packet","queue");
  240. //实例化信号处理类
  241. $this->rfid_proto = new Rlgs\Proto\RfidStation2();
  242. $start_time = time();
  243. do{
  244. //query one record
  245. $packet_text = $redis_raw_packet->pop();
  246. if(!$packet_text){
  247. echo 'no raw packet.'.PHP_EOL;
  248. sleep(1);
  249. continue;
  250. }
  251. //parse packet
  252. $packet = $this->rfid_proto->tcp_str2bin($packet_text);
  253. if(!$packet){
  254. $this->rfid_proto->decode_error_log('parse_fail','parse packet failed ,packet_text : '.$packet_text);
  255. continue;
  256. }
  257. $this->import($packet,$packet_text);
  258. }while(time()-$start_time<60);
  259. }
  260. /*
  261. 参数说明:
  262. signal_list:
  263. */
  264. private function push_redis_vsignal($signal_list){
  265. foreach($signal_list as $key=>$row){
  266. if($row['IsOnline']){
  267. $data = array(
  268. 'CityId' => $row['CityId'],
  269. 'VehicleNumber'=>$row['VehicleNumber'],
  270. 'StationCode'=> $row['StationCode'],
  271. 'OnlineTime' => $row['OnlineTime'],
  272. 'Timestamp' => $row['Timestamp'],
  273. 'SignalCount' => $row['SignalCount'],
  274. 'AddTime' => date('Y-m-d H:i:s'),
  275. );
  276. $r = Redis("fdqu_vehicle_signal","queue");
  277. $r->push($data);
  278. echo '成功添加一条轨迹信号到redis'. PHP_EOL;
  279. }
  280. }
  281. }
  282. /*
  283. 参数说明:
  284. result:
  285. station_info:
  286. */
  287. private function add_monitor_sroute($result, $station_info){
  288. /*
  289. //先删除该移动基站2天以前的轨迹
  290. $cond = array(
  291. 'StationId'=>$station_info['ID'],
  292. 'OnlineTime' => array( 'lt',date('Y-m-d 00:00:00',strtotime("-2 day")) )
  293. );
  294. if(M('jms_monitor_sroute')->where($cond)->find()){
  295. $result = M('jms_monitor_sroute')->where($cond)->delete();
  296. tcp_log( 'success delete 2 days ago data count : '.$result.PHP_EOL );
  297. }*/
  298. //添加车辆轨迹到临时表
  299. $addTime = date('Y-m-d H:i:s');
  300. foreach($result['VehicleList'] as $row){
  301. $row['StationCode'] = $result['StationCode'];
  302. if(!$row['VehicleId']){
  303. decode_log( '[not found]skip add route '. $row['StationName'] . ' '. $row['VehicleNumber'] );
  304. continue;
  305. }
  306. $start = microtime(true);
  307. //不接收所有标签数据的基站,要检查车辆是否已开户
  308. if(!$station_info['IsReceiveAll']){
  309. $cond = array('DeviceNumber'=>$row['VehicleNumber']);
  310. if(!M('jms_vehicle')->where($cond)->getField('UserId')){
  311. $end = microtime(true);
  312. decode_log( 'not kaihu , skip add monitor route '. $row['VehicleNumber']);
  313. continue;
  314. }
  315. }
  316. echo '************time1:'.use_microtime($start).PHP_EOL;
  317. if($row['IsOnline']){
  318. //查看车辆最近一个基站是否这个基站
  319. $row['CityId'] = $station_info['CityId'];
  320. $row['StationId'] = $station_info['StationNumericId']?:$station_info['ID'];
  321. $row['StationName'] = $station_info['DeviceName'];
  322. $row['Longitude'] = $station_info['Longitude'];
  323. $row['Latitude'] = $station_info['Latitude'];
  324. $row['Address'] = $station_info['Address'];
  325. $row['AddTime'] = $addTime;
  326. //如果是被盗状态车辆,轨迹同时保存到固定基站轨迹表
  327. $cond = array('DeviceNumber'=>$row['VehicleNumber']);
  328. $vehicle_status = M('jms_vehicle')->where($cond)->getField('DeviceStatus');
  329. $start = microtime(true);
  330. if($vehicle_status == C('车辆状态_被盗')){
  331. if( M('jms_sroute')->createAdd($row) ){
  332. decode_log( 'stolen monitor_route add to sroute ok '. $row['StationName'] . ' '. $row['VehicleNumber']);
  333. }
  334. else{
  335. decode_log( 'stolen monitor_route add to sroute fail '. $row['StationName'] . ' '. $row['VehicleNumber'] . ' sql-' .M('jms_sroute')->getLastSql());
  336. }
  337. echo '************time2:'.use_microtime($start).PHP_EOL;
  338. }
  339. $start = microtime(true);
  340. if( M('jms_monitor_sroute')->createAdd($row) )
  341. decode_log( 'add monitor_sroute ok '. $row['StationName'] . ' '. $row['VehicleNumber'] .' OnlineTime: '.$row['OnlineTime'].' ,AddTime: '.$addTime.' ,timestamp: '.$row['time']);
  342. else
  343. decode_log( 'add monitor_sroute fail '. $row['StationName'] . ' '. $row['VehicleNumber'] . ' sql-' .M('jms_sroute_tmp')->getLastSql());
  344. echo '************time3:'.use_microtime($start).PHP_EOL;
  345. }
  346. else{
  347. decode_log( '[offline]skip monitor_sroute add route '. $row['StationName'] . ' '. $row['VehicleNumber'] );
  348. }
  349. }
  350. }
  351. /*
  352. 参数说明:
  353. result:
  354. station_info:
  355. */
  356. private function add_normal_sroute($result, $station_info){
  357. //保存到轨迹表
  358. $addTime = date('Y-m-d H:i:s');
  359. foreach($result['VehicleList'] as $row){
  360. if(!$row['Timestamp']){
  361. decode_error_log('time_stamp_empty','skip update(time_stamp is empty),vehicle: '. $row['VehicleNumber'].',station_code: '.$result['StationCode']);
  362. continue;
  363. }
  364. $cond = array('DeviceNumber'=>$row['VehicleNumber']);
  365. if(!M('jms_vehicle')->where($cond)->getField('UserId')){
  366. decode_log( 'not kaihu , skip add route ' .$row['VehicleNumber'] );
  367. continue;
  368. }
  369. $row['StationCode'] = $result['StationCode'];
  370. if(! $row['VehicleId']){
  371. decode_log( '[not found]skip add route '. $row['StationName'] . ' '. $row['VehicleNumber'] );
  372. continue;
  373. }
  374. if($row['IsOnline']){
  375. //查看车辆最近一个基站是否这个基站
  376. if($result['StationCode'] != $result['LastStationCode']){ //不是的话,是个新的轨迹
  377. $row['CityId'] = $station_info['CityId'];
  378. //分表轨迹数据要,stationid要用整数类型,不能用guid类型
  379. $row['StationId'] = $station_info['StationNumericId']?:($station_info['ID']?:0);//兼容旧版本
  380. $row['StationName'] = $station_info['DeviceName'];
  381. $row['Longitude'] = $station_info['Longitude'];
  382. $row['Latitude'] = $station_info['Latitude'];
  383. $row['Address'] = $station_info['Address'];
  384. $row['AddTime'] = $addTime;
  385. $start = microtime(true);
  386. if( M('jms_vroute')->createAdd($row) )
  387. decode_log( 'add vroute ok '. $row['StationName'] . ' '. $row['VehicleNumber'] );
  388. else
  389. decode_log( 'add vroute fail '. $row['StationName'] . ' '. $row['VehicleNumber'] . ' sql-' .M('jms_route')->getLastSql());
  390. echo '************time2:'.use_microtime($start).PHP_EOL;
  391. $start = microtime(true);
  392. if( M('jms_sroute')->createAdd($row) )
  393. decode_log( 'add sroute ok '. $row['StationName'] . ' '. $row['VehicleNumber'] );
  394. else
  395. decode_log( 'add sroute fail '. $row['StationName'] . ' '. $row['VehicleNumber'] . ' sql-' .M('jms_route')->getLastSql());
  396. echo '************time3:'.use_microtime($start).PHP_EOL;
  397. //如果是被盗状态车辆,轨迹同时保存到监控轨迹表
  398. $cond = array('DeviceNumber'=>$row['VehicleNumber']);
  399. $vehicle_status = M('jms_vehicle')->where($cond)->getField('DeviceStatus');
  400. if($vehicle_status == C('车辆状态_被盗')){
  401. $row['StationType'] = C('基站类型_普通基站');
  402. $start = microtime(true);
  403. if( M('jms_monitor_sroute')->createAdd($row) ){
  404. decode_log( 'add monitor_sroute ok '. $row['StationName'] . ' '. $row['VehicleNumber'] );
  405. }
  406. else{
  407. decode_log( 'add monitor_sroute fail '. $row['StationName'] . ' '. $row['VehicleNumber'] . ' sql-' .M('jms_monitor_sroute')->getLastSql());
  408. }
  409. echo '************time1:'.use_microtime($start).PHP_EOL;
  410. }
  411. }
  412. else{
  413. decode_log( '[same-station]skip add route '. $row['StationName'] . ' '. $row['VehicleNumber'] );
  414. }
  415. }
  416. else{
  417. decode_log( '[offline]skip add route '. $row['StationName'] . ' '. $row['VehicleNumber'] );
  418. }
  419. }
  420. }
  421. /*
  422. */
  423. public function delete_monitor_route(){
  424. //先删除该移动基站2天以前的轨迹
  425. $cond = array(
  426. 'OnlineTime' => array( 'lt',date('Y-m-d 00:00:00',strtotime("-2 day")) )
  427. );
  428. if(M('jms_monitor_sroute')->where($cond)->find()){
  429. echo 'start to delete '.PHP_EOL;
  430. $result = M('jms_monitor_sroute')->where($cond)->delete();
  431. echo 'finished to delete '.PHP_EOL;
  432. decode_log( 'success delete 2 days ago data result : '.$result.PHP_EOL );
  433. }else{
  434. echo 'no data to delete '.PHP_EOL;
  435. }
  436. exit;
  437. }
  438. /*
  439. 参数说明:
  440. station_no:基站标签
  441. */
  442. private function check_station_is_cathed($station_no){
  443. $cache=S('is_cached_station_'.$station_no);
  444. if(!$cache){
  445. S('is_cached_station_'.$station_no,1,60);
  446. return false;
  447. }else{
  448. return true;
  449. }
  450. }
  451. /*
  452. 参数说明:
  453. result:
  454. station_info:
  455. */
  456. public function add_normal_tablsestore_sroute($result, $station_info){
  457. //保存到轨迹表
  458. $addTime = date('Y-m-d H:i:s');
  459. $monitorRows = []; // tablestore
  460. $normalRows = []; // tablestore
  461. foreach($result['VehicleList'] as $row){
  462. $cond = array('DeviceNumber'=>$row['VehicleNumber']);
  463. if(!M('jms_vehicle')->where($cond)->getField('UserId')){
  464. continue;
  465. }
  466. $row['StationCode'] = $result['StationCode'];
  467. if(! $row['VehicleId']){
  468. continue;
  469. }
  470. if($row['IsOnline']){
  471. //查看车辆最近一个基站是否这个基站
  472. if($result['StationCode'] != $result['LastStationCode']){ //不是的话,是个新的轨迹
  473. $row['StationType'] = C('基站类型_普通基站');//tablestore
  474. $row['CityId'] = $station_info['CityId'];
  475. //分表轨迹数据要,stationid要用整数类型,不能用guid类型
  476. $row['StationId'] = $station_info['StationNumericId']?:($station_info['ID']?:0);//兼容旧版本
  477. $row['StationName'] = $station_info['DeviceName'];
  478. $row['Longitude'] = $station_info['Longitude'];
  479. $row['Latitude'] = $station_info['Latitude'];
  480. $row['Address'] = $station_info['Address'];
  481. $row['AddTime'] = $addTime;
  482. //如果是被盗状态车辆,轨迹同时保存到监控轨迹表
  483. $cond = array('DeviceNumber'=>$row['VehicleNumber']);
  484. $vehicle_status = M('jms_vehicle')->where($cond)->getField('DeviceStatus');
  485. if($vehicle_status == C('车辆状态_被盗')){
  486. $row['StationType'] = C('基站类型_普通基站');
  487. $row['StationCode'] = $station_info['DeviceNumber'];// tablestore
  488. $monitorRows[] = $row; // tablestore
  489. } else {
  490. $row['StationCode'] = $station_info['DeviceNumber'];// tablestore
  491. }
  492. $normalRows[] = $row; // tablestore
  493. }
  494. }
  495. }
  496. $this->routeStore->addMonitorRoute($monitorRows); // tablestore
  497. $this->routeStore->addNormalRoute($normalRows); // tablestore
  498. }
  499. /*
  500. 参数说明:
  501. result:
  502. station_info:
  503. */
  504. public function add_monitor_tablestore_sroute($result, $station_info){
  505. /*
  506. //先删除该移动基站2天以前的轨迹
  507. $cond = array(
  508. 'StationId'=>$station_info['ID'],
  509. 'OnlineTime' => array( 'lt',date('Y-m-d 00:00:00',strtotime("-2 day")) )
  510. );
  511. if(M('jms_monitor_sroute')->where($cond)->find()){
  512. $result = M('jms_monitor_sroute')->where($cond)->delete();
  513. tcp_log( 'success delete 2 days ago data count : '.$result.PHP_EOL );
  514. }*/
  515. //添加车辆轨迹到临时表
  516. $monitorRows = []; // tablestore
  517. $mobileRows = []; // tablestore
  518. $addTime = date('Y-m-d H:i:s');
  519. foreach($result['VehicleList'] as $row){
  520. $row['StationCode'] = $result['StationCode'];
  521. if(!$row['VehicleId']){
  522. // tcp_log( '[not found]skip add route '. $row['StationName'] . ' '. $row['VehicleNumber'] );
  523. continue;
  524. }
  525. $start = microtime(true);
  526. //不接收所有标签数据的基站,要检查车辆是否已开户
  527. if(!$station_info['IsReceiveAll']){
  528. $cond = array('DeviceNumber'=>$row['VehicleNumber']);
  529. if(!M('jms_vehicle')->where($cond)->getField('UserId')){
  530. $end = microtime(true);
  531. // tcp_log( 'not kaihu , skip add monitor route '. $row['VehicleNumber']);
  532. continue;
  533. }
  534. }
  535. echo '************time1:'.use_microtime($start).PHP_EOL;
  536. if($row['IsOnline']){
  537. //查看车辆最近一个基站是否这个基站
  538. $row['StationType'] = C('基站类型_移动基站');// tablestore
  539. $row['CityId'] = $station_info['CityId'];
  540. $row['StationId'] = $station_info['StationNumericId']?:$station_info['ID'];
  541. $row['StationName'] = $station_info['DeviceName'];
  542. $row['Longitude'] = $station_info['Longitude'];
  543. $row['Latitude'] = $station_info['Latitude'];
  544. $row['Address'] = $station_info['Address'];
  545. $row['AddTime'] = $addTime;
  546. //如果是被盗状态车辆,轨迹同时保存到固定基站轨迹表
  547. $cond = array('DeviceNumber'=>$row['VehicleNumber']);
  548. $vehicle_status = M('jms_vehicle')->where($cond)->getField('DeviceStatus');
  549. $start = microtime(true);
  550. if($vehicle_status == C('车辆状态_被盗')){
  551. // if( M('jms_sroute')->createAdd($row) ){
  552. // tcp_log( 'stolen monitor_route add to sroute ok '. $row['StationName'] . ' '. $row['VehicleNumber']);
  553. // }
  554. // else{
  555. // tcp_log( 'stolen monitor_route add to sroute fail '. $row['StationName'] . ' '. $row['VehicleNumber'] . ' sql-' .M('jms_sroute')->getLastSql());
  556. // }
  557. // echo '************time2:'.use_microtime($start).PHP_EOL;
  558. $row['StationCode'] = $station_info['DeviceNumber'];// tablestore
  559. $monitorRows[] = $row; // tablestore
  560. } else {
  561. $row['StationCode'] = $station_info['DeviceNumber'];// tablestore
  562. }
  563. $mobileRows[] = $row; // tablestore
  564. // $start = microtime(true);
  565. // if( M('jms_monitor_sroute')->createAdd($row) )
  566. // tcp_log( 'add monitor_sroute ok '. $row['StationName'] . ' '. $row['VehicleNumber'] .' OnlineTime: '.$row['OnlineTime'].' ,AddTime: '.$addTime.' ,timestamp: '.$row['time']);
  567. // else
  568. // tcp_log( 'add monitor_sroute fail '. $row['StationName'] . ' '. $row['VehicleNumber'] . ' sql-' .M('jms_sroute_tmp')->getLastSql());
  569. // echo '************time3:'.use_microtime($start).PHP_EOL;
  570. }
  571. else{
  572. // tcp_log( '[offline]skip monitor_sroute add route '. $row['StationName'] . ' '. $row['VehicleNumber'] );
  573. }
  574. }
  575. //移动基站的数据全部添加到移动表里面
  576. //$this->routeStore->addMonitorRoute($monitorRows); // tablestore
  577. $this->routeStore->addMobileRoute($mobileRows); // tablestore
  578. }
  579. /*
  580. */
  581. public function index_test(){
  582. /*
  583. 在cli模式下,用手工生成的数据,测试解码程序使用
  584. 例子:php index.php decode/index_test '9c bc 01 31 00 ca 00 20 88 88 '
  585. */
  586. //$redis_raw_packet = Redis("fdqu_raw_packet","queue");
  587. $start_time = time();
  588. if (C("是否支持表格存储")) {
  589. //C("是否支持表格存储", false);
  590. $this->routeStore = new \Jiaruan\RouteStore();// tablestore
  591. $this->routeStore->reAddTimeoutInfo();
  592. }
  593. do{
  594. //query one record
  595. //$packet_text = $redis_raw_packet->pop();
  596. global $argv;
  597. if (count($argv) != 3 || strpos($argv[2], "9c bc") !==0) {
  598. echo "参数错误";
  599. exit();
  600. }
  601. $packet_text = $argv[2];//'9c bc 01 31 00 cd 00 10 88 88 cd 88 88 ca 01 01 00 5a 54 68 cb 58 00 01';
  602. if(!$packet_text){
  603. echo 'no raw packet.'.PHP_EOL;
  604. sleep(1);
  605. break;
  606. continue;
  607. }
  608. //parse packet
  609. $packet = tcp_str2bin($packet_text);
  610. if(!$packet){
  611. echo 'parse packet failed.'.PHP_EOL;
  612. decode_error_log('parse_fail','parse packet failed ,packet_text : '.$packet_text);
  613. break;
  614. continue;
  615. }
  616. $this->import($packet,$packet_text);
  617. break;
  618. }while(time()-$start_time<60);
  619. }
  620. /*
  621. 参数说明:
  622. cityId:
  623. data:
  624. */
  625. private function TsAddRawPacket($cityId, $data){
  626. $tableName = 'yiwushi_28_rpacket';//\Jiaruan\ClTableStoreGridTp::getCountyTableName($cityId, "rpacket");
  627. $model = new OtsModel($tableName);
  628. $addTime = strtotime($data['AddTime']);
  629. $stationMac = strtoupper(substr(md5($data['StationCode']), 0, 2)) . '-' . $data['StationCode'] . '-' . date('ymd', $addTime);
  630. $micro = str_pad(explode(' ', microtime())[0] * 1000000, 6, 0, STR_PAD_LEFT);
  631. $onlineTime = $addTime . "." . $micro;
  632. $ret = $model->add(['StationMac' => $stationMac, 'OnlineTime' => $onlineTime, 'PacketData' => $data['PacketData']]);
  633. if ($ret == false || $ret != 1) {
  634. echo $model->getError();
  635. $error = $model->getDbError();
  636. if (strpos($error, "cURL error 28:") !== false) {//received超时 记录到日志里面 需要重试
  637. } else {
  638. }
  639. echo $error;
  640. }
  641. }
  642. }