#pragma once #include #include #include #include #include "AlarmDefine.h" //缓冲数据 50小时 毫秒 #define MAX_SAVE_TIME_MILLI 180000000 #define MAX_SAVE_TIME_SECOND 180000 enum class SENSOR_STATUS : int8_t { UNKONW = -1, ABNORMAL = 0, NORMAL = 1 }; class CDevice { public: CDevice(std::string a, std::string b, std::string c, std::string d); virtual ~CDevice(); void Insert(int index, time_t time, int data0, int data1, int data2); //调用Insert数据插入完 来判断是否需要插入数据 返回false 不需要 返回true 需要 inline bool CalcBInsertData(int index, time_t* time, int* data0, int* data1, int* data2) { if (index == 0) return CalcBInsertData(m_mapSecondStatInfo00, m_mapSecondStatInfo01, m_mapSecondStatInfo02, time, data0, data1, data2); else if (index == 1) return CalcBInsertData(m_mapSecondStatInfo10, m_mapSecondStatInfo11, m_mapSecondStatInfo12, time, data0, data1, data2); else return CalcBInsertData(m_mapSecondStatInfo20, m_mapSecondStatInfo21, m_mapSecondStatInfo22, time, data0, data1, data2); } void LoadHist(); inline void updateActive() { time(&m_tmLastActive); } std::map* GetMapData(uint8_t idx, uint8_t no); inline BOOL IsDeviceOnline(time_t tmNow = 0, int inteval = 180000) { if (tmNow == 0) time(&tmNow); if (tmNow - m_tmLastActive < inteval) return TRUE; return FALSE; } inline BOOL GetSendStatInfo(time_t tmStart, time_t tmEnd, uint8_t idx, std::map& map0, std::map& map1, std::map& map2) { if (idx == 0) { if (m_mapSecondStatInfo00.size() == 0) return FALSE; for (auto i = tmStart; i < tmEnd; i++) { auto it0 = m_mapSecondStatInfo00.find(i); if (it0 == m_mapSecondStatInfo00.end()) continue; auto it1 = m_mapSecondStatInfo01.find(i); auto it2 = m_mapSecondStatInfo02.find(i); if (it1 == m_mapSecondStatInfo01.end() || it2 == m_mapSecondStatInfo02.end()) { ASSERT(FALSE); } auto it00 = it0, it01 = it1, it02 = it2; for (; it00 != m_mapSecondStatInfo00.end();) { if (it00->first <= tmEnd) { it00++; it01++; it02++; } else { map0.insert(it0, it00); map1.insert(it1, it01); map2.insert(it2, it02); return TRUE; } } if (it0 != it00) { map0.insert(it0, it00); map1.insert(it1, it01); map2.insert(it2, it02); return TRUE; } } } else if (idx == 1) { if (m_mapSecondStatInfo10.size() == 0) return FALSE; for (auto i = tmStart; i < tmEnd; i++) { auto it0 = m_mapSecondStatInfo10.find(i); if (it0 == m_mapSecondStatInfo10.end()) continue; auto it1 = m_mapSecondStatInfo11.find(i); auto it2 = m_mapSecondStatInfo12.find(i); if (it1 == m_mapSecondStatInfo11.end() || it2 == m_mapSecondStatInfo12.end()) { ASSERT(FALSE); } auto it00 = it0, it01 = it1, it02 = it2; for (; it00 != m_mapSecondStatInfo10.end();) { if (it00->first <= tmEnd) { it00++; it01++; it02++; } else { map0.insert(it0, it00); map1.insert(it1, it01); map2.insert(it2, it02); return TRUE; } } if (it0 != it00) { map0.insert(it0, it00); map1.insert(it1, it01); map2.insert(it2, it02); return TRUE; } } } else if (idx == 2) { if (m_mapSecondStatInfo20.size() == 0) return FALSE; for (auto i = tmStart; i < tmEnd; i++) { auto it0 = m_mapSecondStatInfo20.find(i); if (it0 == m_mapSecondStatInfo20.end()) continue; auto it1 = m_mapSecondStatInfo21.find(i); auto it2 = m_mapSecondStatInfo22.find(i); if (it1 == m_mapSecondStatInfo21.end() || it2 == m_mapSecondStatInfo22.end()) { ASSERT(FALSE); } auto it00 = it0, it01 = it1, it02 = it2; for (; it00 != m_mapSecondStatInfo20.end();) { if (it00->first <= tmEnd) { it00++; it01++; it02++; } else { map0.insert(it0, it00); map1.insert(it1, it01); map2.insert(it2, it02); return TRUE; } } if (it0 != it00) { map0.insert(it0, it00); map1.insert(it1, it01); map2.insert(it2, it02); return TRUE; } } } return FALSE; } //新的接口 inline void Insert(const uint8_t idx, const __time64_t tmStartTime, const int step, const vector& data0, const vector& data1, const vector& data2, const vector result, const size_t len, const SECOND_STAT_INFO& stSS1, const SECOND_STAT_INFO& stSS2, const SECOND_STAT_INFO& stSS3) { //TRACE("%s:%d %s\r\n", __FUNCTION__, __LINE__, CTime(tmStartTime / 1000).Format("%Y-%m-%d %H:%M:%S")); lock_guard lock(m_mtx); switch (idx) { case 0: { for (auto i = 0; i < len; i++) { if (result[i] == false) continue; map_resist_idx00[tmStartTime + i * step] = data0[i]; map_resist_idx01[tmStartTime + i * step] = data1[i]; map_resist_idx02[tmStartTime + i * step] = data2[i]; } auto tmStartTimeSecond = tmStartTime / 1000; m_mapSecondStatInfo00[tmStartTimeSecond] = stSS1; m_mapSecondStatInfo01[tmStartTimeSecond] = stSS2; m_mapSecondStatInfo02[tmStartTimeSecond] = stSS3; time(&m_tmMoveDetectTime0); { auto it = map_resist_idx00.begin(); while (tmStartTime - it->first > MAX_SAVE_TIME_MILLI) it = map_resist_idx00.erase(it); it = map_resist_idx01.begin(); while (tmStartTime - it->first > MAX_SAVE_TIME_MILLI) it = map_resist_idx01.erase(it); it = map_resist_idx02.begin(); while (tmStartTime - it->first > MAX_SAVE_TIME_MILLI) it = map_resist_idx02.erase(it); } { auto it = m_mapSecondStatInfo00.begin(); while (tmStartTimeSecond - it->first > MAX_SAVE_TIME_SECOND) it = m_mapSecondStatInfo00.erase(it); it = m_mapSecondStatInfo01.begin(); while (tmStartTimeSecond - it->first > MAX_SAVE_TIME_SECOND) it = m_mapSecondStatInfo01.erase(it); it = m_mapSecondStatInfo02.begin(); while (tmStartTimeSecond - it->first > MAX_SAVE_TIME_SECOND) it = m_mapSecondStatInfo02.erase(it); } } break; case 1: { for (auto i = 0; i < len; i++) { if (result[i] == false) continue; map_resist_idx10[tmStartTime + i * step] = data0[i]; map_resist_idx11[tmStartTime + i * step] = data1[i]; map_resist_idx12[tmStartTime + i * step] = data2[i]; } auto tmStartTimeSecond = tmStartTime / 1000; m_mapSecondStatInfo10[tmStartTimeSecond] = stSS1; m_mapSecondStatInfo11[tmStartTimeSecond] = stSS2; m_mapSecondStatInfo12[tmStartTimeSecond] = stSS3; time(&m_tmMoveDetectTime1); { auto it = map_resist_idx10.begin(); while (tmStartTime - it->first > MAX_SAVE_TIME_MILLI) it = map_resist_idx10.erase(it); it = map_resist_idx11.begin(); while (tmStartTime - it->first > MAX_SAVE_TIME_MILLI) it = map_resist_idx11.erase(it); it = map_resist_idx12.begin(); while (tmStartTime - it->first > MAX_SAVE_TIME_MILLI) it = map_resist_idx12.erase(it); } { auto it = m_mapSecondStatInfo10.begin(); while (tmStartTimeSecond - it->first > MAX_SAVE_TIME_SECOND) it = m_mapSecondStatInfo10.erase(it); it = m_mapSecondStatInfo11.begin(); while (tmStartTimeSecond - it->first > MAX_SAVE_TIME_SECOND) it = m_mapSecondStatInfo11.erase(it); it = m_mapSecondStatInfo12.begin(); while (tmStartTimeSecond - it->first > MAX_SAVE_TIME_SECOND) it = m_mapSecondStatInfo12.erase(it); } } break; case 2: { for (auto i = 0; i < len; i++) { if (result[i] == false) continue; map_resist_idx20[tmStartTime + i * step] = data0[i]; map_resist_idx21[tmStartTime + i * step] = data1[i]; map_resist_idx22[tmStartTime + i * step] = data2[i]; } auto tmStartTimeSecond = tmStartTime / 1000; m_mapSecondStatInfo20[tmStartTimeSecond] = stSS1; m_mapSecondStatInfo21[tmStartTimeSecond] = stSS2; m_mapSecondStatInfo22[tmStartTimeSecond] = stSS3; time(&m_tmMoveDetectTime2); { auto it = map_resist_idx20.begin(); while (tmStartTime - it->first > MAX_SAVE_TIME_MILLI) it = map_resist_idx20.erase(it); it = map_resist_idx21.begin(); while (tmStartTime - it->first > MAX_SAVE_TIME_MILLI) it = map_resist_idx21.erase(it); it = map_resist_idx22.begin(); while (tmStartTime - it->first > MAX_SAVE_TIME_MILLI) it = map_resist_idx22.erase(it); } { auto it = m_mapSecondStatInfo20.begin(); while (tmStartTimeSecond - it->first > MAX_SAVE_TIME_SECOND) it = m_mapSecondStatInfo20.erase(it); it = m_mapSecondStatInfo21.begin(); while (tmStartTimeSecond - it->first > MAX_SAVE_TIME_SECOND) it = m_mapSecondStatInfo21.erase(it); it = m_mapSecondStatInfo22.begin(); while (tmStartTimeSecond - it->first > MAX_SAVE_TIME_SECOND) it = m_mapSecondStatInfo22.erase(it); } } break; default: ASSERT(0); break; } //TRACE("%s:%d %s\r\n", __FUNCTION__, __LINE__, fmt::format("size 1:{} 2:{} 3:{}", m_mapSecondStatInfo00.size(), m_mapSecondStatInfo10.size(), m_mapSecondStatInfo20.size()).c_str()); } public: //战场名 const std::string m_station; //道岔名 const std::string m_mo; //转辙机名 const std::string m_mp; // const std::string taskid; std::string name1; std::string name2; std::string name3; std::string direct1; std::string direct2; std::string mo_name; std::string mp_name; //0通道数据 std::map map_resist_idx00; //毫秒数, 阻力值 std::map map_resist_idx01; std::map map_resist_idx02; std::map m_mapSecondStatInfo00; std::map m_mapSecondStatInfo01; std::map m_mapSecondStatInfo02; //1通道数据 std::map map_resist_idx10; std::map map_resist_idx11; std::map map_resist_idx12; std::map m_mapSecondStatInfo10; std::map m_mapSecondStatInfo11; std::map m_mapSecondStatInfo12; //2通道数据 std::map map_resist_idx20; std::map map_resist_idx21; std::map map_resist_idx22; std::map m_mapSecondStatInfo20; std::map m_mapSecondStatInfo21; std::map m_mapSecondStatInfo22; std::mutex m_mtx; COleDateTime m_odt_data0; COleDateTime m_odt_data1; COleDateTime m_odt_data2; //心跳时间 CTime m_ctUpdateTime = 0; SENSOR_STATUS m_sensor_status[9][2]; time_t m_tmMoveDetectTime0 = 0; time_t m_tmMoveDetectTime1 = 0; time_t m_tmMoveDetectTime2 = 0; time_t m_tmLastActive; private: static void InsertData(std::map& map, time_t tTime, int val); inline static void InsertData(std::map& mapSecondStatInfo, time_t tTime, int val) { time_t tt = tTime / 1000; //换算成秒数 if (mapSecondStatInfo[tt].first_val == INT_MIN) { mapSecondStatInfo[tt].first_val = val; //存储第一个值 } auto& it = mapSecondStatInfo[tt]; if (val > it.max_val) { it.max_val = val; it.max_time = tTime; } if (val < it.min_val) { it.min_val = val; it.min_time = tTime; } it.dif_val = it.max_val - it.min_val; it.sum_val += val; it.cout++; it.end_val = val; } inline static bool CalcBInsertData(std::map& mapSecondStatInfo0, std::map& mapSecondStatInfo1, std::map& mapSecondStatInfo2, time_t* time, int* data0, int* data1, int* data2) { if (mapSecondStatInfo0.size() < 2) return false; //for (auto it = mapSecondStatInfo0.crbegin(); it != mapSecondStatInfo0.crend(); ++it) { // TRACE(fmt::format("{}:{}", it->first, it->second.dif_val).c_str()); //} auto it0 = mapSecondStatInfo0.crbegin(); auto it1 = mapSecondStatInfo1.crbegin(); auto it2 = mapSecondStatInfo2.crbegin(); if (it0->second.dif_val < 100 && it1->second.dif_val < 100 && it2->second.dif_val < 100) return false; //无波动 if (it0->second.dif_val > 100) { auto it = it0; it++; if (it->second.dif_val < 100 && it0->first - it->first > 2 && it0->first - it->first < 60) //前面无波动 相隔时差 大于2秒 小于 60秒 { *time = it0->first * 1000 - 20; *data0 = (++it0)->second.end_val; *data1 = (++it1)->second.end_val; *data2 = (++it2)->second.end_val; return true; } } else if (it1->second.dif_val > 100) { auto it = it1; it++; if (it->second.dif_val < 100 && it1->first - it->first > 2 && it1->first - it->first < 60) //前面无波动 相隔时差 大于2秒 小于 60秒 { *time = it1->first * 1000 - 20; *data0 = (++it0)->second.end_val; *data1 = (++it1)->second.end_val; *data2 = (++it2)->second.end_val; return true; } } else if (it2->second.dif_val > 100) { auto it = it2; it++; if (it->second.dif_val < 100 && it2->first - it->first > 2 && it2->first - it->first < 60) //前面无波动 相隔时差 大于2秒 小于 60秒 { *time = it2->first * 1000 - 20; *data0 = (++it0)->second.end_val; *data1 = (++it1)->second.end_val; *data2 = (++it2)->second.end_val; return true; } } return false; } }; class CDeviceMng { private: CDeviceMng(); ~CDeviceMng(); public: static inline CDeviceMng* Instance() { return &obj; }; void LoadDevice(); bool Insert(CDevice*); CDevice* Find(std::string taskid); BOOL IsDeviceOnline(std::string taskid, int interval = 180000); //默认3分钟判断是否在线 private: static CDeviceMng obj; public: std::mutex m_mtx; //imei std::map m_map_devices; };