/* * @Description: 车位分配算法模块,使用单例模式,接收外部请求并通过调用通信块接口发送反馈 * @Author: yct * @Date: 2020-07-10 11:02:40 * @LastEditTime: 2020-07-22 19:21:03 * @LastEditors: yct */ #include "parkspace_allocator.h" #include "parkspace_allocation_communicator.h" Parkspace_allocator::Parkspace_allocator() { } Parkspace_allocator::~Parkspace_allocator() { parkspace_allocator_uninit(); } //初始化 Error_manager Parkspace_allocator::parkspace_allocator_init(int threads_size, parkspace_proto::database_config db_config) { // 初始化db连接 mp_db_manager = Parkspace_db_manager::get_instance_pointer(); if(mp_db_manager == nullptr) { return POINTER_IS_NULL; } Error_manager ec = mp_db_manager->Parkspace_db_manager_init(db_config); if(ec != SUCCESS) { return ec; } // 初始化任务处理线程池 m_thread_pool.thread_pool_init(threads_size); // 读数据库车位数据,初始化车位管理 message::Parkspace_allocation_status_msg all_parkspace_info; ec = mp_db_manager->get_all_parkspace_info(all_parkspace_info); if(ec != SUCCESS) { return ec; } Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(all_parkspace_info); m_current_status = eParkspace_allocator_normal; return Error_code::SUCCESS; } //反初始化 Error_manager Parkspace_allocator::parkspace_allocator_uninit() { m_thread_pool.thread_pool_uninit(); mp_db_manager->Parkspace_db_manager_uninit(); m_current_status = eParkspace_allocator_unknown; return Error_code::SUCCESS; } //检查执行者的状态, 判断能否处理这条消息, Error_manager Parkspace_allocator::check_executer(Communication_message* p_msg) { if ( p_msg == NULL ) { return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR, " POINTER IS NULL "); } Error_manager t_error = SUCCESS; return t_error; } //处理消息的执行函数 Error_manager Parkspace_allocator::execute_msg(Communication_message* p_msg) { if ( p_msg == nullptr ) { return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR, " POINTER IS NULL "); } switch ( p_msg->get_message_type() ) { ///车位分配请求消息 case Communication_message::eParkspace_allocation_request_msg: { message::Parkspace_allocation_request_msg request; bool result = request.ParseFromString(p_msg->get_message_buf()); LOG(INFO)<<"allocation request, car license: "<get_message_buf()); LOG(INFO)<<"search request, car license: "<get_message_buf()); LOG(INFO)<<"release request, parkspace id: "<get_message_buf()); LOG(INFO)<<"force update request, parkspace id: "<get_message_buf()); LOG(INFO)<<"confirm alloc request, parkspace id: "< lck(m_mutex); LOG(INFO) << "分配"; //根据请求的信息反馈分配的车位,并封装发送 message::Parkspace_allocation_response_msg response_msg; message::Base_info t_response_header; t_response_header.set_msg_type(message::Message_type::eParkspace_allocation_response_msg); t_response_header.set_timeout_ms(1000); t_response_header.set_sender(message::Communicator::eParkspace); t_response_header.set_receiver(message::Communicator::eMain); message::Error_manager t_error; message::Parkspace_info t_allocated_space; //获取当前所有车位状态,分配车位 message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status(); int index = -1; if(t_current_parkspace_status.parkspace_info_size()<=0) { t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY); t_error.set_error_level(message::Error_level::MAJOR_ERROR); LOG(ERROR) << "无车位"; } else { for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++) { // 找到高于车高且空闲车位,则分配 if (t_current_parkspace_status.parkspace_info(i).has_car_info() /* && t_current_parkspace_status.parkspace_info(i).height() > car_info.car_height() && t_current_parkspace_status.parkspace_info(i).width() > car_info.car_width() */ && t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_empty) { index = i; break; } } if(index<0){ t_error.set_error_code(PARKSPACE_ALLOCATOR_ALLOCATE_FAILED); t_error.set_error_level(message::Error_level::MAJOR_ERROR); t_allocated_space.CopyFrom(t_current_parkspace_status.parkspace_info(0)); t_allocated_space.mutable_car_info()->CopyFrom(car_info); LOG(WARNING) << "分配车位失败"; }else{ t_error.set_error_code(SUCCESS); t_error.set_error_level(message::Error_level::NORMAL); message::Parkspace_info t_space_to_lock = t_current_parkspace_status.parkspace_info(index); t_space_to_lock.set_parkspace_status(message::Parkspace_status::eParkspace_locked); t_space_to_lock.mutable_car_info()->CopyFrom(car_info); t_allocated_space.CopyFrom(t_space_to_lock); // 分配车位后更新车位状态 Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_space_to_lock); LOG(INFO) << "第"<CopyFrom(t_response_header); response_msg.set_command_id(command_id); response_msg.mutable_error_manager()->CopyFrom(t_error); response_msg.mutable_allocated_space_info()->CopyFrom(t_allocated_space); Communication_message response=Communication_message(); response.reset(t_response_header, response_msg.SerializeAsString()); Parkspace_allocation_communicator::get_instance_references().send_response(&response); } //查询车位线程函数 void Parkspace_allocator::execute_for_search(message::Car_info car_info, int command_id) { std::lock_guard lck(m_mutex); LOG(INFO) << "查询"; //根据车辆凭证信息查询车辆位置 message::Parkspace_search_response_msg response_msg; message::Base_info t_response_header; message::Error_manager t_error; message::Parkspace_info t_car_position; t_response_header.set_msg_type(message::Message_type::eParkspace_search_response_msg); t_response_header.set_timeout_ms(1000); t_response_header.set_sender(message::Communicator::eParkspace); t_response_header.set_receiver(message::Communicator::eMain); //获取当前所有车位状态,查询车辆位置 message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status(); int index = -1; if(t_current_parkspace_status.parkspace_info_size()<=0) { t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY); t_error.set_error_level(message::Error_level::MAJOR_ERROR); LOG(ERROR) << "无车位"; } else { for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++) { // 找到凭证号/号牌对应车位,记录 if (t_current_parkspace_status.parkspace_info(i).has_car_info() && t_current_parkspace_status.parkspace_info(i).car_info().license() == car_info.license() && t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_occupied) { index = i; break; } } if(index<0){ t_error.set_error_code(PARKSPACE_ALLOCATOR_SEARCH_FAILED); t_error.set_error_level(message::Error_level::MAJOR_ERROR); // 默认第一个车位 t_car_position.CopyFrom(t_current_parkspace_status.parkspace_info(0)); LOG(INFO) << "查询车位失败"; }else{ t_error.set_error_code(SUCCESS); t_error.set_error_level(message::Error_level::NORMAL); message::Parkspace_info t_space_searching = t_current_parkspace_status.parkspace_info(index); t_car_position.CopyFrom(t_space_searching); LOG(INFO) << "车辆"<CopyFrom(t_response_header); response_msg.set_command_id(command_id); response_msg.mutable_error_manager()->CopyFrom(t_error); response_msg.mutable_car_position()->CopyFrom(t_car_position); Communication_message response=Communication_message(); response.reset(t_response_header, response_msg.SerializeAsString()); Parkspace_allocation_communicator::get_instance_references().send_response(&response); } //释放车位线程函数 void Parkspace_allocator::execute_for_release(message::Parkspace_info space_info, int command_id) { std::lock_guard lck(m_mutex); LOG(INFO) << "释放"; //根据车位信息定位待释放车位位置,车辆凭证号用于校验 message::Parkspace_release_response_msg response_msg; message::Base_info t_response_header; t_response_header.set_msg_type(message::eParkspace_release_response_msg); t_response_header.set_sender(message::eParkspace); t_response_header.set_receiver(message::eMain); t_response_header.set_timeout_ms(1000); message::Error_manager t_error; message::Parkspace_info t_release_space; //获取当前所有车位状态,找到待释放的车位 message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status(); int index = -1; if(t_current_parkspace_status.parkspace_info_size()<=0) { t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY); t_error.set_error_level(message::Error_level::MAJOR_ERROR); LOG(ERROR) << "无车位"; } else if (!space_info.has_car_info()) { t_error.set_error_code(PARKSPACE_ALLOCATOR_RELEASE_FAILED); t_error.set_error_level(message::Error_level::MAJOR_ERROR); LOG(WARNING) << "传入待释放车位无车辆信息"; } else { for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++) { // 找到占用或锁定的车位,且车辆信息匹配 if (t_current_parkspace_status.parkspace_info(i).parkspace_id() == space_info.parkspace_id() && (t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_occupied ||t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_locked) && t_current_parkspace_status.parkspace_info(i).has_car_info() && t_current_parkspace_status.parkspace_info(i).car_info().license() == space_info.car_info().license()) { index = i; break; } } if(index<0){ t_error.set_error_code(PARKSPACE_ALLOCATOR_RELEASE_FAILED); t_error.set_error_level(message::Error_level::MAJOR_ERROR); // 传入默认车位信息 t_release_space.CopyFrom(space_info); LOG(WARNING) << "释放车位失败"; }else{ t_error.set_error_code(SUCCESS); t_error.set_error_level(message::Error_level::NORMAL); message::Parkspace_info t_space_to_release = t_current_parkspace_status.parkspace_info(index); t_space_to_release.set_parkspace_status(message::Parkspace_status::eParkspace_empty); t_release_space.CopyFrom(t_space_to_release); // 分配车位后更新车位状态 Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_space_to_release); LOG(INFO) << "第"<tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); t_space_to_release.set_leave_time(my_time_buf); ec = Parkspace_db_manager::get_instance_references().update_parking_record(t_space_to_release, t_park_record_id); if(ec != SUCCESS) { LOG(ERROR) << "更新db停车记录失败: "<< ec.to_string(); } } } } response_msg.mutable_base_info()->CopyFrom(t_response_header); response_msg.set_command_id(command_id); response_msg.mutable_error_manager()->CopyFrom(t_error); response_msg.mutable_release_space_info()->CopyFrom(t_release_space); Communication_message response=Communication_message(); response.reset(t_response_header, response_msg.SerializeAsString()); Parkspace_allocation_communicator::get_instance_references().send_response(&response); } //强制更新车位信息线程函数 void Parkspace_allocator::execute_for_force_update(message::Parkspace_info space_info, int command_id) { std::lock_guard lck(m_mutex); LOG(INFO) << "手动"; //根据车位信息定位待释放车位位置,车辆凭证号用于校验 //!!!!!此处跳过外部处理与调用的过程,直接在内部调用,发送分配结果用于测试,目前一直发布第一个车位 message::Parkspace_force_update_response_msg response_msg; message::Base_info t_response_header; t_response_header.set_msg_type(message::eParkspace_force_update_response_msg); t_response_header.set_sender(message::eParkspace); t_response_header.set_receiver(message::eMain); t_response_header.set_timeout_ms(1000); message::Error_manager t_error; message::Parkspace_info t_update_space; //获取当前所有车位状态,找到待释放的车位 message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status(); int index = -1; if(t_current_parkspace_status.parkspace_info_size()<=0) { t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY); t_error.set_error_level(message::Error_level::MAJOR_ERROR); LOG(ERROR) << "无车位"; } else { for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++) { // 找到高于车高且空闲车位,则分配 if (t_current_parkspace_status.parkspace_info(i).parkspace_id() == space_info.parkspace_id()) { index = i; break; } } if(index<0){ t_error.set_error_code(PARKSPACE_ALLOCATOR_FORCE_UPDATE_FAILED); t_error.set_error_level(message::Error_level::MAJOR_ERROR); t_update_space.CopyFrom(space_info); LOG(WARNING) << "手动更新车位失败"; }else{ t_error.set_error_code(SUCCESS); t_error.set_error_level(message::Error_level::NORMAL); t_update_space.CopyFrom(space_info); // 分配车位后更新车位状态 Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_update_space); LOG(INFO) << "第"<CopyFrom(t_response_header); response_msg.set_command_id(command_id); response_msg.mutable_error_manager()->CopyFrom(t_error); response_msg.mutable_update_space_info()->CopyFrom(t_update_space); Communication_message response=Communication_message(); response.reset(t_response_header, response_msg.SerializeAsString()); Parkspace_allocation_communicator::get_instance_references().send_response(&response); } //确认分配车位线程函数 void Parkspace_allocator::execute_for_confirm_alloc(message::Parkspace_info space_info, int command_id) { std::lock_guard lck(m_mutex); LOG(INFO) << "确认分配"; //根据车位信息定位待确认占用车位 message::Parkspace_confirm_alloc_response_msg response_msg; message::Base_info t_response_header; t_response_header.set_msg_type(message::eParkspace_confirm_alloc_response_msg); t_response_header.set_sender(message::eParkspace); t_response_header.set_receiver(message::eMain); t_response_header.set_timeout_ms(1000); message::Error_manager t_error; message::Parkspace_info t_confirm_space; //获取当前所有车位状态,找到待释放的车位 message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status(); int index = -1; if(t_current_parkspace_status.parkspace_info_size()<=0) { t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY); t_error.set_error_level(message::Error_level::MAJOR_ERROR); LOG(ERROR) << "无车位"; } else if (!space_info.has_car_info()) { t_error.set_error_code(PARKSPACE_ALLOCATOR_PARAM_ERROR); t_error.set_error_level(message::Error_level::MAJOR_ERROR); LOG(WARNING) << "传入确认占用车位无车辆信息"; } else { for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++) { // 找到相同车位,车辆信息匹配,且车位为锁定状态 if (t_current_parkspace_status.parkspace_info(i).parkspace_id() == space_info.parkspace_id() && t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_locked && t_current_parkspace_status.parkspace_info(i).has_car_info() && t_current_parkspace_status.parkspace_info(i).car_info().license() == space_info.car_info().license()) { index = i; break; } } if(index<0){ t_error.set_error_code(PARKSPACE_ALLOCATOR_CONFIRM_ALLOC_ERROR); t_error.set_error_level(message::Error_level::MAJOR_ERROR); t_confirm_space.CopyFrom(space_info); LOG(WARNING) << "确认占用车位失败"; }else{ t_error.set_error_code(SUCCESS); t_error.set_error_level(message::Error_level::NORMAL); t_confirm_space.CopyFrom(space_info); t_confirm_space.set_parkspace_status(message::Parkspace_status::eParkspace_occupied); time_t tt = time(NULL); tm *t = localtime(&tt); char my_time_buf[255]; memset(my_time_buf, 0, 255); sprintf(my_time_buf, "%d-%02d-%02d %02d:%02d:%02d", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); t_confirm_space.set_entry_time(my_time_buf); // 分配车位后更新车位状态 Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_confirm_space); LOG(INFO) << "第" << index << "号位已确认占用, id: " << t_confirm_space.parkspace_id(); // 数据库操作,车位状态改为占用,插入停车记录,更新车辆状态为入库 Error_manager ec = Parkspace_db_manager::get_instance_references().update_parkspace_status(t_confirm_space); if(ec != SUCCESS) { LOG(ERROR) << "更新db车位状态失败: "<< ec.to_string(); } ec = Parkspace_db_manager::get_instance_references().insert_parking_record(t_confirm_space); if(ec != SUCCESS) { LOG(ERROR) << "插入db停车记录失败: "<< ec.to_string(); } message::Vehicle_status t_vehicle_status = message::Vehicle_status::eVehicle_in_garage; ec = Parkspace_db_manager::get_instance_references().update_vehicle_status(t_confirm_space, t_vehicle_status); if(ec != SUCCESS) { LOG(ERROR) << "更新db车辆状态失败: "<< ec.to_string(); } } } response_msg.mutable_base_info()->CopyFrom(t_response_header); response_msg.set_command_id(command_id); response_msg.mutable_error_manager()->CopyFrom(t_error); response_msg.mutable_confirm_alloc_space_info()->CopyFrom(t_confirm_space); Communication_message response=Communication_message(); response.reset(t_response_header, response_msg.SerializeAsString()); Parkspace_allocation_communicator::get_instance_references().send_response(&response); }