using System; using System.Reflection; using System.Text.RegularExpressions; using System.Threading.Tasks; using WCS.BLL.Config; using WCS.BLL.DbModels; using WCS.BLL.DbModels.Task; using WCS.BLL.Manager; using WCS.DAL.Db; using WCS.DAL.DbModels; using WCS.Model; using WCS.Model.ApiModel.InOutRecord; using WCS.Model.ApiModel.OutStore; using WCS.Model.WebSocketModel; using static WCS.BLL.HardWare.WarningLight; namespace WCS.BLL.HardWare { /// /// 智能货架 /// public class MXL4Shelf : IShelfBase { public MXL4Shelf(ShelfInfo shelfInfo) { ShelfTypeName = shelfInfo.ShelfTypeName; ShelfId = shelfInfo.Id; ShelfCode = shelfInfo.ShelfCode; RowCounts = shelfInfo.Rowcounts; ColumnCounts = shelfInfo.Columncounts; SetCurrentMode(TaskModeEnum.待机模式); ClientIp = shelfInfo.ClientIp; LightId = shelfInfo.LightId; WarningLight = new WarningLight() { LightId = shelfInfo.LightId }; //初始化Module var task = Task.Run(() => { var modules = DbHelp.db.Queryable().Where(t => t.ShelfId == ShelfId).ToList(); foreach (var module in modules) { MXL4Modules.Add(new MXL4ShelfModule() { ModuleId = module.Id, ModuleCode = module.ModuleCode, BoardId = module.BoardId, IsEnable = module.IsEnable, CurrentMode = TaskModeEnum.待机模式 }); } ModulesStr = string.Join(";", MXL4Modules.Select(t => t.ModuleCode)); ModuleIds = MXL4Modules.Select(t => t.BoardId).ToList(); }); //一个货架存在一个线程去刷新数据 Task.Run(async () => { //等待模组加载完毕再开始发送数据进行刷新 Task.WaitAll(task); while (true) { Logs.Write($"[test]{ShelfCode}"); try { //未完成首次连接时 暂不发送 if (TcpCleint.IsFirstConnected == false) { await Task.Delay(2000); continue; } //查询属于本货架的任务 var currentShelfTasks = DbHelp.db.Queryable() .Where(t => t.ShelfId == this.ShelfId) .Where(t => t.IsSended == false) .OrderBy(t => t.CreateTime) .ToList(); //获取因为任务需要刷新的module var haveTaskModules = currentShelfTasks.Select(t => t.ModuleId).Distinct().ToList(); MXL4Modules.ForEach(t => { if (haveTaskModules.Contains(t.ModuleId)) { t.IsNeedRefresh = true; } }); //查询是否有需要刷新的 var needRefreshModules = MXL4Modules.Where(t => t.IsNeedRefresh) .ToList(); foreach (var module in needRefreshModules) { try { //查询当前是否有任务 var currentTasks = currentShelfTasks.Where(t => t.ModuleId == module.ModuleId) .OrderBy(t => t.CreateTime) .ToList(); //入库、出库、盘点等任务 if (currentTasks != null && currentTasks.Count > 0) { var firstTask = currentTasks.First(); var taskMode = currentTasks.First().TaskMode; #region 处理模组的模式 没有Continue if (module.CurrentMode == TaskModeEnum.待机模式) { //进入对应模式 switch (taskMode) { case (TaskModeEnum.入库模式): module.GoInInstoreMode(TcpCleint); break; case (TaskModeEnum.出库模式): module.GoInOutstoreMode(TcpCleint); break; case (TaskModeEnum.盘点模式): module.GoInStocktakingMode(TcpCleint); break; default: break; } //等待10ms这边将状态成功更新了来 await Task.Delay(10); } else { taskMode = module.CurrentMode; } #endregion //只显示当前模式的任务 currentTasks = currentTasks.Where(t => t.TaskMode == taskMode).ToList(); //这个分支应该很少跑到 有刷新必然有新任务 if (currentTasks == null || currentTasks.Count == 0) { Logs.Write($"【后台发送线程】{module.ModuleCode}当前模式{module.CurrentMode},需要刷新!但是没有对应的新任务!"); var tasks = DbHelp.db.Queryable() .Where(t => t.ModuleId == module.ModuleId) .Where(t => t.IsSended == true) .Where(t => t.TaskMode == taskMode) .OrderBy(t => t.CreateTime) .ToList(); if (tasks != null && tasks.Count > 0) { Logs.Write($"【后台发送线程】{module.ModuleCode}当前模式{module.CurrentMode},需要刷新!但是没有对应的新任务!有已发送的任务未完成故不处理!"); module.IsNeedRefresh = false; continue; } //退出对应模式到待机模式! 后续持续刷新数据! else { Logs.Write($"【后台发送线程】{module.ModuleCode}当前模式{module.CurrentMode},需要刷新!但是没有对应的新任务!没有已发送未完成的任务!退出当前模式!"); // 退出对应模式 switch (taskMode) { case (TaskModeEnum.入库模式): module.GoOutInstoreMode(TcpCleint); break; case (TaskModeEnum.出库模式): module.GoOutOutstoreMode(TcpCleint); break; case (TaskModeEnum.盘点模式): module.GoOutStocktakingMode(TcpCleint); break; default: break; } continue; } } //按照任务顺序给其发送数据 foreach (var currentTask in currentTasks) { module.SendTaskId(currentTask.TaskID, TcpCleint); module.SendMatCode(currentTask.MatCode, TcpCleint); module.SendMatName(currentTask.MatName, TcpCleint); module.SendMatSpec(currentTask.MatSpec, TcpCleint); module.SendMatBatch(currentTask.MatBatch, TcpCleint); module.SendMatQty(currentTask.Qty, TcpCleint); currentTask.IsSended = true; DbHelp.db.Updateable(currentTask).ExecuteCommand(); } //发送完毕后就不刷新了 module.IsNeedRefresh = false; continue; } //不存在入库、出库、盘点等任务 应该变成待机 else { //退出对应模式到待机模式! 后续持续刷新数据! if (module.CurrentMode != TaskModeEnum.待机模式) { // 退出对应模式 switch (module.CurrentMode) { case (TaskModeEnum.入库模式): module.GoOutInstoreMode(TcpCleint); break; case (TaskModeEnum.出库模式): module.GoOutOutstoreMode(TcpCleint); break; case (TaskModeEnum.盘点模式): module.GoOutStocktakingMode(TcpCleint); break; default: break; } continue; } //向上层系统获取数据 //获取成功 有数据 绑定对应数据 //获取成功 无数据 module.StandbyNoInfoDisplay(TcpCleint); module.IsNeedRefresh = false;//未获取到库存数据 回没有库位显示信息给硬件 //获取失败 跳过此次循环后继续获取 } } catch (Exception ex) { Logs.Write($"【后台发送线程】遇到异常{ex.Message},{ex.StackTrace}"); } } } catch (Exception ex) { Logs.Write($"【后台发送线程】遇到异常{ex.Message},{ex.StackTrace}"); } await Task.Delay(1000); } }); } public string ShelfTypeName { get; set; } public int ShelfId { get; set; } public string ShelfCode { get; set; } public int RowCounts { get; set; } public int ColumnCounts { get; set; } public TaskModeEnum CurrentMode { get; set; } public DateTime SetCurrentModeTime { get; set; } public string ModulesStr { get; set; }//当前货架所有模组的Str public string GroupName { get; set; } public List Modules { get; set; } = new List(); public List MXL4Modules { get; set; } = new List(); public TCPClient TcpCleint { get { return TCPClientManager.GetTCPClientByIPHost(ClientIp); } } public int LightId { get; set; } public LightColorEnum LightColor { get; set; } public bool IsWarning { get; set; } = false; public WarningLight WarningLight { get; set; } public void ClearWarning() { if (this.CurrentMode == TaskModeEnum.入库模式) { WarningLight.BlueLight(TcpCleint); } else if (this.CurrentMode == TaskModeEnum.出库模式) { WarningLight.GreenLight(TcpCleint); } else if (this.CurrentMode == TaskModeEnum.盘点模式) { WarningLight.GreenLight(TcpCleint); } else { WarningLight.CloseLight(TcpCleint); } } /// /// 自检异常、未响应对应模式的异常 /// public List ExceptionMessages { get; set; } = new List(); /// /// 过程中异常 入库过程中异常/出库过程中异常 /// public List ProcessingExceptions { get; set; } = new List(); public string? CurrentCom { get; set; } = string.Empty; public MatInfoResponse InStoreData { get; set; } public List CurrentOutStoreMatSNs { get; set; } = new List(); public OutOrder CurrentOutOrder { get; set; } public string OrderNumber { get; set; } public StockTakingOrder CurrentStockTakingOrder { get; set; } public List ModuleIds { get; set; } public string ClientIp { get; set; } //websocket通知的前端的IP地址 public string WebSocketIpAddress { get; set; } = "127.0.0.2"; public string OutOperateUser { get; set; } = string.Empty; #region 协议处理 public void Reset() { MXL4Modules.ForEach(t => t.Reset(TcpCleint)); } #region 弃用 void IShelfBase.Warning() { } public void ShelfCheck() { } public void GoInInstore(string? IPAddress) { } public void GoOutInstore() { } public void GoInOutstore(List MatDetails, OutOrder outOrder, string OperateUser) { } public void GoOutOutstore() { } public void GoInStocktaking(List MatDetails, StockTakingOrder stockTakingOrder) { } /// /// 确认盘点 Pda进行触发 /// public bool ConfirmStocktakingSingle(int BoardId, int LightNumber) { return false; } public void GoOutStocktaking() { } #endregion public void SetCurrentMode(TaskModeEnum mode) { this.CurrentMode = mode; this.SetCurrentModeTime = DateTime.Now; Task.Run(() => { var shelf = DbHelp.db.Queryable().Where(t => t.Id == ShelfId).First(); if (shelf != null) { shelf.CurrentMode = mode; shelf.SetCurrentModeTime = SetCurrentModeTime; DbHelp.db.Updateable(shelf).ExecuteCommand(); } }); } #endregion #region 报警灯协议返回处理 public void WarningLightProcess(byte[] data, int boardId) { if (data[TcpCleint.PreFixLength + 2] == 0x20 && data[TcpCleint.PreFixLength + 3] == 0x01) { //常亮或关闭 0x00常亮 0x01关闭 if (data[TcpCleint.PreFixLength + 5] == 0x00) { LightColor = LightColorEnum.关闭; Logs.Write($"货架[{ShelfCode}],灯状态更新为:{LightColor}"); } else if (data[TcpCleint.PreFixLength + 5] == 0x01) { switch (data[7]) { case 0x01: LightColor = LightColorEnum.红色; break; case 0x02: LightColor = LightColorEnum.绿色; break; case 0x03: LightColor = LightColorEnum.蓝色; break; default: break; } Logs.Write($"货架[{ShelfCode}],灯状态更新为:{LightColor}"); } } } #endregion #region 液晶标签协议返回处理 public void ProtocolProcess(byte[] data, int boardId) { //协议处理 判断功能位 switch (data[TcpCleint.PreFixLength + 2]) { case 0xA4://标签回到待机模式 请求获取显示数据的信号 if (data[TcpCleint.PreFixLength + 3] == 0x02) GoBackStandbyModeReturnProcess(data, boardId); break; case 0xA1: //标签返回入库成功信号 if (data[TcpCleint.PreFixLength + 3] == 0x05) InStoreSuccessProcess(data, boardId); //进入入库模式成功 else if (data[TcpCleint.PreFixLength + 3] == 0x01) GoInInStoreReturnProcess(data, boardId); //退出入库模式 else if (data[TcpCleint.PreFixLength + 3] == 0x03) GoBackStandbyModeReturnProcess(data, boardId); break; case 0xA2: //标签返回出库成功信号 if (data[TcpCleint.PreFixLength + 3] == 0x04) OutStoreSuccessProcess(data, boardId); //进入出库模式成功 else if (data[TcpCleint.PreFixLength + 3] == 0x01) GoInOutStoreReturnProcess(data, boardId); //退出出库模式 else if (data[TcpCleint.PreFixLength + 3] == 0x03) GoBackStandbyModeReturnProcess(data, boardId); break; case 0xA3: //标签返回盘点成功信号 if (data[TcpCleint.PreFixLength + 3] == 0x03) StocktakingSuccessProcess(data, boardId); //进入盘点模式 else if (data[TcpCleint.PreFixLength + 3] == 0x01) GoInStocktakingReturnProcess(data, boardId); //退出盘点模式 else if (data[TcpCleint.PreFixLength + 3] == 0x02) GoBackStandbyModeReturnProcess(data, boardId); break; default: ; break; } } /// /// 标签回到待机模式 /// /// public void GoBackStandbyModeReturnProcess(byte[] data, int boardId) { //获取对应的模组 var module = MXL4Modules.Where(t => t.BoardId == boardId) .FirstOrDefault(); if (module != null) { module.SetCurrentMode(TaskModeEnum.待机模式); module.IsNeedRefresh = true; } else { Logs.Write($"【回到待机模式】货架【{ShelfCode}】通过板子ID【{boardId}】未找到对应模组!"); } //TO DO 所有退出后货架才待机 SetCurrentMode(TaskModeEnum.待机模式); } /// /// 标签返回进入入库模式信号 /// /// public void GoInInStoreReturnProcess(byte[] data, int boardId) { //获取对应的模组 var module = MXL4Modules.Where(t => t.BoardId == boardId) .FirstOrDefault(); if (module != null) { module.SetCurrentMode(TaskModeEnum.入库模式); } else { Logs.Write($"【进入入库模式成功】货架【{ShelfCode}】通过板子ID【{boardId}】未找到对应模组!"); } } /// /// 标签返回进入出库模式信号 /// /// public void GoInOutStoreReturnProcess(byte[] data, int boardId) { //获取对应的模组 var module = MXL4Modules.Where(t => t.BoardId == boardId) .FirstOrDefault(); if (module != null) { module.SetCurrentMode(TaskModeEnum.出库模式); } else { Logs.Write($"【进入出库模式成功】货架【{ShelfCode}】通过板子ID【{boardId}】未找到对应模组!"); } } /// /// 标签返回进入盘点模式信号 /// /// public void GoInStocktakingReturnProcess(byte[] data, int boardId) { //获取对应的模组 var module = MXL4Modules.Where(t => t.BoardId == boardId) .FirstOrDefault(); if (module != null) { module.SetCurrentMode(TaskModeEnum.盘点模式); } else { Logs.Write($"【进入盘点模式成功】货架【{ShelfCode}】通过板子ID【{boardId}】未找到对应模组!"); } } /// /// 标签返回入库成功信号 /// /// public void InStoreSuccessProcess(byte[] data, int boardId) { var taskId = Convert.ToInt32(data[TcpCleint.PreFixLength + 4]); var finishQty = (data[TcpCleint.PreFixLength + 5] << 8) + data[TcpCleint.PreFixLength + 6]; //获取对应的模组 var module = MXL4Modules.Where(t => t.BoardId == boardId) .FirstOrDefault(); if (module != null) { //获取对应的任务 var task = DbHelp.db.Queryable() .Where(t => t.ModuleCode == module.ModuleCode) .Where(t => t.TaskID == taskId) .First(); if (task != null) { var finishedTask = new FinishedTask() { ShelfId = task.ShelfId, ShelfCode = task.ShelfCode, ModuleId = task.ModuleId, ModuleCode = task.ModuleCode, StoreId = task.StoreId, StoreCode = task.StoreCode, TaskID = task.TaskID, Guid = task.Guid, ItemNo = task.ItemNo, TaskMode = task.TaskMode, OrderNumber = task.OrderNumber, ButtonColor = task.ButtonColor, MatCode = task.MatCode, MatName = task.MatName, MatSpec = task.MatSpec, MatBatch = task.MatBatch, MatSN = task.MatSN, CreateTime = task.CreateTime, FinishQty = finishQty, FinishTime = DateTime.Now, }; DbHelp.db.Insertable(finishedTask).ExecuteCommand(); DbHelp.db.Deleteable(task).ExecuteCommand(); } else { Logs.Write($"【入库成功】货架【{ShelfCode}】通过模组{module.ModuleCode}({boardId}),通过任务id{taskId}未找到对应任务!"); } } else { Logs.Write($"【入库成功】货架【{ShelfCode}】通过板子ID【{boardId}】未找到对应模组!"); } } /// /// 标签返回出库成功信号 /// /// public void OutStoreSuccessProcess(byte[] data, int boardId) { var taskId = Convert.ToInt32(data[TcpCleint.PreFixLength + 4]); var finishQty = (data[TcpCleint.PreFixLength + 5] << 8) + data[TcpCleint.PreFixLength + 6]; //获取对应的模组 var module = MXL4Modules.Where(t => t.BoardId == boardId) .FirstOrDefault(); if (module != null) { //获取对应的任务 var task = DbHelp.db.Queryable() .Where(t => t.ModuleCode == module.ModuleCode) .Where(t => t.TaskID == taskId) .First(); if (task != null) { var finishedTask = new FinishedTask() { ShelfId = task.ShelfId, ShelfCode = task.ShelfCode, ModuleId = task.ModuleId, ModuleCode = task.ModuleCode, StoreId = task.StoreId, StoreCode = task.StoreCode, TaskID = task.TaskID, Guid = task.Guid, ItemNo = task.ItemNo, TaskMode = task.TaskMode, OrderNumber = task.OrderNumber, ButtonColor = task.ButtonColor, MatCode = task.MatCode, MatName = task.MatName, MatSpec = task.MatSpec, MatBatch = task.MatBatch, MatSN = task.MatSN, CreateTime = task.CreateTime, FinishQty = finishQty, FinishTime = DateTime.Now, }; DbHelp.db.Insertable(finishedTask).ExecuteCommand(); DbHelp.db.Deleteable(task).ExecuteCommand(); } else { Logs.Write($"【出库成功】货架【{ShelfCode}】通过模组{module.ModuleCode}({boardId}),通过任务id{taskId}未找到对应任务!"); } } else { Logs.Write($"【出库成功】货架【{ShelfCode}】通过板子ID【{boardId}】未找到对应模组!"); } } /// /// 标签返回盘点成功信号 /// /// public void StocktakingSuccessProcess(byte[] data, int boardId) { var taskId = Convert.ToInt32(data[TcpCleint.PreFixLength + 4]); var finishQty = (data[TcpCleint.PreFixLength + 5] << 8) + data[TcpCleint.PreFixLength + 6]; //获取对应的模组 var module = MXL4Modules.Where(t => t.BoardId == boardId) .FirstOrDefault(); if (module != null) { //获取对应的任务 var task = DbHelp.db.Queryable() .Where(t => t.ModuleCode == module.ModuleCode) .Where(t => t.TaskID == taskId) .First(); if (task != null) { var finishedTask = new FinishedTask() { ShelfId = task.ShelfId, ShelfCode = task.ShelfCode, ModuleId = task.ModuleId, ModuleCode = task.ModuleCode, StoreId = task.StoreId, StoreCode = task.StoreCode, TaskID = task.TaskID, Guid = task.Guid, ItemNo = task.ItemNo, TaskMode = task.TaskMode, OrderNumber = task.OrderNumber, ButtonColor = task.ButtonColor, MatCode = task.MatCode, MatName = task.MatName, MatSpec = task.MatSpec, MatBatch = task.MatBatch, MatSN = task.MatSN, CreateTime = task.CreateTime, FinishQty = finishQty, FinishTime = DateTime.Now, }; DbHelp.db.Insertable(finishedTask).ExecuteCommand(); DbHelp.db.Deleteable(task).ExecuteCommand(); } else { Logs.Write($"【盘点成功】货架【{ShelfCode}】通过模组{module.ModuleCode}({boardId}),通过任务id{taskId}未找到对应任务!"); } } else { Logs.Write($"【盘点成功】货架【{ShelfCode}】通过板子ID【{boardId}】未找到对应模组!"); } } #endregion } }