parkspace_allocator.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  1. /*
  2. * @Description: 车位分配算法模块,使用单例模式,接收外部请求并通过调用通信块接口发送反馈
  3. * @Author: yct
  4. * @Date: 2020-07-10 11:02:40
  5. * @LastEditTime: 2020-08-06 10:32:28
  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_key());
  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_key());
  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_key());
  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_key());
  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_key());
  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. bool Parkspace_allocator::check_car_existence(std::string license, message::Parkspace_allocation_status_msg status_msg)
  170. {
  171. for (size_t i = 0; i < status_msg.parkspace_info_size(); i++)
  172. {
  173. // 找到相同号牌,且车位状态锁定或占用
  174. if(status_msg.parkspace_info(i).has_car_info()
  175. && status_msg.parkspace_info(i).car_info().license() == license
  176. && (status_msg.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_locked ||
  177. status_msg.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_occupied))
  178. {
  179. return true;
  180. }
  181. }
  182. return false;
  183. }
  184. //分配车位线程函数
  185. void Parkspace_allocator::execute_for_allocate(message::Car_info car_info, int terminal_id, std::string command_key)
  186. {
  187. std::lock_guard<std::mutex> lck(m_mutex);
  188. LOG(INFO) << "分配";
  189. //根据请求的信息反馈分配的车位,并封装发送
  190. message::Parkspace_allocation_response_msg response_msg;
  191. message::Base_info t_response_header;
  192. t_response_header.set_msg_type(message::Message_type::eParkspace_allocation_response_msg);
  193. t_response_header.set_timeout_ms(1000);
  194. t_response_header.set_sender(message::Communicator::eParkspace);
  195. t_response_header.set_receiver(message::Communicator::eMain);
  196. message::Error_manager t_error;
  197. message::Parkspace_info t_allocated_space;
  198. //获取当前所有车位状态,分配车位
  199. message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status();
  200. int index = -1;
  201. if(t_current_parkspace_status.parkspace_info_size()<=0)
  202. {
  203. t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY);
  204. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  205. LOG(ERROR) << "无车位";
  206. }
  207. else if(check_car_existence(car_info.license(), t_current_parkspace_status))
  208. {
  209. t_error.set_error_code(PARKSPACE_ALLOCATOR_CAR_ALREADY_EXIST);
  210. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  211. LOG(ERROR) << "车辆已存在";
  212. }
  213. else
  214. {
  215. for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++)
  216. {
  217. // 找到高于车高且空闲车位,则分配
  218. if (t_current_parkspace_status.parkspace_info(i).has_car_info()
  219. /* && t_current_parkspace_status.parkspace_info(i).height() > car_info.car_height()
  220. && t_current_parkspace_status.parkspace_info(i).width() > car_info.car_width() */
  221. && t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_empty)
  222. {
  223. index = i;
  224. break;
  225. }
  226. }
  227. if(index<0){
  228. t_error.set_error_code(PARKSPACE_ALLOCATOR_ALLOCATE_FAILED);
  229. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  230. t_allocated_space.CopyFrom(t_current_parkspace_status.parkspace_info(0));
  231. t_allocated_space.mutable_car_info()->CopyFrom(car_info);
  232. LOG(WARNING) << "分配车位失败";
  233. }else{
  234. t_error.set_error_code(SUCCESS);
  235. t_error.set_error_level(message::Error_level::NORMAL);
  236. message::Parkspace_info t_space_to_lock = t_current_parkspace_status.parkspace_info(index);
  237. t_space_to_lock.set_parkspace_status(message::Parkspace_status::eParkspace_locked);
  238. t_space_to_lock.mutable_car_info()->CopyFrom(car_info);
  239. t_allocated_space.CopyFrom(t_space_to_lock);
  240. // 分配车位后更新车位状态
  241. Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_space_to_lock);
  242. LOG(INFO) << "第"<<index<<"号位占用, id: "<<t_space_to_lock.parkspace_id()<<", 号牌: "<<t_space_to_lock.car_info().license();
  243. // 数据库操作,修改车位状态为锁定,车辆状态为停车中
  244. message::Vehicle_status t_vehicle_status = message::Vehicle_status::eVehicle_parking;
  245. Error_manager ec = Parkspace_db_manager::get_instance_references().update_parkspace_status(t_space_to_lock);
  246. if(ec != SUCCESS)
  247. {
  248. LOG(ERROR) << "更新db车位状态失败: "<< ec.to_string();
  249. }
  250. ec = Parkspace_db_manager::get_instance_references().update_vehicle_status(t_space_to_lock, t_vehicle_status);
  251. if (ec != SUCCESS)
  252. {
  253. LOG(ERROR) << "更新db车辆状态失败: " <<ec.to_string();
  254. }
  255. }
  256. }
  257. response_msg.mutable_base_info()->CopyFrom(t_response_header);
  258. response_msg.set_command_key(command_key);
  259. response_msg.mutable_error_manager()->CopyFrom(t_error);
  260. response_msg.mutable_allocated_space_info()->CopyFrom(t_allocated_space);
  261. Communication_message response=Communication_message();
  262. response.reset(t_response_header, response_msg.SerializeAsString());
  263. Parkspace_allocation_communicator::get_instance_references().send_response(&response);
  264. }
  265. //查询车位线程函数
  266. void Parkspace_allocator::execute_for_search(message::Car_info car_info,std::string command_key)
  267. {
  268. std::lock_guard<std::mutex> lck(m_mutex);
  269. LOG(INFO) << "查询";
  270. //根据车辆凭证信息查询车辆位置
  271. message::Parkspace_search_response_msg response_msg;
  272. message::Base_info t_response_header;
  273. message::Error_manager t_error;
  274. message::Parkspace_info t_car_position;
  275. t_response_header.set_msg_type(message::Message_type::eParkspace_search_response_msg);
  276. t_response_header.set_timeout_ms(1000);
  277. t_response_header.set_sender(message::Communicator::eParkspace);
  278. t_response_header.set_receiver(message::Communicator::eMain);
  279. //获取当前所有车位状态,查询车辆位置
  280. message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status();
  281. int index = -1;
  282. if(t_current_parkspace_status.parkspace_info_size()<=0)
  283. {
  284. t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY);
  285. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  286. LOG(ERROR) << "无车位";
  287. }
  288. else
  289. {
  290. for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++)
  291. {
  292. // 找到凭证号/号牌对应车位,记录
  293. if (t_current_parkspace_status.parkspace_info(i).has_car_info()
  294. && t_current_parkspace_status.parkspace_info(i).car_info().license() == car_info.license()
  295. && t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_occupied)
  296. {
  297. index = i;
  298. break;
  299. }
  300. }
  301. if(index<0){
  302. t_error.set_error_code(PARKSPACE_ALLOCATOR_SEARCH_FAILED);
  303. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  304. // 默认第一个车位
  305. t_car_position.CopyFrom(t_current_parkspace_status.parkspace_info(0));
  306. LOG(INFO) << "查询车位失败";
  307. }else{
  308. t_error.set_error_code(SUCCESS);
  309. t_error.set_error_level(message::Error_level::NORMAL);
  310. message::Parkspace_info t_space_searching = t_current_parkspace_status.parkspace_info(index);
  311. t_car_position.CopyFrom(t_space_searching);
  312. LOG(INFO) << "车辆"<<car_info.license() <<"在第"<<index<<"号位, id: "<<t_space_searching.parkspace_id();
  313. // 无数据库操作
  314. }
  315. }
  316. response_msg.mutable_base_info()->CopyFrom(t_response_header);
  317. response_msg.set_command_key(command_key);
  318. response_msg.mutable_error_manager()->CopyFrom(t_error);
  319. response_msg.mutable_car_position()->CopyFrom(t_car_position);
  320. Communication_message response=Communication_message();
  321. response.reset(t_response_header, response_msg.SerializeAsString());
  322. Parkspace_allocation_communicator::get_instance_references().send_response(&response);
  323. }
  324. //释放车位线程函数
  325. void Parkspace_allocator::execute_for_release(message::Parkspace_info space_info, std::string command_key)
  326. {
  327. std::lock_guard<std::mutex> lck(m_mutex);
  328. LOG(INFO) << "释放";
  329. //根据车位信息定位待释放车位位置,车辆凭证号用于校验
  330. message::Parkspace_release_response_msg response_msg;
  331. message::Base_info t_response_header;
  332. t_response_header.set_msg_type(message::eParkspace_release_response_msg);
  333. t_response_header.set_sender(message::eParkspace);
  334. t_response_header.set_receiver(message::eMain);
  335. t_response_header.set_timeout_ms(1000);
  336. message::Error_manager t_error;
  337. message::Parkspace_info t_release_space;
  338. //获取当前所有车位状态,找到待释放的车位
  339. message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status();
  340. int index = -1;
  341. if(t_current_parkspace_status.parkspace_info_size()<=0)
  342. {
  343. t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY);
  344. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  345. LOG(ERROR) << "无车位";
  346. }
  347. else if (!space_info.has_car_info())
  348. {
  349. t_error.set_error_code(PARKSPACE_ALLOCATOR_RELEASE_FAILED);
  350. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  351. LOG(WARNING) << "传入待释放车位无车辆信息";
  352. }
  353. else
  354. {
  355. for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++)
  356. {
  357. // 找到占用或锁定的车位,且车辆信息匹配
  358. if (t_current_parkspace_status.parkspace_info(i).parkspace_id() == space_info.parkspace_id()
  359. && (t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_occupied
  360. ||t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_locked)
  361. && t_current_parkspace_status.parkspace_info(i).has_car_info()
  362. && t_current_parkspace_status.parkspace_info(i).car_info().license() == space_info.car_info().license())
  363. {
  364. index = i;
  365. break;
  366. }
  367. }
  368. if(index<0){
  369. t_error.set_error_code(PARKSPACE_ALLOCATOR_RELEASE_FAILED);
  370. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  371. // 传入默认车位信息
  372. t_release_space.CopyFrom(space_info);
  373. LOG(WARNING) << "释放车位失败 input:"<<space_info.DebugString()<<", self:"<<t_current_parkspace_status.parkspace_info(space_info.parkspace_id()-1).DebugString();
  374. }else{
  375. t_error.set_error_code(SUCCESS);
  376. t_error.set_error_level(message::Error_level::NORMAL);
  377. message::Parkspace_info t_space_to_release = t_current_parkspace_status.parkspace_info(index);
  378. t_space_to_release.set_parkspace_status(message::Parkspace_status::eParkspace_empty);
  379. t_release_space.CopyFrom(t_space_to_release);
  380. // 分配车位后更新车位状态
  381. Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_space_to_release);
  382. LOG(INFO) << "第"<<index<<"号位释放, id: "<<t_space_to_release.parkspace_id();
  383. // 数据库操作,车位状态改为空闲,查询车辆状态,确定是停车失败还是取车完成
  384. // 停车失败仅修改车位与车辆状态
  385. // 取车完成同时还修改停车记录
  386. Error_manager ec = Parkspace_db_manager::get_instance_references().update_parkspace_status(t_space_to_release);
  387. if(ec != SUCCESS)
  388. {
  389. LOG(ERROR) << "更新db车位状态失败: "<< ec.to_string();
  390. }
  391. message::Vehicle_status t_vehicle_status = message::Vehicle_status::eVehicle_idle;
  392. ec = Parkspace_db_manager::get_instance_references().update_vehicle_status(t_space_to_release, t_vehicle_status);
  393. if(ec != SUCCESS)
  394. {
  395. LOG(ERROR) << "更新db车辆状态失败: "<< ec.to_string();
  396. }
  397. int t_park_record_id;
  398. ec = Parkspace_db_manager::get_instance_references().query_vehicle(t_space_to_release.car_info().license(), t_vehicle_status, t_park_record_id);
  399. if(ec != SUCCESS)
  400. {
  401. LOG(ERROR) << "查询db车辆状态失败: "<< ec.to_string();
  402. }else if(t_vehicle_status == message::Vehicle_status::eVehicle_in_garage)
  403. {
  404. time_t tt = time(NULL);
  405. tm *t = localtime(&tt);
  406. char my_time_buf[255];
  407. memset(my_time_buf, 0, 255);
  408. sprintf(my_time_buf, "%d-%02d-%02d %02d:%02d:%02d",
  409. t->tm_year + 1900,
  410. t->tm_mon + 1,
  411. t->tm_mday,
  412. t->tm_hour,
  413. t->tm_min,
  414. t->tm_sec);
  415. t_space_to_release.set_leave_time(my_time_buf);
  416. ec = Parkspace_db_manager::get_instance_references().update_parking_record(t_space_to_release, t_park_record_id);
  417. if(ec != SUCCESS)
  418. {
  419. LOG(ERROR) << "更新db停车记录失败: "<< ec.to_string();
  420. }
  421. }
  422. }
  423. }
  424. response_msg.mutable_base_info()->CopyFrom(t_response_header);
  425. response_msg.set_command_key(command_key);
  426. response_msg.mutable_error_manager()->CopyFrom(t_error);
  427. response_msg.mutable_release_space_info()->CopyFrom(t_release_space);
  428. Communication_message response=Communication_message();
  429. response.reset(t_response_header, response_msg.SerializeAsString());
  430. Parkspace_allocation_communicator::get_instance_references().send_response(&response);
  431. }
  432. //强制更新车位信息线程函数
  433. void Parkspace_allocator::execute_for_force_update(message::Parkspace_info space_info, std::string command_key)
  434. {
  435. std::lock_guard<std::mutex> lck(m_mutex);
  436. LOG(INFO) << "手动";
  437. //根据车位信息定位待释放车位位置,车辆凭证号用于校验
  438. //!!!!!此处跳过外部处理与调用的过程,直接在内部调用,发送分配结果用于测试,目前一直发布第一个车位
  439. message::Parkspace_force_update_response_msg response_msg;
  440. message::Base_info t_response_header;
  441. t_response_header.set_msg_type(message::eParkspace_force_update_response_msg);
  442. t_response_header.set_sender(message::eParkspace);
  443. t_response_header.set_receiver(message::eMain);
  444. t_response_header.set_timeout_ms(1000);
  445. message::Error_manager t_error;
  446. message::Parkspace_info t_update_space;
  447. //获取当前所有车位状态,找到待释放的车位
  448. message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status();
  449. int index = -1;
  450. if(t_current_parkspace_status.parkspace_info_size()<=0)
  451. {
  452. t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY);
  453. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  454. LOG(ERROR) << "无车位";
  455. }
  456. else
  457. {
  458. // id 9999为特殊情况,复位所有车位状态
  459. if (space_info.parkspace_id() == 9999)
  460. {
  461. t_error.set_error_code(SUCCESS);
  462. t_error.set_error_level(message::Error_level::NORMAL);
  463. t_update_space.CopyFrom(space_info);
  464. // 复位所有车位状态
  465. for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++)
  466. {
  467. t_current_parkspace_status.mutable_parkspace_info(i)->set_parkspace_status(message::Parkspace_status::eParkspace_empty);
  468. t_current_parkspace_status.mutable_parkspace_info(i)->mutable_car_info()->set_license("");
  469. }
  470. Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(t_current_parkspace_status);
  471. LOG(INFO) << "所有车位已手动更新 ";
  472. // 数据库操作,车位状态根据手动值进行修改
  473. Error_manager ec = Parkspace_db_manager::get_instance_references().clean_all_parkspace_info();
  474. if (ec != SUCCESS)
  475. {
  476. LOG(ERROR) << "复位db车位状态失败: " << ec.to_string();
  477. }
  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. {
  486. index = i;
  487. break;
  488. }
  489. }
  490. if (index < 0)
  491. {
  492. t_error.set_error_code(PARKSPACE_ALLOCATOR_FORCE_UPDATE_FAILED);
  493. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  494. t_update_space.CopyFrom(space_info);
  495. LOG(WARNING) << "手动更新车位失败";
  496. }
  497. else
  498. {
  499. t_error.set_error_code(SUCCESS);
  500. t_error.set_error_level(message::Error_level::NORMAL);
  501. t_update_space.CopyFrom(space_info);
  502. // 分配车位后更新车位状态
  503. Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_update_space);
  504. LOG(INFO) << "第" << index << "号位已手动更新, id: " << t_update_space.parkspace_id();
  505. // 数据库操作,车位状态根据手动值进行修改
  506. Error_manager ec = Parkspace_db_manager::get_instance_references().update_parkspace_status(t_update_space);
  507. if (ec != SUCCESS)
  508. {
  509. LOG(ERROR) << "更新db车位状态失败: " << ec.to_string();
  510. }
  511. }
  512. }
  513. }
  514. response_msg.mutable_base_info()->CopyFrom(t_response_header);
  515. response_msg.set_command_key(command_key);
  516. response_msg.mutable_error_manager()->CopyFrom(t_error);
  517. response_msg.mutable_update_space_info()->CopyFrom(t_update_space);
  518. Communication_message response=Communication_message();
  519. response.reset(t_response_header, response_msg.SerializeAsString());
  520. Parkspace_allocation_communicator::get_instance_references().send_response(&response);
  521. }
  522. //确认分配车位线程函数
  523. void Parkspace_allocator::execute_for_confirm_alloc(message::Parkspace_info space_info, std::string command_key)
  524. {
  525. std::lock_guard<std::mutex> lck(m_mutex);
  526. LOG(INFO) << "确认分配";
  527. //根据车位信息定位待确认占用车位
  528. message::Parkspace_confirm_alloc_response_msg response_msg;
  529. message::Base_info t_response_header;
  530. t_response_header.set_msg_type(message::eParkspace_confirm_alloc_response_msg);
  531. t_response_header.set_sender(message::eParkspace);
  532. t_response_header.set_receiver(message::eMain);
  533. t_response_header.set_timeout_ms(1000);
  534. message::Error_manager t_error;
  535. message::Parkspace_info t_confirm_space;
  536. //获取当前所有车位状态,找到待释放的车位
  537. message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status();
  538. int index = -1;
  539. if(t_current_parkspace_status.parkspace_info_size()<=0)
  540. {
  541. t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY);
  542. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  543. LOG(ERROR) << "无车位";
  544. }
  545. else if (!space_info.has_car_info())
  546. {
  547. t_error.set_error_code(PARKSPACE_ALLOCATOR_PARAM_ERROR);
  548. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  549. LOG(WARNING) << "传入确认占用车位无车辆信息";
  550. }
  551. else
  552. {
  553. for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++)
  554. {
  555. // 找到相同车位,车辆信息匹配,且车位为锁定状态
  556. if (t_current_parkspace_status.parkspace_info(i).parkspace_id() == space_info.parkspace_id()
  557. && t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_locked
  558. && t_current_parkspace_status.parkspace_info(i).has_car_info()
  559. && t_current_parkspace_status.parkspace_info(i).car_info().license() == space_info.car_info().license())
  560. {
  561. index = i;
  562. break;
  563. }
  564. }
  565. if(index<0){
  566. t_error.set_error_code(PARKSPACE_ALLOCATOR_CONFIRM_ALLOC_ERROR);
  567. t_error.set_error_level(message::Error_level::MAJOR_ERROR);
  568. t_confirm_space.CopyFrom(space_info);
  569. LOG(WARNING) << "确认占用车位失败, " << t_confirm_space.DebugString()<<", self:"<<t_current_parkspace_status.parkspace_info(space_info.parkspace_id()-1).DebugString();
  570. }else{
  571. t_error.set_error_code(SUCCESS);
  572. t_error.set_error_level(message::Error_level::NORMAL);
  573. t_confirm_space.CopyFrom(space_info);
  574. t_confirm_space.set_parkspace_status(message::Parkspace_status::eParkspace_occupied);
  575. time_t tt = time(NULL);
  576. tm *t = localtime(&tt);
  577. char my_time_buf[255];
  578. memset(my_time_buf, 0, 255);
  579. sprintf(my_time_buf, "%d-%02d-%02d %02d:%02d:%02d",
  580. t->tm_year + 1900,
  581. t->tm_mon + 1,
  582. t->tm_mday,
  583. t->tm_hour,
  584. t->tm_min,
  585. t->tm_sec);
  586. t_confirm_space.set_entry_time(my_time_buf);
  587. // 分配车位后更新车位状态
  588. Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_confirm_space);
  589. LOG(INFO) << "第" << index << "号位已确认占用, id: " << t_confirm_space.parkspace_id();
  590. // 数据库操作,车位状态改为占用,插入停车记录,更新车辆状态为入库
  591. Error_manager ec = Parkspace_db_manager::get_instance_references().update_parkspace_status(t_confirm_space);
  592. if(ec != SUCCESS)
  593. {
  594. LOG(ERROR) << "更新db车位状态失败: "<< ec.to_string();
  595. }
  596. ec = Parkspace_db_manager::get_instance_references().insert_parking_record(t_confirm_space);
  597. if(ec != SUCCESS)
  598. {
  599. LOG(ERROR) << "插入db停车记录失败: "<< ec.to_string();
  600. }
  601. message::Vehicle_status t_vehicle_status = message::Vehicle_status::eVehicle_in_garage;
  602. ec = Parkspace_db_manager::get_instance_references().update_vehicle_status(t_confirm_space, t_vehicle_status);
  603. if(ec != SUCCESS)
  604. {
  605. LOG(ERROR) << "更新db车辆状态失败: "<< ec.to_string();
  606. }
  607. }
  608. }
  609. response_msg.mutable_base_info()->CopyFrom(t_response_header);
  610. response_msg.set_command_key(command_key);
  611. response_msg.mutable_error_manager()->CopyFrom(t_error);
  612. response_msg.mutable_confirm_alloc_space_info()->CopyFrom(t_confirm_space);
  613. Communication_message response=Communication_message();
  614. response.reset(t_response_header, response_msg.SerializeAsString());
  615. Parkspace_allocation_communicator::get_instance_references().send_response(&response);
  616. }