算出Lw Rs再保存

desktop
esea_info 3 years ago
parent c161407db2
commit de7d73aa50
  1. 237
      dataplot.py
  2. 134
      handheld.py
  3. 96
      mypanel.py
  4. 126
      mythread.py
  5. 2
      retrieve.yml
  6. 100
      uiconfig/ui_plot_setting.py
  7. 179
      yiwinframe.py

@ -0,0 +1,237 @@
# import numpy as np
from pathlib import Path
class DataPlot():
'''
从文件读取数据出来成待显示数据
'''
# def __init__(self, mypanel, ):
def __init__(self, ):
# self.mypanel = mypanel
# self.__eventManager = eventManger
# self.dataSaveFile = DATA_FNAME_WITHOUT_WATER
# self.axes_title = "Water Attenuation Coefficient"
# self.axes_xlabel = "Wavelength (nm)"
# self.axes_ylabel = "Attenuation Coefficient m(-1)"
# self.axes_title = "Attenuation Coefficient Demo"
self.demo_time = ''
self.demo_wl = [] # 纯水
self.demo_data = [] # 纯水
self.wavelength = None
self.data_one = None
self.data_multi = None
# self.mode = "one" # multi
# self.begin_line = None
# self.line_interval = None
self.fpath :Path = Path()
self.total_lines = 0
self.token = ";"
# self.MPL = myPanel.MPL_Panel(self) # 调用自己建立的 panel 类
# self.Figure = self.MPL.Figure
# self.axes = self.MPL.axes
# self.FigureCanvas = self.MPL.FigureCanvas
def set_file_path( self, fpath:Path ):
self.fpath = fpath
pass
def set_wavelength(self):
pass
# def set_mode(self, mode ="one"):
# self.mode = mode
# pass
def set_token(self, token =";"):
self.token = token
pass
def set_begin_line( self, lineno = 0 ):
self.begin_line = lineno
pass
def set_line_interval( self, line_interval = 0 ):
self.line_interval = line_interval
pass
def get_total_lines( self, ):
''' 大文件 '''
count = 0
thefile = open( self.fpath, 'rb')
while True:
buffer = thefile.read(8192*1024)
if not buffer:
break
count += buffer.count(b'\n')
self.total_lines = count + 1
def get_wavelength_from_file( self, ):
tmp = self.get_first_line()
self.wavelength = tmp.split(self.token)[1:]
pass
def get_reverse_x_lineno( self, x ):
line = self.__get_reverse_x_lineno(x)
line = line.split(self.token)
return line[0], line[1:]
pass
def get_multi_by_x_m_n( self, x,m,n ):
# res_time = []
# res_lines = []
lines = self.__get_reverse_x_m_n_line(x,m,n)
# print(f'+++++ {lines}')
# for i in range(len(lines)):
# ln =
# res_time.append( lines[i] [0] )
# res_lines.append( lines[i][1:] )
# return res_time, res_lines
return lines
pass
def __get_reverse_x_lineno(self, x):
"""
获得倒数第x行
"""
try:
# filesize = os.path.getsize(self.fpath)
filesize = self.fpath.stat().st_size
if filesize == 0:
return None
else:
with open(self.fpath, 'rb') as fp: # to use seek from end, must use mode 'rb'
offset = -8 # initialize offset
while -offset < filesize: # offset cannot exceed file size
fp.seek(offset, 2) # read # offset chars from eof(represent by number '2')
lines = fp.readlines() # read from fp to eof
if len(lines) >= x+1: # if contains at least 2 lines
return lines[-1*x] # then last line is totally included
else:
offset *= 2 # enlarge offset
fp.seek(0)
lines = fp.readlines()
if len(lines) < x:
raise Exception("行数有误,请重试")
return lines[-1*x]
except FileNotFoundError:
print(self.fpath.name + ' not found!')
return None
def __get_reverse_x_m_n_line(self, x, m=1, n=1):
"""
获得倒数第x行, 间隔m行, 共取n个行
"""
print(f'__get_reverse_x_m_n_line {x} {self.fpath}')
min_lines = x + m*n
res_lines = []
try:
# filesize = os.path.getsize(self.fpath)
filesize = self.fpath.stat().st_size
if filesize == 0:
return None
else:
with open(self.fpath, 'rb') as fp: # to use seek from end, must use mode 'rb'x
offset = -8 # initialize offset
while -offset < filesize: # offset cannot exceed file size
fp.seek( offset, 2 ) # read # offset chars from eof(represent by number '2')
lines = fp.readlines() # read from fp to eof
if len(lines) >= min_lines+1 :
for i in range(n):
res_lines.append( lines[-1*(x+m*i)].decode())
return res_lines
else:
offset *= 2 # enlarge offset
fp.seek( 0 )
lines = fp.readlines( )
if len(lines) < min_lines:
raise Exception("行数有误,请重试")
for i in range(n):
res_lines.append( lines[-1*(x+m*i)].decode())
return res_lines
print(res_lines)
except FileNotFoundError:
print(self.fpath.name + ' not found!')
return None
def get_first_line(self, ):
firstline = ''
with open(self.fpath, 'rb') as fp: # to use seek from end, must use mode 'rb'x
firstline = fp.readline()
return firstline.decode()
def get_last_line(self,filename:Path):
"""
获得最后一行
:param filename: file name
:return: last line or None for empty file
"""
try:
filesize = filename.stat().st_size
if filesize == 0:
return None
else:
with open(filename, 'rb') as fp: # to use seek from end, must use mode 'rb'
offset = -8 # initialize offset
while -offset < filesize: # offset cannot exceed file size
fp.seek(offset, 2) # read # offset chars from eof(represent by number '2')
lines = fp.readlines() # read from fp to eof
if len(lines) >= 2: # if contains at least 2 lines
return lines[-1] # then last line is totally included
else:
offset *= 2 # enlarge offset
fp.seek(0)
lines = fp.readlines()
return lines[-1]
except FileNotFoundError:
print(filename + ' not found!')
return None
def tail(file, taillines=500, return_str=True, avg_line_length=None):
"""
大文件的尾行小文件会导致报错
taillines : 读取尾部多少行
avg_line_length:每行字符平均数,
return_str:返回类型默认为字符串False为列表
offset:每次循环相对文件末尾指针偏移数
f.tell() 当前指针位置
f.seek(a,b) a 偏移量 b:0 1 2 文件头 当前位置 文件尾部
"""
with open(file, errors='ignore') as f:
if not avg_line_length:
f.seek(0, 2)
f.seek(f.tell() - 3000)
avg_line_length = int(3000 / len(f.readlines())) + 10
f.seek(0, 2)
end_pointer = f.tell()
offset = taillines * avg_line_length
if offset > end_pointer:
f.seek(0, 0)
lines = f.readlines()[-taillines:]
return "".join(lines) if return_str else lines
offset_init = offset
i = 1
while len(f.readlines()) < taillines:
location = f.tell() - offset
f.seek(location)
i += 1
offset = i * offset_init
if f.tell() - offset < 0:
f.seek(0, 0)
break
else:
f.seek(end_pointer - offset)
lines = f.readlines()
if len(lines) >= taillines:
lines = lines[-taillines:]
return "".join(lines) if return_str else lines
if __name__ == "__main__":
d = DataPlot()

