using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using WCS.Data;
using WCS.Data.Models;
using WCS.Data.Utils;
using WCS.PLC.Model.Equipment;
namespace WCS.PLC
{
public class Base_SingleRgv3 : Base_Rgv
{
#region Constructor
public Base_SingleRgv3() : base() { }
#endregion;
#region property
//工位编号
protected string RgvPos { get; set; }
///
/// RGV上料点列表
///
protected override List RGVOnPosList
{
get
{
var _onPosList = RGVOnUpPosList.Where(v => v.RGVOUTIN_ISSTOP == false && (v.RGVOUTIN_OUTINTYPE == "OnMat" || v.RGVOUTIN_OUTINTYPE == "OnUpMat")).OrderBy(v => v.LastOnMatTime).ToList();
return _onPosList;
}
}
///
/// RGV下料点列表
///
protected override List RGVUpPosList
{
get
{
var _upPosList = RGVOnUpPosList.Where(v => v.RGVOUTIN_ISSTOP == false && (v.RGVOUTIN_OUTINTYPE == "UpMat" || v.RGVOUTIN_OUTINTYPE == "OnUpMat")).OrderBy(v => v.LastUpMatTime).ToList();
return _upPosList;
}
}
#endregion;
#region Method
private int _locRgvExecute = 0;
public override void Run()
{
if (Interlocked.Exchange(ref _locRgvExecute, 1) == 0)
{
try
{
RgvExecute();
}
catch (Exception ex)
{
string errormsg = string.Format("Rgv[{0}]执行异常,消息:{1}", PlcName, ex.ToString());
LogMessageHelper.RecordLogMessage(errormsg, ex);
}
finally
{
Interlocked.Exchange(ref _locRgvExecute, 0);
}
}
}
internal void RgvExecute()
{
//RGV完成任务
Rgv_Finish();
//上下料
OnUpMateriel();
//其它功能
Rgv_OtherExtend();
}
internal void Rgv_Finish()
{
if (Rgv.DB521_Finish_1)
{
var task = Current.TaskSet.FirstOrDefault(v => v.TASK_NO == Rgv.DB521_TaskID_1 && v.TASK_RGVNO == PlcName);
if (task != null)
{
task.TASK_RGVNO = "";
if (task.TASK_WKSTATUS == 7) task.TASK_WKSTATUS = (int)WkStatus.RGV完成;
string stratPos = Rgv.DB521_StartPosition_1.ToString();
string endPos = Rgv.DB521_DestPosition_1.ToString();
TryCachHelper.TryExecute((db) =>
{
string routeSet = task.TASK_POSIDNEXT;
if (task.TASK_POSIDNEXT == "1196")
routeSet = "1199";
db.Updateable(it => new WCS_TASK() { TASK_WKSTATUS = task.TASK_WKSTATUS, TASK_POSIDCUR = task.TASK_POSIDNEXT, TASK_POSIDNEXT = routeSet, TASK_RGVNO = "", TASK_EDITUSERNO = "WCS", TASK_EDITDATETIME = DateTime.Now })
.Where(it => it.TASK_NO == task.TASK_NO)
.ExecuteCommand();
DateTime dt = SugarBase.DB.GetDate();
db.Updateable(it => new WCS_RGVOutInInfo() { LastOnMatTime = dt })
.Where(it => it.RGVOUTIN_CONVNO == stratPos).ExecuteCommand();
db.Updateable(it => new WCS_RGVOutInInfo() { LastUpMatTime = dt })
.Where(it => it.RGVOUTIN_CONVNO == endPos).ExecuteCommand();
DateTime lastfinishtime = db.GetDate();
//更新最后完成时间
db.Updateable(it => new WCS_PLC() { PLC_LASTFINISHTIME = lastfinishtime }).Where(it => it.PLC_NAME == PlcName).ExecuteCommand();
});
}
}
}
internal void OnUpMateriel()
{
if (string.IsNullOrWhiteSpace(PlcName)) return;
if (Rgv.DB521_SystemStatus != 1) return;
if (Rgv.DB521_WorkMode != 1) return;
if (!Rgv.DB521_Finish_1) return;
if (Rgv.DB521_PH_Status_1) return;
if (Rgv.DB520_Trigger_1 == 1) return;
//是否存在执行的任务
if (SugarBase.DB.Queryable().Any(v => v.TASK_RGVNO == PlcName)) return;
if (WaitExecTask.IsNotEmpty())
{
try
{
var taskitem = SugarBase.DB.Queryable().First(v => v.TASK_NO == WaitExecTask.WaitExecTaskNo &&
(v.TASK_POSIDNEXT != WaitExecTask.WaitExecUpMatPosNo) &&
(v.TASK_POSIDCUR == WaitExecTask.WaitExecOnMatPosNo));
if (taskitem == null)
{
WaitExecTask.Clear();
}
else
{
var rgvwrite = new WCSWriteToRgvSignal()
{
Plc = RgvPlc,
RgvPos = RgvPosEnum.一号工位,
DBName = WCS_PLCItem.WCS_DBSet.FirstOrDefault(v => v.DB_TypeCh == DB_TypeEnum.WCS可读可写DB).DB_NAME,
RgvNo = PlcName,
WriteStartAddress = Rgv.EquDbInfo_ReadWrite.DBReadIndox,
Tasknum = taskitem.TASK_NO,
StartPosition = Convert.ToInt32(WaitExecTask.WaitExecOnMatPosNo),
DestPosition = Convert.ToInt32(WaitExecTask.WaitExecUpMatPosNo)
};
Log4netHelper.Logger_Info.InfoFormat("存在预执行任务[{0}]直接执行", taskitem.TASK_NO);
WriteTask(rgvwrite);
}
}
catch (Exception ex)
{
WaitExecTask.Clear();
LogMessageHelper.RecordLogMessage(ex);
}
return;
}
foreach (var item in RGVOnPosList)
{
try
{
var conv = ConveyorHelper.GetConveyorSignal(item.PLCNAME, item.RGVOUTIN_CONVNO);
if (conv.DB521_Tasknum <= 0) continue;
var task = SugarBase.DB.Queryable().Single(v => v.TASK_POSIDCUR == item.RGVOUTIN_CONVNO && conv.DB521_Tasknum == v.TASK_NO);
if (task == null || task.TASK_WKSTATUS != (int)WkStatus.输送机执行) continue;
//查询任务下料点列表
var routeSet = EquRouteHelper.QueryRoute(item.RGVOUTIN_CONVNO, task.TASK_POSIDTO)
.Where(v => v.ROUTE_STARTPOS == item.RGVOUTIN_CONVNO)
.Select(t => t.ROUTE_SONPOS).ToList();
if (routeSet.Count() == 0)
{
if (task.TASK_POSIDFROM == "1094" || task.TASK_POSIDFROM == "Pvc_4_Full01" || task.TASK_POSIDFROM == "Pvc_4_Full02" || task.TASK_POSIDFROM == "Pvc_4_Back")
{
routeSet.Add("1120");
}
else
{
LogMessageHelper.RecordLogMessage(string.Format("任务[{0}]当前地址[{1}]目标地址[{2}]未查询到路由地址。", task.TASK_NO, item.RGVOUTIN_CONVNO, task.TASK_POSIDTO));
continue;
}
}
if (!CheckOnTaskToPos(task, item.RGVOUTIN_CONVNO)) continue;
var rgvUpPosList = QueryRgvUpPosList(item.RGVOUTIN_CONVNO);
rgvUpPosList = rgvUpPosList.Where(v => routeSet.Any(t => t.Contains(v.RGVOUTIN_CONVNO))).ToList();
if (rgvUpPosList.Any(v => v.SrmTunnelNo <= 0) == false && task.TASK_POSIDTO == srm)
{
if (string.IsNullOrWhiteSpace(task.TASK_ITEM7) || task.TASK_ITEM7 == "0")
{
//预分配堆垛机巷道
ThreadHelper.TaskThread(BaseWorkflow.PreparatoryAssignSrmTunnel, task, 2000);
}
if (string.IsNullOrWhiteSpace(task.TASK_ITEM7))
{
rgvUpPosList = new List();//清零
}
else
{
//根据巷道预分配调整下料口顺序
var srmTunnelList = task.TASK_ITEM7.Split(',');
var rgvUpPosSet = rgvUpPosList.Where(v => srmTunnelList.Contains(v.SrmTunnelNo.ToString())).ToList();
var rgvUpPosList_temp = new List();
srmTunnelList.ToList().ForEach(v => rgvUpPosList_temp.Add(rgvUpPosSet.First(t => t.SrmTunnelNo.ToString() == v)));
rgvUpPosList = rgvUpPosList_temp;
}
}
string upPosConvNo = string.Empty;
//检测下料位置是否可用
foreach (var upItem in rgvUpPosList)
{
var upConv = ConveyorHelper.GetConveyorSignal(upItem.PLCNAME, upItem.RGVOUTIN_CONVNO);
if (upConv.CvDB51_PH_Status == false && upConv.DB521_Tasknum == 0 && upConv.DB521_Request == false || (upItem.IsCheckUpMatPos == false))
{
if (SugarBase.DB.Queryable().Any(v => v.TASK_POSIDCUR == upItem.RGVOUTIN_CONVNO && v.TASK_POSIDNEXT == upItem.RGVOUTIN_CONVNO) && upItem.IsCheckUpMatPos)
{
LogMessageHelper.RecordLogMessage(string.Format("穿梭车[{0}]下料位置[{1}]PLC无光电和任务号但WCS存在任务。", PlcName, upItem.RGVOUTIN_CONVNO));
}
else
{
if (CheckUpTaskToPos(task, upItem.RGVOUTIN_CONVNO))
{
if (!string.IsNullOrWhiteSpace(task.TASK_ITEM7))
{
var srminitem = Current.WCS_SrmOutInInfoSet.FirstOrDefault(v => v.SRMOUTIN_CONVNO == upItem.RGVOUTIN_CONVNO);
//任务分配巷道
var result = TryCachHelper.TryExecute((db) =>
{
db.Updateable(it => new WCS_TASK()
{
TASK_EndTunnelNum = upItem.SrmTunnelNo.ToString(),
TASK_POSIDTO = srminitem.SRMOUTIN_SRMNO,
TASK_SRMNO = srminitem.SRMOUTIN_SRMNO,
TASK_EDITUSERNO = "WCS",
TASK_EDITDATETIME = DateTime.Now
})
.Where(it => it.TASK_NO == task.TASK_NO)
.ExecuteCommand();
});
if (!string.IsNullOrWhiteSpace(result))
{
throw new Exception(string.Format("WMS任务[{0}]分配巷道更新任务失败,原因[{1}]", task.TASK_WMSNO, result));
}
}
upPosConvNo = upItem.RGVOUTIN_CONVNO;
break;
}
}
}
}
if (string.IsNullOrWhiteSpace(upPosConvNo)) continue;
var rgvwrite = new WCSWriteToRgvSignal();
rgvwrite.Plc = RgvPlc;
rgvwrite.RgvPos = RgvPosEnum.一号工位;
rgvwrite.DBName = WCS_PLCItem.WCS_DBSet.FirstOrDefault(v => v.DB_TypeCh == DB_TypeEnum.WCS可读可写DB).DB_NAME;
rgvwrite.RgvNo = PlcName;
rgvwrite.WriteStartAddress = Rgv.EquDbInfo_ReadWrite.DBReadIndox;
rgvwrite.Tasknum = task.TASK_NO;
rgvwrite.StartPosition = Convert.ToInt32(item.RGVOUTIN_CONVNO);
rgvwrite.DestPosition = Convert.ToInt32(upPosConvNo);
Log4netHelper.Logger_ProductLog.InfoFormat("不存在预执行任务[{0}]先写入信息", task.TASK_NO);
WriteTask(rgvwrite);
if (WaitExecTask.IsNotEmpty()) break;
}
catch (Exception ex)
{
LogMessageHelper.RecordLogMessage(ex);
}
}
}
protected override void UpdateRgvTaskStatus(SqlSugarClient db, WCSWriteToRgvSignal rgvwrite)
{
var task = Current.TaskSet.First(t => t.TASK_NO == rgvwrite.Tasknum);
string msg = string.Empty;
if (rgvwrite.TaskType == 3)
{
//移动
db.Updateable(it => new WCS_TASK() { TASK_WKSTATUS = (int)WkStatus.RGV移动, TASK_RGVNO = PlcName, TASK_ITEM4 = rgvwrite.StartPosition.ToString(), TASK_POSIDNEXT = rgvwrite.DestPosition.ToString(), TASK_EDITUSERNO = "WCS", TASK_EDITDATETIME = DateTime.Now })
.Where(it => it.TASK_NO == task.TASK_NO)
.ExecuteCommand();
msg = string.Format("穿梭车[{0}]开始执行移动任务[{1}]起始点[{2}]终点[{3}]", rgvwrite.RgvNo, rgvwrite.Tasknum, rgvwrite.StartPosition, rgvwrite.DestPosition);
}
else
{
db.Updateable(it => new WCS_TASK() { TASK_WKSTATUS = (int)WkStatus.RGV执行中, TASK_RGVNO = PlcName, TASK_ITEM4 = rgvwrite.StartPosition.ToString(), TASK_POSIDNEXT = rgvwrite.DestPosition.ToString(), TASK_EDITUSERNO = "WCS", TASK_EDITDATETIME = DateTime.Now })
.Where(it => it.TASK_NO == task.TASK_NO)
.ExecuteCommand();
msg = string.Format("穿梭车[{0}]开始执行上下料任务[{1}]上料点[{2}]下料点[{3}]", rgvwrite.RgvNo, rgvwrite.Tasknum, rgvwrite.StartPosition, rgvwrite.DestPosition);
}
if (!string.IsNullOrWhiteSpace(msg))
{
CommonData.AddWCS_TASK_DTL(db, task.TASK_NO, task.TASK_NO, task.TASK_POSIDCUR, rgvwrite.DestPosition.ToString(), msg);
}
}
///
/// 查询RGV下料列表(就近原则)
///
protected List QueryRgvUpPosList(string onPosConvNo)
{
var tempList = Current.WCS_RGVOutInInfoSet.Where(v => v.RGVOUTIN_ISSTOP == false && v.RGVOUTIN_RGVNO == PlcName && (v.RGVOUTIN_OUTINTYPE == "UpMat" || v.RGVOUTIN_OUTINTYPE == "OnUpMat")).ToList();
var curItem = RGVOnPosList.FirstOrDefault(v => v.RGVOUTIN_CONVNO == onPosConvNo);
if (curItem != null)
{
foreach (var item in tempList)
{
int difference = item.RGVOUTIN_SEQUENCE - curItem.RGVOUTIN_SEQUENCE;
item.RGVCURRENT_SEQUENCE = Math.Abs(difference);
}
}
return tempList.OrderBy(v => v.RGVCURRENT_SEQUENCE).ToList();
}
protected virtual bool CheckOnTaskToPos(WCS_TASK task, string onPosConvNo) { return true; }
protected virtual bool CheckUpTaskToPos(WCS_TASK task, string upPosConvNo) { return true; }
protected virtual void Rgv_OtherExtend() { }
#endregion;
}
}