瀏覽代碼

保持力异常报警修改,未测试。

git-svn-id: https://202.107.226.68:8443/svn/Services/ResistanceMonitor@6 a05970a1-87b9-9d4f-9ee5-fa77e2ec115b
shenchunzhong 1 年之前
父節點
當前提交
8a5bcc4908
共有 8 個文件被更改,包括 277 次插入10 次删除
  1. 1 1
      4.Data/AppService.cpp
  2. 5 0
      4.Data/HttpPrcess.cpp
  3. 0 1
      4.Data/MGDataHandler.cpp
  4. 1 0
      4.Data/MonitorObject.h
  5. 224 5
      4.Data/ResistAlarm.cpp
  6. 16 2
      4.Data/ResistAlarm.h
  7. 1 1
      inc/AlarmDefine.h
  8. 29 0
      inc/ZlDataDefine.h

+ 1 - 1
4.Data/AppService.cpp

@@ -271,7 +271,7 @@ bool CAppService::Start()
 		ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
 		if (true != ret)
 		{
-			sql = "ALTER TABLE [rm_map] ADD [zzjno] int ;";
+			sql = "ALTER TABLE [rm_map] ADD [zzjno] int default 0 ;";
 			ret = CDBConnectPool::Instance()->DBExecuteSQL(sql);
 
 			sql = "WITH CTE AS ( SELECT [zzjno], ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNum FROM [rm_map] ) UPDATE CTE SET [zzjno] = RowNum;\

+ 5 - 0
4.Data/HttpPrcess.cpp

@@ -660,11 +660,16 @@ int DealGetRetesionForce(const httplib::Request& req, const string token, char**
 			yyjson_mut_obj_add_int(doc, root, "dw_alarm_low_drop", pInfo->dw_alarm_low_drop);
 		else
 			yyjson_mut_obj_add_null(doc, root, "dw_alarm_low_drop");
+		yyjson_mut_obj_add_int(doc, root, "alarm_low_percent", pInfo->alarm_low_percent);
+		yyjson_mut_obj_add_int(doc, root, "alarm_high_percent", pInfo->alarm_high_percent);
 	}
 	else
 	{
+		ASSERT(FALSE);
 		yyjson_mut_obj_add_bool(doc, root, "enable", false);
 		yyjson_mut_obj_add_null(doc, root, "dw_alarm_low_drop");
+		yyjson_mut_obj_add_null(doc, root, "alarm_low_percent");
+		yyjson_mut_obj_add_null(doc, root, "alarm_high_percent");
 	}
 
 	*json = yyjson_mut_write(doc, 0, json_len);

+ 0 - 1
4.Data/MGDataHandler.cpp

@@ -538,7 +538,6 @@ int CMGDataHandler::HandleConfRead(string tag, string type, yyjson_mut_doc* doc,
 	{
 		auto pInfo = CMonitorObjectMng::Instance()->GetMoMpInfo(tag);
 		if (pInfo == nullptr) return 404;
-		char utf[200];
 		if (pInfo->name1.length())
 			yyjson_mut_arr_add_strcpy(doc, conf, pInfo->name1utf.c_str());
 		else

+ 1 - 0
4.Data/MonitorObject.h

@@ -45,6 +45,7 @@ public:
 	//DAOCHA_POSITION epos = DAOCHA_POSITION::MP_UNKNOWN;
 	std::map<time_t, DAOCHA_POSITION> mapPos;
 
+	int m_nPowerZeroOffset = 0;	//×èÁ¦ÁãÖµ²¹³¥
 	
 	~ST_MOMP_INFO(){
 		check = 0x00;

+ 224 - 5
4.Data/ResistAlarm.cpp

@@ -1185,7 +1185,7 @@ void CResistAlarmMng::JudgeAlarm(CResistAlarmMng* pService, RETENSION_FORCE_DROP
 								ctAlarmTime.GetAsSystemTime(pAlarm->recoveryTime);
 							}
 
-							g_p315ClientManager->GetTcpClient()->SendAlarmData(zzjno, 2, CTime(pAlarmInfo->time).GetTime(), alarm_time / 1000,
+							g_p315ClientManager->GetTcpClient()->SendAlarmData(zzjno, 2, CTime(pAlarmInfo->time).GetTime(), ctAlarmTime.GetTime(),
 								pAlarmInfo->type, posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT, pAlarmInfo->level, pAlarm->loworhigh,
 								TIEDA_ACQ_VALUE(pAlarm->val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), TIEDA_ACQ_VALUE(pAlarm->refer_val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), 0);
 						}
@@ -1284,6 +1284,199 @@ void CResistAlarmMng::JudgeAlarm(CResistAlarmMng* pService, RETENSION_FORCE_DROP
 	}
 }
 
+void CResistAlarmMng::JudgeAlarm(CResistAlarmMng* pService, RETENSION_FORCE_DROP* pConstRetensionForceWaveInfo, 
+	time_t show_time, int show_val, eSuoBiPosi posi, string mo, string mp, uint32_t zzjno, void* pInfo)
+{
+	ASSERT(pConstRetensionForceWaveInfo);
+	ST_MOMP_INFO* pMoMpInfo = (ST_MOMP_INFO*)pInfo;
+	CTime ctShowTime(show_time / 1000);
+	bool bSkylight = CSkylightMng::GetInstance()->IsSkylight(&ctShowTime);
+	int nOldVal = 0;
+	if (bSkylight && show_val == 0)
+	{
+		if (posi == eSuoBiPosi::SB_FIX)
+		{
+			pMoMpInfo->fix_const_retension_force = INT_MIN;
+		}
+		else
+		{
+			pMoMpInfo->invert_const_retension_force = INT_MIN;
+		}
+	}
+	else
+	{
+		if (posi == eSuoBiPosi::SB_FIX)
+		{
+			nOldVal = pMoMpInfo->fix_const_retension_force;
+			if (nOldVal == INT_MIN)
+			{
+				pMoMpInfo->fix_const_retension_force = show_val;
+				return;
+			}
+		}
+		else
+		{
+			nOldVal = pMoMpInfo->invert_const_retension_force;
+			if (nOldVal == INT_MIN)
+			{
+				pMoMpInfo->invert_const_retension_force = show_val;
+				return;
+			}
+
+		}
+	}
+	ASSERT(pConstRetensionForceWaveInfo);
+	if (pConstRetensionForceWaveInfo->enable == false) return;
+
+	if (nOldVal != INT_MIN)
+	{
+		int nRatio = show_val * 100 / nOldVal;
+		eLowHigh loworhigh = eLowHigh::LH_UNKNOWN;
+		int alarm_refer = 0;
+		if (nOldVal != 0)
+		{
+			//下降20%或上升40% 进行预警
+			if (pConstRetensionForceWaveInfo->dw_alarm_low_drop != INT_MIN && nRatio <= (100 - pConstRetensionForceWaveInfo->dw_alarm_low_drop))
+			{
+				loworhigh = eLowHigh::LH_LOW;
+				alarm_refer = nOldVal * (100 - pConstRetensionForceWaveInfo->dw_alarm_low_drop) / 100;
+			}
+			else if (nRatio >= (100 + pConstRetensionForceWaveInfo->alarm_high_percent))
+			{
+				loworhigh = eLowHigh::LH_HIGH;
+				alarm_refer = nOldVal * (100 + pConstRetensionForceWaveInfo->alarm_high_percent) / 100;
+			}
+		}
+
+		ALARM_INFO* pAlarmInfo = nullptr;
+		CTime ctAlarmTime(show_time / 1000);
+		bool bNew = false;
+		//产生预警
+		if (loworhigh != eLowHigh::LH_UNKNOWN)
+		{
+			//查找是否原有的报警已存在
+			int level = 0;// 预警
+			{
+				std::lock_guard<mutex> lock(pService->m_mtxAlarm);
+				for (const auto& alarm : pService->m_lstUnConfirmAlarm)
+				{
+					if (alarm->no == (uint8_t)posi && alarm->type == eZL_ALARMTYPE::RETENSION_FORCE
+						&& level == alarm->level && alarm->recoveryTime.wYear < 2000 //预警和报警单独计算
+						&& alarm->mo.compare(mo) == 0 && alarm->mp.compare(mp) == 0)
+					{
+						pAlarmInfo = alarm;
+						break;
+					}
+				}
+			}
+
+			if (pAlarmInfo == nullptr)
+			{
+				bNew = true;
+				pAlarmInfo = new ALARM_INFO;
+				pAlarmInfo->event_id = hjfunc_GetGUID();
+				pAlarmInfo->id = ++pService->m_nAlarmID;
+				pAlarmInfo->level = level;// 预警
+				pAlarmInfo->mo = mo;
+				pAlarmInfo->mp = mp;
+				pAlarmInfo->no = (uint8_t)posi;
+				ctAlarmTime.GetAsSystemTime(pAlarmInfo->time);
+				pAlarmInfo->time.wMilliseconds = show_time % 1000;
+				pAlarmInfo->type = eZL_ALARMTYPE::RETENSION_FORCE;
+				pAlarmInfo->val = show_val;
+				pAlarmInfo->refer_val = alarm_refer;
+				pAlarmInfo->posi = (posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT);
+				pAlarmInfo->loworhigh = loworhigh;
+				pAlarmInfo->zzjno = zzjno;
+				pAlarmInfo->sunroof = CSkylightMng::GetInstance()->IsSkylight(&pAlarmInfo->time);
+				char szInfo[200] = { 0 };
+				sprintf_s(szInfo, sizeof(szInfo), "保持力异常报警,位置:%s, 报警值为%dN, 上一次值:%dN, 参考值为%dN",
+					posi == eSuoBiPosi::SB_FIX ? "定位" : "反位", show_val, nOldVal, alarm_refer);
+
+				pAlarmInfo->desc = szInfo;
+				lock_guard<mutex> lock(pService->m_mtxAlarm);
+				pService->m_lstUnConfirmAlarm.push_back(pAlarmInfo);
+			}
+
+			//主动推送315
+			if (bNew)
+			{
+				g_p315ClientManager->GetTcpClient()->SendAlarmData(zzjno, 1, CTime(pAlarmInfo->time).GetTime(), 0xFFFFFFFF,
+					pAlarmInfo->type, posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT, pAlarmInfo->level, loworhigh,
+					TIEDA_ACQ_VALUE(pAlarmInfo->val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), TIEDA_ACQ_VALUE(pAlarmInfo->refer_val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), 0);
+			}
+
+
+			if (bNew) 
+			{
+				CString sql;
+				sql.Format("INSERT INTO [rm_alarm]([ID],[mo],[mp],[no],[type],[occur_time],[level],[desc],[suggest],[val],[event_id],[rel_id],posi,loworhigh,referval,[sunroof]) "\
+					"VALUES(%d, '%s', '%s', %d, %d, '%s', %d, '%s', '%s', %d, '%s', '%s',%d,%d,%d,%d);",
+					pAlarmInfo->id, pAlarmInfo->mo.c_str(), pAlarmInfo->mp.c_str(), pAlarmInfo->no, pAlarmInfo->type,
+					ctAlarmTime.Format("%Y-%m-%d %H:%M:%S"), pAlarmInfo->level, pAlarmInfo->desc.c_str(), pAlarmInfo->suggest.c_str(), pAlarmInfo->val,
+					pAlarmInfo->event_id.c_str(), pAlarmInfo->rel_id.c_str(), uint8_t(pAlarmInfo->posi), uint8_t(pAlarmInfo->loworhigh), pAlarmInfo->refer_val,
+					pAlarmInfo->sunroof);
+
+				if (false == CDBConnectPool::Instance()->DBExecuteSQL(sql))
+					CSimpleLog::Error("执行语句失败" + sql);
+				else
+				{
+					uint8_t* pack = nullptr; int len = 0;
+					auto packno = CResistAlarmMng::GeneralNewAlarmData(pAlarmInfo, &pack, &len);
+					if (packno) CSuperManager::Instance()->SendPack(pack, len, packno, E_ZL_PROTOCAL::ZL_ALARM_DATA, true);
+					delete[] pack;
+					pack = nullptr;
+				}
+			}
+		}
+		else
+		{
+			//恢复
+			{
+				std::lock_guard<mutex> lock(pService->m_mtxAlarm);
+				for (auto it = pService->m_lstUnConfirmAlarm.begin(); it != pService->m_lstUnConfirmAlarm.end();)
+				{
+					auto pAlarm = *it;
+					if (pAlarm->no == (uint8_t)posi && pAlarm->type == eZL_ALARMTYPE::RETENSION_FORCE && pAlarm->recoveryTime.wYear < 2000 //预警和报警单独计算
+						&& pAlarm->mo.compare(mo) == 0 && pAlarm->mp.compare(mp) == 0)
+					{
+						pAlarmInfo = pAlarm;
+						if (pAlarmInfo)
+						{
+							//恢复
+							//1. 更新数据库
+							//2. 更新内存数据
+							//3. 上送恢复消息
+							if (ctAlarmTime.GetTime() == 0) ctAlarmTime = CTime::GetCurrentTime();
+							string recovery_time = ctAlarmTime.Format("%Y-%m-%d %H:%M:%S");
+							CString sql;
+							sql.Format("UPDATE [rm_alarm] SET [recovery_time]='%s' WHERE ID = %d;", recovery_time.c_str(), pAlarmInfo->id);
+							CDBConnectPool::Instance()->DBExecuteSQL(sql);
+
+							if (pAlarmInfo->ack_result == 1)
+							{
+								it = pService->m_lstUnConfirmAlarm.erase(it);
+								continue;
+							}
+							else
+							{
+								ctAlarmTime.GetAsSystemTime(pAlarm->recoveryTime);
+							}
+
+							g_p315ClientManager->GetTcpClient()->SendAlarmData(zzjno, 2, CTime(pAlarmInfo->time).GetTime(), ctAlarmTime.GetTime(),
+								pAlarmInfo->type, posi == eSuoBiPosi::SB_FIX ? eDaoChaPosi::DCP_FIX : eDaoChaPosi::DCP_INVERT, pAlarmInfo->level, pAlarm->loworhigh,
+								TIEDA_ACQ_VALUE(pAlarm->val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), TIEDA_ACQ_VALUE(pAlarm->refer_val, TIEDA_VAL_STATE::TVS_AFTER_MOVE), 0);
+						}
+					}
+					it++;
+				}
+			}
+			return;
+
+		}
+	}
+}
+
 void CResistAlarmMng::JudgeAlarm1(CResistAlarmMng* pService, RETENSION_FORCE_DROP* pRetensionForceDropInfo, time_t show_time, int show_val, 
 	eSuoBiPosi posi, string mo, string mp, uint32_t zzjno)
 {
@@ -2190,6 +2383,13 @@ void CResistAlarmMng::ThreadProcAlarmSet(DWORD_PTR param)
 				else
 					continue;
 
+				//zzj位置是否变化
+				bool bEPOSChanged = CMonitorObjectMng::Instance()->IsZZJEPOSChanged(momp,
+					(eSuoBiPosi)pAlarmSet->no == eSuoBiPosi::SB_FIX ? DAOCHA_POSITION::MP_FIX : DAOCHA_POSITION::MP_INVERT, tt);
+
+				//位置变化后不能使用
+				if (bEPOSChanged) continue;
+
 				int  nMinVal = INT_MAX;
 				time_t tMinTime = 0;
 				{
@@ -2220,6 +2420,9 @@ void CResistAlarmMng::ThreadProcAlarmSet(DWORD_PTR param)
 				if (nMinVal != INT_MAX)
 					JudgeAlarm(pService, pAlarmSet, tMinTime, nMinVal, (eSuoBiPosi)pAlarmSet->no, pInfo->mo, pInfo->mp, pInfo->zzjno);
 			}
+
+			//清理无效位置
+			CMonitorObjectMng::Instance()->ClearZZJHistroyEPOS(tt);
 		}
 
 	} while (pService->m_bWork);
@@ -2689,6 +2892,22 @@ void CResistAlarmMng::ThreadProcMove(DWORD_PTR param)
 					auto pFixSuobiOverInfo = (SUOBI_OVER_LIMIT_INFO*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_FIX, eZL_ALARMTYPE::SUOBI_LOCK_LIMIT);
 					//反位
 					auto pInvertSuobiOverInfo = (SUOBI_OVER_LIMIT_INFO*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_INVERT, eZL_ALARMTYPE::SUOBI_LOCK_LIMIT);
+
+					//定位保持力报警设置项
+					auto pFixConstRetensionForceWaveInfo = (RETENSION_FORCE_DROP*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_FIX, eZL_ALARMTYPE::RETENSION_FORCE);
+					if (pFixConstRetensionForceWaveInfo == nullptr)//默认开启
+					{
+						pFixConstRetensionForceWaveInfo = new RETENSION_FORCE_DROP;
+						pService->Insert(mo, mp, (uint8_t)eSuoBiPosi::SB_FIX, (uint8_t)eZL_ALARMTYPE::RETENSION_FORCE, pFixConstRetensionForceWaveInfo);
+					}
+					//反位
+					auto pInvertConstRetensionForceWaveInfo = (RETENSION_FORCE_DROP*)pService->Find(mo, mp, (uint8_t)eSuoBiPosi::SB_INVERT, eZL_ALARMTYPE::RETENSION_FORCE);
+					if (pInvertConstRetensionForceWaveInfo == nullptr)//默认开启
+					{
+						pInvertConstRetensionForceWaveInfo = new RETENSION_FORCE_DROP;
+						pService->Insert(mo, mp, (uint8_t)eSuoBiPosi::SB_INVERT, (uint8_t)eZL_ALARMTYPE::RETENSION_FORCE, pInvertConstRetensionForceWaveInfo);
+					}
+
 					//获取报警设置 end
 
 					eDaoChaPosi posiLock0;
@@ -2710,7 +2929,7 @@ void CResistAlarmMng::ThreadProcMove(DWORD_PTR param)
 							CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0,
 								(int)it.second, show_val, i, (uint8_t)eDaoChaPosi::DCP_FIX, (uint8_t)ePowerName::PN_RETENTION, fmt::format("保持力:{}", show_val));
 
-							//JudgeAlarm(pService, pFixSuobiOverInfo, it.first, show_val, eSuoBiPosi::SB_FIX, mo, mp, zzjno);
+							JudgeAlarm(pService, pFixConstRetensionForceWaveInfo, it.first, show_val, eSuoBiPosi::SB_FIX, mo, mp, pMompInfo->zzjno, pMompInfo);
 						}
 
 						for (auto& it : maxlock1)