@ -15,6 +15,7 @@ import locale
import struct import struct
import numpy as np import numpy as np
from pathlib import PurePath,Path from pathlib import PurePath,Path
from pubsub import pub
from myconfig import CURRENT_DIR,DATA_DIR,OUTPUT_DIR,NEWLINE,ROWFACTOR,SAVE_EXT_NAME,TOKEN from myconfig import CURRENT_DIR,DATA_DIR,OUTPUT_DIR,NEWLINE,ROWFACTOR,SAVE_EXT_NAME,TOKEN
from myconfig import DeviceType,RamsesSURFACE,RamsesAWRAMS,RamsesPROFILE from myconfig import DeviceType,RamsesSURFACE,RamsesAWRAMS,RamsesPROFILE
from tools.mylogger import log from tools.mylogger import log
@ -413,6 +414,12 @@ class HandHeld(object):
if self.device_type == DeviceType.PROFILE.name: if self.device_type == DeviceType.PROFILE.name:
self.device_enum = RamsesPROFILE self.device_enum = RamsesPROFILE
def __set_msg(self, flag, d):
self.msg = {}
self.msg.update( {"flag":flag} )
self.msg.update( {"data":d} )
pass
def getDataFileList(self, ): def getDataFileList(self, ):
self.hhp.getDataFileList() self.hhp.getDataFileList()
self.filelist = self.hhp.getFilelist() self.filelist = self.hhp.getFilelist()
@ -457,6 +464,8 @@ class HandHeld(object):
log.error( "处理传感器文件" + self.sensor_path_fname.name + "出现错误",__name__,"dealAllMeasurements") log.error( "处理传感器文件" + self.sensor_path_fname.name + "出现错误",__name__,"dealAllMeasurements")
raise MyException( "处理传感器文件" + self.sensor_path_fname.name + "出现错误" ) raise MyException( "处理传感器文件" + self.sensor_path_fname.name + "出现错误" )
pass pass
self.__set_msg('notice', '处理文件完成')
pub.sendMessage('update' , msg=self.msg)
log.info(f"Finished !! ", __name__, "dealAllMeasurements") log.info(f"Finished !! ", __name__, "dealAllMeasurements")
return True,self.error_result return True,self.error_result
pass pass
@ -464,7 +473,7 @@ class HandHeld(object):
def dealOneHandheldMeasurement(self, fpath:Path): def dealOneHandheldMeasurement(self, fpath:Path):
'''handheld一次测量包含多组数据''' '''handheld一次测量包含多组数据'''
# 调用handheldbuf 处理,将一组数据提交出来 # 调用handheldbuf 处理,将一组数据提交出来
log.info(f" 手持一个文件,多组测量数据", __name__, "dealOneHandheldMeasurement") log.info(f" 处理一个文件,多组测量数据", __name__, "dealOneHandheldMeasurement")
if len(self.filelist)<1: if len(self.filelist)<1:
pass pass
@ -519,49 +528,49 @@ class HandHeld(object):
self.__do_sensor_dict_interpo() self.__do_sensor_dict_interpo()
# 选择追加保存, 一个Lsky 可能多组文件,只能单独保存为 Lsky Esky ..Rs # 选择追加保存, 一个Lsky 可能多组文件,只能单独保存为 Lsky Esky ..Rs
self.appendSave() # self.appendSave()
# self.checkAndSaveData( ) self.getLwRs()
# self.getLwRsAndSave() self.checkAndSaveData( )
# path_info_txt = self.output_path.joinpath( "info.txt" ) path_info_txt = self.output_path.joinpath( "info.txt" )
# self.save_dict_to_file( self.info_dict, path_info_txt ) self.save_dict_to_file( self.info_dict, path_info_txt )
def dealOneGroup(self, ): # def dealOneGroup(self, ):
# 分组,并获得平均值, 255个未插值结果 (依据 measurement_interval measurement_repeat) # # 分组,并获得平均值, 255个未插值结果 (依据 measurement_interval measurement_repeat)
self.output_path = OUTPUT_DIR # self.output_path = OUTPUT_DIR
self.getAvg( self.intensity_before_avg ) # self.getAvg( self.intensity_before_avg )
# 插值 # # 插值
self.real_wavelength = self.getWavelenthDict() # self.real_wavelength = self.getWavelenthDict()
self.__do_sensor_dict_interpo() # self.__do_sensor_dict_interpo()
self.ymdhms = "20"+ str(self.info_dict['year']) + '_' \ # self.ymdhms = "20"+ str(self.info_dict['year']) + '_' \
+ str(self.info_dict['month']) + '_' \ # + str(self.info_dict['month']) + '_' \
+ str(self.info_dict['day']) + '_' \ # + str(self.info_dict['day']) + '_' \
+ str(self.info_dict['hour']) + '_' \ # + str(self.info_dict['hour']) + '_' \
+ str(self.info_dict['minute']) + '_' \ # + str(self.info_dict['minute']) + '_' \
+ str(self.info_dict['second']) # + str(self.info_dict['second'])
self.output_path = self.output_path.joinpath( self.ymdhms ) # self.output_path = self.output_path.joinpath( self.ymdhms )
self.appendSave() # self.appendSave()
# self.checkAndSaveData( ) # # self.checkAndSaveData( )
# self.getLwRsAndSave() # # self.getLwRsAndSave()
# path_info_txt = self.output_path.joinpath( "info.txt" ) # # path_info_txt = self.output_path.joinpath( "info.txt" )
# self.save_dict_to_file( self.info_dict, path_info_txt ) # # self.save_dict_to_file( self.info_dict, path_info_txt )
def dealOneMeasurement(self, fpath:Path): # def dealOneMeasurement(self, fpath:Path):
'''handheld一次测量包含多组数据''' # '''handheld一次测量包含多组数据'''
# 调用handheldbuf 处理,将一组数据提交出来 # # 调用handheldbuf 处理,将一组数据提交出来
log.info(f"dealOneMeasurement: 一组测量数据", __name__, "dealOneMeasurement") # log.info(f"dealOneMeasurement: 一组测量数据", __name__, "dealOneMeasurement")
if len(self.filelist)<1: # if len(self.filelist)<1:
pass # pass
# 当前文件名 # # 当前文件名
self.current_filepath = fpath # self.current_filepath = fpath
self.current_measure_time = self.hhp.getCurrentMeasureTimeFromPath(fpath) # ?? # self.current_measure_time = self.hhp.getCurrentMeasureTimeFromPath(fpath) # ??
self.hhb.readFile2Buf(fpath) # self.hhb.readFile2Buf(fpath)
self.decode_sensor_buf() # self.decode_sensor_buf()
self.real_wavelength = self.getWavelenthDict() # self.real_wavelength = self.getWavelenthDict()
self.dealOneGroup() # self.dealOneGroup()
def decode_sensor_buf(self,) : def decode_sensor_buf(self,) :
@ -685,11 +694,15 @@ class HandHeld(object):
self.newFileByFunc( self.device_enum(1).name ) self.newFileByFunc( self.device_enum(1).name )
self.newFileByFunc( self.device_enum(2).name ) self.newFileByFunc( self.device_enum(2).name )
self.newFileByFunc( self.device_enum(3).name ) self.newFileByFunc( self.device_enum(3).name )
self.newFileByFunc( self.device_enum(4).name )
self.newFileByFunc( self.device_enum(5).name )
pass pass
self.appendFileByFunc( self.device_enum(1).name ) self.appendFileByFunc( self.device_enum(1).name )
self.appendFileByFunc( self.device_enum(2).name ) self.appendFileByFunc( self.device_enum(2).name )
self.appendFileByFunc( self.device_enum(3).name ) self.appendFileByFunc( self.device_enum(3).name )
self.appendFileByFunc( self.device_enum(4).name )
self.appendFileByFunc( self.device_enum(5).name )
def newFileByFunc(self, func:str) -> None: def newFileByFunc(self, func:str) -> None:
self.mydir.newFileIfNot( func+SAVE_EXT_NAME) self.mydir.newFileIfNot( func+SAVE_EXT_NAME)
@ -713,26 +726,37 @@ class HandHeld(object):
def clearRes(self, ) -> None: def clearRes(self, ) -> None:
self.res = { } self.res = { }
def getLwRsAndSave(self, ) -> bool: def getLwRs(self, ) -> bool:
""" """
并计算Lw Rs并保存 并计算Lw Rs并保存
""" """
Lw = self.res["Lwater"] - ROWFACTOR * self.res["Lsky"] Lw = self.res["Lwater"] - ROWFACTOR * self.res["Lsky"]
self.res.update({ "Lw" : Lw }) self.res.update({ self.device_enum(4).name : Lw })
Rs = self.res["Lw"] / self.res["Esky"] Rs = self.res["Lw"] / self.res["Esky"]
self.res.update({ "Rs" : Rs }) self.res.update({ self.device_enum(5).name : Rs })
self.mydir.setBaseDir(self.output_path) #基路径
return True
# def getLwRsAndSave(self, ) -> bool:
# """
# 并计算Lw Rs并保存
# """
# Lw = self.res["Lwater"] - ROWFACTOR * self.res["Lsky"]
# self.res.update({ "Lw" : Lw })
# Rs = self.res["Lw"] / self.res["Esky"]
# self.res.update({ "Rs" : Rs })
# self.mydir.setBaseDir(self.output_path) #基路径
# 保存 # # 保存
if self.current_group_num == 0: # if self.current_group_num == 0:
self.newFileByFunc( "Lw" ) # self.newFileByFunc( "Lw" )
self.newFileByFunc( "Rs" ) # self.newFileByFunc( "Rs" )
pass # pass
self.appendFileByFunc( "Lw" ) # self.appendFileByFunc( "Lw" )
self.appendFileByFunc( "Rs" ) # self.appendFileByFunc( "Rs" )
return True return True

