module_traffic_light_manager.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. #include "module_traffic_light_manager.h"
  2. #include "db_api/CDBSingletonDefine.h"
  3. #include <db_api/CDBResultSet.h>
  4. #include "websocket/constdef.h"
  5. //#include "websocket/wsTimerThread.h"
  6. #include "websocket/ws_common.h"
  7. #include "event.h"
  8. traffic_light_manager* traffic_light_manager::instance()
  9. {
  10. static traffic_light_manager tlm;
  11. return &tlm;
  12. }
  13. /*
  14. * @breif
  15. * 加载红绿灯基础信息
  16. * @param
  17. * int lid 红绿灯号
  18. * @return
  19. * 无
  20. * @note
  21. * @warning
  22. * @bug
  23. * */
  24. void traffic_light_manager::init_light_from_db(int lid)
  25. {
  26. /*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";
  27. if(0 == lid){
  28. sql += ";";
  29. }else{
  30. sql += " where light_id = " + std::to_string(lid);
  31. sql += ";";
  32. }
  33. std::string err = "";
  34. YADB::CDBResultSet res;
  35. sDBConnPool.Query(sql.c_str(), res, err);
  36. int count = res.GetRecordCount(err);
  37. if(count < 1){
  38. log_error("增加或修改失败,error:%s", sql.c_str());
  39. return;
  40. }
  41. while(res.GetNextRecod(err)){
  42. int light_id = 0;
  43. res.GetField("light_id", light_id, err);
  44. int group_id = 0;
  45. res.GetField("lights_group_id", group_id, err);
  46. std::string ip = "";
  47. res.GetField("ip", ip, err);
  48. double x = 0.0, y = 0.0, z = 0.0;
  49. res.GetField("x", x, err);
  50. res.GetField("y", y, err);
  51. res.GetField("z", z, err);
  52. int site_id = 0, state = 0, port = 0, phy_light_id = 0, phy_direction = 0, special = 0, stream = 0;
  53. res.GetField("reader_id", site_id, err);
  54. res.GetField("state", state, err);
  55. res.GetField("port", port, err);
  56. res.GetField("physics_light_id", phy_light_id, err);
  57. res.GetField("physics_light_direction", phy_direction, err);
  58. res.GetField("special_flag", special, err);
  59. res.GetField("stream_state", stream, err);
  60. traffic_light_ptr pl = find_light(light_id);
  61. if(nullptr == pl){
  62. pl = std::make_shared<traffic_light>(x, y, z, light_id, group_id, ip, state, port, phy_light_id, phy_direction, special, stream);
  63. m_unmap_lights.insert(std::make_pair(light_id, pl));
  64. }else{
  65. pl->update(x, y , z, light_id, group_id, ip, state, port, phy_light_id, phy_direction, special, stream);
  66. }
  67. // 将红绿灯分配到对应组中
  68. auto it_group = m_unmap_groups.find(pl->m_group_id);
  69. if(it_group != m_unmap_groups.end())
  70. {
  71. it_group->second->m_vt_lights.push_back(pl);
  72. pl->m_area_id = it_group->second->m_area_id;
  73. pl->m_map_id = it_group->second->m_map_id;
  74. }
  75. }
  76. logn_info(2, "sql:%s",sql.c_str());*/
  77. std::string sql = "select light_id, lights_group_id, x, y, stream_state from dat_light";
  78. if(0 == lid){
  79. sql += ";";
  80. }else{
  81. sql += " where light_id = " + std::to_string(lid);
  82. sql += ";";
  83. }
  84. std::string err = "";
  85. YADB::CDBResultSet res;
  86. sDBConnPool.Query(sql.c_str(), res, err);
  87. int count = res.GetRecordCount(err);
  88. if(count < 1){
  89. log_error("增加或修改失败,error:%s", sql.c_str());
  90. return;
  91. }
  92. while(res.GetNextRecod(err)){
  93. int light_id = 0;
  94. res.GetField("light_id", light_id, err);
  95. int group_id = 0;
  96. res.GetField("lights_group_id", group_id, err);
  97. std::string ip = "";
  98. res.GetField("ip", ip, err);
  99. double x = 0.0, y = 0.0, z = 0.0;
  100. res.GetField("x", x, err);
  101. res.GetField("y", y, err);
  102. int site_id = 0, state = 0, port = 0, phy_light_id = 0, phy_direction = 0, special = 0, stream = 0;
  103. res.GetField("stream_state", stream, err);
  104. traffic_light_ptr pl = find_light(light_id);
  105. if(nullptr == pl){
  106. pl = std::make_shared<traffic_light>(x, y, z, light_id, group_id, ip, state, port, phy_light_id, phy_direction, special, stream);
  107. m_unmap_lights.insert(std::make_pair(light_id, pl));
  108. }else{
  109. pl->update(x, y , z, light_id, group_id, ip, state, port, phy_light_id, phy_direction, special, stream);
  110. }
  111. // 将红绿灯分配到对应组中
  112. auto it_group = m_unmap_groups.find(pl->m_group_id);
  113. if(it_group != m_unmap_groups.end())
  114. {
  115. it_group->second->m_vt_lights.push_back(pl);
  116. pl->m_area_id = it_group->second->m_area_id;
  117. pl->m_map_id = it_group->second->m_map_id;
  118. }
  119. }
  120. logn_info(2, "sql:%s",sql.c_str());
  121. }
  122. /*
  123. * @brief
  124. * 加载红绿灯组基础信息
  125. * @param
  126. * int gid 红绿灯组id
  127. * @return
  128. * 无
  129. * @note
  130. * @warning
  131. * @bug
  132. *
  133. * */
  134. void traffic_light_manager::init_light_group_from_db(int gid)
  135. {
  136. /*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";
  137. if(gid > 0){
  138. sql += " where lights_group_id = " + std::to_string(gid);
  139. }
  140. sql += ";";
  141. std::string err = "";
  142. YADB::CDBResultSet res;
  143. sDBConnPool.Query(sql.c_str(), res, err);
  144. int count = res.GetRecordCount(err);
  145. if(count < 1){
  146. log_error("增加或修改失败,数据库中找不到:sql=%s", sql.c_str());
  147. return;
  148. }
  149. while(res.GetNextRecod(err)){
  150. int group_id = 0;
  151. res.GetField("lights_group_id", group_id, err);
  152. double x = 0.0, y = 0.0, z = 0.0, scope = 0.0;
  153. res.GetField("x", x, err);
  154. res.GetField("y", y, err);
  155. res.GetField("z", z, err);
  156. res.GetField("scope", scope, err);
  157. int map_id = 0, area_id = 0;
  158. res.GetField("map_id", map_id, err);
  159. res.GetField("area_id", area_id, err);
  160. int ai = 0;
  161. res.GetField("light_auto_interval", ai, err);
  162. int usi = 0;
  163. res.GetField("up_stream_idx", usi, err);
  164. traffic_light_group_ptr pg = find_group(group_id);
  165. if(nullptr == pg){
  166. pg = std::make_shared<traffic_light_group>(x, y, z, group_id, scope, ai, map_id, area_id);
  167. m_unmap_groups.insert(std::make_pair(group_id, pg));
  168. }else{
  169. pg->update(x, y, z, group_id, scope, ai, map_id, area_id);
  170. }
  171. pg->set_down_stream_idx(usi);
  172. auto ppg = m_map_groups.find(usi);
  173. if(ppg == m_map_groups.end()){
  174. m_map_groups.insert(std::make_pair(usi, pg));
  175. }
  176. }
  177. logn_info(2, "sql:%s",sql.c_str());
  178. output_upstreamidx();*/
  179. std::string sql = "select lights_group_id, x, y, scope from dat_lights_group";
  180. if(gid > 0){
  181. sql += " where lights_group_id = " + std::to_string(gid);
  182. }
  183. sql += ";";
  184. std::string err = "";
  185. YADB::CDBResultSet res;
  186. sDBConnPool.Query(sql.c_str(), res, err);
  187. int count = res.GetRecordCount(err);
  188. if(count < 1){
  189. log_error("增加或修改失败,数据库中找不到:sql=%s", sql.c_str());
  190. return;
  191. }
  192. while(res.GetNextRecod(err)){
  193. int group_id = 0;
  194. res.GetField("lights_group_id", group_id, err);
  195. double x = 0.0, y = 0.0, z = 0.0, scope = 0.0;
  196. res.GetField("x", x, err);
  197. res.GetField("y", y, err);
  198. res.GetField("scope", scope, err);
  199. int map_id = 0, area_id = 0;
  200. traffic_light_group_ptr pg = find_group(group_id);
  201. if(nullptr == pg){
  202. pg = std::make_shared<traffic_light_group>(x, y, 0.0, group_id, scope, 0, 0, 0);
  203. m_unmap_groups.insert(std::make_pair(group_id, pg));
  204. }else{
  205. pg->update(x, y, z, group_id, scope, 0, 0, 0);
  206. }
  207. }
  208. logn_info(2, "sql:%s",sql.c_str());
  209. }
  210. void traffic_light_manager::init_light_group_path()
  211. {
  212. std::string sql = "select reader_id, tof_flag, b_x, b_y, b_z, e_x, e_y, e_z, spacing_ratio from dat_reader_path_tof_n;";
  213. //std::map<int, std::vector<line_v>> map_path;
  214. std::string error;
  215. YADB::CDBResultSet res;
  216. sDBConnPool.Query(sql.c_str(), res, error);
  217. int count = res.GetRecordCount(error);
  218. log_info("init_light_group_path, the record count=%d\n", count);
  219. while(res.GetNextRecod(error)){
  220. int reader_id = 0;
  221. res.GetField("reader_id", reader_id, error);
  222. int pid=0;
  223. res.GetField("tof_flag", pid, error);
  224. double b_x = 0;
  225. res.GetField("b_x", b_x, error);
  226. double b_y = 0;
  227. res.GetField("b_y", b_y, error);
  228. double b_z = 0;
  229. res.GetField("b_z", b_z, error);
  230. double e_x = 0;
  231. res.GetField("e_x", e_x, error);
  232. double e_y = 0;
  233. res.GetField("e_y", e_y, error);
  234. double e_z = 0;
  235. res.GetField("e_z", e_z, error);
  236. double spacing_ratio = 0;
  237. res.GetField("spacing_ratio", spacing_ratio, error);
  238. log_info("[traffic_light] src-path: site=%d, x0=%.2f, y0=%.2f, x1=%.2f, y1=%.2f", reader_id, b_x, b_y, e_x, e_y);
  239. point p1(b_x, -b_y, spacing_ratio);
  240. point p2(e_x, -e_y, spacing_ratio);
  241. m_map_path.insert(std::make_pair(reader_id, std::vector<line_v>()));
  242. m_map_path.find(reader_id)->second.push_back(line_v(p1, p2));
  243. }
  244. for(auto itg : m_unmap_groups){
  245. for(auto itp : m_map_path){
  246. bool tag = false;
  247. for(size_t i = 0;i < itp.second.size();i++){
  248. if(itp.second[i].contain(point(itg.second->x, itg.second->y),1)){
  249. tag = true;
  250. }
  251. }
  252. if(tag){
  253. itg.second->set_path(itp.second);
  254. }
  255. }
  256. }
  257. }
  258. void traffic_light_manager::init_map(int id)
  259. {
  260. std::string sql = "select map_id, scale from dat_map";
  261. if(id > 0){
  262. sql += " where map_id = " + std::to_string(id);
  263. }
  264. sql += ";";
  265. std::string err = "";
  266. YADB::CDBResultSet res;
  267. sDBConnPool.Query(sql.c_str(), res, err);
  268. int count = res.GetRecordCount(err);
  269. if(count < 1){
  270. log_error("增加或修改失败,数据库中找不到:sql=%s", sql.c_str());
  271. return;
  272. }
  273. while(res.GetNextRecod(err)){
  274. int map_id = 0;
  275. res.GetField("map_id", map_id, err);
  276. double scale = 0.0;
  277. res.GetField("scale", scale, err);
  278. set_scale(scale);
  279. log_info("init_map: map_id=%d, scale=%.2f", map_id, scale);
  280. }
  281. logn_info(2, "sql:%s" ,sql.c_str());
  282. }
  283. void traffic_light_manager::init(const int& lgc)
  284. {
  285. // 1.先获得红绿灯组数据
  286. init_light_group_from_db();
  287. init_light_group_path();
  288. // 2.再获得红绿灯数据
  289. init_light_from_db();
  290. init_map();
  291. for(hashmap_light::iterator it_light = m_unmap_lights.begin(); it_light != m_unmap_lights.end(); ++it_light){
  292. if(it_light->second->m_group_id >0){
  293. hashmap_group::iterator it_group = m_unmap_groups.find(it_light->second->m_group_id);
  294. if(it_group != m_unmap_groups.end()){
  295. it_group->second->insert(it_light->second);
  296. }
  297. }
  298. }
  299. for(auto it : m_unmap_groups){
  300. log_info("[traffic_light] gid=%d, size=%d", it.first, it.second->m_vt_lights.size());
  301. }
  302. m_light_group_ctrl_num = lgc;
  303. }
  304. void traffic_light_manager::start()
  305. {
  306. log_info("[traffic_light] start traffic light service, light_group's size=%d", m_unmap_groups.size());
  307. m_stop = false;
  308. m_crossing_rule = std::unique_ptr<crossing_rule>(new crossing_rule);
  309. if(nullptr == m_crossing_rule){
  310. log_info("[traffic_light] create crossing rule failed");
  311. return;
  312. }else{
  313. for(auto it = m_unmap_groups.begin(); it != m_unmap_groups.end(); ++it)
  314. {
  315. m_crossing_rule->put(it->second);
  316. }
  317. }
  318. m_avoidance_rule = std::unique_ptr<avoidance_rule>(new avoidance_rule);
  319. if(nullptr == m_avoidance_rule){
  320. log_info("[traffic_light] create avoidance rule failed");
  321. return;
  322. }else{
  323. for(auto it = m_unmap_groups.begin(); it != m_unmap_groups.end(); ++it)
  324. {
  325. log_info("[traffic_light] insert light group %d into area, area_id=%d", it->second->m_group_id, it->second->m_area_id);
  326. m_avoidance_rule->put(it->second);
  327. }
  328. }
  329. log_info("[traffic_light] rule's map size, crossing=%d, avoidance=%d", m_crossing_rule->size(), m_avoidance_rule->size());
  330. m_thread_light.reset(new std::thread(std::bind(&traffic_light_manager::run, this)));
  331. }
  332. void traffic_light_manager::stop()
  333. {
  334. log_info("[traffic_light] stop traffic light service");
  335. m_stop = true;
  336. m_thread_light->join();
  337. }
  338. void traffic_light_manager::put(const light_message& msg)
  339. {
  340. std::unique_lock<std::mutex> lock(m_mutex);
  341. m_list_data.push_back(msg);
  342. lock.unlock();
  343. m_condition.notify_all();
  344. }
  345. void traffic_light_manager::run()
  346. {
  347. while(!m_stop){
  348. std::list<light_message> tmp_data;
  349. tmp_data.clear();
  350. {
  351. std::unique_lock<std::mutex> lock(m_mutex);
  352. while(m_list_data.empty()){
  353. m_condition.wait(lock);
  354. }
  355. if(m_list_data.size() > 0){
  356. m_list_data.swap(tmp_data);
  357. }
  358. lock.unlock();
  359. }
  360. for(std::list<light_message>::iterator it = tmp_data.begin(); it != tmp_data.end(); ++it){
  361. switch(it->m_cmd){
  362. case cmd_reload:
  363. log_info("[traffic_light] cmd=%d, gid=%d, lid=%d",it->m_cmd, it->m_group_id, it->m_light_id);
  364. handle_reload(it->m_group_id, it->m_light_id);
  365. break;
  366. case cmd_manual_ctrl:
  367. log_info("[traffic_light] cmd=%d, gid=%d, lid=%d, name=%s, lc=%d", it->m_cmd, it->m_group_id, it->m_light_id, it->m_ctrl_name.c_str(), it->m_light_state);
  368. handle_manual(it->m_group_id,it->m_light_id, it->m_ctrl_name, it->m_light_state);
  369. break;
  370. case cmd_card_data:
  371. log_info("[traffic_light] cmd=%d, cid=%d, ctype=%d, bigger=%d, aid=%d, speed=%.2f, sid=%d", it->m_cmd, it->m_pos.m_card_id, it->m_pos.m_type, it->m_pos.m_bigger, it->m_pos.m_area_id, it->m_pos.m_speed, it->m_pos.m_site_id);
  372. handle_position(it->m_pos);
  373. break;
  374. default:
  375. log_warn("[traffic_light] message cmd error, cmd=%d", it->m_cmd);
  376. break;
  377. }
  378. }
  379. }
  380. log_info("[traffic_light] working thread is exit. m_stop=%d", m_stop);
  381. }
  382. // 红绿灯及灯组基础数据更新
  383. void traffic_light_manager::handle_reload(const int& gid, const int& lid)
  384. {
  385. if(lid > 0){
  386. init_light_from_db(lid);
  387. }
  388. if(gid > 0){
  389. init_light_group_from_db(gid);
  390. }
  391. }
  392. // 红绿灯基础数据更新
  393. int traffic_light_manager::reload_light(const int& lid)
  394. {
  395. init_light_from_db(lid);
  396. return 0;
  397. }
  398. // 灯组基础数据更新
  399. int traffic_light_manager::reload_group(const int& gid)
  400. {
  401. init_light_group_from_db(gid);
  402. return 0;
  403. }
  404. std::vector<traffic_light_group_ptr> traffic_light_manager::find_stream_groups(traffic_light_group_ptr ptr_group, const move_stream& stream)
  405. {
  406. std::vector<traffic_light_group_ptr> vt_group;
  407. switch(stream){
  408. case move_stream::up_stream:
  409. {
  410. auto itg = m_map_groups.end();
  411. for(auto it = m_map_groups.begin(); it != m_map_groups.end(); ++it){
  412. if(it->second->m_group_id == ptr_group->m_group_id){
  413. itg = it;
  414. }
  415. }
  416. auto ite = itg;
  417. std::advance(ite, m_light_group_ctrl_num);
  418. std::for_each(itg, ite, [&vt_group](std::pair<int, traffic_light_group_ptr> p){
  419. if(p.second != nullptr){
  420. vt_group.push_back(p.second);
  421. }
  422. });
  423. }
  424. break;
  425. case move_stream::down_stream:
  426. {
  427. auto itg = m_map_groups.rend();
  428. for(auto it = m_map_groups.rbegin(); it != m_map_groups.rend(); ++it){
  429. if(it->second->m_group_id == ptr_group->m_group_id){
  430. itg = it;
  431. }
  432. }
  433. auto ite = itg;
  434. std::advance(ite, m_light_group_ctrl_num);
  435. std::for_each(itg, ite, [&vt_group](std::pair<int, traffic_light_group_ptr> p){
  436. if(p.second != nullptr){
  437. vt_group.push_back(p.second);
  438. }
  439. });
  440. }
  441. break;
  442. default:
  443. break;
  444. }
  445. return std::move(vt_group);
  446. }
  447. // 处理web端发起的手工控制
  448. void traffic_light_manager::manual_ctrl(sio::message::ptr const& data)
  449. {
  450. std::map<std::string, sio::message::ptr> mp = data->get_map()[JSON_ROOT_KEY_DATA]->get_map();
  451. log_info("[traffic_light] map's size=%d", mp.size());
  452. light_message lm;
  453. lm.m_group_id = mp["group_id"]->get_int();
  454. lm.m_light_id = mp["light_id"]->get_int();
  455. lm.m_light_state = mp["light_color"]->get_int();
  456. lm.m_ctrl_name = mp["ctrl_name"]->get_string();
  457. int ctrl = mp["control"]->get_int();
  458. // 如果手工控制,否则取消手工控制
  459. (ctrl == 1)?set_manual(lm):cancel_manual(lm);
  460. }
  461. void traffic_light_manager::handle_manual(const int& gid, const int& ld, const std::string& name, const int& lc)
  462. {
  463. traffic_light_group_ptr pg = find_group(gid);
  464. if(nullptr != pg){
  465. pg->set_manual_ctrl(name, ld, lc);
  466. }
  467. }
  468. bool traffic_light_manager::on_path(const std::vector<pos_data>& vtp, const point& p)
  469. {
  470. if(vtp.size() < 2){
  471. return false;
  472. }
  473. int sid = vtp[0].m_site_id;
  474. auto it = m_map_path.find(sid);
  475. bool exist = false;
  476. if(it != m_map_path.end()){
  477. for(size_t i = 0;i<it->second.size();++i)
  478. {
  479. if(it->second[i].contain(p, 20)){
  480. exist = true;
  481. break;
  482. }
  483. }
  484. }
  485. return exist;
  486. }
  487. // 红绿灯处理模块入口
  488. void traffic_light_manager::handle_position(pos_data& p)
  489. {
  490. if(p.m_type == 3 || p.m_type == 1){
  491. std::map<uint64_t, pos_data>::iterator it = m_map_card.find(p.m_card_id);
  492. if(it != m_map_card.end()){
  493. m_map_card.erase(it);
  494. }
  495. }else if(p.m_type == 2){
  496. update(p.x, p.y, p.m_card_id);
  497. m_map_card[p.m_card_id] = p;
  498. log_info("[traffic_light] handle position, card_id=%d, x=%.2f, y=%.2f, aid=%d, speed=%.2f, sid=%d", p.m_card_id, p.x, p.y, p.m_area_id, p.m_speed, p.m_site_id);
  499. // 路口规则
  500. if(nullptr != m_crossing_rule){
  501. m_crossing_rule->put_pos(p);
  502. m_crossing_rule->handle_rule(p);
  503. }
  504. if(!p.m_bigger && nullptr != m_avoidance_rule){
  505. m_avoidance_rule->put_pos(p);
  506. m_avoidance_rule->handle_rule(p);
  507. }
  508. }
  509. }
  510. // 手工控制红绿灯
  511. void traffic_light_manager::set_manual(light_message& msg)
  512. {
  513. auto g = m_unmap_groups.find(msg.m_group_id);
  514. if(g != m_unmap_groups.end()){
  515. for(auto it : g->second->m_vt_lights){
  516. if(it->m_light_id == msg.m_light_id){
  517. send_light_data(msg.m_light_id, 0, msg.m_light_state);
  518. }
  519. }
  520. //log_info("[traffic_light] manual ctrl's group info, group_id=%d, light %d's shape is %d, other's shape is %d", msg.m_group_id, msg.m_light_id, msg.m_light_state, state);
  521. }
  522. }
  523. // 取消手工控制
  524. void traffic_light_manager::cancel_manual(light_message& msg)
  525. {
  526. auto g = m_unmap_groups.find(msg.m_group_id);
  527. if(g != m_unmap_groups.end()){
  528. g->second->get_turn();
  529. g->second->reset();
  530. g->second->release_turn();
  531. for(auto it_light : g->second->m_vt_lights){
  532. send_light_data(it_light->m_light_id, 0, it_light->m_state);
  533. }
  534. log_info("[traffic_light] %s cancel manual control %d's light group of %d light", msg.m_ctrl_name.c_str(), msg.m_group_id, msg.m_light_id);
  535. }
  536. }
  537. int traffic_light_manager::remove_light(const int& id)
  538. {
  539. std::lock_guard<std::mutex> lg(m_mutex);
  540. auto it = m_unmap_lights.find(id);
  541. if(it != m_unmap_lights.end()){
  542. m_unmap_lights.erase(it);
  543. }
  544. log_info("[meta_data_change] remove light, lid=%d", id);
  545. return 0;
  546. }
  547. /*
  548. * @brief 删除红绿灯组
  549. * @param 红绿灯组id号
  550. * @return 成功返回0
  551. * @note
  552. * @warning
  553. * @bug
  554. * */
  555. int traffic_light_manager::remove_light_group(const int& id)
  556. {
  557. std::lock_guard<std::mutex> lg(m_mutex);
  558. auto it = m_unmap_groups.find(id);
  559. if(it != m_unmap_groups.end()){
  560. m_unmap_groups.erase(it);
  561. }
  562. log_info("[meta_data_change] remove light group, gid=%d", id);
  563. return 0;
  564. }
  565. /*
  566. * @brief 获得红绿灯实时状态
  567. * @param 无
  568. * @return 无
  569. * @note
  570. * @warning
  571. * @bug
  572. * */
  573. std::string traffic_light_manager::get_light_state()
  574. {
  575. std::lock_guard<std::mutex> lg(m_vtlg_mutex);
  576. std::vector<sys::light_state> lights;
  577. for(auto itg : m_unmap_groups){
  578. for(auto itl : itg.second->m_vt_lights){
  579. sys::light_state state;
  580. state.m_group_id = itg.second->m_group_id;
  581. state.m_light_id = itl->m_light_id;
  582. state.m_light_state = itl->m_state;
  583. //state.m_card_id = itg->second->m_card_id;
  584. lights.push_back(state);
  585. }
  586. }
  587. return m_jsBuilder.build_traffic_light(lights);
  588. }
  589. /*
  590. * @brief 红绿灯失联告警, 红绿灯超过30秒未收到心跳数据产生红绿灯失联告警
  591. * 如果采集在30秒内未收到红绿灯的心跳数据,产生红绿灯失联告警;(告警id+start_time)
  592. * 采集收到了红绿灯心跳数据,结束红绿灯失联告警(告警id+end_time)
  593. * @param 无
  594. * @return 无
  595. * @note
  596. * modified by zhuyf, 2022-04-22
  597. * @warning
  598. * @bug
  599. * */
  600. void traffic_light_manager::visit_light_status()
  601. {
  602. std::lock_guard<std::mutex> lg(m_mutex);
  603. time_t now = time(0);
  604. int diff = 0;
  605. for(auto it : m_unmap_lights){
  606. diff = now - it.second->m_rec_time;
  607. event_tool::instance()->handle_event(OT_DEVICE_LIGHT, ET_LIGHT_ERROR, it.second->m_light_id, LIGHT_TIMEOUT, diff, (diff > LIGHT_TIMEOUT));
  608. }
  609. }