using DC_A95; using ExternalDataSync; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using SystemFramework; using WebApi; namespace MesWork { /// /// 程式启动 /// public partial class MesWorkForm { /// /// 从这里启动 /// /// protected override void OnShown(EventArgs e) { } public void OnStart(params object[] o) { //【1】系统基本参数设定 ThreadPool.SetMaxThreads(workerThreads, completionPortThreads); Never_Know.Hello_You_All_Never_Know = Hello_You_All_Never_Know; // 加载信号表(按设备类型对应表展开多工位) var (dt_Tag_Mes, dt_Device) = BuildSignalTable(BasicDataTableFile); // 保存工位名称列表及显示名映射(供UC_Weighing标题使用) StationOpNames = new System.Collections.Generic.List(); StationDisplayNames = new System.Collections.Generic.Dictionary(System.StringComparer.OrdinalIgnoreCase); int stIdx = 1; foreach (System.Data.DataRow row in dt_Device.Rows) { string opName = row["工位号"].ToString().Trim(); string dataSource = row["数据来源"].ToString().Trim(); // 称重位1, 称重位2 StationOpNames.Add(opName); // 显示格式:"OP10-称重位1" StationDisplayNames[opName] = $"{opName}-{dataSource}"; stIdx++; } ValidateStationConfig(); LoadOPCData(dt_Tag_Mes, dt_Device, IsDemoMesServer, IsWriteMonitorLog, true, false, out string error); if (error.Length > 0) { MessageBox.Show($"加载信号产生错误,程序不能启动!!错误:{error}"); Process.GetCurrentProcess().Kill(); } Thread.Sleep(200); StartServer(); Thread.Sleep(200); First_TagMonitor(); var task1 = new Thread(new ThreadStart(Loop_SelectAlarmShow)); task1.IsBackground = true; task1.Start(); // Loop_ReadRealPageShow 已移除,PLC信号显示将在 UC_Weighing 中实现 // var task2 = new Thread(new ThreadStart(Loop_ReadRealPageShow)); // task2.IsBackground = true; // task2.Start(); initServer = new InitServer(MesWorkForm.WebApi_Port); B_DB_Opera.SaveLog_Request(Curr_Station, Log_Type.ZK_Login, "", Log_FromAndTo.ZK, Log_FromAndTo.ZK, $"称重系统启动成功!WebPort:[{MesWorkForm.WebApi_Port}]", out long AID); } /// /// 校验App.config中的逻辑工位必须能匹配Excel启用工位,避免工位号配错后继续运行。 /// private static void ValidateStationConfig() { string station1 = Station1OpName?.Trim(); string station2 = Station2OpName?.Trim(); if (string.IsNullOrWhiteSpace(station1) || string.IsNullOrWhiteSpace(station2)) { MessageBox.Show("App.config未配置Station1OpName或Station2OpName,程序不能启动。"); Process.GetCurrentProcess().Kill(); } if (string.Equals(station1, station2, StringComparison.OrdinalIgnoreCase)) { MessageBox.Show($"App.config中Station1OpName和Station2OpName不能相同,当前均为[{station1}],程序不能启动。"); Process.GetCurrentProcess().Kill(); } bool hasStation1 = StationOpNames.Exists(x => string.Equals(x, station1, StringComparison.OrdinalIgnoreCase)); bool hasStation2 = StationOpNames.Exists(x => string.Equals(x, station2, StringComparison.OrdinalIgnoreCase)); if (!hasStation1 || !hasStation2) { string excelStations = string.Join("、", StationOpNames); MessageBox.Show($"App.config工位配置与SignalTable_CZ.xlsx不一致,程序不能启动。\r\nStation1OpName={station1}\r\nStation2OpName={station2}\r\nExcel启用工位={excelStations}"); Process.GetCurrentProcess().Kill(); } } /// /// 构建信号表:读取Excel模板,按「设备类型对应表」的工位配置展开 /// 每个工位独立克隆一份模板,TagID加工位号前缀(如 OP10_TAG_0000001), /// 并填充对应的 工位号、数据来源、IP、DB /// /// 信号表Excel文件路径 /// (展开后的信号表, 设备类型对应表) private static (DataTable dtTagMes, DataTable dtDevice) BuildSignalTable(string excelFile) { // 读取设备类型对应表(所有启用的工位) var dtDevice = NPOITest.ExeclHelper.ExcelToDataTable(excelFile, "设备类型对应表", true) .Select("是否启用='1'").CopyToDataTable(); // 读取 MES_基本变量原始数据 模板(取全部启用行作为模板) var dtTemplate = NPOITest.ExeclHelper.ExcelToDataTable(excelFile, "MES_基本变量原始数据", true) .Select("是否启用='1'").CopyToDataTable(); // 按工位数量克隆模板 var dtTagMes = dtTemplate.Clone(); foreach (DataRow devRow in dtDevice.Rows) { string stationNo = devRow["工位号"].ToString().Trim(); // OP10, OP20 string dataSource = devRow["数据来源"].ToString().Trim(); // 称重位1, 称重位2 string deviceIP = devRow["设备IP"].ToString().Trim(); // 192.168.0.1 string deviceDB = devRow["DB"].ToString().Trim(); // DB1310, DB1311 // 提取纯DB号 ("DB1310" → "1310",若本身是数字则保持) //string dbNumber = deviceDB.StartsWith("DB", StringComparison.OrdinalIgnoreCase) // ? deviceDB.Substring(2) : deviceDB; string dbNumber = deviceDB; foreach (DataRow tplRow in dtTemplate.Rows) { var newRow = dtTagMes.NewRow(); for (int c = 0; c < dtTemplate.Columns.Count; c++) newRow[c] = tplRow[c]; // 覆盖关键字段 newRow["TagID"] = $"{stationNo}_{tplRow["TagID"].ToString().Trim()}"; newRow["工位号"] = stationNo; newRow["数据来源"] = dataSource; newRow["IP"] = deviceIP; newRow["DBName"] = dbNumber; dtTagMes.Rows.Add(newRow); } } return (dtTagMes, dtDevice); } } }