public bool WriteInt16(string startAddr, short sData) { OperateResult write = m_plc.Write(startAddr, sData); IsConnected = write.IsSuccess; return(IsConnected); }
/// <summary> /// 翻转请求处理 /// </summary> /// <param name="machine"></param> /// <param name="flipFlag"></param> /// <param name="plc"></param> /// <returns></returns> protected BllResult SendFlipToPlc(Equipment machine, IPLC plc, FlipFlag wcsAllowFlip) { var WCSAllowFlip = machine.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == MachineProps.WCSAllowFlip.ToString()); WCSAllowFlip.Value = wcsAllowFlip.GetIndexString(); BllResult plcResult = plc.Write(WCSAllowFlip); return(plcResult); }
/// <summary> /// 打标请求处理 /// </summary> /// <param name="machine"></param> /// <param name="flipFlag"></param> /// <param name="plc"></param> /// <returns></returns> protected BllResult SendPintToPlc(Equipment machine, IPLC plc, PrintFlag wcsPint) { var WCSPint = machine.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == MachineProps.WCSPint.ToString()); WCSPint.Value = wcsPint.GetIndexString(); BllResult plcResult = plc.Write(WCSPint); return(plcResult); }
/// <summary> /// 写入或清除 上料完成 /// </summary> /// <param name="plc"></param> /// <param name="robot"></param> /// <param name="arrive">是否到达,true为到达,false为清除</param> /// <param name="result"></param> /// <returns></returns> protected BllResult SendArriveToPlc(IPLC plc, Equipment machineTool, bool arrive) { var operate = arrive ? "写入" : "清除"; var WCS_Allow_Load = machineTool.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == EcsToMachineToolPorps.WCS_Allow_Load.ToString()); WCS_Allow_Load.Value = arrive.ToString(); BllResult plcResult = plc.Write(WCS_Allow_Load); if (plcResult.Success) { Logger.Log($"{operate}设备【{machineTool.Name}】 ECS确认上料完成 信号成功", LogLevel.Success); } else { Logger.Log($"{operate}设备【{machineTool.Name}】 ECS确认上料完成 信号失败,写入PLC失败:原因:{plcResult.Msg}", LogLevel.Error); } return(plcResult); }
/// <summary> /// 写入或清除 ECS允许下料信号,True为写入,False为清除 /// </summary> /// <param name="plc"></param> /// <param name="robot"></param> /// <param name="result"></param> /// <returns></returns> protected BllResult SendBlankReadyToPlc(bool blank_Ready, Equipment robot, IPLC plc) { var operate = blank_Ready ? "写入" : "清除"; var Blank_Ready = robot.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == PcRobotStation.Blank_Ready.ToString()); Blank_Ready.Value = blank_Ready.ToString(); BllResult plcResult = plc.Write(Blank_Ready); if (plcResult.Success) { Logger.Log($"{operate}设备【{robot.Name}】下料准备完成 信号成功", LogLevel.Success); } else { Logger.Log($"{operate}设备【{robot.Name}】下料准备完成 信号失败,写入PLC失败:原因:{plcResult.Msg}", LogLevel.Error); } return(plcResult); }
/// <summary> /// 写入或清除 ECS允许焊接机器人翻转,True为写入,False为清除 /// </summary> /// <param name="plc"></param> /// <param name="robot">机器人</param> /// <param name="allow">是否允许翻转,true为允许,false为清除</param> /// <param name="result"></param> /// <returns></returns> protected BllResult SendFlipToPlc(bool allow, Equipment robot, IPLC plc) { var operate = allow ? "写入" : "清除"; var WCS_Allow_Flip = robot.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == PcRobotStation.WCS_Allow_Flip.ToString()); WCS_Allow_Flip.Value = allow.ToString(); BllResult plcResult = plc.Write(WCS_Allow_Flip); if (plcResult.Success) { Logger.Log($"{operate}设备【{robot.Name}】ECS允许翻转信号成功", LogLevel.Success); } else { Logger.Log($"{operate}设备【{robot.Name}】ECS允许翻转信号失败,写入PLC失败:原因:{plcResult.Msg}", LogLevel.Error); } return(plcResult); }
/// <summary> /// 写入或清除 ECS允许焊接机器人翻转,True为写入,False为清除 /// </summary> /// <param name="plc"></param> /// <param name="cutter">机器人</param> /// <param name="allow">是否允许翻转,true为允许,false为清除</param> /// <param name="result"></param> /// <returns></returns> protected BllResult SendCutToPlc(Equipment cutter, CutFlag cutFlag, IPLC plc) { var operate = cutFlag == CutFlag.默认 ? "清除" : "写入"; var WCS_Allow_Flip = cutter.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == MachineProps.WCSAllowFlip.ToString()); WCS_Allow_Flip.Value = cutFlag.ToString(); BllResult plcResult = plc.Write(WCS_Allow_Flip); if (plcResult.Success) { Logger.Log($"{operate}设备【{cutter.Name}】ECS允许翻转信号成功", LogLevel.Success); } else { Logger.Log($"{operate}设备【{cutter.Name}】ECS允许翻转信号失败,写入PLC失败:原因:{plcResult.Msg}", LogLevel.Error); } return(plcResult); }
/// <summary> /// 写入或清除 允许下料 /// </summary> /// <param name="plc"></param> /// <param name="bevel"></param> /// <param name="arrive">是否写入,true为写入,false为清除</param> /// <param name="result"></param> /// <returns></returns> protected BllResult SendRequestToPlc(IPLC plc, Equipment LengthMeasuringMachine, bool request) { var operate = request ? "写入" : "清除"; var WCS_Request_Blank = LengthMeasuringMachine.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == ECSToMeasuringMachineProps.WCS_Request_Blank.ToString()); WCS_Request_Blank.Value = request ? MachineMessageFlag.回复允许下料.GetIndexString() : MachineMessageFlag.默认.GetIndexString();; BllResult plcResult = plc.Write(WCS_Request_Blank); if (plcResult.Success) { Logger.Log($"{operate}设备【{LengthMeasuringMachine.Name}】 ECS确认下料 信号成功", LogLevel.Success); } else { Logger.Log($"{operate}设备【{LengthMeasuringMachine.Name}】 ECS确认下料 信号失败,写入PLC失败:原因:{plcResult.Msg}", LogLevel.Error); } return(plcResult); }
/// <summary> /// 处理到达信号 /// </summary> /// <param name="plc"></param> /// <param name="car"></param> /// <param name="v"></param> private BllResult ExcuteArrive(Equipment car, ArriveMessage arriveMessage, IPLC plc) { var operate = arriveMessage == ArriveMessage.回复到达 ? "写入" : "清除"; var replyArrive = car.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == ArriveMessage.回复到达.GetIndexString()); replyArrive.Value = arriveMessage.ToString(); BllResult plcResult = plc.Write(replyArrive); if (plcResult.Success) { Logger.Log($"{operate}设备[{car.Name}] ECS确认到达完成 信号成功", LogLevel.Success); } else { Logger.Log($"{operate}设备[{car.Name}] ECS确认到达完成 信号失败,写入PLC失败:原因:{plcResult.Msg}", LogLevel.Error); } return(plcResult); }
/// <summary> /// 写入或清除 ECS允许焊接机器人翻转,True为写入,False为清除 /// </summary> /// <param name="plc"></param> /// <param name="bevel">机器人</param> /// <param name="allow">是否允许翻转,true为允许,false为清除</param> /// <param name="result"></param> /// <returns></returns> protected BllResult SendFlipToPlc(Equipment bevel, bool allow, IPLC plc) { var operate = allow ? "写入" : "清除"; var status = allow ? FlipFlag.回复允许翻转.GetIndexString() : FlipFlag.默认.GetIndexString(); var WCS_Allow_Flip = bevel.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == MachineProps.WCSAllowFlip.ToString()); WCS_Allow_Flip.Value = status.ToString(); BllResult plcResult = plc.Write(WCS_Allow_Flip); if (plcResult.Success) { Logger.Log($"{operate}设备【{bevel.Name}】ECS允许翻转信号成功", LogLevel.Success); } else { Logger.Log($"{operate}设备【{bevel.Name}】ECS允许翻转信号失败,写入PLC失败:原因:{plcResult.Msg}", LogLevel.Error); } return(plcResult); }
/// <summary> /// 写入或清除 下料完成 /// </summary> /// <param name="plc"></param> /// <param name="cutter"></param> /// <param name="arrive">是否到达,true为到达,false为清除</param> /// <param name="result"></param> /// <returns></returns> protected BllResult SendRequestToPlc(IPLC plc, Equipment cutter, bool request) { var status = request ? StationMessageFlag.WCSPLCACK.GetIndexString() : StationMessageFlag.默认.GetIndexString(); var operate = request ? "写入" : "清除"; var WCSReplyMessage = cutter.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == MachineProps.WCSReplyMessage.ToString()); WCSReplyMessage.Value = status.ToString(); BllResult plcResult = plc.Write(WCSReplyMessage); if (plcResult.Success) { Logger.Log($"{operate}设备【{cutter.Name}】 ECS确认下料完成 信号成功", LogLevel.Success); } else { Logger.Log($"{operate}设备【{cutter.Name}】 ECS确认下料完成 信号失败,写入PLC失败:原因:{plcResult.Msg}", LogLevel.Error); } return(plcResult); }
/// <summary> /// 写入或清除 ECS允许下料信号,True为写入,False为清除 /// </summary> /// <param name="plc"></param> /// <param name="robot"></param> /// <param name="result"></param> /// <returns></returns> protected BllResult SendBlankReadyToPlc(bool blank_Ready, Equipment robot, IPLC plc) { var operate = blank_Ready ? "写入" : "清除"; var status = blank_Ready ? MachineMessageFlag.WCS回复允许下料.GetIndexString() : MachineMessageFlag.默认.GetIndexString(); var WCSReplyMessage = robot.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == MachineProps.WCSReplyMessage.ToString()); WCSReplyMessage.Value = status.ToString(); BllResult plcResult = plc.Write(WCSReplyMessage); if (plcResult.Success) { Logger.Log($"{operate}设备【{robot.Name}】下料准备完成 信号成功", LogLevel.Success); } else { Logger.Log($"{operate}设备【{robot.Name}】下料准备完成 信号失败,写入PLC失败:原因:{plcResult.Msg}", LogLevel.Error); } return(plcResult); }
/// <summary> /// 控制逻辑实现 /// </summary> /// <param name="srm"></param> /// <param name="plc"></param> /// <returns></returns> public BllResult ExcuteSingle(Equipment srm, List <Equipment> allEquipments, IPLC plc) { //联机、无故障 if (Validate(srm).Success) { #region 对于单叉堆垛机,判断这个货叉有误故障 if (srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.Fork1TotalError.ToString()).Value == "True") { //如果报有故障,则返回 return(BllResultFactory.Error("货叉1故障")); } #endregion #region 任务执行判断 if (srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.Fork1TaskExcuteStatus.ToString()).Value == SRMTaskExcuteStatus.任务执行中.GetIndexString()) { //任务执行中就return return(BllResultFactory.Sucess()); } if (srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.Fork1TaskExcuteStatus.ToString()).Value == SRMTaskExcuteStatus.任务中断_出错.GetIndexString()) { //由人工处理,一般为空出和重入 return(BllResultFactory.Sucess()); } if (srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.Fork1TaskExcuteStatus.ToString()).Value == SRMTaskExcuteStatus.发任务错误.GetIndexString()) { //由人工处理,需要重新下发任务 return(BllResultFactory.Sucess()); } #endregion #region 任务,货位和本巷道的其他设备 //找出所有未完成的任务 var tasksResult = AppSession.Dal.GetCommonModelByCondition <TaskEntity>($"where taskStatus < {TaskEntityStatus.任务完成.GetIndexInt()} " + $"and taskStatus>={TaskEntityStatus.下发任务.GetIndexInt()} and deleted = 0 and warehouseCode='{AppSession.WarehouseCode}'"); if (!tasksResult.Success) { //如果没有找到任务就直接返回 return(BllResultFactory.Error(tasksResult.Msg)); } //找出同巷道的库位,考虑到可能多个巷道移库,这里分别查询出所有库位和当前堆垛机所在巷道的库位 var locationsResult = AppSession.LocationService.GetAllLocations(null, null, null, null, null, null, null, srm.WarehouseCode); if (!locationsResult.Success) { return(BllResultFactory.Error(locationsResult.Msg)); } //所有库位 var allLocations = locationsResult.Data; //本巷道库位 var locationsRoadWay = allLocations.Where(t => t.RoadWay == srm.RoadWay).ToList(); //找出本巷道的所有设备 var equipmentsRoadWay = allEquipments.Where(t => t.RoadWay == srm.RoadWay && t.WarehouseCode == srm.WarehouseCode).ToList(); //可用的可出站台 //hack:注意,此处针对每个巷道均需要配置StationStatusMonitor!如果没有配置,则可出站台为空集合; var stationOutStatusMonitor = equipmentsRoadWay.Find(a => a.EquipmentType.Code == "StationStatusMonitor"); var availableOutStation = stationOutStatusMonitor == null ? new List <Equipment>() : equipmentsRoadWay.Where(t => t.EquipmentType.Code.Contains("Station") && stationOutStatusMonitor.EquipmentProps. Count(b => b.EquipmentTypeTemplateCode == t.StationIndex.ToString() && b.Value == StationTaskLimit.可出.GetIndexString()) > 0).ToList(); //hack:这里筛选本巷道或关联到本巷道的任务,规则为起始或目标库位,所以,当将来出现跨巷道移库时,需要特别处理跨巷道移库任务 var tasks = tasksResult.Data.Where(t => locationsRoadWay.Count(a => a.Code == t.FromLocationCode || a.Code == t.ToLocationCode) > 0).ToList(); //筛选任务,任务的前置任务如果存在,则其前置任务需要大于完成状态 tasks = tasks.Where(t => { if (t.PreTaskId != 0) { var tempResult = AppSession.Dal.GetCommonModelByCondition <TaskEntity>($"where id = {t.PreTaskId}"); if (tempResult.Success) { var innerTask = tempResult.Data[0]; if (innerTask.TaskStatus >= (int)TaskEntityStatus.任务完成) { return(true); } else { return(false); } } else { Logger.Log($"未找到任务{t.Id},远程任务号:{t.RemoteTaskNo}的前置远程任务:{t.PreRemoteTaskNo},前置内部任务号:{t.PreTaskId},该任务不允许执行。如果要执行,请取消其前置任务号", LogLevel.Warning); return(false); } } else { return(true); } }).ToList(); #endregion //堆垛机待机情况下 string Fork1TaskExecuteStatus = srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.Fork1TaskExcuteStatus.ToString()).Value; if (Fork1TaskExecuteStatus == SRMTaskExcuteStatus.待机.GetIndexString()) { //货叉任务待机时,可执行放和取任务,同时当执行完成时,交互后堆垛机会从任务完成更新为待机 //均判断put放货任务标志 //响应任务删除 string WcsFork1TaskFlag = srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.WCSPutFork1TaskFlag.ToString()).Value; if (WcsFork1TaskFlag == SRMForkTaskFlag.除任务.GetIndexString()) { return(ClearWCSDataS(srm, plc)); } //响应任务完成 string WcsTaskAccount = srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.WCSTaskCompleteFlag.ToString()).Value; if (WcsTaskAccount == SRMForkTaskFlag.任务完成.GetIndexString()) { return(ClearWCSDataS(srm, plc)); } //响应无任务且货叉在中心 else if (WcsFork1TaskFlag == SRMForkTaskFlag.无任务.GetIndexString() && srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.Fork1Center.ToString()).Value == "True") { //hack:单任务由人员手动处理,不重发 //获取需要下发给堆垛机的任务 if (srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.Fork1HasPallet.ToString()).Value == "True") { Logger.Log($"堆垛机{srm.Name}显示货叉上有货且无任务,状态错误", LogLevel.Error); return(BllResultFactory.Error()); } else { //判断任务限制情况 var tempTasks = tasks; //完全空闲的堆垛机实际只执行取货任务,则为库外取与库内取两种 //找出下发状态的待取的离堆垛机最近的任务,并且对应站台口需要可用 var task1s = tempTasks.Where(t => t.TaskStatus == TaskEntityStatus.发任务.GetIndexInt() && (t.TaskType == TaskType.出库查看.GetIndexInt() || t.TaskType == TaskType.分拣出库.GetIndexInt() || t.TaskType == TaskType.整盘出库.GetIndexInt() || t.TaskType == TaskType.盘点.GetIndexInt() || t.TaskType == TaskType.空容器出库.GetIndexInt() || t.TaskType == TaskType.补充入库.GetIndexInt() || t.TaskType == TaskType.移库.GetIndexInt()) && locationsRoadWay.Exists(a => a.Code == t.FromLocationCode)).ToList(); task1s.ForEach(t => { t.FromLocation = locationsRoadWay.Find(a => a.Code == t.FromLocationCode); t.ToLocation = allLocations.Find(a => a.Code == t.ToLocationCode); t.ToPortEquipment = equipmentsRoadWay.FirstOrDefault(a => a.Code == t.ToPort); }); //任务过滤条件,任务port对应的station要可用 task1s = task1s.Where(t => availableOutStation.Exists(a => AppSession.ExcuteService.GetOutStationByPort(srm.DestinationArea, t.ToPort, App.WarehouseCode).Data?.Exists(b => b.Code == a.Code) == true)).ToList(); //库内取货的任务 var task1 = task1s.OrderByDescending(t => t.Priority).ThenBy(t => Math.Abs((int)t.FromLocation.Line - CurrentColumn)).FirstOrDefault(); //本巷道接入口的任务 var task2s = tempTasks.Where(t => t.TaskStatus == TaskEntityStatus.响应接入站台到达.GetIndexInt() && equipmentsRoadWay.Exists(a => a.Code == t.Gateway)).ToList(); task2s.ForEach(t => { t.ArrivaEquipment = equipmentsRoadWay.Find(a => a.Code == t.Gateway); t.ToLocation = allLocations.Find(a => a.Code == t.ToLocationCode); }); //按优先级以及站台与现有堆垛机的距离优先做调度 var task2 = task2s.OrderByDescending(t => t.Priority).ThenBy(t => Math.Abs(t.ArrivaEquipment.ColumnIndex - CurrentColumn)).FirstOrDefault(); if (task1 == null && task2 == null) { //说明当前没有可以被执行的任务 return(BllResultFactory.Sucess()); } if (task2 != null) { //说明库外取货任务不为空,则下发接入任务 //库外取分为换站和其他,换站需要再放到库外,其他则放到库内 return(OutGet(srm, plc, availableOutStation, task2)); } if (task1 != null) { //说明库内取货任务不为空 //库内取分为两种,一种移到库外,一种重新到到库内另一个库位上 return(InGet(srm, plc, locationsRoadWay, availableOutStation, task1)); } //当两种任务均存在时,此处设置两种模式,出库优先与均衡模式(按堆垛机位置进行) var configResult = AppSession.BllService.GetAllConfig(); var config = configResult.Data?.FirstOrDefault(t => t.Code == ConfigStrings.OutFirst.ToString()); if (config == null || config.Value != "1") { //均衡模式 var dis1 = Math.Abs((int)task1.FromLocation.Line - CurrentColumn); var dis2 = Math.Abs(task2.ArrivaEquipment.RowIndex1 - CurrentColumn); if (dis1 <= dis2) { return(InGet(srm, plc, locationsRoadWay, availableOutStation, task1)); } else { return(OutGet(srm, plc, availableOutStation, task2)); } } else { //出库优先模式 return(OutGet(srm, plc, availableOutStation, task2)); } } } else { //hack:其他情况1-库内取货,2-库内放货,3-库外入库,4库外出库, 5重新分配入库地址,暂时不做处理,这里也应不需要处理这些情况 } } //当堆垛机有任务完成且wcs没有任务完成时,说明是堆垛机新发任务完成 else if (Fork1TaskExecuteStatus == SRMTaskExcuteStatus.任务完成.GetIndexString() && srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.WCSTaskCompleteFlag.ToString()).Value != SSRMTaskCompleteFlag.任务完成.GetIndexString()) { //todo:检查任务完成 //单叉单任务堆垛机只有2种情况会有完成信号 库外出库和库内放货 //根据任务号和货叉类型进行任务完成处理 int taskNo = int.Parse(srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.Fork1TaskNo.ToString()).Value); int forkType = int.Parse(srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.Fork1TaskType.ToString()).Value); //库内放货完成 if (forkType == SRMForkTaskFlag.库内放货.GetIndexInt()) { var task = tasks.FirstOrDefault(t => t.Id == taskNo); if (task != null) { if (!locationsRoadWay.Exists(a => a.Code == task.ToLocationCode)) { Logger.Log($"堆垛机{srm.Code},任务:{task.Id},去向库位:{task.ToLocationCode}不在本巷道中", LogLevel.Error); return(BllResultFactory.Error()); } var tempStatus = task.TaskStatus; task.TaskStatus = TaskEntityStatus.任务完成.GetIndexInt(); task.Updated = DateTime.Now; task.UpdatedBy = Accounts.WCS.ToString(); var tempResult = AppSession.Dal.UpdateCommonModel <TaskEntity>(task); if (tempResult.Success) { //标记交换区地址,任务完成10 var prop = srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.WCSTaskCompleteFlag.ToString()); prop.Value = SSRMTaskCompleteFlag.任务完成.GetIndexString(); var sendResult = plc.Write(prop); if (sendResult.Success) { Logger.Log($"堆垛机{srm.Name}完成库内放货成功,任务:{task.Id}", LogLevel.Success); return(BllResultFactory.Sucess()); } else { //回滚 task.TaskStatus = tempStatus; AppSession.Dal.UpdateCommonModel <TaskEntity>(task); Logger.Log($"堆垛机{srm.Name}完成库内放货失败,任务:{task.Id},原因:{sendResult.Msg}", LogLevel.Error); return(BllResultFactory.Error()); } } else { Logger.Log($"完成堆垛机{srm.Name}库内放货失败,任务{task.Id}请求WMS接口失败:{tempResult.Msg}", LogLevel.Error); return(BllResultFactory.Error($"完成堆垛机{srm.Name}库内放货失败,任务{task.Id}请求WMS接口失败:{tempResult.Msg}")); } } else { Logger.Log($"堆垛机{srm.Code}记录任务{task.Id}状态不对,请核查任务是否为本巷道任务,以及任务的状态{Enum.GetName(typeof(TaskEntityStatus), task.TaskStatus)}", LogLevel.Error); return(BllResultFactory.Error()); } } //库外放货完成时 else if (forkType == SRMForkTaskFlag.库外放货.GetIndexInt()) { var task = tasks.FirstOrDefault(t => t.Id == taskNo); if (task != null) { //更新任务状态 int preStatus = task.TaskStatus; task.TaskStatus = TaskEntityStatus.响应堆垛机库外放货完成.GetIndexInt(); task.Updated = DateTime.Now; task.UpdatedBy = Accounts.WCS.ToString(); var tempResult = AppSession.Dal.UpdateCommonModel <TaskEntity>(task); if (tempResult.Success) { //标记交换区地址,任务完成10 var prop = srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SSRMProps.WCSTaskCompleteFlag.ToString()); prop.Value = SSRMTaskCompleteFlag.任务完成.GetIndexString(); var sendResult = plc.Write(prop); if (sendResult.Success) { Logger.Log($"堆垛机{srm.Name}完成库外放货成功,任务:{task.Id}", LogLevel.Success); return(BllResultFactory.Sucess()); } else { Logger.Log($"堆垛机{srm.Name}完成库外放货失败,任务:{task.Id},原因:{sendResult.Msg}", LogLevel.Error); task.TaskStatus = preStatus; AppSession.Dal.UpdateCommonModel <TaskEntity>(task); return(BllResultFactory.Error()); } } else { Logger.Log($"完成堆垛机{srm.Name}库外放货时,更新任务{task.Id}状态失败:{tempResult.Msg}", LogLevel.Error); return(BllResultFactory.Error($"完成堆垛机{srm.Name}库外放货时,更新任务{task.Id}状态失败:{tempResult.Msg}")); } } else { Logger.Log($"堆垛机{srm.Code}记录任务{task.Id}状态不对,请核查任务是否为本巷道任务,以及任务的状态{Enum.GetName(typeof(TaskEntityStatus), task.TaskStatus)}", LogLevel.Error); return(BllResultFactory.Error()); } } //未知情况 Logger.Log($"堆垛机{srm.Name}的任务完成时候和系统对应的任务出现了异常:PLC:{taskNo}或 货叉的任务类型:{forkType} ", LogLevel.Warning); return(BllResultFactory.Error($"堆垛机{srm.Name}的任务完成时候和系统对应的任务出现了异常:PLC:{taskNo}或 货叉的任务类型:{forkType} ")); } else { //Logger.Log($"堆垛机{stocker.Name}的任务完成时候和系统对应的任务出现了异常:PLC:{taskNo}或 货叉的任务类型:{forkType} ", LogLevel.Warning); //未知情况 Logger.Log($"堆垛机{srm.Name}处理中,执行状态为:{srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == "Fork1TaskExcuteStatus").Value}", LogLevel.Warning); return(BllResultFactory.Sucess()); } } return(BllResultFactory.Sucess()); }
///// <summary> ///// 处理设备下料准备完成 ///// </summary> ///// <param name="robot"></param> ///// <param name="allEquipments"></param> ///// <param name="stepTraceList"></param> ///// <param name="plc"></param> ///// <returns></returns> //public override BllResult ExcuteBlankReady(Equipment robot, List<Equipment> allEquipments, List<StepTrace> stepTraceList, IPLC plc) //{ // return SendBlankReadyToPlc(true, robot, plc); //} /// <summary> /// 处理设备请求下线 /// </summary> /// <param name="robot"></param> /// <param name="allEquipments"></param> /// <param name="stepTraceList"></param> /// <param name="plc"></param> /// <returns></returns> public override BllResult ExcuteRequest(Equipment robot, List <Equipment> allEquipments, List <StepTrace> stepTraceList, IPLC plc) { try { var Step_Trace_Id = robot.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == MachineProps.RequestTaskId.ToString()); var convertResult = int.TryParse(Step_Trace_Id.Value, out int stepTraceId); if (!convertResult) { Logger.Log($"处理设备【{robot.Name}】下料请求失败,工序任务的id[{Step_Trace_Id.Value}]转化为整数失败!", LogLevel.Error); return(BllResultFactory.Error()); } if (stepTraceId > 0) { var stepTrace = stepTraceList.FirstOrDefault(t => t.Id == Convert.ToInt32(Step_Trace_Id.Value)); if (stepTrace != null) { if (stepTrace.Status == StepTraceStatus.设备开始生产.GetIndexInt()) { //修改工序跟踪 stepTrace.Status = StepTraceStatus.设备请求下料.GetIndexInt(); stepTrace.UpdateTime = DateTime.Now; stepTrace.UpdateBy = App.User.UserCode; var result = AppSession.Dal.UpdateCommonModel <StepTrace>(stepTrace); if (result.Success) { //回复允许下料 return(SendBlankReadyToPlc(true, robot, plc)); } return(BllResultFactory.Sucess()); } if (stepTrace.Status > StepTraceStatus.设备请求下料.GetIndexInt()) { var WCS_Step_Trace_Id = robot.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == MachineProps.WCSReplyTaskId.ToString()); WCS_Step_Trace_Id.Value = "0"; BllResult plcResult = plc.Write(WCS_Step_Trace_Id); if (plcResult.Success) { Logger.Log($"清除设备【{robot.Name}】的任务号{stepTrace.Id}成功", LogLevel.Success); return(BllResultFactory.Sucess()); } else { Logger.Log($"清除设备【{robot.Name}】的任务号{stepTrace.Id}失败,写入PLC失败:{plcResult.Msg}", LogLevel.Error); return(BllResultFactory.Error()); } } } else { Logger.Log($"处理设备【{robot.Name}】下料请求失败,找不到未完成的工序任务id[{Step_Trace_Id.Value}]", LogLevel.Error); return(BllResultFactory.Error()); } } else { // 如果不存在 已经处理过的任务,但是还在请求下线,说明是手动上的,或是id丢了 if (!stepTraceList.Exists(t => t.StationId == robot.StationId && t.Status >= StepTraceStatus.设备请求下料.GetIndexInt())) { Logger.Log($"处理设备[{robot.Name}]的站台[{robot.StationId}]下料请求失败,工序跟踪ID为0", LogLevel.Error); return(BllResultFactory.Error()); } } } catch (Exception ex) { Logger.Log($"处理设备【{robot.Name}】下料请求时候,发生异常:{ex.Message}", LogLevel.Exception, ex); return(BllResultFactory.Error()); } return(BllResultFactory.Sucess()); }
/// <summary> /// 写寄存器数据(高位在前,低位在后) /// </summary> /// <param name="plcAddr">PLC地址(TCP为0)</param> /// <param name="regType">寄存器类型</param> /// <param name="startAddr">开始地址</param> /// <param name="N">长度</param> /// <param name="strHex">16进制字符FFFF,反转处理:高在前,低位在后</param> /// <param name="er"></param> /// <returns></returns> public bool Write(int plcAddr, ERegType regType, int startAddr, int N, string strHex, out string er) { return(_devPLC.Write(plcAddr, regType, startAddr, N, strHex, out er)); }