parkspace_allocator.cpp 28 KB

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