@@ -2728,7 +2947,7 @@ void CResistAlarmMng::ThreadProcMove(DWORD_PTR param)
 							CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0,
 								(int)it.second, show_val, i, (uint8_t)eDaoChaPosi::DCP_INVERT, (uint8_t)ePowerName::PN_RETENTION, fmt::format("保持力:{}", show_val));
 
-							//JudgeAlarm(pService, pFixSuobiOverInfo, it.first, show_val, eSuoBiPosi::SB_FIX, mo, mp, zzjno);
+							JudgeAlarm(pService, pInvertConstRetensionForceWaveInfo, it.first, show_val, eSuoBiPosi::SB_FIX, mo, mp, pMompInfo->zzjno, pMompInfo);
 						}
 
 					}
@@ -2750,7 +2969,7 @@ void CResistAlarmMng::ThreadProcMove(DWORD_PTR param)
 							CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0, (int)it.second, show_val, i,
 								(uint8_t)eDaoChaPosi::DCP_INVERT, (uint8_t)ePowerName::PN_RETENTION, fmt::format("保持力:{}", show_val));
 
-							//JudgeAlarm(pService, pInvertSuobiOverInfo, it.first, show_val, eSuoBiPosi::SB_INVERT, mo, mp, zzjno);
+							JudgeAlarm(pService, pInvertConstRetensionForceWaveInfo, it.first, show_val, eSuoBiPosi::SB_INVERT, mo, mp, pMompInfo->zzjno);
 						}
 
 						for (auto& it : maxlock1)