@ -1,4 +1,100 @@
import wx import wx
import numpy as np
from enum import Enum
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas #FigureCanvasWxAgg
# from matplotlib.backends.backend_wx import NavigationToolbar2Wx as NavigationToolbar # FIgure 导航
from matplotlib.figure import Figure
class LineColor(Enum):
RED = 0
ORANGE = 1
YELLOW = 2
GREEN = 3
CYAN = 4
BLUE = 5
PURPLE = 6
class Plot(wx.Panel):
'''
# 需要在 Frame 实例化一个实例
# 改变需要对实例化后的进行操作
'''
'''
Matplotlib Panel 单独拿出来画图
可以 __do_layout
可以 __add_widgets
可以 button事件
可以鼠标事件
'''
def __init__(self,parent):
'''
* panel 初始化后的样子
'''
super(Plot,self).__init__(parent)
# 本地化语言
self.locale = wx.Locale(wx.LANGUAGE_CHINESE_SIMPLIFIED)
self.Figure = Figure(figsize=(4,3)) # 4,3 为英寸
self.axes = self.Figure.add_axes([0.1,0.1,0.8,0.8],facecolor="lightgray") # 坐标系起始位置
self.FigureCanvas = FigureCanvas(self,-1,self.Figure)
#继承鼠标移动显示鼠标处坐标的事件
# self.FigureCanvas.mpl_connect('motion_notify_event',self.MPLOnMouseMove)
# self.NavigationToolbar = NavigationToolbar(self.FigureCanvas)
# self.StaticText = wx.StaticText(self,-1,label=u'坐标信息')
# self.SubBoxSizer = wx.BoxSizer(wx.HORIZONTAL)
# self.SubBoxSizer.Add(self.NavigationToolbar,proportion =0, border = 2,flag = wx.ALL | wx.EXPAND)
# self.SubBoxSizer.Add(self.StaticText,proportion =-1, border = 2,flag = wx.ALL | wx.EXPAND)
self.TopBoxSizer = wx.BoxSizer(wx.VERTICAL)
# self.TopBoxSizer.Add(self.SubBoxSizer,proportion =-1, border = 2,flag = wx.ALL | wx.EXPAND)
self.TopBoxSizer.Add(self.FigureCanvas,proportion =-10, border = 2,flag = wx.ALL | wx.EXPAND)
self.SetSizer(self.TopBoxSizer)
self.purewater_legend = (" Rs"
,"Wavelength (nm)"
," Rs " )
self.measure_legend = (" Rs"
,"Wavelength (nm)"
," Rs" )
def set_axes_title(self,title):
self.axes.set_title(title)
def set_axes_xlabel(self,x):
self.axes.set_xlabel(x)
def set_axes_ylable(self,y):
self.axes.set_ylabel(y)
def set_title_x_y(self,title, x, y):
self.axes.set_title(title)
self.axes.set_xlabel(x)
self.axes.set_ylabel(y)
def plot_one( self, time_, wavelength:np.ndarray, data:np.ndarray, color="green" ):
self.axes.plot(wavelength, data, color=color, linewidth=0.5 , label=time_ )
self.axes.legend( )
self.axes.grid( True )
self.FigureCanvas.draw()
def plot_multi( self, tm, wavelength:np.ndarray, data:np.ndarray ):
len_ = len(data)
for i in range(len_):
self.axes.plot(wavelength, data[i], color=LineColor(i).name.lower(), linewidth=0.5 , label=tm[i] )
self.axes.legend( )
self.axes.grid(True)
self.FigureCanvas.draw()
def clear_past( self, ):
self.axes.clear()
class MyPanel(wx.Panel): class MyPanel(wx.Panel):
"""docstring for MyPanel.""" """docstring for MyPanel."""

