using iWareCc.Cache.Entity; using iWareCc.Conveyor.Entity; using iWareCc.DecomposeTask.Chain; using iWareCc.DecomposeTask.Entity; using iWareCc.DoConveyorTaskAuto.Chain; using iWareCc.DoStackerTaskAuto.Chain; using iWareCc.FinishConveyorTask.Chain; using iWareCc.FinishStackerTask.Chain; using iWareCc.HandleTask.Chain; using iWareCc.Properties; using iWareCc.Srm.Entity; using iWareCc.Srm.Strategy; using iWareCc.WCF.ControlCenter; using iWareCommon.Common.Entity; using iWareCommon.Common.EnumType; using iWareCommon.Utils; using iWareDataCore.DEV.EnumType; using iWareDataCore.TASK.EnumType; using iWareLog.LOG.Service; using iWareLog.ORM; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Linq; using System.ServiceModel; using System.ServiceProcess; using System.Text; using System.Threading; using System.Threading.Tasks; using Castle.DynamicProxy; using iWareDataCore.ORM; using iWareLog.LOG.Entity; using iWareLog.LOG.Dao; using iWareCc.Conveyor.EnumType; using iWareCc.Conveyor.Service; using iWareDataCore.BASE.EnumType; using iWareCc.CreateMainTask.chain; using iWareCc.CreateOutMainTask.chain; using iWareCc.Srm.EnumType; namespace iWareCc { public partial class Service1 : ServiceBase { private object DecomposeLock = new object(); /// /// ControlCenterWcf服务 /// private ServiceHost ControlCenterWcfHost = null; /// /// 每个堆垛机获取状态的线程 /// private List GetStackerStateThreads = new List(); /// /// 每个输送机端口获取状态的线程 /// // private List GetGateStateThreads = new List(); /// /// 每个输送机端口接收到的报文信息的线程(Client) /// // private List ClientGetGateSocketInforThreads = new List(); /// /// 每个输送机端口发送报文信息的线程(Client) /// // private List ClientSendGateSocketInforThreads = new List(); /// /// 处理服务端每个输送机端口接收到的报文信息的线程(server) /// private List ServerGateHandleCraneReceivedMsgThreads = new List(); /// /// 每个输送机端口发送报文信息写入本地日志的线程 /// //private List ServerGateWriteDatagamLogThreads = new List(); /// /// 开启Socket的线程 /// private List StartSocketThreads = new List(); /// /// 生成入库主任务 /// private Thread CreatMainTaskInThread = null; /// /// 生成出库主任务 /// private Thread CreatMainTaskOutThread = null; /// /// 分解任务的线程 /// private Thread DecomposeTaskThread = null; /// /// 处理任务的线程 /// private Thread HandleTaskThread = null; /// /// 自动执行输送机任务的线程 /// private List DoConveyorTaskAutoThreads = new List(); /// /// 自动执行堆垛机任务的线程 /// private List DoStackerTaskAutoThreads = new List(); /// /// 完成输送机任务的线程 /// private List FinishConveyorTaskThreads = new List(); /// /// 完成堆垛机任务的线程 /// private List FinishStackerTaskThreads = new List(); /// /// 发送堆垛机状态的线程 /// // private Thread SendStackerStatusThread = null; /// /// 发送堆垛机告警状态的线程 /// private List SendStackerAlertThreads = new List(); /// /// 发送输送机告警信息的线程 /// private Thread SendConveyorAlertThread = null; /// /// 增加每个堆垛机离线次数的线程 /// private List AddStackerOffLineTimesThreads = new List(); /// /// 设定每个堆垛机是否在线的线程 /// private List SetStackerIsOnlineThreads = new List(); /// /// 同步完成次数的线程 /// private Thread SyncFinishTimesThread = null; /// /// 同步处理次数的线程 /// private Thread SyncHandleTimesThread = null; /// /// 同步处理次数的线程 /// private Thread SyncDecompositionTimesThread = null; /// /// 定时获取心跳信息的线程 /// //private Thread GetHeartBeatStateThread = null; /// /// 写入堆垛机报表的线程 /// private Thread WriteStackerReportThread = null; /// /// 重推的线程 /// //private Thread ReSendThread = null; public Service1() { InitializeComponent(); } protected override void OnStart(string[] args) { LogTextHelper.WriteLine(Resources.LogDir, "外高桥iWareCc启动了!"); ControlCenterWcfHost = new ServiceHost(typeof(ControlCenterWcfService)); ControlCenterWcfHost.Open(); ////开启每个输送机端口获取状态的线程 //CacheEntity.Conveyors.ForEach(x => //{ // x.Gates.ForEach(y => // { // var thread = new Thread(new ParameterizedThreadStart(GetGateState)); // thread.Name = string.Format("获取输送机端口{0}的状态", y.Place.PlaceTypeName); // GetGateStateThreads.Add(thread); // StartThread(thread, y); // }); //}); //#region Client //开启处理输送线各端口接收到的报文信息的线程 //CacheEntity.Conveyors.ForEach(x => //{ // x.Gates.ForEach(y => // { // var thread = new Thread(new ParameterizedThreadStart(GetGateSocketInfor)); // thread.Name = string.Format("获取输送机端口{0}的状态", y.Place.PlaceTypeName); // ClientGetGateSocketInforThreads.Add(thread); // StartThread(thread, y); // }); //}); ////开启处理输送线各端口发送的报文信息的线程 //CacheEntity.Conveyors.ForEach(x => //{ // x.Gates.ForEach(y => // { // var thread = new Thread(new ParameterizedThreadStart(SendGateSocketInfor)); // thread.Name = string.Format("获取输送机端口{0}的状态", y.Place.PlaceTypeName); // ClientSendGateSocketInforThreads.Add(thread); // StartThread(thread, y); // }); //}); //#endregion #region Server //开启处理输送线各端口接收到的报文信息的线程 CacheEntity.Conveyors.ForEach(x => { x.Gates.ForEach(y => { var thread = new Thread(new ParameterizedThreadStart(ServerHandleGateMsg)); thread.Name = string.Format("处理输送机端口{0}接收或发送的报文信息", y.Place.PlaceTypeName); ServerGateHandleCraneReceivedMsgThreads.Add(thread); StartThread(thread, y); }); }); //开启处理输送线各端口接收到的报文信息写入本地日志 //CacheEntity.Conveyors.ForEach(x => //{ // x.Gates.ForEach(y => // { // var thread = new Thread(new ParameterizedThreadStart(ServerGateWriteDatagamLog)); // thread.Name = string.Format("获输送机端口{0}接收或发送的报文信息", y.Place.PlaceTypeName); // ServerGateWriteDatagamLogThreads.Add(thread); // StartThread(thread, y); // }); //}); #endregion //开启打开socket的线程 CacheEntity.Conveyors.ForEach(x => { x.Gates.ForEach(y => { var thread = new Thread(new ParameterizedThreadStart(StartSocket)); thread.Name = string.Format("开启输送机端口{0}的通讯", y.Place.PlaceTypeName); StartSocketThreads.Add(thread); StartThread(thread, y); }); }); //开启每个堆垛机获取状态的线程 CacheEntity.Stackers.ForEach(x => { var thread = new Thread(new ParameterizedThreadStart(GetStackerState)); thread.Name = string.Format("获取输堆垛机{0}的状态", x.Equipment.EquipName); GetStackerStateThreads.Add(thread); StartThread(thread, x); }); //生成入库主任务 CreatMainTaskInThread = new Thread(new ThreadStart(CreateMainInTask)); CreatMainTaskInThread.Name = "生成入库主任务"; StartThread(CreatMainTaskInThread); //生成出库主任务 CreatMainTaskOutThread = new Thread(new ThreadStart(CreateMainOutTask)); CreatMainTaskOutThread.Name = "生成出库主任务"; StartThread(CreatMainTaskOutThread); //开启分解任务的线程 DecomposeTaskThread = new Thread(new ThreadStart(DecomposeTask)); DecomposeTaskThread.Name = "分解任务"; StartThread(DecomposeTaskThread); //开启处理任务的线程 HandleTaskThread = new Thread(new ThreadStart(HandleTask)); HandleTaskThread.Name = "处理任务"; StartThread(HandleTaskThread); //开启自动执行输送机任务的线程 CacheEntity.Conveyors.ForEach(x => { var thread = new Thread(new ParameterizedThreadStart(DoConveyorTaskAuto)); thread.Name = string.Format("自动执行输送机{0}的任务", x.Equipment.EquipName); DoConveyorTaskAutoThreads.Add(thread); StartThread(thread, x); }); //开启自动执行堆垛机任务的线程 CacheEntity.Stackers.ForEach(x => { var thread = new Thread(new ParameterizedThreadStart(DoStackerTaskAuto)); thread.Name = string.Format("自动执行堆垛机{0}的任务", x.Equipment.EquipName); DoStackerTaskAutoThreads.Add(thread); StartThread(thread, x); }); //开启完成输送机任务的线程 CacheEntity.Conveyors.ForEach(x => { var thread = new Thread(new ParameterizedThreadStart(FinishConveyorTask)); thread.Name = string.Format("完成输送机{0}的任务", x.Equipment.EquipName); FinishConveyorTaskThreads.Add(thread); StartThread(thread, x); }); //开启完成堆垛机任务的线程 CacheEntity.Stackers.ForEach(x => { var thread = new Thread(new ParameterizedThreadStart(FinishStackerTask)); thread.Name = string.Format("完成堆垛机{0}的任务", x.Equipment.EquipName); FinishStackerTaskThreads.Add(thread); StartThread(thread, x); }); //开启推送Stacker状态的线程 //SendStackerStatusThread = new Thread(new ThreadStart(SendStackerStatus)); //SendStackerStatusThread.Name = "发送堆垛机状态"; //StartThread(SendStackerStatusThread); //开启发送Stacker告警的线程 CacheEntity.Stackers.ForEach(x => { var thread = new Thread(new ParameterizedThreadStart(SendStackerAlert)); thread.Name = string.Format("发送堆垛机{0}告警", x.Equipment.EquipName); SendStackerAlertThreads.Add(thread); StartThread(thread, x); }); ////开启发送输送机告警信息的线程 SendConveyorAlertThread = new Thread(new ThreadStart(SendConveyorAlert)); SendConveyorAlertThread.Name = "发送输送机告警信息"; StartThread(SendConveyorAlertThread); //开启增加每个堆垛机离线次数的线程 CacheEntity.Stackers.ForEach(x => { var thread = new Thread(new ParameterizedThreadStart(AddStackerOffLineTimes)); thread.Name = string.Format("添加堆垛机{0}离线次数", x.Equipment.EquipName); AddStackerOffLineTimesThreads.Add(thread); StartThread(thread, x); }); //开启设定每个堆垛机是否在线的线程 CacheEntity.Stackers.ForEach(x => { var thread = new Thread(new ParameterizedThreadStart(SetStackerIsOnline)); thread.Name = string.Format("设定堆垛机{0}是否在线", x.Equipment.EquipName); SetStackerIsOnlineThreads.Add(thread); StartThread(thread, x); }); //开启同步完成次数的线程 SyncFinishTimesThread = new Thread(new ThreadStart(SyncFinishTimes)); SyncFinishTimesThread.Name = "同步完成次数"; StartThread(SyncFinishTimesThread); //开启同步处理次数的线程 SyncHandleTimesThread = new Thread(new ThreadStart(SyncHandleTimes)); SyncHandleTimesThread.Name = "同步处理次数"; StartThread(SyncHandleTimesThread); //开启同步处理次数的线程 SyncDecompositionTimesThread = new Thread(new ThreadStart(SyncDecompositionTimes)); SyncDecompositionTimesThread.Name = "同步处理次数"; StartThread(SyncDecompositionTimesThread); ////开启定时获取心跳信息的线程 //GetHeartBeatStateThread = new Thread(new ThreadStart(GetHeartBeatState)); //GetHeartBeatStateThread.Name = "获取心跳信息"; //StartThread(GetHeartBeatStateThread); //开启推送同步立库里的物料信息的线程 //SyncMaterialInfoThread = new Thread(new ThreadStart(SyncMaterialInfo)); //SyncMaterialInfoThread.Name = "同步立库里的物料信息"; // StartThread(SyncMaterialInfoThread); //开启写入堆垛机报表的线程 WriteStackerReportThread = new Thread(new ThreadStart(WriteStackerReport)); WriteStackerReportThread.Name = "写入堆垛机报表信息"; StartThread(WriteStackerReportThread); // 开启重推的线程 //ReSendThread = new Thread(new ThreadStart(ReSend)); //ReSendThread.Name = "向WIP重新推送报文"; //StartThread(ReSendThread); } protected override void OnStop() { //关闭ControleCenter服务 CloseWcf(ControlCenterWcfHost); //关闭每个堆垛机获取状态的线程 GetStackerStateThreads.ForEach(x => CloseThread(x)); //关闭每个输送机端口获取状态的线程 // GetGateStateThreads.ForEach(x => CloseThread(x)); //关闭每个输送机端口接收到的报文信息的线程 // ClientGetGateSocketInforThreads.ForEach(x => CloseThread(x)); //关闭每个输送机端口处理接收或发送报文信息的线程 //ClientSendGateSocketInforThreads.ForEach(x => CloseThread(x)); //关闭处理服务端每个输送机端口接收到的报文信息的线程 ServerGateHandleCraneReceivedMsgThreads.ForEach(x => CloseThread(x)); //关闭每个输送机端口接收或发送报文信息写入本地日志的线程 //ServerGateWriteDatagamLogThreads.ForEach(x => CloseThread(x)); //关闭每个输送机端口Socket通讯的线程 StartSocketThreads.ForEach(x => CloseThread(x)); //结束生成入库主任务的线程 CloseThread(CreatMainTaskInThread); //结束生成出库主任务的线程 CloseThread(CreatMainTaskOutThread); //关闭分解任务的线程 CloseThread(DecomposeTaskThread); //关闭处理任务的线程 CloseThread(HandleTaskThread); //关闭自动执行输送机任务的线程 DoConveyorTaskAutoThreads.ForEach(x => CloseThread(x)); //关闭自动执行堆垛机任务的线程 DoStackerTaskAutoThreads.ForEach(x => CloseThread(x)); //关闭自动执行输送机任务的线程 FinishConveyorTaskThreads.ForEach(x => CloseThread(x)); //关闭完成堆垛机任务的线程 FinishStackerTaskThreads.ForEach(x => CloseThread(x)); //关闭发送Stacker状态的线程 // CloseThread(SendStackerStatusThread); //关闭发送输送机告警信息的线程 //CloseThread(SendConveyorAlertThread); //关闭增加每个堆垛机离线次数的线程 AddStackerOffLineTimesThreads.ForEach(x => CloseThread(x)); //关闭设定每个堆垛机是否在线的线程 SetStackerIsOnlineThreads.ForEach(x => CloseThread(x)); //关闭发送Stacker告警的线程 SendStackerAlertThreads.ForEach(x => CloseThread(x)); //关闭同步完成次数的线程 CloseThread(SyncFinishTimesThread); //关闭同步处理次数的线程 CloseThread(SyncHandleTimesThread); //关闭同步处理次数的线程 CloseThread(SyncDecompositionTimesThread); //关闭推送同步立库里的物料信息的线程 // CloseThread(SyncMaterialInfoThread); ////关闭定时获取心跳信息的线程 //CloseThread(GetHeartBeatStateThread); //关闭写入堆垛机报表的线程 CloseThread(WriteStackerReportThread); //关闭重推的线程 //CloseThread(ReSendThread); LogTextHelper.WriteLine(Resources.LogDir, "外高桥iWareCc关闭了!"); } /// /// 获取每个堆垛机状态 /// /// 需要获取状态的堆垛机 private void GetStackerState(object stacker) { var s = (StackerEntity)stacker; //LogTextHelper.WriteLine(Resources.LogDir, "获取堆垛机{0}状态线程已开启", s.Equipment.EquipName); var items = new string[] { s.OpcReadItems.SrmNo,// 1Srm编号 s.OpcReadItems.Mode,// 2任务号 s.OpcReadItems.Alarm,// 3告警 s.OpcReadItems.LiftFull, // 4载货工位是否有货 s.OpcReadItems.PosX,// 5当前列 s.OpcReadItems.PosY,// 6当前层 s.OpcReadItems.PosZ,//7货叉位置 s.OpcReadItems.PosXmm,// 8当前列坐标 s.OpcReadItems.PosYmm,// 9当前层坐标 s.OpcReadItems.PosZmm,// 10当前货叉标 s.OpcReadItems.PickFinish,// 11完成取货信号 s.OpcReadItems.DeliveryFinish,//// 12完成放货信号 s.OpcReadItems.TaskFinish,// 13任务完成 s.OpcReadItems.TaskNo,// 14当前任务号 s.OpcReadItems.State,// 15当前任务执行状态 s.OpcReadItems.ActualLane,// 16当前巷道号 s.OpcReadItems.AlarmNumber,// 17告警代码 s.OpcReadItems.HandShake,// 18心跳 s.OpcWriteItems.SrmNo,// 1Srm编号 s.OpcWriteItems.TaskNo,// 2任务号 s.OpcWriteItems.SourcePosX,// 3源列 s.OpcWriteItems.SourcePosY,// 4源层 s.OpcWriteItems.SourcePosZ,//5源排 s.OpcWriteItems.DestinationPosX,// 6宿列 s.OpcWriteItems.DestinationPosY,// 7宿层 s.OpcWriteItems.DestinationPosZ,// 8宿排 s.OpcWriteItems.Command,// 9发送命令 s.OpcWriteItems.EmergencyStop,// 10紧急停止 s.OpcWriteItems.AlarmAck,// 11解除告警 s.OpcWriteItems.Stb,// 12WCS通讯 s.OpcWriteItems.Ack,// 13SRM 应答位 s.OpcWriteItems.HandShake,// 14心跳 s.OpcWriteItems.Lots }; while (true) { try { var opcs = CacheEntity.OpcWcfServiceClient.ReadValues(items); if (opcs == null || opcs.Length <= 0) { LogTextHelper.WriteLine(Resources.LogDir, "获取堆状态读取失败"); Thread.Sleep(1000); continue; } var i = 0; s.SrmNo = int.Parse(opcs[i++].ToString()); s.Mode = int.Parse(opcs[i++].ToString()); s.Alarm = int.Parse(opcs[i++].ToString()); s.LiftFull = int.Parse(opcs[i++].ToString()); s.PosX = int.Parse(opcs[i++].ToString()); s.PosY = int.Parse(opcs[i++].ToString()); s.PosZ = int.Parse(opcs[i++].ToString()); s.PosXmm = int.Parse(opcs[i++].ToString()); s.PosYmm = int.Parse(opcs[i++].ToString()); s.PosZmm = int.Parse(opcs[i++].ToString()); s.PickFinish = int.Parse(opcs[i++].ToString()); s.DeliveryFinish = int.Parse(opcs[i++].ToString()); s.TaskFinish = int.Parse(opcs[i++].ToString()); s.TaskNo = int.Parse(opcs[i++].ToString()); s.State = int.Parse(opcs[i++].ToString()); s.ActualLane = int.Parse(opcs[i++].ToString()); s.AlarmNumber = int.Parse(opcs[i++].ToString()); s.HandShake = int.Parse(opcs[i++].ToString()); s.WSrmNo = int.Parse(opcs[i++].ToString()); s.WTaskNo = int.Parse(opcs[i++].ToString()); s.WSourcePosX = int.Parse(opcs[i++].ToString()); s.WSourcePosY = int.Parse(opcs[i++].ToString()); s.WSourcePosZ = int.Parse(opcs[i++].ToString()); s.WDestinationPosX = int.Parse(opcs[i++].ToString()); s.WDestinationPosY = int.Parse(opcs[i++].ToString()); s.WDestinationPosZ = int.Parse(opcs[i++].ToString()); s.WCommand = int.Parse(opcs[i++].ToString()); s.WEmergencyStop = int.Parse(opcs[i++].ToString()); s.WAlarmAck = int.Parse(opcs[i++].ToString()); s.WStb = int.Parse(opcs[i++].ToString()); s.WAck = int.Parse(opcs[i++].ToString()); s.WHandShake = int.Parse(opcs[i++].ToString()); s.WLots = int.Parse(opcs[i++].ToString()); } catch (Exception ex) { LogTextHelper.WriteLine(Resources.LogDir, "堆垛机{0}读取状态失败:{1}", s.Equipment.EquipName, ex.Message); } Thread.Sleep(1000); } } /// /// 获取输送机端口状态的函数 /// /// 输送机 private void GetGateState(object gate) { var g = (GateEntity)gate; //LogTextHelper.WriteLine(Resources.LogDir, "获取输送机端口{0}状态线程已开启", g.Place.Name); var items = new List(); //////Read //1 if (!string.IsNullOrEmpty(g.OpcReadItems.RTaskId)) { items.Add(g.OpcReadItems.RTaskId); } //2 if (!string.IsNullOrEmpty(g.OpcReadItems.ROccupied)) { items.Add(g.OpcReadItems.ROccupied); } //3 if (!string.IsNullOrEmpty(g.OpcReadItems.RIsEmpty)) { items.Add(g.OpcReadItems.RIsEmpty); } //4 if (!string.IsNullOrEmpty(g.OpcReadItems.RCheckResult)) { items.Add(g.OpcReadItems.RCheckResult); } //////Write //1 if (!string.IsNullOrEmpty(g.OpcWriteItems.WTaskId)) { items.Add(g.OpcWriteItems.WTaskId); } //2 if (!string.IsNullOrEmpty(g.OpcWriteItems.WStartRotation)) { items.Add(g.OpcWriteItems.WStartRotation); } //3 if (!string.IsNullOrEmpty(g.OpcWriteItems.WPickFinishSymbol)) { items.Add(g.OpcWriteItems.WPickFinishSymbol); } //4 if (!string.IsNullOrEmpty(g.OpcWriteItems.WPutFinishSymbol)) { items.Add(g.OpcWriteItems.WPutFinishSymbol); } //5 if (!string.IsNullOrEmpty(g.OpcWriteItems.WIsInStorage)) { items.Add(g.OpcWriteItems.WIsInStorage); } while (true) { try { var opcs = CacheEntity.OpcWcfServiceClient.ReadValues(items.ToArray()); if (opcs == null || opcs.Length <= 0) { Thread.Sleep(1000); continue; } var i = 0; //1 if (!string.IsNullOrEmpty(g.OpcReadItems.RTaskId)) { var value = opcs[i++]; g.TaskId = value == null ? "" : value.ToString(); } //2 if (!string.IsNullOrEmpty(g.OpcReadItems.ROccupied)) { var value = opcs[i++]; g.ROccupied = value == null ? false : bool.Parse(value.ToString()); } //3 if (!string.IsNullOrEmpty(g.OpcReadItems.RIsEmpty)) { var value = opcs[i++]; g.RIsEmpty = value == null ? false : bool.Parse(value.ToString()); } //4 if (!string.IsNullOrEmpty(g.OpcReadItems.RCheckResult)) { var value = opcs[i++]; g.RCheckMaterialCode = value == null ? "" : value.ToString(); } //1 if (!string.IsNullOrEmpty(g.OpcWriteItems.WTaskId)) { var value = opcs[i++]; g.TaskId = value == null ? "" : value.ToString(); } //2 if (!string.IsNullOrEmpty(g.OpcWriteItems.WPutFinishSymbol)) { var value = opcs[i++]; g.WPutFinishSymbol = value == null ? false : bool.Parse(value.ToString()); } //3 if (!string.IsNullOrEmpty(g.OpcWriteItems.WPickFinishSymbol)) { var value = opcs[i++]; g.WPickFinishSymbol = value == null ? false : bool.Parse(value.ToString()); } //4 if (!string.IsNullOrEmpty(g.OpcWriteItems.WStartRotation)) { var value = opcs[i++]; g.WStartRotation = value == null ? false : bool.Parse(value.ToString()); } //5 if (!string.IsNullOrEmpty(g.OpcWriteItems.WIsInStorage)) { var value = opcs[i++]; g.WIsInStorage = value == null ? false : bool.Parse(value.ToString()); } } catch (Exception ex) { LogTextHelper.WriteLine(Resources.LogDir, "端口{0}读取状态失败:{1}", g.Place.PlaceTypeName, ex.Message); } Thread.Sleep(1000); } } #region Client /// /// 获取输送机端口报文的函数 /// /// 输送机 //private void GetGateSocketInfor(object gate) //{ // var g = (GateEntity)gate; // while (true) // { // try // { // var gateService = new GateService(g); // gateService.HandleMsg(gateService.ReadFromDatagramReceivePool()); // } // catch (Exception ex) // { // LogTextHelper.WriteLine(Resources.LogDir, "端口{0}读取状态失败:{1}", g.Place.PlaceTypeName, ex.Message); // } // Thread.Sleep(1000); // } //} /// /// 发送输送机端口报文的函数 /// /// 输送机 private void SendGateSocketInfor(object gate) { var g = (GateEntity)gate; while (true) { try { if (!g.SendFlag) { continue; } string msg = new GateService(g).ReadFromDatagramSendPool(); if (!string.IsNullOrEmpty(msg)) { if (!g.Socket.Send(ASCIIEncoding.UTF8.GetBytes(msg))) { //过滤心跳和读取状态 if (!msg.StartsWith(EGateCommandWordUtil.EGateCommandWord2String(EGateCommandWord.心跳))) { LogTextHelper.WriteLine(Resources.LogDir, "在类{0}中执行方法{1}时出现异常:{2}", this.ToString(), "SendGateSocketInfor", "发送报文异常"); } } else { if (!msg.StartsWith(EGateCommandWordUtil.EGateCommandWord2String(EGateCommandWord.心跳)) && !msg.StartsWith(EGateCommandWordUtil.EGateCommandWord2String(EGateCommandWord.开始滚动)) && !msg.StartsWith(EGateCommandWordUtil.EGateCommandWord2String(EGateCommandWord.停止滚动)) ) { if (g.ClientSendLogger.Count >= 20) { g.ClientSendLogger.RemoveAt(0); } g.ClientSendLogger.Add(msg); } } } } catch (Exception ex) { LogTextHelper.WriteLine(Resources.LogDir, "端口{0}发送报文失败:{1}", g.Place.PlaceTypeName, ex.Message); } Thread.Sleep(1000); } } #endregion #region Server /// /// 处理从输送机端口获取的报文信息的函数 /// /// 输送机 private void ServerHandleGateMsg(object gate) { var g = (GateEntity)gate; while (true) { try { var gateService = new GateService(g); gateService.HandleMsgSend(gateService.ReadFromDatagramPoolSend()); if (g.Place.PlaceTypeName == "sc") { gateService.HandleMsgSCReceive(gateService.ReadFromDatagramPoolSCReceive()); } else { gateService.HandleMsgReceive(gateService.ReadFromDatagramPoolReceive()); gateService.HandleMsgAlarmReceive(gateService.ReadFromDatagramPoolAlarmReceive()); } } catch (Exception ex) { LogTextHelper.WriteLine(Resources.LogDir, "端口{0}信息读取失败:{1}", g.Place.PlaceTypeName, ex.Message); } Thread.Sleep(2000); } } /// /// 将从输送机端口获取的报文写入日志 /// /// //private void ServerGateWriteDatagamLog(object gate) //{ // var g = (GateEntity)gate; // while (true) // { // try // { // LogTextHelper.WriteLine(Resources.LogDir, "端口{0}读取接收的报文:{1}", g.Place.PlaceTypeName, g.DatagramReceivePool); // LogTextHelper.WriteLine(Resources.LogDir, "端口{0}读取发送的报文:{1}", g.Place.PlaceTypeName, g.DatagramSendPool); // } // catch (Exception ex) // { // LogTextHelper.WriteLine(Resources.LogDir, "端口{0}读取状态失败:{1}", g.Place.PlaceTypeName, ex.Message); // } // Thread.Sleep(60000); // } //} #endregion private void StartSocket(object gate) { var g = (GateEntity)gate; while (true) { try { //Socket服务端启动接收 if (!g.SocketServer.IsServerStarted) { if (!g.SocketServer.ServerStart()) { LogTextHelper.WriteLine(Resources.LogDir, "{0}的发送服务套接字启动异常", g.Place.PlaceTypeName); } } } catch (Exception ex) { LogTextHelper.WriteLine(Resources.LogDir, "端口{0}读取状态失败:{1}", g.Place.PlaceTypeName, ex.Message); } Thread.Sleep(2000); } } /// /// 生成入库主任务 /// private void CreateMainInTask() { var c = (ConveyorEntity)CacheEntity.Conveyors.Find(x => x.Equipment.EquipName == "conveyor1"); var mainTaskContainer = new MainTaskContainer(); var 生成入库主任务 = new 根据扫码生成入库主任务(c, mainTaskContainer); var 保存生成的任务 = new 保存生成的入库任务(c, mainTaskContainer); 生成入库主任务.NextHandler = 保存生成的任务; while (true) { if (CacheEntity.IsAutoRun) { 生成入库主任务.Handle(); } Thread.Sleep(1000); } } /// /// 生成出库主任务 /// private void CreateMainOutTask() { var mainTaskContainer = new MainTaskContainer(); var 生成出库主任务 = new 生成出库主任务(mainTaskContainer); var 保存生成的出库任务 = new 保存生成的出库任务(mainTaskContainer); 生成出库主任务.NextHandler = 保存生成的出库任务; while (true) { if (CacheEntity.IsAutoRun) { 生成出库主任务.Handle(); } Thread.Sleep(2000); } } /// /// 分解任务 /// private void DecomposeTask() { var mainTaskContainer = new MainTaskContainer(); var partTaskContainer = new PartTaskContainer(); var placeContainer = new PlaceContainer(); var resultContainer = new ResultContainer(); var 按策略获取一个待分解任务 = new 按策略获取一个待分解任务(mainTaskContainer); var 根据任务类型生成分解任务 = new 根据任务类型生成分解任务(resultContainer, mainTaskContainer, partTaskContainer, placeContainer); var 保存分解任务 = new 保存分解任务(mainTaskContainer, partTaskContainer, placeContainer); 按策略获取一个待分解任务.NextHandler = 根据任务类型生成分解任务; 根据任务类型生成分解任务.NextHandler = 保存分解任务; while (true) { mainTaskContainer.MainTask = null; partTaskContainer.PartTask = null; resultContainer.Msg = ""; if (CacheEntity.IsAutoMode) { 按策略获取一个待分解任务.Handle(); } Thread.Sleep(1000); } } /// /// 处理任务的线程 /// private void HandleTask() { var resultContainer = new ResultContainer(); var handleTaskContainer = new PartTaskContainer(); var nextTaskContainer = new PartTaskContainer(); var 获取一个已完成但未处理的分解任务 = new 获取一个已完成但未处理的分解任务(handleTaskContainer); var 根据任务类型获取下一阶段任务 = new 根据任务类型获取下一阶段任务(handleTaskContainer, nextTaskContainer, resultContainer); var 保存处理信息 = new 保存处理信息(handleTaskContainer, nextTaskContainer); 获取一个已完成但未处理的分解任务.NextHandler = 根据任务类型获取下一阶段任务; 根据任务类型获取下一阶段任务.NextHandler = 保存处理信息; while (true) { resultContainer.Msg = ""; handleTaskContainer.PartTask = null; nextTaskContainer.PartTask = null; if (CacheEntity.IsAutoHandle) { 获取一个已完成但未处理的分解任务.Handle(); } Thread.Sleep(200); } } /// /// 自动执行输送机任务 /// private void DoConveyorTaskAuto(object conveyor) { var c = (ConveyorEntity)conveyor; var decompositionTaskContainer = new PartTaskContainer(); var 选择一个未执行的输送机的任务 = new 选择一个未执行的输送机的任务(c, decompositionTaskContainer); var 发送输送机任务 = new 发送输送机任务(c, decompositionTaskContainer); 选择一个未执行的输送机的任务.NextHandler = 发送输送机任务; while (true) { if (CacheEntity.IsAutoRun) { 选择一个未执行的输送机的任务.Handle(); } Thread.Sleep(200); } } /// /// 自动执行堆垛机任务 /// private void DoStackerTaskAuto(object stacker) { var s = (StackerEntity)stacker; var decompositionTaskContainer = new PartTaskContainer(); var 选择一个未执行的堆垛机的任务 = new 选择一个未执行的堆垛机的任务(s, decompositionTaskContainer); var 发送堆垛机任务 = new 发送堆垛机任务(s, decompositionTaskContainer); 选择一个未执行的堆垛机的任务.NextHandler = 发送堆垛机任务; while (true) { if (CacheEntity.IsAutoRun) { 选择一个未执行的堆垛机的任务.Handle(); } Thread.Sleep(2000); } } /// /// 完成输送机任务 /// private void FinishConveyorTask(object conveyor) { var c = (ConveyorEntity)conveyor; var decompositionTaskContainer = new PartTaskContainer(); var 获取当前的任务 = new 获取当前的任务(c, decompositionTaskContainer); var 查看物料是否到输送机末端 = new 查看物料是否到输送机末端(c, decompositionTaskContainer); 获取当前的任务.NextHandler = 查看物料是否到输送机末端; while (true) { 获取当前的任务.Handle(); Thread.Sleep(200); } } /// /// 完成堆垛机任务 /// private void FinishStackerTask(object stacker) { var s = (StackerEntity)stacker; var decompositionTaskContainer = new PartTaskContainer(); var 获取当前的堆垛机任务 = new 获取当前的堆垛机任务(s, decompositionTaskContainer); var 等待堆垛机完成任务 = new 等待堆垛机完成任务(s, decompositionTaskContainer); var 将完成结果更新至数据库 = new 将完成结果更新至数据库(s, decompositionTaskContainer); var 保存出入库明细信息 = new 保存出入库明细信息(s, decompositionTaskContainer); 获取当前的堆垛机任务.NextHandler = 等待堆垛机完成任务; 等待堆垛机完成任务.NextHandler = 将完成结果更新至数据库; 将完成结果更新至数据库.NextHandler = 保存出入库明细信息; while (true) { 获取当前的堆垛机任务.Handle(); Thread.Sleep(2000); } } /// /// 添加堆垛机离线次数 /// private void AddStackerOffLineTimes(object stacker) { var s = (StackerEntity)stacker; while (true) { if (s.OffLineTimes > 5) { s.IsOnline = false; } else { s.OffLineTimes += 1; } Thread.Sleep(1000); } } //设定每个堆垛机是否在线的线程 private void SetStackerIsOnline(object stacker) { var s = (StackerEntity)stacker; while (true) { if (s.HandShake != s.LastHandShake) { s.LastHandShake = s.HandShake; s.OffLineTimes = 0; s.IsOnline = true; } Thread.Sleep(1000); } } //获取Stacker告警 private void SendStackerAlert(object stacker) { var generator = new ProxyGenerator(); var s = (StackerEntity)stacker; while (true) { using (var dbModel = new DbModelLog()) { try { var alertList = new List(); var alerts = dbModel.DEVAlerts.Where(x => x.name == s.Equipment.EquipName && x.isfinished == (int)EYesOrNo.否).ToList(); if (s.Alarm == (int)EYesOrNo.是) { string alertnumber = s.AlarmNumber.ToString(); var alert = alerts.FirstOrDefault(x => x.alertcode == alertnumber && x.eventcode == (int)EEventCode.警告触发); if (alert == null) { alertList.Add(new AlertEntity() { Name = s.Equipment.EquipName, CreateTime = DateTime.Now, Type = (int)EEquipmentType.堆垛机, EquipId = EEquipmentType.堆垛机.ToString(), FinishTime = DateTime.Now, IsFinished = (int)EYesOrNo.否, AlertCode = s.AlarmNumber.ToString(), EventCode = (int)EEventCode.警告触发, AlertName = ((ESrmAlarm1)s.AlarmNumber).ToString(), }); AlertDao.GetInstance().Save(alertList, dbModel); } } else { alerts.ForEach(x => { x.isfinished = (int)EYesOrNo.是; x.finishtime = DateTime.Now; x.eventcode = (int)EEventCode.警告已修复; alertList.Add(new AlertEntity(x)); }); dbModel.SaveChanges(); } } catch (Exception ex) { LogTextHelper.WriteLine(Resources.LogDir, "推送堆垛机告警失败:{0}", ex.Message); } } Thread.Sleep(5000); } } ////获取输送机告警 private void SendConveyorAlert() { while (true) { using (var dbModel = new DbModelLog()) { try { string conveyorCnName = Enum.GetName(typeof(EEquipmentType), EEquipmentType.输送机); var alerm = CacheEntity.Conveyors.Find(x => x.Equipment.EquipName == "conveyor1").Gates.Find(x => x.Place.PlaceTypeName == "alarm"); var alertList = new List(); var alerts = dbModel.DEVAlerts.Where(x => x.name == conveyorCnName && x.isfinished == (int)EYesOrNo.否).ToList(); if (int.Parse(alerm.AlarmCode) != (int)EConveyorAlarm.无告警) { var alert = alerts.FirstOrDefault(x => x.alertcode == alerm.AlarmCode && x.eventcode == (int)EEventCode.警告触发); if (alert == null) { alertList.Add(new AlertEntity() { Name = conveyorCnName, CreateTime = DateTime.Now, Type = (int)EEquipmentType.输送机, EquipId = EEquipmentType.输送机.ToString(), FinishTime = DateTime.Now, IsFinished = (int)EYesOrNo.否, AlertCode = alerm.AlarmCode, AlertName = ((EConveyorAlarm)int.Parse(alerm.AlarmCode)).ToString(), EventCode = (int)EEventCode.警告触发 }); AlertDao.GetInstance().Save(alertList, dbModel); } } else { alerts.ForEach(x => { x.isfinished = (int)EYesOrNo.是; x.finishtime = DateTime.Now; x.eventcode = (int)EEventCode.警告已修复; alertList.Add(new AlertEntity(x)); }); dbModel.SaveChanges(); } } catch (Exception ex) { LogTextHelper.WriteLine(Resources.LogDir, "推送获取输送机告警失败:{0}", ex.Message); } } Thread.Sleep(5000); } } /// /// 写入堆垛机报表 /// private void WriteStackerReport() { while (true) { using (var dbModel = new DbModelLog()) { try { // string stackerName = Enum.GetName(typeof(EEquipmentCnName), EEquipmentCnName.stacker1); var reports = dbModel.COUNTStackerReports.Where(x => x.isfinished == (int)EYesOrNo.否).ToList(); var stacker = CacheEntity.Stackers.FirstOrDefault(x => x.Equipment.EquipName == "stacker1"); var unfinishedReport = reports.FirstOrDefault(x => x.name == stacker.Equipment.EquipName); if (unfinishedReport == null) { dbModel.COUNTStackerReports.Add(new COUNTStackerReport { name = stacker.Equipment.EquipName, status = stacker.State, createtime = DateTime.Now, isfinished = 0 }); dbModel.SaveChanges(); } else if (unfinishedReport.status != stacker.State) { unfinishedReport.isfinished = (int)EYesOrNo.是; unfinishedReport.finishtime = DateTime.Now; dbModel.COUNTStackerReports.Add(new COUNTStackerReport { name = stacker.Equipment.EquipName, status = stacker.State, createtime = DateTime.Now, isfinished = 0 }); dbModel.SaveChanges(); } } catch (Exception ex) { LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "WriteStackerReport", ex.Message); } } Thread.Sleep(5000); } } //同步完成次数 private void SyncFinishTimes() { while (true) { using (var dbModel = new DbModelCore()) { try { var sql = "UPDATE [dbo].[TASKPartTask] SET [finishtimes]=0 WHERE [isreleased]=1 AND [isfinished]=0"; dbModel.Database.ExecuteSqlCommand(sql); } catch (Exception ex) { LogTextHelper.WriteLine(Resources.LogDir, "同步完成次数失败:{0}", ex.Message); } } Thread.Sleep(49000); } } //同步处理次数 private void SyncHandleTimes() { while (true) { using (var dbModel = new DbModelCore()) { try { var sql = "UPDATE [dbo].[TASKPartTask] SET [handletimes]=0 WHERE [isfinished] = 1 AND [ishandled] = 0 "; dbModel.Database.ExecuteSqlCommand(sql); } catch (Exception ex) { LogTextHelper.WriteLine(Resources.LogDir, "同步处理次数失败:{0}", ex.Message); } } Thread.Sleep(23000); } } //同步分解次数 private void SyncDecompositionTimes() { while (true) { using (var dbModel = new DbModelCore()) { try { var sql = "UPDATE [dbo].[TASKMainTask] SET [decompositiontimes]=0 WHERE [status]=0 "; dbModel.Database.ExecuteSqlCommand(sql); } catch (Exception ex) { LogTextHelper.WriteLine(Resources.LogDir, "同步分解次数失败:{0}", ex.Message); } } Thread.Sleep(87000); } } //同步立库里的物料信息 private void SyncMaterialInfo() { var generator = new ProxyGenerator(); while (true) { using (var dbModel = new DbModelCore()) { try { var wareHouseInfo = new List(); var materialList = new List(); var placeMaterial = dbModel.BASEPlaceMaterialViews.ToList(); var tasks = dbModel.TASKPartTasks.Where(x => x.type == (int)EPartTaskType.堆垛机任务 && x.isfinished == (int)EYesOrNo.否).ToList(); tasks.ForEach(x => materialList.Add(x.materialcode)); foreach (var pc in placeMaterial) { if (materialList.Contains(pc.materialcode)) { continue; } wareHouseInfo.Add(new { materialcode = pc.materialcode, wareHousePlaceId = pc.placecode, packageNumber = "", quantity = 1, materialCode = pc.materialcode, flag = true }); } var requestBody = new { sysCode = "WCS", timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), wareHouseInfo = wareHouseInfo }; // new Context(new 同步立库物料信息(requestBody)).Invoke(); LogTextHelper.WriteLine(Resources.LogDir, "SyncMaterialInfo:{0}", "同步物料已完成"); } catch (Exception ex) { LogTextHelper.WriteLine(Resources.LogDir, "SyncMaterialInfo:{0}", ex.Message); } } Thread.Sleep(2 * 3600 * 1000); } } /// /// 重推报文发送失败信息 /// private void ReSend() { //LogTextHelper.WriteLine(Resources.LogDir, "重推的线程已开启"); while (true) { using (var dbModel = new DbModelLog()) { try { var eMsg = dbModel.LOGERRORFailSentMessages.OrderBy(x => x.retrytimes).ThenBy(x => x.createtime).FirstOrDefault(x => x.isok == (int)EYesOrNo.否 && x.ismailed == (int)EYesOrNo.否 && x.retrytimes < 3); if (eMsg != null) { string msg; var flag = FailSentMessageService.GetInstance().ReSend(eMsg.id, out msg); LogTextHelper.WriteLine(Resources.LogDir, "重推报文id={0},flag={1},msg={2}", eMsg.id, flag, msg); } } catch (Exception ex) { LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "ReSend", ex.Message); } } Thread.Sleep(1000); } } /// ///关闭WCF /// ///需要关闭的WCF private void CloseWcf(ServiceHost host) { if (host != null) { host.Close(); } } /// /// 开启线程 /// private void StartThread(Thread thread) { if (thread != null) { thread.IsBackground = true; thread.Start(); } LogTextHelper.WriteLine(Resources.LogDir, "线程{0}已开启", thread.Name); } /// /// 开启带参数的线程 /// private void StartThread(Thread thread, object obj) { if (thread != null) { thread.IsBackground = true; thread.Start(obj); } LogTextHelper.WriteLine(Resources.LogDir, "线程{0}已开启", thread.Name); } /// /// 关闭线程 /// /// 需要关闭的线程 private void CloseThread(Thread thread) { if (thread != null) { thread.Abort(); } LogTextHelper.WriteLine(Resources.LogDir, "线程{0}已关闭", thread.Name); } } }