XiangdianOutStationExcute.cs 21.9 KB
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HHECS.Model;
using HHECS.Bll;
using HHECS.OPC;
using S7.Net;

namespace HHECS.Common
{
    /// <summary>
    /// todo:湘电出库站台处理类
    /// </summary>
    public class XiangdianOutStationExcute : IStationExcute
    {
        public EquipmentType EquipmentType { get; set; }

        public BllResult Excute(List<Equipment> stations, List<Plc> plcs)
        {
            try
            {
                foreach(var station in stations)
                {
                    #region  出库站台的处理逻辑
                    //------------------------------------------出库站台的处理逻辑------------------------------------------------------
                    //step1: 查看是否有出库请求  
                    var requestMessage = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "RequestMessage");
                    var wcsReplyMessage = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplyMessage");
                    var requestNumber= station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "RequestNumber");//地址编码
                    if (requestMessage.Value == "1")
                    {
                        //step2: 判断是否已经处理  06表示处理
                        if (wcsReplyMessage.Value != "6")
                        {
                            //step3: 根据条码获取对应的任务类型、以及相应的任务状态
                            var tasksResult = AppSession.Bll.GetCommonModelByCondition<TaskEntity>($"where station={requestNumber.Value} and firstStatus = {(int)TaskEntityStatus.响应堆垛机库外放货任务完成}");
                            if (tasksResult.Success)
                            {
                                //step4: 回复PLC相关信息
                                TaskEntity taskEntity = tasksResult.Data[0];
                                if (taskEntity != null)
                                {
                                    List<EquipmentProp> propsToWriter = new List<EquipmentProp>();
                                    //回复PLC考虑标志位 放置最后 控制数据传递的完整性
                                    var number = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplyNumber");
                                    number.Value = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "RequestNumber").Value;//地址编码
                                    var loadStatus = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplayLoadStatus");
                                    loadStatus.Value = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "RequestLoadStatus").Value;//装载状态
                                    var barcode = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplayBarcode");
                                    barcode.Value = taskEntity.ContainerCode;//容器条码
                                    var weight = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplyWeight");
                                    weight.Value = "0";
                                    var length = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplyLength");
                                    length.Value = "0";//长
                                    var width = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplyWidth");
                                    width.Value = "0";//宽
                                    var height = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplyHeight");
                                    height.Value = "0";//高
                                    var address = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplyAddress");
                                    address.Value = taskEntity.Port.ToString();//目标地址
                                    var backup = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplyBackUp");
                                    backup.Value = "0";//备用
                                    var flag = wcsReplyMessage;
                                    flag.Value = "6";//报文名称
                                    propsToWriter.AddRange(new List<EquipmentProp>() { number, loadStatus, barcode, weight, length, width, height, address, backup, flag });
                                    //判断是那个对应plc
                                    Plc plc = plcs.FirstOrDefault(t => t.IP == station.IP);
                                    if (plc == null)
                                    {
                                        string errInfo = string.Format("出库站台:{0} 对应PLC的IP地址:{1}和系统传入的PLC列表进行IP匹配失败,请检查IP地址是否设置正确", station.Code, station.IP);
                                        Logger.Log(errInfo, LogLevel.Error);
                                        continue;
                                    }
                                    BllResult result = S7Helper.PlcSplitWrite(plc, propsToWriter, 20);
                                    if (result.Success)// 写入成功后更新任务状态为  
                                    {
                                        //todo: 后续更改
                                        taskEntity.FirstStatus = (int)TaskEntityStatus.响应接出口站台地址请求;
                                        BllResult bllResult = AppSession.Bll.UpdateCommonModel<TaskEntity>(taskEntity);
                                        if (bllResult.Success)
                                        {
                                            Logger.Log(String.Format("任务ID:{0} 到达出库站台:{1} 即将去向出入库口:{2}处理并更新任务状态为:{3} 成功", taskEntity.Id, taskEntity.Station, taskEntity.Port, taskEntity.FirstStatus), LogLevel.Success);
                                        }
                                        else
                                        {
                                            Logger.Log(String.Format("任务ID:{0} 到达出库站台:{1} 即将去向出入库口:{2}处理并更新任务状态为:{3} 失败", taskEntity.Id, taskEntity.Station, taskEntity.Port, taskEntity.FirstStatus), LogLevel.Error);
                                        }
                                    }
                                    else
                                    {
                                        Logger.Log(string.Format("任务ID:{0} 到达出库站台:{1} 写入去向地址:{2}失败", taskEntity.Id, taskEntity.Station, taskEntity.Port), LogLevel.Error);
                                    }
                                }
                                else
                                {
                                    Logger.Log(string.Format("获取站台:{0}对应的请求任务转实体类失败", requestNumber.Value), LogLevel.Error);
                                }
                            }
                            else
                            {
                                Logger.Log(string.Format("获取站台:{0}对应的请求任务根据站台编码和任务状态未查询到", requestNumber.Value), LogLevel.Error);
                            }
                        }
                        else
                        {
                            Logger.Log(string.Format("出库站台:{0} WCS写入信息成功,等待PLC响应执行",requestNumber.Value), LogLevel.Warning);
                        }
                    }
                    else if (requestMessage.Value == "0")
                    {
                        if (wcsReplyMessage.Value == "6")// 需要清除WCS_PLC的数据
                        {
                            List<EquipmentProp> propsToWriter = new List<EquipmentProp>();
                            //回复PLC考虑标志位 放置最后 控制数据传递的完整性
                            var number = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplyNumber");
                            number.Value = "0";//地址编码
                            var loadStatus = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplayLoadStatus");
                            loadStatus.Value = "0";//装载状态
                            var barcode = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplayBarcode");
                            barcode.Value = "0";//容器条码
                            var weight = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplyWeight");
                            weight.Value = "0";
                            var length = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplyLength");
                            length.Value = "0";//长
                            var width = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplyWidth");
                            width.Value = "0";//宽
                            var height = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplyHeight");
                            height.Value = "0";//高
                            var address = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplyAddress");
                            address.Value = "0";//目标地址
                            var backup = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplyBackUp");
                            backup.Value = "0";//备用
                            var flag = wcsReplyMessage;
                            flag.Value = "0";//报文名称
                            propsToWriter.AddRange(new List<EquipmentProp>() { number, loadStatus, barcode, weight, length, width, height, address, backup, flag });
                            //判断是那个对应plc
                            Plc plc = plcs.FirstOrDefault(t => t.IP == station.IP);
                            if (plc == null)
                            {
                                string errInfo = string.Format("出库站台:{0} 对应PLC的IP地址:{1}和系统传入的PLC列表进行IP匹配失败,请检查IP地址是否设置正确", station.Code, station.IP);
                                Logger.Log(errInfo, LogLevel.Error);
                                continue;
                            }
                            BllResult result = S7Helper.PlcSplitWrite(plc, propsToWriter, 20);
                            if (result.Success)// 清除WCS写入PLC的信息成功  
                            {
                                Logger.Log(string.Format("出库站台:{0} 清除WCS到PLC的地址回复信息成功", requestNumber.Value), LogLevel.Info);
                            }
                            else
                            {
                                Logger.Log(string.Format("出库站台:{0} 清除WCS到PLC的地址回复信息失败", requestNumber.Value), LogLevel.Error);
                            }
                        }
                        else
                        {
                            Logger.Log(string.Format("出库站台:{0} WCS清除信息成功,等待PLC响应清除", requestNumber.Value), LogLevel.Warning);
                        }
                    }
                    //--------------------------------------------------------------------------------------------------------------------
                    #endregion
                    # region 位置到达处理逻辑
                    //--------------------------------------------位置到达处理逻辑-------------------------------------------------------
                    // step1: 查看是否有位置到达信号请求
                    var arriveMessage = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "ArriveMessage");
                    var wcsAckMessage = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSACKMessage");
                    var ArriveRealAddress = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "ArriveRealAddress");
                    if (arriveMessage.Value == "2")
                    {
                        //step2: 判断是否已经回复  08标识已回复
                        if (wcsAckMessage.Value != "8")
                        {
                            //step3: 根据条码获取对应的任务类型、以及相应的任务状态
                            string containerCode = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "ArriveBarcode").Value;
                            var AllcationAddress = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "ArriveAllcationAddress");
                            var ArriveResult = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "ArriveResult");
                            var tasksResult = AppSession.Bll.GetCommonModelByCondition<TaskEntity>($"where containerCode={containerCode} and port={AllcationAddress.Value} and firstStatus = {(int)TaskEntityStatus.响应接出口站台地址请求}");
                            if (tasksResult.Success)
                            {
                                //step4: 回复PLC相关信息
                                TaskEntity taskEntity = tasksResult.Data[0];
                                if (taskEntity != null)
                                {
                                    List<EquipmentProp> propsToWriter = new List<EquipmentProp>();
                                    //判断是否成功
                                    if (ArriveResult.Value == "1")//成功
                                    {
                                        //回复PLC考虑标志位 放置最后 控制数据传递的完整性
                                        var number = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSACKNumber");
                                        number.Value = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "ArriveRealAddress").Value;//地址编码
                                        var loadStatus = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSACKLoadStatus");
                                        loadStatus.Value = "1";//装载状态  到达1  控制2
                                        var backup = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplyBackUp");
                                        backup.Value = "0";//备用
                                        var flag = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSACKMessage");
                                        flag.Value = "8";//报文名称
                                        propsToWriter.AddRange(new List<EquipmentProp>() { number, loadStatus, backup, flag });
                                        //判断是那个对应plc
                                        Plc plc = plcs.FirstOrDefault(t => t.IP == station.IP);
                                        if (plc == null)
                                        {
                                            string errInfo = string.Format("出库站台:{0} 对应PLC的IP地址:{1}和系统传入的PLC列表进行IP匹配失败,请检查IP地址是否设置正确", station.Code, station.IP);
                                            Logger.Log(errInfo, LogLevel.Error);
                                            continue;
                                        }
                                        BllResult result = S7Helper.PlcSplitWrite(plc, propsToWriter, 20);
                                        if (result.Success)// 写入成功后更新任务状态为  
                                        {
                                            //todo: 后续更改

                                            BllResult bllResult = AppSession.Bll.CompleteTask(taskEntity.Id.ToString());
                                            taskEntity.FirstStatus = (int)TaskEntityStatus.任务完成;
                                            // AppSession.Bll.UpdateCommonModel<TaskEntity>(taskEntity);
                                            if (bllResult.Success)
                                            {
                                                Logger.Log(String.Format("任务ID:{0} 到达出入库口:{1}处理并更新任务状态为:{2} 成功", taskEntity.Id,  taskEntity.Port, taskEntity.FirstStatus), LogLevel.Success);
                                            }
                                            else
                                            {
                                                Logger.Log(String.Format("任务ID:{0}  到达出入库口:{1}处理并更新任务状态为:{2} 失败", taskEntity.Id, taskEntity.Port, taskEntity.FirstStatus), LogLevel.Error);
                                            }
                                        }
                                        else
                                        {
                                            Logger.Log(String.Format("任务ID:{0}  到达出入库口:{1} 写入PLC的ACK信息 失败", taskEntity.Id,  taskEntity.Port), LogLevel.Error);
                                        }
                                    }
                                    else if (ArriveResult.Value == "2")//失败  不是分拣线 不考虑
                                    {
                                        //TODO: 暂时不考虑这块的问题
                                    }
                                }
                                else
                                {
                                    Logger.Log(string.Format("获取出入库口:{0}对应的请求任务未查询到", ArriveRealAddress.Value), LogLevel.Error);
                                }
                            }
                            else
                            {
                                Logger.Log(string.Format("获取出入库口:{0}对应的请求任务根据容器条码:{1}和任务状态未查询到", ArriveRealAddress.Value,containerCode), LogLevel.Error);
                            }
                        }
                        else
                        {
                            Logger.Log(string.Format("出入库口:{0} WCS写入信息成功,等待PLC响应执行", ArriveRealAddress.Value), LogLevel.Warning);
                        }
                    }
                    // 处理位置到达--清除信息
                    else if(arriveMessage.Value == "0")
                    {
                        if (wcsAckMessage.Value == "8") // 需要清除信息
                        {
                            List<EquipmentProp> propsToWriter = new List<EquipmentProp>();
                            //回复PLC考虑标志位 放置最后 控制数据传递的完整性
                            var number = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSACKNumber");
                            number.Value ="0";//地址编码
                            var loadStatus = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSACKLoadStatus");
                            loadStatus.Value = "0";//装载状态  到达1  控制2
                            var backup = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSReplyBackUp");
                            backup.Value = "0";//备用
                            var flag = station.EquipmentProps.Find(t => t.EquipmentTypePropTemplateCode == "WCSACKMessage");
                            flag.Value = "0";//报文名称
                            propsToWriter.AddRange(new List<EquipmentProp>() { number, loadStatus, backup, flag });
                            //判断是那个对应plc
                            Plc plc = plcs.FirstOrDefault(t => t.IP == station.IP);
                            if (plc == null)
                            {
                                string errInfo = string.Format("出库站台:{0} 对应PLC的IP地址:{1}和系统传入的PLC列表进行IP匹配失败,请检查IP地址是否设置正确", station.Code, station.IP);
                                Logger.Log(errInfo, LogLevel.Error);
                                continue;
                            }
                            BllResult result = S7Helper.PlcSplitWrite(plc, propsToWriter, 20);
                            if (result.Success)// 写入成功后更新任务状态为  
                            {
                                Logger.Log(String.Format("到达出入库口:{0} 清除WCS-PLC的ACK信息 成功", ArriveRealAddress.Value), LogLevel.Success);
                            }
                            else
                            {
                                Logger.Log(String.Format("到达出入库口:{0} 清除WCS-PLC的ACK信息 失败",ArriveRealAddress.Value), LogLevel.Error);
                            }
                        }
                        else  //等待电气清除信息
                        {
                            Logger.Log(string.Format("出入库台:{0} WCS清除信息成功,等待PLC响应清除", ArriveRealAddress.Value), LogLevel.Warning);
                        }
                    }
                    //--------------------------------------------------------------------------------------------------------------------
                    #endregion
                }
                return BllResultFactory.Sucess();
            }
            catch(Exception ex)
            {
                Logger.Log($"出库站台处理过程中出现异常:{ex.Message}", LogLevel.Exception);
                return BllResultFactory.Error();
            }
        }
    }
}