@ -0,0 +1,126 @@
import threading
import time
class Mythead(threading.Thread):
'''线程守护'''
def __init__(self ):
super(Mythead, self).__init__()
pass
def set_task(self, func, *args):
self.func = func
self.args = args
def run(self):
# print(f" --- {len(self.args)}")
if len(self.args) > 0:
self.func(self.args)
else:
self.func( )
class Multithread(threading.Thread):
'''
多线程
子线程.join() -> ( 设置在start之后, 等所有阻塞线程运行完, 再运行主线程 )
子线程.setDaemon(True) -> 设置子线程A为守护线程, 主线程所在的进程内所有非守护线程统统运行完毕,
无论子线程A有没有结束, 程序都结束
Method:
'''
def __init__(self):
super(Multithread, self).__init__()
self.__tasks = []
self.act = []
# self.__block = False
pass
# def set_task( self, tasks ):
# self.__tasks = tasks
def add_task(self, func, daemon=False, join=True,args=()):
tmp_dict = {}
tmp_dict.update( {"func" : func})
if daemon == True:
tmp_dict.update( {"daemon" : True})
else:
tmp_dict.update( {"daemon" : False})
if join == True:
tmp_dict.update( {"join" : True})
else:
tmp_dict.update( {"join" : False})
if args == ():
tmp_dict.update( {"args" : ()})
else:
tmp_dict.update( {"args" : args})
self.__tasks.append( tmp_dict )
def remove_tasks(self, ):
self.__tasks = []
self.act = []
def add_task_2_act(self, task):
t = threading.Thread( target = task['func'], args = task['args'] )
self.act.append(t)
t.start()
def execute_one_act(self,i):
if self.__tasks[i]['join']:
self.act[i].join() # 子线程阻塞完毕再运行主线程
pass
def prepare_tasks(self):
self.act = []
for task in self.__tasks:
self.add_task_2_act(task)
def execute_tasks(self):
try:
for i in range( len(self.act) ):
self.execute_one_act( i )
pass
except Exception as e:
print(e)
def prepare_tasks(self):
self.act = []
for task in self.__tasks:
t = threading.Thread( target = task['func'], args = task['args'] )
self.act.append(t)
t.start()
def simultaneously_execute_tasks(self):
self.prepare_tasks()
self.execute_tasks()
def sequently_execute_tasks(self):
for task in self.__tasks:
t = threading.Thread( target = task['func'], args = task['args'] )
t.start()
t.join()
def t1(self):
print("thread1...")
time.sleep(10)
print("thread1... after sleep...")
def t2(self):
print("thread2...")
time.sleep(5)
print("thread2... after sleep...")
def t3(self):
print("thread3...")
time.sleep(3)
print("thread3... after sleep...")
if __name__ == '__main__':
mt = Multithread()
mt.add_task(mt.t1)
mt.add_task(mt.t2)
mt.add_task(mt.t3)
# mt.prepare_tasks() # 线程同步运行
# mt.execute_tasks()
# mt.simultaneously_execute_tasks()
mt.sequently_execute_tasks()

