using System; using System.Collections; using System.Collections.Generic; using System.Text; using WCS.Data; using WCS.Data.Models; using WCS.PLC.Model.Equipment; using System.Linq; using WCS.Data.Utils; using System.Threading; namespace WCS.PLC { public class Base_Conv : Base_EquPlc { public Base_Conv() { } /// /// 写入任务信息到输送机 /// /// /// /// public virtual void WriteInfoToConveyor(ConvSignal converySignal, WCSWriteToConveyorSignal converywrite, bool isNotTask = false) { if (converySignal.DB520_Tasknum == converywrite.Tasknum && converySignal.DB520_Goodscode == converywrite.Goodscode && converySignal.DB520_Goodstype == converywrite.Goodstype && converySignal.DB520_Goodssize == converywrite.Goodssize && converySignal.DB520_Goodsstart == converywrite.Goodsstart && converySignal.DB520_Goodsend == converywrite.Goodsend && converySignal.DB520_Notask== converywrite.Notask && converySignal.DB520_TaskDelete == converywrite.TaskDelete && converySignal.DB520_RollerTurn == converywrite.UpMatRequest && converySignal.DB520_Res01 == converywrite.Res01 && converySignal.DB520_Res02 == converywrite.Res02 && converySignal.DB520_Res03 == converywrite.Res03 && converySignal.DB520_Res04 == converywrite.Res04) { if (isNotTask) { ConfirmTask(converySignal, converywrite); } else { Log4netHelper.Logger_ProductLog.InfoFormat("任务[{0}]输送机[0]开始执行.",converywrite.Tasknum, converywrite.ConveyorNo); string result = TryCachHelper.TryTranExecute((db) => { var task = db.Queryable().First(v => v.TASK_NO == converywrite.Tasknum); if (string.IsNullOrWhiteSpace(converywrite.Srmno)) { db.Updateable(it => new WCS_TASK() { TASK_WKSTATUS = (int)WkStatus.输送机执行, TASK_POSIDNEXT = converywrite.Goodsend.ToString(), //TASK_ITEM5 = converywrite.Goodsstart.ToString(), TASK_EDITUSERNO = "WCS", TASK_EDITDATETIME = DateTime.Now }) .Where(it => it.TASK_NO == task.TASK_NO).ExecuteCommand(); } else { db.Updateable(it => new WCS_TASK() { TASK_WKSTATUS = (int)WkStatus.输送机执行, TASK_POSIDNEXT = converywrite.Goodsend.ToString(), //TASK_ITEM5 = converywrite.Goodsstart.ToString(), TASK_POSIDTO = converywrite.Srmno, TASK_SRMNO = converywrite.Srmno, TASK_EDITUSERNO = "WCS", TASK_EDITDATETIME = DateTime.Now }) .Where(it => it.TASK_NO == task.TASK_NO) .ExecuteCommand(); } string msg = string.Format("任务已下发给输送机[{0}]执行,起点地址[{1}]目标地址[{2}]", converywrite.ConveyorNo, converywrite.Goodsstart, converywrite.Goodsend); CommonData.AddWCS_TASK_DTL(db, task.TASK_NO, task.TASK_NO, task.TASK_POSIDCUR, converywrite.Goodsend.ToString(), msg); ConfirmTask(converySignal, converywrite); }); if (!string.IsNullOrWhiteSpace(result)) { throw new Exception(string.Format("任务[{0}]输送机[{1}]执行失败,原因:[{1}]", converywrite.Tasknum, converywrite.ConveyorNo, result)); } Log4netHelper.Logger_ProductLog.InfoFormat("任务[{0}]输送机[0]执行结束.", converywrite.Tasknum, converywrite.ConveyorNo); } } else { WriteTaskToBuffer(converywrite); } } /// /// 写入任务信息到输送机 /// /// /// /// public virtual void WriteInfoToConv(ConvSignal converySignal, WCSWriteToConveyorSignal converywrite, bool isNotTask = false) { WriteTaskToBuffer(converywrite); if (isNotTask) { ConfirmTask(converySignal, converywrite); } else { Log4netHelper.Logger_ProductLog.InfoFormat("任务[{0}]输送机[0]开始执行.", converywrite.Tasknum, converywrite.ConveyorNo); string result = TryCachHelper.TryTranExecute((db) => { var task = db.Queryable().First(v => v.TASK_NO == converywrite.Tasknum); if (converywrite.isClearPalletizingPos) { //清除机械手码垛位置条码记录 var sysset = Current.SysSets.SingleOrDefault(v => v.SET_TYPE == "PalletizingPos" && v.SET_ID == task.TASK_POSIDFROM); if (sysset != null) { string date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); db.Updateable(it => new WCS_SYSSET() { SET_MEMO = "", SET_EDITUSERNO = "wcs", SET_EDITTIME = date }) .Where(it => it.SET_ID == sysset.SET_ID).ExecuteCommand(); } } if (string.IsNullOrWhiteSpace(converywrite.Srmno)) { if (converywrite.Remark == converywrite.Goodsend.ToString()) { //完成任务 db.Updateable(it => new WCS_TASK() { TASK_WKSTATUS = 99, TASK_EDITUSERNO = "WCS", TASK_EDITDATETIME = DateTime.Now }) .Where(it => it.TASK_NO == task.TASK_NO) .ExecuteCommand(); } else { db.Updateable(it => new WCS_TASK() { TASK_WKSTATUS = (int)WkStatus.输送机执行, TASK_POSIDNEXT = converywrite.Goodsend.ToString(), //TASK_ITEM5 = converywrite.Goodsstart.ToString(), TASK_EDITUSERNO = "WCS", TASK_EDITDATETIME = DateTime.Now }) .Where(it => it.TASK_NO == task.TASK_NO).ExecuteCommand(); } } else { db.Updateable(it => new WCS_TASK() { TASK_WKSTATUS = (int)WkStatus.输送机执行, TASK_POSIDNEXT = converywrite.Goodsend.ToString(), //TASK_ITEM5 = converywrite.Goodsstart.ToString(), TASK_POSIDTO = converywrite.Srmno, TASK_SRMNO = converywrite.Srmno, TASK_EDITUSERNO = "WCS", TASK_EDITDATETIME = DateTime.Now }) .Where(it => it.TASK_NO == task.TASK_NO) .ExecuteCommand(); } string msg = string.Format("任务已下发给输送机[{0}]执行,起点地址[{1}]目标地址[{2}]", converywrite.ConveyorNo, converywrite.Goodsstart, converywrite.Goodsend); CommonData.AddWCS_TASK_DTL(db, task.TASK_NO, task.TASK_NO, task.TASK_POSIDCUR, converywrite.Goodsend.ToString(), msg); ConfirmTask(converySignal, converywrite); }); if (!string.IsNullOrWhiteSpace(result)) { throw new Exception(string.Format("任务[{0}]输送机[{1}]执行失败,原因:[{1}]", converywrite.Tasknum, converywrite.ConveyorNo, result)); } Log4netHelper.Logger_ProductLog.InfoFormat("任务[{0}]输送机[0]执行结束.", converywrite.Tasknum, converywrite.ConveyorNo); } } public string WriteInfoToConv(ConvSignal converySignal, WCSWriteToConveyorSignal converywrite,string cacheAreaName, bool isNotTask = false) { using (var mutex = new Mutex(false, cacheAreaName)) { string resultMsg = string.Empty; try { if (mutex.WaitOne(-1, false)) { var task = SugarBase.DB.Queryable().First(v=>v.TASK_NO== converywrite.Tasknum); string barcode = task == null ? string.Empty : task.TASK_BOXBARCODE; Current.WcsInterface.CoatingRoomTrafficControl(converywrite.ConveyorNo, "", barcode); WriteInfoToConv(converySignal, converywrite, isNotTask); } } catch (Exception ex) { resultMsg = ex.Message; } finally { mutex.ReleaseMutex(); } return resultMsg; } } public void WriteInfoToCv(ConvSignal converySignal, WCSWriteToConveyorSignal converywrite, bool isNotTask = false) { string cacheAreaName = converywrite.Tasknum.ToString(); var cacheInfo = SugarBase.DB.Queryable().First(v => v.Cache_ConvNo == converywrite.Goodsstart.ToString()); if (cacheInfo != null) { cacheAreaName = cacheInfo.Cache_AreaName; } string errorMsg = WriteInfoToConv(converySignal, converywrite, cacheAreaName, isNotTask); if (!string.IsNullOrWhiteSpace(errorMsg)) throw new Exception(errorMsg); } /// /// 提交任务 /// public virtual void ConfirmTask(ConvSignal converySignal, WCSWriteToConveyorSignal converywrite) { if (!converySignal.DB520_Confirm) { if (converywrite.Plc.WriteBits((ushort)converywrite.DBName, (uint)((converywrite.WriteStartAddress + 16) * 8 + 1), true)) { Log4netHelper.Logger_Info.InfoFormat(string.Format("任务[{0}]写入确认信号到输送线[{1}]成功!", converywrite.Tasknum, converywrite.ConveyorNo)); } else { throw new Exception(string.Format("任务[{0}]写入确认信号到输送线[{1}]失败!", converywrite.Tasknum, converywrite.ConveyorNo)); } } else { throw new Exception(string.Format("任务[{0}]写入确认信号到输送线[{1}]失败,因为该信号未清除。", converywrite.Tasknum, converywrite.ConveyorNo)); } } /// /// 写入任务信息 /// /// /// public virtual bool WriteTaskToBuffer(WCSWriteToConveyorSignal conv, bool isWriteConfirm = false) { List list = new List(); //写入任务号 list.AddRange(ExtendsUtil.UintToByte((uint)conv.Tasknum).ToList()); //var codes = Encoding.UTF8.GetBytes(conv.Goodscode); //货物条码 list.AddRange(ExtendsUtil.UintToByte((uint)conv.Goodscode).ToList()); //货物类型 list.AddRange(ExtendsUtil.UshortToByte((ushort)conv.Goodstype).ToList()); //货位尺寸 list.AddRange(ExtendsUtil.UshortToByte((ushort)conv.Goodssize).ToList()); //写入起点地址 list.AddRange(ExtendsUtil.UshortToByte((ushort)conv.Goodsstart).ToList()); //写入目标地址 list.AddRange(ExtendsUtil.UshortToByte((ushort)conv.Goodsend).ToList()); BitArray bit16 = new BitArray(16); if (isWriteConfirm) { bit16[9] = conv.Confirm; } if (conv.Remark == conv.Goodsend.ToString()) { bit16[0] = conv.TrayColor_Three; bit16[14] = conv.TrayColor_One; bit16[15] = conv.TrayColor_Two; } bit16[5] = conv.UpMatRequest; bit16[6] = conv.Res01; bit16[7] = conv.Res02; bit16[10] = conv.TaskDelete;//删除任务 bit16[11] = conv.Notask; int BitInfo = ExtendsUtil.BitToInt(bit16); list.AddRange(ExtendsUtil.UshortToByte((ushort)BitInfo).ToList()); if (conv.TASK_WEIGHT > 0)//1390获取重量值 { list.AddRange(ExtendsUtil.UintToByte((uint)conv.TASK_WEIGHT).ToList()); } else { list.AddRange(ExtendsUtil.UshortToByte((ushort)conv.Res03).ToList()); } if (conv.Plc.Write((ushort)conv.DBName, (ushort)(conv.WriteStartAddress), list.ToArray())) { Log4netHelper.Logger_Info.InfoFormat(string.Format("输送机[{0}]写入任务[{1}]信息成功。", conv.Goodsstart, conv.Tasknum)); return true; } else { throw new Exception(string.Format("输送机[{0}]写入任务[{1}]信息失败。", conv.Goodsstart, conv.Tasknum)); } } /// /// 输送线任务完成 /// /// Plc /// 输送线出口 /// 是否检测当前地址和任务目标地址一致 /// 是否删除输送线任务 public virtual void ConveyorTaskFinish(string plcName, string convNo, bool isCheckEndPos = true, bool isTaskDelete = false) { try { var plc = Current.PlcSet.FirstOrDefault(v => v.PLC_NAME == plcName); var conveyorTo = plc.WCS_EquipmentInfoSet.FirstOrDefault(v => v.Equ_No == convNo); var cs = conveyorTo.EquSignal_Conv; if (cs.DB521_Tasknum > 0) { //调用函数完成任务 string result = TryCachHelper.TryExecute((db) => { WCS_TASK taskcur = db.Queryable().First(v => v.TASK_NO == cs.DB521_Tasknum && v.TASK_WKSTATUS < 99); if (taskcur == null) return; if (isCheckEndPos) { if (taskcur.TASK_COMTYPE != 6 && taskcur.TASK_POSIDTO != convNo) return; } //任务类型不是出库/搬运/移动类型 if (taskcur.TASK_COMTYPE != 2 && taskcur.TASK_COMTYPE != 4 && taskcur.TASK_COMTYPE != 5) return; //修改任务的状态 db.Updateable(it => new WCS_TASK() { TASK_WKSTATUS = 99, TASK_EDITUSERNO = "WCS", TASK_EDITDATETIME = DateTime.Now }) .Where(it => it.TASK_NO == taskcur.TASK_NO) .ExecuteCommand(); }); if (!string.IsNullOrWhiteSpace(result)) { throw new Exception(result); } if (isTaskDelete) { if (cs.DB521_Tasknum > 0 && cs.DB523_Fault == false && cs.CvDB51_PH_Status == false //&& cs.DB521_Goodsend == Convert.ToInt32(convNo) && cs.DB521_Request) { var converywrite = new WCSWriteToConveyorSignal(); converywrite.Plc = plc.Plc; converywrite.DBName = plc.WriteDBName; converywrite.ConveyorNo = convNo; converywrite.WriteStartAddress = cs.EquDbInfo_ReadWrite.DBReadIndox; converywrite.TaskDelete = true; WriteInfoToConv(cs, converywrite, true); } } } } catch (Exception ex) { LogMessageHelper.RecordLogMessage(ex); } } public string TranslationBarCode(string barCode) { var arr = barCode.Split('}'); return arr[10]; } public virtual void ConveyorWriteTaskExecute(string convNo, bool endPosIsCurConv = false) { try { var equ_conv = WCS_PLCItem.WCS_EquipmentInfoSet.FirstOrDefault(v => v.Equ_No == convNo).EquSignal_Conv; if (equ_conv.DB523_Fault) return; if (!equ_conv.CvDB51_PH_Status) return; if (!equ_conv.DB521_Request) return; if (equ_conv.DB521_Tasknum <= 0) return; var task = SugarBase.DB.Queryable().First(v => v.TASK_NO == equ_conv.DB521_Tasknum); if (task==null || task.TASK_POSIDNEXT != convNo) return; if (task.TASK_WKSTATUS == 7 || task.TASK_WKSTATUS == 3 || task.TASK_WKSTATUS == 4) return; if (equ_conv.DB521_H_Outside) { if (task.TASK_POSIDTO == srm) return; } if (convNo == "1072") { //检查是否绑定了第二个原膜卷 if (string.IsNullOrWhiteSpace(task.TASK_ITEM6)) { throw new Exception(string.Format("出库任务[{0}]未绑定原膜第二卷", task.TASK_NO)); } } int goodsend = 0; if (endPosIsCurConv) { goodsend = Convert.ToInt32(convNo); } else { var routeSet = EquRouteHelper.QueryRoute(convNo, task.TASK_POSIDTO); var routes = routeSet.Where(v => v.ROUTE_STARTPOS == convNo).ToList(); if (routes.Count == 1) { goodsend = Convert.ToInt32(routes[0].ROUTE_SONPOS); } else { goodsend = ConveyorWriteTaskExecuteToMoreAddress(convNo, task, routes); } } if (goodsend == 0) return; var convwrite = new WCSWriteToConveyorSignal() { Plc = WCS_PLCItem.Plc, DBName = WCS_PLCItem.WriteDBName, ConveyorNo = convNo, WriteStartAddress = equ_conv.EquDbInfo_ReadWrite.DBReadIndox, Tasknum = task.TASK_NO, Goodscode = 0,//待定 Goodstype = 0, Goodssize = 0,//待定 Goodsstart = Convert.ToInt32(convNo), Goodsend = goodsend }; SetConvwrite(convwrite,task); WriteInfoToConv(equ_conv, convwrite); } catch (Exception ex) { LogMessageHelper.RecordLogMessage(ex); } } /// /// 多个地址 /// /// /// public virtual int ConveyorWriteTaskExecuteToMoreAddress(string convNo,WCS_TASK task,List routes) { throw new Exception(string.Format("该函数不支持多个分支输送地址,请编写扩展接口。")); } public virtual void SetConvwrite(WCSWriteToConveyorSignal convwrite,WCS_TASK task) { } /// /// 扫描通用方法 /// /// 扫描位置输送线 /// 扫描异常退回输送线(为空则不能退回) /// 任务目标地址(为空则查询路由表) protected virtual void Conv_ScanningRequest(string convPosFrom, string warehouseid, string exitNo="",string convPosTo="") { try { var plc = Current.PlcSet.FirstOrDefault(v => v.PLC_NAME == PlcName); var conveyor = plc.WCS_EquipmentInfoSet.FirstOrDefault(v => v.Equ_No == convPosFrom); var cs = conveyor.EquSignal_Conv; if (!cs.DB521_Request) return; if (cs.DB520_Confirm) return; string barcode = cs.BarCodeStr; WCS_TASK task = null; if (convPosFrom == "1004") { var conveyor01 = plc.WCS_EquipmentInfoSet.FirstOrDefault(v => v.Equ_No == exitNo); var cs01 = conveyor01.EquSignal_Conv; task = QueryTaskByBarcode(cs01, convPosFrom); barcode = TranslationBarCode(cs01.BarCodeStr); } else { task = QueryTaskByBarcode(cs, convPosFrom); } if (task == null) { if (WcsScanConvIsUsed(exitNo)) { var param = new GetInTaskParam(); param.ContainerBarCode = barcode; param.ContainerType = 1; param.MatBarCode = string.Empty; param.WareHouseId = warehouseid; param.EquipmentNo = convPosFrom; param.EndPostion = srm; param.Memo2 = exitNo; task = ScanningCallWmsInterface(param); } } if (task == null) return; var converywrite = new WCSWriteToConveyorSignal(); converywrite.Plc = plc.Plc; converywrite.DBName = plc.WriteDBName; converywrite.ConveyorNo = convPosFrom; converywrite.WriteStartAddress = cs.EquDbInfo_ReadWrite.DBReadIndox; converywrite.Tasknum = task.TASK_NO; converywrite.Goodstype = 1; converywrite.Goodssize = 0;// converywrite.Goodsstart = Convert.ToInt32(convPosFrom); //判断任务是否已经执行 if (task.TASK_WKSTATUS >= 2) return; if (task.TASK_COMTYPE == (int)ComTypeEnum.托盘异常退回) { converywrite.Notask = true; converywrite.Goodsend = Convert.ToInt32(exitNo); } else { if (string.IsNullOrWhiteSpace(convPosTo)) { var routeSet = EquRouteHelper.QueryRoute(convPosFrom, task.TASK_POSIDTO); var routes = routeSet.Where(v => v.ROUTE_STARTPOS == convPosFrom).ToList(); if (routes.Count() == 0) { throw new Exception(string.Format("输送线扫描位置[{0}]任务[{1}]查询路由失败。", convPosFrom, task.TASK_NO)); } else if (routes.Count() == 1) { converywrite.Goodsend = Convert.ToInt32(routes.First().ROUTE_SONPOS); } else { converywrite.Goodsend = QueryTaskPosTo(task, convPosFrom); } } else { converywrite.Goodsend = Convert.ToInt32(convPosTo); } } WriteInfoToConv(cs, converywrite); } catch (Exception ex) { BaseWorkflow.AddLedErrorMsg(convPosFrom, ex.Message, 0); LogMessageHelper.RecordLogMessage(ex); } } protected virtual WCS_TASK ScanningCallWmsInterface(GetInTaskParam param) { return ThreadHelper.TaskThread(BaseWorkflow.GetWcsInTask, param, 3000); } protected virtual WCS_TASK ScanningCallWmsInterface(string barcode,string convPosFrom,string exitNo, string convPosTo) { var param = new GetInTaskParam() { ContainerBarCode = barcode, ContainerType = 1, MatBarCode = string.Empty, WareHouseId = Current.Pvchouseputong, EquipmentNo = convPosFrom, EndPostion = srm, Memo2 = exitNo }; return ThreadHelper.TaskThread(BaseWorkflow.GetWcsInTask, param); } protected virtual int QueryTaskPosTo(WCS_TASK task,string convPosFrom) { throw new Exception(string.Format("扫描任务[{0}]有多个目标地址需要编写扩展函数。", task.TASK_NO)); } protected WCS_TASK QueryTaskByBarcode(ConvSignal cs, string convNo) { if (cs.DB521_BCR_Noread) throw new Exception(string.Format("输送线[{0}]报读码错误,但是存在请求。", convNo)); if (string.IsNullOrWhiteSpace(cs.BarCodeStr)) throw new Exception(string.Format("输送线[{0}]存在请求信号,但没读取到条码信息。", convNo)); if (cs.BarCodeStr.ToUpper().Contains("ERROR") || cs.BarCodeStr.ToUpper().Contains("N") || cs.BarCodeStr.Contains("?")) { throw new Exception(string.Format("输送线[{0}]存在请求信号,但条码是:[{1}]存在报错,PLC应该报条码错误信号", convNo, cs.BarCodeStr)); } string code = cs.BarCodeStr; if (convNo == "1004") { code = TranslationBarCode(cs.BarCodeStr); } WCS_TASK task = null; var tasks = SugarBase.DB.Queryable().Where(v => v.TASK_BOXBARCODE == code && v.TASK_COMTYPE == 6).ToList(); foreach (var item in tasks) { if (item.TASK_WKSTATUS == 2) { int updateResult = SugarBase.DB.Updateable(it => new WCS_TASK() { TASK_WKSTATUS = 99, TASK_EDITUSERNO = "wcs", TASK_EDITDATETIME = DateTime.Now }) .Where(it => it.TASK_NO == item.TASK_NO) .ExecuteCommand(); if (updateResult <= 0) { throw new Exception(string.Format("异常任务[{0}]结束失败。", item.TASK_NO)); } } else { task = item; } } if (task == null) { task = SugarBase.DB.Queryable().Single(v => v.TASK_BOXBARCODE == code && v.TASK_COMTYPE != 6); } return task; } public bool WcsScanConvIsUsed(string convPosFrom) { var wcsScanConv = Current.WCS_ScanSet.Single(v => v.SCANN_STATIONNO == convPosFrom); if (wcsScanConv == null) return true; return wcsScanConv.SCANN_ISUSED; } public class WCSWriteToConveyorSignal { public PLC Plc; /// /// DB名称 /// public int DBName; /// /// 输送线编号 /// public string ConveyorNo; /// /// 写入信号起始地址 /// public int WriteStartAddress; /// /// 任务类型 1放货、2取货、3码盘、4拆盘 、5取托盘组、6送托盘组 /// public int TaskType; /// /// AGV任务号 /// public string AgvTasknum; /// /// 入库分配的堆垛机编号 /// public string Srmno; public string Remark; public string Remark_TaskNo; public int TASK_WEIGHT; public bool isClearPalletizingPos = false; #region 写入PLC的WCS信息 /// /// 任务号 /// public int Tasknum; /// /// 货物条码 /// public int Goodscode; /// /// 货物类型(1.熟化架 2.原膜托盘) /// public int Goodstype; /// /// 货物尺寸 /// public int Goodssize; /// /// 起始地址 /// public int Goodsstart; /// /// 目标地址 /// public int Goodsend; /// /// WCS确认信号 /// public bool Confirm; /// /// 任务删除 /// public bool TaskDelete; /// /// 上位未分配任务 /// public bool Notask; /// /// 子托盘颜色1 /// public bool TrayColor_One; /// /// 子托盘颜色2 /// public bool TrayColor_Two; /// /// 子托盘颜色3 /// public bool TrayColor_Three; /// /// 备用(放货请求) /// public bool UpMatRequest; /// /// 备用(放货完成) /// public bool Res01; /// /// 备用(取货请求) /// public bool Res02; /// /// 备用(取货完成) /// public int Res03; /// /// 备用 /// public int Res04; #endregion; } } }