StationInOrOutExcute.cs 12.5 KB
using System;
using System.Collections.Generic;
using System.Linq;
using HHECS.Bll;
using HHECS.Model.BllModel;
using HHECS.Model.Common;
using HHECS.Model.Entities;
using HHECS.Model.Enums;
using HHECS.OPC;

namespace HHECS.EquipmentExcute
{
    /// <summary>
    /// 开关控制的可入可出站台
    /// </summary>
    public class StationInOrOutExcute : StationExcute
    {
        private List<Equipment> equipments = null;

        public override BllResult Excute(List<Equipment> equipments, OPCHelp plc)
        {
            this.equipments = equipments;
            List<Equipment> stations = equipments.Where(a => a.EquipmentType.Id == EquipmentType.Id).ToList();
            foreach (var station in stations)
            {
                InnerExcute(station, plc);
            }
            return BllResultFactory.Sucess();
        }

        private void InnerExcute(Equipment station, OPCHelp plc)
        {
            //如果PLC标记为3,则表示解析有误,这里报警
            if (station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "Flag").Value == "3")
            {
                Logger.Log("PLC解析站台" + station + "数据失败,请检查基础数据!", LogLevel.Error);
                return;
            }

            //PLC 有新消息标记 && WCS回复有新消息标记:此时WCS已经回复了消息,等待PLC响应,不做处理,如果PLC新标记为3,表示解析错误
            if (station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "Flag").Value == "1" && station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "WCSFlag").Value == "1")
            {
                return;
            }

            //PLC没有新消息标记 && WCS有新消息标记:此时PLC已经确认消息,清除WCS回复消息
            if (station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "Flag").Value != "1" && station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "WCSFlag").Value == "1")
            {
                var result = WriteWCSStationDataAddress(station, plc, "0", "0", "0", "0", "0", "0", "", "0", "0");
                if (result.Success)
                {
                    Logger.Log("清空" + station + "WCS区地址成功", LogLevel.Success);
                }
                else
                {
                    Logger.Log("清空" + station + "WCS区地址失败:" + result.Msg, LogLevel.Error);
                }
                return;
            }

            //PLC有新消息标记 && WCS没有新消息标记:此时PLC发送了消息而WCS没有响应,写响应逻辑发送地址数据给PLC
            if (station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "Flag").Value == "1"
                && station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "WCSFlag").Value != "1"
                && station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "Type").Value != "0"
                && station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "PLCNo").Value != "0"
                && station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "StationNo").Value != "0"
                && !String.IsNullOrWhiteSpace(station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "Barcode").Value))
            {
                //获取任务
                string pallet = station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "Barcode").Value;
                var taskResult = AppSession.Bll.GetTaskUncompleteByPalletCode(pallet);
                if (!taskResult.Success)
                {
                    Logger.Log(station + " 根据" + pallet + "获取任务失败:" + taskResult.Msg, LogLevel.Error);
                    return;
                }
                TaskEntity taskEntity = taskResult.Data;
                //判断报文类型
                if (station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "Type").Value == "1")
                {
                    //表示地址请求,此时可能是分拣回库,也可能是新入库,也可能是空托入库,这里空托入库如果没有任务就自动生成任务(自动生成空托盘入库暂时不实现)
                    //获取目标库位
                    //hack:这里临时加个判断,如果任务状态不是31,则不响应
                    if (taskEntity.LastStatus == TaskEntityStatus.拣选台回库.GetIndexInt())
                    {
                        Location location;
                        if (taskEntity.Type == TaskType.整盘入库.GetIndexInt() || taskEntity.Type == TaskType.空容器入库.GetIndexInt())
                        {
                            var locationResult = AppSession.Bll.GetAllLocations(null, null, null, null, null, null, taskEntity.DestinationLocation);
                            if (!locationResult.Success)
                            {
                                Logger.Log("未找到任务" + taskEntity.Id + "对应的" + taskEntity.DestinationLocation + "库位", LogLevel.Error);
                                return;
                            }
                            location = locationResult.Data[0];
                        }
                        else if (taskEntity.Type == TaskType.补充入库.GetIndexInt() || taskEntity.Type == TaskType.分拣出库.GetIndexInt() || 
                                 taskEntity.Type == TaskType.盘点.GetIndexInt() || taskEntity.Type == TaskType.出库查看.GetIndexInt())
                        {
                            var locationResult = AppSession.Bll.GetAllLocations(null, null, null, null, null, null, taskEntity.SourceLocation);
                            if (!locationResult.Success)
                            {
                                Logger.Log("未找到任务" + taskEntity.Id + "对应的" + taskEntity.SourceLocation + "库位", LogLevel.Error);
                                return;
                            }
                            location = locationResult.Data[0];
                        }
                        else
                        {
                            Logger.Log("任务" + taskEntity.Id + "对应的类型" + taskEntity.Type + "不符合地址请求要求", LogLevel.Error);
                            return;
                        }
                        //获取这个库位的目标巷道,从而得出对应的接入站台
                         var stockerStationIn = equipments.FirstOrDefault(x => x.EquipmentType.Code == "StationForStockerIn" && x.RoadWay == location.Roadway.ToString());
                        if (stockerStationIn == null)
                        {
                            Logger.Log("未找到任务" + taskEntity.Id + "对应的堆垛机接入站台,巷道:" + location.Roadway + ",托盘:" + taskEntity.ContainerCode, LogLevel.Error);
                            return;
                        }
                        else
                        {
                            var plcNo = station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "PLCNo").Value;
                            var stationNo = station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "StationNo").Value;
                            var taskNo = station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "TaskNo").Value;
                            var barcode = station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "Barcode").Value;
                            //写入响应地址
                            var result = WriteWCSStationDataAddress(station, plc, "1", "6", plcNo, "0", stationNo, taskNo, barcode, stockerStationIn.SelfAddress.ToString(), "0");
                            if (result.Success)
                            {
                                //这里清空led显示
                                Logger.Log("写入" + station + "WCS区地址成功;任务:" + taskEntity.Id.ToString(), LogLevel.Success);
                            }
                            else
                            {
                                Logger.Log("写入" + station + "WCS区地址失败,任务:" + taskEntity.Id.ToString() + "消息:" + result.Msg, LogLevel.Error);
                            }
                        }
                    }
                }

                if (station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "Type").Value == "2")
                {
                    //表示位置到达,此时检查任务,如果是整出、空出则完成任务
                    //写给PLC的一个标志位,当为1时,表示托盘到此中止;当为2时,表示托盘还需要回库;
                    int flag = 0;
                    if (taskEntity.LastStatus != TaskEntityStatus.响应接出口站台地址请求.GetIndexInt())
                    {
                        Logger.Log($"站台{station}位置到达,但是任务{taskEntity.Id}状态为{taskEntity.LastStatus},此处要求状态为【响应接出口站台地址请求】才会处理", LogLevel.Error);
                        return;
                    }
                    if (taskEntity.Type == TaskType.整盘出库.GetIndexInt() || taskEntity.Type == TaskType.空容器出库.GetIndexInt())
                    {
                        var result = AppSession.Bll.CompleteTask(taskEntity.Id.ToString(), AppSession.Client, AppSession.Urls);
                        if (result.Success)
                        {
                            flag = 1;
                            Logger.Log("站台" + station + ",完成" + taskEntity.Id.ToString() + "成功", LogLevel.Success);
                        }
                        else
                        {
                            Logger.Log("完成任务" + taskEntity.Id.ToString() + "失败:" + result.Msg, LogLevel.Error);
                            return;
                        }
                    }
                    else
                    {
                        //如果是其他类型的任务则更新状态为到达站台并响应
                        var result = AppSession.Bll.SetTaskStatus(taskEntity.Id, TaskEntityStatus.到达拣选站台.GetIndexInt());
                        if (result.Success)
                        {
                            flag = 2;
                            Logger.Log("站台" + station + ",更新任务" + taskEntity.Id.ToString() + "状态【到达拣选站台】成功", LogLevel.Success);
                        }
                        else
                        {
                            Logger.Log("站台" + station + ",更新任务" + taskEntity.Id.ToString() + "状态【到达拣选站台】失败:" + result.Msg, LogLevel.Error);
                            return;
                        }
                    }
                    var plcNo = station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "PLCNo").Value;
                    var stationNo = station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "StationNo").Value;
                    var taskNo = station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "TaskNo").Value;
                    var barcode = station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "Barcode").Value;
                    //响应一个位置请求
                    var temp = WriteWCSStationDataAddress(station, plc, "1", "8", plcNo, "0", stationNo, taskNo, barcode, "0", flag.ToString());
                    if (temp.Success)
                    {
                        //发送电子屏
                        AppSession.Bll.SendLED(station, taskEntity, AppSession.LEDExcute);
                        Logger.Log("位置到达写入" + station + "WCS区地址成功", LogLevel.Success);
                    }
                    else
                    {
                        Logger.Log("位置到达写入" + station + "WCS区地址失败:" + temp.Msg, LogLevel.Error);
                    }
                    return;
                }

                if (station.EquipmentProps.FirstOrDefault(t => t.EquipmentTypePropTemplateCode == "Type").Value == "3")
                {
                    //表示控制指令
                    //todo:控制指令先不弄
                    Logger.Log("控制指令暂时没有实现", LogLevel.Success);
                }
            }

        }










    }
}