@ -1,3 +1,5 @@
LineBegin: 1
LineInterval: 1
beginWL: 350 beginWL: 350
endWL: 950 endWL: 950
interval: 1 interval: 1

@ -0,0 +1,100 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import wx
# from configobj import ConfigObj
from myconfig import MyConfig
from myconfig import YAML_FILE_NAME
class UI_Plot_Setting(wx.Dialog):
"""
@description : 绘图 配置
"""
def __init__(self, parent, id):
# 串口页面配置
super(UI_Plot_Setting, self).__init__( parent ,id = id )
self.config = MyConfig()
self.InitUI()
self.SetSize((400, 400))
self.SetTitle(" 绘图 序列号 ")
def InitUI(self):
self.config_yml = self.config.read_rtv_yaml()
self.panel = wx.Panel(self)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.sb = wx.StaticBox(self.panel, label='指定绘图设置 ')
self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL)
self.hbox1 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText1 = wx.StaticText(self.panel, label='起始行号 ',size=(60, -1), style=wx.ALIGN_CENTRE_VERTICAL )
self.textCtrl1 = wx.TextCtrl(self.panel, value="",size=(250,25) )
tmp = self.get_str_from_config( "LineBegin" )
if tmp is not None:
self.textCtrl1.SetValue(tmp)
self.hbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5)
self.hbox1.Add(self.textCtrl1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox1, flag=wx.TOP|wx.LEFT, border= 5)
self.hbox2 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText2 = wx.StaticText(self.panel, label='间隔行号: ' ,size=(60, -1))
# self.staticText2_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1))
self.textCtrl2 = wx.TextCtrl(self.panel, value="",size=(250,25))
tmp = self.get_str_from_config( "LineInterval" )
if tmp is not None:
self.textCtrl2.SetValue(tmp)
self.hbox2.Add(self.staticText2, flag=wx.TOP|wx.LEFT, border=5)
self.hbox2.Add(self.textCtrl2,flag=wx.TOP|wx.LEFT, border=5)
# self.hbox2.Add(self.staticText2_1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox2, flag=wx.TOP|wx.LEFT, border=5)
self.panel.SetSizer(self.sbs)
self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL)
self.okButton = wx.Button(self, label=u'保存配置')
self.closeButton = wx.Button(self, label='Close')
self.hbox_0.Add(self.okButton)
self.hbox_0.Add(self.closeButton, flag = wx.LEFT, border=5)
# 添加 vbox 到panel
self.vbox.Add(self.panel, proportion=1,
flag=wx.ALL | wx.EXPAND, border=5)
self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10)
self.SetSizer(self.vbox)
self.okButton.Bind(wx.EVT_BUTTON, self.OnSave)
self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose)
def get_str_from_config( self, key ):
return str(self.config_yml[key])
pass
def set_config_by_key_val( self, key, val ):
# print(f" {key} current type {type( self.config_yml[section][key] )}")
if type( self.config_yml [key] ) == int:
self.config_yml [key] = int(val)
elif type( self.config_yml [key] ) == float:
self.config_yml [key] = float(val)
else:
self.config_yml[key] = val
pass
def saveData(self, e):
pass
def OnClose(self, e):
self.Destroy()
def OnSave(self, e):
success = True
# 赋值字典,写入文件
self.set_config_by_key_val( "LineBegin",self.textCtrl1.GetValue( ))
self.set_config_by_key_val( "LineInterval",self.textCtrl2.GetValue( ))
self.config.write_rtv_yaml(self.config_yml)
del self.config
if success:
self.EndModal(wx.ID_OK)