@@ -2768,7 +2987,7 @@ void CResistAlarmMng::ThreadProcMove(DWORD_PTR param)
 							CResistAlarmMng::InsertToDBByMove(mo, mp, it.first, 0, 0, (int)it.second, show_val, i,
 								(uint8_t)eDaoChaPosi::DCP_FIX, (uint8_t)ePowerName::PN_RETENTION, fmt::format("保持力:{}", show_val));
 
-							//JudgeAlarm(pService, pFixSuobiOverInfo, it.first, show_val, eSuoBiPosi::SB_FIX, mo, mp, zzjno);
+							JudgeAlarm(pService, pFixConstRetensionForceWaveInfo, it.first, show_val, eSuoBiPosi::SB_FIX, mo, mp, pMompInfo->zzjno, pMompInfo);
 						}
 
 					}

+ 16 - 2
4.Data/ResistAlarm.h

@@ -69,7 +69,17 @@ typedef struct tagConvertResist_Over_Limit : public tagBaseInfo
 
 typedef struct tagRetension_Force_Drop : public  tagBaseInfo
 {
-	int dw_alarm_low_drop = INT_MIN;    //下降报警值
+	int dw_alarm_low_drop = INT_MIN;    //最低预警值
+	int alarm_low_percent = 20;    //下降百分比报警值
+	int alarm_high_percent = 40;    //上升百分比报警值
+
+	time_t tLastCalc = 0;				//上一次计算时间(不参与配置)   //是不是可以用 tmLastCheckTime
+
+	tagRetension_Force_Drop()
+	{
+		enable = true;
+	}
+
 }RETENSION_FORCE_DROP;
 
 //有string 不能拷贝
