diff --git a/ReadMe.txt b/ReadMe.txt index 3fd5311..e97ca1e 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -79,3 +79,6 @@ 2023.10.19 守护进程识别u盘后自动升级小板程序和方案 分析工具自动生成图像 +2023.10.19 + 分析工具在后台线程中下载检测数据 + 解决特定情况下导出方案文件名日期不对的问题 diff --git a/analysis/analysis.py b/analysis/analysis.py index 0672ec4..68b1e06 100644 --- a/analysis/analysis.py +++ b/analysis/analysis.py @@ -93,10 +93,13 @@ class TParamLayout(QObject): return self.__layout class Analysis(QWidget): + data_recv_end_signal =pyqtSignal([list,list]) + calc_item_end_signal =pyqtSignal([list]) def __init__(self,parent=None): super(Analysis,self).__init__(parent) self.setWindowTitle("检测数据分析") - + self.calc_item_end_signal.connect(self.calc_item_end_slot) + self.data_recv_end_signal.connect(self.data_recv_end_slot) self.__import_but = QPushButton("导入方案",self) self.__import_but.clicked.connect(self.import_but_clicked) self.__import_but.setGeometry(QRect(0,0,100,27)) @@ -109,12 +112,46 @@ class Analysis(QWidget): self.__layout = QFormLayout() self.__layout.addRow(' ',self.__export_but) self.__items=[] + def add_item(self,data_dict:dict): + data=data_dict["data"] + x=data_dict["x"] + name=data_dict["name"] + max=data_dict["max"] + min=data_dict["min"] + avg=data_dict["avg"] + mid=data_dict["mid"] + std=data_dict["std"] + limit_max=data_dict["limit_max"] + limit_min=data_dict["limit_min"] + dat_count=data_dict["dat_count"] + y=data_dict["y"] + figure = QFigure(name) + figure.lable("序号","数值") + tplayout=TParamLayout() + tplayout.add_item(name+":Max",str(max)) + tplayout.add_item(name+":Min",str(min)) + tplayout.add_item(name+":Avg",str(avg)) + tplayout.add_item(name+":Mid",str(mid)) + tplayout.add_item(name+":Std",str(std)) + tplayout.add_item(name+":LimitMax",str(limit_max)) + tplayout.add_item(name+":LimitMin",str(limit_min)) + self.__layout.addRow(figure.canvas(),tplayout.layout()) + figure.draw(range(len(data)),data,lable="原始值",limit_max=limit_max,limit_min=limit_min) + figure.draw(dat_count,y,lable="权重") + figure.save(self._save_path,str(self._item_index)+".") + self.__items.append((figure,tplayout)) + self._item_index+=1 + def calc_item_end_slot(self,data:list): + print("calc_item end.") + widget=QWidget() + widget.setGeometry(QRect(0,0,1200,20000)) + for i in data: + self.add_item(i) + widget.setLayout(self.__layout) + self.__scroll.setWidget(widget) - def addItem(self,data,name:str,params:list()): + def calc_item(self,data,name:str): length=len(data) - if(length<1000): - print("data length too less.") - return # 排序,从小到大 sort_list=np.sort(data) dat_count=np.bincount(data) @@ -139,42 +176,42 @@ class Analysis(QWidget): # limit_min=avg-3*std if(limit_min<0): limit_min=0 - figure = QFigure(name) - figure.lable("序号","数值") - tplayout=TParamLayout() - for i in params: - tplayout.add_item(i+":Max",str(max)) - tplayout.add_item(i+":Min",str(min)) - tplayout.add_item(i+":Avg",str(avg)) - tplayout.add_item(i+":Mid",str(mid)) - tplayout.add_item(i+":Std",str(std)) - tplayout.add_item(i+":LimitMax",str(limit_max)) - tplayout.add_item(i+":LimitMin",str(limit_min)) - self.__layout.addRow(figure.canvas(),tplayout.layout()) - figure.draw(range(len(data)),data,lable="原始值",limit_max=limit_max,limit_min=limit_min) + x=range(length) y=np.add(range(len(dat_count)),min) - figure.draw(dat_count,y,lable="权重") - figure.save(self._save_path,str(self._item_index)+".") - self.__items.append((figure,tplayout)) - self._item_index+=1 + dat_struct={"name":name,"max":max,"min":min,"avg":avg,"mid":mid,"std":std,"limit_max":limit_max, + "limit_min":limit_min,"dat_count":dat_count,"y":y,"x":x,"data":data} + # self.add_item_signal.emit(dat_struct) + return dat_struct # 连接的绘制的方法 def import_but_clicked(self): self.sch_data=scheme_data.sch_data() self.__import_but.setEnabled(False) - widget=QWidget() - widget.setGeometry(QRect(0,0,1200,20000)) - self.titles,datas=self.sch_data.datas_sql() - if(self.titles==None): - self.__import_but.setEnabled(True) - return - self._item_index=0 + self.sch_data.select_scheme() self._save_path="file/"+self.sch_data.scheme_name.split('/')[-1].split('.')[0] print(self._save_path) - for i in range(len(self.titles)): - self.addItem(datas[i],self.titles[i],[self.titles[i]]) - widget.setLayout(self.__layout) - self.__scroll.setWidget(widget) + self.recv_data() + def recv_data(self): + self._item_index=0 + def recv_data_thread(sch_data:scheme_data.sch_data): + titles,data,num=sch_data.datas_sql() + print("recv data,len=",num) + self.data_recv_end_signal.emit(titles,data) + if(num<1000): + print("data len too less.") + return + items_data=[] + for i in range(len(titles)): + a=self.calc_item(data[i],titles[i]) + items_data.append(a) + self.calc_item_end_signal.emit(items_data) + + t = threading.Thread(target=recv_data_thread, args=(self.sch_data,)) + t.start() + def data_recv_end_slot(self,titles:list,data:list): + self.titles=titles + self.sql_data=data + print("data recv end.") def export_but_clicked(self): ret_limit=[] for i,t in zip(self.__items,self.titles): diff --git a/analysis/data_deal.py b/analysis/data_deal.py new file mode 100644 index 0000000..00be1ec --- /dev/null +++ b/analysis/data_deal.py @@ -0,0 +1,107 @@ +import matplotlib +import numpy as np +import matplotlib.pyplot as plt + + +plt.rcParams['font.sans-serif']=['SimHei'] +plt.rcParams['axes.unicode_minus']=False + + +x=np.arange(0,np.pi,0.01) +y=np.sin(x)*0.5 + + +# 添加方波 +def add_line(x): + ret=[] + length=len(x) + num=length//10 + index=0 + for i in x: + t=(index//num) + if((t&1)!=0): + ret.append(0.1*t) + else: + ret.append(0) + index+=1 + return ret +y=add_line(x)+y + +# 添加噪声 +def add_random(x): + ret=[] + length=len(x) + index_table=[] + for i in range(10): + index_table.append(int(np.random.random_sample()*10000%length)) + # print(index_table) + for i in range(length): + if(i in index_table): + ret.append(x[i]+np.random.random_sample()-0.5) + else: + ret.append(x[i]) + return ret + +# 滤波 +def my_filter(x): + ret=[] + sub=[] + temp=np.sum(x[0:10])/10 + t=0 + t_p=0 + k=0.005 + signal=False + for i in x: + t_p=t + # t=t*0.9+i*0.1 + t=temp + temp=(temp*9+i)/10 + t_p=t-t_p + if(t_p>k): + signal=True + elif(t_p<-k): + signal=False + if(signal): + ret.append(0.3) + else: + ret.append(0) + sub.append(t_p) + return ret,sub + + + +# 卡尔曼 +class kalman: + LastP=0.02 #上次估算的协方差 + Now_P=0# 当前估算的协方差 + out=0# 输出值 + Kg=0#卡尔曼增益 + Q=0.001# 过程噪声协方差 + R=.0543# 观测噪声协方差 + def calc(self,value:int): + self.Now_P=self.LastP+self.Q + self.Kg=self.Now_P/(self.Now_P+self.R) + self.out=self.out+self.Kg*(value-self.out) + self.LastP=(1-self.Kg)*self.Now_P + return self.out +def my_kalman(x): + ret=[] + k=kalman() + for i in x: + ret.append(k.calc(i)) + return ret + +y2=add_random(y) +y3,y4=my_filter(y) + +def show_xy(xy_list:list): + figure = plt.figure(figsize=(14,7)) + ax = figure.add_axes([0.1,0.1,0.8,0.8]) + index=0 + for xy in xy_list: + line,=ax.plot(xy[0],xy[1],) + line.set_label("index:{d}".format(d=index)) + ax.legend() + index+=1 + plt.show() +show_xy([(x,y),(x,y3),(x,y4)]) diff --git a/analysis/scheme_data.py b/analysis/scheme_data.py index c89665d..5779b89 100644 --- a/analysis/scheme_data.py +++ b/analysis/scheme_data.py @@ -216,26 +216,35 @@ def _main(): class sch_data(object): def __init__(self): - self.scheme_name="" - def datas_sql(self): + pass + # self.scheme_name="" + # self.date_start="" + # self.date_end="" + def select_scheme(self): fileName,fileType = QFileDialog.getOpenFileNames(None, "选取文件", os.getcwd(), "检测方案(*.json)") + self.scheme_name=fileName[0] if(len(fileName)==0): print("user cancelled.") - return None,None + return False print(fileName,fileType) - scheme_name=fileName[0] info=_get_info() quest=quest_text("请输入要获取数据的日期",info[3]+','+info[4]) ack,date_interval=quest.show() if(ack!=True): print("user cancelled.") - return None,None + return False date_interval=date_interval.split(',') - date_start=date_interval[0]+" 00:00:00" - date_end=date_interval[1]+" 23:59:59" + self.date_start=date_interval[0]+" 00:00:00" + self.date_end=date_interval[1]+" 23:59:59" _save_info((info[0],info[1],info[2],date_interval[0],date_interval[1])) - self.scheme_name=scheme_name + return True + def datas_sql(self): + if(self.scheme_name==None): + return None,None + if(self.date_start==None) or (self.date_end==None): + return None,None + scheme_name=self.scheme_name title,scheme_id=_json_extract_retinfo(scheme_name) data_list=[] for i in title: @@ -246,15 +255,14 @@ class sch_data(object): cmd="""SELECT id,create_time,addr,err_code,valuez FROM check_result_detail where create_time > %s and create_time < %s and result_id in (select pk from check_result where plan_id =%s) ;""" - cur.execute(cmd,(date_start,date_end,scheme_id)) + cur.execute(cmd,(self.date_start,self.date_end,scheme_id)) check_data=cur.fetchall() - print("check_data_len=",len(check_data)) for row in check_data: if(row[3]==0): s=row[4].split(',') for i in range(len(s)): data_list[i].append(int(s[i])) - return title,data_list + return title,data_list,len(check_data) def export_scheme(self,ret_limit): name=self.scheme_name @@ -276,6 +284,8 @@ class sch_data(object): j["Max"]=ret_limit[index][0] j["Min"]=ret_limit[index][1] json_obj["PlanID"],sid=_reflush_scheme_id(json_obj["PlanID"]) + # 刷新方案id号之后更新日期 + date=_get_info()[0] save_name=save_name+"_"+date+"{d:02d}".format(d=sid) json_obj["PlanBrief"]=save_name json_str=json.dumps(json_obj, sort_keys=True, indent=4, separators=(',', ': '),ensure_ascii=False)