VM暫存
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

Cars_model.php 50KB

hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
hace 8 años
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425
  1. <?php
  2. /*
  3. file: cars_model.php
  4. */
  5. require_once(ALTOB_SYNC_FILE) ;
  6. define('CARS_TMP_LOG', 'cars_tmp_log'); // 暫存進出車號
  7. class Cars_model extends CI_Model
  8. {
  9. var $vars = array();
  10. var $io_name = array('I' => '車入', 'O' => '車出', 'MI' => '機入', 'MO' => '機出', 'FI' => '樓入', 'FO' => '樓出');
  11. var $now_str;
  12. function __construct()
  13. {
  14. parent::__construct();
  15. $this->load->database();
  16. $this->now_str = date('Y-m-d H:i:s');
  17. }
  18. public function init($vars)
  19. {
  20. $this->vars = $vars;
  21. }
  22. // 特殊方式進出註記
  23. public function ipcam_meta($parms)
  24. {
  25. trigger_error(__FUNCTION__ . '|特殊註記:' . print_r($parms, true));
  26. }
  27. // 車輛進出傳入車牌號碼 (2016/07/27)
  28. public function opendoor_lprio($parms)
  29. {
  30. $parms['lpr'] = urldecode($parms['lpr']);
  31. $rows = array();
  32. // $parms['ts'] = date('Y-m-d H:i:s', $parms['ts']);
  33. trigger_error(__FUNCTION__ . '|車牌傳入:' . print_r($parms, true));
  34. if ($parms['etag'] != 'NONE')
  35. {
  36. if ($parms['lpr'] != 'NONE')
  37. {
  38. // do nothing
  39. }
  40. else // 車辨失敗但有eTag, 查詢是否有車號
  41. {
  42. //$parms['lpr'] = $this->etag2lpr_2($parms['etag']); // 2017/01/10 預設都不用 ETAG 找車牌
  43. }
  44. }
  45. $rows = $this->get_member($parms['lpr']);
  46. $this->save_db_io($parms, $rows, true);
  47. return true;
  48. }
  49. // 車輛進出傳入車牌號碼
  50. public function lprio($parms)
  51. {
  52. //$parms['lpr'] = urldecode($parms['lpr']);
  53. $rows = array();
  54. // $parms['ts'] = date('Y-m-d H:i:s', $parms['ts']);
  55. trigger_error('車牌傳入:' . print_r($parms, true));
  56. if ($parms['etag'] != 'NONE')
  57. {
  58. if ($parms['lpr'] != 'NONE')
  59. {
  60. // 有車牌有eTag, 檢查資料庫是否double驗證
  61. //get_headers("http://192.168.10.201/cars.html/check_lpr_etag/{$parms['lpr']}/{$parms['etag']}");
  62. get_headers("http://localhost/cars.html/check_lpr_etag/{$parms['lpr']}/{$parms['etag']}"); // update 2016/07/26
  63. }
  64. else // 車辨失敗但有eTag, 查詢是否有車號
  65. {
  66. // $parms['lpr'] = $this->etag2lpr_2($parms['etag']); // 2017/01/10 預設都不用 ETAG 找車牌
  67. }
  68. }
  69. $rows = $this->get_member($parms['lpr']);
  70. $this->save_db_io($parms, $rows);
  71. return true;
  72. }
  73. // 入出口異動cario
  74. public function save_db_io($parms, $rows, $opendoor=false)
  75. {
  76. if (!empty($rows['lpr_correct'])) $parms['lpr'] = $rows['lpr_correct'];
  77. // [START] 擋重覆 20170912 前端不止一筆 opendoor 送來時, 只處理第一個 (限 2 sec 內)
  78. if($opendoor)
  79. {
  80. $skip_or_not = false;
  81. $new_cars_tmp = array
  82. (
  83. 'timestamp' => time(),
  84. 'sno_io' => $parms['sno'] . $parms['io'],
  85. 'lpr' => $parms['lpr']
  86. );
  87. $cars_tmp_arr = array();
  88. $cars_tmp_log_arr = $this->vars['mcache']->get(CARS_TMP_LOG);
  89. if(!empty($cars_tmp_log_arr))
  90. {
  91. foreach($cars_tmp_log_arr as $tmp)
  92. {
  93. if(isset($tmp['timestamp']) && $tmp['timestamp'] > time() - 2) // 時限內才判斷
  94. {
  95. array_push($cars_tmp_arr, $tmp);
  96. }
  97. }
  98. }
  99. // 判斷是否繼續
  100. foreach($cars_tmp_arr as $tmp)
  101. {
  102. if( $new_cars_tmp['lpr'] == $tmp['lpr'] &&
  103. $new_cars_tmp['sno_io'] == $tmp['sno_io'])
  104. {
  105. $skip_or_not = true;
  106. }
  107. }
  108. // 更新
  109. array_push($cars_tmp_arr, $new_cars_tmp);
  110. $this->vars['mcache']->set(CARS_TMP_LOG, $cars_tmp_arr);
  111. trigger_error(__FUNCTION__ . '..new ' . CARS_TMP_LOG . " |s:{$skip_or_not}|" . print_r($cars_tmp_arr, true));
  112. // 跳過
  113. if($skip_or_not)
  114. {
  115. trigger_error(__FUNCTION__ . '..skip..');
  116. return false;
  117. }
  118. }
  119. // [END] 擋重覆
  120. // 車辨失敗, 結束
  121. if ($parms['lpr'] == 'NONE')
  122. {
  123. if($opendoor)
  124. {
  125. $this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_MSG.",1,{$parms['ivsno']}".MQ_ALTOB_MSG_END_TAG);
  126. // $this->mq_send(MQ_TOPIC_SUBTEXT, "{$parms['ivsno']},車辨失敗");
  127. if(substr($parms['io'], -strlen('O')) === 'O')
  128. {
  129. // [acer] cmd:102 離場車辨失敗流程 START
  130. $this->call_acer('102', array('cario_no' => 0, 'ivs_no' => $parms['ivsno'], 'msg_code' => 1));
  131. // [acer] cmd:102 離場車辨失敗流程 END
  132. }
  133. }
  134. else
  135. {
  136. if(substr($parms['io'], -strlen('I')) === 'I')
  137. {
  138. // [acer] cmd:101 入場車辨失敗流程 START
  139. $ticket_no = $this->gen_pass_code();
  140. $data = array
  141. (
  142. 'station_no' => $parms['sno'],
  143. 'obj_type' => 1,
  144. 'obj_id' => $parms['lpr'],
  145. 'etag' => $parms['etag'] == 'NONE' ? '' : $parms['etag'],
  146. 'in_out' => $parms['io'],
  147. 'member_no' => 0,
  148. 'finished' => 0,
  149. 'in_time' => $this->now_str,
  150. 'in_lane' => $parms['ivsno'],
  151. 'in_pic_name' => empty($parms['pic_name']) ? '' : $parms['pic_name'],
  152. 'out_before_time' => date("Y-m-d H:i:s"),
  153. 'ticket_no' => $ticket_no
  154. );
  155. $this->db->insert('cario', $data);
  156. trigger_error("[車辨失敗] 新增入場資料:".print_r($parms, true));
  157. $acer_parms = array
  158. (
  159. 'cario_no' => $this->db->insert_id(),
  160. 'in_time' => $this->now_str,
  161. 'ticket_no' => $ticket_no,
  162. 'lpr' => '',
  163. 'ivs_no' => $parms['ivsno']
  164. );
  165. $this->call_acer('101', $acer_parms);
  166. // [acer] cmd:101 入場車辨失敗流程 END
  167. }
  168. }
  169. return false;
  170. }
  171. $msg = $rows['member_no'] != 0 ? "{$parms['lpr']}." : $parms['lpr']; // 月租車號加.符號
  172. // 月租鎖車, 結束
  173. //if (($parms['io'] == 'CO' || $parms['io'] == 'MO') && $rows['member_no'] != 0 && !empty($rows['locked']) && $rows['locked'] == 1)
  174. if ((substr($parms['io'], -strlen('O')) === 'O') && $rows['member_no'] != 0 && !empty($rows['locked']) && $rows['locked'] == 1)
  175. {
  176. if($opendoor){
  177. //// $this->mq_send(MQ_TOPIC_SUBTEXT, "{$parms['ivsno']},{$msg}已鎖車!");
  178. $this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_MSG.",2,{$parms['ivsno']},{$parms['lpr']}".MQ_ALTOB_MSG_END_TAG);
  179. // $this->mq_send(MQ_TOPIC_SUBTEXT, "{$parms['ivsno']},{$msg}禁止離場請後退");
  180. // [acer] cmd:102 離場車辨已鎖車 START
  181. $this->call_acer('102', array('cario_no' => 0, 'ivs_no' => $parms['ivsno'], 'msg_code' => 2));
  182. // [acer] cmd:102 離場車辨已鎖車 END
  183. }
  184. return false;
  185. }
  186. // 取得會員資訊
  187. $parms['member_no'] = $rows['member_no'];
  188. switch($parms['io'])
  189. {
  190. case 'CI':
  191. case 'MI':
  192. if($opendoor){
  193. // 開門
  194. /*
  195. if ($rows['member_no'] != 0)
  196. {
  197. $this->member_opendoors($parms);
  198. }
  199. else
  200. {
  201. $this->temp_opendoors($parms);
  202. }
  203. */
  204. // 取得出入口 888 資訊
  205. /*
  206. $pks_888_arr = $this->get_888_info($parms);
  207. if ($pks_888_arr['availables'] == 0)
  208. {
  209. if ($rows['member_no'] == 0)
  210. {
  211. // 滿車訊號 (臨停)
  212. $this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_MSG.",14,{$parms['ivsno']},{$parms['lpr']}".MQ_ALTOB_MSG_END_TAG);
  213. // 開門訊號 (臨停)
  214. $this->temp_opendoors($parms);
  215. return false;
  216. }
  217. else
  218. {
  219. // 滿車訊號 (會員)
  220. $this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_MSG.",15,{$parms['ivsno']},{$parms['lpr']}".MQ_ALTOB_MSG_END_TAG);
  221. }
  222. }
  223. */
  224. // 空車位導引
  225. $pks_arr = $this->get_valid_seat();
  226. if ($pks_arr['result']['location_no'] != 0)
  227. {
  228. $pks_loc_name = $pks_arr['loc_name'];
  229. $pks_loc_no = $pks_arr['result']['location_no'];
  230. $pks_floors = $pks_arr['floors'];
  231. }
  232. else
  233. {
  234. $pks_loc_name = 0;
  235. $pks_loc_no = 0;
  236. $pks_floors = 0;
  237. }
  238. // 訊息
  239. if ($rows['member_no'] == 0)
  240. {
  241. $ck = md5($parms['lpr']);
  242. $jdata = file_get_contents("http://localhost/allpa_service.html/get_allpa_valid_user/{$parms['lpr']}/{$ck}");
  243. $results = json_decode($jdata, true);
  244. if($results['result_code'] == 0)
  245. {
  246. // 歐pa, 開門
  247. $this->member_opendoors($parms);
  248. // 歐pa, 進場
  249. $this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_MSG.",3,{$parms['ivsno']},{$parms['lpr']},{$pks_floors},{$pks_loc_no}".MQ_ALTOB_MSG_END_TAG);
  250. // old msg
  251. // $this->mq_send(MQ_TOPIC_SUBTEXT, "{$parms['ivsno']},{$msg},歐pa卡用戶您好:請停{$pks_loc_name}{$pks_loc_no}車位");
  252. }
  253. else
  254. {
  255. // 臨停車, 開門 (同會員)
  256. $this->temp_opendoors($parms);
  257. // 臨停車, 進場
  258. $this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_MSG.",11,{$parms['ivsno']},{$parms['lpr']},{$pks_floors},{$pks_loc_no}".MQ_ALTOB_MSG_END_TAG);
  259. // old msg
  260. // $this->mq_send(MQ_TOPIC_SUBTEXT, "{$parms['ivsno']},{$msg}請停{$pks_loc_name}{$pks_loc_no}車位");
  261. }
  262. }
  263. else
  264. {
  265. // 會員, 開門
  266. $this->member_opendoors($parms);
  267. // 會員, 進場
  268. $this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_MSG.",4,{$parms['ivsno']},{$parms['lpr']},{$pks_floors},{$pks_loc_no}".MQ_ALTOB_MSG_END_TAG);
  269. // old msg
  270. // $this->mq_send(MQ_TOPIC_SUBTEXT, "{$parms['ivsno']},{$msg},月租戶請進場:請停{$pks_loc_name}{$pks_loc_no}車位");
  271. }
  272. }else{
  273. // 資料流
  274. if ($parms['lpr'] != 'NONE')
  275. {
  276. $data = array
  277. (
  278. 'err' => 1,
  279. 'finished' => 1
  280. );
  281. // 原有歷史記錄, 設定錯誤碼為1(入場不應該有歷史記錄)
  282. $this->db->update('cario', $data, array('obj_id' => $parms['lpr'], 'finished' => 0, 'err' => 0, 'obj_type' => 1));
  283. $affect_rows = $this->db->affected_rows();
  284. if ($affect_rows > 0)
  285. {
  286. trigger_error("err://入場郤已有歷史進場記錄[{$affect_rows}]筆,已設成錯誤並結清記錄".print_r($parms, true));
  287. }
  288. }
  289. // [acer] cmd:101 入場車辨成功流程 START
  290. $ticket_no = $this->gen_pass_code();
  291. $data = array
  292. (
  293. 'station_no' => $parms['sno'],
  294. 'obj_type' => 1,
  295. 'obj_id' => $parms['lpr'],
  296. 'etag' => $parms['etag'] == 'NONE' ? '' : $parms['etag'],
  297. 'in_out' => $parms['io'],
  298. 'member_no' => $rows['member_no'],
  299. 'finished' => 0,
  300. 'in_time' => $this->now_str,
  301. 'in_lane' => $parms['ivsno'],
  302. 'in_pic_name' => empty($parms['pic_name']) ? '' : $parms['pic_name'],
  303. 'out_before_time' => date("Y-m-d H:i:s"),
  304. //'out_before_time' => date('Y-m-d H:i:s', strtotime(" + 15 minutes")), // 15分鐘內, 可直接離場
  305. 'ticket_no' => $ticket_no
  306. );
  307. $this->db->insert('cario', $data);
  308. trigger_error("新增入場資料:".print_r($parms, true));
  309. $acer_parms = array
  310. (
  311. 'cario_no' => $this->db->insert_id(),
  312. 'in_time' => $this->now_str,
  313. 'ticket_no' => $ticket_no,
  314. 'lpr' => $parms['lpr'],
  315. 'ivs_no' => $parms['ivsno']
  316. );
  317. $this->call_acer('101', $acer_parms);
  318. // [acer] cmd:101 入場車辨成功流程 END
  319. // 傳送進場記錄
  320. $sync_agent = new AltobSyncAgent();
  321. $sync_agent->init($parms['sno'], $this->now_str);
  322. $sync_agent->cario_no = $this->db->insert_id(); // 進出編號
  323. $sync_agent->member_no = $rows['member_no']; // 會員編號
  324. $sync_result = $sync_agent->sync_st_in($parms);
  325. trigger_error( "..sync_st_in.." . $sync_result);
  326. }
  327. break;
  328. // 出場
  329. case 'CO':
  330. case 'MO':
  331. // 讀取最近一筆入場資料
  332. $rows_cario = $this->db
  333. ->select('cario_no, payed, in_time, pay_time, out_before_time')
  334. ->from('cario')
  335. //->where(array('in_out' => 'CI', 'obj_id' => $parms['lpr'], 'finished' => 0, 'err' => 0))
  336. ->where(array('obj_id' => $parms['lpr'], 'err' => 0))
  337. ->order_by('cario_no', 'desc')
  338. ->limit(1)
  339. ->get()
  340. ->row_array();
  341. trigger_error("opendoor={$opendoor}| 出場讀到資料:{$rows['member_no']}|".time().'|'.print_r($rows_cario, true));
  342. if (!empty($rows_cario['cario_no'])) // 在限時內可出場
  343. {
  344. $co_time_minutes = floor((strtotime($this->now_str) - strtotime($rows_cario['in_time'])) / 60); // 停車時數 (分鐘)
  345. // 合規定者開門放行
  346. switch(true)
  347. {
  348. case $rows['member_no'] != 0:
  349. // CO.A.1 會員車
  350. // 判斷時段租是否超時 (超過 12 小時)
  351. if($rows['park_time'] != 'RE' && $co_time_minutes > 720)
  352. {
  353. if($opendoor)
  354. {
  355. // 時段租超時字幕
  356. $this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_MSG.",16,{$parms['ivsno']},{$parms['lpr']}".MQ_ALTOB_MSG_END_TAG);
  357. // [acer] cmd:102 離場車辨成功流程 START
  358. $this->call_acer('102', array('cario_no' => $rows_cario['cario_no'], 'ivs_no' => $parms['ivsno'], 'msg_code' => 16));
  359. // [acer] cmd:102 離場車辨成功流程 END
  360. }
  361. else
  362. {
  363. $data = array
  364. (
  365. 'out_time' => $this->now_str,
  366. 'out_lane' => $parms['ivsno'],
  367. 'minutes' => $co_time_minutes,
  368. 'out_pic_name' => $parms['pic_name']
  369. );
  370. $this->db->update('cario', $data, array('cario_no' => $rows_cario['cario_no'])); // 記錄出場
  371. trigger_error("{$parms['lpr']}|時段租超時" . print_r($rows_cario, true));
  372. // 傳送離場記錄
  373. $sync_agent = new AltobSyncAgent();
  374. $sync_agent->init($parms['sno'], $this->now_str);
  375. $sync_agent->cario_no = $rows_cario['cario_no']; // 進出編號
  376. $sync_agent->member_no = $rows['member_no']; // 會員編號
  377. $sync_agent->in_time = $rows_cario['in_time']; // 入場時間
  378. $sync_result = $sync_agent->sync_st_out($parms);
  379. trigger_error( "..sync_st_out.." . $sync_result);
  380. }
  381. return false;
  382. }
  383. if($opendoor)
  384. {
  385. // 會員開門
  386. $this->member_opendoors($parms);
  387. // 會員字幕
  388. $this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_MSG.",5,{$parms['ivsno']},{$parms['lpr']}".MQ_ALTOB_MSG_END_TAG);
  389. // $this->mq_send(MQ_TOPIC_SUBTEXT, "{$parms['ivsno']},{$msg}謝謝光臨");
  390. // [acer] cmd:102 離場車辨成功流程 START
  391. $this->call_acer('102', array('cario_no' => $rows_cario['cario_no'], 'ivs_no' => $parms['ivsno'], 'msg_code' => 5));
  392. // [acer] cmd:102 離場車辨成功流程 END
  393. }
  394. else
  395. {
  396. $data = array
  397. (
  398. 'in_out' => $parms['io'],
  399. 'finished' => 1,
  400. 'out_time' => $this->now_str,
  401. 'out_lane' => $parms['ivsno'],
  402. 'minutes' => $co_time_minutes,
  403. 'out_pic_name' => $parms['pic_name']
  404. );
  405. $this->db->update('cario', $data, array('cario_no' => $rows_cario['cario_no']));
  406. trigger_error('會員車離場:' . print_r($rows, true));
  407. // 傳送離場記錄
  408. $sync_agent = new AltobSyncAgent();
  409. $sync_agent->init($parms['sno'], $this->now_str);
  410. $sync_agent->cario_no = $rows_cario['cario_no']; // 進出編號
  411. $sync_agent->member_no = $rows['member_no']; // 會員編號
  412. $sync_agent->in_time = $rows_cario['in_time']; // 入場時間
  413. $sync_agent->finished = 1; // 已離場
  414. $sync_result = $sync_agent->sync_st_out($parms);
  415. trigger_error( "..sync_st_out.." . $sync_result);
  416. }
  417. break;
  418. case strtotime($rows_cario['out_before_time']) >= time():
  419. if ($rows_cario['payed'])
  420. {
  421. // CO.B.1 臨停車已付款
  422. if($opendoor)
  423. {
  424. // 臨停開門
  425. $this->temp_opendoors($parms);
  426. // 臨停字幕
  427. $this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_MSG.",6,{$parms['ivsno']},{$parms['lpr']}".MQ_ALTOB_MSG_END_TAG);
  428. //// $this->mq_send(MQ_TOPIC_SUBTEXT, "{$parms['ivsno']},{$msg}付款確認請 離 場謝謝光臨");
  429. // $this->mq_send(MQ_TOPIC_SUBTEXT, "{$parms['ivsno']},{$msg}謝謝光臨");
  430. // [acer] cmd:102 離場車辨成功流程 START
  431. $this->call_acer('102', array('cario_no' => $rows_cario['cario_no'], 'ivs_no' => $parms['ivsno'], 'msg_code' => 6));
  432. // [acer] cmd:102 離場車辨成功流程 END
  433. }
  434. else
  435. {
  436. $data = array
  437. (
  438. 'in_out' => $parms['io'],
  439. 'finished' => 1,
  440. 'out_time' => $this->now_str,
  441. 'out_lane' => $parms['ivsno'],
  442. 'minutes' => $co_time_minutes,
  443. 'out_pic_name' => $parms['pic_name']
  444. );
  445. $this->db->update('cario', $data, array('cario_no' => $rows_cario['cario_no']));
  446. trigger_error('臨停車已付款:' . print_r($rows, true));
  447. // 傳送離場記錄
  448. $sync_agent = new AltobSyncAgent();
  449. $sync_agent->init($parms['sno'], $this->now_str);
  450. $sync_agent->cario_no = $rows_cario['cario_no']; // 進出編號
  451. $sync_agent->in_time = $rows_cario['in_time']; // 入場時間
  452. $sync_agent->finished = 1; // 已離場
  453. $sync_result = $sync_agent->sync_st_out($parms);
  454. trigger_error( "..sync_st_out.." . $sync_result);
  455. }
  456. }
  457. else
  458. {
  459. // CO.B.2 臨停車未付款
  460. if($opendoor)
  461. {
  462. // 臨停字幕
  463. $this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_MSG.",8,{$parms['ivsno']},{$parms['lpr']}".MQ_ALTOB_MSG_END_TAG);
  464. // $this->mq_send(MQ_TOPIC_SUBTEXT, "{$parms['ivsno']},{$msg}臨時車請投票卡或刷卡出場");
  465. // [acer] cmd:102 離場車辨成功流程 START
  466. $this->call_acer('102', array('cario_no' => $rows_cario['cario_no'], 'ivs_no' => $parms['ivsno'], 'msg_code' => 8));
  467. // [acer] cmd:102 離場車辨成功流程 END
  468. }
  469. else
  470. {
  471. // TODO: 歐pa卡離場記錄和臨停未付款一樣, 待更正
  472. $data = array
  473. (
  474. 'out_time' => $this->now_str,
  475. 'out_lane' => $parms['ivsno'],
  476. 'minutes' => $co_time_minutes,
  477. 'out_pic_name' => $parms['pic_name']
  478. );
  479. $this->db->update('cario', $data, array('cario_no' => $rows_cario['cario_no'])); // 記錄出場
  480. trigger_error('臨停未付款:' . print_r($rows, true));
  481. // 傳送離場記錄
  482. $sync_agent = new AltobSyncAgent();
  483. $sync_agent->init($parms['sno'], $this->now_str);
  484. $sync_agent->cario_no = $rows_cario['cario_no']; // 進出編號
  485. $sync_agent->in_time = $rows_cario['in_time']; // 入場時間
  486. $sync_result = $sync_agent->sync_st_out($parms);
  487. trigger_error( "..sync_st_out.." . $sync_result);
  488. // [mitac] 要求 mitac 扣款 START
  489. $this->call_mitac_pay($parms['lpr'], $parms['ivsno'], $rows_cario);
  490. // [mitac] 要求 mitac 扣款 END
  491. }
  492. }
  493. break;
  494. default:
  495. // CO.C.1 其它付款方式
  496. if($opendoor)
  497. {
  498. $in_time = strtotime($rows_cario['out_before_time']);
  499. $ck = md5($in_time. $parms['lpr'] . $parms['sno']);
  500. //$jdata = file_get_contents("http://localhost/allpa_service.html/allpa_go/{$in_time}/{$parms['lpr']}/{$parms['sno']}/{$ck}");
  501. $jdata = file_get_contents("http://localhost/allpa_service.html/allpa_go_remote/{$in_time}/{$parms['lpr']}/{$parms['sno']}/{$ck}");
  502. trigger_error("allpa回傳:{$jdata}|{$in_time}/{$parms['lpr']}/{$parms['sno']}/{$ck}");
  503. $results = json_decode($jdata, true);
  504. if (isset($results['result_code'])) // 歐pa卡, 點數足夠扣
  505. {
  506. if($results['result_code'] == 0)
  507. {
  508. // 臨停開門
  509. $this->temp_opendoors($parms);
  510. // 歐pa卡, 字幕
  511. $this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_MSG.",7,{$parms['ivsno']},{$parms['lpr']},{$results['amt']}".MQ_ALTOB_MSG_END_TAG);
  512. // // $this->mq_send(MQ_TOPIC_SUBTEXT, "{$parms['ivsno']},{$msg}扣{$results['amt']}點請離場");
  513. // $this->mq_send(MQ_TOPIC_SUBTEXT, "{$parms['ivsno']},{$msg}請離場歐pa卡扣:{$results['amt']}點謝謝光臨");
  514. // updated 2016/09/01
  515. $data = array(
  516. 'out_before_time' => date('Y-m-d H:i:s', strtotime(" + 15 minutes")),
  517. 'pay_time' => $this->now_str,
  518. 'pay_type' => 9, // 歐pa卡
  519. 'payed' => 1
  520. );
  521. $this->db->update('cario', $data, array('cario_no' => $rows_cario['cario_no'])); // 記錄出場
  522. // [acer] cmd:102 離場車辨成功流程 START
  523. $this->call_acer('102', array('cario_no' => $rows_cario['cario_no'], 'ivs_no' => $parms['ivsno'], 'msg_code' => 7));
  524. // [acer] cmd:102 離場車辨成功流程 END
  525. }
  526. else if ($results['result_code'] == 12) // 歐pa卡, 餘額不足
  527. {
  528. // 臨停字幕
  529. $this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_MSG.",12,{$parms['ivsno']},{$parms['lpr']}".MQ_ALTOB_MSG_END_TAG);
  530. // [acer] cmd:102 離場車辨成功流程 START
  531. $this->call_acer('102', array('cario_no' => $rows_cario['cario_no'], 'ivs_no' => $parms['ivsno'], 'msg_code' => 12));
  532. // [acer] cmd:102 離場車辨成功流程 END
  533. }
  534. else if ($results['result_code'] == 11) // 歐pa卡, 查無會員
  535. {
  536. // 臨停字幕
  537. $this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_MSG.",9,{$parms['ivsno']},{$parms['lpr']}".MQ_ALTOB_MSG_END_TAG);
  538. //// $this->mq_send(MQ_TOPIC_SUBTEXT, "{$parms['ivsno']},{$msg}其它付款方式");
  539. // $this->mq_send(MQ_TOPIC_SUBTEXT, "{$parms['ivsno']},{$msg}臨時車請投票卡或刷卡出場");
  540. // [acer] cmd:102 離場車辨成功流程 START
  541. $this->call_acer('102', array('cario_no' => $rows_cario['cario_no'], 'ivs_no' => $parms['ivsno'], 'msg_code' => 9));
  542. // [acer] cmd:102 離場車辨成功流程 END
  543. }
  544. else
  545. {
  546. // 臨停字幕
  547. $this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_MSG.",9,{$parms['ivsno']},{$parms['lpr']}".MQ_ALTOB_MSG_END_TAG);
  548. // [acer] cmd:102 離場車辨成功流程 START
  549. $this->call_acer('102', array('cario_no' => $rows_cario['cario_no'], 'ivs_no' => $parms['ivsno'], 'msg_code' => 9));
  550. // [acer] cmd:102 離場車辨成功流程 END
  551. }
  552. }
  553. else
  554. {
  555. // 臨停字幕
  556. $this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_MSG.",9,{$parms['ivsno']},{$parms['lpr']}".MQ_ALTOB_MSG_END_TAG);
  557. // [acer] cmd:102 離場車辨成功流程 START
  558. $this->call_acer('102', array('cario_no' => $rows_cario['cario_no'], 'ivs_no' => $parms['ivsno'], 'msg_code' => 9));
  559. // [acer] cmd:102 離場車辨成功流程 END
  560. }
  561. }
  562. else
  563. {
  564. $data = array
  565. (
  566. 'out_time' => $this->now_str,
  567. 'out_lane' => $parms['ivsno'],
  568. 'minutes' => $co_time_minutes,
  569. 'out_pic_name' => $parms['pic_name']
  570. );
  571. $this->db->update('cario', $data, array('cario_no' => $rows_cario['cario_no'])); // 記錄出場
  572. trigger_error("{$parms['lpr']}|其它付款方式:" . print_r($rows_cario, true));
  573. // 傳送離場記錄
  574. $sync_agent = new AltobSyncAgent();
  575. $sync_agent->init($parms['sno'], $this->now_str);
  576. $sync_agent->cario_no = $rows_cario['cario_no']; // 進出編號
  577. $sync_agent->in_time = $rows_cario['in_time']; // 入場時間
  578. $sync_result = $sync_agent->sync_st_out($parms);
  579. trigger_error( "..sync_st_out.." . $sync_result);
  580. // [mitac] 要求 mitac 扣款 START
  581. $this->call_mitac_pay($parms['lpr'], $parms['ivsno'], $rows_cario);
  582. // [mitac] 要求 mitac 扣款 END
  583. }
  584. break;
  585. }
  586. }
  587. else if ($rows['member_no'] != 0)
  588. {
  589. // CO.Z.1 月租車無入場資料
  590. if($opendoor)
  591. {
  592. // 會員開門
  593. $this->member_opendoors($parms);
  594. // 會員字幕
  595. $this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_MSG.",10,{$parms['ivsno']},{$parms['lpr']}".MQ_ALTOB_MSG_END_TAG);
  596. // $this->mq_send(MQ_TOPIC_SUBTEXT, "{$parms['ivsno']},{$msg}月租戶請離場謝謝光臨");
  597. // [acer] cmd:102 離場車辨成功流程 START
  598. $this->call_acer('102', array('cario_no' => $rows_cario['cario_no'], 'ivs_no' => $parms['ivsno'], 'msg_code' => 10));
  599. // [acer] cmd:102 離場車辨成功流程 END
  600. }
  601. else
  602. {
  603. trigger_error('月租車無入場資料:' . print_r($rows, true));
  604. // 傳送離場記錄
  605. $sync_agent = new AltobSyncAgent();
  606. $sync_agent->init($parms['sno'], $this->now_str);
  607. $sync_agent->member_no = $rows['member_no']; // 會員編號
  608. $sync_agent->finished = 1; // 已離場
  609. $sync_result = $sync_agent->sync_st_out($parms);
  610. trigger_error( "..sync_st_out.." . $sync_result);
  611. }
  612. }
  613. else
  614. {
  615. // CO.Z.Z 無入場資料
  616. if($opendoor)
  617. {
  618. $this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_MSG.",13,{$parms['ivsno']},{$parms['lpr']}".MQ_ALTOB_MSG_END_TAG);
  619. // [acer] cmd:102 離場車辨成功流程 START
  620. $this->call_acer('102', array('cario_no' => 0, 'ivs_no' => $parms['ivsno'], 'msg_code' => 13));
  621. // [acer] cmd:102 離場車辨成功流程 END
  622. }
  623. else
  624. {
  625. trigger_error('無入場資料:' . print_r($rows, true));
  626. // 傳送離場記錄
  627. $sync_agent = new AltobSyncAgent();
  628. $sync_agent->init($parms['sno'], $this->now_str);
  629. $sync_result = $sync_agent->sync_st_out($parms);
  630. trigger_error( "..sync_st_out.." . $sync_result);
  631. }
  632. }
  633. break;
  634. }
  635. }
  636. // 檢查是否合法會員或VIP資料
  637. public function get_member($lpr)
  638. {
  639. $where_arr = array
  640. (
  641. 'c.lpr' => $lpr,
  642. 'c.start_time <=' => $this->now_str,
  643. 'c.end_time >=' => $this->now_str
  644. );
  645. $sql = "select
  646. c.lpr_correct,
  647. c.member_no,
  648. m.member_name,
  649. m.member_type,
  650. m.locked,
  651. m.remarks,
  652. m.park_time,
  653. m.suspended,
  654. m.valid_time,
  655. c.etag,
  656. c.start_time,
  657. c.end_time
  658. from member_car c, members m
  659. where c.member_no = m.member_no
  660. and c.start_time <= '{$this->now_str}'
  661. and c.end_time >= '{$this->now_str}'
  662. and c.lpr = '{$lpr}'
  663. limit 1";
  664. $rows = $this->db->query($sql)->row_array();
  665. // 新增 park_time_check 2016/11/11
  666. $park_time_check = 0;
  667. if (!empty($rows['lpr_correct']))
  668. {
  669. $park_time = $rows['park_time'];
  670. $pt_arr = $this->vars['mcache']->get('pt');
  671. if(empty($pt_arr) || empty($park_time))
  672. {
  673. // ERROR: 無法驗証時段, 跳過時段限制判斷
  674. trigger_error("[ERROR] mcache.pt is empty !!");
  675. $park_time_check = 1;
  676. }
  677. else
  678. {
  679. $now_time = substr($this->now_str, 11); // 日期字串只取最後時間字串(13:25:32)
  680. $week_no = date('w',strtotime($this->now_str)); // 取星期幾
  681. $park_time_array = explode(',', $park_time); // 用 , 格開
  682. foreach($park_time_array as $idx => $park_time_value)
  683. {
  684. foreach($pt_arr[$park_time_value]['timex'] as $idx => $pt_rows)
  685. {
  686. if ($week_no >= $pt_rows['w_start'] &&
  687. $week_no <= $pt_rows['w_end'] &&
  688. $now_time >= $pt_rows['time_start'] &&
  689. $now_time <= $pt_rows['time_end'])
  690. {
  691. $park_time_check = 2;
  692. trigger_error("時段代碼:{$park_time_value} 星期:{$week_no}");
  693. break;
  694. }
  695. }
  696. }
  697. }
  698. }
  699. if (empty($rows['lpr_correct'])) // A. 非月租車
  700. {
  701. $rows = array
  702. (
  703. 'lpr_correct' => '',
  704. 'member_no' => 0,
  705. 'member_name' => '',
  706. 'member_type' => 9,
  707. 'etag' => '',
  708. 'start_time' => '',
  709. 'end_time' => '',
  710. );
  711. }
  712. else if(empty($park_time_check)) // B. 月租車, 時段無效
  713. {
  714. trigger_error("無效的時段!! " . print_r($rows, true));
  715. $rows = array
  716. (
  717. 'lpr_correct' => '',
  718. 'member_no' => 0,
  719. 'member_name' => '',
  720. 'member_type' => 9,
  721. 'etag' => '',
  722. 'start_time' => '',
  723. 'end_time' => '',
  724. );
  725. }
  726. else if(!empty($rows['suspended'])) // C. 月租車, 停權中
  727. {
  728. trigger_error("停權中!! " . print_r($rows, true));
  729. $rows = array
  730. (
  731. 'lpr_correct' => '',
  732. 'member_no' => 0,
  733. 'member_name' => '',
  734. 'member_type' => 9,
  735. 'etag' => '',
  736. 'start_time' => '',
  737. 'end_time' => '',
  738. );
  739. }
  740. else if(!empty($rows['valid_time']) && $rows['valid_time'] < $this->now_str) // D. 月租車, 已無效 (審核未通過)
  741. {
  742. trigger_error("已無效!! " . print_r($rows, true));
  743. $rows = array
  744. (
  745. 'lpr_correct' => '',
  746. 'member_no' => 0,
  747. 'member_name' => '',
  748. 'member_type' => 9,
  749. 'etag' => '',
  750. 'start_time' => '',
  751. 'end_time' => '',
  752. );
  753. }
  754. trigger_error('讀取會員:' . print_r($rows, true) . ", park_time_check: {$park_time_check}");
  755. // 20171025 強制先不導入會員
  756. $rows = array
  757. (
  758. 'lpr_correct' => '',
  759. 'member_no' => 0,
  760. 'member_name' => '',
  761. 'member_type' => 9,
  762. 'etag' => '',
  763. 'start_time' => '',
  764. 'end_time' => '',
  765. );
  766. trigger_error(__FUNCTION__ . '..force not found..');
  767. return $rows;
  768. }
  769. /*
  770. // 開門 (月租)
  771. public function member_opendoors($parms)
  772. {
  773. $this->mq_send(MQ_TOPIC_OPEN_DOOR, "DO{$parms['ivsno']},OPEN,{$parms['lpr']}");
  774. return true;
  775. }
  776. // 開門 (臨停)
  777. public function temp_opendoors($parms)
  778. {
  779. $this->mq_send(MQ_TOPIC_OPEN_DOOR, "DO{$parms['ivsno']},TICKET,{$parms['lpr']}");
  780. return true;
  781. }
  782. */
  783. // 用eTag讀出車號
  784. public function etag2lpr_2($etag)
  785. {
  786. // 用讀取eTag記錄(有double驗證過)
  787. $rows = $this->db->select('lpr')
  788. ->from('etag_lpr')
  789. ->where(array('etag' => $etag, 'confirms >' => 0))
  790. ->limit(1)
  791. ->get()
  792. ->row_array();
  793. // 讀出eTag資料
  794. if (!empty($rows['lpr']))
  795. {
  796. trigger_error("+++車牌NONE,以eTag讀入車牌:{$etag}|{$rows['lpr']}");
  797. return $rows['lpr'];
  798. }
  799. return 'NONE';
  800. }
  801. // 有車牌與eTag, 檢查資料庫 (2017/03/22 new)
  802. public function check_lpr_etag($lpr, $etag)
  803. {
  804. $ETAG_LOG_TITLE = 'etag://';
  805. $ETAG_WARMIN_TITLE = 'etag-warning://';
  806. trigger_error($ETAG_LOG_TITLE. "輸入: {$lpr},{$etag}");
  807. // 手動值上下限
  808. $max_admin_confirms_value = 99;
  809. $min_admin_confirms_value = 50;
  810. // 自動值上下限
  811. $max_system_confirms_value = 33;
  812. $min_system_confirms_value = 0;
  813. // 判斷對應加權
  814. $etag_confirms_bias_plus = 11; // etag 找 車牌, 對上一次可扺 11次
  815. $etag_confirms_bias_minus = -1;
  816. $lpr_confirms_bias_plus = 3; // 車牌 找 etag, 對上一次可扺 3次
  817. $lpr_confirms_bias_minus = -1;
  818. // eTag 找 車牌
  819. $lpr_info_from_etag = $this->db->select('lpr, confirms')
  820. ->from('etag_lpr')
  821. ->where(array('etag' => $etag))
  822. ->limit(1)
  823. ->get()
  824. ->row_array();
  825. if (!empty($lpr_info_from_etag['lpr']))
  826. {
  827. // B. etag 有找到 車牌
  828. if ($lpr_info_from_etag['lpr'] == $lpr)
  829. {
  830. // B.1. etag 有找到 車牌, 且 車牌 相符, confirms 上升
  831. $confirms_bias = $etag_confirms_bias_plus;
  832. }
  833. else
  834. {
  835. // B.2. etag 有找到 車牌, 但 車牌 不符, confirms 下降
  836. $confirms_bias = $etag_confirms_bias_minus;
  837. trigger_error($ETAG_WARMIN_TITLE . "etag 找 lpr | lpr error : {$lpr},{$etag} | query:" . print_r($lpr_info_from_etag, true));
  838. }
  839. $next_confirms_value = $lpr_info_from_etag['confirms'] + $confirms_bias;
  840. trigger_error($ETAG_LOG_TITLE . "etag 找 lpr | {$lpr},{$etag}, next_confirms: {$next_confirms_value}, bias:{$confirms_bias}");
  841. // 更新 confirms 資訊
  842. if($next_confirms_value > $max_admin_confirms_value)
  843. {
  844. // B.3.0 confirms 超過 max_admin_confirms_value, skip
  845. //trigger_error($ETAG_LOG_TITLE . "etag 找 lpr | {$lpr},{$etag} next_confirms_value > max_admin_confirms_value : {$max_admin_confirms_value}");
  846. }
  847. else if ($next_confirms_value >= $min_admin_confirms_value)
  848. {
  849. // B.3.1 人工確認過的記錄, 誤判多次後會停留在 min_admin_confirms_value, 或加到 max_admin_confirms_value
  850. $this->db->where('etag', $etag)->update('etag_lpr', array('confirms' => $next_confirms_value));
  851. }
  852. else if ($next_confirms_value > $max_system_confirms_value)
  853. {
  854. // B.3.2 confirms 超過 max_system_confirms_value, skip
  855. //trigger_error($ETAG_LOG_TITLE . "etag 找 lpr | {$lpr},{$etag} next_confirms_value > max_system_confirms_value : {$max_system_confirms_value}");
  856. }
  857. else if ($next_confirms_value <= $max_system_confirms_value && $next_confirms_value >= $min_system_confirms_value)
  858. {
  859. // B.3.3 confirms 不到 max_system_confirms_value 為系統生成記錄, 誤判多次後 confirms 會扣到 min_system_confirms_value
  860. $this->db->where('etag', $etag)->update('etag_lpr', array('confirms' => $next_confirms_value));
  861. }
  862. else
  863. {
  864. // B.3.4 若低於 min_system_confirms_value,刪除
  865. $this->db->delete('etag_lpr', array('etag' => $etag));
  866. trigger_error($ETAG_LOG_TITLE . "etag 找 lpr | etag confirms fail and removed : {$lpr_info_from_etag['lpr']}, {$etag}");
  867. trigger_error($ETAG_WARMIN_TITLE . "etag 找 lpr | etag confirms fail and removed : {$lpr_info_from_etag['lpr']}, {$etag}");
  868. }
  869. }
  870. else
  871. {
  872. // 車牌 找 etag
  873. $etag_info_form_lpr = $this->db->select('etag, confirms, member_no')
  874. ->from('etag_lpr')
  875. ->where(array('lpr' => $lpr))
  876. ->limit(1)
  877. ->get()
  878. ->row_array();
  879. if (!empty($etag_info_form_lpr['etag']))
  880. {
  881. // A. 車牌 有找到 etag
  882. if ($etag_info_form_lpr['etag'] == $etag)
  883. {
  884. // A.1. 車牌 有找到 etag, 且 etag 相符, confirms 上升
  885. $confirms_bias = $lpr_confirms_bias_plus;
  886. // 若尚未登記為會員
  887. if(empty($etag_info_form_lpr['member_no']))
  888. {
  889. // 檢查是否會員
  890. $member_info_from_lpr = $this->db->select('member_no, member_name')
  891. ->from('members')
  892. ->where(array('lpr' => $lpr))
  893. ->limit(1)
  894. ->get()
  895. ->row_array();
  896. // 確認為會員, 建立 eTag 資訊
  897. if (!empty($member_info_from_lpr['member_no']))
  898. {
  899. $data['member_no'] = $member_info_from_lpr['member_no'];
  900. $data['member_name'] = $member_info_from_lpr['member_name'];
  901. $this->db->where('member_no', $member_info_from_lpr['member_no'])->update('member_car', array('etag' => $etag));
  902. $this->db->where('member_no', $member_info_from_lpr['member_no'])->update('members', array('etag' => $etag));
  903. // 更新 etag_lpr
  904. $this->db->where('etag', $etag)->update('etag_lpr', $data);
  905. }
  906. }
  907. }
  908. else
  909. {
  910. // A.2. 車牌 有找到 etag, 但 etag 不符, confirms 下降
  911. $confirms_bias = $lpr_confirms_bias_minus;
  912. trigger_error($ETAG_WARMIN_TITLE . "lpr 找 etag | etag error : {$lpr},{$etag} | query:" . print_r($etag_info_form_lpr, true));
  913. }
  914. $next_confirms_value = $lpr_info_from_etag['confirms'] + $confirms_bias;
  915. trigger_error($ETAG_LOG_TITLE . "lpr 找 etag | {$lpr},{$etag}, next_confirms: {$next_confirms_value}, bias:{$confirms_bias}");
  916. // 更新 confirms 資訊
  917. if($next_confirms_value > $max_admin_confirms_value)
  918. {
  919. // A.3.0 confirms 超過 max_admin_confirms_value, skip
  920. //trigger_error($ETAG_LOG_TITLE . "lpr 找 etag | {$lpr},{$etag} next_confirms_value > max_admin_confirms_value : {$max_admin_confirms_value}");
  921. }
  922. else if ($next_confirms_value >= $min_admin_confirms_value)
  923. {
  924. // A.3.1 人工確認過的記錄, 誤判多次後會停留在 min_admin_confirms_value, 或加到 max_admin_confirms_value
  925. $this->db->where('lpr', $lpr)->update('etag_lpr', array('confirms' => $next_confirms_value));
  926. }
  927. else if ($next_confirms_value > $max_system_confirms_value)
  928. {
  929. // A.3.2 confirms 超過 max_system_confirms_value, skip
  930. //trigger_error($ETAG_LOG_TITLE . "lpr 找 etag | {$lpr},{$etag} next_confirms_value > max_system_confirms_value : {$max_system_confirms_value}");
  931. }
  932. else if ($next_confirms_value <= $max_system_confirms_value && $next_confirms_value >= $min_system_confirms_value)
  933. {
  934. // A.3.3 confirms 不到 max_system_confirms_value 為系統生成記錄, 誤判多次後 confirms 會扣到 min_system_confirms_value
  935. $this->db->where('lpr', $lpr)->update('etag_lpr', array('confirms' => $next_confirms_value));
  936. }
  937. else
  938. {
  939. // A.3.4 若低於 min_system_confirms_value,刪除
  940. $this->db->delete('etag_lpr', array('lpr' => $lpr));
  941. trigger_error($ETAG_LOG_TITLE . "lpr 找 etag | lpr confirms fail and removed : {$lpr}, {$etag_info_form_lpr['etag']}");
  942. trigger_error($ETAG_WARMIN_TITLE . "lpr 找 etag | lpr confirms fail and removed : {$lpr}, {$etag_info_form_lpr['etag']}");
  943. }
  944. }
  945. else
  946. {
  947. // C. 車牌 與 etag 都找不到記錄
  948. $data = array
  949. (
  950. 'lpr' => $lpr,
  951. 'lpr_correct' => $lpr,
  952. 'etag' => $etag
  953. );
  954. // 檢查是否會員
  955. $member_info_from_lpr = $this->db->select('member_no, member_name')
  956. ->from('members')
  957. ->where(array('lpr' => $lpr))
  958. ->limit(1)
  959. ->get()
  960. ->row_array();
  961. // 會員者, 將eTag update回去
  962. if (!empty($member_info_from_lpr['member_no']))
  963. {
  964. $data['member_no'] = $member_info_from_lpr['member_no'];
  965. $data['member_name'] = $member_info_from_lpr['member_name'];
  966. $this->db->where('member_no', $member_info_from_lpr['member_no'])->update('member_car', array('etag' => $etag));
  967. $this->db->where('member_no', $member_info_from_lpr['member_no'])->update('members', array('etag' => $etag));
  968. }
  969. // 建立第一筆記錄
  970. $this->db->insert('etag_lpr', $data);
  971. $etag_lpr_seqno = $this->db->insert_id();
  972. trigger_error($ETAG_LOG_TITLE . "create | insert seqno = {$etag_lpr_seqno}". print_r($data, true));
  973. }
  974. }
  975. }
  976. /*
  977. // 有車牌與eTag, 檢查資料庫
  978. public function check_lpr_etag($lpr, $etag)
  979. {
  980. // 用讀取eTag記錄(有double驗證過)
  981. $rows = $this->db->select('etag, confirms')
  982. ->from('etag_lpr')
  983. ->where(array('lpr' => $lpr))
  984. ->limit(1)
  985. ->get()
  986. ->row_array();
  987. // 讀出eTag資料
  988. if (!empty($rows['etag']))
  989. {
  990. // 車牌與eTag皆相符, 檢查是否confirms欄位若為0, 設成1(double驗證)
  991. if ($rows['etag'] == $etag)
  992. {
  993. if ($rows['confirms'] == 0) $this->db->where('lpr', $lpr)->update('etag_lpr', array('confirms' => 1));
  994. }
  995. else // eTag不相符
  996. {
  997. if ($rows['confirms'] == 1)
  998. {
  999. $this->db->where('lpr', $lpr)->update('etag_lpr', array('confirms' => 0));
  1000. }
  1001. else // 原confirms為0者, 刪除之
  1002. {
  1003. $this->db->delete('etag_lpr', array('lpr' => $lpr));
  1004. }
  1005. }
  1006. }
  1007. else // 無資料, 新增一筆
  1008. {
  1009. // 再檢查一次是否有eTag ?
  1010. $rows_etag = $this->db->select('lpr, confirms')
  1011. ->from('etag_lpr')
  1012. ->where(array('etag' => $etag))
  1013. ->limit(1)
  1014. ->get()
  1015. ->row_array();
  1016. if (empty($rows_etag['lpr'])) // 無資料
  1017. {
  1018. $data = array
  1019. (
  1020. 'lpr' => $lpr,
  1021. 'lpr_correct' => $lpr,
  1022. 'etag' => $etag
  1023. );
  1024. // 檢查是否會員
  1025. $rows_members = $this->db->select('member_no, member_name')
  1026. ->from('members')
  1027. ->where(array('lpr' => $lpr))
  1028. ->limit(1)
  1029. ->get()
  1030. ->row_array();
  1031. // 會員者, 將eTag update回去
  1032. if (!empty($rows_members['member_no']))
  1033. {
  1034. $data['member_no'] = $rows_members['member_no'];
  1035. $data['member_name'] = $rows_members['member_name'];
  1036. $this->db->where('member_no', $rows_members['member_no'])->update('member_car', array('etag' => $etag));
  1037. $this->db->where('member_no', $rows_members['member_no'])->update('members', array('etag' => $etag));
  1038. }
  1039. $this->db->insert('etag_lpr', $data);
  1040. }
  1041. else
  1042. {
  1043. if ($rows_etag['confirms'] == 1)
  1044. {
  1045. $this->db->where('etag', $etag)->update('etag_lpr', array('confirms' => 0));
  1046. }
  1047. else // 原confirms為0者, 刪除之
  1048. {
  1049. $this->db->delete('etag_lpr', array('etag' => $etag));
  1050. }
  1051. }
  1052. }
  1053. }
  1054. */
  1055. // 送出至message queue(目前用mqtt)
  1056. public function mq_send($topic, $msg)
  1057. {
  1058. $this->vars['mqtt']->publish($topic, $msg, 0);
  1059. trigger_error("mqtt:{$topic}|{$msg}");
  1060. usleep(100000); // delay 0.1 sec (避免漏訊號)
  1061. }
  1062. // 產生 CK
  1063. public function gen_opendoor_ck($parms, $function_name)
  1064. {
  1065. return md5($parms['ivsno']. 'alt' . date('dmh') . 'o' . $parms['lpr'] . 'b' . $function_name);
  1066. }
  1067. // 開門 (月租)
  1068. public function member_opendoors($parms)
  1069. {
  1070. //$this->mq_send_opendoor(MQ_TOPIC_OPEN_DOOR, "DO{$parms['ivsno']},OPEN,{$parms['lpr']}");
  1071. $ck = $this->gen_opendoor_ck($parms, __FUNCTION__);
  1072. get_headers("http://localhost/cars.html/" . __FUNCTION__ . "/{$parms['ivsno']}/{$parms['lpr']}/{$ck}");
  1073. return true;
  1074. }
  1075. // 開門 (臨停)
  1076. public function temp_opendoors($parms)
  1077. {
  1078. //$this->mq_send_opendoor(MQ_TOPIC_OPEN_DOOR, "DO{$parms['ivsno']},TICKET,{$parms['lpr']}");
  1079. $ck = $this->gen_opendoor_ck($parms, __FUNCTION__);
  1080. get_headers("http://localhost/cars.html/" . __FUNCTION__ ."/{$parms['ivsno']}/{$parms['lpr']}/{$ck}");
  1081. return true;
  1082. }
  1083. // 開門 (月租)
  1084. public function do_member_opendoor($parms)
  1085. {
  1086. if($parms['ck'] != $this->gen_opendoor_ck($parms, 'member_opendoors'))
  1087. {
  1088. return 'ck_error'; // 中斷
  1089. }
  1090. $this->mq_send(MQ_TOPIC_OPEN_DOOR, "DO{$parms['ivsno']},OPEN,{$parms['lpr']}");
  1091. return 'ok';
  1092. }
  1093. // 開門 (臨停)
  1094. public function do_temp_opendoor($parms)
  1095. {
  1096. if($parms['ck'] != $this->gen_opendoor_ck($parms, 'temp_opendoors'))
  1097. {
  1098. return 'ck_error'; // 中斷
  1099. }
  1100. $this->mq_send(MQ_TOPIC_OPEN_DOOR, "DO{$parms['ivsno']},TICKET,{$parms['lpr']}");
  1101. return 'ok';
  1102. }
  1103. // 指派車位
  1104. // http://203.75.167.89/parkingquery.html/get_valid_seat
  1105. // 註記現在時間, 並保留10分鐘
  1106. public function get_valid_seat()
  1107. {
  1108. $data = array();
  1109. //$data['result']['location_no'] = '0';
  1110. //$data['result_code'] = 'FAIL';
  1111. //return $data;
  1112. // 撈 roger db
  1113. /*
  1114. $sql = "
  1115. SELECT ParkingNum AS pksno FROM table_carpark
  1116. WHERE LPR = '' AND DisableSeat = 0 AND
  1117. (SELECT COUNT(*) FROM table_carpark WHERE LPR = '' AND DisableSeat = 0) <= 10
  1118. ORDER BY RAND() LIMIT 1 FOR UPDATE;
  1119. ";
  1120. $dsn_old_db = $this->load->database('old_db', true);
  1121. // 2016/12/14 roger_db 掛了的可能
  1122. if ($dsn_old_db->initialize())
  1123. {
  1124. $retults = $dsn_old_db->query($sql)->result_array();
  1125. }
  1126. if(!empty($retults[0]))
  1127. {
  1128. $data['result']['location_no'] = substr($retults[0]['pksno'], 1);
  1129. $data['result_code'] = 'OK';
  1130. $data['loc_name'] = 'B'.substr($retults[0]['pksno'], 0, 1);
  1131. $data['floors'] = 'B'.substr($retults[0]['pksno'], 0, 1);
  1132. }
  1133. else
  1134. {
  1135. $data['result']['location_no'] = '0';
  1136. $data['result_code'] = 'FAIL';
  1137. }
  1138. */
  1139. $this->db->trans_start();
  1140. $sql = "select pksno from pks where status = 'VA' and prioritys != 0 and (book_time is null or book_time <= now()) order by prioritys asc limit 1 for update;";
  1141. $rows = $this->db->query($sql)->row_array();
  1142. if (!empty($rows['pksno']))
  1143. {
  1144. $data['result']['location_no'] = substr($rows['pksno'], -3);
  1145. $data['result_code'] = 'OK';
  1146. $sql = "update pks set book_time = addtime(now(), '00:10:00') where pksno = {$rows['pksno']};";
  1147. $this->db->query($sql);
  1148. $sql = "select g.group_name, g.floors from pks_groups g, pks_group_member m where m.pksno = {$rows['pksno']} and g.group_id = m.group_id and g.group_type = 1 limit 1";
  1149. $rows = $this->db->query($sql)->row_array();
  1150. $data['loc_name'] = $rows['group_name'];
  1151. $data['floors'] = $rows['floors'];
  1152. }
  1153. else
  1154. {
  1155. $data['result']['location_no'] = '0';
  1156. $data['result_code'] = 'FAIL';
  1157. }
  1158. $this->db->trans_complete();
  1159. return $data;
  1160. }
  1161. // 取得出入口 888 資訊
  1162. public function get_888_info($parms)
  1163. {
  1164. $data = array();
  1165. $sql = "select availables as availables, tot as tot from pks_groups where group_id = 'C888' and station_no = {$parms['sno']}";
  1166. $rows = $this->db->query($sql)->row_array();
  1167. if (!empty($rows) && array_key_exists('availables', $rows))
  1168. {
  1169. $data['result_code'] = 'OK';
  1170. $data['availables'] = $rows['availables'];
  1171. $data['tot'] = $rows['tot'];
  1172. }
  1173. else
  1174. {
  1175. trigger_error(__FUNCTION__ . "..not found..".print_r($parms, true));
  1176. $data['result_code'] = 'FAIL';
  1177. $data['availables'] = 9999; // 如果拿不到就忽略這個流程
  1178. $data['tot'] = 0;
  1179. }
  1180. return $data;
  1181. }
  1182. // ===============================================
  1183. // acer cmd
  1184. // ===============================================
  1185. // 產生通行碼
  1186. function gen_pass_code()
  1187. {
  1188. return rand(100000,999999);
  1189. }
  1190. // 呼叫acer
  1191. function call_acer($cmd, $parms)
  1192. {
  1193. return false; // 尚未啟用
  1194. try{
  1195. $ch = curl_init();
  1196. curl_setopt($ch, CURLOPT_URL, 'http://localhost/acer_service.html/cmd_'. $cmd);
  1197. curl_setopt($ch, CURLOPT_HEADER, FALSE);
  1198. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  1199. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  1200. curl_setopt($ch, CURLOPT_POST, TRUE);
  1201. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,3);
  1202. curl_setopt($ch, CURLOPT_TIMEOUT, 3); //timeout in seconds
  1203. curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($parms));
  1204. $data = curl_exec($ch);
  1205. if(curl_errno($ch))
  1206. {
  1207. trigger_error(__FUNCTION__ . ', curl error: '. curl_error($ch));
  1208. }
  1209. curl_close($ch);
  1210. trigger_error(__FUNCTION__ . '..'. $data);
  1211. }catch (Exception $e){
  1212. trigger_error(__FUNCTION__ . 'error:'.$e->getMessage());
  1213. }
  1214. }
  1215. // ===============================================
  1216. // mitac cmd
  1217. // ===============================================
  1218. // 要求 mitac 扣款
  1219. function call_mitac_pay($lpr, $ivsno, $rows_cario)
  1220. {
  1221. $function_name = 'parking_fee_altob';
  1222. $seqno = $rows_cario['cario_no'];
  1223. $lpr = $lpr;
  1224. $in_time = $rows_cario['out_before_time'];
  1225. $out_time = $this->now_str;
  1226. $gate_id = $ivsno;
  1227. // 通訊內容
  1228. $parms = array(
  1229. 'seqno' => $seqno,
  1230. 'lpr' => $lpr,
  1231. 'in_time' => $in_time,
  1232. 'out_time' => $out_time,
  1233. 'gate_id' => $gate_id);
  1234. // 驗証碼
  1235. $parms['ck'] = md5($parms['seqno']. 'a' . date('dmh') . 'l' . $parms['lpr'] . 't'. $parms['in_time']. 'o'. $parms['out_time'] . 'b'. $parms['gate_id'] . $function_name);
  1236. // 呼叫
  1237. try{
  1238. $ch = curl_init();
  1239. curl_setopt($ch, CURLOPT_URL, "http://localhost/mitac_service.html/{$function_name}");
  1240. curl_setopt($ch, CURLOPT_HEADER, FALSE);
  1241. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  1242. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  1243. curl_setopt($ch, CURLOPT_POST, TRUE);
  1244. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,3);
  1245. curl_setopt($ch, CURLOPT_TIMEOUT, 3); //timeout in seconds
  1246. curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($parms));
  1247. $data = curl_exec($ch);
  1248. if(curl_errno($ch))
  1249. {
  1250. trigger_error(__FUNCTION__ . ', curl error: '. curl_error($ch));
  1251. }
  1252. curl_close($ch);
  1253. trigger_error(__FUNCTION__ . '..'. $data);
  1254. }catch (Exception $e){
  1255. trigger_error(__FUNCTION__ . 'error:'.$e->getMessage());
  1256. }
  1257. }
  1258. }