You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
6.8 KiB
Python
170 lines
6.8 KiB
Python
import tkinter as tk
|
|
from tkinter import ttk, messagebox
|
|
from .base_page import BasePage
|
|
from protocol import DebugPktState
|
|
from config import Cmd
|
|
import time
|
|
|
|
|
|
class StatusPage(BasePage):
|
|
def __init__(self, parent, tcp_client):
|
|
super().__init__(parent, tcp_client, "实时状态")
|
|
|
|
# 注册回调
|
|
tcp_client.register_callback(Cmd.STATE_GET, self.on_data_received)
|
|
|
|
# self.create_widgets()
|
|
self.update_interval = 1000 # 1秒更新一次
|
|
self.start_periodic_update()
|
|
|
|
def create_widgets(self):
|
|
"""创建界面控件"""
|
|
# 标题
|
|
ttk.Label(self, text="设备实时状态", font=('Arial', 14, 'bold')).pack(pady=10)
|
|
|
|
# 状态信息框架
|
|
state_frame = ttk.LabelFrame(self, text="状态信息", padding=10)
|
|
state_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
|
|
# UTC时间
|
|
ttk.Label(state_frame, text="UTC时间:").grid(row=0, column=0, sticky='e', padx=5, pady=2)
|
|
self.utc_var = tk.StringVar(value="未知")
|
|
ttk.Label(state_frame, textvariable=self.utc_var, width=20).grid(row=0, column=1, sticky='w', padx=5, pady=2)
|
|
|
|
# 运行时间
|
|
ttk.Label(state_frame, text="运行时间:").grid(row=1, column=0, sticky='e', padx=5, pady=2)
|
|
self.run_time_var = tk.StringVar(value="未知")
|
|
ttk.Label(state_frame, textvariable=self.run_time_var, width=20).grid(row=1, column=1, sticky='w', padx=5,
|
|
pady=2)
|
|
|
|
# 后台连接状态
|
|
ttk.Label(state_frame, text="后台连接:").grid(row=2, column=0, sticky='e', padx=5, pady=2)
|
|
self.connect_var = tk.StringVar(value="未知")
|
|
ttk.Label(state_frame, textvariable=self.connect_var, width=20).grid(row=2, column=1, sticky='w', padx=5,
|
|
pady=2)
|
|
|
|
# 本地时间(用于参考)
|
|
ttk.Label(state_frame, text="本地时间:").grid(row=3, column=0, sticky='e', padx=5, pady=2)
|
|
self.local_time_var = tk.StringVar()
|
|
ttk.Label(state_frame, textvariable=self.local_time_var, width=20).grid(row=3, column=1, sticky='w', padx=5,
|
|
pady=2)
|
|
|
|
# 按钮框架
|
|
button_frame = ttk.Frame(self)
|
|
button_frame.pack(pady=10)
|
|
|
|
# ttk.Button(button_frame, text="读取状态", command=self.read_status, width=12).pack(side=tk.LEFT, padx=5)
|
|
ttk.Button(button_frame, text="对时", command=self.sync_time, width=12).pack(side=tk.LEFT, padx=5)
|
|
ttk.Button(button_frame, text="重启设备", command=self.reboot_device, width=12).pack(side=tk.LEFT, padx=5)
|
|
ttk.Button(button_frame, text="自动刷新", command=self.toggle_auto_refresh, width=12).pack(side=tk.LEFT, padx=5)
|
|
|
|
# 自动刷新状态
|
|
self.auto_refresh = True
|
|
self.auto_refresh_var = tk.StringVar(value="自动刷新: 开")
|
|
ttk.Label(button_frame, textvariable=self.auto_refresh_var).pack(side=tk.LEFT, padx=5)
|
|
|
|
# 最后更新时间
|
|
self.last_update_var = tk.StringVar(value="最后更新: 从未")
|
|
ttk.Label(self, textvariable=self.last_update_var).pack(pady=5)
|
|
|
|
def start_periodic_update(self):
|
|
"""启动定时更新"""
|
|
self.update_local_time()
|
|
if self.auto_refresh:
|
|
self.read_status()
|
|
self.after(self.update_interval, self.start_periodic_update)
|
|
|
|
def update_local_time(self):
|
|
"""更新本地时间显示"""
|
|
local_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
|
|
self.local_time_var.set(local_time)
|
|
|
|
def read_status(self):
|
|
"""读取设备状态"""
|
|
if not self.tcp_client.connected:
|
|
# self.show_error("未连接到设备")
|
|
return
|
|
|
|
self.tcp_client.send_packet(Cmd.STATE_GET)
|
|
|
|
def sync_time(self):
|
|
"""对时功能:将本地时间发送给设备"""
|
|
if not self.tcp_client.connected:
|
|
self.show_error("未连接到设备")
|
|
return
|
|
|
|
try:
|
|
# 获取当前UTC时间戳
|
|
current_utc = int(time.time())
|
|
|
|
time_data = current_utc.to_bytes(4, 'little')
|
|
if self.tcp_client.send_packet(Cmd.TIME_SYNC, time_data): # 假设对时命令码为0x0A
|
|
self.show_info("对时命令已发送")
|
|
else:
|
|
self.show_error("对时命令发送失败")
|
|
|
|
except Exception as e:
|
|
self.show_error(f"对时失败: {e}")
|
|
|
|
def reboot_device(self):
|
|
"""重启设备"""
|
|
if not self.tcp_client.connected:
|
|
self.show_error("未连接到设备")
|
|
return
|
|
|
|
if messagebox.askyesno("确认", "确定要重启设备吗?"):
|
|
if self.tcp_client.send_packet(Cmd.REBOOT_DEVICE, b''):
|
|
self.show_info("重启命令已发送")
|
|
else:
|
|
self.show_error("重启命令发送失败")
|
|
|
|
def toggle_auto_refresh(self):
|
|
"""切换自动刷新状态"""
|
|
self.auto_refresh = not self.auto_refresh
|
|
status = "开" if self.auto_refresh else "关"
|
|
self.auto_refresh_var.set(f"自动刷新: {status}")
|
|
|
|
def on_data_received(self, header, body):
|
|
"""处理接收到的状态数据"""
|
|
try:
|
|
state = DebugPktState.from_bytes(body)
|
|
|
|
# 更新UTC时间显示
|
|
utc_time = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(state.utc))
|
|
self.utc_var.set(utc_time)
|
|
|
|
# 更新运行时间显示
|
|
self.run_time_var.set(self.format_runtime(state.run_time))
|
|
|
|
# 更新连接状态显示
|
|
connect_status = "已连接" if state.is_connect else "未连接"
|
|
self.connect_var.set(connect_status)
|
|
|
|
# 更新最后更新时间
|
|
current_time = time.strftime("%H:%M:%S", time.localtime())
|
|
self.last_update_var.set(f"最后更新: {current_time}")
|
|
|
|
except Exception as e:
|
|
print(f"解析状态数据失败: {e}")
|
|
|
|
def format_runtime(self, seconds):
|
|
"""格式化运行时间"""
|
|
if seconds == 0:
|
|
return "0秒"
|
|
|
|
days = seconds // (24 * 3600)
|
|
hours = (seconds % (24 * 3600)) // 3600
|
|
minutes = (seconds % 3600) // 60
|
|
secs = seconds % 60
|
|
|
|
parts = []
|
|
if days > 0:
|
|
parts.append(f"{days}天")
|
|
if hours > 0:
|
|
parts.append(f"{hours}时")
|
|
if minutes > 0:
|
|
parts.append(f"{minutes}分")
|
|
if secs > 0 or not parts:
|
|
parts.append(f"{secs}秒")
|
|
|
|
return "".join(parts) |