8 Commit-ok a5eb60e5c5 ... 6ef76b2259

Szerző SHA1 Üzenet Dátum
  zhuyf 6ef76b2259 fix merge and add over speed 2 éve
  zhuyf 0051c3d4a0 fix alarm 2 éve
  zhuyf 368ab13f13 Merge branch 'xcjk' of http://121.42.8.157:13000/software-l/server into xcjk 2 éve
  zhuyf c541072a7a Merge branch 'xcjk' of http://121.42.8.157:13000/software-l/server into xcjk 2 éve
  zhuyf 7ecb4bbc87 Merge branch 'xcjk' of http://121.42.8.157:13000/software-l/server into xcjk 2 éve
  zhuyf cd00f9c61d turn off site time check 2 éve
  zhuyf 927e7e2e76 Merge branch 'xcjk' of http://121.42.8.157:13000/software-l/server into xcjk 2 éve
  zhuyf fa7431341e fix load data from database 2 éve
12 módosított fájl, 518 hozzáadás és 34 törlés
  1. 15 0
      ant.cpp
  2. 1 1
      card_base.cpp
  3. 75 0
      card_car.cpp
  4. 5 2
      card_car.h
  5. 1 1
      common.h
  6. 116 1
      db/db_card.cpp
  7. 165 20
      event.cpp
  8. 4 0
      event.h
  9. 18 0
      module_service/module_call.cpp
  10. 110 6
      module_service/module_traffic_light_manager.cpp
  11. 6 1
      module_service/module_web.cpp
  12. 2 2
      net-service.cpp

+ 15 - 0
ant.cpp

@@ -245,6 +245,21 @@ std::vector<point> ant::getsol(const double &dist) const
 	return std::move(v);
 }
 
