using HH.WCS.Mobox3.WeiLi.dispatch; using HH.WCS.Mobox3.WeiLi.models; using HH.WCS.Mobox3.WeiLi.process; using HH.WCS.Mobox3.WeiLi.util; using HH.WCS.Mobox3.WeiLi.wms; using Newtonsoft.Json; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using static HH.WCS.Mobox3.WeiLi.api.ApiModel; namespace HH.WCS.Mobox3.WeiLi.core { internal class WCSCore { private static HttpHelper httpHelper = new HttpHelper(); public static void OperateAgvTaskStatus(AgvTaskState model) { try { if (string.IsNullOrEmpty(model.task_no)) { //无任务号请求(交管) //DeviceProcess.Traffic(model.ForkliftNo, model.LockNo, model.State==1023); } else { var TN_Task = WCSHelper.GetTask(model.task_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); //if (TN_Task.S_OP_NAME == "出库") //{ // WMSHelper.DeleteChange(TN_Task); //} break; case 5: WCSHelper.UpdateStatus(TN_Task, "开始卸货"); break; case 6: WCSHelper.UpdateStatus(TN_Task, "卸货完成"); TaskProcess.OperateStatus(TN_Task, 6); WMSHelper.End(TN_Task); if (Settings.DJCodes.Where(a => a.DJAreaCode == TN_Task.S_END_AREA).FirstOrDefault() != null) { TaskProcess.InspectionAreaStockUpdate(TN_Task.S_CNTR_CODE, TN_Task.S_END_LOC); } break; #endregion case 2: WCSHelper.End(TN_Task); //sendsencondtask(TN_Task); break; case 7: TaskProcess.OperateStatus(TN_Task, 7); WCSHelper.Fail(TN_Task); WMSHelper.Fail(TN_Task); //sendsencondtask(TN_Task); //WMSHelper.End(TN_Task); break; } WCSHelper.AddActionRecord(model.task_no, model.State, model.forklift_no, model.ext_data); //调用第三方接口(如果有)TaskProcess.ReportStatus TaskProcess.ThirdReportStatus(TN_Task, model.State, model.forklift_no); TaskProcess.UpdateAgvNo(TN_Task, model.forklift_no); } else { //安全请求等 TaskProcess.AddTaskAction(model); WCSHelper.AddActionRecord(model.task_no, model.State, model.forklift_no, model.ext_data); //TaskProcess.OperateReq(TN_Task, model.State, model.forklift_no, model.ext_data); } } } } catch (Exception ex) { LogHelper.Error($"AGV回报流程异常 异常信息{ex.Message}", ex); } } internal static void TaskAction() { var db = new SqlHelper().GetInstance(); var TaskActionList = db.Queryable().ToList(); var tasks = new List(); TaskActionList.ForEach(a => { tasks.Add(Task.Run(() => { var TN_Task = WCSHelper.GetTask(a.TASK_NO); if (TN_Task != null) { try { TaskProcess.OperateReq(TN_Task, a.STATE, a.FORKLIFT_NO, a.EXT_DATA); } catch (Exception ex) { LogHelper.Error($"交互信号处理异常 异常信息{ex.Message}", ex); } db.Deleteable(a).ExecuteCommand(); } })); }); Task.WaitAll(tasks.ToArray(), 3000); } internal static void GetConnetState() { var db = new SqlHelper().GetInstance(); Settings.ConnetBits.ForEach(a => { var S_WMS_LOCATION = ""; var S_WCS_LOCATION = ""; var S_ITEM_CODE = ""; var S_ITEM_NAME = ""; double N_QTY = 0; double F_QTY = 0; var S_TRAY_CODE = ""; var S_TYPE = ""; var S_SORTING = ""; try { var LocInfo = db.Queryable().Where(it => it.S_CODE == a).First(); if (LocInfo != null) { S_WMS_LOCATION = a; var WcsInfo = db.Queryable().Where(it => it.BitCode == a).First(); if (WcsInfo != null) { S_WCS_LOCATION = WcsInfo.PlcLocation; } var TrayInfo = db.Queryable().Where(it => it.S_LOC_CODE == a).First(); if (TrayInfo != null) { S_TRAY_CODE = TrayInfo.S_CNTR_CODE; } if (!string.IsNullOrEmpty(S_TRAY_CODE)) { var ItemInfo = db.Queryable().Where(it => it.S_CNTR_CODE == S_TRAY_CODE).First(); if (ItemInfo != null) { S_ITEM_CODE = ItemInfo.S_ITEM_CODE; S_ITEM_NAME = ItemInfo.S_ITEM_NAME; var ItemSum = db.Queryable().Where(it => it.S_CNTR_CODE == S_TRAY_CODE).Select(it => new { sum = SqlFunc.AggregateSum(it.F_QTY) }).First(); if (ItemSum != null) { N_QTY = ItemSum.sum; } } var SortingInfo = db.Queryable().Where(it => it.S_CNTR_CODE == S_TRAY_CODE && it.N_B_STATE == 2).First(); if (SortingInfo != null) { S_SORTING = SortingInfo.S_SORT_TYPE; var SortingDeInfo = db.Queryable().Where(it => it.S_CNTR_CODE == S_TRAY_CODE).OrderByDescending(it => it.T_CREATE).First(); if (SortingDeInfo != null) { F_QTY = SortingDeInfo.F_QTY; } } var WmsTaskInfo = db.Queryable().Where(it => it.S_CNTR_CODE == S_TRAY_CODE && it.N_B_STATE == 0 || it.N_B_STATE == 1 || it.N_B_STATE == 3).First(); if (WmsTaskInfo != null) { LogHelper.Info($"LED显示 获取正在执行的作业 托盘号{S_TRAY_CODE} 作业号{WmsTaskInfo.S_CODE} 作业类型{WmsTaskInfo.S_TYPE}"); S_TYPE = WmsTaskInfo.S_TYPE; } } var ConnetInfo = db.Queryable().Where(it => it.S_WMS_LOCATION == a).First(); if (ConnetInfo != null) { //修改 ConnetInfo.N_QTY = N_QTY; ConnetInfo.F_QTY = F_QTY; ConnetInfo.S_ITEM_CODE = S_ITEM_CODE; ConnetInfo.S_ITEM_NAME = S_ITEM_NAME; ConnetInfo.S_SORTING = S_SORTING; ConnetInfo.S_TRAY_CODE = S_TRAY_CODE; ConnetInfo.S_WCS_LOCATION = S_WCS_LOCATION; ConnetInfo.S_TYPE = S_TYPE; db.Updateable(ConnetInfo).UpdateColumns(it => new { it.F_QTY, it.N_QTY, it.S_ITEM_CODE, it.S_ITEM_NAME, it.S_TRAY_CODE, it.S_SORTING, it.S_WCS_LOCATION, it.S_TYPE }).ExecuteCommand(); } else { //新增 ConnetInfo = new ConnetState { S_WMS_LOCATION = a, N_QTY = N_QTY, F_QTY = F_QTY, S_ITEM_CODE = S_ITEM_CODE, S_ITEM_NAME = S_ITEM_NAME, S_SORTING = S_SORTING, S_TRAY_CODE = S_TRAY_CODE, S_WCS_LOCATION = S_WCS_LOCATION, S_TYPE = S_TYPE }; db.Insertable(ConnetInfo).ExecuteCommand(); } } } catch (Exception ex) { LogHelper.Error($"监控接驳位线程异常 异常接驳位编码{a} 异常信息{ex.Message}", ex); } }); } internal static void DuiDuoInfo() { var db = new SqlHelper().GetInstance(); string DuiDuoInfo = ""; var DuiDuoInfos = Settings.DuiDuoInfos; try { DuiDuoInfos.ForEach(it => { DuiDuoInfo = DuiDuoInfo + it.DuiDuoCode + ","; }); var Url = Settings.HASeverUrl; if (Url != null && !string.IsNullOrEmpty(DuiDuoInfo)) { var model = new { reqDvc = DuiDuoInfo }; var feed = httpHelper.WebPost(Url + "dvc-state", JsonConvert.SerializeObject(model)); LogHelper.Info($"获取堆垛机状态 参数={JsonConvert.SerializeObject(model)} 返回参数={feed}"); if (!string.IsNullOrEmpty(feed)) { var res = JsonConvert.DeserializeObject>(feed); if (res.Count > 0) { res.ForEach(it => { var Info = Settings.DuiDuoInfos.Where(a => a.DuiDuoCode == it.DVC_NO).FirstOrDefault(); if (Info != null) { //获取库区和巷道 var PeizInfo = db.Queryable().Where(a => a.S_AREA_CODE == Info.AreaCode && a.N_LANE == Info.Roadway).First(); if (PeizInfo != null) { PeizInfo.N_STATE = int.Parse(it.IS_USE); PeizInfo.S_PLC_NO = it.DVC_NO; //更新 db.Updateable(PeizInfo).UpdateColumns(a => new { a.N_STATE, a.S_PLC_NO }).ExecuteCommand(); } else { //新增 PeizInfo = new DuiDuoPeiz { N_STATE = int.Parse(it.IS_USE), S_PLC_NO = it.DVC_NO, S_AREA_CODE = Info.AreaCode, N_LANE = Info.Roadway }; db.Insertable(PeizInfo).ExecuteCommand(); } } }); } } } else { LogHelper.Info($"推送下游PLC任务 获取API地址配置失败 请检查配置文件"); } } catch (Exception ex) { LogHelper.Error($"查询堆垛机状态异常 异常信息{ex.Message}", ex); } } public class DuiDuoState { public string DVC_NO { get; set; } public string IS_USE { get; set; } } internal static void CheckSortingOutEmytTask() { var db = new SqlHelper().GetInstance(); try { var settings = Settings.ConnetAreas; foreach (var item in settings) { Location startLoc = null; Location endLoc = null; if (item.EmptyList.Length > 0) { //选取可用终点 for (int i = 0; i < item.EmptyList.Length; i++) { var endbit = item.EmptyList[i]; endLoc = db.Queryable().Where(a => a.S_CODE == endbit && a.N_LOCK_STATE == 0 && a.N_CURRENT_NUM == 0).First(); if (endLoc != null) { LogHelper.Info($"自动空框出库 获取到终点{endLoc.S_CODE}"); break; } } if (endLoc != null) { var trayNo = ""; //选取起点 var startList = db.Queryable().Where(a => a.S_AREA_CODE == item.LiKuArea && a.N_CURRENT_NUM > 0 && a.N_LOCK_STATE == 0).ToList(); if (startList.Count > 0) { foreach (var it in startList) { var DuiDuoPeiz = db.Queryable().Where(a => a.S_AREA_CODE == it.S_AREA_CODE && a.N_LANE == it.N_ROADWAY && a.N_STATE == 1).First(); if (DuiDuoPeiz != null) { var cntrInfo = db.Queryable().Where(a => a.S_LOC_CODE == it.S_CODE).First(); if (cntrInfo != null) { var itemInfo = db.Queryable().Where(a => a.S_CNTR_CODE == cntrInfo.S_CNTR_CODE).First(); if (itemInfo == null) { LogHelper.Info($"自动空框出库 获取到起点{it.S_CODE} 托盘{cntrInfo.S_CNTR_CODE}"); trayNo = cntrInfo.S_CNTR_CODE; startLoc = it; break; } } } } } if (startLoc != null) { //创建任务 var optask = new WMSTask { S_CODE = WMSHelper.GenerateTaskNo(), S_START_LOC = startLoc.S_CODE, S_START_AREA = startLoc.S_AREA_CODE, S_START_WH = startLoc.S_WH_CODE, S_END_LOC = endLoc.S_CODE, S_END_AREA = endLoc.S_AREA_CODE, S_END_WH = endLoc.S_WH_CODE, S_STATION_LOC = item.Station, S_TYPE = "出库", N_TYPE = 2, N_B_STATE = 0, S_CNTR_CODE = trayNo, S_OP_DEF_NAME = "自动呼叫空框" }; var note = Settings.Tasktypes.Where(it => it.StartArea == optask.S_START_AREA && it.EndArea == optask.S_END_AREA).FirstOrDefault(); if (note != null) { optask.S_NOTE = note.TaskType; } var res = db.Insertable(optask).ExecuteCommand() > 0; if (res) { startLoc.N_LOCK_STATE = 2; startLoc.S_LOCK_STATE = "出库锁"; db.Updateable(startLoc).UpdateColumns(it => new { it.S_LOCK_STATE, it.N_LOCK_STATE }).ExecuteCommand(); LocationHelper.LockLoc(endLoc.S_CODE, 1); } } else { LogHelper.Info($"自动空框出库 未获取可用空框"); } } else { LogHelper.Info($"自动空框出库 未获取可用终点"); } } } } catch (Exception ex) { LogHelper.Error($"创建分拣口空框出任务异常 异常信息{ex.Message}", ex); } } private static void sendsencondtask(WCSTask task) { var db = new SqlHelper().GetInstance(); var optask = db.Queryable().Where(a => a.S_CODE == task.S_OP_CODE).First(); if (task.S_END_LOC != optask.S_END_LOC) { optask.N_B_STATE = 0; optask.S_B_STATE = "等待"; WMSHelper.UpdateTaskState(optask); } } /// /// 任务分发,根据调度类型发给不同的调度系统 /// internal static void Dispatch() { //查询任务 //获取所有等待的任务 var list = WCSHelper.GetWaitingTaskList(); if (list.Count > 0) { list.ForEach(task => { if (!TaskProcess.Intercept(task)) { if (task.S_SCHEDULE_TYPE == "NDC") { //使用自定义任务推送 TaskProcess.SendTask(task); } else { TaskProcess.PlcSendTask(task); } } }); } } /// /// 杭奥堆垛机信号反馈 /// /// internal static void OperateHATaskStatus(HanAo.TaskStateInfoModel model) { var wcsTask = WCSHelper.GetTask(model.requestPk); if (wcsTask != null) { var start = LocationHelper.GetLoc(wcsTask.S_START_LOC); var end = LocationHelper.GetLoc(wcsTask.S_END_LOC); if (model.code == "0") { //入库 if (Settings.LKCodes.Where(a => a.LiKuCode == end.S_AREA_CODE).FirstOrDefault() != null) { //终点托盘绑定 LocationHelper.UnBindingLoc(wcsTask.S_START_LOC, new List { wcsTask.S_CNTR_CODE }); if (LocationHelper.BindingLoc(wcsTask.S_END_LOC, new List { wcsTask.S_CNTR_CODE })) { //修改托盘状态为可用,增加库存量表,后面分拣出可以计算到 if (wcsTask.S_TYPE != "备料入库") { ContainerHelper.Enable(wcsTask.S_CNTR_CODE, wcsTask.S_END_LOC); } } } //出库 else if (Settings.LKCodes.Where(a => a.LiKuCode == start.S_AREA_CODE).FirstOrDefault() != null) { //起点托盘解绑 LocationHelper.UnBindingLoc(wcsTask.S_START_LOC, new List { wcsTask.S_CNTR_CODE }); LocationHelper.BindingLoc(wcsTask.S_END_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); } sendsencondtask(wcsTask); } } } } }