| | |
| | | using HMI.Core.Setting; |
| | | using HMI.Core.Util; |
| | | using HMI.MQUtil; |
| | | using HMI.Simple.Util; |
| | | using HMI.UI.Util; |
| | | using HMI.Util; |
| | | using log4net; |
| | | using NationalInstruments.TestStand.Interop.API; |
| | | using NationalInstruments.TestStand.Interop.UI.Ax; |
| | | using NPOI.HSSF.UserModel; |
| | | using NPOI.SS.UserModel; |
| | | using OpenTap; |
| | | using Plugin.TsSupport; |
| | | using ScottPlot; |
| | | using ScottPlot.Plottables; |
| | |
| | | using System.ComponentModel; |
| | | using System.IO; |
| | | using System.Linq; |
| | | using System.Runtime.InteropServices; |
| | | using System.Timers; |
| | | using System.Windows; |
| | | using System.Windows.Controls; |
| | | using System.Windows.Forms.DataVisualization.Charting; |
| | | |
| | | namespace Plugin.TsExecution |
| | | { |
| | |
| | | /// <summary> |
| | | /// TS 引擎 |
| | | /// </summary> |
| | | private Engine engine = null; |
| | | //private Engine engine = null; |
| | | |
| | | ///// <summary> |
| | | ///// 测试序列 |
| | | ///// </summary> |
| | | //private SequenceFile testSeq = null; |
| | | |
| | | ///// <summary> |
| | | ///// 测试模型序列 |
| | | ///// </summary> |
| | | //private SequenceFile modeSeq = null; |
| | | |
| | | //private Execution execution = null; |
| | | |
| | | private string testSeqFile = string.Empty; |
| | | /// <summary> |
| | | /// 测试序列 |
| | | /// </summary> |
| | | private SequenceFile testSeq = null; |
| | | |
| | | /// <summary> |
| | | /// 测试模型序列 |
| | | /// </summary> |
| | | private SequenceFile modeSeq = null; |
| | | public AxApplicationMgr AxApplicationMgr; |
| | | private Execution execution = null; |
| | | |
| | | private SequenceContext sequenceContext = null; |
| | | |
| | | private Chart chart; |
| | | private ITestExecutionWrapper testExecutionWrapper; |
| | | #endregion |
| | | |
| | | public static ILog logger { get; private set; } |
| | | private List<SingleControl> tsSockets = new List<SingleControl>(); |
| | | public List<SingleControl> tsSockets { get; private set; } = new List<SingleControl>(); |
| | | /// <summary> |
| | | /// 样件模式状态 |
| | | /// </summary> |
| | |
| | | |
| | | |
| | | private bool isLoadOK = false; |
| | | private Timer GCTimer; |
| | | |
| | | private int PassAmount = 0; |
| | | private int FailAmount = 0; |
| | |
| | | foreach (SingleControl socket in tsSockets) |
| | | { |
| | | socket.RefreshProduct(value); |
| | | // socket.RefreshProbeCount(value); |
| | | } |
| | | } |
| | | SetTestSeqFile(value); |
| | |
| | | get => _enableCanLog; |
| | | set |
| | | { |
| | | if (WriteConfig("EnableCanLog", value)) |
| | | if (RequirePassword() == true) |
| | | { |
| | | Set(ref _enableCanLog, value); |
| | | if (WriteConfig("EnableCanLog", value)) |
| | | { |
| | | Set(ref _enableCanLog, value); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | get => _enableSimpleMode; |
| | | set |
| | | { |
| | | if (WriteConfig("EnableSimpleMode", value)) |
| | | if (RequirePassword() == true) |
| | | { |
| | | Set(ref _enableSimpleMode, value); |
| | | foreach (var cell in tsSockets) cell.SetSimpleUI(value); |
| | | if (WriteConfig("EnableSimpleMode", value)) |
| | | { |
| | | Set(ref _enableSimpleMode, value); |
| | | foreach (var cell in tsSockets) cell.SetSimpleUI(value); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | get => _ui_showInfoDock; |
| | | set |
| | | { |
| | | if (WriteConfig("UI_ShowInfoDock", value)) |
| | | if (RequirePassword() == true) |
| | | { |
| | | Set(ref _ui_showInfoDock, value); |
| | | detailPanel.Visibility = value ? Visibility.Visible : Visibility.Collapsed; |
| | | if (WriteConfig("UI_ShowInfoDock", value)) |
| | | { |
| | | Set(ref _ui_showInfoDock, value); |
| | | detailPanel.Visibility = value ? Visibility.Visible : Visibility.Collapsed; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | if (WriteIni("UI_CurrentWorkorder", value)) |
| | | { |
| | | Set(ref currentWorkorder, value); |
| | | engine?.Globals.SetValString("StationState.WorkOrder", 1, value); |
| | | engine?.CommitGlobalsToDisk(promptOnSaveConflicts: false); |
| | | testExecutionWrapper?.SetStationGlobalValue("StationState.WorkOrder", 1, value); |
| | | testExecutionWrapper?.CommitToDisk(false); |
| | | } |
| | | } |
| | | } |
| | |
| | | get => _DisableScanner; |
| | | set |
| | | { |
| | | if (WriteConfig("DisableScanner", value)) |
| | | if (RequirePassword() == true) |
| | | { |
| | | Set(ref _DisableScanner, value); |
| | | if (WriteConfig("DisableScanner", value)) |
| | | { |
| | | Set(ref _DisableScanner, value); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | private string tsModelPath; |
| | | private bool enableManualDebug; |
| | | public bool EnableManualDebug |
| | | { |
| | | get => enableManualDebug; |
| | | set |
| | | { |
| | | if (IsTesting) |
| | | { |
| | | MsgBoxHelper2.Warn("请先结束自动测试"); |
| | | return; |
| | | } |
| | | Set(ref enableManualDebug, value); |
| | | } |
| | | } |
| | | |
| | | public string tsModelPath { get; private set; } |
| | | private string dataLogPath; |
| | | private SqliteHelper sqliteHelper; |
| | | |
| | |
| | | public TsExecution() |
| | | { |
| | | DataContext = this; |
| | | GCTimer = new Timer(); |
| | | InitializeComponent(); |
| | | |
| | | InitChart(); |
| | | InitTsEngine(); |
| | | //初始化TestStand引擎 |
| | | this.InitTestStandEngine(); |
| | | } |
| | | |
| | | public override void SetBaseFolder(string folder) |
| | |
| | | |
| | | public override void InitFinish() |
| | | { |
| | | InitTsEngine(); |
| | | this.ReadCount(out int pass, out int fail); |
| | | this.DisplayCount(pass, fail); |
| | | ReadConfig(); |
| | |
| | | { |
| | | UserInfo user = UserInfo.User; |
| | | CurrentUserCode = user?.Code; |
| | | engine?.Globals.SetValString("StationState.OPID", 1, CurrentUserCode); |
| | | engine?.CommitGlobalsToDisk(promptOnSaveConflicts: false); |
| | | |
| | | testExecutionWrapper?.SetStationGlobalValue("StationState.OPID", 1, CurrentUserCode); |
| | | testExecutionWrapper?.CommitToDisk(false); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | log.Warn("Get Login User Failed.", ex); |
| | | } |
| | | RefreshUIConfig(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 刷新UI配置 |
| | | /// </summary> |
| | | private void RefreshUIConfig() |
| | | { |
| | | try |
| | | { |
| | | bool enableManualDebug = ParameterManager.GetCommonParameterByName("EnableManualDebug", false); |
| | | if (enableManualDebug) |
| | | { |
| | | Cb_ManualDebug.Visibility = Visibility.Visible; |
| | | EnableManualDebug = false; |
| | | } |
| | | else |
| | | { |
| | | Cb_ManualDebug.Visibility = Visibility.Collapsed; |
| | | EnableManualDebug = false; |
| | | } |
| | | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | log.Error("RefreshUIConfig Error.", ex); |
| | | } |
| | | } |
| | | |
| | |
| | | Products = ProductManager.GetProducts<ObservableCollection<ProductData>>(); |
| | | if (Products != null && Products.Count > 0) |
| | | { |
| | | string lastModel = engine?.Globals.GetValString("StationState.ProductModel", 1); |
| | | string lastModel = testExecutionWrapper?.GetStationGlobalValue<string>("StationState.ProductModel", 1); |
| | | var tempProduct = Products[0]; |
| | | if (!string.IsNullOrEmpty(lastModel)) |
| | | { |
| | |
| | | /// </summary> |
| | | private void InitTsEngine() |
| | | { |
| | | AxApplicationMgr = TestAppManager.GetAxApplicationMgr(); |
| | | if (ParamSetting.EngineType == "Tap") |
| | | { |
| | | var wrapper = new TapWrapper(); |
| | | wrapper.RegisteUserInput(this); |
| | | log.Debug($"Wrapper UI is {wrapper.ui}"); |
| | | testExecutionWrapper = wrapper; |
| | | } |
| | | else |
| | | { |
| | | testExecutionWrapper = new TeststandWrapper(); |
| | | } |
| | | |
| | | |
| | | //AxApplicationMgr. += AxApplicationMgr_EndExecution; |
| | | AxApplicationMgr.EndExecution += AxApplicationMgr_EndExecution; |
| | | |
| | | AxApplicationMgr.ExitApplication += this.AxApplicationMgr_ExitApplication; |
| | | AxApplicationMgr.UIMessageEvent += this.AxApplicationMgr_UIMessageEvent; |
| | | AxApplicationMgr.ExecutionClosed += this.AxApplicationMgr_ExecutionClosed; |
| | | |
| | | ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).BeginInit(); |
| | | host.Child = AxApplicationMgr; |
| | | ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).EndInit(); |
| | | testExecutionWrapper.EndExecutionEvent += TestExecutionWrapper_EndExecutionEvent; |
| | | testExecutionWrapper.UIMessageEvent += TestExecutionWrapper_UIMessageEvent; |
| | | if (testExecutionWrapper is TeststandWrapper tsw) |
| | | { |
| | | var AxApplicationMgr = tsw.AxApplicationMgr; |
| | | ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).BeginInit(); |
| | | host.Child = AxApplicationMgr; |
| | | ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).EndInit(); |
| | | } |
| | | testExecutionWrapper.Init(); |
| | | } |
| | | |
| | | private volatile bool canSwitchModel = false; |
| | | private volatile Action switchAction = null; |
| | | private void TestExecutionWrapper_UIMessageEvent(object sender, UIMessageEvent e) |
| | | { |
| | | try |
| | | { |
| | | int eventCode = Convert.ToInt32(e.EventCode); |
| | | int index = Convert.ToInt16(e.NumberData);//SocketIndex |
| | | string strData = e.StrData; |
| | | |
| | | private void AxApplicationMgr_EndExecution(object sender, _ApplicationMgrEvents_EndExecutionEvent e) |
| | | try |
| | | { |
| | | log.Debug($"Event: {eventCode}, NumericData: {index}, StringData: {strData}"); |
| | | } |
| | | catch |
| | | { |
| | | |
| | | } |
| | | if (eventCode == 10001) |
| | | { |
| | | testExecutionWrapper?.SetContext((SequenceContext)e.Data); |
| | | tsSockets[index].SequenceFileContext = (SequenceContext)e.Data; |
| | | return; |
| | | } |
| | | HandleUIMessage(eventCode, index, strData); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | log.Warn("Ts Event Error.", ex); |
| | | } |
| | | } |
| | | |
| | | private void TestExecutionWrapper_EndExecutionEvent(object sender, ExecutionEndEvent e) |
| | | { |
| | | log.Info("AxApplicationMgr_EndExecution"); |
| | | if (ReleaseSequenceFile()) |
| | |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 进程结束事件 |
| | | /// </summary> |
| | | /// <param name="sender"></param> |
| | | /// <param name="e"></param> |
| | | private void AxApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e) |
| | | { |
| | | //ReleaseSequenceFile(); |
| | | } |
| | | private volatile bool canSwitchModel = false; |
| | | private volatile Action switchAction = null; |
| | | |
| | | private void PluginControl_Loaded(object sender, RoutedEventArgs e) |
| | | { |
| | |
| | | { |
| | | log.Error("TsExecution Loaded Failed.", ex); |
| | | MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.UserControlLoadFailed")}: {ex.Message}"); |
| | | } |
| | | |
| | | try |
| | | { |
| | | if (Environment.Version.ToString() != this.AxApplicationMgr.GetEngine().DotNetCLRVersion) |
| | | this.GCTimer.Enabled = true; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | log.Error("TsExecution GCTimer Start Failed", ex); |
| | | MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.LoadFailed")}: {ex.Message}"); |
| | | } |
| | | |
| | | Dispatcher.Invoke(() => |
| | |
| | | { |
| | | SocketName = name |
| | | }; |
| | | control.parent = this; |
| | | panel.Children.Add(control); |
| | | tsSockets.Add(control); |
| | | |
| | |
| | | else |
| | | { |
| | | panel.Columns = 2; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 初始化TestStand引擎 |
| | | /// </summary> |
| | | private void InitTestStandEngine() |
| | | { |
| | | try |
| | | { |
| | | this.engine = this.AxApplicationMgr.GetEngine(); |
| | | this.engine.PersistBreakpoints = false; |
| | | this.AxApplicationMgr.IsEditor = true; |
| | | this.AxApplicationMgr.LoginOnStart = false; |
| | | this.AxApplicationMgr.Start(); |
| | | //this.modeSeq = this.engine.GetSequenceFileEx(@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq"); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | throw new Exception(LangUtil.Get("Ts.InitTestStandEngineFail"), ex); |
| | | } |
| | | } |
| | | |
| | |
| | | /// <param name="fail"></param> |
| | | private void ReadConfig() |
| | | { |
| | | ParameterData value; |
| | | HMI.Core.Entity.ParameterData value; |
| | | |
| | | |
| | | bool flag = false; |
| | |
| | | { |
| | | |
| | | value = ParameterManager.GetCommonParameterByName("TestReportFolder"); |
| | | csvDir = value.Value; |
| | | csvDir = value?.Value ?? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestReport"); |
| | | if (!Directory.Exists(csvDir)) |
| | | { |
| | | Directory.CreateDirectory(csvDir); |
| | |
| | | { |
| | | |
| | | value = ParameterManager.GetCommonParameterByName("IsOptRequirePassword"); |
| | | IsOptRequirePassword = bool.Parse(value.Value); |
| | | IsOptRequirePassword = value == null ? false : bool.Parse(value.Value); |
| | | } |
| | | catch |
| | | { |
| | |
| | | foreach (var ts in tsSockets) |
| | | { |
| | | ts?.SequenceFileContext?.StationGlobals.SetValBoolean($"SystemSetting.{name}", 1, value); |
| | | if (ts?.SequenceFileContext?.Sequence != null) |
| | | if (name == "EnableDebugMode" && ts?.SequenceFileContext?.Sequence != null) |
| | | { |
| | | ts.SequenceFileContext.Sequence.FailureAction = |
| | | value ? FailureActions.FailureAction_None : FailureActions.FailureAction_GotoCleanup; |
| | |
| | | /// </summary> |
| | | private void StartSequence() |
| | | { |
| | | log.Info($"Start ATE Seq isLoadOK:{isLoadOK}"); |
| | | if (!isLoadOK) return; |
| | | engine?.Globals.SetValBoolean("StationState.StopTest", 0, false); |
| | | try |
| | | { |
| | | testExecutionWrapper?.SetStationGlobalValue("StationState.StopTest", 1, false); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | log.Error("Reset StopTest Failed.", ex); |
| | | } |
| | | if (ParamSetting.EnableAutoModel) |
| | | { |
| | | try |
| | |
| | | return; |
| | | } |
| | | this.testSeqFile = path; |
| | | this.modeSeq = this.engine.GetSequenceFileEx(tsModelPath); |
| | | this.testSeq = this.engine.GetSequenceFileEx(this.testSeqFile, 2, TypeConflictHandlerTypes.ConflictHandler_UseGlobalType); |
| | | this.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null); |
| | | testExecutionWrapper?.StartSequence(this.testSeqFile, this.tsModelPath); |
| | | //this.modeSeq = this.engine.GetSequenceFileEx(tsModelPath); |
| | | //this.testSeq = this.engine.GetSequenceFileEx(this.testSeqFile, 2, TypeConflictHandlerTypes.ConflictHandler_UseGlobalType); |
| | | //this.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null); |
| | | IsTesting = true; |
| | | } |
| | | catch (Exception ex) |
| | |
| | | //MaskWindow mask = new MaskWindow(); |
| | | try |
| | | { |
| | | engine?.Globals.SetValString("StationState.ProductModel", 1, CurrentProductModel); |
| | | engine?.CommitGlobalsToDisk(promptOnSaveConflicts: false); |
| | | this.modeSeq = this.engine.GetSequenceFileEx(tsModelPath); |
| | | this.testSeq = this.engine.GetSequenceFileEx(this.testSeqFile, 2, TypeConflictHandlerTypes.ConflictHandler_UseGlobalType); |
| | | this.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null); |
| | | testExecutionWrapper?.SetStationGlobalValue("StationState.ProductModel", 1, CurrentProductModel); |
| | | testExecutionWrapper?.CommitToDisk(false); |
| | | testExecutionWrapper?.StartSequence(this.testSeqFile, this.tsModelPath); |
| | | //this.modeSeq = this.engine.GetSequenceFileEx(tsModelPath); |
| | | //this.testSeq = this.engine.GetSequenceFileEx(this.testSeqFile, 2, TypeConflictHandlerTypes.ConflictHandler_UseGlobalType); |
| | | //this.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null); |
| | | IsTesting = true; |
| | | } |
| | | catch (Exception ex) |
| | |
| | | { |
| | | try |
| | | { |
| | | if (this.tsSockets.Count > 0) |
| | | { |
| | | for (int i = 0; i < tsSockets.Count; i++) |
| | | { |
| | | var context = this.tsSockets[i].SequenceFileContext; |
| | | context?.StationGlobals.SetValBoolean("StationState.StopTest", 1, true); |
| | | } |
| | | } |
| | | if (this.execution == null) return true; |
| | | testExecutionWrapper.SetStationGlobalValue("StationState.StopTest", 1, true); |
| | | |
| | | |
| | | //bool res = this.execution.WaitForEndEx(-1, true, null, null); |
| | | bool res = this.execution?.WaitForEndEx(-1, true, Type.Missing, null) == true; |
| | | Marshal.ReleaseComObject(this.execution); |
| | | this.execution = null; |
| | | bool res = this.testExecutionWrapper.WaitForExit(); |
| | | //if (this.execution != null) |
| | | // Marshal.ReleaseComObject(this.execution); |
| | | //this.execution = null; |
| | | return res; |
| | | } |
| | | catch (Exception ex) |
| | |
| | | // }).Info(LangUtil.Get("Ts.SequenceIsStarting")); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 退出应用 |
| | | /// </summary> |
| | | /// <param name="sender"></param> |
| | | /// <param name="e"></param> |
| | | private void AxApplicationMgr_ExitApplication(object sender, EventArgs e) |
| | | { |
| | | //Environment.ExitCode = this.AxApplicationMgr.ExitCode; |
| | | //this.Close(); |
| | | } |
| | | |
| | | public void UpdatePositionStatus(int index, string status) |
| | | { |
| | | this.tsSockets[index].UpdateStatus(status); |
| | | this.UpdateTestCounter(); |
| | | Dispatcher.Invoke(() => |
| | | { |
| | | this.tsSockets[index].UpdateStatus(status); |
| | | OnStatusPublished(index, status); |
| | | this.UpdateTestCounter(); |
| | | }); |
| | | } |
| | | |
| | | private void OnStatusPublished(int index, string status) |
| | | { |
| | | if (ParamSetting.CustomerCode != "SOUND") |
| | | { |
| | | return; |
| | | } |
| | | if (status == "Passed" || status == "Failed") |
| | | { |
| | | SaveSOUNDExcel(index, status); |
| | | } |
| | | } |
| | | |
| | | private string ConvertStatus(string status) |
| | | { |
| | | if (string.Equals(status, "passed", StringComparison.OrdinalIgnoreCase)) |
| | | { |
| | | return "Pass"; |
| | | } |
| | | else |
| | | { |
| | | return "Fail"; |
| | | } |
| | | } |
| | | |
| | | #region 桑德定制 |
| | | private ICell CreateCell(ISheet sheet, int r, int c, ICellStyle style) |
| | | { |
| | | var row = sheet.GetRow(r); |
| | | if (row == null) |
| | | { |
| | | row = sheet.CreateRow(r); |
| | | } |
| | | var cell = row.GetCell(c); |
| | | if (cell == null) |
| | | { |
| | | cell = row.CreateCell(c); |
| | | } |
| | | if (style != null) |
| | | { |
| | | cell.CellStyle = style; |
| | | } |
| | | return cell; |
| | | } |
| | | |
| | | private string GetOutputFolder() |
| | | { |
| | | var value = ParameterManager.GetCommonParameterByName("SOUND_Output"); |
| | | if (value != null) |
| | | { |
| | | return value.Value; |
| | | } |
| | | return ParamSetting.DataLogFolder; |
| | | } |
| | | |
| | | private void SaveSOUNDExcel(int index, string status) |
| | | { |
| | | lock (this) |
| | | { |
| | | try |
| | | { |
| | | string outputFolder = GetOutputFolder(); |
| | | |
| | | var socket = this.tsSockets[index]; |
| | | DateTime testTime = DateTime.Now; |
| | | string filePath = Path.Combine(outputFolder, $"{testTime.ToString("yy-MM-dd")}_{CurrentProductModel}.xls"); |
| | | if (!File.Exists(filePath)) |
| | | { |
| | | Dictionary<string, int> columnMap = new Dictionary<string, int>(); |
| | | HSSFWorkbook workbook = new HSSFWorkbook(); |
| | | ISheet sheet = workbook.CreateSheet("Sheet1"); |
| | | |
| | | ICellStyle border = workbook.CreateCellStyle(); |
| | | border.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin; |
| | | border.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin; |
| | | border.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin; |
| | | border.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin; |
| | | border.BottomBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index; |
| | | border.TopBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index; |
| | | border.LeftBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index; |
| | | border.RightBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index; |
| | | |
| | | |
| | | ICellStyle red = workbook.CreateCellStyle(); |
| | | red.CloneStyleFrom(border); |
| | | red.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Red.Index; |
| | | red.FillPattern = FillPattern.SolidForeground; |
| | | |
| | | ICellStyle green = workbook.CreateCellStyle(); |
| | | green.CloneStyleFrom(border); |
| | | green.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.BrightGreen.Index; |
| | | green.FillPattern = FillPattern.SolidForeground; |
| | | |
| | | CreateCell(sheet, 1, 0, border); |
| | | CreateCell(sheet, 1, 1, border); |
| | | CreateCell(sheet, 1, 2, border); |
| | | CreateCell(sheet, 1, 3, border); |
| | | CreateCell(sheet, 1, 4, border); |
| | | |
| | | CreateCell(sheet, 2, 0, border); |
| | | CreateCell(sheet, 2, 1, border); |
| | | CreateCell(sheet, 2, 2, border); |
| | | CreateCell(sheet, 2, 3, border); |
| | | CreateCell(sheet, 2, 4, border).SetCellValue("上限"); |
| | | |
| | | CreateCell(sheet, 3, 0, border).SetCellValue("测试时间"); |
| | | CreateCell(sheet, 3, 1, border).SetCellValue("测试人"); |
| | | CreateCell(sheet, 3, 2, border).SetCellValue("测试设备"); |
| | | CreateCell(sheet, 3, 3, border).SetCellValue("条形码"); |
| | | CreateCell(sheet, 3, 4, border).SetCellValue("下限"); |
| | | |
| | | int column = 5; |
| | | int row = 4; |
| | | |
| | | CreateCell(sheet, row, 0, border).SetCellValue(testTime.ToString("*HH:mm:ss*")); |
| | | CreateCell(sheet, row, 1, border).SetCellValue(UserInfo.User.Name); |
| | | CreateCell(sheet, row, 2, border).SetCellValue(ParamSetting.StationName); |
| | | CreateCell(sheet, row, 3, border).SetCellValue(socket.Barcode); |
| | | CreateCell(sheet, row, 4, status == "Passed" ? green : red).SetCellValue(ConvertStatus(status)); |
| | | |
| | | foreach (var data in socket.Datasource) |
| | | { |
| | | int col = column; |
| | | if (columnMap.ContainsKey(data.Name)) |
| | | { |
| | | col = columnMap[data.Name]; |
| | | } |
| | | else |
| | | { |
| | | columnMap[data.Name] = column++; |
| | | } |
| | | |
| | | CreateCell(sheet, 1, col, border).SetCellValue(data.Name); |
| | | CreateCell(sheet, 2, col, border).SetCellValue(data.LimitUp); |
| | | CreateCell(sheet, 3, col, border).SetCellValue(data.LimitDown); |
| | | CreateCell(sheet, row, col, data.Result == "Failed" ? red : border).SetCellValue(data.Value); |
| | | } |
| | | using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate)) |
| | | { |
| | | workbook.Write(fs); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | using (FileStream fs = File.OpenRead(filePath)) |
| | | { |
| | | IWorkbook workbook = new HSSFWorkbook(fs); |
| | | ICellStyle border = workbook.CreateCellStyle(); |
| | | border.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin; |
| | | border.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin; |
| | | border.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin; |
| | | border.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin; |
| | | border.BottomBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index; |
| | | border.TopBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index; |
| | | border.LeftBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index; |
| | | border.RightBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index; |
| | | |
| | | |
| | | ICellStyle red = workbook.CreateCellStyle(); |
| | | red.CloneStyleFrom(border); |
| | | red.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Red.Index; |
| | | red.FillPattern = FillPattern.SolidForeground; |
| | | |
| | | ICellStyle green = workbook.CreateCellStyle(); |
| | | green.CloneStyleFrom(border); |
| | | green.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.BrightGreen.Index; |
| | | green.FillPattern = FillPattern.SolidForeground; |
| | | |
| | | ISheet sheet = workbook.GetSheet("Sheet1"); |
| | | Dictionary<string, int> columnMap = new Dictionary<string, int>(); |
| | | var titleRow = sheet.GetRow(1); |
| | | for (int i = 0; i < titleRow.LastCellNum; i++) |
| | | { |
| | | if (!string.IsNullOrEmpty(titleRow.GetCell(i).StringCellValue)) |
| | | { |
| | | columnMap[titleRow.GetCell(i).StringCellValue] = i; |
| | | } |
| | | } |
| | | int row = sheet.LastRowNum + 1; |
| | | CreateCell(sheet, row, 0, border).SetCellValue(testTime.ToString("*HH:mm:ss*")); |
| | | CreateCell(sheet, row, 1, border).SetCellValue(UserInfo.User.Name); |
| | | CreateCell(sheet, row, 2, border).SetCellValue(ParamSetting.StationName); |
| | | CreateCell(sheet, row, 3, border).SetCellValue(socket.Barcode); |
| | | CreateCell(sheet, row, 4, status == "Passed" ? green : red).SetCellValue(ConvertStatus(status)); |
| | | |
| | | foreach (var data in socket.Datasource) |
| | | { |
| | | int col = titleRow.LastCellNum; |
| | | if (columnMap.ContainsKey(data.Name)) |
| | | { |
| | | col = columnMap[data.Name]; |
| | | } |
| | | else |
| | | { |
| | | columnMap[data.Name] = col; |
| | | } |
| | | |
| | | CreateCell(sheet, 1, col, border).SetCellValue(data.Name); |
| | | CreateCell(sheet, 2, col, border).SetCellValue(data.LimitUp); |
| | | CreateCell(sheet, 3, col, border).SetCellValue(data.LimitDown); |
| | | CreateCell(sheet, row, col, data.Result == "Failed" ? red : border).SetCellValue(data.Value); |
| | | } |
| | | using (FileStream nfs = new FileStream(filePath, FileMode.OpenOrCreate)) |
| | | { |
| | | workbook.Write(nfs); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | log.Error("SOUND Export Excel Data Error.", ex); |
| | | } |
| | | } |
| | | } |
| | | #endregion |
| | | |
| | | public void UpdatePositionProcessValue(int index, int value) |
| | | { |
| | |
| | | sqls.Add($@"INSERT INTO serialData (sn,model,station,step,position,limitDown,limitUp,unit,value,status,finalStatus,consumeTime,totalConsumeTime,time) VALUES |
| | | ('{snr}','{model}','','{data.Name}','{index}','{data.LimitDown}','{data.LimitUp}','{data.Unit}','{data.Value}','{data.Result}','{socket.Status}','{data.ConsumeTime}','{socket.ElapseTime}','{time}')"); |
| | | } |
| | | sqls.Add($@"INSERT INTO testResult (sn,model,station,result,time,position,status) VALUES |
| | | ('{snr}','{model}','','{socket.Status}','{time}','{index}','{status}')"); |
| | | sqliteHelper.ExecuteBatchSql(sqls); |
| | | |
| | | var ssql = $@"INSERT INTO testResult (sn,model,station,result,time,position,status) VALUES |
| | | ('{snr}','{model}','','{socket.Status}','{time}','{index}','{status}')"; |
| | | sqliteHelper.ExecuteSql(ssql); |
| | | } |
| | | |
| | | private void HandleUIMessage(int eventCode, int index, string strData) |
| | |
| | | break; |
| | | |
| | | case 10006://发送产品条码 |
| | | SetPositionBarcode(index, strData); |
| | | Dispatcher.Invoke(() => |
| | | { |
| | | SetPositionBarcode(index, strData); |
| | | }); |
| | | break; |
| | | |
| | | case 10007://开始测试计时 |
| | | tsSockets[index].ElapseTime = "Start Timing"; |
| | | BtnStopSeq.IsEnabled = false; |
| | | Dispatcher.Invoke(() => |
| | | { |
| | | tsSockets[index].ElapseTime = "Start Timing"; |
| | | BtnStopSeq.IsEnabled = false; |
| | | }); |
| | | break; |
| | | |
| | | case 10008://停止测试计时 |
| | | tsSockets[index].ElapseTime = "Stop Timing"; |
| | | BtnStopSeq.IsEnabled = true; |
| | | Dispatcher.Invoke(() => |
| | | { |
| | | tsSockets[index].ElapseTime = "Stop Timing"; |
| | | BtnStopSeq.IsEnabled = true; |
| | | }); |
| | | break; |
| | | |
| | | case 10009: |
| | |
| | | |
| | | break; |
| | | case 10017://更新测试计时,针对部分计时有PLC完成的项目 |
| | | this.tsSockets[index].ElapseTime = strData; |
| | | Dispatcher.Invoke(() => |
| | | { |
| | | this.tsSockets[index].ElapseTime = strData; |
| | | }); |
| | | break; |
| | | case (int)UIMessageCodes.UIMsg_EndExecution://执行结束 |
| | | //IsTesting = false; |
| | |
| | | break; |
| | | case 10030://显示测试进度 |
| | | int ProcessVal = Convert.ToInt32(strData); |
| | | this.tsSockets[index].SetTestProcess(ProcessVal); |
| | | Dispatcher.Invoke(() => |
| | | { |
| | | this.tsSockets[index].SetTestProcess(ProcessVal); |
| | | }); |
| | | break; |
| | | case 10031://导出CSV |
| | | |
| | | if (ParamSetting.CustomerCode == "SOUND") |
| | | { |
| | | string[] datas = strData.Split(';'); |
| | | this.tsSockets[index].WriteToExcel(datas[0]); |
| | | if (datas.Length >= 2) |
| | | { |
| | | SavePositionDB(index, datas[1]); |
| | | } |
| | | else |
| | | { |
| | | Dispatcher.Invoke(() => |
| | | { |
| | | var sss = this.tsSockets[index].Status; |
| | | SavePositionDB(index, sss); |
| | | }); |
| | | } |
| | | return; |
| | | } |
| | | |
| | | if (string.IsNullOrEmpty(strData)) |
| | | { |
| | | SaveTemplateCSV(index); |
| | |
| | | } |
| | | else |
| | | { |
| | | var sss = this.tsSockets[index].Status; |
| | | SavePositionDB(index, sss); |
| | | Dispatcher.Invoke(() => |
| | | { |
| | | var sss = this.tsSockets[index].Status; |
| | | SavePositionDB(index, sss); |
| | | }); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | |
| | | points[i - 1] = new int[2] { int.Parse(strs[0]), int.Parse(strs[1]) }; |
| | | } |
| | | this.tsSockets[index].DrawScreenPoints(int.Parse(arr_10035[0]), points); |
| | | break; |
| | | case 100350: |
| | | string[] arr_100350 = strData.Split(';'); |
| | | |
| | | int[][] points_0 = new int[arr_100350.Length - 1][]; |
| | | |
| | | for (int i = 1; i < arr_100350.Length; i++) |
| | | { |
| | | if (string.IsNullOrEmpty(arr_100350[i])) |
| | | { |
| | | continue; |
| | | } |
| | | string[] strs = arr_100350[i].Split(','); |
| | | points_0[i - 1] = new int[2] { int.Parse(strs[0]), int.Parse(strs[1]) }; |
| | | } |
| | | this.tsSockets[index].DrawNewScreenPoints(int.Parse(arr_100350[0]), points_0); |
| | | break; |
| | | case 10036: |
| | | this.tsSockets[index].ClearScreenPoint(int.Parse(strData)); |
| | |
| | | { |
| | | log?.Info("开始自动换型"); |
| | | SelectedProduct = target; |
| | | engine?.Globals.SetValString($"CacheSNR[{index}]", 1, snr); |
| | | engine?.CommitGlobalsToDisk(false); |
| | | testExecutionWrapper?.SetStationGlobalValue($"CacheSNR[{index}]", 1, snr); |
| | | testExecutionWrapper?.CommitToDisk(false); |
| | | StartClick(); |
| | | } |
| | | catch (Exception ex) |
| | |
| | | private void ShowAlarm(AlarmText alarm) |
| | | { |
| | | AlarmShowHelper.ShowAlarm(alarm); |
| | | mSMQHelper.Send("Alarm", $"ATE测试 {alarm.AlarmInfo}"); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// TestStand用户交互事件 |
| | | /// </summary> |
| | | /// <param name="sender"></param> |
| | | /// <param name="e"></param> |
| | | private void AxApplicationMgr_UIMessageEvent(object sender, _ApplicationMgrEvents_UIMessageEventEvent e) |
| | | { |
| | | try |
| | | { |
| | | int eventCode = Convert.ToInt32(e.uiMsg.Event); |
| | | int index = Convert.ToInt16(e.uiMsg.NumericData);//SocketIndex |
| | | string strData = e.uiMsg.StringData; |
| | | |
| | | try |
| | | { |
| | | log.Debug($"Event: {eventCode}, NumericData: {index}, StringData: {strData}"); |
| | | } |
| | | catch |
| | | { |
| | | |
| | | } |
| | | if (eventCode == 10001) |
| | | { |
| | | sequenceContext = (SequenceContext)e.uiMsg.ActiveXData; |
| | | |
| | | tsSockets[index].SequenceFileContext = (SequenceContext)e.uiMsg.ActiveXData; |
| | | return; |
| | | } |
| | | HandleUIMessage(eventCode, index, strData); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | log.Warn("Ts Event Error.", ex); |
| | | } |
| | | mSMQHelper.Send("Alarm", "PC", $"ATE测试 {alarm.AlarmInfo}", 2); |
| | | } |
| | | |
| | | private void UpdateTestCounter() |
| | |
| | | return; |
| | | } |
| | | string name = product.Name; |
| | | List<ParameterData> parameters = ProductManager.GetParametersByProductName(name); |
| | | List<HMI.Core.Entity.ParameterData> parameters = ProductManager.GetParametersByProductName(name); |
| | | testSeqFile = parameters.FirstOrDefault(p => p.Name == "TestSequence")?.Value?.ToString(); |
| | | if (AutoExecuteSeq) |
| | | { |
| | |
| | | |
| | | public override void DoClose(object sender, EventArgs e) |
| | | { |
| | | testExecutionWrapper?.Dispose(); |
| | | base.DoClose(sender, e); |
| | | } |
| | | |
| | |
| | | { |
| | | lock (this) |
| | | { |
| | | if (this.testSeq == null) |
| | | { |
| | | return true; |
| | | } |
| | | //execution.Abort(); |
| | | int count = 10; |
| | | while (count > 0) |
| | | { |
| | | try |
| | | { |
| | | if (this.testSeq == null) |
| | | return true; |
| | | |
| | | if (this.engine?.ReleaseSequenceFileEx(this.testSeq, 4) == true) |
| | | { |
| | | Marshal.ReleaseComObject(this.testSeq); |
| | | this.testSeq = null; |
| | | // GC.Collect(); |
| | | } |
| | | if (this.engine?.ReleaseSequenceFileEx(this.modeSeq, 4) == true) |
| | | { |
| | | Marshal.ReleaseComObject(this.modeSeq); |
| | | this.modeSeq = null; |
| | | } |
| | | this.engine?.UnloadAllModules(); |
| | | return this.testSeq == null && this.modeSeq == null; |
| | | return testExecutionWrapper.ReleaseSeqFile(); |
| | | } |
| | | catch (Exception ex) |
| | | { |