界面优化,监控逻辑优化
This commit is contained in:
244
aio.py
244
aio.py
@ -4,6 +4,7 @@ import os
|
||||
import re
|
||||
import sqlite3
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
from urllib import request
|
||||
import os.path
|
||||
@ -92,46 +93,43 @@ class MainWindow(main_window.Ui_MainWindow):
|
||||
|
||||
def __init__(self):
|
||||
super(MainWindow, self).__init__()
|
||||
self.close_on_net_error = None
|
||||
self.is_searching = False
|
||||
self.setupUi(self)
|
||||
self.predoes()
|
||||
self.pre_does()
|
||||
|
||||
def predoes(self):
|
||||
def pre_does(self):
|
||||
# ========================= treeview init =========================
|
||||
self.cb_data_current.setDisabled(True)
|
||||
self.setup_statusbar()
|
||||
self.setWindowIcon(QIcon(f"{clibs.PREFIX}/media/icon.ico"))
|
||||
self.treew_log.header().setFont(QFont("Arial", 12, QFont.Weight.Bold))
|
||||
header = self.treew_log.header()
|
||||
for i in range(self.treew_log.columnCount()):
|
||||
header.setSectionResizeMode(i, QHeaderView.ResizeMode.ResizeToContents)
|
||||
self.md_btn.setStyleSheet("background-color: DarkGrey; color: white;")
|
||||
self.ec_btn.setStyleSheet("background-color: DarkGrey; color: white;")
|
||||
# ========================= stylesheet =========================
|
||||
with open(f"{clibs.PREFIX}/qss/style.qss", mode="r", encoding="utf-8") as f_qss:
|
||||
style_sheet = f_qss.read()
|
||||
self.setStyleSheet(style_sheet)
|
||||
# ========================= clibs =========================
|
||||
self.setup_statusbar()
|
||||
self.setWindowIcon(QIcon(f"{clibs.PREFIX}/media/icon.ico"))
|
||||
# ========================= styleSheet =========================
|
||||
tws = [self.tw_funcs, self.tw_docs]
|
||||
for tw in tws:
|
||||
tw.setStyleSheet("""
|
||||
QTabBar::tab:selected {
|
||||
background: #0078D4;
|
||||
color: white;
|
||||
border-radius: 4px;
|
||||
}
|
||||
QTabBar::tab:!selected {
|
||||
background: #F0F0F0;
|
||||
color: #333;
|
||||
}
|
||||
QTabWidget::pane {
|
||||
border: 1px solid #CCCCCC;
|
||||
}
|
||||
""")
|
||||
|
||||
# ============================↓↓↓debug↓↓↓============================
|
||||
# print(f"self.cb_data_func.currentIndex() = {self.cb_data_func.currentIndex()}")
|
||||
logger_handler = clibs.LoggerHandler()
|
||||
logger_handler.signal.connect(self.w2t)
|
||||
clibs.logger = logger_handler.logger
|
||||
# ========================= detection =========================
|
||||
self.detection_thread = StateDetection()
|
||||
self.detection_thread.finished.connect(self.prog_done_detection)
|
||||
self.detection_thread.start()
|
||||
# ========================= debug =========================
|
||||
# for i in range(105):
|
||||
# clibs.logger("DEBUG", "aio", "debug testing log for aio", color="gray")
|
||||
# clibs.logger("INFO", "clibs", "info testing log for clibs", color="green")
|
||||
# clibs.logger("WARNING", "iso", "warning testing log for aio", color="yellow")
|
||||
# # clibs.logger("ERROR", "openapi", "error testing log for aio", color="red")
|
||||
|
||||
def run_program_thread(self, prog, idx, prog_done, reserved):
|
||||
if idx != -98 and idx != -97:
|
||||
self.tw_docs.setCurrentIndex(0)
|
||||
if idx != -99 and idx != -98:
|
||||
prog.output.connect(self.w2t)
|
||||
|
||||
self.t = QThread(self)
|
||||
self.run = RunProg()
|
||||
@ -191,7 +189,13 @@ class MainWindow(main_window.Ui_MainWindow):
|
||||
self.run_program_thread(factory_test.DoFactoryTest(self.le_durable_path.text(), self.le_durable_interval.text(), self.get_checkbox_states()), 6, prog_done, None)
|
||||
|
||||
def prog_stop(self):
|
||||
QMessageBox.warning(self, "停止运行", "运行过程中不建议停止运行,可能会损坏文件,如果确实需要停止运行,可以直接关闭窗口!")
|
||||
if sum(clibs.running) == 0:
|
||||
return
|
||||
|
||||
idx = clibs.running.index(1)
|
||||
clibs.running[idx] = 0
|
||||
clibs.logger("INFO", "aio", f"{clibs.functions[idx]}程序已经停止,涉及Excel文件读写时可能会损坏该文件!", "red")
|
||||
# QMessageBox.warning(self, "停止运行", "运行过程中不建议停止运行,可能会损坏文件,如果确实需要停止运行,可以直接关闭窗口!")
|
||||
|
||||
def prog_reset(self):
|
||||
self.tw_docs.setCurrentIndex(0)
|
||||
@ -205,7 +209,6 @@ class MainWindow(main_window.Ui_MainWindow):
|
||||
idx_dict[tab_index].setText(dir_path)
|
||||
|
||||
def curve_draw(self):
|
||||
output = Signal(str, str)
|
||||
procs = self.get_checkbox_states()
|
||||
dir_path = self.le_durable_path.text()
|
||||
curve_map = {
|
||||
@ -230,7 +233,7 @@ class MainWindow(main_window.Ui_MainWindow):
|
||||
self.w2t(f"需要选择至少一个功能,才能继续绘图......", "red")
|
||||
return
|
||||
|
||||
_, files = clibs.traversal_files(dir_path, output)
|
||||
_, files = clibs.traversal_files(dir_path)
|
||||
csv_files = []
|
||||
for file in files:
|
||||
if file.endswith(".csv"):
|
||||
@ -320,7 +323,7 @@ class MainWindow(main_window.Ui_MainWindow):
|
||||
end = first_id-1 if first_id-1 > 0 else None
|
||||
if end is None:
|
||||
return
|
||||
start = end-100 if end-100 > 0 else 1
|
||||
start = end-100+1 if end-100+1 > 0 else 1
|
||||
|
||||
clibs.cursor.execute(f"SELECT * FROM logs WHERE id BETWEEN {start} AND {end}")
|
||||
records = clibs.cursor.fetchall()
|
||||
@ -397,12 +400,12 @@ class MainWindow(main_window.Ui_MainWindow):
|
||||
line_number = self.treew_log.topLevelItemCount()
|
||||
last_id = int(self.treew_log.topLevelItem(line_number-1).text(0))
|
||||
start = last_id + 1 if last_id % 100 == 0 else last_id - last_id % 100 + 1
|
||||
end = int(start) + 100
|
||||
if int(start) <= len_records:
|
||||
end = int(start) + 100 - 1
|
||||
if start <= len_records:
|
||||
clibs.cursor.execute(f"select * from logs where id between {start} and {end}")
|
||||
records = clibs.cursor.fetchall()
|
||||
pages_all = len_records // 100 if len_records % 100 == 0 else len_records // 100 + 1
|
||||
current_page = int(start) // 100 if int(start) % 100 == 0 else int(start) // 100 + 1
|
||||
current_page = start // 100 if start % 100 == 0 else start // 100 + 1
|
||||
return pages_all, current_page, records
|
||||
|
||||
elif self.is_searching is True:
|
||||
@ -688,25 +691,26 @@ class MainWindow(main_window.Ui_MainWindow):
|
||||
|
||||
flag, result, ret, error, idx, network = results
|
||||
if flag is False:
|
||||
...
|
||||
# self.w2t(f"{network.upper()}连接失败", "red")
|
||||
self.w2t(f"{network.upper()}连接失败", "red")
|
||||
elif flag is True:
|
||||
clibs.status[network] = 1
|
||||
if network == "hmi":
|
||||
self.btn_hmi_conn.setText("断开")
|
||||
self.hmi_state.setText(f'<img src="{clibs.PREFIX}/media/green.png" width="10" height="10" /><font face="consolas" size="4"><b>HR </b></font>')
|
||||
clibs.c_hr = result
|
||||
elif network == "md":
|
||||
self.btn_md_conn.setText("断开")
|
||||
self.md_state.setText(f'<img src="{clibs.PREFIX}/media/green.png" width="10" height="10" /><font face="consolas" size="4"><b>MD </b></font>')
|
||||
clibs.c_md = result
|
||||
elif network == "ec":
|
||||
self.btn_ec_conn.setText("断开")
|
||||
self.ec_state.setText(f'<img src="{clibs.PREFIX}/media/green.png" width="10" height="10" /><font face="consolas" size="4"><b>EC </b></font>')
|
||||
clibs.c_ec = result
|
||||
|
||||
def prog_done_disconn(self, results):
|
||||
self.btn_hmi_conn.setDisabled(False)
|
||||
self.btn_md_conn.setDisabled(False)
|
||||
self.btn_ec_conn.setDisabled(False)
|
||||
|
||||
flag, result, ret, error, idx, network = results
|
||||
if flag is False:
|
||||
self.w2t(f"{network.upper()}断开连接失败", "red")
|
||||
@ -714,13 +718,16 @@ class MainWindow(main_window.Ui_MainWindow):
|
||||
clibs.status[network] = 0
|
||||
if network == "hmi":
|
||||
self.btn_hmi_conn.setText("连接")
|
||||
clibs.c_hr = result
|
||||
self.hmi_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>HR </b></font>')
|
||||
clibs.c_hr = None
|
||||
elif network == "md":
|
||||
self.btn_md_conn.setText("连接")
|
||||
clibs.c_md = result
|
||||
self.md_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>MD </b></font>')
|
||||
clibs.c_md = None
|
||||
elif network == "ec":
|
||||
self.btn_ec_conn.setText("连接")
|
||||
clibs.c_ec = result
|
||||
self.ec_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>EC </b></font>')
|
||||
clibs.c_ec = None
|
||||
|
||||
def hmi_conn(self):
|
||||
self.btn_hmi_conn.setDisabled(True)
|
||||
@ -759,22 +766,51 @@ class MainWindow(main_window.Ui_MainWindow):
|
||||
self.run_program_thread(clibs.c_ec.close, -99, self.prog_done_disconn, "ec")
|
||||
|
||||
def hmi_page(self):
|
||||
self.pte_md_send.clear()
|
||||
self.pte_md_recv.clear()
|
||||
self.pte_ec_send.clear()
|
||||
self.pte_ec_recv.clear()
|
||||
self.tw_funcs.setCurrentIndex(3)
|
||||
self.sw_network.setCurrentIndex(0)
|
||||
self.hmi_btn.setStyleSheet("background-color: DarkCyan; color: white;")
|
||||
self.md_btn.setStyleSheet("background-color: DarkGrey; color: white;")
|
||||
self.ec_btn.setStyleSheet("background-color: DarkGrey; color: white;")
|
||||
|
||||
def md_page(self):
|
||||
self.pte_hmi_send.clear()
|
||||
self.pte_hmi_recv.clear()
|
||||
self.pte_ec_send.clear()
|
||||
self.pte_ec_recv.clear()
|
||||
self.tw_funcs.setCurrentIndex(3)
|
||||
self.sw_network.setCurrentIndex(1)
|
||||
self.hmi_btn.setStyleSheet("background-color: DarkGrey; color: white;")
|
||||
self.md_btn.setStyleSheet("background-color: DarkCyan; color: white;")
|
||||
self.ec_btn.setStyleSheet("background-color: DarkGrey; color: white;")
|
||||
|
||||
def ec_page(self):
|
||||
self.pte_md_send.clear()
|
||||
self.pte_md_recv.clear()
|
||||
self.pte_hmi_send.clear()
|
||||
self.pte_hmi_recv.clear()
|
||||
self.tw_funcs.setCurrentIndex(3)
|
||||
self.sw_network.setCurrentIndex(2)
|
||||
self.hmi_btn.setStyleSheet("background-color: DarkGrey; color: white;")
|
||||
self.md_btn.setStyleSheet("background-color: DarkGrey; color: white;")
|
||||
self.ec_btn.setStyleSheet("background-color: DarkCyan; color: white;")
|
||||
|
||||
def prog_done_hmi_send(self, results):
|
||||
_, result, ret, error, idx, (msg_id, flag) = results
|
||||
if _ is False:
|
||||
self.btn_hmi_send.setDisabled(False)
|
||||
clibs.logger("INFO", "aio", f"hmi: [send] 请求发送失败 {msg_id}", "red")
|
||||
return
|
||||
|
||||
records = clibs.c_hr.get_from_id(msg_id)
|
||||
for record in records:
|
||||
if "请求发送成功" not in record[0]:
|
||||
self.pte_him_recv.clear()
|
||||
self.pte_hmi_recv.clear()
|
||||
response = eval(record[0]) if flag == 0 else json.loads(record[0])
|
||||
self.pte_him_recv.appendPlainText(json.dumps(response, indent=4, separators=(",", ":")))
|
||||
self.pte_hmi_recv.appendPlainText(json.dumps(response, indent=4, separators=(",", ":")))
|
||||
else:
|
||||
self.btn_hmi_send.setDisabled(False)
|
||||
|
||||
@ -852,9 +888,7 @@ class MainWindow(main_window.Ui_MainWindow):
|
||||
self.pte_ec_recv.clear()
|
||||
cmd = self.pte_ec_send.toPlainText().strip()
|
||||
try:
|
||||
clibs.c_ec.s_string(cmd)
|
||||
time.sleep(clibs.INTERVAL/2)
|
||||
result = clibs.c_ec.r_string(cmd)
|
||||
result = clibs.c_ec.sr_string(cmd)
|
||||
self.pte_ec_recv.appendPlainText(str(result))
|
||||
except Exception as err:
|
||||
self.pte_ec_recv.appendPlainText(f"操作失败:{err}")
|
||||
@ -862,7 +896,7 @@ class MainWindow(main_window.Ui_MainWindow):
|
||||
def hmi_cb_change(self):
|
||||
cmd = self.cb_hmi_cmd.currentText()
|
||||
self.pte_hmi_send.clear()
|
||||
self.pte_him_recv.clear()
|
||||
self.pte_hmi_recv.clear()
|
||||
with open(f"{clibs.PREFIX}/files/protocols/hmi/{cmd}.json", mode="r", encoding="utf-8") as f_hmi:
|
||||
hmi_dict = json.load(f_hmi)
|
||||
t = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")
|
||||
@ -886,6 +920,13 @@ class MainWindow(main_window.Ui_MainWindow):
|
||||
c_send = f_md.read()
|
||||
self.pte_ec_send.appendPlainText(c_send)
|
||||
|
||||
def data_cb_change(self):
|
||||
proc = self.cb_data_func.currentText()
|
||||
if proc != "转矩":
|
||||
self.cb_data_current.setDisabled(True)
|
||||
else:
|
||||
self.cb_data_current.setDisabled(False)
|
||||
|
||||
def check_interval(self):
|
||||
try:
|
||||
interval = float(self.le_durable_interval.text())
|
||||
@ -894,13 +935,21 @@ class MainWindow(main_window.Ui_MainWindow):
|
||||
interval = clibs.CYCLE
|
||||
self.le_durable_interval.setText(str(interval))
|
||||
|
||||
def state_detection(self):
|
||||
while True:
|
||||
time.sleep(clibs.INTERVAL)
|
||||
if clibs.status["hmi"] == 0 and self.btn_hmi_conn.text() == "断开":
|
||||
self.btn_hmi_conn.setText("连接")
|
||||
elif clibs.status["hmi"] == 1 and self.btn_hmi_conn.text() == "连接":
|
||||
self.btn_hmi_conn.setText("断开")
|
||||
def prog_done_detection(self, finished):
|
||||
if clibs.status["hmi"] == 0:
|
||||
self.btn_hmi_conn.setText("连接")
|
||||
self.hmi_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>HR </b></font>')
|
||||
if clibs.status["md"] == 0:
|
||||
self.btn_md_conn.setText("连接")
|
||||
self.md_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>MD </b></font>')
|
||||
if clibs.status["ec"] == 0:
|
||||
self.btn_ec_conn.setText("连接")
|
||||
self.ec_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>EC </b></font>')
|
||||
# ============= Program running status =============
|
||||
if sum(clibs.running) == 1:
|
||||
self.run_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>BUSY</b></font>')
|
||||
else:
|
||||
self.run_state.setText(f'<img src="{clibs.PREFIX}/media/green.png" width="10" height="10" /><font face="consolas" size="4"><b>IDLE</b></font>')
|
||||
|
||||
def closeEvent(self, event):
|
||||
idx = -1 if clibs.running.count(1) == 0 else clibs.running.index(1)
|
||||
@ -913,7 +962,7 @@ class MainWindow(main_window.Ui_MainWindow):
|
||||
|
||||
clibs.conn.backup(target=disk_conn, pages=1, progress=None)
|
||||
|
||||
_, logs = clibs.traversal_files(".", None)
|
||||
_, logs = clibs.traversal_files(".")
|
||||
logs.sort()
|
||||
while len(logs) > 10:
|
||||
_ = logs.pop(0)
|
||||
@ -938,24 +987,68 @@ class MainWindow(main_window.Ui_MainWindow):
|
||||
with open(f"{clibs.PREFIX}/files/version/server_vers", mode="r", encoding="utf-8") as f_server:
|
||||
server_vers = f_server.read().strip()
|
||||
|
||||
update_label = QLabel()
|
||||
version_label = QLabel()
|
||||
self.statusbar.addWidget(version_label, 0)
|
||||
self.statusbar.addPermanentWidget(update_label, 0) # 添加到右侧
|
||||
self.update_label, self.hmi_state, self.md_state, self.ec_state, self.run_state, self.version_label = QLabel(), ClickableLabel(), ClickableLabel(), ClickableLabel(), QLabel(), QLabel()
|
||||
self.statusbar.addWidget(self.version_label, 0)
|
||||
self.statusbar.addWidget(self.hmi_state, 0)
|
||||
self.statusbar.addWidget(self.md_state, 0)
|
||||
self.statusbar.addWidget(self.ec_state, 0)
|
||||
self.statusbar.addWidget(self.run_state, 0)
|
||||
self.statusbar.addPermanentWidget(self.update_label, 0) # 添加到右侧
|
||||
self.hmi_state.clicked.connect(self.hmi_page)
|
||||
self.md_state.clicked.connect(self.md_page)
|
||||
self.ec_state.clicked.connect(self.ec_page)
|
||||
|
||||
if local_vers == server_vers:
|
||||
update_label.setText(f'<img src="{clibs.PREFIX}/media/updated.png" width="12" height="12" /><font color="#0D8A3D" face="consolas" size="4"><b> 当前是最新版本,继续保持! </b></font>')
|
||||
self.update_label.setText(f'<img src="{clibs.PREFIX}/media/updated.png" width="14" height="14" style="vertical-align: middle;" /><span style="vertical-align: middle; font-size: 14px; font-weight: bold; color: #0D8A3D;"> Current is the latest version!</span>')
|
||||
elif local_vers > server_vers:
|
||||
pass
|
||||
elif local_vers < server_vers:
|
||||
update_label.setText(f'''<a href="https://www.rustle.cc/aio.zip" style="text-decoration: none;"><img src="{clibs.PREFIX}/media/upgrade.png" width="12" height="12" /><font color="#D81E06" face="consolas" size="4"><b> v{server_vers.split('@')[0]}已经发布,尽快更新至最新版本! </b></font></a>''')
|
||||
self.update_label.setText(f'''<a href="https://www.rustle.cc/aio.zip" style="text-decoration: none;"><img src="{clibs.PREFIX}/media/upgrade.png" width="14" height="14" style="vertical-align: middle;" /><span style="vertical-align: middle; font-size: 14px; font-weight: bold; color: #D81E06;"> v{server_vers.split('@')[0]} has been released, update ASAP!</span></a>''')
|
||||
|
||||
version_label.setText(f'<font color="black" face="consolas" size="4"><b> {vers_info}</b></font>')
|
||||
update_label.setOpenExternalLinks(True) # 允许超链接在浏览器中打开
|
||||
# update_label.setAlignment(Qt.AlignmentFlag.AlignVCenter | Qt.AlignmentFlag.AlignRight)
|
||||
update_label.setStyleSheet("border: none;")
|
||||
update_label.setFrameShape(QFrame.Shape.NoFrame)
|
||||
update_label.setFrameShadow(QFrame.Shadow.Plain)
|
||||
self.close_on_net_error = False
|
||||
self.version_label.setText(f'<font color="black" face="consolas" size="4"><b>{vers_info} </b></font>')
|
||||
self.hmi_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>HR </b></font>')
|
||||
self.md_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>MD </b></font>')
|
||||
self.ec_state.setText(f'<img src="{clibs.PREFIX}/media/red.png" width="10" height="10" /><font face="consolas" size="4"><b>EC </b></font>')
|
||||
self.run_state.setText(f'<img src="{clibs.PREFIX}/media/green.png" width="10" height="10" /><font face="consolas" size="4"><b>IDLE</b></font>')
|
||||
self.update_label.setOpenExternalLinks(True) # 允许超链接在浏览器中打开
|
||||
|
||||
|
||||
class StateDetection(QThread):
|
||||
finished = Signal(bool)
|
||||
|
||||
def __init__(self, /):
|
||||
super().__init__()
|
||||
|
||||
def run(self):
|
||||
while True:
|
||||
time.sleep(clibs.INTERVAL*2)
|
||||
# ============= HMI connection status =============
|
||||
try:
|
||||
clibs.c_hr.execution("controller.heart")
|
||||
except:
|
||||
clibs.status["hmi"] = 0
|
||||
# ============= MD connection status =============
|
||||
try:
|
||||
clibs.c_md.c.read_holding_registers(40503, count=1).registers[0]
|
||||
except:
|
||||
clibs.status["md"] = 0
|
||||
# ============= EC connection status =============
|
||||
try:
|
||||
clibs.c_ec.sr_string("controller_is_running")
|
||||
except:
|
||||
clibs.status["ec"] = 0
|
||||
|
||||
self.finished.emit(True)
|
||||
|
||||
|
||||
class ClickableLabel(QLabel):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
self.clicked.emit()
|
||||
|
||||
clicked = Signal()
|
||||
|
||||
|
||||
class InitWork(QThread):
|
||||
@ -994,13 +1087,16 @@ class SplashScreen(QApplication):
|
||||
self.splash.show()
|
||||
self.splash.showMessage("正在加载资源.....", Qt.AlignmentFlag.AlignBottom | Qt.AlignmentFlag.AlignHCenter, Qt.GlobalColor.white)
|
||||
|
||||
self.t = QThread(self)
|
||||
self.run = InitWork()
|
||||
self.run.moveToThread(self.t)
|
||||
self.run.completed.connect(self.prog_done)
|
||||
self.action.connect(self.run.program)
|
||||
self.t.start()
|
||||
self.action.emit(1)
|
||||
# self.t = QThread(self)
|
||||
# self.run = InitWork()
|
||||
# self.run.moveToThread(self.t)
|
||||
# self.run.completed.connect(self.prog_done)
|
||||
# self.action.connect(self.run.program)
|
||||
# self.t.start()
|
||||
# self.action.emit(1)
|
||||
|
||||
# without validation of server version
|
||||
self.prog_done("true")
|
||||
|
||||
def prog_done(self, result):
|
||||
if result == "false" or result == "":
|
||||
|
Reference in New Issue
Block a user