#ifndef MODULE_CONST_H #define MODULE_CONST_H /** * @brief 包含常用的常量,接口基类,工具类 * @author 戴月腾 * @date 2018-08-24 */ #include #include #include #include #include"db_api/CDBConnPool.h" #include"log.h" #include #include #include #include #include #include"card.h" #include"area.h" #include"constdef.h" #define LENGTH_SQL 2000 ///全局常量 class global_constant { public: // ///区域超速最小次数门限 // static int AREA_SPEED_COUNT_MIN; ///区域超速最大次数门限 static int AREA_SPEED_COUNT_LIMIT; // ///区域超速最小时间门限 // static int AREA_SPEED_TIME_MIN; // ///区域超速最大时间门限 // static int AREA_SPEED_TIME_MAX; // ///车辆考勤最小次数门限 // static int ATTENDANCE_VEHICLE_COUNT_MIN; ///车辆考勤最大次数门限 static int ATTENDANCE_VEHICLE_COUNT_LIMIT; // ///车辆考勤最小时间门限 // static int ATTENDANCE_VEHICLE_TIME_MIN; // ///车辆考勤最大时间门限 // static int ATTENDANCE_VEHICLE_TIME_MAX; }; /** * @brief 事件状态 */ enum EVENT_STATUS { ///事件开始 ES_START = 0, ///呼救已处理状态 ES_DEAL_HELP = 1, ///事件结束 ES_END = 100 }; //enum STATUS_CARD //{ // STATUS_NORMAL = 0, //正常 // STATUS_ERROR = 1, // STATUS_ERROR_SERIOUS = 2, // STATUS_POWER_LOWER = 1, //电量低 // STATUS_POWER_LOWER_SERIOUS = 2, //电量极低 // STATUS_OVER_TIME = 4, //超时 // //STATUS_OVER_COUNT = 1, // STATUS_OVER_SPEED = 8, //超速 // STATUS_AREA_OVER_TIME = 16, //区域超时 // //STATUS_AREA_OVER_COUNT = 1, // STATUS_AREA_OVER_SPEED = 32, //区域超速 // STATUS_AREA_FORBIDDEN = 64, //进入限制区域 // ////STATUS_HELP = 128, //呼救 // STATUS_HELP_DEALED = 256, //呼救已处理 // STATUS_CALL = 512, //呼叫 // STATUS_LOST = 1024 //进入盲区 // //STATUS_ERROR_DEALED, //}; enum EVENT_TYPE{ // 事件类型 ET_UNKNOWN = 0, ET_OVER_COUNT_PERSON = 1, // 井下人员超员mp_card_list_over_count_person ET_OVER_COUNT_VEHICLE = 2, // 井下车辆超员mp_card_list_over_count_person ET_AREA_OVER_COUNT_PERSON = 3, // 区域人员超员 ET_AREA_OVER_COUNT_VEHICLE = 4, // 区域车辆超员 ET_SECTION_OVER_COUNT = 5, // 路段拥堵 ET_READER_ERROR = 6, // 分站通信异常 ET_ctrl_reader_ERROR = 7, // 控制分站异常 ET_LIGHT_ERROR = 8, // 交通灯异常 ET_READER_CALL = 9, // 分站呼叫标识卡 ET_READER_CALL_CANCEL = 10, // 取消呼叫分站 ET_CARD_LOW_POWER = 11, // 电量低 ET_CARD_LOW_POWER_SERIOUS = 12, // 电量极低 ET_CARD_OVER_TIME_PERSON = 13, // 人员井下超时mp_card_list_over_time_person ET_CARD_OVER_TIME_VEHICLE = 14, // 车辆井下超时mp_card_list_over_time_vehicle ET_CARD_AREA_OVER_TIME_PERSON = 15, // 人员区域超时 ET_CARD_AREA_OVER_TIME_VEHICLE = 16, // 车辆区域超时 ET_CARD_AREA_LIMIT_PERSON = 17, // 人员进入限制区域 ET_CARD_AREA_LIMIT_VEHICLE = 18, // 车辆进入限制区域 ET_CARD_AREA_FORBIDDEN_PERSON = 19, // 人员进入禁止区域 ET_CARD_AREA_FORBIDDEN_VEHICLE = 20, // 车辆进入禁止区域 ET_CARD_OVER_SPEED = 21, // 车辆超速 ET_CARD_AREA_OVER_SPEED = 22, // 车辆区域超速 ET_CARD_RUN_THE_RED_LIGHT = 23, // 车辆闯红灯 ET_CARD_HELP = 24, // 人员呼救 ET_CARD_CALLED = 25, // 人员已被呼叫 ET_CARD_PATROL_ERROR = 26, // 人员巡检异常 ET_CARD_LOST = 27, // 标识卡信号丢失 ET_CARD_DRIVINGFACE_WARNING_AREA = 28, // 掘进面靠近预警区域告警 ET_CARD_NEAR_DRIVINGFACE_VEHICLE=29,// 人员靠近掘进机告警 ET_CARD_NEAR_DRIVINGFACE_OVERCOUNT=30,//掘进机附近人员超员 ET_UWB_MORE_CARD = 31, ET_CARD_MOTIONLESS=32, CARD_EVENT_COUNT_MAX, }; /** * @brief 对象类型 */ enum OBJECT_TYPE { ///矿井 OT_MINE = 1, ///区域 OT_AREA = 2, ///路段 OT_SECTION = 3, ///分站 OT_DEVICE_READER = 4, ///交通灯 OT_DEVICE_LIGHT = 5, ///控制分站 OT_DEVICE_ctrl_reader = 6, ///led屏 OT_DEVICE_LED = 7, ///防爆音箱 OT_DEVICE_SPEAKER = 8, ///标识卡,包括人员、车辆、自组网等 OT_CARD = 9, /// OT_DRIVINGFACE_AREA=10, /// OT_UWB_MORE_CARD=11, }; /** * @brief 告警事件 */ class ya_event { private: uint64_t m_ev_id; public: ya_event(uint64_t e_id):m_cur_time(std::chrono::system_clock::now()) { m_ev_id = e_id; m_obj_id = 0; m_map_id = 0; m_area_id = 0; x = 0; y = 0; m_limit_value = 0; m_cur_value = 0; m_desc = ""; m_landmarkid = 0; m_landmarkdirect = 0; m_landmarkdist = 0; m_status=ES_START; } ~ya_event(){} public: ///告警状态,开始、结束 EVENT_STATUS m_status; ///告警类型 EVENT_TYPE m_ev_type; ///告警对象类型 OBJECT_TYPE m_obj_type; /// 告警对象编号,与告警对象类型对应,如告警对象类型为分站,此字段为分站编号 uint64_t m_obj_id; ///当前时间,为告警事件的触发时间,如果状态为开始,则表示开始时间,否则为结束时间 std::chrono::system_clock::time_point m_cur_time; ///告警所在地图 int m_map_id; ///告警所在区域 int m_area_id; ///位置 double x; ///位置 double y; ///告警阈值 double m_limit_value; ///当前值 double m_cur_value; ///描述 std::string m_desc; /// 地标信息 int m_landmarkid; /// 与地标的距离 double m_landmarkdist; /// 所处地标的方向 int m_landmarkdirect; ///作为事件map列表的id,方便查找;(obj_type<<32| obj_id) uint64_t m_list_id; uint64_t get_id(){return m_ev_id;} }; typedef std::shared_ptr event_ptr; typedef std::map> event_map; typedef std::shared_ptr event_map_ptr; class tool_time { public: static uint32_t elapse_seconds(std::chrono::system_clock::time_point &start) { return std::chrono::duration_cast (std::chrono::system_clock::now() - start).count(); } static uint64_t elapse_ms(std::chrono::system_clock::time_point &start) { return std::chrono::duration_cast (std::chrono::system_clock::now() - start).count(); } static uint32_t now_to_seconds() { return std::chrono::duration_cast (std::chrono::system_clock::now().time_since_epoch()).count(); } static uint64_t now_to_ms() { return std::chrono::duration_cast (std::chrono::system_clock::now().time_since_epoch()).count(); } static uint64_t to_ms(const std::chrono::system_clock::time_point &time) { return std::chrono::duration_cast (time.time_since_epoch()).count(); } static std::string to_str(const std::chrono::system_clock::time_point &time) { char _time[25] = {0}; time_t tt = std::chrono::system_clock::to_time_t(time); struct tm *local_time=localtime(&tt); strftime(_time, 22, "%Y-%m-%d %H:%M:%S", local_time); return std::string(_time); } ///"%u-%u-%u %u:%u:%u.%u" static std::string to_str_ex(const std::chrono::system_clock::time_point &time) { uint64_t mill = std::chrono::duration_cast(time.time_since_epoch()).count() -std::chrono::duration_cast(time.time_since_epoch()).count()*1000; char _time[25] = {0}; time_t tt = std::chrono::system_clock::to_time_t(time); struct tm *local_time=localtime(&tt); //strftime(_time, 22, "%Y-%m-%d %H:%M:%S", local_time); sprintf(_time, "%d-%02d-%02d %02d:%02d:%02d.%d", local_time->tm_year+1900, local_time->tm_mon+1, local_time->tm_mday, local_time->tm_hour, local_time->tm_min, local_time->tm_sec, mill); return std::string(_time); } }; class tool_other { public: static uint64_t to_uint64_cardid(uint32_t type, uint32_t id) { return (static_cast(type)<<32)|id; ////// (类型<<32)|卡号 } static uint64_t to_event_list_id(int obj_id, EVENT_TYPE ev_type) { return (static_cast(ev_type)<<32)|static_cast(obj_id); } static event_ptr create_event(OBJECT_TYPE obj_type, int obj_id, EVENT_TYPE ev_type) { auto ev_ptr = std::make_shared(tool_time::now_to_ms()); ev_ptr->m_ev_type = ev_type; ev_ptr->m_obj_type = obj_type; ev_ptr->m_obj_id = static_cast(obj_id); ev_ptr->m_list_id = to_event_list_id(obj_id, ev_type); return ev_ptr; } static void insert_event(const event_ptr ev_ptr, event_map& out_ev_map) { out_ev_map.insert(std::make_pair(ev_ptr->m_list_id, ev_ptr)); } static void copy_event(const std::shared_ptr card_ptr, event_ptr ev_ptr) { ev_ptr->x = card_ptr->x; ev_ptr->y = card_ptr->y; if(nullptr!=card_ptr->m_area_hover) { ev_ptr->m_area_id = card_ptr->m_area_hover->m_area->id(); } ev_ptr->m_landmarkid = card_ptr->m_landmarkid; ev_ptr->m_landmarkdist = card_ptr->m_landmarkdist; ev_ptr->m_landmarkdirect = card_ptr->m_landmarkdirect; } static event_ptr find_event(int obj_id, EVENT_TYPE ev_type, const event_map& ev_map) { auto it = ev_map.find(to_event_list_id(obj_id, ev_type)); if(ev_map.end() == it) { return nullptr; } return it->second; } }; class tool_db { private: //void CYAServerDlg::load_his_event_data() //load_alarm_reader() static void PushAsync(char* sql) { log_debug("PushAsync记录到队列中:%s\n", sql); if(!sDBConnPool.PushAsync(sql)) { log_error( "PushAsync记录到队列中失败\n"); } } public: static void save_event(const event_ptr ev_ptr) { char sql[LENGTH_SQL] = {'\0'}; std::string _time = tool_time::to_str(ev_ptr->m_cur_time); sprintf(sql, "INSERT IGNORE INTO his_event_data(event_id, stat, event_type_id, obj_type_id, obj_id, \ map_id, area_id, limit_value, cur_value, x, y, cur_time, description, \ landmark_id, landmark_dist,direction_mapper_id )\ VALUES(%ld, %d, %d, %d, %ld, %d, %d, %.2f, %.2f, %f, %f, '%s', '%s', %d, %d, %10.3f);", ev_ptr->get_id(), ev_ptr->m_status, ev_ptr->m_ev_type, ev_ptr->m_obj_type, ev_ptr->m_obj_id, ev_ptr->m_map_id, ev_ptr->m_area_id, ev_ptr->m_limit_value, ev_ptr->m_cur_value, ev_ptr->x, ev_ptr->y, _time.c_str(), ev_ptr->m_desc.c_str(), ev_ptr->m_landmarkid, ev_ptr->m_landmarkdirect, ev_ptr->m_landmarkdist); PushAsync(sql); } static void save_attendance(const std::shared_ptr card_ptr) { char sql[LENGTH_SQL] = {0}; std::string call("add_att_staff"); if(CT_VEHICLE==card_ptr->m_type)//车卡 { call="add_att_vehicle"; } auto tt = card_ptr->m_attendance_start_time; if(AS_ATTENDANCE != card_ptr->m_stat_attendance)//考勤结束时间 { tt = std::chrono::system_clock::now(); } std::string _time = tool_time::to_str(tt); sprintf(sql, "CALL %s(%ld, %d, '%s', '%s', %d, %d, %.3f);", call.c_str(), card_ptr->m_id, card_ptr->m_type, _time.c_str(), _time.c_str(), card_ptr->m_landmarkid, card_ptr->m_landmarkdirect, card_ptr->m_landmarkdist); PushAsync(sql); } static void save_his_raw_data(const std::shared_ptr card_ptr) { char sql[LENGTH_SQL] = {0}; std::string _time = tool_time::to_str(card_ptr->m_deal_time); sprintf(sql, "INSERT IGNORE INTO his_raw_data(card_id, reader_id, antenna_id, reader_stamp, card_stamp, \ fly_time, distance, ranging_type, power_state, accelerate, his_time, rec_time ) \ VALUES(%d, %d, %d, %d, %d, %ld, %4.f, %d, %d, %d, '%s', '%s');", card_ptr->m_id, card_ptr->m_site_id, card_ptr->m_antenna_id, card_ptr->m_reader_tickcount, card_ptr->m_time_stamp, card_ptr->m_flying_time, card_ptr->m_distance, card_ptr->m_ranging_type, card_ptr->m_power_state, card_ptr->m_accelerate_state, card_ptr->m_str_his_time.c_str(), card_ptr->m_str_rec_time.c_str()); } static void save_his_location(const std::shared_ptr card_ptr) { // sprintf_s(_time, // STR_LEN_TIME, // "%u-%u-%u %u:%u:%u.%u", // card->deal_time.wYear,card->deal_time.wMonth,card->deal_time.wDay, // card->deal_time.wHour,card->deal_time.wMinute,card->deal_time.wSecond,card->deal_time.wMilliseconds); // if(card->map_id != 0 && card->area_id != 0){ // b_exec = true; // switch (card->card_type) // { // case CT_PERSON: // sprintf_s(sql, LENGTH_SQL, // "INSERT IGNORE INTO his_location_staff(card_id, staff_id, cur_time, x, y, z, map_id, area_id, state,speed,mileage, landmark_id, direction_mapper_id, landmark_dist) VALUES(%s, %d, '%s', %.3f, %.3f, %.3f, %d, %d, %d,%.3f,%.4f, %d, %d, %.4f);", // card->card_id.c_str(), card->id, _time, card->x_offset_after(), card->y_offset_after(), card->z_offset_after(), card->map_id, card->area_id, card->state,card->get_speed(),card->mileage, card->landmark_id, card->landmark_direction, card->landmark_dis); // break; // case CT_VEHICLE: // sprintf_s(sql, LENGTH_SQL, // "INSERT IGNORE INTO his_location_vehicle(card_id, vehicle_id, cur_time, x, y, z, map_id, area_id, state,speed,mileage, landmark_id, direction_mapper_id, landmark_dist) VALUES(%s, %d, '%s', %.3f, %.3f, %.3f, %d, %d, %d,%.3f,%.4f, %d, %d, %.4f);", // card->card_id.c_str(), card->id, _time, card->x_offset_after(), card->y_offset_after(), card->z_offset_after(), card->map_id, card->area_id, card->state,card->get_speed(),card->mileage, card->landmark_id, card->landmark_direction, card->landmark_dis); // break; // } // } } static void save_his_area_location_enter(const std::shared_ptr card_ptr) { // sprintf_s(_time, // STR_LEN_TIME, // "%u-%u-%u %u:%u:%u.%u", // card->deal_time.wYear,card->deal_time.wMonth,card->deal_time.wDay, // card->deal_time.wHour,card->deal_time.wMinute,card->deal_time.wSecond,card->deal_time.wMilliseconds); // if(card->map_id != 0 && card->area_id != 0){ // b_exec = true; // switch (card->card_type) // { // case CT_PERSON: // sprintf_s(sql, LENGTH_SQL, // "call add_area_staff(%s, %d, %d, %d, '%s','%s');", // card->card_id.c_str(), card->id, card->area_id, card->map_id, _time, _time); // break; // case CT_VEHICLE: // sprintf_s(sql, LENGTH_SQL, // "call add_area_vehicle(%s, %d, %d, %d, '%s','%s');", // card->card_id.c_str(), card->id, card->area_id, card->map_id, _time, _time); // break; // } // } } static void save_his_area_location_leave(const std::shared_ptr card_ptr) { // sprintf_s(_time, // STR_LEN_TIME, // "%u-%u-%u %u:%u:%u.%u", // card->deal_time.wYear,card->deal_time.wMonth,card->deal_time.wDay, // card->deal_time.wHour,card->deal_time.wMinute,card->deal_time.wSecond,card->deal_time.wMilliseconds); // if(card->map_id != 0 && card->area_id != 0){ // b_exec = true; // sprintf_s(_time_ex, // STR_LEN_TIME, // "%u-%u-%u %u:%u:%u.%u", // card->enter_area_time.wYear,card->enter_area_time.wMonth,card->enter_area_time.wDay, // card->enter_area_time.wHour,card->enter_area_time.wMinute,card->enter_area_time.wSecond,card->enter_area_time.wMilliseconds); // switch (card->card_type) // { // case CT_PERSON: // sprintf_s(sql, LENGTH_SQL, // "call add_area_staff(%s, %d, %d, %d, '%s','%s');", // card->card_id.c_str(), card->id, card->area_id, card->map_id, _time_ex, _time); // break; // case CT_VEHICLE: // sprintf_s(sql, LENGTH_SQL, // "call add_area_vehicle(%s, %d, %d, %d, '%s','%s');", // card->card_id.c_str(), card->id, card->area_id, card->map_id, _time_ex, _time); // break; // } // } } }; /** * @brief 线程接口类,重写run函数,改变睡眠时间 sleep_ms */ class i_thread { public: i_thread() { sleep_ms=10*1000; } virtual ~i_thread(){} /** * @brief 启动线程 */ void start() { _thread_flag=true; _thread_handler=std::thread(&i_thread::thread_proc, this); } /** * @brief 终止线程 */ void stop() { _thread_flag=false; _thread_handler.join(); } ///线程睡眠时间 毫秒 std::atomic sleep_ms; protected: /// 互斥量 std::mutex _mutex; /** * @brief 线程函数 */ virtual void run(){} private: /// 线程句柄 std::thread _thread_handler; /// 线程标志 std::atomic _thread_flag; void thread_proc() { while(_thread_flag) { run(); std::this_thread::sleep_for(std::chrono::milliseconds(sleep_ms)); } } }; template class singleton_base { public: static T *instance() { if(nullptr != _instance) { return _instance; } std::lock_guard ll(_mutex_singleton_base); if(nullptr == _instance) { _instance = new(std::nothrow) T(); } return _instance; } protected: //使继承者无法public构造函数和析构函数 singleton_base(){} virtual ~singleton_base(){} private: //禁止拷贝构造和赋值运算符 singleton_base(const singleton_base& src){} singleton_base &operator=(const singleton_base& src){} //它的唯一工作就是在析构函数中析构Singleton的实例,所以private class Garbo { public: ~Garbo() { if (singleton_base::_instance) { delete singleton_base::_instance; singleton_base::_instance = nullptr; } } }; //定义一个静态成员变量,程序结束时,系统会自动调用它的析构函数,我们不需要访问这个变量,所以不需要初始化 static Garbo garbo; static T *_instance; static std::mutex _mutex_singleton_base; }; template T *singleton_base::_instance = nullptr; template std::mutex singleton_base::_mutex_singleton_base; #endif // MODULE_CONST_H