using HH.WCS.JunzhouNongfu.device; using HH.WCS.Mobox3.HD.device; using HH.WCS.Mobox3.HD.dispatch; using HH.WCS.Mobox3.HD.models; using HH.WCS.Mobox3.HD.process; using HH.WCS.Mobox3.HD.util; using HH.WCS.Mobox3.HD.wms; using Newtonsoft.Json; using NLog; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading.Tasks; using static HH.WCS.Mobox3.HD.api.ApiModel; using static HH.WCS.Mobox3.HD.dispatch.ShopFloorControl; using static HH.WCS.Mobox3.HD.util.Settings; namespace HH.WCS.Mobox3.HD.core { internal class WCSCore { public static void OperateAgvTaskStatus(AgvTaskState model) { if (string.IsNullOrEmpty(model.No)) { //无任务号请求(交管) //DeviceProcess.Traffic(model.ForkliftNo, model.LockNo, model.State==1023); } else { var TN_Task = WCSHelper.GetTask(model.No); if (TN_Task != null) { if (model.State <= 7) { //有任务号请求 switch (model.State) { case 1: WCSHelper.Begin(TN_Task); break; #region MyRegion case 3: WCSHelper.UpdateStatus(TN_Task, "开始取货"); break; case 4: WCSHelper.UpdateStatus(TN_Task, "取货完成"); TaskProcess.OperateStatus(TN_Task, 4); break; case 5: WCSHelper.UpdateStatus(TN_Task, "开始卸货"); break; case 6: WCSHelper.UpdateStatus(TN_Task, "卸货完成"); TaskProcess.OperateStatus(TN_Task, 6); break; #endregion case 2: WCSHelper.End(TN_Task); break; case 7: //判断是否收到过强制取消,有就不做任何处理 if (!WCSHelper.CheckActionRecordExist(TN_Task.S_CODE, 17)) { TaskProcess.OperateStatus(TN_Task, 7); WCSHelper.Fail(TN_Task); } break; } WCSHelper.AddActionRecord(model.No, model.State, model.ForkliftNo, model.ExtData); //调用第三方接口(如果有)TaskProcess.ReportStatus } else { //安全请求等 TaskProcess.OperateReq(model.No, model.State, model.ForkliftNo, model.ExtData); } } } } /// /// 合力 任务状态反馈 /// /// public static void OperateHLTaskStatus(HLAgvTaskState model) { if (string.IsNullOrEmpty(model.orderId)) { //无任务号请求(交管) //DeviceProcess.Traffic(model.ForkliftNo, model.LockNo, model.State==1023); } else { var wcsTask = WCSHelper.GetTask(model.orderId); if (wcsTask != null && wcsTask.N_B_STATE != 3 && wcsTask.S_SCHEDULE_TYPE.Equals("HL")) { HLStatusInfo hLStatusInfo = null ; WMSTask wmsTask = WMSHelper.GetWmsTask(wcsTask.S_OP_CODE); if (wmsTask != null ) { hLStatusInfo = new HLStatusInfo() { orderId = wmsTask.S_CODE, agvId = model.agvId, status = model.status, reason = model.reason }; } //有任务号请求 switch (model.status) { case "1": WCSHelper.Begin(wcsTask); LocationHelper.UnBindingLoc(wcsTask.S_START_LOC, new List { wcsTask.S_CNTR_CODE }); LocationHelper.UnLockLoc(wcsTask.S_START_LOC); wcsTask.S_EQ_NO = model.agvId; WCSHelper.UpdateStatus(wcsTask, "取货完成"); break; case "2": WCSHelper.End(wcsTask); if (wcsTask.S_TYPE.Contains("入库")) { LocationHelper.BindingLoc(wcsTask.S_END_LOC, new List { wcsTask.S_CNTR_CODE }); } LocationHelper.UnLockLoc(wcsTask.S_END_LOC); if (wmsTask != null) { // 判断作业任务是否已完成 if (wmsTask.S_END_LOC.Equals(wcsTask.S_END_LOC)) { wmsTask.N_B_STATE = 2; wmsTask.T_END_TIME = DateTime.Now; WMSHelper.UpdateTaskState(wmsTask); if (wmsTask.S_OP_DEF_NAME == "模具出库(初始化)") { // 删除模具信息 MouldHelper.deleteMouldByCntr(wmsTask.S_CNTR_CODE); } if (wmsTask.S_TYPE == "模具入库") { MouldHelper.updateMouldStatus(wmsTask.S_CNTR_CODE, "Y"); } if (wmsTask.S_TYPE == "模具出库") { MouldHelper.updateMouldStatus(wmsTask.S_CNTR_CODE, "N"); } if (wmsTask.S_TYPE == "钢卷出库") { ContainerHelper.UpdateCntrItem(wmsTask.S_CNTR_CODE, 0); } if (wmsTask.S_TYPE == "钢卷入库" || wmsTask.S_TYPE == "钢卷来料入库") { ContainerHelper.UpdateCntrItem(wmsTask.S_CNTR_CODE, 1); } var cntrItemRels = ItemHelper.GetCntrItemByCntrCode(wmsTask.S_CNTR_CODE); if (cntrItemRels != null && cntrItemRels.Count > 0) { foreach (var cntrItemRel in cntrItemRels) { // 更新出入库记录 WMSHelper.AddStockRecord(wmsTask, cntrItemRel); // 终点货位在系统中没有维护,则删除容器物料信息 var endLoc = LocationHelper.GetLoc(wmsTask.S_END_LOC); if (endLoc == null) { ContainerHelper.deleteCntrItem(wmsTask.S_CNTR_CODE); } else if (cntrItemRel.S_ITEM_TYPE.Equals("半成品")) { ContainerHelper.deleteCntrItem(wmsTask.S_CNTR_CODE); } } } else { // 更新出入库记录 WMSHelper.AddStockRecord(wmsTask, null); } } else { if (wmsTask.S_END_LOC == "虚拟库位" && wmsTask.S_TYPE == "钢卷入库") { var gjWeight = getGjWeight(wcsTask.S_END_LOC , wcsTask.S_CNTR_CODE ,wmsTask.S_OP_DEF_CODE); Location endLoc = WMSHelper.GetGJEndLocation(gjWeight); if (endLoc != null) { wmsTask.S_END_LOC = endLoc.S_CODE; wmsTask.S_END_AREA = endLoc.S_AREA_CODE; WMSHelper.UpdateTask(wmsTask); // 输送线称重回报车间控制器 SteelWeightInfo productWeightInfo = new SteelWeightInfo() { transferId = wmsTask.S_OP_DEF_CODE, steelcoilCode = wmsTask.S_CNTR_CODE, weight = gjWeight, endStationCode = endLoc.S_CODE, endAreaCode = endLoc.S_AREA_CODE }; ShopFloorControl.reportSteelWeight(productWeightInfo); } else { wmsTask.S_ERR = "没有可入的钢卷货位"; WMSHelper.UpdateTask(wmsTask); } } var twoWcsTask = new WCSTask { S_OP_NAME = wmsTask.S_OP_DEF_NAME, S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = wmsTask.S_TYPE+"-2", S_START_LOC = wcsTask.S_END_LOC, S_START_AREA = wcsTask.S_END_AREA, S_END_LOC = wmsTask.S_END_LOC, S_END_AREA = wmsTask.S_END_AREA, S_SCHEDULE_TYPE = "HL", S_CNTR_CODE = wmsTask.S_CNTR_CODE, N_CNTR_COUNT = 1, S_OP_CODE = wmsTask.S_CODE, N_PRIORITY = wmsTask.N_PRIORITY, }; if (wmsTask.S_TYPE.Equals("半成品/成品出库")) { twoWcsTask.S_SCHEDULE_TYPE = "LD-AUTO"; } if (wmsTask.S_TYPE.Equals("成品出库")) { twoWcsTask.S_SCHEDULE_TYPE = "LD"; } if (WCSHelper.CreateTask(twoWcsTask)) { LocationHelper.LockLoc(twoWcsTask.S_START_LOC, 2); LocationHelper.LockLoc(twoWcsTask.S_END_LOC, 1); } } } break; case "3": // 任务取消 WCSHelper.Fail(wcsTask); LocationHelper.UnLockLoc(wcsTask.S_START_LOC); LocationHelper.UnLockLoc(wcsTask.S_END_LOC); // 作业取消 wmsTask.N_B_STATE = 3; wmsTask.T_END_TIME = DateTime.Now; WMSHelper.UpdateTaskState(wmsTask); LocationHelper.UnLockLoc(wmsTask.S_END_LOC); LogHelper.Info("任务已取消,任务号:" + wcsTask.S_CODE, "合力"); break; } // 回报车间控制器合力任务状态 if (hLStatusInfo != null) { ShopFloorControl.updateStatus(hLStatusInfo); } WCSHelper.AddActionRecord(model.orderId, int.Parse(model.status), model.agvId, null); } } } public static float getGjWeight(string locCode ,string cntrCode ,string transferId = null) { var weightPlcInfo = weightPlcInfos.Where(a => a.location == locCode).FirstOrDefault(); LogHelper.Info("称重设备信息:" + JsonConvert.SerializeObject(weightPlcInfo), "Mobox"); float weight = 0; if (weightPlcInfo != null) { try { // 获取称重结果 LogHelper.Info("开始查询称重结果", "Mobox"); string hexString = TcpClient.SendHexOnce(weightPlcInfo.ip, 502, weightPlcInfo.command); LogHelper.Info("hexString:" + hexString, "Mobox"); weight = Convert.ToInt32(hexString.Substring(6, 8), 16); LogHelper.Info("称重结果:" + weight + " ;hexString:" + hexString, "Mobox"); // 更新物料重量数据 if (weight != 0) { var cntrItemRels = ItemHelper.GetCntrItemByCntrCode(cntrCode); if (cntrItemRels != null && cntrItemRels.Count > 0) { foreach (var cntrItemRel in cntrItemRels) { cntrItemRel.F_WEIGHT = weight; if (cntrItemRel.F_INIT_WEIGHT == 0) { cntrItemRel.F_INIT_WEIGHT = weight; } ItemHelper.updateCntrItem(cntrItemRel); } } } } catch (Exception e) { LogHelper.Info("获取称重数据错误,错误原因:"+e.Message, "Mobox"); } } return weight; } /// /// 任务分发,根据调度类型发给不同的调度系统 /// internal static void Dispatch() { //查询任务 //获取所有等待的任务 var list = WCSHelper.GetWaitingTaskList(); if (list.Count > 0) { list.ForEach(task => { if (TaskProcess.Intercept(task)) { //使用自定义任务推送 TaskProcess.SendTask(task); } }); } } /// /// 杭奥堆垛机信号反馈 /// /// internal static void OperateHATaskStatus(HanAo.TaskStateInfoModel model) { var wcsTask = WCSHelper.GetTask(model.requestPk); if (wcsTask != null) { if (model.code == "0") { // if (wcsTask.S_TYPE == "堆垛机入库") { //终点托盘绑定 if (LocationHelper.BindingLoc(wcsTask.S_END_LOC, new List { wcsTask.S_CNTR_CODE })) { //修改托盘状态为可用,增加库存量表,后面分拣出可以计算到 ContainerHelper.Enable(wcsTask.S_CNTR_CODE, wcsTask.S_END_LOC); } } else if (wcsTask.S_TYPE == "堆垛机出库") { //起点托盘解绑 LocationHelper.UnBindingLoc(wcsTask.S_START_LOC, new List { wcsTask.S_CNTR_CODE }); } //标记任务完成 //标记作业完成 wcsTask.N_B_STATE = 3; WCSHelper.UpdateStatus(wcsTask); var wmsTask = WMSHelper.GetWmsTask(wcsTask.S_OP_CODE); if (wmsTask != null) { wmsTask.N_B_STATE = 2; WMSHelper.UpdateTaskState(wmsTask); } } } } public class IssueTaskModel { public int taskId { get; set; } // 任务号 public short targetAddress { get; set; } // WCS分配的目标地址 public short instruction { get; set; } // 下发命令 WCS下发的动作指令 入库=2 出库=1 public string trayCode { get; set; } // 托盘编码 } } }