VM暫存
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

1094 lines
34KB

  1. <?php
  2. /*
  3. file: carpark.php 停車管理
  4. */
  5. if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  6. require_once(MQ_CLASS_FILE);
  7. // ----- 定義常數(路徑, cache秒數) -----
  8. define('APP_VERSION', '100'); // 版本號
  9. define('MAX_AGE', 604800); // cache秒數, 此定義1個月
  10. define('APP_NAME', 'carpark'); // 應用系統名稱
  11. define('PAGE_PATH', APP_BASE.'ci_application/views/'.APP_NAME.'/'); // path of views
  12. //define('SERVER_URL', 'http://'.(isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost').'/'); // URL
  13. define('SERVER_URL', 'http://'.(isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost') . ($_SERVER['SERVER_PORT'] != 60123 ? ':' . $_SERVER['SERVER_PORT'] : '') .'/'); // URL
  14. define('APP_URL', SERVER_URL.APP_NAME.'.html/'); // controller路徑
  15. define('WEB_URL', SERVER_URL.APP_NAME.'/'); // 網頁路徑
  16. define('WEB_LIB', SERVER_URL.'libs/'); // 網頁lib
  17. define('BOOTSTRAPS', WEB_LIB.'bootstrap_sb/'); // bootstrap lib
  18. define('LOG_PATH', FILE_BASE.APP_NAME.'/logs/'); // log path
  19. class Carpark extends CI_Controller
  20. {
  21. var $vars = array(); // 共用變數
  22. function __construct()
  23. {
  24. parent::__construct();
  25. // ----- 程式開發階段log設定 -----
  26. if (@ENVIRONMENT == 'development')
  27. {
  28. ini_set('display_errors', '1');
  29. //error_reporting(E_ALL ^ E_NOTICE);
  30. error_reporting(E_ALL);
  31. }
  32. set_error_handler(array($this, 'error_handler'), E_ALL); // 資料庫異動需做log
  33. // 共用記憶體
  34. $this->vars['mcache'] = new Memcache;
  35. $this->vars['mcache']->connect(MEMCACHE_HOST, MEMCACHE_PORT) or die ('Could not connect memcache');
  36. /*
  37. // mqtt subscribe
  38. $this->vars['mqtt'] = new phpMQTT(MQ_HOST, MQ_PORT, uniqid());
  39. //if(!$this->vars['mqtt']->connect()){ die ('Could not connect mqtt'); }
  40. $this->vars['mqtt']->connect();
  41. */
  42. $this->load->model('carpark_model');
  43. $this->carpark_model->init($this->vars);
  44. // 資料介接模組
  45. $this->load->model('sync_data_model');
  46. $this->sync_data_model->init($this->vars); // for memcache
  47. // 產生 excel 報表
  48. $this->load->model('excel_model');
  49. $this->excel_model->init($this->vars);
  50. // [START] 2016/06/03 登入
  51. $this->load->model('user_model');
  52. // load library
  53. $this->load->library(array('form_validation','session'));
  54. // load helpers
  55. $this->load->helper(array('form'));
  56. // ajax code
  57. define('RESULT_SUCCESS', 'ok');
  58. define('RESULT_FORM_VALIDATION_FAIL', '-1');
  59. define('RESULE_FAIL', 'gg');
  60. // [START] 2016/06/03 登入
  61. }
  62. // 發生錯誤時集中在此處理
  63. public function error_handler($errno, $errstr, $errfile, $errline, $errcontext)
  64. {
  65. // ex: car_err://message....
  66. $log_msg = explode('://', $errstr);
  67. if (count($log_msg) > 1)
  68. {
  69. $log_file = LOG_PATH.$log_msg[0];
  70. $str = date('H:i:s')."|{$log_msg[1]}|{$errfile}|{$errline}|{$errno}\n";
  71. }
  72. else
  73. {
  74. $log_file = LOG_PATH.APP_NAME;
  75. $str = date('H:i:s')."|{$errstr}|{$errfile}|{$errline}|{$errno}\n";
  76. }
  77. //$str = date('H:i:s')."|{$errstr}|{$errfile}|{$errline}|{$errno}\n";
  78. error_log($str, 3, $log_file . '.' . date('Ymd').'.log.txt'); // 3代表參考後面的檔名
  79. }
  80. // 顯示靜態網頁(html檔)
  81. protected function show_page($page_name, &$data = null)
  82. {
  83. $page_file = PAGE_PATH.$page_name.'.php';
  84. $last_modified_time = filemtime($page_file);
  85. // 若檔案修改時間沒有異動, 或版本無異動, 通知瀏覽器使用cache, 不再下傳網頁
  86. // header('Cache-Control:max-age='.MAX_AGE); // cache 1個月
  87. header('Last-Modified: '.gmdate('D, d M Y H:i:s', $last_modified_time).' GMT');
  88. header('Etag: '. APP_VERSION);
  89. header('Cache-Control: public');
  90. // 20170921
  91. header("cache-Control: no-store, no-cache, must-revalidate");
  92. header("cache-Control: post-check=0, pre-check=0", false);
  93. header("Pragma: no-cache");
  94. header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
  95. if (!empty($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == APP_VERSION && @strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time)
  96. {
  97. header('HTTP/1.1 304 Not Modified');
  98. }
  99. else
  100. {
  101. $this->load->view(APP_NAME.'/'.$page_name, $data);
  102. }
  103. }
  104. // ------------------------------------------------
  105. //
  106. // CRM (START)
  107. //
  108. // ------------------------------------------------
  109. // [test] zzz
  110. public function gen_test_case()
  111. {
  112. $sno = '12302';
  113. $ivsno = 0;
  114. $io = 'CI';
  115. $lpr = 'TEST1109A';
  116. $ts = date('YmdHis');
  117. $parms = array();
  118. $parms['sno'] = $sno;
  119. $parms['ivsno'] = $ivsno;
  120. $parms['io'] = $io;
  121. $parms['lpr'] = $lpr;
  122. $parms['ts'] = $ts;
  123. $function_name = 'remote_lprio';
  124. $ck = $this->gen_cms_ck($parms, $function_name);
  125. echo "http://localhost/carpark.html/{$function_name}/sno/{$sno}/ivsno/{$ivsno}/io/{$io}/type/C/lpr/{$lpr}/color/NONE/sq/0/ts/{$ts}/sq2/0/etag/NONE/ant/1/ck/{$ck}";
  126. echo "\n\n";
  127. $function_name = 'remote_opendoor_lprio';
  128. $ck = $this->gen_cms_ck($parms, $function_name);
  129. echo "http://localhost/carpark.html/{$function_name}/sno/{$sno}/ivsno/{$ivsno}/io/{$io}/type/C/lpr/{$lpr}/color/NONE/sq/0/ts/{$ts}/sq2/0/etag/NONE/ant/1/ck/{$ck}";
  130. echo "\n\n";
  131. $function_name = 'remote_opendoor_anyway';
  132. $ck = $this->gen_cms_ck($parms, $function_name);
  133. echo "http://localhost/carpark.html/{$function_name}/sno/{$sno}/ivsno/{$ivsno}/io/{$io}/lpr/{$lpr}/ts/{$ts}/ck/{$ck}";
  134. echo "\n\n";
  135. exit;
  136. }
  137. // 產生 CK
  138. function gen_cms_ck($parms, $function_name)
  139. {
  140. return md5($parms['sno']. 'a' . date('dmh') . 'l' . $parms['ts'] . 't'. $parms['lpr']. 'o'. $parms['ivsno'] . 'b'. $parms['io'] . $function_name);
  141. }
  142. // [remote] 新增車辨記錄
  143. public function remote_lprio()
  144. {
  145. $LOG_FLAG = 'cms://';
  146. $parms = $this->uri->uri_to_assoc(3);
  147. // ck
  148. if($parms['ck'] != $this->gen_cms_ck($parms, __FUNCTION__))
  149. {
  150. echo 'ck_error'; // 中斷
  151. exit;
  152. }
  153. $parms['lpr'] = urldecode($parms['lpr']);
  154. $parms['obj_type'] = 1;
  155. $parms['curr_time_str'] = date('Y-m-d H:i:s');
  156. $parms['pic_name'] = '';
  157. trigger_error($LOG_FLAG . __FUNCTION__ . '..' . print_r($parms, true));
  158. // 載入模組
  159. $this->load->model('cars_model');
  160. $this->cars_model->init($this->vars);
  161. $this->cars_model->lprio($parms);
  162. echo 'ok';
  163. exit;
  164. }
  165. // [remote] 車辨開門
  166. public function remote_opendoor_lprio()
  167. {
  168. $LOG_FLAG = 'cms://';
  169. $parms = $this->uri->uri_to_assoc(3);
  170. // ck
  171. if($parms['ck'] != $this->gen_cms_ck($parms, __FUNCTION__))
  172. {
  173. echo 'ck_error'; // 中斷
  174. exit;
  175. }
  176. $parms['lpr'] = urldecode($parms['lpr']);
  177. trigger_error($LOG_FLAG . __FUNCTION__ . '..' . print_r($parms, true));
  178. // mqtt subscribe
  179. $station_setting = $this->sync_data_model->station_setting_query();
  180. $mqtt_ip = isset($station_setting['mqtt_ip']) ? $station_setting['mqtt_ip'] : MQ_HOST;
  181. $mqtt_port = isset($station_setting['mqtt_port']) ? $station_setting['mqtt_port'] : MQ_PORT;
  182. // 字幕 MQTT
  183. $this->vars['mqtt'] = new phpMQTT($mqtt_ip, $mqtt_port, uniqid());
  184. $this->vars['mqtt']->connect();
  185. // 開門 MQTT
  186. $this->vars['mqtt_opendoor'] = new phpMQTT($mqtt_ip, $mqtt_port, uniqid());
  187. $this->vars['mqtt_opendoor']->connect();
  188. // 載入模組
  189. $this->load->model('cars_model');
  190. $this->cars_model->init($this->vars);
  191. $this->cars_model->opendoor_lprio($parms);
  192. echo 'ok';
  193. exit;
  194. }
  195. // [remote] 直接開門
  196. public function remote_opendoor_anyway()
  197. {
  198. $LOG_FLAG = 'cms://';
  199. $parms = $this->uri->uri_to_assoc(3);
  200. // ck
  201. if($parms['ck'] != $this->gen_cms_ck($parms, __FUNCTION__))
  202. {
  203. echo 'ck_error'; // 中斷
  204. exit;
  205. }
  206. $parms['lpr'] = urldecode($parms['lpr']);
  207. trigger_error($LOG_FLAG . __FUNCTION__ . '..' . print_r($parms, true));
  208. // mqtt subscribe
  209. $station_setting = $this->sync_data_model->station_setting_query();
  210. $mqtt_ip = isset($station_setting['mqtt_ip']) ? $station_setting['mqtt_ip'] : MQ_HOST;
  211. $mqtt_port = isset($station_setting['mqtt_port']) ? $station_setting['mqtt_port'] : MQ_PORT;
  212. // 開門 MQTT
  213. $this->vars['mqtt_opendoor'] = new phpMQTT($mqtt_ip, $mqtt_port, uniqid());
  214. $this->vars['mqtt_opendoor']->connect();
  215. // 載入模組
  216. $this->load->model('cars_model');
  217. $this->cars_model->init($this->vars);
  218. // 判斷會員身份
  219. $rows = $this->cars_model->get_member($lpr);
  220. if ($rows['member_no'] == 0)
  221. {
  222. $this->cars_model->mq_send_opendoor(MQ_TOPIC_OPEN_DOOR, "DO{$parms['ivsno']},TICKET,{$parms['lpr']}"); // 臨停訊號
  223. }
  224. else
  225. {
  226. $this->cars_model->mq_send_opendoor(MQ_TOPIC_OPEN_DOOR, "DO{$parms['ivsno']},OPEN,{$parms['lpr']}"); // 月租訊號
  227. }
  228. echo 'ok';
  229. exit;
  230. }
  231. // ------------------------------------------------
  232. //
  233. // 接收端 (START)
  234. //
  235. // ------------------------------------------------
  236. // [mqtt] 接收端
  237. public function mqtt_service()
  238. {
  239. $LOG_FLAG = 'mqtt://';
  240. $topic = $this->input->post('topic', true);
  241. $msg = $this->input->post('msg', true);
  242. $ck = $this->input->post('ck', true);
  243. if(md5($topic.'altob'.$msg) != $ck)
  244. {
  245. echo 'ck_error';
  246. exit;
  247. }
  248. trigger_error($LOG_FLAG . __FUNCTION__ . "|{$topic}|{$msg}");
  249. if($topic == 'altob.888.mqtt')
  250. {
  251. // 第一個場站編號 先不管場站
  252. $station_setting = $this->sync_data_model->station_setting_query();
  253. $station_no_arr = explode(SYNC_DELIMITER_ST_NO, $station_setting['station_no']);
  254. $first_station_no = $station_no_arr[0];
  255. $msg_arr = explode(',', $msg);
  256. if(sizeof($msg_arr) != 4)
  257. {
  258. trigger_error($LOG_FLAG . __FUNCTION__ . "..error_size.." . print_r($msg_arr, true));
  259. echo 'error_size';
  260. exit;
  261. }
  262. if($msg_arr[0] != 'N888' || $msg_arr[3] != 'altob')
  263. {
  264. trigger_error($LOG_FLAG . __FUNCTION__ . "..unknown_msg.." . print_r($msg_arr, true));
  265. echo 'unknown_msg';
  266. exit;
  267. }
  268. $msg_arr = explode(',', $msg);
  269. $group_id = isset($msg_arr[1]) && $msg_arr[1] == 2 ? 'M888' : 'C888';
  270. $value = isset($msg_arr[2]) ? $msg_arr[2] : 0;
  271. $result = $this->sync_data_model->force_sync_888($first_station_no, $group_id, $value);
  272. trigger_error($LOG_FLAG . __FUNCTION__ . "..{$first_station_no}|{$group_id}|{$value}..result..{$result}..");
  273. }
  274. echo 'ok';
  275. exit;
  276. }
  277. // [設定檔] 取得設定
  278. public function station_setting_query()
  279. {
  280. $reload = $this->input->post('reload', true);
  281. if(isset($reload) && $reload > 0)
  282. {
  283. $station_setting = $this->sync_data_model->station_setting_query(true); // 強制重新載入
  284. trigger_error(__FUNCTION__ . '..station_setting: '. print_r($station_setting, true));
  285. if(!$station_setting)
  286. {
  287. echo json_encode('fail', JSON_UNESCAPED_UNICODE);
  288. exit; // 中斷
  289. }
  290. $info = array('station_no_arr' => $station_setting['station_no']);
  291. usleep(300000); // 0.3 sec delay
  292. // 費率資料同步
  293. $result = $this->sync_data_model->sync_price_plan($info);
  294. trigger_error(__FUNCTION__ . '..sync_price_plan: '. $result);
  295. usleep(300000); // 0.3 sec delay
  296. // 會員資料同步
  297. $result = $this->sync_data_model->sync_members($info);
  298. trigger_error(__FUNCTION__ . '..sync_members: '. $result);
  299. usleep(300000); // 0.3 sec delay
  300. // 在席資料同步
  301. $result = $this->sync_data_model->sync_pks_groups_reload($station_setting);
  302. trigger_error(__FUNCTION__ . '..sync_pks_groups_reload: '. $result);
  303. }
  304. else
  305. {
  306. $station_setting = $this->sync_data_model->station_setting_query(false);
  307. if(!$station_setting)
  308. {
  309. echo json_encode('fail', JSON_UNESCAPED_UNICODE);
  310. exit; // 中斷
  311. }
  312. }
  313. echo json_encode($station_setting, JSON_UNESCAPED_UNICODE);
  314. }
  315. // [排程 or 強制] 同步場站資訊
  316. public function sync_station_data()
  317. {
  318. trigger_error(__FUNCTION__ . '..from..'. $this->my_ip() .'..network..'); // IP 會浮動?
  319. $switch_lpr_arr = array(); // 換車牌
  320. $meta = $this->input->post('meta', true);
  321. if(!empty($meta))
  322. {
  323. trigger_error( __FUNCTION__ . '..meta_arr..' . $meta);
  324. $meta_arr = explode('@@@', $meta);
  325. foreach($meta_arr as $raw)
  326. {
  327. if(empty($raw))
  328. continue;
  329. $data = json_decode($raw, true);
  330. if($data['key'] == 'switch_lpr')
  331. {
  332. array_push($switch_lpr_arr, $data['value']);
  333. }
  334. }
  335. }
  336. // 0. 取得場站設定
  337. $station_setting = $this->sync_data_model->station_setting_query(false);
  338. trigger_error(__FUNCTION__ . '..station_setting: '. print_r($station_setting, true));
  339. $station_no_arr = array('station_no_arr' => $station_setting['station_no']);
  340. // 1. 月租系統
  341. $result = $this->sync_data_model->sync_members($station_no_arr);
  342. trigger_error(__FUNCTION__ . '..sync_members: '. $result);
  343. // 2. 同步車牌更換
  344. if(!empty($switch_lpr_arr))
  345. {
  346. $this->sync_data_model->sync_switch_lpr($switch_lpr_arr);
  347. }
  348. }
  349. // [API] 取得最新未結清
  350. public function get_last_unbalanced_cario()
  351. {
  352. trigger_error(__FUNCTION__ . '..from..'. $this->my_ip() .'..network..'); // IP 會浮動?
  353. $lpr = $this->input->post('lpr', true);
  354. $station_no = $this->input->post('station_no', true);
  355. $c_s = $this->input->post('c_s', true);
  356. // 確認正確性
  357. if(empty($c_s) || $c_s != md5('altob'.$lpr.'botla'.$station_no))
  358. {
  359. trigger_error(__FUNCTION__ . "..{$lpr}|".$station_no."|{$c_s}..check fail..");
  360. echo 'fail';
  361. exit;
  362. }
  363. $data = $this->sync_data_model->get_last_unbalanced_cario($lpr, $station_no);
  364. echo json_encode($data, JSON_UNESCAPED_UNICODE);
  365. }
  366. // [API] 更新未結清 (行動支付)
  367. public function sync_m2payed()
  368. {
  369. trigger_error(__FUNCTION__ . '..from..'. $this->my_ip() .'..network..'); // IP 會浮動?
  370. $lpr = $this->input->post('lpr', true);
  371. $amt = $this->input->post('amt', true);
  372. $station_no = $this->input->post('station_no', true);
  373. $cario_no = $this->input->post('cario_no', true);
  374. $c_s = $this->input->post('c_s', true);
  375. // 確認正確性
  376. if(empty($c_s) || $c_s != md5($lpr.$amt.'altob'.$station_no.'botla'.$cario_no))
  377. {
  378. trigger_error(__FUNCTION__ . "..{$lpr}|{$amt}|{$station_no}|{$cario_no}|{$c_s}..check fail..");
  379. echo 'fail';
  380. exit;
  381. }
  382. // 臨停繳費
  383. $this->load->model('carpayment_model');
  384. echo $this->carpayment_model->p2payed(array('seqno' => $cario_no, 'lpr' => $lpr, 'amt' => $amt), true);
  385. exit;
  386. //echo 'ok';
  387. }
  388. // 驗証 IP
  389. function is_ip_valid()
  390. {
  391. $client_ip = $this->my_ip();
  392. if(!in_array($client_ip, array('61.219.172.11', '61.219.172.82')))
  393. {
  394. trigger_error('..block..from:'.$client_ip.'..unknown network..');
  395. return false;
  396. }
  397. return true;
  398. }
  399. // 取得 IP
  400. function my_ip()
  401. {
  402. if (getenv('HTTP_X_FORWARDED_FOR'))
  403. {
  404. $ip = getenv('HTTP_X_FORWARDED_FOR');
  405. }
  406. elseif (getenv('HTTP_X_REAL_IP'))
  407. {
  408. $ip = getenv('HTTP_X_REAL_IP');
  409. }
  410. else {
  411. $ip = $_SERVER['REMOTE_ADDR'];
  412. }
  413. return $ip;
  414. }
  415. // 同步 (由排程呼叫)
  416. public function sync_minutely()
  417. {
  418. $this->sync_data_model->sync_pks_groups(); // 同步在席現況
  419. }
  420. // 20170816 手動新增入場資料
  421. public function gen_carin()
  422. {
  423. trigger_error(__FUNCTION__ . '..from..'. $this->my_ip() .'..network..'); // IP 會浮動?
  424. $lpr = $this->input->post('lpr', true);
  425. $station_no = $this->input->post('station_no', true);
  426. $c_s = $this->input->post('c_s', true);
  427. // 確認正確性
  428. if(empty($c_s) || $c_s != md5($lpr.'altob'.$station_no.'botla'. __FUNCTION__ ))
  429. {
  430. trigger_error(__FUNCTION__ . "..{$lpr}|{$station_no}|{$c_s}..check fail..");
  431. echo 'fail';
  432. exit;
  433. }
  434. $parms = array(
  435. 'sno' => $station_no,
  436. 'lpr' => $lpr,
  437. 'etag' => 'NONE',
  438. 'io' => 'CI',
  439. 'ivsno' => 0
  440. );
  441. $this->carpark_model->gen_carin($parms);
  442. echo 'ok';
  443. }
  444. // ------------------------------------------------
  445. //
  446. // 接收端 (END)
  447. //
  448. // ------------------------------------------------
  449. // [START] 2016/06/03 登入
  450. public function index()
  451. {
  452. if($this->session->userdata('logged_in'))
  453. {
  454. $session_data = $this->session->userdata('logged_in');
  455. $data['username'] = $session_data['username'];
  456. $data['type'] = $session_data['type'];
  457. if($data['type'] == 'admin')
  458. {
  459. $this->show_page('admin_page', $data); // 進階管理者介面
  460. }
  461. else
  462. {
  463. $this->show_page('main_page', $data); // 一般
  464. }
  465. }
  466. else
  467. {
  468. //If no session, redirect to login page
  469. //redirect('login', 'refresh');
  470. $this->show_page('login_page');
  471. }
  472. }
  473. // 登入
  474. public function user_login()
  475. {
  476. // form_validation
  477. $this->form_validation->set_rules('login_name', 'login_name', 'trim|required');
  478. $this->form_validation->set_rules('pswd', 'pswd', 'trim|required');
  479. if($this->form_validation->run() == FALSE)
  480. {
  481. return RESULT_FORM_VALIDATION_FAIL;
  482. }
  483. // go model
  484. $data = array
  485. (
  486. 'login_name' => $this->input->post('login_name', true),
  487. 'pswd' => $this->input->post('pswd', true)
  488. );
  489. $result = $this->user_model->user_login($data);
  490. if($result)
  491. {
  492. $sess_array = array();
  493. foreach($result as $row)
  494. {
  495. $sess_array = array
  496. (
  497. 'username' => $row->login_name ,
  498. 'type' => $row->user_type
  499. );
  500. $this->session->set_userdata('logged_in', $sess_array);
  501. }
  502. echo RESULT_SUCCESS;
  503. }
  504. else
  505. {
  506. return RESULE_FAIL;
  507. }
  508. }
  509. // 登出
  510. public function user_logout()
  511. {
  512. $this->session->unset_userdata('logged_in');
  513. session_destroy();
  514. return RESULT_SUCCESS;
  515. }
  516. // [END] 2016/06/03 登入
  517. // response http
  518. protected function http_return($return_code, $type)
  519. {
  520. if ($type == 'text') echo $return_code;
  521. else echo json_encode($return_code, JSON_UNESCAPED_UNICODE);
  522. }
  523. // 送出html code
  524. public function get_html()
  525. {
  526. /*
  527. $data = array
  528. (
  529. 'company_no' => $this->input->post('company_no', true), // 場站統編
  530. 'hq_company_no' => '80682490'
  531. );
  532. $this->load->view(APP_NAME.'/'.$this->input->post('tag_name', true), $data);
  533. */
  534. $this->load->view(APP_NAME.'/'.$this->input->post('tag_name', true), array());
  535. }
  536. // 讀取cookie內容
  537. protected function get_cookie($cookie_name)
  538. {
  539. if (empty($_COOKIE[$cookie_name])) return array();
  540. return(json_decode($_COOKIE[$cookie_name], true));
  541. }
  542. // 儲存cookie內容
  543. protected function save_cookie($cookie_name, $cookie_info)
  544. {
  545. return setcookie($cookie_name, json_encode($cookie_info, JSON_UNESCAPED_UNICODE), 0, '/');
  546. }
  547. // 月租資料同步
  548. public function rent_sync()
  549. {
  550. $station_no = $this->input->post('station_no', true);
  551. $start_date = $this->input->post('start_date', true);
  552. $end_date = $this->input->post('end_date', true);
  553. // $data = $this->carpark_model->rent_sync($station_no, $start_date, $end_date);
  554. // print_r($data);
  555. }
  556. // 重設剩餘車位數
  557. public function available_set()
  558. {
  559. $data = $this->carpark_model->available_set();
  560. $this->http_return($data, 'json');
  561. }
  562. // 剩餘車位數更新
  563. public function available_update()
  564. {
  565. $station_no = $this->input->get_post('station_no', true);
  566. $data['name'] = $this->input->get_post('st_name', true);
  567. $data['tot_pkg'] = $this->input->get_post('tot_pkg', true);
  568. $data['ava_pkg'] = $this->input->get_post('ava_pkg', true);
  569. $this->http_return($this->carpark_model->available_update($station_no, $data), 'json');
  570. }
  571. // 剩餘車位數查核
  572. public function available_check()
  573. {
  574. $time_point = $this->input->get_post('time_point', true);
  575. $this->http_return($this->carpark_model->available_check($time_point), 'json');
  576. }
  577. // 顯示logs
  578. public function show_logs()
  579. {
  580. $lines = $this->uri->segment(3); // 顯示行數
  581. if (empty($lines)) $lines = 140; // 無行數參數, 預設為40行
  582. if($lines > 1000) $lines = 1000; // 最多 1000行
  583. // echo '<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body><pre style="white-space: pre-wrap;">';
  584. echo '<html lang="zh-TW"><body><pre style="white-space: pre-wrap;">';
  585. passthru('/usr/bin/tail -n ' . $lines . ' ' . LOG_PATH.APP_NAME . '.' . date('Ymd').'.log.txt'); // 利用linux指令顯示倒數幾行的logs內容
  586. echo "\n----- " . LOG_PATH.APP_NAME . '.' . date('Ymd').'.log.txt' . ' -----';
  587. echo '</pre></body></html>';
  588. }
  589. // 顯示logs (cars grep 888)
  590. public function show_888_logs()
  591. {
  592. $lines = $this->uri->segment(3); // 顯示行數
  593. if (empty($lines)) $lines = 1000; // 無行數參數, 預設為1000行
  594. if($lines > 20000) $lines = 20000; // 最多 20000行
  595. $grep_str = ' |grep 888';
  596. $target_str = LOG_PATH.APP_NAME . '.' . date('Ymd').'.log.txt'. $grep_str;
  597. // echo '<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body><pre style="white-space: pre-wrap;">';
  598. echo '<html lang="zh-TW"><body><pre style="white-space: pre-wrap;">';
  599. passthru('/usr/bin/tail -n ' . $lines . ' ' . $target_str); // 利用linux指令顯示倒數幾行的logs內容
  600. echo "\n----- " . $target_str . ' -----';
  601. echo '</pre></body></html>';
  602. }
  603. // 新增月租資料
  604. public function member_add()
  605. {
  606. $data = array
  607. (
  608. 'member_no' => $this->input->post('member_no', true),
  609. 'station_no' => $this->input->post('station_no', true),
  610. 'lpr' => strtoupper($this->input->post('lpr', true)),
  611. 'old_lpr' => strtoupper($this->input->post('old_lpr', true)),
  612. 'etag' => strtoupper($this->input->post('etag', true)),
  613. 'start_date' => $this->input->post('start_date', true),
  614. 'end_date' => $this->input->post('end_date', true),
  615. 'member_name' => $this->input->post('member_name', true),
  616. 'member_nick_name' => $this->input->post('member_name', true),
  617. 'mobile_no' => $this->input->post('mobile_no', true),
  618. 'member_id' => $this->input->post('member_id', true),
  619. 'contract_no' => $this->input->post('contract_no', true),
  620. 'amt' => $this->input->post('amt', true),
  621. 'tel_h' => $this->input->post('tel_h', true),
  622. 'tel_o' => $this->input->post('tel_o', true),
  623. 'addr' => $this->input->post('addr', true)
  624. );
  625. trigger_error("add:".print_r($data, true));
  626. if ($data['member_no'] == 0 || $data['old_lpr'] != $data['lpr'])
  627. {
  628. if ($this->carpark_model->check_lpr($data['lpr']) > 0)
  629. {
  630. echo '車牌重複, 請查明再輸入';
  631. exit;
  632. }
  633. }
  634. $this->carpark_model->member_add($data);
  635. echo 'ok';
  636. }
  637. // 查詢月租資料
  638. public function member_query()
  639. {
  640. $data = $this->carpark_model->member_query();
  641. echo json_encode($data, JSON_UNESCAPED_UNICODE);
  642. }
  643. // 刪除月租資料
  644. public function member_delete()
  645. {
  646. $member_no = $this->input->post('member_no', true);
  647. $this->carpark_model->member_delete($member_no);
  648. echo 'ok';
  649. }
  650. // 進出場現況表
  651. public function cario_list()
  652. {
  653. $data = $this->carpark_model->cario_list();
  654. echo json_encode($data, JSON_UNESCAPED_UNICODE);
  655. }
  656. // 進出場事件即時顯示
  657. public function cario_event()
  658. {
  659. set_time_limit(0);
  660. while(true)
  661. {
  662. }
  663. }
  664. // 顯示圖檔(http://url/carpark.html/pics/lpr_ABY8873_O_0_0_C_20150919210022)
  665. public function pics()
  666. {
  667. // ???
  668. readfile(CAR_PIC.$this->uri->segment(3).'/'.str_replace('/', '', $this->uri->segment(4)).'.jpg');
  669. }
  670. // 汽車開門
  671. public function opendoors()
  672. {
  673. $ivsno = $this->uri->segment(3);
  674. $lanes = array
  675. (
  676. 0 => array ('devno' => 0, 'temp' => 0, 'member' => 1), // 1號入口, temp:臨停, member:月租
  677. // 1 => array ('devno' => 0, 'temp' => 2, 'member' => 3), // 2號調撥入口
  678. 1 => array ('devno' => 1, 'temp' => 0, 'member' => 1), // 3號調撥出口
  679. 2 => array ('devno' => 1, 'temp' => 0, 'member' => 1), // 3號調撥出口
  680. 3 => array ('devno' => 1, 'temp' => 2, 'member' => 3) // 4號出口
  681. );
  682. $url = 'http://admin:99999999@192.168.10.53/cgi-bin/basic_setting.cgi?ID=1&';
  683. $member_tag = 'member'; // member:月租會員
  684. // 短路開柵欄
  685. @get_headers("{$url}OUTDEV={$lanes[$ivsno]['devno']}&OUTCH={$lanes[$ivsno][$member_tag]}&OUTSTATUS=1");
  686. usleep(400000); // 暫停0.4秒
  687. // 斷路, 車過關柵欄
  688. @get_headers("{$url}OUTDEV={$lanes[$ivsno]['devno']}&OUTCH={$lanes[$ivsno][$member_tag]}&OUTSTATUS=0");
  689. }
  690. // 調撥車道查詢
  691. public function reversible_lane_query()
  692. {
  693. $max_lane = 4; // 共幾個車道數
  694. for ($idx = 0; $idx < $max_lane; ++$idx)
  695. {
  696. $data[$idx] = file_get_contents("http://192.168.10.51:8090/cgi-bin/switcher.cgi?id={$idx}&action=9");
  697. }
  698. // $data = array(1, 1, 0, 1);
  699. echo json_encode($data);
  700. }
  701. // 車號入場查詢
  702. public function carin_lpr_query()
  703. {
  704. $lpr = $this->uri->segment(3);
  705. $data = $this->carpark_model->carin_lpr_query($lpr);
  706. echo json_encode($data);
  707. }
  708. // 以時間查詢入場資訊
  709. public function carin_time_query()
  710. {
  711. $time_query = $this->input->post('time_query', true);
  712. $minutes_range = $this->input->post('minutes_range', true);
  713. $data = $this->carpark_model->carin_time_query($time_query, $minutes_range);
  714. echo json_encode($data);
  715. }
  716. // 調撥車道設定
  717. public function reversible_lane_set()
  718. {
  719. $lane_no = $this->input->post('lane_no', true);
  720. $actions = $this->input->post('actions', true);
  721. $data = file_get_contents("http://192.168.10.51:8090/cgi-bin/switcher.cgi?id={$lane_no}&action={$actions}");
  722. echo "{$lane_no}|{$actions}|{$data}";
  723. }
  724. // 在席車位檢查未有入場資料清單
  725. public function pks_check_list()
  726. {
  727. $max_rows = $this->uri->segment(3, 100); // 一次讀取筆數, 預設為100筆
  728. $data = $this->carpark_model->pks_check_list($max_rows);
  729. echo json_encode($data, JSON_UNESCAPED_UNICODE);
  730. }
  731. // 重設在席查核
  732. public function reset_pks_check()
  733. {
  734. $data = $this->carpark_model->reset_pks_check();
  735. echo json_encode($data, JSON_UNESCAPED_UNICODE);
  736. }
  737. // 更正在席車號
  738. public function correct_pks_lpr()
  739. {
  740. $pksno = $this->uri->segment(3, 0); // 車格號碼
  741. $lpr = $this->uri->segment(4, 'NONE'); // 車號
  742. if ($pksno == 0 || $lpr == 'NONE')
  743. {
  744. echo json_encode(array('err' => 1, 'cario_no' => 0), JSON_UNESCAPED_UNICODE);
  745. }
  746. else
  747. {
  748. $data = $this->carpark_model->correct_pks_lpr($pksno, $lpr);
  749. echo json_encode($data, JSON_UNESCAPED_UNICODE);
  750. }
  751. }
  752. // 入場車號查核在席無資料清單
  753. public function carin_check_list()
  754. {
  755. $max_rows = $this->uri->segment(3, 20); // 一次讀取筆數, 預設為100筆
  756. $data = $this->carpark_model->carin_check_list($max_rows);
  757. echo json_encode($data, JSON_UNESCAPED_UNICODE);
  758. }
  759. // 更正入場車號
  760. public function correct_carin_lpr()
  761. {
  762. $cario_no = $this->uri->segment(3, 0); // 車格號碼
  763. $lpr = $this->uri->segment(4, 'NONE'); // 車號
  764. $in_time = urldecode($this->uri->segment(5, '')); // 入場時間
  765. $data = $this->carpark_model->correct_carin_lpr($cario_no, $lpr, $in_time);
  766. echo json_encode($data, JSON_UNESCAPED_UNICODE);
  767. }
  768. // 查詢行動支付記錄
  769. public function tx_bill_query()
  770. {
  771. $data = $this->carpark_model->tx_bill_query();
  772. echo json_encode($data, JSON_UNESCAPED_UNICODE);
  773. }
  774. // 查詢月租繳款機記錄
  775. public function tx_bill_ats_query()
  776. {
  777. $data = $this->carpark_model->tx_bill_ats_query();
  778. echo json_encode($data, JSON_UNESCAPED_UNICODE);
  779. }
  780. // 查詢樓層在席群組
  781. public function pks_group_query()
  782. {
  783. $data = $this->carpark_model->pks_group_query();
  784. echo json_encode($data, JSON_UNESCAPED_UNICODE);
  785. }
  786. // 微調剩餘車位數
  787. public function pks_availables_update()
  788. {
  789. $group_id = $this->uri->segment(3); // id
  790. $value = $this->uri->segment(4, 0); // value
  791. $station_no = $this->uri->segment(5); // station_no
  792. // mqtt subscribe
  793. $station_setting = $this->sync_data_model->station_setting_query();
  794. $mqtt_ip = isset($station_setting['mqtt_ip']) ? $station_setting['mqtt_ip'] : MQ_HOST;
  795. $mqtt_port = isset($station_setting['mqtt_port']) ? $station_setting['mqtt_port'] : MQ_PORT;
  796. // 字幕 MQTT
  797. $this->vars['mqtt'] = new phpMQTT($mqtt_ip, $mqtt_port, uniqid());
  798. $this->vars['mqtt']->connect();
  799. // 重新載入
  800. $this->sync_data_model->init($this->vars);
  801. $data = $this->sync_data_model->pks_availables_update($group_id, $value, true, $station_no);
  802. echo json_encode($data, JSON_UNESCAPED_UNICODE);
  803. }
  804. // 進出場觸發 888 呼叫
  805. /*
  806. public function sync_888()
  807. {
  808. $io = $this->uri->segment(3); // CI, CO, MI, MO
  809. if(empty($io))
  810. {
  811. echo 'io_not_found';
  812. exit;
  813. }
  814. $parms = array('io' => $io, 'etag' => __FUNCTION__, 'lpr' => __FUNCTION__);
  815. echo $this->sync_data_model->sync_888($parms);
  816. exit;
  817. }
  818. */
  819. public function test()
  820. {
  821. //echo `whoami`;
  822. //echo phpinfo();
  823. }
  824. // 博辰測試用
  825. // http://localhost/carpark.html/test_8068_002/APK7310
  826. public function test_8068_002()
  827. {
  828. $lpr_in = $this->uri->segment(3);
  829. $seqno = '00001';
  830. $cmd = '002';
  831. $token = '000000000';
  832. $lpr = str_pad($lpr_in, 7, '%', STR_PAD_LEFT);
  833. $in_time = '2000/01/01 00:00:00';
  834. $error_str = '';
  835. $service_port = 8068;
  836. $address = "192.168.10.201";
  837. /* Create a TCP/IP socket. */
  838. $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  839. if ($socket === false) {
  840. echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
  841. $error_str .= "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
  842. } else {
  843. echo "OK.\n";
  844. }
  845. echo "Attempting to connect to '{$address}' on port '{$service_port}'...";
  846. $result = socket_connect($socket, $address, $service_port);
  847. if ($result === false) {
  848. echo "socket_connect() failed.\nReason: ({$result}) " . socket_strerror(socket_last_error($socket)) . "\n";
  849. $error_str .= "socket_connect() failed: reason: " . socket_strerror(socket_last_error($socket)) . "\n";
  850. } else {
  851. echo "OK.\n";
  852. }
  853. $in = pack('Ca5Ca3Ca9Ca7Ca19', 0x1c, $seqno, 0x1c, $cmd, 0x1c,
  854. $token, 0x1f, $lpr, 0x1f, $in_time
  855. );
  856. $out = '';
  857. echo "socket_write:";
  858. echo "{$in}<br/><br/>";
  859. if(!socket_write($socket, $in, strlen($in)))
  860. {
  861. echo('<p>Write failed</p>');
  862. $error_str .= "socket_write() failed: reason: " . socket_strerror(socket_last_error($socket)) . "\n";
  863. }
  864. echo "socket_write..OK..";
  865. echo "<br/><br/>socket_read:";
  866. $out = socket_read($socket, 2048) or die("Could not read server responsen");
  867. //while ($out = socket_read($socket, 2048)) {
  868. // echo $out;
  869. //}
  870. echo "{$out}<br/><br/>";
  871. echo "Closing socket...";
  872. socket_close($socket);
  873. echo "OK.\n\n";
  874. trigger_error($error_str);
  875. exit;
  876. }
  877. // test
  878. public function test_phpexcel()
  879. {
  880. $query_year = 2017;
  881. $query_month = 3;
  882. //$this->excel_model->export_cario_data($query_year, $query_month);
  883. $this->excel_model->export_members();
  884. }
  885. }