This repository has been archived on 2025-02-25. You can view files and clone it, but cannot push or open issues or pull requests.
gitea 25fc43be81 优化 ssh 输入密码的部分
create_plot 函数中增加 close('all'),解决循环画图不销毁占用内存的问题
2024-07-31 11:21:24 +08:00

659 lines
38 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import tkinter
from os.path import exists
from os import getcwd, remove
from threading import Thread
import tkinter.messagebox
import customtkinter
from time import time, strftime, localtime, sleep
from urllib.request import urlopen
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from data_process import brake, current, iso, wavelogger
from automatic_test import do_current, do_brake, btn_functions
from durable_action import factory_test
from commons import openapi, clibs
from matplotlib.pyplot import rcParams, figure, subplots_adjust, close
from matplotlib import use
from pandas import DataFrame, read_excel
import logging
with open(clibs.log_data, 'w') as _:
for i in range(1, 11):
try:
remove(f'{clibs.log_data}.{i}')
except FileNotFoundError:
pass
logger = logging.getLogger(__file__)
logger.info("日志文件初始化完成...")
use('Agg')
customtkinter.set_appearance_mode("System") # Modes: "System" (standard), "Dark", "Light"
customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue"
customtkinter.set_widget_scaling(1.1) # widget dimensions and text size
customtkinter.set_window_scaling(1.1) # window geometry dimensions
# global vars
btns_func = {
'start': {'btn': '', 'row': 1, 'text': '开始运行'},
'check': {'btn': '', 'row': 2, 'text': '检查参数'},
'log': {'btn': '', 'row': 3, 'text': '保存日志'},
'end': {'btn': '', 'row': 4, 'text': '结束运行'},
}
widgits_dp = {
'path': {'label': '', 'entry': '', 'row': 1, 'col': 2, 'text': '数据文件夹路径'},
'dur': {'label': '', 'entry': '', 'row': 2, 'col': 2, 'text': '周期时间'},
'vel': {'label': '', 'optionmenu': '', 'row': 2, 'col': 4, 'text': ''},
'trq': {'label': '', 'optionmenu': '', 'row': 2, 'col': 6, 'text': ''},
'trqh': {'label': '', 'optionmenu': '', 'row': 2, 'col': 8, 'text': ''},
'estop': {'label': '', 'optionmenu': '', 'row': 2, 'col': 10, 'text': ''},
}
widgits_at = {
'path': {'label': '', 'entry': '', 'row': 2, 'col': 2, 'text': '数据文件夹路径'},
'loadsel': {'label': '', 'optionmenu': '', 'row': 2, 'col': 1, 'text': '负载信息'},
}
widgits_da = {
'path': {'label': '', 'entry': '', 'row': 1, 'col': 2, 'text': '数据文件夹路径'},
'curvesel': {'label': '', 'optionmenu': '', 'row': 1, 'col': 1, 'text': '指标选择'},
}
class App(customtkinter.CTk):
def __init__(self):
super().__init__()
self.my_font = customtkinter.CTkFont(family="Consolas", size=16, weight="bold")
self.w_param = 84
self.hr = None
self.md = None
self.canvas = None
self.flg = 0
self.df_copy = None
self.old_curve = None
self.myThread = None
# =====================================================================
# configure window
self.title("AIO - All in one automatic toolbox")
# self.iconbitmap('./icon.ico')
self.geometry("1200x550+30+30")
self.protocol("WM_DELETE_WINDOW", self.func_end_callback)
self.config(bg='#E9E9E9')
self.grid_rowconfigure(6, weight=1)
self.grid_columnconfigure((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), weight=1)
self.minsize(1200, 550)
# =====================================================================
# create frame sidebar(left)
self.frame_func = customtkinter.CTkFrame(self, width=120, corner_radius=0, fg_color='#E9E9E9')
self.frame_func.grid(row=0, column=0, rowspan=7, sticky='nsew')
# create AIO logo
self.label_logo = customtkinter.CTkLabel(self.frame_func, text="Rokae AIO", height=60, font=customtkinter.CTkFont(family="Segoe Script Bold", size=24, weight="bold"), text_color="#4F4F4F")
self.label_logo.grid(row=0, column=0, padx=15, pady=15)
# create buttons
for func in btns_func:
btns_func[func]['btn'] = customtkinter.CTkButton(self.frame_func, corner_radius=10, text=btns_func[func]['text'], fg_color='#4F4F4F', font=self.my_font)
btns_func[func]['btn'].grid(row=btns_func[func]['row'], column=0, sticky='new', padx=10, pady=10, ipadx=5, ipady=5)
btns_func['start']['btn'].configure(command=lambda: self.thread_it(self.func_start_callback))
btns_func['check']['btn'].configure(command=lambda: self.thread_it(self.func_check_callback))
btns_func['log']['btn'].configure(command=lambda: self.thread_it(self.func_log_callback))
btns_func['end']['btn'].configure(command=lambda: self.thread_it(self.func_end_callback))
# create version info
self.label_version = customtkinter.CTkLabel(self.frame_func, justify='left', text="Vers: 0.2.0.5\nDate: 08/02/2024", font=self.my_font, text_color="#4F4F4F")
self.frame_func.rowconfigure(6, weight=1)
self.label_version.grid(row=6, column=0, padx=20, pady=20, sticky='s')
# =====================================================================
# create tabviews
self.tabview = customtkinter.CTkTabview(self, width=10000, height=100, anchor='w', fg_color='#E9E9E9', border_width=2, border_color='#CDCDCD', command=self.tabview_click)
self.tabview.grid(row=0, column=1, padx=10, pady=5, sticky="nsew")
self.tabview.add("Data Process")
self.tabview.add("Automatic Test")
self.tabview.add("Durable Action")
# create main menu for data process
self.menu_main_dp = customtkinter.CTkOptionMenu(self.tabview.tab('Data Process'), values=["init", "brake", "current", "iso", "wavelogger"], font=self.my_font, text_color='yellow', button_color='red', fg_color='green', command=self.func_main_callback)
self.menu_main_dp.grid(row=1, column=1, sticky='we', padx=5, pady=10)
self.menu_main_dp.set("Start Here!")
# create sub menu for data process
self.menu_sub_dp = customtkinter.CTkOptionMenu(self.tabview.tab('Data Process'))
# create main menu for automatic test
self.menu_main_at = customtkinter.CTkOptionMenu(self.tabview.tab('Automatic Test'), values=["init", "brake", "current"], font=self.my_font, text_color='yellow', button_color='red', fg_color='green', command=self.func_main_callback)
self.menu_main_at.grid(row=1, column=1, sticky='we', padx=5, pady=5)
self.menu_main_at.set("Start Here!")
# For data process tab START =====================================================================
# create widgits_dp
for widgit in widgits_dp:
if widgit == 'path':
widgits_dp[widgit]['label'] = customtkinter.CTkLabel(self.tabview.tab('Data Process'), text=f'{widgit.upper()}', font=self.my_font)
widgits_dp[widgit]['label'].grid(row=widgits_dp[widgit]['row'], column=widgits_dp[widgit]['col'], sticky='e', pady=10)
widgits_dp[widgit]['entry'] = customtkinter.CTkEntry(self.tabview.tab('Data Process'), width=670, placeholder_text=widgits_dp[widgit]['text'], font=self.my_font)
widgits_dp[widgit]['entry'].grid(row=widgits_dp[widgit]['row'], column=widgits_dp[widgit]['col']+1, columnspan=11, padx=(5, 10), pady=5, sticky='we')
widgits_dp[widgit]['entry'].configure(state='disabled')
elif widgit in ['dur']:
widgits_dp[widgit]['label'] = customtkinter.CTkLabel(self.tabview.tab('Data Process'), text=f"{widgit.upper()}", font=self.my_font)
widgits_dp[widgit]['label'].grid(row=widgits_dp[widgit]['row'], column=widgits_dp[widgit]['col'], sticky='e', pady=5)
widgits_dp[widgit]['entry'] = customtkinter.CTkEntry(self.tabview.tab('Data Process'), width=self.w_param, placeholder_text=f"{widgits_dp[widgit]['text']}", font=self.my_font)
widgits_dp[widgit]['entry'].grid(row=widgits_dp[widgit]['row'], column=widgits_dp[widgit]['col']+1, padx=(5, 10), pady=5, sticky='w')
widgits_dp[widgit]['entry'].configure(state='disabled')
elif widgit in ['vel', 'trq', 'trqh', 'estop']:
widgits_dp[widgit]['label'] = customtkinter.CTkLabel(self.tabview.tab('Data Process'), text=f"{widgit.upper()}", font=self.my_font)
widgits_dp[widgit]['label'].grid(row=widgits_dp[widgit]['row'], column=widgits_dp[widgit]['col'], sticky='e', pady=5)
widgits_dp[widgit]['optionmenu'] = customtkinter.CTkOptionMenu(self.tabview.tab('Data Process'), button_color='#708090', fg_color='#778899', values=["1", "2", "3", "4", "5", "6", "7"], width=self.w_param, font=self.my_font)
widgits_dp[widgit]['optionmenu'].grid(row=widgits_dp[widgit]['row'], column=widgits_dp[widgit]['col']+1, padx=(5, 10), pady=5, sticky='w')
widgits_dp[widgit]['optionmenu'].configure(state='disabled')
# For data process tab END =====================================================================
# For automatic test tab START =====================================================================
# create buttons
self.seg_button = customtkinter.CTkSegmentedButton(self.tabview.tab('Automatic Test'), dynamic_resizing=False, font=customtkinter.CTkFont(size=16, weight='bold'), command=lambda value='机器状态': self.thread_it(self.segmented_button_callback))
self.seg_button.grid(row=1, column=2, columnspan=12, padx=(65, 10), pady=(10, 10), sticky="ew")
self.seg_button.configure(dynamic_resizing=False, values=["功能切换", "触发急停", "恢复急停", "待定功能", "功能待定", "机器状态", "告警信息"])
self.seg_button.set("功能切换")
# create progress bar
self.progressbar = customtkinter.CTkProgressBar(self.tabview.tab('Automatic Test'))
self.progressbar.grid(row=5, column=1, padx=5, pady=5, sticky="ew")
self.progressbar.configure(mode="determinnate", width=10)
self.progressbar.start()
# create widgits_at
for widgit in widgits_at:
if widgit == 'path':
widgits_at[widgit]['label'] = customtkinter.CTkLabel(self.tabview.tab('Automatic Test'), text=f'{widgit.upper()}', font=self.my_font)
widgits_at[widgit]['label'].grid(row=widgits_at[widgit]['row'], column=widgits_at[widgit]['col'], sticky='e', padx=(20, 5), pady=5)
widgits_at[widgit]['entry'] = customtkinter.CTkEntry(self.tabview.tab('Automatic Test'), width=670, placeholder_text=widgits_at[widgit]['text'], font=self.my_font)
widgits_at[widgit]['entry'].grid(row=widgits_at[widgit]['row'], column=widgits_at[widgit]['col']+1, columnspan=11, padx=(5, 10), pady=5, sticky='we')
widgits_at[widgit]['entry'].configure(state='disabled')
elif widgit in ['loadsel', ]:
widgits_at[widgit]['optionmenu'] = customtkinter.CTkOptionMenu(self.tabview.tab('Automatic Test'), button_color='#708090', fg_color='#778899', values=["tool33", "tool66", "tool100", "inertia"], width=self.w_param, font=self.my_font)
widgits_at[widgit]['optionmenu'].grid(row=widgits_at[widgit]['row'], column=widgits_at[widgit]['col'], padx=5, pady=5, sticky='we')
widgits_at[widgit]['optionmenu'].set(widgits_at[widgit]['text'])
widgits_at[widgit]['optionmenu'].configure(state='disabled')
# For automatic test tab END =====================================================================
# For durable_action tab START =====================================================================
# create progress bar
self.progressbar_da = customtkinter.CTkProgressBar(self.tabview.tab('Durable Action'))
self.progressbar_da.grid(row=2, column=1, padx=5, pady=5, sticky="ew")
self.progressbar_da.configure(mode="determinnate", width=self.w_param)
self.progressbar_da.start()
for widgit in widgits_da:
if widgit == 'path':
widgits_da[widgit]['label'] = customtkinter.CTkLabel(self.tabview.tab('Durable Action'), text=f'{widgit.upper()}', font=self.my_font)
widgits_da[widgit]['label'].grid(row=widgits_da[widgit]['row'], column=widgits_da[widgit]['col'], sticky='e', padx=(20, 5), pady=10)
widgits_da[widgit]['entry'] = customtkinter.CTkEntry(self.tabview.tab('Durable Action'), width=670, placeholder_text=widgits_da[widgit]['text'], font=self.my_font)
widgits_da[widgit]['entry'].grid(row=widgits_da[widgit]['row'], column=widgits_da[widgit]['col']+1, columnspan=11, padx=(5, 10), pady=10, sticky='we')
elif widgit in ['curvesel']:
widgits_da[widgit]['optionmenu'] = customtkinter.CTkOptionMenu(self.tabview.tab('Durable Action'), dynamic_resizing=False, button_color='#708090', fg_color='#778899', values=['device_servo_trq_feedback', '[max] device_servo_trq_feedback'], font=self.my_font)
widgits_da[widgit]['optionmenu'].grid(row=widgits_da[widgit]['row'], column=widgits_da[widgit]['col'], padx=5, pady=10, sticky='we')
widgits_da[widgit]['optionmenu'].set(widgits_da[widgit]['text'])
# For durable_action tab END =====================================================================
# create textbox
self.textbox = customtkinter.CTkTextbox(self, wrap='none', font=customtkinter.CTkFont(family="consolas", size=14), text_color="blue", fg_color='#E9E9E9', border_width=2, border_color='#CDCDCD', border_spacing=5)
self.textbox.grid(row=6, column=1, columnspan=13, ipadx=10, ipady=10, padx=10, pady=(5, 10), sticky='nsew')
self.textbox.configure(state='normal')
# =====================================================================
# version check
cur_vers = self.label_version.cget("text").replace('\n', ' @ ').replace("Vers: ", '').replace("Date: ", '')
url_vers = 'http://10.2.23.150:10008/vers'
try:
new_vers = urlopen(url_vers).read().decode('utf-8')
if cur_vers.strip() != new_vers.strip():
msg = f"""当前版本:{cur_vers}\n更新版本:{new_vers}\n\n请及时前往钉盘更新~~~"""
tkinter.messagebox.showwarning(title="版本更新", message=msg)
except:
tkinter.messagebox.showwarning(title="版本更新", message="连接服务器失败,无法确认当前是否是最新版本......")
# functions below ↓ ----------------------------------------------------------------------------------------
def create_canvas(self, _figure):
self.canvas = FigureCanvasTkAgg(_figure, self.tabview.tab('Durable Action'))
self.canvas.draw()
self.canvas.get_tk_widget().configure(height=600)
self.canvas.get_tk_widget().grid(row=3, column=1, rowspan=3, columnspan=13, padx=20, pady=10, sticky="nsew")
def create_plot(self):
rcParams['font.sans-serif'] = ['SimHei']
rcParams['axes.unicode_minus'] = False
rcParams['figure.dpi'] = 100
rcParams['font.size'] = 14
rcParams['lines.marker'] = 'o'
curvesel = widgits_da['curvesel']['optionmenu'].get()
while True:
if not self.hr.durable_lock:
self.hr.durable_lock = 1
if curvesel == 'device_servo_trq_feedback':
df = read_excel(clibs.durable_data_current_xlsx)
_title = 'device_servo_trq_feedback'
elif curvesel == '[max] device_servo_trq_feedback':
_title = '[max] device_servo_trq_feedback'
df = read_excel(clibs.durable_data_current_max_xlsx)
else:
_title = 'device_servo_trq_feedback'
df = read_excel(clibs.durable_data_current_xlsx)
self.hr.durable_lock = 0
break
else:
sleep(1)
if not df.equals(self.df_copy) or self.flg == 0 or curvesel != self.old_curve:
self.flg = 1
self.df_copy = df.copy()
self.old_curve = widgits_da['curvesel']['optionmenu'].get()
close('all')
_figure = figure(frameon=True, facecolor='#E9E9E9')
subplots_adjust(left=0.04, right=0.98, bottom=0.1, top=0.95)
_ = df['time'].to_list()
_xticks = [str(_i) for _i in _]
ax = _figure.add_subplot(1, 1, 1)
ax.set_xticks(range(len(_xticks)))
ax.set_xticklabels(_xticks)
df.plot(grid=True, x='time', y='axis1', ax=ax)
df.plot(grid=True, x='time', y='axis2', ax=ax)
df.plot(grid=True, x='time', y='axis3', ax=ax)
df.plot(grid=True, x='time', y='axis4', ax=ax)
df.plot(grid=True, x='time', y='axis5', ax=ax)
df.plot(grid=True, x='time', y='axis6', ax=ax, title=_title, legend='upper left', rot=30)
self.create_canvas(_figure)
def thread_it(self, func, *args):
""" 将函数打包进线程 """
self.myThread = Thread(target=func, args=args)
self.myThread.daemon = True # 主线程退出就直接让子线程跟随退出,不论是否运行完成。
self.myThread.start()
def segmented_button_callback(self):
_btn_funcs = {'trigger_estop': '触发急停', 'reset_estop': '恢复急停', 'get_state': '机器状态', 'warning_info': '告警信息'}
value = self.seg_button.get()
self.seg_button.configure(state='disabled')
# self.tabview.configure(state='disabled')
self.textbox.delete(index1='1.0', index2='end')
with open(clibs.heartbeat, 'r', encoding='utf-8') as f_h:
c_state = f_h.read().strip()
if c_state == '0' and value != '功能切换':
self.write2textbox("无法连接机器人检查是否已经使用Robot Assist软件连接机器重试中...", 0, 50, 'red')
else:
for _func in _btn_funcs:
if _btn_funcs[_func] == value:
btn_functions.main(self.hr, self.md, _func, self.write2textbox)
break
self.seg_button.configure(state='normal')
# self.tabview.configure(state='normal')
def detect_network(self):
df = DataFrame(clibs.durable_data_current)
df.to_excel(clibs.durable_data_current_xlsx, index=False)
df = DataFrame(clibs.durable_data_current_max)
df.to_excel(clibs.durable_data_current_max_xlsx, index=False)
with open(clibs.heartbeat, "w", encoding='utf-8') as f_hb:
f_hb.write('0')
self.hr = openapi.HmiRequest(self.write2textbox)
self.md = openapi.ModbusRequest(self.write2textbox)
while True:
if self.tabview.get() == 'Durable Action':
self.create_plot()
with open(clibs.heartbeat, 'r', encoding='utf-8') as f_hb:
c_state = f_hb.read().strip()
pb_color = 'green' if c_state == '1' else 'red'
self.progressbar.configure(progress_color=pb_color)
self.progressbar_da.configure(progress_color=pb_color)
if c_state == '0':
self.hr.t_bool = False
sleep(4)
del self.hr
self.hr = openapi.HmiRequest(self.write2textbox)
sleep(3)
def tabview_click(self):
self.initialization()
tab_name = self.tabview.get()
if tab_name == 'Data Process':
self.flg = 0
self.menu_main_dp.set("Start Here!")
elif tab_name == 'Automatic Test':
self.flg = 0
self.menu_main_at.set("Start Here!")
self.seg_button.configure(state='normal')
elif tab_name == 'Durable Action':
pass
def initialization(self):
tab_name = self.tabview.get()
self.textbox.delete(index1='1.0', index2='end')
if tab_name == 'Data Process':
for widgit in widgits_dp:
if widgit in ['path', 'dur']:
widgits_dp[widgit]['label'].configure(text=f'{widgit.upper()}', text_color='black')
widgits_dp[widgit]['entry'].delete(0, tkinter.END)
widgits_dp[widgit]['entry'].configure(placeholder_text=widgits_dp[widgit]['text'], state='normal')
widgits_dp[widgit]['entry'].configure(state='disabled')
elif widgit in ['vel', 'trq', 'trqh', 'estop']:
widgits_dp[widgit]['label'].configure(text=f'{widgit.upper()}', text_color="black")
widgits_dp[widgit]['optionmenu'].configure(state='normal')
widgits_dp[widgit]['optionmenu'].set('1')
widgits_dp[widgit]['optionmenu'].configure(state='disabled')
self.menu_sub_dp.grid_forget()
elif tab_name == 'Automatic Test':
for widgit in widgits_at:
if widgit in ['path', ]:
widgits_at[widgit]['label'].configure(text=f'{widgit.upper()}', text_color='black')
widgits_at[widgit]['entry'].delete(0, tkinter.END)
widgits_at[widgit]['entry'].configure(placeholder_text=widgits_at[widgit]['text'], state='normal')
widgits_at[widgit]['entry'].configure(state='disabled')
elif widgit in ['loadsel']:
widgits_at[widgit]['optionmenu'].configure(state='normal')
widgits_at[widgit]['optionmenu'].set(widgits_at[widgit]['text'])
widgits_at[widgit]['optionmenu'].configure(state='disabled')
self.seg_button.set("功能切换")
elif tab_name == 'Durable Action':
for widgit in widgits_da:
if widgit in ['path', ]:
widgits_da[widgit]['label'].configure(text=f'{widgit.upper()}', text_color='black')
widgits_da[widgit]['entry'].delete(0, tkinter.END)
widgits_da[widgit]['entry'].configure(placeholder_text=widgits_at[widgit]['text'], state='normal')
elif widgit in ['curvesel']:
widgits_da[widgit]['optionmenu'].configure(state='normal')
widgits_da[widgit]['optionmenu'].set(widgits_da[widgit]['text'])
def func_main_callback(self, func_name):
self.initialization()
tab_name = self.tabview.get()
if tab_name == 'Data Process':
if func_name == 'brake':
for widgit in widgits_dp:
if widgit in ['path']:
widgits_dp[widgit]['label'].configure(text_color='red')
widgits_dp[widgit]['entry'].configure(state='normal')
elif widgit in ['vel', 'trq', 'estop']:
widgits_dp[widgit]['label'].configure(text_color="red")
widgits_dp[widgit]['optionmenu'].configure(state='normal')
elif func_name == 'current':
self.menu_sub_dp = customtkinter.CTkOptionMenu(self.tabview.tab('Data Process'), values=["max", "avg", "cycle"], font=self.my_font, button_color='red', fg_color='green', command=self.func_sub_callback)
self.menu_sub_dp.grid(row=2, column=1, sticky='we', padx=5, pady=5)
self.menu_sub_dp.set("--select--")
self.menu_sub_dp.configure(text_color='yellow')
elif func_name == 'iso' or func_name == 'wavelogger':
for widgit in widgits_dp:
if widgit in ['path']:
widgits_dp[widgit]['label'].configure(text_color='red')
widgits_dp[widgit]['entry'].configure(state='normal')
else:
self.initialization()
self.menu_main_dp.set("Start Here!")
elif tab_name == 'Automatic Test':
if func_name == 'brake':
for widgit in widgits_at:
if widgit in ['path',]:
widgits_at[widgit]['label'].configure(text_color='red')
widgits_at[widgit]['entry'].delete(0, tkinter.END)
widgits_at[widgit]['entry'].configure(placeholder_text=widgits_at[widgit]['text'], state='normal')
widgits_at[widgit]['entry'].configure(state='normal')
elif widgit in ['loadsel', ]:
widgits_at[widgit]['optionmenu'].set(widgits_at[widgit]['text'])
widgits_at[widgit]['optionmenu'].configure(state='normal', text_color='red')
elif func_name == 'current':
for widgit in widgits_at:
if widgit in ['path',]:
widgits_at[widgit]['label'].configure(text_color='red')
widgits_at[widgit]['entry'].delete(0, tkinter.END)
widgits_at[widgit]['entry'].configure(placeholder_text=widgits_at[widgit]['text'], state='normal')
widgits_at[widgit]['entry'].configure(state='normal')
elif widgit in ['loadsel', ]:
widgits_at[widgit]['optionmenu'].set(widgits_at[widgit]['text'])
widgits_at[widgit]['optionmenu'].configure(state='normal', text_color='red')
else:
self.initialization()
self.menu_main_at.set("Start Here!")
def func_sub_callback(self, func_name):
if func_name == "max" or func_name == "avg":
for widgit in widgits_dp:
if widgit in ['path']:
widgits_dp[widgit]['label'].configure(text_color='red')
widgits_dp[widgit]['entry'].delete(0, tkinter.END)
widgits_dp[widgit]['entry'].configure(placeholder_text=widgits_dp[widgit]['text'], state='normal')
widgits_dp[widgit]['entry'].configure(state='normal')
elif widgit in ['dur']:
widgits_dp[widgit]['label'].configure(text_color='black')
widgits_dp[widgit]['entry'].delete(0, tkinter.END)
widgits_dp[widgit]['entry'].configure(placeholder_text=widgits_dp[widgit]['text'], state='normal')
widgits_dp[widgit]['entry'].configure(state='disabled')
elif widgit in ['vel', 'trqh', 'estop']:
widgits_dp[widgit]['label'].configure(text_color='black')
widgits_dp[widgit]['optionmenu'].set('1')
widgits_dp[widgit]['optionmenu'].configure(state='disabled')
elif widgit in ['trq']:
widgits_dp[widgit]['label'].configure(text_color='red')
widgits_dp[widgit]['optionmenu'].set('1')
widgits_dp[widgit]['optionmenu'].configure(state='normal')
elif func_name == 'cycle':
for widgit in widgits_dp:
if widgit in ['path', 'dur']:
color = 'blue' if widgit == 'dur' else 'red'
widgits_dp[widgit]['label'].configure(text_color=color)
widgits_dp[widgit]['entry'].delete(0, tkinter.END)
widgits_dp[widgit]['entry'].configure(placeholder_text=widgits_dp[widgit]['text'], state='normal')
widgits_dp[widgit]['entry'].configure(state='normal')
elif widgit in ['vel', 'trq', 'trqh']:
color = 'blue' if widgit == 'trqh' else 'red'
widgits_dp[widgit]['label'].configure(text_color=color)
widgits_dp[widgit]['optionmenu'].set('1')
widgits_dp[widgit]['optionmenu'].configure(state='normal')
elif widgit in ['estop']:
widgits_dp[widgit]['label'].configure(text_color="black")
widgits_dp[widgit]['optionmenu'].set('1')
widgits_dp[widgit]['optionmenu'].configure(state='disabled')
def write2textbox(self, text, wait=0, exitcode=0, color='blue', tab_name='Data Process'):
self.textbox.tag_add(color, 'insert', 'end')
self.textbox.tag_config(tagName=color, foreground=color)
tab_name_cur = self.tabview.get()
if tab_name == tab_name_cur:
if wait != 0:
self.textbox.insert(index='end', text=text, tags=color)
self.textbox.update()
self.textbox.see('end')
elif exitcode != 0:
self.textbox.insert(index='end', text=text + '\n', tags=color)
self.textbox.update()
self.textbox.see('end')
raise Exception(f"Error code: {exitcode}")
else:
self.textbox.insert(index='end', text=text + '\n', tags=color)
self.textbox.update()
self.textbox.see('end')
elif tab_name == 'openapi' and tab_name_cur == 'Automatic Test' or tab_name_cur == 'Durable Action':
if wait != 0:
self.textbox.insert(index='end', text=text, tags=color)
self.textbox.update()
self.textbox.see('end')
elif exitcode != 0:
self.textbox.insert(index='end', text=text + '\n', tags=color)
self.textbox.update()
self.textbox.see('end')
raise Exception(f"Error code: {exitcode}")
else:
self.textbox.insert(index='end', text=text + '\n', tags=color)
self.textbox.update()
self.textbox.see('end')
def is_float(self, flag, *args):
for item in args:
try:
if flag == 'optional':
item = 0 if item == '' else item
_ = float(item)
elif flag == 'required':
_ = float(item)
except Exception as Err:
tkinter.messagebox.showerror(title="参数错误", message="请检查对应参数是否填写正确!", )
self.write2textbox(f"错误信息:{Err}\n参数数据缺失,或者数据类型错误,更正后重新运行...\n", 0, 3, 'red')
return True
def check_param(self):
tab_name = self.tabview.get()
if tab_name == 'Data Process':
func_name = self.menu_main_dp.get()
if func_name == 'brake':
path = widgits_dp['path']['entry'].get().strip()
vel = widgits_dp['vel']['optionmenu'].get()
trq = widgits_dp['trq']['optionmenu'].get()
estop = widgits_dp['estop']['optionmenu'].get()
c1 = exists(path)
c2 = True if len({vel, trq, estop}) == 3 else False
if c1 and c2:
return 1, path, int(vel), int(trq), int(estop)
else:
return 0, 0
# =======================================================
elif func_name == 'current':
path = widgits_dp['path']['entry'].get().strip()
dur = widgits_dp['dur']['entry'].get().strip()
vel = widgits_dp['vel']['optionmenu'].get()
trq = widgits_dp['trq']['optionmenu'].get()
trqh = widgits_dp['trqh']['optionmenu'].get()
sub = self.menu_sub_dp.get()
c1 = exists(path)
c2 = sub in ['max', 'avg', 'cycle']
c3 = c4 = True
if sub == 'cycle':
c3 = True if len({vel, trq}) == 2 else False
c4 = self.is_float('optional', dur)
elif sub == 'max' or sub == 'avg':
pass
if c1 and c2 and c3 and c4:
dur = 0 if dur == '' else dur
return 2, path, sub, float(dur), int(vel), int(trq), int(trqh)
else:
return 0, 0
# =======================================================
elif func_name == 'iso':
path = widgits_dp['path']['entry'].get().strip()
if exists(path):
return 3, path
else:
return 0, 0
# =======================================================
elif func_name == 'wavelogger':
path = widgits_dp['path']['entry'].get().strip()
if exists(path):
return 4, path
else:
return 0, 0
# =======================================================
else:
return 0, 0
elif tab_name == 'Automatic Test':
func_name = self.menu_main_at.get()
if func_name == 'brake':
path = widgits_at['path']['entry'].get().strip()
loadsel = widgits_at['loadsel']['optionmenu'].get()
c1 = exists(path)
c2 = loadsel in ['tool100', 'tool66', 'tool33']
if c1 and c2:
return 5, path, loadsel
else:
return 0, 0
elif func_name == 'current':
path = widgits_at['path']['entry'].get().strip()
loadsel = widgits_at['loadsel']['optionmenu'].get()
c1 = exists(path)
c2 = loadsel in ['tool100', 'inertia']
if c1 and c2:
return 6, path, loadsel
else:
return 0, 0
else:
return 0, 0
elif tab_name == 'Durable Action':
path = widgits_da['path']['entry'].get().strip()
curvesel = widgits_da['curvesel']['optionmenu'].get()
c1 = exists(path)
c2 = curvesel in ['device_servo_trq_feedback', '[max] device_servo_trq_feedback']
if c1 and c2:
return 7, path, curvesel
else:
return 0, 0
def func_start_callback(self):
self.textbox.delete(index1='1.0', index2='end')
flag, *args = self.check_param()
func_dict = {
1: brake.main, 2: current.main, 3: iso.main, 4: wavelogger.main, 5: do_brake.main, 6: do_current.main,
7: factory_test.main
}
if flag == 1:
func_dict[flag](path=args[0], vel=args[1], trq=args[2], estop=args[3], w2t=self.write2textbox)
elif flag == 2:
func_dict[flag](path=args[0], sub=args[1], dur=args[2], vel=args[3], trq=args[4], trqh=args[5], w2t=self.write2textbox)
elif flag == 3:
func_dict[flag](path=args[0], w2t=self.write2textbox)
elif flag == 4:
func_dict[flag](path=args[0], w2t=self.write2textbox)
elif flag == 5:
self.pre_warning()
func_dict[flag](path=args[0], hr=self.hr, md=self.md, loadsel=args[1], w2t=self.write2textbox)
elif flag == 6:
self.pre_warning()
func_dict[flag](path=args[0], hr=self.hr, md=self.md, loadsel=args[1], w2t=self.write2textbox)
elif flag == 7:
self.pre_warning()
func_dict[flag](path=args[0], hr=self.hr, md=self.md, w2t=self.write2textbox)
else:
tkinter.messagebox.showerror(title="参数错误", message="请检查对应参数是否填写正确!", )
def pre_warning(self):
if self.tabview.get() == 'Durable Action':
df = DataFrame(clibs.durable_data_current)
df.to_excel(clibs.durable_data_current_xlsx, index=False)
df = DataFrame(clibs.durable_data_current_max)
df.to_excel(clibs.durable_data_current_max_xlsx, index=False)
if tkinter.messagebox.askyesno(title="开始运行", message="确认机器已按照测试规范更新固件,并提按照测试机型前修改好工程?"):
pass
else:
self.write2textbox("请按照测试规范更新机器固件,并在实际运行前确认工程已经修改完毕,以防撞机!!!", 0, 123, 'red', 'Automatic Test')
def func_check_callback(self):
self.textbox.delete(index1='1.0', index2='end')
flag, *args = self.check_param()
if flag:
tkinter.messagebox.showinfo(title="参数正确", message="所有参数形式上填写无误,可以开始运行!")
else:
tkinter.messagebox.showerror(title="参数错误", message="需要检查对应参数是否填写正确!", )
def func_log_callback(self):
content = self.textbox.get(index1='1.0', index2='end')
if len(content) > 1:
try:
now = strftime('%Y%m%d%H%M%S', localtime(time()))
log_name = f"{now}_aio.log"
with open(f'{log_name}', 'w', encoding='utf-8') as objlog:
objlog.write(content)
tkinter.messagebox.showinfo(title="保存成功", message=f'{log_name}已被保存存至↓↓↓\n{getcwd()}')
except Exception as Err:
self.write2textbox(Err)
tkinter.messagebox.showerror(title="保存失败", message="未能保存本次日志或未能完整保存请准备好相关数据联系fanmingfu@rokae.com查看详细信息", )
else:
tkinter.messagebox.showwarning(title="未能保存", message="日志数据为空,不可保存!")
def func_end_callback(self):
if tkinter.messagebox.askyesno(title="关闭程序", message="相关数据可能未保存,正在运行程序时有概率会损坏数据文件,确定要终止程序运行吗?"):
self.destroy()
if __name__ == "__main__":
aio = App()
aio.net_detect = Thread(target=aio.detect_network)
aio.net_detect.daemon = True
aio.net_detect.start()
aio.mainloop()