|
@@ -19,9 +19,31 @@ using System.Text.RegularExpressions;
|
|
|
|
|
|
namespace Bird_tool
|
|
|
{
|
|
|
+ public enum LogLevel
|
|
|
+ {
|
|
|
+ debug,
|
|
|
+ info,
|
|
|
+ error
|
|
|
+ };
|
|
|
+
|
|
|
+ public enum TestMode
|
|
|
+ {
|
|
|
+ none,
|
|
|
+ hw_test,
|
|
|
+ config
|
|
|
+ }
|
|
|
+
|
|
|
+ public enum TestType
|
|
|
+ {
|
|
|
+ StartIndex,
|
|
|
+ StartFrom,
|
|
|
+ TestSingle
|
|
|
+ }
|
|
|
+
|
|
|
public partial class bird_tool : Form
|
|
|
{
|
|
|
- private SerialPort _uart = new SerialPort();//定义串口
|
|
|
+ private SerialManager _serialManager = new SerialManager();//定义串口
|
|
|
+ private TestExecutor _testExecutor;
|
|
|
|
|
|
private BindingList<string> _portList = new BindingList<string>();
|
|
|
private string _lastSelectedPort = ""; // 保存上次选择的串口
|
|
@@ -30,6 +52,15 @@ namespace Bird_tool
|
|
|
private bool flag_load_config = false;
|
|
|
// 是否选择串口
|
|
|
private bool flag_selected_serial = false;
|
|
|
+ private static LogLevel show_log_level = LogLevel.info;
|
|
|
+ private static StringBuilder logBuilder = new StringBuilder();
|
|
|
+
|
|
|
+
|
|
|
+ private bool SetWifi = false;
|
|
|
+ private string wifi_ssid = "";
|
|
|
+ private string wifi_password = "";
|
|
|
+ private string wifi_act = "hfyswj100";
|
|
|
+ private string sd_act = "hfyswj188";
|
|
|
|
|
|
|
|
|
public bird_tool()
|
|
@@ -39,15 +70,131 @@ namespace Bird_tool
|
|
|
//serialTimer.Enabled = true;
|
|
|
}
|
|
|
|
|
|
- private void Log(string message)
|
|
|
+ static public void Log(string message, LogLevel level = LogLevel.info)
|
|
|
{
|
|
|
- System.Diagnostics.Debug.WriteLine(message);
|
|
|
+ string logStr = "";
|
|
|
+ if (level == LogLevel.debug)
|
|
|
+ {
|
|
|
+ logStr = $"[Debug] {message}";
|
|
|
+
|
|
|
+ }
|
|
|
+ else if (level == LogLevel.info)
|
|
|
+ {
|
|
|
+ logStr = $"[Info] {message}";
|
|
|
+ }
|
|
|
+ else if (level == LogLevel.error)
|
|
|
+ {
|
|
|
+ logStr = $"[Error] {message}";
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ logStr = $"[Unknow] {message}";
|
|
|
+ }
|
|
|
+ // 调试控制台, 全部输出
|
|
|
+ System.Diagnostics.Debug.WriteLine(logStr);
|
|
|
+ // 将内容追加至本地log文件中
|
|
|
+ if (level < show_log_level)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 值得保存的调试控制台
|
|
|
+ Console.WriteLine(logStr);
|
|
|
+ logBuilder.AppendLine(logStr);
|
|
|
+ }
|
|
|
+
|
|
|
+ static public void Log_show(string message)
|
|
|
+ {
|
|
|
+ MessageBox.Show(message);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ShowLogWindow()
|
|
|
+ {
|
|
|
+ Form logForm = new Form
|
|
|
+ {
|
|
|
+ Text = "测试日志",
|
|
|
+ Size = new Size(700, 500),
|
|
|
+ StartPosition = FormStartPosition.CenterParent
|
|
|
+ };
|
|
|
+
|
|
|
+ // 日志文本框
|
|
|
+ TextBox logBox = new TextBox
|
|
|
+ {
|
|
|
+ Multiline = true,
|
|
|
+ Dock = DockStyle.Fill,
|
|
|
+ ScrollBars = ScrollBars.Both,
|
|
|
+ ReadOnly = true,
|
|
|
+ Font = new Font("Consolas", 10),
|
|
|
+ Text = logBuilder.ToString()
|
|
|
+ };
|
|
|
+
|
|
|
+ // 底部按钮面板
|
|
|
+ Panel buttonPanel = new Panel
|
|
|
+ {
|
|
|
+ Dock = DockStyle.Bottom,
|
|
|
+ Height = 40
|
|
|
+ };
|
|
|
+
|
|
|
+ // 复制按钮
|
|
|
+ Button copyButton = new Button
|
|
|
+ {
|
|
|
+ Text = "复制日志",
|
|
|
+ Size = new Size(100, 30),
|
|
|
+ Location = new Point(10, 5)
|
|
|
+ };
|
|
|
+ copyButton.Click += (s, e) =>
|
|
|
+ {
|
|
|
+ Clipboard.SetText(logBuilder.ToString());
|
|
|
+ MessageBox.Show("日志已复制到剪贴板");
|
|
|
+ };
|
|
|
+
|
|
|
+ // 保存按钮
|
|
|
+ Button saveButton = new Button
|
|
|
+ {
|
|
|
+ Text = "保存日志",
|
|
|
+ Size = new Size(100, 30),
|
|
|
+ Location = new Point(120, 5)
|
|
|
+ };
|
|
|
+ saveButton.Click += (s, e) =>
|
|
|
+ {
|
|
|
+ SaveFileDialog saveDialog = new SaveFileDialog
|
|
|
+ {
|
|
|
+ Filter = "文本文件|*.txt",
|
|
|
+ FileName = $"test_log_{DateTime.Now:yyyyMMdd_HHmmss}.txt"
|
|
|
+ };
|
|
|
+
|
|
|
+ if (saveDialog.ShowDialog() == DialogResult.OK)
|
|
|
+ {
|
|
|
+ File.WriteAllText(saveDialog.FileName, logBuilder.ToString());
|
|
|
+ MessageBox.Show("日志已保存");
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 关闭按钮
|
|
|
+ Button closeButton = new Button
|
|
|
+ {
|
|
|
+ Text = "关闭",
|
|
|
+ Size = new Size(100, 30),
|
|
|
+ Location = new Point(230, 5)
|
|
|
+ };
|
|
|
+ closeButton.Click += (s, e) => logForm.Close();
|
|
|
+
|
|
|
+ // 组装按钮面板
|
|
|
+ buttonPanel.Controls.Add(copyButton);
|
|
|
+ buttonPanel.Controls.Add(saveButton);
|
|
|
+ buttonPanel.Controls.Add(closeButton);
|
|
|
+
|
|
|
+ // 组装日志窗体
|
|
|
+ logForm.Controls.Add(logBox);
|
|
|
+ logForm.Controls.Add(buttonPanel);
|
|
|
+
|
|
|
+ logForm.ShowDialog();
|
|
|
}
|
|
|
|
|
|
-
|
|
|
private void Tool_load(object sender, EventArgs e)
|
|
|
{
|
|
|
+ _uart_ui_change(false);
|
|
|
SerialPort_Load();
|
|
|
+ //_serialManager.OnLineReceived += _handle_received_line;
|
|
|
}
|
|
|
|
|
|
private void SerialPort_Load()
|
|
@@ -64,6 +211,18 @@ namespace Bird_tool
|
|
|
|
|
|
// 初始加载串口列表
|
|
|
RefreshPortList();
|
|
|
+ Log("inti ");
|
|
|
+ _testExecutor = new TestExecutor(_serialManager);
|
|
|
+
|
|
|
+ // 绑定事件处理
|
|
|
+ _testExecutor.OnLog += Log;
|
|
|
+
|
|
|
+ _testExecutor.OnPrompt += (question, onYes, onNo, waitTime) =>
|
|
|
+ this.Invoke((Action)(() => PromptUser(question, onYes, onNo, waitTime)));
|
|
|
+
|
|
|
+ _testExecutor.OnFailed += TestFailedhandle;
|
|
|
+ _testExecutor.OnSuccess += TestSuccesshandle;
|
|
|
+ _testExecutor.OnStepChanged += HandleStepChanged;
|
|
|
}
|
|
|
|
|
|
// 刷新串口列表并保持选择
|
|
@@ -136,6 +295,1171 @@ namespace Bird_tool
|
|
|
}
|
|
|
// 尝试连接串口
|
|
|
Log($"连接串口{currentSelection}");
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (_serialManager.IsOpen())
|
|
|
+ {
|
|
|
+ // 调用停止函数
|
|
|
+ StopTest();
|
|
|
+ _serialManager.Disconnect();
|
|
|
+ System.Threading.Thread.Sleep(100);
|
|
|
+ _uart_ui_change(false);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!_serialManager.Connect(currentSelection))
|
|
|
+ {
|
|
|
+ Log("串口开启失败");
|
|
|
+ _uart_ui_change(false);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Log("串口开启成功");
|
|
|
+ // 设置窗口内容
|
|
|
+ _uart_ui_change(true);
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private void Evt_hw_click(object sender, EventArgs e)
|
|
|
+ {
|
|
|
+ if (!_serialManager.IsOpen())
|
|
|
+ {
|
|
|
+ MessageBox.Show("请先打开串口");
|
|
|
+ _serialManager.Disconnect();
|
|
|
+ System.Threading.Thread.Sleep(100);
|
|
|
+ _uart_ui_change(false);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ checkWifi();
|
|
|
+ hw_test();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void Evt_set_wifi(object sender, EventArgs e)
|
|
|
+ {
|
|
|
+ checkWifi();
|
|
|
}
|
|
|
+
|
|
|
+ private void checkWifi ()
|
|
|
+ {
|
|
|
+ // 获取wifi值
|
|
|
+ string ssid = txt_ssid.Text;
|
|
|
+ string password = txt_password.Text;
|
|
|
+ Log($"ssid:{ssid} passwd:{password}");
|
|
|
+ // string.IsNullOrEmpty()
|
|
|
+ if (string.IsNullOrEmpty(ssid) || string.IsNullOrEmpty(password))
|
|
|
+ {
|
|
|
+ Log_show("请输入wifi信息");
|
|
|
+ SetWifi = false;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Log_show($"将使用{ssid} 密码:{password}让设备连接WiFi");
|
|
|
+ wifi_ssid = ssid;
|
|
|
+ wifi_password = password;
|
|
|
+ SetWifi = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void _SetTestButtonsEnabled(bool enabled)
|
|
|
+ {
|
|
|
+ el_btn_hw_test.Enabled = enabled;
|
|
|
+ el_btn_config.Enabled = enabled;
|
|
|
+
|
|
|
+ // 可选:添加视觉反馈
|
|
|
+ if (enabled)
|
|
|
+ {
|
|
|
+ el_btn_hw_test.BackColor = SystemColors.Control; // 标准按钮背景色
|
|
|
+ el_btn_hw_test.ForeColor = SystemColors.ControlText; // 标准文本色
|
|
|
+ el_btn_hw_test.FlatStyle = FlatStyle.Standard; // 恢复原始样式
|
|
|
+ el_btn_hw_test.Cursor = Cursors.Default;
|
|
|
+
|
|
|
+ el_btn_config.BackColor = SystemColors.Control;
|
|
|
+ el_btn_config.ForeColor = SystemColors.ControlText;
|
|
|
+ el_btn_config.FlatStyle = FlatStyle.Standard;
|
|
|
+ el_btn_config.Cursor = Cursors.Default;
|
|
|
+
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // 禁用状态:更直观的视觉反馈
|
|
|
+ el_btn_hw_test.BackColor = SystemColors.Control; // 保持背景色
|
|
|
+ el_btn_hw_test.ForeColor = SystemColors.GrayText; // 标准禁用文本色
|
|
|
+ el_btn_hw_test.FlatStyle = FlatStyle.Flat; // 扁平化样式增强禁用感
|
|
|
+ el_btn_hw_test.Cursor = Cursors.No;
|
|
|
+
|
|
|
+ el_btn_config.BackColor = SystemColors.Control;
|
|
|
+ el_btn_config.ForeColor = SystemColors.GrayText;
|
|
|
+ el_btn_config.FlatStyle = FlatStyle.Flat;
|
|
|
+ el_btn_config.Cursor = Cursors.No;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void AdjustTopPanelHeight(bool showFull)
|
|
|
+ {
|
|
|
+ if (showFull)
|
|
|
+ {
|
|
|
+ // 恢复完整高度
|
|
|
+ topPanel.Height = 60;
|
|
|
+ tableLayoutPanel.Location = new System.Drawing.Point(0, 60);
|
|
|
+ tableLayoutPanel.Size = new System.Drawing.Size(962, 497);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // 缩小顶部面板
|
|
|
+ topPanel.Height = 30;
|
|
|
+ tableLayoutPanel.Location = new System.Drawing.Point(0, 30);
|
|
|
+ tableLayoutPanel.Size = new System.Drawing.Size(962, 527);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 重新布局确保控件正确显示
|
|
|
+ topPanel.PerformLayout();
|
|
|
+ this.Refresh();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void _uart_ui_change(bool uart_flag)
|
|
|
+ {
|
|
|
+ if (uart_flag)
|
|
|
+ {
|
|
|
+ el_btn_conn.Text = "断开连接";
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ el_btn_conn.Text = "连接串口";
|
|
|
+ }
|
|
|
+ _SetTestButtonsEnabled(uart_flag);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private void PromptUser(string question, Action onYes, Action onNo, int waitTime = -1)
|
|
|
+ {
|
|
|
+ this.Invoke((Action)(() =>
|
|
|
+ {
|
|
|
+ // 创建自定义提示窗口
|
|
|
+ var prompt = new Form
|
|
|
+ {
|
|
|
+ Width = 450,
|
|
|
+ Height = 250,
|
|
|
+ FormBorderStyle = FormBorderStyle.FixedDialog,
|
|
|
+ Text = "操作确认",
|
|
|
+ StartPosition = FormStartPosition.CenterParent,
|
|
|
+ Font = new Font("Microsoft YaHei UI", 10),
|
|
|
+ Icon = this.Icon,
|
|
|
+ MinimizeBox = false,
|
|
|
+ MaximizeBox = false
|
|
|
+ };
|
|
|
+
|
|
|
+ // 主面板 - 使用表格布局实现更好的响应式设计
|
|
|
+ var mainPanel = new TableLayoutPanel
|
|
|
+ {
|
|
|
+ Dock = DockStyle.Fill,
|
|
|
+ ColumnCount = 1,
|
|
|
+ RowCount = 3,
|
|
|
+ Padding = new Padding(15),
|
|
|
+ RowStyles = {
|
|
|
+ new RowStyle(SizeType.Percent, 70F),
|
|
|
+ new RowStyle(SizeType.AutoSize),
|
|
|
+ new RowStyle(SizeType.AutoSize)
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 问题标签
|
|
|
+ var label = new Label
|
|
|
+ {
|
|
|
+ Text = question,
|
|
|
+ Dock = DockStyle.Fill,
|
|
|
+ TextAlign = ContentAlignment.MiddleCenter,
|
|
|
+ Font = new Font("Microsoft YaHei UI", 12, FontStyle.Regular),
|
|
|
+ AutoSize = false
|
|
|
+ };
|
|
|
+
|
|
|
+ // 倒计时标签(初始隐藏)
|
|
|
+ var countdownLabel = new Label
|
|
|
+ {
|
|
|
+ Text = "",
|
|
|
+ Dock = DockStyle.Top,
|
|
|
+ TextAlign = ContentAlignment.MiddleCenter,
|
|
|
+ Font = new Font("Microsoft YaHei UI", 9, FontStyle.Italic),
|
|
|
+ ForeColor = Color.Gray,
|
|
|
+ Height = 30,
|
|
|
+ Visible = false
|
|
|
+ };
|
|
|
+
|
|
|
+ // 按钮面板
|
|
|
+ var buttonPanel = new FlowLayoutPanel
|
|
|
+ {
|
|
|
+ Dock = DockStyle.Fill,
|
|
|
+ FlowDirection = FlowDirection.RightToLeft,
|
|
|
+ Padding = new Padding(0, 10, 0, 0),
|
|
|
+ AutoSize = true
|
|
|
+ };
|
|
|
+
|
|
|
+ // 否按钮
|
|
|
+ var noButton = new Button
|
|
|
+ {
|
|
|
+ Text = "否",
|
|
|
+ DialogResult = DialogResult.No,
|
|
|
+ Size = new Size(100, 35),
|
|
|
+ Font = new Font("Microsoft YaHei UI", 9.5F),
|
|
|
+ BackColor = Color.White,
|
|
|
+ FlatStyle = FlatStyle.Flat,
|
|
|
+ Cursor = Cursors.Hand
|
|
|
+ };
|
|
|
+
|
|
|
+ // 是按钮
|
|
|
+ var yesButton = new Button
|
|
|
+ {
|
|
|
+ Text = "是",
|
|
|
+ DialogResult = DialogResult.Yes,
|
|
|
+ Size = new Size(100, 35),
|
|
|
+ Font = new Font("Microsoft YaHei UI", 9.5F, FontStyle.Bold),
|
|
|
+ BackColor = Color.FromArgb(220, 235, 252),
|
|
|
+ FlatStyle = FlatStyle.Flat,
|
|
|
+ Cursor = Cursors.Hand
|
|
|
+ };
|
|
|
+
|
|
|
+ // 计时器(用于倒计时)
|
|
|
+ System.Windows.Forms.Timer timeoutTimer = null;
|
|
|
+ int remainingTime = waitTime;
|
|
|
+
|
|
|
+ if (waitTime > 0)
|
|
|
+ {
|
|
|
+ // 显示倒计时标签
|
|
|
+ countdownLabel.Visible = true;
|
|
|
+ countdownLabel.Text = $"操作将在 {remainingTime} 秒后自动取消";
|
|
|
+
|
|
|
+ // 设置按钮初始文本(包含倒计时)
|
|
|
+ noButton.Text = $"否 ({remainingTime})";
|
|
|
+
|
|
|
+ // 创建并启动计时器
|
|
|
+ timeoutTimer = new System.Windows.Forms.Timer { Interval = 1000 };
|
|
|
+ timeoutTimer.Tick += (s, e) => {
|
|
|
+ remainingTime--;
|
|
|
+
|
|
|
+ // 更新倒计时显示
|
|
|
+ countdownLabel.Text = $"操作将在 {remainingTime} 秒后自动取消";
|
|
|
+ noButton.Text = $"否 ({remainingTime})";
|
|
|
+
|
|
|
+ // 倒计时结束
|
|
|
+ if (remainingTime <= 0)
|
|
|
+ {
|
|
|
+ timeoutTimer.Stop();
|
|
|
+ prompt.Close();
|
|
|
+ onNo?.Invoke();
|
|
|
+ }
|
|
|
+ };
|
|
|
+ timeoutTimer.Start();
|
|
|
+
|
|
|
+ // 记录日志
|
|
|
+ Log($"配置询问倒计时 {waitTime} 秒,超时则自动选择'否'");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 是按钮点击事件
|
|
|
+ yesButton.Click += (sender, e) => {
|
|
|
+ timeoutTimer?.Stop();
|
|
|
+ prompt.Close();
|
|
|
+ onYes?.Invoke();
|
|
|
+ };
|
|
|
+
|
|
|
+ // 否按钮点击事件
|
|
|
+ noButton.Click += (sender, e) => {
|
|
|
+ timeoutTimer?.Stop();
|
|
|
+ prompt.Close();
|
|
|
+ onNo?.Invoke();
|
|
|
+ };
|
|
|
+
|
|
|
+ // 处理窗体关闭事件
|
|
|
+ prompt.FormClosed += (sender, e) => {
|
|
|
+ timeoutTimer?.Stop();
|
|
|
+ // 如果窗体关闭时倒计时仍在运行,执行No操作
|
|
|
+ if (timeoutTimer != null && timeoutTimer.Enabled)
|
|
|
+ {
|
|
|
+ onNo?.Invoke();
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 添加键盘快捷键
|
|
|
+ prompt.KeyPreview = true;
|
|
|
+ prompt.KeyDown += (sender, e) => {
|
|
|
+ if (e.KeyCode == Keys.Enter)
|
|
|
+ {
|
|
|
+ yesButton.PerformClick();
|
|
|
+ e.Handled = true;
|
|
|
+ }
|
|
|
+ else if (e.KeyCode == Keys.Escape)
|
|
|
+ {
|
|
|
+ noButton.PerformClick();
|
|
|
+ e.Handled = true;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 组装按钮面板
|
|
|
+ buttonPanel.Controls.Add(noButton);
|
|
|
+ buttonPanel.Controls.Add(yesButton);
|
|
|
+
|
|
|
+ // 添加间距
|
|
|
+ buttonPanel.Controls.Add(new Panel { Width = 15 });
|
|
|
+
|
|
|
+ // 组装主面板
|
|
|
+ mainPanel.Controls.Add(label, 0, 0);
|
|
|
+ mainPanel.Controls.Add(countdownLabel, 0, 1);
|
|
|
+ mainPanel.Controls.Add(buttonPanel, 0, 2);
|
|
|
+
|
|
|
+ prompt.Controls.Add(mainPanel);
|
|
|
+
|
|
|
+ // 显示窗口
|
|
|
+ prompt.ShowDialog(this);
|
|
|
+ }));
|
|
|
+ }
|
|
|
+
|
|
|
+ // ui控件操作
|
|
|
+ private void ui_hide_start_panpel()
|
|
|
+ {
|
|
|
+ tableLayoutPanel.Visible = false;
|
|
|
+ panelWifi.Visible = false;
|
|
|
+ }
|
|
|
+ private void ui_show_start_panpel()
|
|
|
+ {
|
|
|
+ tableLayoutPanel.Visible = true;
|
|
|
+ panelWifi.Visible = true;
|
|
|
+ progressPanel.Visible = false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void ui_show_test_panpel()
|
|
|
+ {
|
|
|
+ ui_hide_start_panpel();
|
|
|
+ // 显示进度面板
|
|
|
+ progressPanel.Visible = true;
|
|
|
+ progressPanel.BringToFront();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void re_main()
|
|
|
+ {
|
|
|
+ ui_show_start_panpel();
|
|
|
+ progressPanel.ResetPanel();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void start_query_test()
|
|
|
+ {
|
|
|
+ Log($"start_query_test");
|
|
|
+ // 判断当前的id是
|
|
|
+ StartTest(TestType.StartIndex);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void setpStart(string key, TestType testType)
|
|
|
+ {
|
|
|
+ StartTest(testType, key);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void config_test()
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // device mac
|
|
|
+ private void hw_test()
|
|
|
+ {
|
|
|
+
|
|
|
+ var steps = CreateTestSteps();
|
|
|
+ if (!_testExecutor.InitTest(steps))
|
|
|
+ {
|
|
|
+ Log_show("无法创建测试表");
|
|
|
+ StopTest();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ ui_show_test_panpel();
|
|
|
+ progressPanel.ResetPanel();
|
|
|
+
|
|
|
+ var groups = _testExecutor.GetGroupInfos();
|
|
|
+ foreach (var group in groups)
|
|
|
+ {
|
|
|
+ if (group.ShowStep)
|
|
|
+ {
|
|
|
+ progressPanel.AddTestStep(group.RowKey, group.GroupName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ progressPanel.Message = "点击开始测试按钮进行测试";
|
|
|
+
|
|
|
+
|
|
|
+ Log($"[{DateTime.Now}] 开始硬件测试");
|
|
|
+ }
|
|
|
+
|
|
|
+ private void StartTest(TestType testType, string groupId = null)
|
|
|
+ {
|
|
|
+ if (!_testExecutor.isInit)
|
|
|
+ {
|
|
|
+ Log_show("测试引擎未初始化!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Log($"testType{testType} by {groupId}");
|
|
|
+ progressPanel.StartTimer();
|
|
|
+ // 初始化测试状态
|
|
|
+ progressPanel.ProgressValue = 0;
|
|
|
+ progressPanel.CurrentTest = "初始化测试环境";
|
|
|
+ progressPanel.Message = "准备开始硬件测试...";
|
|
|
+ progressPanel.startTest();
|
|
|
+ if (string.IsNullOrEmpty(groupId))
|
|
|
+ {
|
|
|
+ _testExecutor.StartTest();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (testType == TestType.StartFrom)
|
|
|
+ {
|
|
|
+ _testExecutor.StartTestFromGroup(groupId);
|
|
|
+ }
|
|
|
+ else if (testType == TestType.TestSingle)
|
|
|
+ {
|
|
|
+ _testExecutor.StartTestGroup(groupId);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _testExecutor.StartTest();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ private void StopTest()
|
|
|
+ {
|
|
|
+ // 停止测试
|
|
|
+ if (_testExecutor.isStart)
|
|
|
+ {
|
|
|
+ if (MessageBox.Show("确定要停止当前测试吗?", "确认停止",
|
|
|
+ MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
|
|
|
+ {
|
|
|
+ // 设置停止标志
|
|
|
+
|
|
|
+ // 更新UI
|
|
|
+ progressPanel.ShowTestResult(false, "测试已取消", LoadCancelledImage());
|
|
|
+
|
|
|
+ // 添加日志
|
|
|
+ logBuilder.AppendLine($"[{DateTime.Now}] 测试已取消");
|
|
|
+ _testExecutor.StopTest();
|
|
|
+ progressPanel.Message = "用户手动停止测试";
|
|
|
+ Log($"[{DateTime.Now}] 测试中止");
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Log($"[{DateTime.Now}] 测试中止");
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private void TestFailedhandle(TestStepConfig step, TestContext context)
|
|
|
+ {
|
|
|
+ string str = $"------ 测试失败-------";
|
|
|
+ _testExecutor.StopTest();
|
|
|
+ progressPanel.ShowTestResult(false, str);
|
|
|
+ Log(str);
|
|
|
+ Log($"------测试结束-------");
|
|
|
+ }
|
|
|
+
|
|
|
+ private void TestSuccesshandle(TestContext context)
|
|
|
+ {
|
|
|
+ string str = $"------ 测试完成, 请更换设备-------";
|
|
|
+ progressPanel.ShowTestResult(true, str);
|
|
|
+ Log(str);
|
|
|
+ Log($"------测试通过-------");
|
|
|
+ Log("------测试成功-------");
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private List<TestStepConfig> CreateTestSteps()
|
|
|
+ {
|
|
|
+
|
|
|
+ return new List<TestStepConfig>
|
|
|
+ {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // 按钮长按功能测试
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "btn_long",
|
|
|
+ GroupName = "按钮测试",
|
|
|
+ Name = "长按测试1",
|
|
|
+ Tips = "请长按电源按钮 5秒后再次长按 第一次",
|
|
|
+ Command = "\r\n",
|
|
|
+ SuccessPattern = "sys off",
|
|
|
+ Timeout = 20000,
|
|
|
+ DelayBefore = 200,
|
|
|
+ MaxRetries = 3,
|
|
|
+ },
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "btn_long",
|
|
|
+ Name = "开机测试1",
|
|
|
+ Tips = "点击电源按钮 2秒后再次点击 第一次",
|
|
|
+ Command = "\r\n",
|
|
|
+ SuccessPattern = "OS start",
|
|
|
+ Timeout = 20000,
|
|
|
+ DelayBefore = 1000,
|
|
|
+ MaxRetries = 3,
|
|
|
+ },
|
|
|
+
|
|
|
+ // 按钮双击功能测试
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "btn_long",
|
|
|
+ Name = "双击测试1",
|
|
|
+ Tips = "请双击电源按钮 第一次",
|
|
|
+ Command = "\r\n",
|
|
|
+ SuccessPattern = "_msg_dbclick_callback",
|
|
|
+ Timeout = 20000,
|
|
|
+ DelayBefore = 500,
|
|
|
+ MaxRetries = 3,
|
|
|
+ },
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "btn_long",
|
|
|
+ Name = "双击测试2",
|
|
|
+ Tips = "请再次双击电源按钮 第二次",
|
|
|
+ Command = "\r\n",
|
|
|
+ SuccessPattern = "_msg_dbclick_callback",
|
|
|
+ Timeout = 20000,
|
|
|
+ DelayBefore = 1000,
|
|
|
+ MaxRetries = 3,
|
|
|
+ },
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "btn_long",
|
|
|
+ Name = "双击测试3",
|
|
|
+ Tips = "请再次双击电源按钮 第三次",
|
|
|
+ Command = "\r\n",
|
|
|
+ SuccessPattern = "_msg_dbclick_callback",
|
|
|
+ Timeout = 20000,
|
|
|
+ DelayBefore = 1000,
|
|
|
+ MaxRetries = 3,
|
|
|
+ },
|
|
|
+
|
|
|
+ // 红外传感器测试
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "pir_test",
|
|
|
+ Name = "配置设备状态",
|
|
|
+ Tips = "等待任务自动执行",
|
|
|
+ Command = "AT+RBOT=0\r\n",
|
|
|
+ SuccessPattern = "OS start",
|
|
|
+ Timeout = 3000,
|
|
|
+ DelayBefore = 1000,
|
|
|
+ MaxRetries = 5,
|
|
|
+ },
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "pir_test",
|
|
|
+ Name = "调试模式",
|
|
|
+ Tips = "等待任务执行",
|
|
|
+ Command = "AT+OSLP=0,1\r\n",
|
|
|
+ SuccessPattern = "Wakeup, unsleep:0 debug:1",
|
|
|
+ Timeout = 3000,
|
|
|
+ DelayBefore = 1000,
|
|
|
+ MaxRetries = 5,
|
|
|
+ },
|
|
|
+
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "pir_test",
|
|
|
+ Name = "红外触发1",
|
|
|
+ Tips = "请将手移动至红外传感器上 第一次",
|
|
|
+ Command = "\r\n",
|
|
|
+ SuccessPattern = "SOC: <=OK cmd:17",
|
|
|
+ Timeout = 30000,
|
|
|
+ DelayAfter = 100,
|
|
|
+ MaxRetries = 3,
|
|
|
+ },
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "pir_test",
|
|
|
+ Name = "等待红外录像完成 1",
|
|
|
+ Tips = "等待红外任务结束 第一次",
|
|
|
+ Command = "\r\n",
|
|
|
+ SuccessPattern = "CAM: Close",
|
|
|
+ Timeout = 30000,
|
|
|
+ DelayAfter = 10,
|
|
|
+ MaxRetries = 3,
|
|
|
+ },
|
|
|
+
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "pir_test",
|
|
|
+ GroupName = "红外触发测试",
|
|
|
+ Name = "红外触发2",
|
|
|
+ Tips = "请将手移动至红外传感器上 第二次",
|
|
|
+ Command = "\r\n",
|
|
|
+ SuccessPattern = "cmd:17",
|
|
|
+ Timeout = 30000,
|
|
|
+ MaxRetries = 3,
|
|
|
+ },
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "btn_reset",
|
|
|
+ GroupName = "重置按钮测试",
|
|
|
+ Name = "重置按钮1",
|
|
|
+ Tips = "请按下重置按钮 第一次",
|
|
|
+ Command = "\r\n",
|
|
|
+ SuccessPattern = "OS start",
|
|
|
+ Timeout = 30000,
|
|
|
+ MaxRetries = 3,
|
|
|
+ },
|
|
|
+
|
|
|
+ // 重置按钮测试
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "btn_reset",
|
|
|
+ Name = "重置按钮2",
|
|
|
+ Tips = "请按下重置按钮 第二次",
|
|
|
+ Command = "\r\n",
|
|
|
+ SuccessPattern = "OS start",
|
|
|
+ Timeout = 30000,
|
|
|
+ MaxRetries = 3,
|
|
|
+ },
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "btn_reset",
|
|
|
+ Name = "重置按钮3",
|
|
|
+ Tips = "请按下重置按钮 第三次",
|
|
|
+ Command = "\r\n",
|
|
|
+ SuccessPattern = "OS start",
|
|
|
+ Timeout = 30000,
|
|
|
+ MaxRetries = 3,
|
|
|
+ },
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "btn_reset",
|
|
|
+ Name = "重置按钮4",
|
|
|
+ Tips = "请按下重置按钮 第四次",
|
|
|
+ Command = "\r\n",
|
|
|
+ SuccessPattern = "OS start",
|
|
|
+ Timeout = 30000,
|
|
|
+ MaxRetries = 3,
|
|
|
+ },
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "btn_reset",
|
|
|
+ Name = "重置按钮5",
|
|
|
+ Tips = "请按下重置按钮 第五次",
|
|
|
+ Command = "\r\n",
|
|
|
+ SuccessPattern = "OS start",
|
|
|
+ Timeout = 30000,
|
|
|
+ MaxRetries = 3,
|
|
|
+ },
|
|
|
+
|
|
|
+ // 其它命令性质测试
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ Name = "测试模式",
|
|
|
+ Command = "AT+OSLP=1,0\r\n",
|
|
|
+ Tips = "启用测试模式中",
|
|
|
+ SuccessPattern = "Wakeup, unsleep:1 debug:0",
|
|
|
+ FailurePattern = "ERROR|FAIL",
|
|
|
+ Timeout = 4000,
|
|
|
+ DelayBefore = 300,
|
|
|
+ },
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ Name = "获取MAC地址",
|
|
|
+ Tips = "提取设备MAC地址",
|
|
|
+ Command = "AT+MAC?\r\n",
|
|
|
+ SuccessPattern = "MAC:",
|
|
|
+ FailurePattern = "ERROR|FAIL",
|
|
|
+ ExtractPattern = @"MAC:([0-9A-Fa-f]{2}(?::[0-9A-Fa-f]{2}){5})",
|
|
|
+ VariableNames = { "mac" },
|
|
|
+ PrivateCammand = true,
|
|
|
+ Timeout = 3000,
|
|
|
+ DelayBefore = 300,
|
|
|
+ Validator = (response, ctx) =>
|
|
|
+ {
|
|
|
+ // 示例:检查MAC地址格式
|
|
|
+ var mac = ctx.Variables["mac"];
|
|
|
+ Log($"设备mac地址{mac}", LogLevel.info);
|
|
|
+ return !IsValidMac(mac);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 版本号检查
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ Name = "获取版本信息",
|
|
|
+ Tips = "设备版本检查地址",
|
|
|
+ FailTips = "设备固件异常, 版本号:{{hwVersion}}{{hwTime}}",
|
|
|
+ Command = "AT+SEND=1, AT+HWCUST?\r\n",
|
|
|
+ SuccessPattern = @"\+HWCUST:",
|
|
|
+ FailurePattern = "ERROR|FAIL",
|
|
|
+ ExtractPattern = @"\+HWCUST:\s*\d+,\s*""([^""]+)"",\s*""([^""]+)""",
|
|
|
+ VariableNames = { "hwVersion" , "hwTime"},
|
|
|
+ Timeout = 6000,
|
|
|
+ DelayBefore = 300,
|
|
|
+ MaxRetries = 10,
|
|
|
+ Validator = (response, ctx) =>
|
|
|
+ {
|
|
|
+ // 示例:检查MAC地址格式
|
|
|
+ var hwVersion = ctx.Variables["hwVersion"];
|
|
|
+ var hwTime = ctx.Variables["hwTime"];
|
|
|
+ Log($"设备版本号 ${hwVersion}", LogLevel.info);
|
|
|
+ Log($"固件时间 ${hwTime}", LogLevel.info);
|
|
|
+ // 判断版本号是否为
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // sd卡测试
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "sdLoad",
|
|
|
+ Key = "sdLoad",
|
|
|
+ Name = "加载SD卡",
|
|
|
+ Command = "AT+SEND=1, AT+SDHCI=1\r\n",
|
|
|
+ Tips = "请确保SD卡插入",
|
|
|
+ SuccessPattern = "<=OK cmd:20",
|
|
|
+ FailurePattern = "ERROR|FAIL",
|
|
|
+ Timeout = 4000,
|
|
|
+ DelayBefore = 300,
|
|
|
+ FailContinue = true,
|
|
|
+ },
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "sdLoad",
|
|
|
+ GroupName = "SD卡检查",
|
|
|
+ Name = "检查是否加载成功",
|
|
|
+ Command = "AT+SEND=1,AT+CAMPARA?\r\n",
|
|
|
+ Tips = "检查sd卡加载状态中",
|
|
|
+ SuccessPattern = "/mnt/sdcard",
|
|
|
+ RetryFromKey = "sdLoad",
|
|
|
+ Timeout = 3000,
|
|
|
+ DelayBefore = 1000,
|
|
|
+ MaxJump = 5,
|
|
|
+ },
|
|
|
+
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "Audio_test",
|
|
|
+ Name = "配置视频格式",
|
|
|
+ Tips = "配置视频格式...",
|
|
|
+ Command = "AT+SEND=1, AT+CAMPARA=5\\,\"h264\"\r\n",
|
|
|
+ SuccessPattern = "<=OK cmd:20",
|
|
|
+ Timeout = 6000,
|
|
|
+ DelayBefore = 1000,
|
|
|
+ MaxRetries = 2,
|
|
|
+ },
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "Audio_test",
|
|
|
+ Key = "audioTest",
|
|
|
+ Name = "配置音频格式",
|
|
|
+ Tips = "音频格式配置",
|
|
|
+ Command = "AT+SEND=1, AT+CAMPARA=20\\,3\r\n",
|
|
|
+ SuccessPattern = "<=OK cmd:20",
|
|
|
+ Timeout = 6000,
|
|
|
+ DelayBefore = 1000,
|
|
|
+ MaxRetries = 2,
|
|
|
+ },
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "Audio_test",
|
|
|
+
|
|
|
+ Name = "录制视频",
|
|
|
+ Command = "AT+SEND=1,AT+CAMRV=0\\\\,\"test\"\r\n",
|
|
|
+ Tips = "视频录制中 请对着麦克风持续讲话",
|
|
|
+ FailTips = "无法录制视频, 检查设备镜头",
|
|
|
+ SuccessPattern = @"\+CAMRV: OK",
|
|
|
+ FailurePattern = "ERROR|FAIL",
|
|
|
+ ExtractPattern = $@"""(.*?.pcma)""",
|
|
|
+ VariableNames = { "audioFile" },
|
|
|
+ Timeout = 20000,
|
|
|
+ DelayBefore = 1000,
|
|
|
+ OnSuccess = ctx =>
|
|
|
+ {
|
|
|
+ Log($"视频文件{ctx.Variables["audioFile"]}");
|
|
|
+ // 保存文件路径到上下文
|
|
|
+ }
|
|
|
+ },
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "Audio_test",
|
|
|
+ GroupName = "音频测试",
|
|
|
+ Name = "播放音频",
|
|
|
+ Command = "AT+SEND=1, AT+HWAUDIO=5\\,\"{{audioFile}}\"\\,800\r\n",
|
|
|
+ //CommandGenerator = ctx =>
|
|
|
+ // $"AT+SEND=1, AT+HWAUDIO=5\\,\"{ctx.Variables["audioFile"]}\"\\,800\r\n",
|
|
|
+ RequiresUserPrompt = true,
|
|
|
+ PromptQuestion = "是否听到音频?",
|
|
|
+ Timeout = 10000,
|
|
|
+ DelayBefore = 500,
|
|
|
+ MaxRetries = 2,
|
|
|
+ RetryFromKey = "audioTest",
|
|
|
+ OnFailure = ctx =>
|
|
|
+ {
|
|
|
+ // 失败时重新录制
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 补光灯测试
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "Led_test",
|
|
|
+ Name = "打开LED",
|
|
|
+ Command = "AT+SEND=1,AT+FACTORY=4\\,\"echo 1 > /sys/class/gpio/gpio107/value\"\r\n",
|
|
|
+ Tips = "补光灯测试中",
|
|
|
+ SuccessPattern = @"\+FACTORY: 4",
|
|
|
+ RequiresUserPrompt = true,
|
|
|
+ PromptQuestion = "LED补光灯是否亮起?",
|
|
|
+ Timeout = 5000,
|
|
|
+ DelayBefore = 200,
|
|
|
+ MaxRetries = 3,
|
|
|
+ },
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "Led_test",
|
|
|
+ GroupName = "补光灯测试",
|
|
|
+ Name = "关闭LED补光灯",
|
|
|
+ Tips = "补光灯测试中",
|
|
|
+ Command = "AT+SEND=1,AT+FACTORY=4\\,\"echo 0 > /sys/class/gpio/gpio107/value\"\r\n",
|
|
|
+ SuccessText = "+FACTORY: 4",
|
|
|
+ RequiresUserPrompt = true,
|
|
|
+ PromptQuestion = "LED补光灯是否熄灭?",
|
|
|
+ Timeout = 5000,
|
|
|
+ DelayBefore = 200,
|
|
|
+ MaxRetries = 3,
|
|
|
+ },
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "red_test",
|
|
|
+ GroupName = "红外灯测试",
|
|
|
+ Name = "打开红外灯",
|
|
|
+ Command = "AT+SEND=1,AT+FACTORY=4\\,\"echo 1 > /sys/class/gpio/gpio108/value\"\r\n",
|
|
|
+ SuccessText = "+FACTORY: 4",
|
|
|
+ RequiresUserPrompt = true,
|
|
|
+ PromptQuestion = "红外补光灯是否亮起?",
|
|
|
+ Timeout = 5000,
|
|
|
+ DelayBefore = 200,
|
|
|
+ MaxRetries = 3,
|
|
|
+ },
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "red_test",
|
|
|
+ Name = "关闭红外灯",
|
|
|
+ Command = "AT+SEND=1,AT+FACTORY=4\\,\"echo 0 > /sys/class/gpio/gpio108/value\"\r\n",
|
|
|
+ SuccessText = "+FACTORY: 4",
|
|
|
+ RequiresUserPrompt = true,
|
|
|
+ PromptQuestion = "红外补光灯是否熄灭?",
|
|
|
+ Timeout = 5000,
|
|
|
+ DelayBefore = 200,
|
|
|
+ MaxRetries = 3,
|
|
|
+ },
|
|
|
+ // 设置基础信息
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "wifi_test",
|
|
|
+ ShowStep = false,
|
|
|
+ Name = "配置sd卡激活码",
|
|
|
+ Tips = "自动配置测试信息",
|
|
|
+ Action = ActionMode.SetVal,
|
|
|
+ VariableNames = { "sdCode" },
|
|
|
+ VariableValues = { sd_act },
|
|
|
+ PrivateCammand = true,
|
|
|
+ },
|
|
|
+ // wifi测试
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "wifi_test",
|
|
|
+ GroupName = "WiFi测试",
|
|
|
+ ShowStep = false,
|
|
|
+ Name = "配置WiFi",
|
|
|
+ Tips = "自动配置wifi信息",
|
|
|
+ Action = ActionMode.SetVal,
|
|
|
+ VariableNames = { "ssid", "password" },
|
|
|
+ VariableValues = { wifi_ssid, wifi_password },
|
|
|
+ },
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "wifi_test",
|
|
|
+ ShowStep = false,
|
|
|
+ Name = "配置设备激活码",
|
|
|
+ Tips = "自动配置wifi信息",
|
|
|
+ Action = ActionMode.SetVal,
|
|
|
+ VariableNames = { "activeCode" },
|
|
|
+ VariableValues = { wifi_act },
|
|
|
+ },
|
|
|
+ new TestStepConfig
|
|
|
+ {
|
|
|
+ GroupId = "wifi_test",
|
|
|
+ Name = "WiFi测试",
|
|
|
+ Tips = "正在连接WiFi中",
|
|
|
+ Command = "AT+WIFI=\"{{ssid}}\",\"{{password}}\",\"CN\",\"{{activeCode}}\"\r\n",
|
|
|
+ SuccessText = "WiFi_STAT: Connected",
|
|
|
+ Timeout = 10000,
|
|
|
+ DelayBefore = 500,
|
|
|
+ MaxRetries = 5,
|
|
|
+ },
|
|
|
+ // 上传测试
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ private bool IsValidMac(string mac)
|
|
|
+ {
|
|
|
+ // 实现MAC地址验证逻辑
|
|
|
+ return !string.IsNullOrEmpty(mac) && mac.Length == 17;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void HandleStepChanged(TestStepConfig step, TestContext context, bool isStarting)
|
|
|
+ {
|
|
|
+ this.Invoke((Action)(() =>
|
|
|
+ {
|
|
|
+ progressPanel.StateText = GetProgressState(step);
|
|
|
+ if (step.ShowStep)
|
|
|
+ {
|
|
|
+ Log($"step.ShowStep {step.Name}");
|
|
|
+ progressPanel.UpdateTestStepStatus(step.GroupId, step.Name, step.stepStatus);
|
|
|
+ }
|
|
|
+ if (isStarting)
|
|
|
+ {
|
|
|
+ // 步骤开始提示
|
|
|
+ ShowStepStart(step, context);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // 步骤结束提示
|
|
|
+ ShowStepCompletion(step, context);
|
|
|
+ }
|
|
|
+ }));
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ShowStepStart(TestStepConfig step, TestContext context)
|
|
|
+ {
|
|
|
+ // 更新UI显示当前步骤
|
|
|
+ //el_currentStepLabel.Text = $"{context.CurrentStepIndex + 1}/{context.Steps.Count} {step.Name}";
|
|
|
+ //el_stepDetailTextBox.Text = "正在执行...";
|
|
|
+
|
|
|
+ // 显示步骤提示
|
|
|
+ var tooltip = new ToolTip();
|
|
|
+ tooltip.ToolTipTitle = "步骤开始";
|
|
|
+ //tooltip.SetToolTip(el_currentStepLabel, step.Name);
|
|
|
+
|
|
|
+ // 在日志中显示
|
|
|
+ Log($"\n===== 开始步骤: {step.Name} =====");
|
|
|
+ Log($"描述: {GetStepDescription(step)}");
|
|
|
+ progressPanel.ProgressValue = 0;
|
|
|
+
|
|
|
+ if (step.JumpCount > 0)
|
|
|
+ {
|
|
|
+ progressPanel.CurrentTest = $"{step.Name} ({step.JumpCount}/{step.MaxJump})";
|
|
|
+ }
|
|
|
+ else if (step.RetryCount > 0)
|
|
|
+ {
|
|
|
+ progressPanel.CurrentTest = $"{step.Name} ({step.RetryCount}/{step.MaxRetries})";
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ progressPanel.CurrentTest = $"{step.Name}";
|
|
|
+ }
|
|
|
+
|
|
|
+ if (string.IsNullOrEmpty(step.Tips))
|
|
|
+ {
|
|
|
+ progressPanel.Message = GetStepDescription(step);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ progressPanel.Message = step.Tips;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ShowStepCompletion(TestStepConfig step, TestContext context)
|
|
|
+ {
|
|
|
+ string statusMessage = "➖ 步骤结束";
|
|
|
+
|
|
|
+ if (step.JumpCount > 0)
|
|
|
+ {
|
|
|
+ progressPanel.CurrentTest = $"{step.Name} ({step.JumpCount}/{step.MaxJump}) {statusMessage}";
|
|
|
+ }
|
|
|
+ else if (step.RetryCount > 0)
|
|
|
+ {
|
|
|
+ progressPanel.CurrentTest = $"{step.Name} ({step.RetryCount}/{step.MaxRetries}) {statusMessage}";
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ progressPanel.CurrentTest = $"{step.Name} {statusMessage}";
|
|
|
+ }
|
|
|
+ if (!string.IsNullOrEmpty(step.Tips))
|
|
|
+ {
|
|
|
+ progressPanel.Message = GetStepDescription(step);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ progressPanel.Message = step.Tips;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private string GetProgressState(TestStepConfig step)
|
|
|
+ {
|
|
|
+ string str = "";
|
|
|
+ switch (step.stepStatus)
|
|
|
+ {
|
|
|
+
|
|
|
+ case StepStatus.Failed:
|
|
|
+ str = "执行失败";
|
|
|
+ break;
|
|
|
+ case StepStatus.Running:
|
|
|
+ str = "等待执行";
|
|
|
+ break;
|
|
|
+ case StepStatus.Waiting:
|
|
|
+ str = "等待结果";
|
|
|
+ break;
|
|
|
+ case StepStatus.Success:
|
|
|
+ str = "执行完成";
|
|
|
+ break;
|
|
|
+ case StepStatus.NotRun:
|
|
|
+ default:
|
|
|
+ str = "待执行";
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return str;
|
|
|
+
|
|
|
+ }
|
|
|
+ private string GetStepDescription(TestStepConfig step)
|
|
|
+ {
|
|
|
+ var sb = new StringBuilder();
|
|
|
+ if (string.IsNullOrEmpty(step.Tips))
|
|
|
+ {
|
|
|
+ return step.Tips;
|
|
|
+ }
|
|
|
+ if (!string.IsNullOrEmpty(step.Command))
|
|
|
+ {
|
|
|
+ if (!step.PrivateCammand)
|
|
|
+ {
|
|
|
+ sb.AppendLine($"命令: {Truncate(step.Command, 50)}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!string.IsNullOrEmpty(step.SuccessPattern))
|
|
|
+ {
|
|
|
+ sb.AppendLine($"期待匹配: {step.SuccessPattern}");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!string.IsNullOrEmpty(step.FailurePattern))
|
|
|
+ {
|
|
|
+ sb.AppendLine($"失败匹配: {step.FailurePattern}");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (step.RequiresUserPrompt)
|
|
|
+ {
|
|
|
+ sb.AppendLine($"用户确认: {step.PromptQuestion}");
|
|
|
+ }
|
|
|
+
|
|
|
+ return sb.ToString();
|
|
|
+ }
|
|
|
+
|
|
|
+ private string Truncate(string value, int maxLength)
|
|
|
+ {
|
|
|
+ return value.Length <= maxLength ? value : value.Substring(0, maxLength) + "...";
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 加载成功图片
|
|
|
+ private Image LoadSuccessImage()
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ // 从资源加载
|
|
|
+ // return Properties.Resources.SuccessIcon;
|
|
|
+
|
|
|
+ // 动态生成成功图标
|
|
|
+ return CreateStatusImage(true);
|
|
|
+ }
|
|
|
+ catch
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 加载失败图片
|
|
|
+ private Image LoadFailureImage()
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ // 从资源加载
|
|
|
+ // return Properties.Resources.FailureIcon;
|
|
|
+
|
|
|
+ // 动态生成失败图标
|
|
|
+ return CreateStatusImage(false);
|
|
|
+ }
|
|
|
+ catch
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 加载取消图片
|
|
|
+ private Image LoadCancelledImage()
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ // 从资源加载
|
|
|
+ // return Properties.Resources.CancelledIcon;
|
|
|
+
|
|
|
+ // 动态生成取消图标
|
|
|
+ Bitmap bmp = new Bitmap(100, 100);
|
|
|
+ using (Graphics g = Graphics.FromImage(bmp))
|
|
|
+ {
|
|
|
+ g.Clear(Color.White);
|
|
|
+ g.DrawEllipse(new Pen(Color.Orange, 3), 10, 10, 80, 80);
|
|
|
+
|
|
|
+ // 感叹号
|
|
|
+ g.FillRectangle(Brushes.Orange, 45, 20, 10, 40);
|
|
|
+ g.FillRectangle(Brushes.Orange, 45, 70, 10, 10);
|
|
|
+ }
|
|
|
+ return bmp;
|
|
|
+ }
|
|
|
+ catch
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建状态图标
|
|
|
+ private Image CreateStatusImage(bool isSuccess)
|
|
|
+ {
|
|
|
+ Bitmap bmp = new Bitmap(100, 100);
|
|
|
+ using (Graphics g = Graphics.FromImage(bmp))
|
|
|
+ {
|
|
|
+ g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
|
|
|
+ g.Clear(Color.White);
|
|
|
+
|
|
|
+ if (isSuccess)
|
|
|
+ {
|
|
|
+ // 绿色对勾
|
|
|
+ using (Pen pen = new Pen(Color.Green, 4))
|
|
|
+ {
|
|
|
+ g.DrawEllipse(pen, 10, 10, 80, 80);
|
|
|
+ g.DrawLine(pen, 30, 50, 45, 70);
|
|
|
+ g.DrawLine(pen, 45, 70, 75, 30);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // 红色叉号
|
|
|
+ using (Pen pen = new Pen(Color.Red, 4))
|
|
|
+ {
|
|
|
+ g.DrawEllipse(pen, 10, 10, 80, 80);
|
|
|
+ g.DrawLine(pen, 30, 30, 70, 70);
|
|
|
+ g.DrawLine(pen, 70, 30, 30, 70);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return bmp;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+
|