#!/users/dsc/binp/Python3 #-*-coding: UTF-8 -*- from datetime import datetime from tokenize import Double from comlib.shm.MemMap import MemMap import logging as d from comlib.shm.Serialization import Serialization import struct import pandas as pd import numpy as np from glitch.alarm_info import AlarmInfo from glitch.GlitchDetector import GlitchDetector from datetime import datetime class GM: def __init__(self): self.mm = MemMap('ZONE20', 16008) self.serializtion=Serialization("2000dii") self.alarm_info=AlarmInfo() self.limit_down=0 self.limit_up=0 self.current_value=0 self.kurtosis_threshold=15#阈值 baseline_kurtosis的倍数 self.detector = GlitchDetector(kurtosis_threshold=self.kurtosis_threshold) self.baseline_kurtosis=0.08#正常数据的峰度(绝对值) self.last_alarm_time={} self.now_time=datetime.now() self.AlarmIntervalHours=1 #最小报警时间间隔 小时 def dispose(self,ruleid:str,rulename:str,alarm_content:str,stime,endtime,th:float): self.now_time=datetime.now() d.info("----dispose---") res=self.mm[ruleid] if res is None: d.error(f"MemMap not find key '{ruleid}' !") d.debug("|ruleid|"+res.key) data_value=self.serializtion.deserialize(res.value) d_n=data_value[-2] dataX=data_value[:data_value[-2]] self.df=pd.DataFrame(data=dataX) is_alarm=self.detection(dataX=dataX,th=th) if is_alarm: # alarm_content=alarm_content+" 当前值:"+format(self.result["current_kurtosis"],'.3f')+" 合理区间:["+format(-self.baseline_kurtosis*self.kurtosis_threshold,'.3f')+","+format(self.baseline_kurtosis*self.kurtosis_threshold,'.3f')+"]" alarm_result=self.alarm_info.build_alarm(ruleid=ruleid,rulename=rulename, alarm_content=alarm_content, stime=stime/1000,etime=endtime/1000) d.debug(alarm_result) if self.check_last_alarm_time(ruleid)==False: d.debug(self.last_alarm_time[ruleid].strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]) return None d.debug("Alarm!"+self.last_alarm_time[ruleid].strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]) return alarm_result return None def detection(self,dataX,th): self.df=pd.DataFrame(data=dataX,columns=["data"]) self.result = self.detector.detect_glitches(self.df,baseline_kurtosis=self.baseline_kurtosis) # self.limit_down=self.detector.lb # self.limit_up=self.detector.ub # self.current_value=self.detector.va # d.debug("self.df.kurtosis():"+str(self.df.kurtosis())) # d.debug("self.df.skew():"+str(self.df.skew())) # res=self.IQR() # d.debug("IQR----res:"+str(res)) # res2=self.sigma(3) # d.debug("sigma---res:"+str(res2)) # self.limit_up=th # self.current_value=res if self.result["has_glitch"]: self.current_value=1 return True self.current_value=0 return False def check_last_alarm_time(self,ruleid): if ruleid in self.last_alarm_time.keys(): d.debug("ruleid:"+ruleid+" in self.last_alarm_time.keys!") exp_time=(self.now_time-self.last_alarm_time[ruleid]).total_seconds() if exp_time> self.AlarmIntervalHours*3600: self.last_alarm_time[ruleid]=self.now_time return True else: d.debug("time:"+str(exp_time)+"s <"+str(self.AlarmIntervalHours*3600)+"s") return False else: d.debug("ruleid:"+ruleid+" not in self.last_alarm_time.keys!") self.last_alarm_time[ruleid]=self.now_time return True def IQR(self): if self.df is not None: d.debug("IQR--------1") if self.df["data"].std()==0: d.debug("数据平稳") return 0 self.df["data"]=(self.df["data"]-self.df["data"].mean())/self.df["data"].std() Q1=self.df["data"].quantile(0.25) Q3=self.df["data"].quantile(0.75) IQR=Q3-Q1 lb=Q1-1.5*IQR ub=Q3+1.5*IQR d.debug(f"Q1:{Q1},Q3:{Q3},IQR:{IQR}") d.debug("lb:"+str(lb)+",ub:"+str(ub)) d.debug("IQR--------2") no_outer=(self.df["data"]>=lb)&(self.df["data"]<=ub) d.debug("max:") d.debug(self.df["data"][(~no_outer)].max()) return (~no_outer).sum()/len(self.df) return None def sigma(self,th=3): if self.df is not None: d.debug("sigma------1") mean=self.df["data"].mean() std=self.df["data"].std() lb=mean-th*std ub=mean+th*std d.debug(f"mean:{mean}, std:{std}") d.debug("lb:"+str(lb)+",ub:"+str(ub)) d.debug("sigma------2") no_outer=(self.df["data"]>=lb)&(self.df["data"]<=ub) return (~no_outer).sum()/len(self.df) def IQR(self,df): pass