@@ -116,7 +126,7 @@ inline string GetAlarmName(eZL_ALARMTYPE id)
 	case eZL_ALARMTYPE::SUOBI_LOCK_LIMIT:
 		return "锁闭力超限";
 	case eZL_ALARMTYPE::RETENSION_FORCE:
-		return "保持力下降告警";
+		return "保持力异常告警";
 	default:
 		return "未知";
 	}
@@ -209,6 +219,10 @@ private:
 	static void JudgeAlarm1(CResistAlarmMng* pService, RETENSION_FORCE_DROP* pRetensionForceDropInfo,
 		time_t show_time, int show_val, eSuoBiPosi posi, string mo, string mp, uint32_t zzjno);
 
+	//判断报警,且保存数据
+	static void JudgeAlarm(CResistAlarmMng* pService, RETENSION_FORCE_DROP* pConstRetensionForceWaveInfo,
+		time_t show_time, int show_val, eSuoBiPosi posi, string mo, string mp, uint32_t zzjno, void* pMoMpInfo);
+
 	//报警规则检测线程
 	static void ThreadProcAlarmSet(DWORD_PTR);
 	//设备报警检测线程

+ 1 - 1
inc/AlarmDefine.h

@@ -47,7 +47,7 @@ enum class eZL_ALARMTYPE : uint8_t
 	FRICTION_OVER_LIMIT = 0x02, //칡꼰제낚掘
 	SUOBI_LOCK_LIMIT = 0x04,   //傑균제낚掘
 	CONVERT_LIMIT = 0x05,		//瘻뻣羸제낚掘
-	RETENSION_FORCE = 0x06,     //괏넣제苟슉멩쒸
+	RETENSION_FORCE = 0x06,     //괏넣제嫩끽멩쒸
 
 	//�구잚괩쒸
 	EQUIP_OFFLINE = 0x20,	//�구잼窟

+ 29 - 0
inc/ZlDataDefine.h

@@ -173,4 +173,33 @@ public:
 
 };
 
+
+//阻力零值补偿
+template<typename T>
+bool OffsetPowerCurve(T& mapData, int offset)
+{
+	if (!offset || mapData.empty())
+		return false;
+
+	auto tFirst = mapData.begin()->first;
+	int count = mapData.size();
+
+	int avr = 0, sum = 0;
+	int cnt = 0;
+	//计算前1秒内的平均值
+	for (auto i = mapData.begin(); i != mapData.end() && i->first < tFirst + 1000; ++i, ++cnt)
+	{
+		sum += i->second;
+		avr = sum / (cnt + 1);
+	}
+	if (avr == 0) return false;
+
+	int zero = avr;
+	for (auto i = mapData.begin(); i != mapData.end(); ++i)
+	{
+		i->second = (WORD)(short)((short)i->second - zero + offset);
+	}
+
+	return true;
+}
 #endif