feat(DLPilot): 新增电源检查卡(PD 自检序列 M301/M302 状态位 + FPDO, 功率检测占位); 窗口加高; 版本 0.3.4 打包
This commit is contained in:
Binary file not shown.
+118
-6
@@ -33,8 +33,14 @@ MONO = ('Consolas', 12)
|
|||||||
BOLD = ('Microsoft YaHei UI', 13, 'bold')
|
BOLD = ('Microsoft YaHei UI', 13, 'bold')
|
||||||
TITLE_FONT = ('Microsoft YaHei UI', 18, 'bold')
|
TITLE_FONT = ('Microsoft YaHei UI', 18, 'bold')
|
||||||
|
|
||||||
|
# 电源自检状态位配色: 灰=未检测, 绿=正常回包, 红=错误/超时
|
||||||
|
CHIP_IDLE = ('gray78', 'gray34')
|
||||||
|
CHIP_IDLE_TEXT = ('#333333', '#E8E8E8')
|
||||||
|
CHIP_OK = '#2FA574'
|
||||||
|
CHIP_ERR = '#D9534F'
|
||||||
|
|
||||||
APP_NAME = 'DLPilot'
|
APP_NAME = 'DLPilot'
|
||||||
APP_VERSION = '0.3.3'
|
APP_VERSION = '0.3.4'
|
||||||
REPO_URL = 'https://gitea.hulk.wang/hulk/LT8619C_Debug_Tools'
|
REPO_URL = 'https://gitea.hulk.wang/hulk/LT8619C_Debug_Tools'
|
||||||
|
|
||||||
|
|
||||||
@@ -73,8 +79,8 @@ class App(ctk.CTk):
|
|||||||
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID('hulk.DLPilot')
|
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID('hulk.DLPilot')
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
self.geometry('1440x920')
|
self.geometry('1440x1010') # 右列新增电源检查卡, 窗口加高
|
||||||
self.minsize(1180, 800)
|
self.minsize(1180, 860)
|
||||||
ic = get_icon_path()
|
ic = get_icon_path()
|
||||||
if ic:
|
if ic:
|
||||||
try:
|
try:
|
||||||
@@ -93,6 +99,8 @@ class App(ctk.CTk):
|
|||||||
self._dlpc_connected = False
|
self._dlpc_connected = False
|
||||||
self._poll_job = None
|
self._poll_job = None
|
||||||
self._tl_order = [] # 温度查询应答顺序: 'DMD'/'LAMP' 先到先得
|
self._tl_order = [] # 温度查询应答顺序: 'DMD'/'LAMP' 先到先得
|
||||||
|
self._pd_seq = [] # 电源自检待执行步骤: [(命令, kind), ...]
|
||||||
|
self._pd_timer = None # 自检单步超时定时器
|
||||||
self._build()
|
self._build()
|
||||||
self._load_displays()
|
self._load_displays()
|
||||||
# 主窗口按 ESC 也能关闭所有投屏(投屏窗口失焦时的兜底出口)
|
# 主窗口按 ESC 也能关闭所有投屏(投屏窗口失焦时的兜底出口)
|
||||||
@@ -319,6 +327,31 @@ class App(ctk.CTk):
|
|||||||
self._dlpc_log('帧格式: D5 01 LEN <命令> CRC / B5 TYPE LEN <payload> CRC, '
|
self._dlpc_log('帧格式: D5 01 LEN <命令> CRC / B5 TYPE LEN <payload> CRC, '
|
||||||
'累加和校验; 全部命令见 README"光机控制"')
|
'累加和校验; 全部命令见 README"光机控制"')
|
||||||
|
|
||||||
|
# -- 电源检查 --
|
||||||
|
card, c = self._card(col, '电源检查 — PD 自检 / 功率读数')
|
||||||
|
card.grid(row=2, column=0, sticky='ew', pady=(10, 0))
|
||||||
|
rowp1 = ctk.CTkFrame(c, fg_color='transparent')
|
||||||
|
rowp1.pack(fill='x')
|
||||||
|
ctk.CTkButton(rowp1, text='电源自检', width=90,
|
||||||
|
command=self._pd_selftest).pack(side='left')
|
||||||
|
ctk.CTkLabel(rowp1, text='协议:').pack(side='left', padx=(10, 4))
|
||||||
|
self.chip_pd = ctk.CTkLabel(rowp1, text='PD', width=60, height=26,
|
||||||
|
corner_radius=6, fg_color=CHIP_IDLE,
|
||||||
|
text_color=CHIP_IDLE_TEXT)
|
||||||
|
self.chip_pd.pack(side='left')
|
||||||
|
self.var_fpdo = tk.StringVar(value='FPDO: —')
|
||||||
|
ctk.CTkLabel(rowp1, textvariable=self.var_fpdo, anchor='w',
|
||||||
|
text_color='#3B8ED0').pack(side='left', padx=(12, 0))
|
||||||
|
rowp2 = ctk.CTkFrame(c, fg_color='transparent')
|
||||||
|
rowp2.pack(fill='x', pady=(6, 0))
|
||||||
|
ctk.CTkButton(rowp2, text='功率检测', width=90,
|
||||||
|
command=self._pwr_query).pack(side='left')
|
||||||
|
self.var_pwr = tk.StringVar(value='电压: — 电流: — 功率: —')
|
||||||
|
ctk.CTkLabel(rowp2, textvariable=self.var_pwr, height=28,
|
||||||
|
corner_radius=6, fg_color=('#F2F2F2', '#181818'),
|
||||||
|
anchor='w').pack(side='left', fill='x', expand=True,
|
||||||
|
padx=(8, 0))
|
||||||
|
|
||||||
# -- 光机命令 --
|
# -- 光机命令 --
|
||||||
# 标题行右侧: 电流实时读数 + 查电流按钮(okR..G..B.. 应答解析)
|
# 标题行右侧: 电流实时读数 + 查电流按钮(okR..G..B.. 应答解析)
|
||||||
cur_frame = ctk.CTkFrame(self, fg_color='transparent')
|
cur_frame = ctk.CTkFrame(self, fg_color='transparent')
|
||||||
@@ -329,7 +362,7 @@ class App(ctk.CTk):
|
|||||||
command=self._query_current).pack(side='left', padx=(6, 0))
|
command=self._query_current).pack(side='left', padx=(6, 0))
|
||||||
card, c = self._card(col,'光机命令 — 预设 / 自定义 / TEC',
|
card, c = self._card(col,'光机命令 — 预设 / 自定义 / TEC',
|
||||||
right_widget=cur_frame)
|
right_widget=cur_frame)
|
||||||
card.grid(row=2, column=0, sticky='ew', pady=(10, 0))
|
card.grid(row=3, column=0, sticky='ew', pady=(10, 0))
|
||||||
row1 = ctk.CTkFrame(c, fg_color='transparent')
|
row1 = ctk.CTkFrame(c, fg_color='transparent')
|
||||||
row1.pack(fill='x')
|
row1.pack(fill='x')
|
||||||
for name, cmd in (('开光机', 'M730S0'), ('关光机', 'M730S1'),
|
for name, cmd in (('开光机', 'M730S0'), ('关光机', 'M730S1'),
|
||||||
@@ -386,7 +419,7 @@ class App(ctk.CTk):
|
|||||||
|
|
||||||
# -- 快捷滑条 --
|
# -- 快捷滑条 --
|
||||||
card, c = self._card(col,'快捷滑条 — 光强 / 定时投光 / TEC 温度')
|
card, c = self._card(col,'快捷滑条 — 光强 / 定时投光 / TEC 温度')
|
||||||
card.grid(row=3, column=0, sticky='ew', pady=(10, 0))
|
card.grid(row=4, column=0, sticky='ew', pady=(10, 0))
|
||||||
rowa = ctk.CTkFrame(c, fg_color='transparent')
|
rowa = ctk.CTkFrame(c, fg_color='transparent')
|
||||||
rowa.pack(fill='x')
|
rowa.pack(fill='x')
|
||||||
ctk.CTkLabel(rowa, text='光强(54-800):').pack(side='left')
|
ctk.CTkLabel(rowa, text='光强(54-800):').pack(side='left')
|
||||||
@@ -733,6 +766,9 @@ class App(ctk.CTk):
|
|||||||
elif kind == 'current':
|
elif kind == 'current':
|
||||||
self.var_current.set(text)
|
self.var_current.set(text)
|
||||||
self._dlpc_log(text)
|
self._dlpc_log(text)
|
||||||
|
if (self._pd_seq and kind == 'event'
|
||||||
|
and text.startswith('← ')):
|
||||||
|
self._pd_on_reply(text) # 电源自检: 应答路由到状态机
|
||||||
except queue.Empty:
|
except queue.Empty:
|
||||||
pass
|
pass
|
||||||
connected = self.dlpc.is_connected()
|
connected = self.dlpc.is_connected()
|
||||||
@@ -814,6 +850,80 @@ class App(ctk.CTk):
|
|||||||
if cmd:
|
if cmd:
|
||||||
self._dlpc_send(cmd)
|
self._dlpc_send(cmd)
|
||||||
|
|
||||||
|
# -- 电源检查: 自检序列 + 功率读数 --
|
||||||
|
|
||||||
|
def _pd_selftest(self):
|
||||||
|
"""电源自检: 按序自动执行 M301/M302(电压检测命令待固件定义后在序列追加),
|
||||||
|
每步应答刷新状态位: 绿=正常回包, 红=错误/超时, 灰=未检测"""
|
||||||
|
if not self.dlpc.is_connected():
|
||||||
|
self.lbl_dlpc_st.configure(text='未连接串口', text_color='#E07A3F')
|
||||||
|
return
|
||||||
|
if self._pd_seq:
|
||||||
|
return # 进行中, 忽略重复触发
|
||||||
|
self._pd_seq = [('M301', 'pd'), ('M302', 'fpdo')]
|
||||||
|
self._pd_chip_reset()
|
||||||
|
self._dlpc_log('电源自检: 开始')
|
||||||
|
self._pd_step_next()
|
||||||
|
|
||||||
|
def _pd_chip_reset(self):
|
||||||
|
self.chip_pd.configure(fg_color=CHIP_IDLE,
|
||||||
|
text_color=CHIP_IDLE_TEXT, text='PD')
|
||||||
|
self.var_fpdo.set('FPDO: —')
|
||||||
|
|
||||||
|
def _pd_step_next(self):
|
||||||
|
if not self._pd_seq:
|
||||||
|
self._dlpc_log('电源自检: 完成')
|
||||||
|
return
|
||||||
|
self.dlpc.send(self._pd_seq[0][0])
|
||||||
|
self._pd_timer = self.after(3000, lambda: self._pd_step_done(False, '超时'))
|
||||||
|
|
||||||
|
def _pd_on_reply(self, line):
|
||||||
|
self._pd_step_done(line.startswith('← ok'), line)
|
||||||
|
|
||||||
|
def _pd_step_done(self, ok, line=''):
|
||||||
|
if not self._pd_seq:
|
||||||
|
return
|
||||||
|
if self._pd_timer:
|
||||||
|
self.after_cancel(self._pd_timer)
|
||||||
|
self._pd_timer = None
|
||||||
|
_cmd, kind = self._pd_seq.pop(0)
|
||||||
|
payload = ''
|
||||||
|
if ok:
|
||||||
|
payload = line[2:].split(' [')[0].strip() # 去 '← ' 与尾部 hex
|
||||||
|
payload = payload[2:].strip() if payload[:2].lower() == 'ok' else ''
|
||||||
|
if kind == 'pd':
|
||||||
|
self.chip_pd.configure(fg_color=CHIP_OK if ok else CHIP_ERR,
|
||||||
|
text_color='#FFFFFF',
|
||||||
|
text=payload if ok and payload else 'PD')
|
||||||
|
elif kind == 'fpdo':
|
||||||
|
mv = re.search(r'(\d+(?:\.\d+)?)\s*V', payload, re.I)
|
||||||
|
ma = re.search(r'(\d+(?:\.\d+)?)\s*A', payload, re.I)
|
||||||
|
if not ok:
|
||||||
|
self.var_fpdo.set('FPDO: 应答错误')
|
||||||
|
elif mv and ma: # 电压 + 电源宣称最大电流 -> FPDO 功率
|
||||||
|
v, a = float(mv.group(1)), float(ma.group(1))
|
||||||
|
self.var_fpdo.set(f'FPDO: {v:g}V / {a:g}A ({v * a:.0f}W)')
|
||||||
|
elif payload:
|
||||||
|
self.var_fpdo.set(f'FPDO: {payload}')
|
||||||
|
if ok:
|
||||||
|
self._pd_step_next()
|
||||||
|
else: # 出错即中止, 后续状态位保持未检测灰
|
||||||
|
self._pd_seq.clear()
|
||||||
|
why = '超时无应答' if not line.startswith('← ') else '应答错误'
|
||||||
|
self._dlpc_log(f'电源自检: {why}, 序列中止')
|
||||||
|
|
||||||
|
def _pwr_query(self):
|
||||||
|
"""功率检测: 命令待固件实现, 先占位(定义后在此发送并接 _pwr_update)"""
|
||||||
|
if not self.dlpc.is_connected():
|
||||||
|
self.lbl_dlpc_st.configure(text='未连接串口', text_color='#E07A3F')
|
||||||
|
return
|
||||||
|
self._dlpc_log('功率检测: 命令待固件实现')
|
||||||
|
|
||||||
|
def _pwr_update(self, volts, amps):
|
||||||
|
"""功率读数框更新入口: 电压/电流到手后换算功率并刷新"""
|
||||||
|
self.var_pwr.set(f'电压: {volts:.1f} V 电流: {amps:.2f} A '
|
||||||
|
f'功率: {volts * amps:.1f} W')
|
||||||
|
|
||||||
def _light_entry_apply(self, _evt=None):
|
def _light_entry_apply(self, _evt=None):
|
||||||
"""滑条数值输入框回车: 校验并限幅 54-800, 同步回滑条"""
|
"""滑条数值输入框回车: 校验并限幅 54-800, 同步回滑条"""
|
||||||
try:
|
try:
|
||||||
@@ -879,9 +989,11 @@ class App(ctk.CTk):
|
|||||||
self._dlpc_send(f'M8S{v}')
|
self._dlpc_send(f'M8S{v}')
|
||||||
|
|
||||||
def destroy(self):
|
def destroy(self):
|
||||||
try: # 取消待触发的轮询回调, 避免销毁后 Tcl 报错
|
try: # 取消待触发的轮询/自检超时回调, 避免销毁后 Tcl 报错
|
||||||
if self._poll_job:
|
if self._poll_job:
|
||||||
self.after_cancel(self._poll_job)
|
self.after_cancel(self._poll_job)
|
||||||
|
if self._pd_timer:
|
||||||
|
self.after_cancel(self._pd_timer)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
try: # 两种退出路径(关窗/--seconds 自动关)都收掉串口线程
|
try: # 两种退出路径(关窗/--seconds 自动关)都收掉串口线程
|
||||||
|
|||||||
Reference in New Issue
Block a user