parkspace_allocator.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. /*
  2. * @Description: 车位分配算法模块,使用单例模式,接收外部请求并通过调用通信块接口发送反馈
  3. * @Author: yct
  4. * @Date: 2020-07-10 11:02:40
  5. * @LastEditTime: 2020-07-21 18:15:51
  6. * @LastEditors: yct
  7. */
  8. #include "parkspace_allocator.h"
  9. #include "parkspace_allocation_communicator.h"
  10. Parkspace_allocator::Parkspace_allocator()
  11. {
  12. }
  13. Parkspace_allocator::~Parkspace_allocator()
  14. {
  15. parkspace_allocator_uninit();
  16. }
  17. //初始化
  18. Error_manager Parkspace_allocator::parkspace_allocator_init(int threads_size, parkspace_proto::database_config db_config)
  19. {
  20. // 初始化db连接
  21. mp_db_manager = Parkspace_db_manager::get_instance_pointer();
  22. if(mp_db_manager == nullptr)
  23. {
  24. return POINTER_IS_NULL;
  25. }
  26. Error_manager ec = mp_db_manager->Parkspace_db_manager_init(db_config);
  27. if(ec != SUCCESS)
  28. {
  29. return ec;
  30. }
  31. m_current_status = eParkspace_allocator_normal;
  32. // 初始化任务处理线程池
  33. m_thread_pool.thread_pool_init(threads_size);
  34. m_current_status = eParkspace_allocator_normal;
  35. return Error_code::SUCCESS;
  36. }
  37. //反初始化
  38. Error_manager Parkspace_allocator::parkspace_allocator_uninit()
  39. {
  40. m_thread_pool.thread_pool_uninit();
  41. mp_db_manager->Parkspace_db_manager_uninit();
  42. m_current_status = eParkspace_allocator_unknown;
  43. return Error_code::SUCCESS;
  44. }
  45. //检查执行者的状态, 判断能否处理这条消息,
  46. Error_manager Parkspace_allocator::check_executer(Communication_message* p_msg)
  47. {
  48. if ( p_msg == NULL )
  49. {
  50. return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
  51. " POINTER IS NULL ");
  52. }
  53. Error_manager t_error = SUCCESS;
  54. return t_error;
  55. }
  56. //处理消息的执行函数
  57. Error_manager Parkspace_allocator::execute_msg(Communication_message* p_msg)
  58. {
  59. if ( p_msg == nullptr )
  60. {
  61. return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR,
  62. " POINTER IS NULL ");
  63. }
  64. switch ( p_msg->get_message_type() )
  65. {
  66. ///车位分配请求消息
  67. case Communication_message::eParkspace_allocation_request_msg:
  68. {
  69. message::Parkspace_allocation_request_msg request;
  70. bool result = request.ParseFromString(p_msg->get_message_buf());
  71. LOG(INFO)<<"allocation request, car license: "<<request.car_info().license();
  72. if(!result)
  73. {
  74. return Error_manager(Error_code::PARKSPACE_ALLOCATOR_MSG_PARSE_ERROR, Error_level::MINOR_ERROR,
  75. " message::Parkspace_allocation_request_msg ParseFromString error ");
  76. }
  77. //往线程池添加执行任务, 之后会唤醒一个线程去执行他.
  78. m_thread_pool.enqueue(&Parkspace_allocator::execute_for_allocate, this,
  79. request.car_info(), request.terminal_id(), request.command_id());
  80. return SUCCESS;
  81. }
  82. // 车位查询请求消息
  83. case Communication_message::eParkspace_search_request_msg:
  84. {
  85. message::Parkspace_search_request_msg request;
  86. bool result = request.ParseFromString(p_msg->get_message_buf());
  87. LOG(INFO)<<"search request, car license: "<<request.car_info().license();
  88. if(!result)
  89. {
  90. return Error_manager(Error_code::PARKSPACE_ALLOCATOR_MSG_PARSE_ERROR, Error_level::MINOR_ERROR,
  91. " message::Parkspace_search_request_msg ParseFromString error ");
  92. }
  93. //往线程池添加执行任务, 之后会唤醒一个线程去执行他.
  94. m_thread_pool.enqueue(&Parkspace_allocator::execute_for_search, this, request.car_info(), request.command_id());
  95. return SUCCESS;
  96. }
  97. // 车位释放请求消息
  98. case Communication_message::eParkspace_release_request_msg:
  99. {
  100. message::Parkspace_release_request_msg request;
  101. bool result = request.ParseFromString(p_msg->get_message_buf());
  102. LOG(INFO)<<"release request, parkspace id: "<<request.release_space_info().parkspace_id();
  103. if(!result)
  104. {
  105. return Error_manager(Error_code::PARKSPACE_ALLOCATOR_MSG_PARSE_ERROR, Error_level::MINOR_ERROR,
  106. " message::Parkspace_release_request_msg ParseFromString error ");
  107. }
  108. //往线程池添加执行任务, 之后会唤醒一个线程去执行他.
  109. m_thread_pool.enqueue(&Parkspace_allocator::execute_for_release, this, request.release_space_info(), request.command_id());
  110. return SUCCESS;
  111. }
  112. // 车位手动更新请求消息
  113. case Communication_message::eParkspace_force_update_request_msg:
  114. {
  115. message::Parkspace_force_update_request_msg request;
  116. bool result = request.ParseFromString(p_msg->get_message_buf());
  117. LOG(INFO)<<"force update request, parkspace id: "<<request.update_space_info().parkspace_id();
  118. if(!result)
  119. {
  120. return Error_manager(Error_code::PARKSPACE_ALLOCATOR_MSG_PARSE_ERROR, Error_level::MINOR_ERROR,
  121. " message::Parkspace_force_update_request_msg ParseFromString error ");
  122. }
  123. //往线程池添加执行任务, 之后会唤醒一个线程去执行他.
  124. m_thread_pool.enqueue(&Parkspace_allocator::execute_for_force_update, this, request.update_space_info(), request.command_id());
  125. return SUCCESS;
  126. }
  127. // 车位确认占用请求消息
  128. case Communication_message::eParkspace_confirm_alloc_request_msg:
  129. {
  130. message::Parkspace_confirm_alloc_request_msg request;
  131. bool result = request.ParseFromString(p_msg->get_message_buf());
  132. LOG(INFO)<<"confirm alloc request, parkspace id: "<<request.confirm_space_info().parkspace_id();
  133. if(!result)
  134. {
  135. return Error_manager(Error_code::PARKSPACE_ALLOCATOR_MSG_PARSE_ERROR, Error_level::MINOR_ERROR,
  136. " message::Parkspace_force_update_request_msg ParseFromString error ");
  137. }
  138. //往线程池添加执行任务, 之后会唤醒一个线程去执行他.
  139. m_thread_pool.enqueue(&Parkspace_allocator::execute_for_force_update, this, request.confirm_space_info(), request.command_id());
  140. return SUCCESS;
  141. }
  142. }
  143. return Error_code::PARKSPACE_ALLOCATOR_MSG_REQUEST_TYPE_ERROR;
  144. }
  145. //判断是否为待机,如果已经准备好,则可以执行任务。
  146. bool Parkspace_allocator::is_ready()
  147. {
  148. if ( m_current_status == eParkspace_allocator_normal && m_thread_pool.thread_is_full_load() == false )
  149. {
  150. return true;
  151. }
  152. else
  153. {
  154. return false;
  155. }
  156. }
  157. Parkspace_allocator::parkspace_allocator_status Parkspace_allocator::get_parkspace_allocator_status()
  158. {
  159. return m_current_status;
  160. }
  161. //分配车位线程函数
  162. void Parkspace_allocator::execute_for_allocate(message::Car_info car_info, int terminal_id, int command_id)
  163. {
  164. std::lock_guard<std::mutex> lck(m_mutex);
  165. LOG(INFO) << "分配";
  166. //根据请求的信息反馈分配的车位,并封装发送
  167. message::Parkspace_allocation_response_msg response_msg;
  168. message::Base_info t_response_header;
  169. t_response_header.set_msg_type(message::Message_type::eParkspace_allocation_response_msg);
  170. t_response_header.set_timeout_ms(1000);
  171. t_response_header.set_sender(message::Communicator::eParkspace);
  172. t_response_header.set_receiver(message::Communicator::eMain);
  173. message::Error_manager t_error;
  174. message::Parkspace_info t_allocated_space;
  175. //获取当前所有车位状态,分配车位
  176. message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status();
  177. int index = -1;
  178. if(t_current_parkspace_status.parkspace_info_size()<=0)
  179. {
  180. t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY);
  181. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  182. LOG(ERROR) << "无车位";
  183. }
  184. else
  185. {
  186. for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++)
  187. {
  188. // 找到高于车高且空闲车位,则分配
  189. if (t_current_parkspace_status.parkspace_info(i).height() > car_info.car_height()
  190. && t_current_parkspace_status.parkspace_info(i).width() > car_info.car_width()
  191. && t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_empty)
  192. {
  193. index = i;
  194. break;
  195. }
  196. }
  197. if(index<0){
  198. t_error.set_error_code(PARKSPACE_ALLOCATOR_ALLOCATE_FAILED);
  199. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  200. t_allocated_space.CopyFrom(t_current_parkspace_status.parkspace_info(0));
  201. LOG(WARNING) << "分配车位失败";
  202. }else{
  203. t_error.set_error_code(SUCCESS);
  204. t_error.set_error_level(message::Error_level::NORMAL);
  205. message::Parkspace_info t_space_to_lock = t_current_parkspace_status.parkspace_info(index);
  206. t_space_to_lock.set_parkspace_status(message::Parkspace_status::eParkspace_locked);
  207. t_space_to_lock.mutable_car_info()->CopyFrom(car_info);
  208. t_allocated_space.CopyFrom(t_space_to_lock);
  209. // 分配车位后更新车位状态
  210. Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_space_to_lock);
  211. LOG(INFO) << "第"<<index<<"号位占用, id: "<<t_space_to_lock.parkspace_id();
  212. // 数据库操作,修改车位状态为锁定,车辆状态为停车中
  213. message::Vehicle_status t_vehicle_status = message::Vehicle_status::eVehicle_parking;
  214. Error_manager ec = Parkspace_db_manager::get_instance_references().update_parkspace_status(t_space_to_lock);
  215. if(ec != SUCCESS)
  216. {
  217. LOG(ERROR) << "更新db车位状态失败";
  218. }
  219. ec = Parkspace_db_manager::get_instance_references().update_vehicle_status(t_space_to_lock, t_vehicle_status);
  220. if (ec != SUCCESS)
  221. {
  222. LOG(ERROR) << "更新db车辆状态失败";
  223. }
  224. }
  225. }
  226. response_msg.mutable_base_info()->CopyFrom(t_response_header);
  227. response_msg.set_command_id(command_id);
  228. response_msg.mutable_error_manager()->CopyFrom(t_error);
  229. response_msg.mutable_allocated_space_info()->CopyFrom(t_allocated_space);
  230. Communication_message response=Communication_message();
  231. response.reset(t_response_header, response_msg.SerializeAsString());
  232. Parkspace_allocation_communicator::get_instance_references().send_response(&response);
  233. }
  234. //查询车位线程函数
  235. void Parkspace_allocator::execute_for_search(message::Car_info car_info, int command_id)
  236. {
  237. std::lock_guard<std::mutex> lck(m_mutex);
  238. LOG(INFO) << "查询";
  239. //根据车辆凭证信息查询车辆位置
  240. message::Parkspace_search_response_msg response_msg;
  241. message::Base_info t_response_header;
  242. message::Error_manager t_error;
  243. message::Parkspace_info t_car_position;
  244. t_response_header.set_msg_type(message::Message_type::eParkspace_search_response_msg);
  245. t_response_header.set_timeout_ms(1000);
  246. t_response_header.set_sender(message::Communicator::eParkspace);
  247. t_response_header.set_receiver(message::Communicator::eMain);
  248. //获取当前所有车位状态,查询车辆位置
  249. message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status();
  250. int index = -1;
  251. if(t_current_parkspace_status.parkspace_info_size()<=0)
  252. {
  253. t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY);
  254. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  255. LOG(ERROR) << "无车位";
  256. }
  257. else
  258. {
  259. for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++)
  260. {
  261. // 找到凭证号/号牌对应车位,记录
  262. if (t_current_parkspace_status.parkspace_info(i).has_car_info()
  263. && t_current_parkspace_status.parkspace_info(i).car_info().license() == car_info.license()
  264. && t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_occupied)
  265. {
  266. index = i;
  267. break;
  268. }
  269. }
  270. if(index<0){
  271. t_error.set_error_code(PARKSPACE_ALLOCATOR_SEARCH_FAILED);
  272. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  273. LOG(INFO) << "查询车位失败";
  274. }else{
  275. t_error.set_error_code(SUCCESS);
  276. t_error.set_error_level(message::Error_level::NORMAL);
  277. message::Parkspace_info t_space_searching = t_current_parkspace_status.parkspace_info(index);
  278. t_car_position.CopyFrom(t_space_searching);
  279. LOG(INFO) << "车辆"<<car_info.license() <<"在第"<<index<<"号位, id: "<<t_space_searching.parkspace_id();
  280. // 无数据库操作
  281. }
  282. }
  283. response_msg.mutable_base_info()->CopyFrom(t_response_header);
  284. response_msg.set_command_id(command_id);
  285. response_msg.mutable_error_manager()->CopyFrom(t_error);
  286. response_msg.mutable_car_position()->CopyFrom(t_car_position);
  287. Communication_message response=Communication_message();
  288. response.reset(t_response_header, response_msg.SerializeAsString());
  289. Parkspace_allocation_communicator::get_instance_references().send_response(&response);
  290. }
  291. //释放车位线程函数
  292. void Parkspace_allocator::execute_for_release(message::Parkspace_info space_info, int command_id)
  293. {
  294. std::lock_guard<std::mutex> lck(m_mutex);
  295. LOG(INFO) << "释放";
  296. //根据车位信息定位待释放车位位置,车辆凭证号用于校验
  297. message::Parkspace_release_response_msg response_msg;
  298. message::Base_info t_response_header;
  299. t_response_header.set_msg_type(message::eParkspace_release_response_msg);
  300. t_response_header.set_sender(message::eParkspace);
  301. t_response_header.set_receiver(message::eMain);
  302. message::Error_manager t_error;
  303. message::Parkspace_info t_release_space;
  304. //获取当前所有车位状态,找到待释放的车位
  305. message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status();
  306. int index = -1;
  307. if(t_current_parkspace_status.parkspace_info_size()<=0)
  308. {
  309. t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY);
  310. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  311. LOG(ERROR) << "无车位";
  312. }
  313. else if (!space_info.has_car_info())
  314. {
  315. t_error.set_error_code(PARKSPACE_ALLOCATOR_RELEASE_FAILED);
  316. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  317. LOG(WARNING) << "传入待释放车位无车辆信息";
  318. }
  319. else
  320. {
  321. for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++)
  322. {
  323. // 找到占用或锁定的车位,且车辆信息匹配
  324. if (t_current_parkspace_status.parkspace_info(i).parkspace_id() == space_info.parkspace_id()
  325. && (t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_occupied
  326. ||t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_locked)
  327. && t_current_parkspace_status.parkspace_info(i).has_car_info()
  328. && t_current_parkspace_status.parkspace_info(i).car_info().license() == space_info.car_info().license())
  329. {
  330. index = i;
  331. break;
  332. }
  333. }
  334. if(index<0){
  335. t_error.set_error_code(PARKSPACE_ALLOCATOR_RELEASE_FAILED);
  336. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  337. LOG(WARNING) << "释放车位失败";
  338. }else{
  339. t_error.set_error_code(SUCCESS);
  340. t_error.set_error_level(message::Error_level::NORMAL);
  341. message::Parkspace_info t_space_to_release = t_current_parkspace_status.parkspace_info(index);
  342. t_space_to_release.set_parkspace_status(message::Parkspace_status::eParkspace_empty);
  343. t_release_space.CopyFrom(t_space_to_release);
  344. // 分配车位后更新车位状态
  345. Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_space_to_release);
  346. LOG(INFO) << "第"<<index<<"号位释放, id: "<<t_space_to_release.parkspace_id();
  347. // 数据库操作,车位状态改为空闲,查询车辆状态,确定是停车失败还是取车完成
  348. // 停车失败仅修改车位与车辆状态
  349. // 取车完成同时还修改停车记录
  350. Error_manager ec = Parkspace_db_manager::get_instance_references().update_parkspace_status(t_space_to_release);
  351. if(ec != SUCCESS)
  352. {
  353. LOG(ERROR) << "更新db车位状态失败";
  354. }
  355. message::Vehicle_status t_vehicle_status = message::Vehicle_status::eVehicle_idle;
  356. ec = Parkspace_db_manager::get_instance_references().update_vehicle_status(t_space_to_release, t_vehicle_status);
  357. if(ec != SUCCESS)
  358. {
  359. LOG(ERROR) << "更新db车辆状态失败";
  360. }
  361. int t_park_record_id;
  362. ec = Parkspace_db_manager::get_instance_references().query_vehicle(t_space_to_release.car_info().license(), t_vehicle_status, t_park_record_id);
  363. if(ec != SUCCESS)
  364. {
  365. LOG(ERROR) << "查询db车辆状态失败";
  366. }else if(t_vehicle_status == message::Vehicle_status::eVehicle_in_garage)
  367. {
  368. time_t tt = time(NULL);
  369. tm *t = localtime(&tt);
  370. char my_time_buf[255];
  371. memset(my_time_buf, 0, 255);
  372. sprintf(my_time_buf, "%d-%02d-%02d %02d:%02d:%02d",
  373. t->tm_year + 1900,
  374. t->tm_mon + 1,
  375. t->tm_mday,
  376. t->tm_hour,
  377. t->tm_min,
  378. t->tm_sec);
  379. t_space_to_release.set_leave_time(my_time_buf);
  380. ec = Parkspace_db_manager::get_instance_references().update_parking_record(t_space_to_release, t_park_record_id);
  381. if(ec != SUCCESS)
  382. {
  383. LOG(ERROR) << "更新db停车记录失败";
  384. }
  385. }
  386. }
  387. }
  388. response_msg.mutable_base_info()->CopyFrom(t_response_header);
  389. response_msg.set_command_id(command_id);
  390. response_msg.mutable_error_manager()->CopyFrom(t_error);
  391. response_msg.mutable_release_space_info()->CopyFrom(t_release_space);
  392. Communication_message response=Communication_message();
  393. response.reset(t_response_header, response_msg.SerializeAsString());
  394. Parkspace_allocation_communicator::get_instance_references().send_response(&response);
  395. }
  396. //强制更新车位信息线程函数
  397. void Parkspace_allocator::execute_for_force_update(message::Parkspace_info space_info, int command_id)
  398. {
  399. std::lock_guard<std::mutex> lck(m_mutex);
  400. LOG(INFO) << "手动";
  401. //根据车位信息定位待释放车位位置,车辆凭证号用于校验
  402. //!!!!!此处跳过外部处理与调用的过程,直接在内部调用,发送分配结果用于测试,目前一直发布第一个车位
  403. message::Parkspace_force_update_response_msg response_msg;
  404. message::Base_info t_response_header;
  405. message::Error_manager t_error;
  406. message::Parkspace_info t_update_space;
  407. //获取当前所有车位状态,找到待释放的车位
  408. message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status();
  409. int index = -1;
  410. if(t_current_parkspace_status.parkspace_info_size()<=0)
  411. {
  412. t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY);
  413. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  414. LOG(ERROR) << "无车位";
  415. }
  416. else
  417. {
  418. for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++)
  419. {
  420. // 找到高于车高且空闲车位,则分配
  421. if (t_current_parkspace_status.parkspace_info(i).parkspace_id() == space_info.parkspace_id())
  422. {
  423. index = i;
  424. break;
  425. }
  426. }
  427. if(index<0){
  428. t_error.set_error_code(PARKSPACE_ALLOCATOR_FORCE_UPDATE_FAILED);
  429. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  430. LOG(WARNING) << "手动更新车位失败";
  431. }else{
  432. t_error.set_error_code(SUCCESS);
  433. t_error.set_error_level(message::Error_level::NORMAL);
  434. t_update_space.CopyFrom(space_info);
  435. // 分配车位后更新车位状态
  436. Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_update_space);
  437. LOG(INFO) << "第"<<index<<"号位已手动更新, id: "<<t_update_space.parkspace_id();
  438. // 数据库操作,车位状态根据手动值进行修改
  439. Error_manager ec = Parkspace_db_manager::get_instance_references().update_parkspace_status(t_update_space);
  440. if(ec != SUCCESS)
  441. {
  442. LOG(ERROR) << "更新db车位状态失败";
  443. }
  444. }
  445. }
  446. response_msg.mutable_base_info()->CopyFrom(t_response_header);
  447. response_msg.set_command_id(command_id);
  448. response_msg.mutable_error_manager()->CopyFrom(t_error);
  449. response_msg.mutable_update_space_info()->CopyFrom(t_update_space);
  450. Communication_message response=Communication_message();
  451. response.reset(t_response_header, response_msg.SerializeAsString());
  452. Parkspace_allocation_communicator::get_instance_references().send_response(&response);
  453. }
  454. //确认分配车位线程函数
  455. void Parkspace_allocator::execute_for_confirm_alloc(message::Parkspace_info space_info, int command_id)
  456. {
  457. std::lock_guard<std::mutex> lck(m_mutex);
  458. LOG(INFO) << "确认分配";
  459. //根据车位信息定位待确认占用车位
  460. message::Parkspace_confirm_alloc_response_msg response_msg;
  461. message::Base_info t_response_header;
  462. message::Error_manager t_error;
  463. message::Parkspace_info t_confirm_space;
  464. //获取当前所有车位状态,找到待释放的车位
  465. message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status();
  466. int index = -1;
  467. if(t_current_parkspace_status.parkspace_info_size()<=0)
  468. {
  469. t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY);
  470. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  471. LOG(ERROR) << "无车位";
  472. }
  473. else if (!space_info.has_car_info())
  474. {
  475. t_error.set_error_code(PARKSPACE_ALLOCATOR_PARAM_ERROR);
  476. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  477. LOG(WARNING) << "传入确认占用车位无车辆信息";
  478. }
  479. else
  480. {
  481. for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++)
  482. {
  483. // 找到相同车位,且车辆信息匹配
  484. if (t_current_parkspace_status.parkspace_info(i).parkspace_id() == space_info.parkspace_id()
  485. && t_current_parkspace_status.parkspace_info(i).has_car_info()
  486. && t_current_parkspace_status.parkspace_info(i).car_info().license() == space_info.car_info().license())
  487. {
  488. index = i;
  489. break;
  490. }
  491. }
  492. if(index<0){
  493. t_error.set_error_code(PARKSPACE_ALLOCATOR_CONFIRM_ALLOC_ERROR);
  494. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  495. LOG(WARNING) << "确认占用车位失败";
  496. }else{
  497. t_error.set_error_code(SUCCESS);
  498. t_error.set_error_level(message::Error_level::NORMAL);
  499. t_confirm_space.CopyFrom(space_info);
  500. t_confirm_space.set_parkspace_status(message::Parkspace_status::eParkspace_occupied);
  501. time_t tt = time(NULL);
  502. tm *t = localtime(&tt);
  503. char my_time_buf[255];
  504. memset(my_time_buf, 0, 255);
  505. sprintf(my_time_buf, "%d-%02d-%02d %02d:%02d:%02d",
  506. t->tm_year + 1900,
  507. t->tm_mon + 1,
  508. t->tm_mday,
  509. t->tm_hour,
  510. t->tm_min,
  511. t->tm_sec);
  512. t_confirm_space.set_entry_time(my_time_buf);
  513. // 分配车位后更新车位状态
  514. Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_confirm_space);
  515. LOG(INFO) << "第" << index << "号位已确认占用, id: " << t_confirm_space.parkspace_id();
  516. // 数据库操作,车位状态改为占用,插入停车记录,更新车辆状态为入库
  517. Error_manager ec = Parkspace_db_manager::get_instance_references().update_parkspace_status(t_confirm_space);
  518. if(ec != SUCCESS)
  519. {
  520. LOG(ERROR) << "更新db车位状态失败";
  521. }
  522. ec = Parkspace_db_manager::get_instance_references().insert_parking_record(t_confirm_space);
  523. if(ec != SUCCESS)
  524. {
  525. LOG(ERROR) << "插入db停车记录失败";
  526. }
  527. message::Vehicle_status t_vehicle_status = message::Vehicle_status::eVehicle_in_garage;
  528. ec = Parkspace_db_manager::get_instance_references().update_vehicle_status(t_confirm_space, t_vehicle_status);
  529. if(ec != SUCCESS)
  530. {
  531. LOG(ERROR) << "更新db车辆状态失败";
  532. }
  533. }
  534. }
  535. response_msg.mutable_base_info()->CopyFrom(t_response_header);
  536. response_msg.set_command_id(command_id);
  537. response_msg.mutable_error_manager()->CopyFrom(t_error);
  538. response_msg.mutable_confirm_alloc_space_info()->CopyFrom(t_confirm_space);
  539. Communication_message response=Communication_message();
  540. response.reset(t_response_header, response_msg.SerializeAsString());
  541. Parkspace_allocation_communicator::get_instance_references().send_response(&response);
  542. }