#pragma once #include #include #include #include #include "AlarmDefine.h" #ifdef DEBUG_202 #define MAX_SAVE_TIME_MILLI 259200000 //十分钟 #define MAX_SAVE_TIME_SECOND 259200 //五分钟 #else //缓冲数据 1小时 毫秒 #define MAX_SAVE_TIME_MILLI 300000 //十分钟 #define MAX_SAVE_TIME_SECOND 300 //五分钟 #endif // DEBUG_202 enum class SENSOR_STATUS : int8_t { UNKONW = -1, ABNORMAL = 0, NORMAL = 1, HFDISTURB = 2,//高频干扰 FIXEDVALUE = 3 //固定值异常 }; class CDevice { public: CDevice(); virtual ~CDevice(); void Insert(int index, time_t time, int data0, int data1, int data2); // 插入设备的状态信息,数据来自push_online指令 bool InsertStatus(const SENSOR_STATUS st[9][2], const int dt[9][2]); //调用Insert数据插入完 来判断是否需要插入数据 返回false 不需要 返回true 需要 inline bool CalcBInsertData(int index, time_t* time, int* data0, int* data1, int* data2) { lock_guard lock(m_mtx); 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(); std::map* GetMapData(uint8_t idx, uint8_t no); std::map* GetStatInfo(uint8_t idx, uint8_t no); BOOL IsDeviceOnline(uint8_t idx, time_t tmNow, int inteval); 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 bool 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, uint8_t nNewNum, int bMakeup = false) { bool bSave = true; auto tmStartTimeSecond = tmStartTime / 1000; //TRACE("%s:%d %s\r\n", __FUNCTION__, __LINE__, CTime(tmStartTime / 1000).Format("%Y-%m-%d %H:%M:%S")); lock_guard lock(m_mtx); if (nNewNum == 1 && tmStartTimeSecond % 3600 != 0) { switch (idx) { case 0: time(&m_tmUpdateTime0); if (m_mapSecondStatInfo00.size()) { if (m_mapSecondStatInfo00.rbegin()->second.dif_val < 100 && m_mapSecondStatInfo01.rbegin()->second.dif_val < 100 && m_mapSecondStatInfo02.rbegin()->second.dif_val < 100 && abs(m_mapSecondStatInfo00.rbegin()->second.min_val - stSS1.min_val) < 100 && abs(m_mapSecondStatInfo01.rbegin()->second.min_val - stSS2.min_val) < 100 && abs(m_mapSecondStatInfo02.rbegin()->second.min_val - stSS3.min_val) < 100) { bSave = false; break; } } map_resist_idx00[tmStartTime] = data0[0]; map_resist_idx01[tmStartTime] = data1[0]; map_resist_idx02[tmStartTime] = data2[0]; m_mapSecondStatInfo00[tmStartTimeSecond] = stSS1; m_mapSecondStatInfo01[tmStartTimeSecond] = stSS2; m_mapSecondStatInfo02[tmStartTimeSecond] = stSS3; break; case 1: time(&m_tmUpdateTime1); if (m_mapSecondStatInfo10.size()) { if (m_mapSecondStatInfo10.rbegin()->second.dif_val < 100 && m_mapSecondStatInfo11.rbegin()->second.dif_val < 100 && m_mapSecondStatInfo12.rbegin()->second.dif_val < 100 && abs(m_mapSecondStatInfo10.rbegin()->second.min_val - stSS1.min_val) < 100 && abs(m_mapSecondStatInfo11.rbegin()->second.min_val - stSS2.min_val) < 100 && abs(m_mapSecondStatInfo12.rbegin()->second.min_val - stSS3.min_val) < 100) { bSave = false; break; } } map_resist_idx10[tmStartTime] = data0[0]; map_resist_idx11[tmStartTime] = data1[0]; map_resist_idx12[tmStartTime] = data2[0]; m_mapSecondStatInfo10[tmStartTimeSecond] = stSS1; m_mapSecondStatInfo11[tmStartTimeSecond] = stSS2; m_mapSecondStatInfo12[tmStartTimeSecond] = stSS3; break; case 2: time(&m_tmUpdateTime2); if (m_mapSecondStatInfo20.size()) { if (m_mapSecondStatInfo20.rbegin()->second.dif_val < 100 && m_mapSecondStatInfo21.rbegin()->second.dif_val < 100 && m_mapSecondStatInfo22.rbegin()->second.dif_val < 100 && abs(m_mapSecondStatInfo20.rbegin()->second.min_val - stSS1.min_val) < 100 && abs(m_mapSecondStatInfo21.rbegin()->second.min_val - stSS2.min_val) < 100 && abs(m_mapSecondStatInfo22.rbegin()->second.min_val - stSS3.min_val) < 100) { bSave = false; break; } } map_resist_idx20[tmStartTime] = data0[0]; map_resist_idx21[tmStartTime] = data1[0]; map_resist_idx22[tmStartTime] = data2[0]; m_mapSecondStatInfo20[tmStartTimeSecond] = stSS1; m_mapSecondStatInfo21[tmStartTimeSecond] = stSS2; m_mapSecondStatInfo22[tmStartTimeSecond] = stSS3; break; default: ASSERT(0); bSave = false; break; } } else { switch (idx) { case 0: { time(&m_tmUpdateTime0); for (auto i = 0; i < len; i++) { if (result[i] == false) continue; const auto tt = tmStartTime + i * step; map_resist_idx00[tt] = data0[i]; map_resist_idx01[tt] = data1[i]; map_resist_idx02[tt] = data2[i]; } m_mapSecondStatInfo00[tmStartTimeSecond] = stSS1; m_mapSecondStatInfo01[tmStartTimeSecond] = stSS2; m_mapSecondStatInfo02[tmStartTimeSecond] = stSS3; //time(&m_tmMoveDetectTime0);//暂时不知道为啥赋值,先注释 2024年5月12日 这个时间20秒未更新,计算扳动数据 if (!bMakeup) { { 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: { time(&m_tmUpdateTime1); for (auto i = 0; i < len; i++) { if (result[i] == false) continue; const auto tt = tmStartTime + i * step; map_resist_idx10[tt] = data0[i]; map_resist_idx11[tt] = data1[i]; map_resist_idx12[tt] = data2[i]; } m_mapSecondStatInfo10[tmStartTimeSecond] = stSS1; m_mapSecondStatInfo11[tmStartTimeSecond] = stSS2; m_mapSecondStatInfo12[tmStartTimeSecond] = stSS3; //time(&m_tmMoveDetectTime1);//暂时不知道为啥赋值,先注释 2024年5月12日 if (!bMakeup) { { 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: { time(&m_tmUpdateTime2); for (auto i = 0; i < len; i++) { if (result[i] == false) continue; const auto tt = tmStartTime + i * step; map_resist_idx20[tt] = data0[i]; map_resist_idx21[tt] = data1[i]; map_resist_idx22[tt] = data2[i]; } m_mapSecondStatInfo20[tmStartTimeSecond] = stSS1; m_mapSecondStatInfo21[tmStartTimeSecond] = stSS2; m_mapSecondStatInfo22[tmStartTimeSecond] = stSS3; //time(&m_tmMoveDetectTime2);//暂时不知道为啥赋值,先注释 2024年5月12日 if (!bMakeup) { { 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); bSave = false; 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()); return bSave; } bool IsHaveTemp()const { return m_nTemperature != INT_MIN; } bool IsHaveHumi()const { return m_nHumidity != INT_MIN; } public: //设备唯一号 std::string imei; //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; int m_nTemperature = INT_MIN; int m_nHumidity = INT_MIN; inline time_t GetUpdateTime(uint8_t idx) { switch (idx) { case 0: return m_tmUpdateTime0; case 1: return m_tmUpdateTime1; case 2: return m_tmUpdateTime2; default: ASSERT(0); return 0; } } private: //最后数据时间 系统时间,用来判断是否在线 time_t m_tmUpdateTime0 = time(0); time_t m_tmUpdateTime1 = time(0); time_t m_tmUpdateTime2 = time(0); private: inline static void InsertData(std::map& map, time_t time, int val) { if (map.size() >= 2) { auto it = map.end(); auto last = --it; auto second_last = --it; if (time / 1000 == last->first / 1000 && second_last->first / 1000 == time / 1000) { if (abs(last->second - val) <= 30 && abs(second_last->second - val) <= 30 && abs(last->second - second_last->second) <= 30) { #ifdef _DEBUG TRACE("%d:%d.%d\r\n", time % 100000, last->first % 100000, (time - last->first) % 1000); #endif // _DEBUG //都相等 先删除 map.erase(last); } } else if (last->first == second_last->first + 980 && abs(last->second - second_last->second) <= 30) { map.erase(last); } map[time] = val; } else { map[time] = val; } auto it = map.begin(); if ((time - it->first) > MAX_SAVE_TIME_MILLI) map.erase(it); } 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; }; CDevice* Insert(std::string imei); CDevice* Find(std::string imei); BOOL IsDeviceOnline(std::string imei, int8_t idx, int interval = 180); //默认3分钟判断是否在线 private: static CDeviceMng obj; public: std::mutex m_mtx; //imei std::map m_map_devices; };