@ -2,20 +2,23 @@ import wx
import os import os
import time import time
import threading import threading
from pathlib import * from pathlib import PurePath,Path
# from configobj import ConfigObj from pubsub import pub
from listctrl import Listctrl from listctrl import Listctrl
from mypanel import MyPanel from mypanel import MyPanel,Plot,LineColor
from uiconfig.uisensor import UISensor from uiconfig.uisensor import UISensor
# from uiconfig.uilogging import UILogging # from uiconfig.uilogging import UILogging
from uiconfig.uiabout import About from uiconfig.uiabout import About
from uiconfig.uihelp import Help from uiconfig.uihelp import Help
from uiconfig.ui_plot_setting import UI_Plot_Setting
from myconfig import TOKEN,DeviceType,YAML_FILE_NAME,RETRIEVE_CFG_FILE from myconfig import TOKEN,DeviceType,YAML_FILE_NAME,RETRIEVE_CFG_FILE
from myconfig import MyConfig from myconfig import MyConfig,RamsesFunc
from mythread import Mythead
from configuration import Configuration from configuration import Configuration
from handheld import HandHeld,HandHeldBuf from handheld import HandHeld,HandHeldBuf
@ -28,6 +31,12 @@ ID_MEASURE = 1
ID_SENSOR_SETTING = 11 ID_SENSOR_SETTING = 11
ID_LOGGING_SETTING = 12 ID_LOGGING_SETTING = 12
ID_CAL_INFO = 13 ID_CAL_INFO = 13
ID_DISPLAY_PARA = 14
ID_PLOT_LAST = 15
ID_PLOT_LAST_7 = 16
ID_PLOT_7 = 17
ID_PLOT_SETTING = 18
ID_HELP = 21 ID_HELP = 21
ID_ABOUT = 22 ID_ABOUT = 22
@ -66,7 +75,12 @@ class YiwinFrame(wx.Frame):
self.BoxSizer.Add( self.mypanel, proportion =-10, border = 0, flag = wx.ALL | wx.EXPAND) self.BoxSizer.Add( self.mypanel, proportion =-10, border = 0, flag = wx.ALL | wx.EXPAND)
self.static_text = self.mypanel.staticText1 self.static_text = self.mypanel.staticText1
# 隐藏 等待show # 隐藏 等待show
self.mypanel.Show() self.mypanel.Hide()
self.plotpanel = Plot( self ) # 调用自己建立的 Listctrl panel 类
self.BoxSizer.Add( self.plotpanel, proportion =-10, border = 0, flag = wx.ALL | wx.EXPAND)
self.plotpanel.set_title_x_y(*self.plotpanel.purewater_legend)
self.plotpanel.Show()
self.statusBar = self.CreateStatusBar() # 创建状态栏 self.statusBar = self.CreateStatusBar() # 创建状态栏
self.statusBar.SetFieldsCount(2) # 状态栏分成3个区域 self.statusBar.SetFieldsCount(2) # 状态栏分成3个区域
@ -81,8 +95,8 @@ class YiwinFrame(wx.Frame):
log.info(f"system init....",__name__, "__init__") log.info(f"system init....",__name__, "__init__")
self.mycfg = MyConfig() self.mycfg = MyConfig()
self.hh = HandHeld() self.hh = HandHeld()
self.mythread = Mythead()
# self.hhb = HandHeldBuf() pub.subscribe( self.updateDisplay, "update")
pass pass
@ -98,10 +112,20 @@ class YiwinFrame(wx.Frame):
settingMenu.Append(ID_CAL_INFO, u'&获取标定信息', ' ') settingMenu.Append(ID_CAL_INFO, u'&获取标定信息', ' ')
settingMenu.AppendSeparator() settingMenu.AppendSeparator()
settingMenu.Append(ID_MEASURE, u'&处理数据', ' ') settingMenu.Append(ID_MEASURE, u'&处理数据', ' ')
# settingMenu.AppendSeparator() settingMenu.AppendSeparator()
# settingMenu.Append(ID_LOGGING_SETTING, u'&采集设置', ' ') settingMenu.Append(ID_LOGGING_SETTING, u'&采集设置', ' ')
self.menubar.Append(settingMenu, u'&系统 ') self.menubar.Append(settingMenu, u'&系统 ')
plotMenu = wx.Menu()
plotMenu.Append(ID_PLOT_LAST, u'&最后一条', '...')
plotMenu.AppendSeparator()
plotMenu.Append(ID_PLOT_LAST_7, u'&最后七条', ' ')
plotMenu.AppendSeparator()
plotMenu.Append(ID_PLOT_7, u'&指定七条', ' ')
plotMenu.AppendSeparator()
plotMenu.Append(ID_PLOT_SETTING, u'&指定设置', ' ')
self.menubar.Append(plotMenu, u'&绘图 ')
aboutMenu = wx.Menu() aboutMenu = wx.Menu()
aboutMenu.Append(ID_HELP, u'&帮助', 'help...') aboutMenu.Append(ID_HELP, u'&帮助', 'help...')
aboutMenu.AppendSeparator() aboutMenu.AppendSeparator()
@ -126,6 +150,11 @@ class YiwinFrame(wx.Frame):
self.Bind(wx.EVT_MENU, self.OnDealData, id=ID_MEASURE) self.Bind(wx.EVT_MENU, self.OnDealData, id=ID_MEASURE)
# self.Bind(wx.EVT_MENU, self.OnLoggingSetting, id=ID_LOGGING_SETTING) # self.Bind(wx.EVT_MENU, self.OnLoggingSetting, id=ID_LOGGING_SETTING)
self.Bind(wx.EVT_MENU, self.OnPlotLast, id=ID_PLOT_LAST )
self.Bind(wx.EVT_MENU, self.OnPlotLast7, id=ID_PLOT_LAST_7 )
self.Bind(wx.EVT_MENU, self.OnPlot7, id=ID_PLOT_7)
self.Bind(wx.EVT_MENU, self.OnPlotSetting, id=ID_PLOT_SETTING)
self.Bind(wx.EVT_MENU, self.OnHelpConfig, id=ID_HELP) self.Bind(wx.EVT_MENU, self.OnHelpConfig, id=ID_HELP)
self.Bind(wx.EVT_MENU, self.OnAboutConfig, id=ID_ABOUT) self.Bind(wx.EVT_MENU, self.OnAboutConfig, id=ID_ABOUT)
pass pass
@ -135,6 +164,36 @@ class YiwinFrame(wx.Frame):
self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer) #绑定一个定时器事件 self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer) #绑定一个定时器事件
pass pass
def updateDisplay(self, msg):
log.warning(f" updateDisplay 。。 {msg['data']}")
if msg['flag'] == "notice":
self.__update_notice(msg['data'])
pass
if msg['flag'] == "data":
# log.info(f" ... update .{msg['data']}........... " )
self.__update_data(msg['data'])
pass
pass
def __update_notice(self,msg):
log.info(f" .......{msg}... ",__name__,'__update_notice')
self.alterStatus_0( msg)
self.popDialog( msg )
pass
def __update_data(self,data ):
log.info(f" .......... ",__name__,'__update_data')
self.plotpanel.set_axes_title( data['tm'])
res = data['res']
x = self.hh.wavelength.tolist()
length = len(data)
self.plotpanel.clear_past()
for display in RamsesFunc:
self.plotpanel.plot_one(display.name, x, res[display.name],color= LineColor(display.value).name )
pass
pass
def OnStart( self, event ): def OnStart( self, event ):
log.info(f"OnStart....interval: {self.interval} min, port: {self.port}") log.info(f"OnStart....interval: {self.interval} min, port: {self.port}")
# self.m = SerialThread() # self.m = SerialThread()
@ -181,11 +240,20 @@ class YiwinFrame(wx.Frame):
MyException( f"System Configuration is empty." ) MyException( f"System Configuration is empty." )
pass pass
if self.hh.dealAllMeasurements( ): # 处理数据
self.onNotify("正在处理数据" ) self.alterStatus_0(" 正在处理数据...." )
self.statusBar.SetStatusText(u" 数据处理完成......", 0) try:
self.onNotify("处理数据已经结束" ) self.mythread.set_task( self.hh.dealAllMeasurements )
pass self.mythread.start()
except Exception as e:
log.error(e)
pass
# if self.hh.dealAllMeasurements( ):
# self.onNotify("正在处理数据" )
# self.statusBar.SetStatusText(u" 数据处理完成......", 0)
# self.onNotify("处理数据已经结束" )
# pass
def OnCalInfo(self,e): def OnCalInfo(self,e):
'''依据传感器获取标定文件信息''' '''依据传感器获取标定文件信息'''
@ -235,7 +303,29 @@ class YiwinFrame(wx.Frame):
def popDialog(self, msg, msg_type=u"错误提示"): def popDialog(self, msg, msg_type=u"错误提示"):
with wx.MessageDialog( self, msg, msg_type, wx.OK )as dlg: with wx.MessageDialog( self, msg, msg_type, wx.OK )as dlg:
dlg.ShowModal() dlg.ShowModal()
def OnPlotLast(self,e):
pass
def OnPlotLast7(self,e):
pass
def OnPlot7(self,e):
pass
def OnPlotSetting(self,e):
with UI_Plot_Setting(
self,
-1 ) as Dialog_Sensor_Setting:
Dialog_Sensor_Setting.CenterOnParent()
resultLog = Dialog_Sensor_Setting.ShowModal()
if resultLog == wx.ID_OK:
log.info( " Plot config dialog confirm, call back " )
self.__read_config()
pass
def OnSensorSetting(self,e): def OnSensorSetting(self,e):
with UISensor( with UISensor(
self, self,
@ -277,61 +367,4 @@ class YiwinFrame(wx.Frame):
self.Close() self.Close()
# class SerialThread(threading.Thread):
# """进度条类 """
# def __init__(self, parent):
# """
# :param parent: 主线程UI
# """
# super(SerialThread, self).__init__() # 继承
# self.parent = parent
# # log.info(f"SerialThread ... {self.parent.kh}")
# self.start()
# self.join()
# # self.setDaemon(True) # 设置为守护线程, 即子线程是守护进程,主线程结束子线程也随之结束。
# def stop(self):
# self.parent.kh.disconnect()
# log.info(" Serial stop.... ")
# pass
# def run(self):
# log.info(" Serial run.... ")
# wx.CallAfter(self.parent.OnRcv)
# wx.CallAfter(self.parent.update_process_bar, count) # 调用parent的函数
# wx.CallAfter(self.parent.close_process_bar) # destroy进度条
# def OnSerialThreadStart(self):
# self.m = SerialThread(self)
# pass
# def OnSerialThreadStop(self):
# self.m.stop()
# pass
# def OnDisplaySave(self):
# '''
# 保存数据 self.result
# '''
# log.info(f"OnDisplaySave ....")
# # self.m = SerialThread(self)
# # self.kh.flush()
# self.OnSerialThreadStart()
# def OnRcv( self ):
# log.info(f"OnRcv....")
# self.kh.setPort(self.port)
# if not self.OnDetectPort:
# MyException(f"Can not find port : {self.port}")
# log.info(f"{self.port} ok!")
# # if not self.kh:
# # self.kh = KH3000(self.port)
# # self.result = self.kh.OneMeasure()
# log.info( f"OnRcv success {self.result}", __class__.__name__ )
# self.OnSave()
# self.OnDisplay()
# pass
Loading…
Cancel
Save