+/*	@brief
+ *		基站失联告警,超时阈值为30秒
+ *		采集在30秒内未收到基站(含通信基站和定位基站)数据,产生基站失联告警
+ *		采集收到了基站心跳数据,结束基站失联告警;
+ *		就在本方法内实现上述逻辑
+ *		逻辑和红绿灯失联告警一样
+ *	@param
+ *		std::shared_ptr<site> s		基站对象
+ *	@return
+ *		执行成功返回true
+ *	@note
+ *	@warning
+ *	@bug
+ *
+ * */
 bool visit_site_status::visit(std::shared_ptr<site> s)
 {
 	time_t now = time(0);

+ 1 - 1
card_base.cpp

@@ -223,7 +223,7 @@ void card_location_base::on_location(const std::vector<point>&vp, const std::vec
 
 		// 姿态判断
 		if (is_vehicle())
-		{
+		{	
 			if (m_stat_last == ENUM_STATUS_BACK)
 			{
 				m_stat = ENUM_STATUS_BACK;

+ 75 - 0
card_car.cpp

@@ -23,6 +23,7 @@ car::car(const std::string&type,uint32_t cardid,uint16_t needdisplay,int16_t t,i
 	 ,m_vehicle_type_id(type_id)
 {
 	m_message_handle.reset(new card_message_handle(this));
+	m_speeds.set_capacity(30);
 	//m_his_location_card.reset(new location_vehicle(m_id,m_type,cid));
 }
 
@@ -50,6 +51,60 @@ void car::do_business(const std::shared_ptr<site>&site,const point &pt,double ac
     }
 	uint64_t id=tool_other::type_id_to_u64(m_type,m_id);
 	mine_business::inst()->make_arg(id,pt,m_time);
+
+	//超速告警业务
+	handle_over_speed();
+}
+
+/*
+ *	@brief
+ *		超速告警,频率为1hz,定位一秒一次;
+ *		开始:连续30个定位点超过35km认为开始超速告警
+ *		结束:连续10个定位点小于35km认为结束超速告警
+ *	@param
+ *		无
+ *	@return
+ *	@note
+ *	@warning
+ *	@bug
+ * */
+void car::handle_over_speed()
+{
+	// 超速告警,频率为1hz,定位一秒一次;
+	// 开始:连续30个定位点超过35km认为开始超速告警
+	// 结束:连续10个定位点小于35km认为结束超速告警			
+	m_speeds.push_back(m_speed);
+
+	bool status = true;
+	if(m_speed.size() < 30){
+		status = false;
+	}else{
+		for(size_t i = 0;i < m_speeds.size();i++){
+			if(v < 35){
+				status = false;
+			}
+		}
+	}
+
+	if(status){
+		// 产生告警
+		event_tool::instance()->handle_event(OT_CARD, ET_CARD_OVER_SPEED, id, 0, 0, status);
+	}
+
+	status = true;
+	if(m_speed.size() == 30){
+		for(size_t i = 20;i < m_speeds.size();i++){
+			if(v>35){
+				status = false;
+			}
+		}
+		if(status){
+			// 结束告警
+			event_tool::instance()->handle_event(OT_CARD, ET_CARD_OVER_SPEED, id, 0, 0, false);
+		}
+	}
+	
+	
 }
 
 int car::get_vehicle_type_id()
@@ -57,6 +112,26 @@ int car::get_vehicle_type_id()
 	return m_vehicle_type_id;
 }
 
+/*
+ * @brief 
+ *		车辆防碰撞判断
+ *		车辆定位后,检查车辆附近(根据防碰撞的三个档位距离阈值)是否有人,有人则产生防碰撞告警
+ *		如果车辆在距离最大档位内没人,则结束告警;
+ *		以车为单位,通知web端,进入一档二档三挡会将三个档位每个档位有多少人通知web端,
+ *		当人从一档变为二档也会将人档位的变化发送给web端;
+ *		发送告警的级别会根据档位的变化动态变化;产生一条告警
+ *		允许重复发送
+ *		在本方法中实现上述逻辑;
+ * @param
+ *		const point& pt		车辆定位位置
+ *		const int& sid		
+ * @return
+ *		无
+ * @note
+ * modified by zhuyf,2022-04-24
+ * @warning
+ * @bug
+ * */
 void car::handle_anti_coll(const point& pt, const int& sid)
 {
     // 车卡下发最紧急的呼叫类型

+ 5 - 2
card_car.h

@@ -15,8 +15,10 @@ struct loc_point;
 
 struct car:card_location_base,card_area
 {
-	int m_vehicle_category_id=0;
-    int m_vehicle_type_id=0;
+	int m_vehicle_category_id = 0;
+    int m_vehicle_type_id = 0;
+
+	boost::circular_buffer<double> m_speeds;
 public:
 
     car(const std::string&type,uint32_t cardid,uint16_t needdisplay,int16_t t,int32_t deptid,
@@ -43,6 +45,7 @@ private:
 	void handle_three_rates(const point &pt);
     void handle_traffic_light(const point& pt, const int& sid);
     void handle_anti_coll(const point& pt, const int& sid);
+	void handle_over_speed();
 	void on_timer();
 	void make_package();
 	loc_point getSmoothPoint();

+ 1 - 1
common.h

@@ -3,7 +3,7 @@
 
 #define LENGTH_SQL 2000
 #define SPEED_COUNT_LIMIT 5
-#define READER_TIMEOUT 20
+#define READER_TIMEOUT 30
 #define LIGHT_TIMEOUT  30
 #define PI 3.1415926
 #define TPI (2*3.1415926)

+ 116 - 1
db/db_card.cpp

@@ -14,7 +14,7 @@ namespace db_card
 {
 	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_car(const std::string & lszId64)
 	{
-		std::string sql = "SELECT ve.vehicle_id, ve.card_id, c.card_type_id, cf.freq_value, \
+		/*std::string sql = "SELECT ve.vehicle_id, ve.card_id, c.card_type_id, cf.freq_value, \
 						   ve.dept_id, ve.group_id, v.vehicle_type_id, vt.vehicle_level_id, \
 						   vt.is_railroad AS vt_is_railroad,ve.need_display ,ve.power_alarm,\
 						   vt.vehicle_category_id,v.bigger_car_flag,vc.over_speed, ve.enable_anti_collision \
@@ -118,6 +118,120 @@ namespace db_card
 	        
             map.insert({cardid,clb});
 
+            log_info("cardId:%s,id:%d dept_id:%d,need_display:%d-cardid:%s,categoryid:%d,vchile_id:%d,type:%d,vehicle_type_id:%d, anti_collision:%d",
+                    card_id.c_str(),
+                    vsid,
+                    dept_id,
+                    need_display,
+                    card_id.c_str(),
+                    vehicle_category_id,
+                    vehicle_id,
+                    card_type_id,
+                    vehicle_type_id,
+                    anti_collision
+                    );
+        }
+
+		return map;*/
+		std::string sql = "SELECT ve.vehicle_id, ve.card_id, ve.dept_id, c.card_type_id, cf.freq_value, v.vehicle_type_id, v.bigger_car_flag \
+		                            FROM dat_vehicle_extend ve \
+									LEFT JOIN dat_vehicle v ON ve.vehicle_id = v.vehicle_id \
+									LEFT JOIN dat_card c ON ve.card_id = c.card_id \
+									LEFT JOIN dat_dept d ON ve.dept_id = d.dept_id \
+								    LEFT JOIN dat_vehicle_type vt ON v.vehicle_type_id = vt.vehicle_type_id \
+									LEFT JOIN dat_card_freq cf on cf.freq_id = c.freq_id \
+									WHERE c.state_id = 0";
+
+		std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> map;
+
+		if("" == lszId64)
+		{
+			sql.append(";");
+		}
+		else
+		{
+			sql.append(" AND ve.card_id ='");
+			sql.append(lszId64);
+			sql.append("';");
+		}
+
+		std::string Error;
+		YADB::CDBResultSet DBRes;
+		sDBConnPool.Query(sql.c_str(),DBRes,Error);
+		int nCount = DBRes.GetRecordCount( Error );
+		if (nCount < 1)
+		{
+			log_error("增加或修改失败,数据库中找不到: sql=%s", sql.c_str());
+			return map;
+		}
+
+		while ( DBRes.GetNextRecod(Error) )
+		{
+			unsigned int vehicle_id  = 0;
+			DBRes.GetField( "vehicle_id",vehicle_id, Error );
+
+			std::string card_id;
+			DBRes.GetField( "card_id",card_id, Error );
+
+			uint32_t vsid = atoi(card_id.substr(3).c_str());
+
+			unsigned int card_type_id  = 0;
+			DBRes.GetField( "card_type_id",card_type_id, Error );
+
+            double freq = 0;
+            DBRes.GetField("freq_value", freq, Error);
+
+			int dept_id = 0;
+			DBRes.GetField( "dept_id",dept_id, Error );
+
+			int group_id = 0;
+			//DBRes.GetField( "group_id",group_id, Error );
+
+			int vehicle_type_id = 0;
+			DBRes.GetField( "vehicle_type_id",vehicle_type_id, Error );
+
+			int vehicle_level_id = 0;
+			//DBRes.GetField( "vehicle_level_id",vehicle_level_id, Error );
+
+			int need_display = 0;
+			//DBRes.GetField( "need_display",need_display, Error );
+
+			int power_alarm = 0;
+			//DBRes.GetField( "power_alarm",power_alarm, Error );
+
+			int vehicle_category_id = 0;
+			//DBRes.GetField( "vehicle_category_id",vehicle_category_id, Error );
+
+			int bigger_car_flag= 0;
+			DBRes.GetField( "bigger_car_flag",bigger_car_flag, Error );
+
+			double over_speed= 0;
+			//DBRes.GetField( "over_speed",over_speed, Error );
+            uint32_t type = tool_other::card_id_to_type(card_id);
+            if(type != card_type_id)
+            {
+                log_error("init_vehicle_card error.Type is not matching..");
+                continue;
+            }
+			std::string strategy;
+			if(card_type_id ==CT_VEHICLE)
+				strategy = config.get("car.strategy","CS_1");
+			else if(vehicle_type_id==VT_COAL_CUTTER)
+				strategy = config.get("coalface.strategy","WS_1");
+            else
+				strategy = config.get("person.strategy","PS_1");
+
+			auto clb = card_location_base::make_car(strategy,vsid,need_display,card_type_id,
+					dept_id,vehicle_category_id, vehicle_type_id,vehicle_level_id,vehicle_id);
+			uint64_t cardid = tool_other::type_id_to_u64(card_type_id,vsid);
+            clb->m_freq = freq;
+
+            int anti_collision = 0;
+            //DBRes.GetField("enable_anti_collision", anti_collision, Error);
+            clb->m_enable_anti_collision = ((anti_collision == 1) ? true : false);
+	        
+            map.insert({cardid,clb});
+
             log_info("cardId:%s,id:%d dept_id:%d,need_display:%d-cardid:%s,categoryid:%d,vchile_id:%d,type:%d,vehicle_type_id:%d, anti_collision:%d",
                     card_id.c_str(),
                     vsid,
@@ -133,6 +247,7 @@ namespace db_card
         }
 
 		return map;
+
 	}
 
 	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_person(const std::string & lszId64,const std::string&strategy)

+ 165 - 20
event.cpp

@@ -72,6 +72,19 @@ event_tool * event_tool::instance()
 {
     return &et;
 }
+
+/*
+ *	@brief
+ *		告警分类:一人带多卡告警、区域告警、基站告警、卡告警、红绿灯告警
+ *	@param
+ *		无
+ *	@return
+ *		无
+ *	@note
+ *	@warning
+ *	@bug
+ *
+ * */
 void event_tool::make_event_object()
 {
     m_map[OT_MORE_CARD] = std::make_shared<mine_event>();
@@ -81,7 +94,7 @@ void event_tool::make_event_object()
     m_map[OT_DEVICE_LIGHT] = std::make_shared<light_event>();
 }
 
-void event_tool::handle_event(OBJECT_TYPE ot,EVENT_TYPE et,uint64_t id,double limit_value,double cur_value,bool f,EVENT_DIS_TYPE edt/*=DT_COMMON*/,const std::string &desc/*=""*/)
+void event_tool::handle_event(OBJECT_TYPE ot, EVENT_TYPE et, uint64_t id, double limit_value, double cur_value, bool f, EVENT_DIS_TYPE edt/*=DT_COMMON*/, const std::string &desc/*=""*/)
 {
     m_map[ot]->handle_alarm_event(et,id,limit_value,cur_value,f,edt,desc);
 }
@@ -96,7 +109,11 @@ std::shared_ptr<ya_event> Event::create_event(const std::string&obj_id,EVENT_TYP
 }
 
 /*
- * @breif		构建开始或者取消告警事件
+ * @breif		构建开始或者取消告警事件,
+ * 告警事件入口,生成事件对象,保存在内存中。
+ * end_time为零表示开始
+ * start_time为零表示结束
+ * 事件的唯一根据id判断。
  * @param		EVENT_TYPE et			事件设备类型
  * @param		uint64_t id
  * @param		double limit_value		阈值
@@ -109,10 +126,11 @@ std::shared_ptr<ya_event> Event::create_event(const std::string&obj_id,EVENT_TYP
  * @bug
  * @warning
  * */
-void Event::handle_alarm_event(EVENT_TYPE et,uint64_t id,double limit_value,double cur_value,bool f,EVENT_DIS_TYPE edt,const std::string &desc)
+void Event::handle_alarm_event(EVENT_TYPE et, uint64_t id, double limit_value, double cur_value, bool f, EVENT_DIS_TYPE edt, const std::string &desc)
 {
     std::shared_ptr<ya_event> ev_ptr = nullptr;
-    uint64_t eid = event_list::to_list_id(et,m_oid,id,edt);
+    uint64_t eid = event_list::to_list_id(et, m_oid, id, edt);
+	//eid是告警的唯一id,如果存在,查找eid来找到的已经存在的事件
     auto event_ptr = event_list::instance()->get(eid);
     if(f)
     {
@@ -125,27 +143,27 @@ void Event::handle_alarm_event(EVENT_TYPE et,uint64_t id,double limit_value,doub
         }
         else
         {
-            uint64_t _id=id;
+            uint64_t _id = id;
             //log_info("Create_Event:desc[%s],id:%d,et:%d",desc.c_str(),id,et);
             if((et == ET_UWB_MORE_CARD||et == ET_VEHICLE_REAR_END) && !desc.empty())//防追尾告警特殊处理
             {
-                std::string cardid = desc.substr(0,desc.find_first_of('&'));
+                std::string cardid = desc.substr(0, desc.find_first_of('&'));
                 _id = tool_other::card_id_to_u64(cardid);
             }
-            ev_ptr=on_message(et,_id,f);
+            ev_ptr = on_message(et,_id,f);
             if(ev_ptr){
-                ev_ptr->m_cur_value=cur_value;
-                ev_ptr->m_limit_value=limit_value;
-                ev_ptr->m_desc=desc;
-                ev_ptr->m_id=eid;
-                ev_ptr->m_dis_type=edt;
-                if(et == ET_VEHICLE_REAR_END||et==ET_UWB_MORE_CARD)//一人多卡特殊处理
+                ev_ptr->m_cur_value = cur_value;
+                ev_ptr->m_limit_value = limit_value;
+                ev_ptr->m_desc = desc;
+                ev_ptr->m_id = eid;
+                ev_ptr->m_dis_type = edt;
+                if(et == ET_VEHICLE_REAR_END|| et == ET_UWB_MORE_CARD)//一人多卡特殊处理
                 {
-                    ev_ptr->m_obj_id=desc;
+                    ev_ptr->m_obj_id = desc;
                     //ev_ptr->m_cur_time=std::chrono::system_clock::time_point(std::chrono::milliseconds((time_t)limit_value * 1000));
                 }
                 //保存告警信息
-                event_list::instance()->add(eid,ev_ptr);
+                event_list::instance()->add(eid, ev_ptr);
             }
         }
     }
@@ -157,14 +175,26 @@ void Event::handle_alarm_event(EVENT_TYPE et,uint64_t id,double limit_value,doub
             event_ptr->m_cur_time = std::chrono::system_clock::now();
             event_ptr->m_status = ES_END;
             event_ptr->m_cur_value = cur_value;
-            event_ptr->m_desc=desc;
-            event_ptr->m_is_sent=false;
+            event_ptr->m_desc = desc;
+            event_ptr->m_is_sent = false;
             ev_ptr=event_ptr;
         }
     }
-    if(ev_ptr)
+    
+	if(ev_ptr)
     {
-        event_list::save_event(ev_ptr);
+        //event_list::save_event(ev_ptr);
+		//基站失联告警:人员和车辆都要有
+		if(ev_ptr->m_ev_type == 6){
+			event_list::save_event(ev_ptr);
+			event_list::save_event_v(ev_ptr);
+		}else if(ev_ptr->m_ev_type == 8 || ev_ptr->m_ev_type == 21 || ev_ptr->m_ev_type == 41){
+			// 红绿灯失联、人车防碰撞、超速告警这三类保存到his_event_data_v表中
+			event_list::save_event_v(ev_ptr);
+		}else{
+			//其他的人员相关报警保存到his_event_data表中
+			event_list::save_event(ev_ptr);
+		}
     }
 }
 
@@ -307,6 +337,36 @@ void event_list::save_event(const std::shared_ptr<ya_event> &ev_ptr)
     db_tool::PushAsync(sql);
 }
 
+/*
+ *	@brief
+ *		保存告警事件
+ *	@param
+ *		const std::shared_ptr<ya_event>& ev_ptr		告警对象
+ *		int type									告警开始结束标志,开始为0,结束为1
+ *	@return
+ *		无
+ *	@note
+ *	@warning
+ *	@bug
+ * */
+void event_list::save_event_v(const std::shared_ptr<ya_event> &ev_ptr)
+{
+    char sql[LENGTH_SQL] = {0};
+    std::string _time = tool_time::to_str_ex(ev_ptr->m_cur_time);
+	switch(ev_ptr->m_status){
+		case 0:
+			sprintf(sql, "INSERT IGNORE INTO his_event_data_v(id, event_type_id, obj_id, x, y ,start_time) VALUES(%ld, %d, '%s', %.2f, %.2f, '%s');",
+					ev_ptr->m_ev_id, ev_ptr->m_ev_type, ev_ptr->m_obj_id.c_str(), ev_ptr->x, ev_ptr->y, _time.c_str());
+			break;
+		case 100:
+			sprintf(sql, "update his_event_data_v set end_time='%s' where id=%ld;", _time.c_str(), ev_ptr->m_ev_id);
+			break;
+	}
+    
+	db_tool::PushAsync(sql);
+}
+
+
 void event_list::load_his_data_from_db(bool init /*=true*/)
 {
     static std::time_t s_last_time=0;
@@ -315,7 +375,8 @@ void event_list::load_his_data_from_db(bool init /*=true*/)
         if(t-s_last_time<15)return;
         s_last_time=t;
     }
-    std::unordered_map<uint64_t, std::shared_ptr<ya_event>> map;
+    
+	std::unordered_map<uint64_t, std::shared_ptr<ya_event>> map;
     std::string sql("SELECT event_id, id,stat,event_type_id,obj_type_id,obj_id,dis_type,map_id,area_id,\
             limit_value,cur_value,x,y, cur_time FROM his_event_data \
             WHERE event_id IN (SELECT MAX(event_id) FROM his_event_data \
@@ -460,6 +521,17 @@ void event_list::load_his_data_from_db(bool init /*=true*/)
     }
 }
 
+/*
+ *	@brief
+ *		事件转为json
+ *	@param
+ *		std::vector<std::shared_ptr<ya_event>> arr		事件列表
+ *	@return
+ *		json字符串
+ *	@note
+ *	@warning
+ *	@bug
+ * */
 std::string event_list::evs_to_json(std::vector<std::shared_ptr<ya_event>> arr)
 {
     rapidjson::Document doc(rapidjson::kObjectType);
@@ -483,6 +555,40 @@ std::string event_list::evs_to_json(std::vector<std::shared_ptr<ya_event>> arr)
     return sb.GetString();
 }
 
+/*
+ *	@brief
+ *		构造alarm的json字符串
+ *	@param
+ *		std::vector<std::shared_ptr<ya_event>> arr	告警事件列表
+ *	@return
+ *		alarm的json字符串
+ *	@note
+ *	@warning
+ *	@bug
+ *
+ * */
+std::string event_list::evs_to_json_v(std::vector<std::shared_ptr<ya_event>> arr)
+{
+    rapidjson::Document doc(rapidjson::kObjectType);
+    rapidjson::Value data(rapidjson::kArrayType);
+    rapidjson::Document::AllocatorType& allocator=doc.GetAllocator();
+
+    auto it=arr.begin();
+    for(;it!=arr.end();++it)
+    {
+        _ev_to_node_v(*it, allocator, data);
+    }
+
+    doc.AddMember(JSON_ROOT_KEY_CMD, "alarm", allocator);
+    doc.AddMember(JSON_ROOT_KEY_DATA, data, allocator);
+
+    rapidjson::StringBuffer sb;
+    rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
+    doc.Accept(writer);
+
+    return sb.GetString();
+}
+
 void event_list::_ev_to_node(std::shared_ptr<ya_event> ev_ptr,
                              rapidjson::Document::AllocatorType& allocator,
                              rapidjson::Value& out_data)
@@ -510,4 +616,43 @@ void event_list::_ev_to_node(std::shared_ptr<ya_event> ev_ptr,
     out_data.PushBack(ev, allocator);
 }
 
+/*
+ * @brief
+ *		构造每个具体告警的数据
+ * @param
+ *		std::shared_ptr<ya_event> ev_ptr				//告警对象
+ *		rapidjson::Document::AllocatorType& allocator	//json的allocator
+ *		rapidjson::Value& out_data						//输出的json value对象
+ * @return
+ * @note
+ * @warning
+ * @bug
+ * */
+void event_list::_ev_to_node_v(std::shared_ptr<ya_event> ev_ptr,
+                             rapidjson::Document::AllocatorType& allocator,
+                             rapidjson::Value& out_data)
+{
+    rapidjson::Value ev(rapidjson::kObjectType);
+
+    //ev.AddMember(JSON_KEY_EVENT_EVENT_ID,ev_ptr->m_id, allocator);
+    tool_json::add_member(ev, JSON_KEY_EVENT_EVENT_ID, std::to_string(ev_ptr->m_id), allocator);
+    ev.AddMember(JSON_KEY_EVENT_TYPE_ID,ev_ptr->m_ev_type, allocator);
+
+    tool_json::add_member(ev, JSON_KEY_EVENT_OBJ_ID, ev_ptr->m_obj_id, allocator);
+    ev.AddMember(JSON_KEY_EVENT_X,ev_ptr->x, allocator);
+    ev.AddMember(JSON_KEY_EVENT_Y,ev_ptr->y, allocator);
+
+	switch(ev_ptr->m_status){
+		case 0:
+			ev.AddMember("start_time", tool_time::to_ms(ev_ptr->m_cur_time), allocator);
+			break;
+		case 100:
+			ev.AddMember("end_time", tool_time::to_ms(ev_ptr->m_cur_time), allocator);
+			break;
+	}
+    
+	out_data.PushBack(ev, allocator);
+}
+
+
 //template<> std::shared_ptr<event_list> single_base<event_list, uint64_t, std::shared_ptr<ya_event>>::m_instance=std::make_shared<event_list>();

+ 4 - 0
event.h

@@ -130,6 +130,7 @@ public:
     }
 
     static void save_event(const std::shared_ptr<ya_event> &event_ptr);
+	static void save_event_v(const std::shared_ptr<ya_event>& event_ptr);
 
     void load_his_data_from_db(bool init=true);
 
@@ -142,6 +143,9 @@ public:
         return evs_to_json(evs);
     }
 
+	static std::string evs_to_json_v(std::vector<std::shared_ptr<ya_event>> arr);
+	static void _ev_to_node_v(std::shared_ptr<ya_event> ev_ptr, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& out_data);
+
     static std::string evs_to_json(std::vector<std::shared_ptr<ya_event>> arr);
 private:
     static void _ev_to_node(std::shared_ptr<ya_event> ev_ptr,

+ 18 - 0
module_service/module_call.cpp

@@ -793,9 +793,27 @@ void module_call::system_cancel_call_apoint(int card_id,int card_type)
 
 /*
  * @brief       发送防碰撞告警
+ * 发送方:采集
+ * 接收方:gis-server
+ * 场景1:开始和结束都调用此send
+ * 数据接口样例:
+ *{
+	"cmd":"alarm",		// 命令字, 4种类型的告警:基站通信异常、红绿灯通信异常、人车防碰撞、车辆超速
+	"data":[{
+		"event_id":1122334423321	// 告警id,唯一性
+		"type_id": 1,	//告警类型,4种类型的一种	
+		"obj_id":"0010000001001", // obj_id为车辆号、基站号,人车防碰撞时,车号[人卡号,...人卡号]
+		"x":0.1, //告警发生的位置
+		"y":0.2, //告警发生的位置 
+		"start_time": 17890234234234,	// 触发时间
+		"end_time":						// 结束时间
+		},......]
+	}
+
  * @param       const std::map<int, call_card>& cards       key为车id,val为人卡信息
  * @return
  * @note
+ *		modify zhuyf, 2022-04-24
  * @warning
  * @bug
  *

+ 110 - 6
module_service/module_traffic_light_manager.cpp

@@ -13,11 +13,19 @@ traffic_light_manager* traffic_light_manager::instance()
 }
 
 /*
- * 加载红绿灯基础信息
+ * @breif
+ *		加载红绿灯基础信息
+ * @param
+ *		int lid		红绿灯号
+ * @return
+ *		无
+ * @note
+ * @warning
+ * @bug
  * */
 void traffic_light_manager::init_light_from_db(int lid)
 {
-    std::string sql = "select light_id, lights_group_id, ip, x, y ,z, reader_id, state, port, physics_light_id, physics_light_direction, special_flag, stream_state from dat_light";
+    /*std::string sql = "select light_id, lights_group_id, ip, x, y ,z, reader_id, state, port, physics_light_id, physics_light_direction, special_flag, stream_state from dat_light";
     if(0 == lid){
         sql += ";";
     }else{
@@ -72,15 +80,73 @@ void traffic_light_manager::init_light_from_db(int lid)
         }
     }
 
+    logn_info(2, "sql:%s",sql.c_str());*/
+	std::string sql = "select light_id, lights_group_id, x, y, stream_state from dat_light";
+    if(0 == lid){
+        sql += ";";
+    }else{
+        sql += " where light_id = " + std::to_string(lid);
+        sql += ";";
+    }
+
+    std::string err = "";
+
+    YADB::CDBResultSet res;
+    sDBConnPool.Query(sql.c_str(), res, err);
+    int count =  res.GetRecordCount(err);
+    if(count < 1){
+        log_error("增加或修改失败,error:%s", sql.c_str());
+        return;
+    }
+
+    while(res.GetNextRecod(err)){
+        int light_id = 0;
+        res.GetField("light_id", light_id, err);
+        int group_id = 0;
+        res.GetField("lights_group_id", group_id, err);
+        std::string ip = "";
+        res.GetField("ip", ip, err);
+        double x = 0.0, y = 0.0, z = 0.0;
+        res.GetField("x", x, err);
+        res.GetField("y", y, err);
+        int site_id = 0, state = 0, port = 0, phy_light_id = 0, phy_direction = 0, special = 0, stream = 0;
+        res.GetField("stream_state", stream, err);
+        traffic_light_ptr pl = find_light(light_id);
+        if(nullptr == pl){
+            pl = std::make_shared<traffic_light>(x, y, z, light_id, group_id, ip, state, port, phy_light_id, phy_direction, special, stream);
+            m_unmap_lights.insert(std::make_pair(light_id, pl));           
+        }else{
+            pl->update(x, y , z, light_id, group_id, ip, state, port, phy_light_id, phy_direction, special, stream);
+        }
+
+        // 将红绿灯分配到对应组中
+        auto it_group = m_unmap_groups.find(pl->m_group_id);
+        if(it_group != m_unmap_groups.end())
+        {
+            it_group->second->m_vt_lights.push_back(pl);
+            pl->m_area_id = it_group->second->m_area_id;
+            pl->m_map_id  = it_group->second->m_map_id;
+        }
+    }
+
     logn_info(2, "sql:%s",sql.c_str());
 }
 
 /*
- * 加载红绿灯组基础信息
+ * @brief
+ *		 加载红绿灯组基础信息
+ * @param
+ *		int gid		红绿灯组id
+ * @return
+ *		无
+ * @note
+ * @warning
+ * @bug
+ *
  * */
 void traffic_light_manager::init_light_group_from_db(int gid)
 {
-    std::string sql = "select lights_group_id, x, y, z, scope, map_id, area_id, manual_control_time, light_auto_interval, up_stream_idx from dat_lights_group";
+    /*std::string sql = "select lights_group_id, x, y, z, scope, map_id, area_id, manual_control_time, light_auto_interval, up_stream_idx from dat_lights_group";
     if(gid > 0){
         sql += " where lights_group_id = " + std::to_string(gid);
     }
@@ -127,7 +193,42 @@ void traffic_light_manager::init_light_group_from_db(int gid)
     }
     
     logn_info(2, "sql:%s",sql.c_str());
-    output_upstreamidx();
+    output_upstreamidx();*/
+	
+	std::string sql = "select lights_group_id, x, y, scope from dat_lights_group";
+    if(gid > 0){
+        sql += " where lights_group_id = " + std::to_string(gid);
+    }
+    sql += ";";
+
+    std::string err = "";
+    YADB::CDBResultSet res;
+    
+    sDBConnPool.Query(sql.c_str(), res, err);
+    int count = res.GetRecordCount(err);
+    if(count < 1){
+        log_error("增加或修改失败,数据库中找不到:sql=%s", sql.c_str());
+        return;
+    }
+
+    while(res.GetNextRecod(err)){
+        int group_id = 0;       
+        res.GetField("lights_group_id", group_id, err); 
+        double x = 0.0, y = 0.0, z = 0.0, scope = 0.0;
+        res.GetField("x", x, err);
+        res.GetField("y", y, err);
+        res.GetField("scope", scope, err);
+        int map_id = 0, area_id = 0;
+        traffic_light_group_ptr pg = find_group(group_id);
+        if(nullptr == pg){
+            pg = std::make_shared<traffic_light_group>(x, y, 0.0, group_id, scope, 0, 0, 0);
+            m_unmap_groups.insert(std::make_pair(group_id, pg));
+        }else{
+            pg->update(x, y, z, group_id, scope, 0, 0, 0);
+        }
+    }
+    
+    logn_info(2, "sql:%s",sql.c_str());
 }
 
 void traffic_light_manager::init_light_group_path()
@@ -589,10 +690,13 @@ std::string traffic_light_manager::get_light_state()
 }
 
 /*
- * @brief       红绿灯通信异常告警
+ * @brief       红绿灯失联告警, 红绿灯超过30秒未收到心跳数据产生红绿灯失联告警
+ * 如果采集在30秒内未收到红绿灯的心跳数据,产生红绿灯失联告警;(告警id+start_time)
+ * 采集收到了红绿灯心跳数据,结束红绿灯失联告警(告警id+end_time)
  * @param       无
  * @return      无
  * @note
+ * modified by zhuyf, 2022-04-22
  * @warning
  * @bug
  * */

+ 6 - 1
module_service/module_web.cpp

@@ -111,6 +111,7 @@ void module_web::response_login()
     if(!arr.empty())
     {
         tool_json::push_back(nodes, event_list::evs_to_json(arr), allocator);
+		tool_json::push_back(nodes, event_list::evs_to_json_v(arr), allocator);
     }
 
     //所有红绿灯信息
@@ -136,7 +137,8 @@ void module_web::response_login()
 }
 
 /*
- * @brief   构造事件列表,并发送给请求端
+ * @brief   构造事件列表,并发送给web端
+ * 将所有事件包括:红绿灯失联、基站失联、超速、人车防碰撞告警发送给web端
  * @param   无
  * @return  无
  * @note
@@ -154,6 +156,9 @@ void module_web::run()
 
         std::string tmp = event_list::evs_to_json(arr);
         swsClientMgr.send(JSON_CMD_VALUE_PUSH, tmp);
+
+		tmp = event_list::evs_to_json_v(arr);
+		swsClientMgr.send(JSON_CMD_VALUE_PUSH, tmp);
     }
 
     // 向web端发送呼救数据

+ 2 - 2
net-service.cpp

@@ -493,7 +493,7 @@ int32_t net_service::parse_data_anchor_opt(const std::shared_ptr<client>& clt, z
    	//site_ptr->m_device_type_id = (power>>3)&0x07;
 	site_ptr->m_net_device_status = (((power>>3)&0x07) == 0 ? 0: 1);
 
-    if(!check_message_time(clt, site_ptr, &site_tm, site_ct, power)){
+    /*if(!check_message_time(clt, site_ptr, &site_tm, site_ct, power)){
 		// 分站时间异常,直接校时
 		//switch(site_ptr->m_device_type_id)
 		switch(site_ptr->m_net_device_status)
@@ -510,7 +510,7 @@ int32_t net_service::parse_data_anchor_opt(const std::shared_ptr<client>& clt, z
 		}
 	
 		return -1;
-	}
+	}*/
 
     if(clt->type()!=2){
         site_ptr->set_client(clt);