AgvClient.cs 11.7 KB

using OnlineStore.Common;
using System;
using System.Collections.Generic;
using AsaPL;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using OnlineStore.LoadCSVLibrary;
using System.Web.UI.WebControls;

namespace OnlineStore.DeviceLibrary
{
    public class AgvClient
    {
        private static string ServerIp = ConfigAppSettings.GetValue(Setting_Init.AgvServerIp);
        private AsaPL.AgvClient agvClient;
        private static bool isInit = false;
        public static Dictionary<string, AsaPL.ClientAction> actionMap = new Dictionary<string, AsaPL.ClientAction>();
        public bool InLine_InProcess = false;
        public bool OutLine_InProcess = false;

        private static string InLine_Name = ConfigAppSettings.GetValue(Setting_Init.InLine_Name);
        private static string OutLine_Name = ConfigAppSettings.GetValue(Setting_Init.OutLine_Name);
        public string OutLine_RFID { get; set; } = "";
        #region InLine Action
        /// <summary>
        /// 无状态
        /// </summary>
        public void InLine_None()
        {
            SetStatus(InLine_Name, "000", ClientAction.None);
        }
        /// <summary>
        /// 可以进入状态
        /// </summary>
        public void InLine_NeedEnter()
        {
            SetStatus(InLine_Name, "000", ClientAction.NeedEnter);
        }
        #endregion

        #region OutLine Action
        /// <summary>
        /// 无状态
        /// </summary>
        public void OutLine_None(string rfid="")
        {
            SetStatus(OutLine_Name, rfid, ClientAction.None);
        }

        /// <summary>
        /// 可以出去状态
        /// </summary>
        public void OutLine_NeedLeave(string rfid)
        {
            if (!OutLine_RFID.Equals(rfid))
            {
                OutLine_RFID = rfid;
                SetStatus(OutLine_Name, rfid, ClientAction.NeedLeave);
            }

        }
        #endregion

        public void Init()
        {
            try
            {
                if (!isInit)
                {
                    isInit = true;
                    agvClient = new AsaPL.AgvClient(ServerIp);
                    agvClient.CancelState = false;
                    agvClient.ReadyEnter += AgvClient_ReadyEnter;
                    agvClient.ReadyLeave += AgvClient_ReadyLeave;
                    agvClient.AGVFinishEnter += AgvClient_FinishEnter;
                    agvClient.AGVFinishLeave += AgvClient_FinishLeave;
                }
                actionMap = new Dictionary<string, AsaPL.ClientAction>();
                agvClient.SetStatus(InLine_Name, "", ClientAction.None);
                agvClient.SetStatus(OutLine_Name, "", ClientAction.None);
                agvClient.Connect();
                LogUtil.info("初始化AGV服务");
            }
            catch (Exception ex)
            {
                LogUtil.error("初始化AGV服务 " + ServerIp + " 出错:", ex);
            }
        }

        /// <summary>
        /// 设置取消状态
        /// </summary>
        /// <param name="isCancel">true则ClientAction为None</param>
        public void SetCancelState(bool isCancel)
        {
            agvClient.CancelState = isCancel;
        }

        public string Feeder_In_Msg = "";
        public string Feeder_Out_Msg = "";
        /// <summary>
        /// 小车准备进入
        /// </summary>
        /// <param name="name">节点名称</param>
        private void AgvClient_ReadyEnter(string name)
        {
            if (IOManager.IOValue(IO_Type.L1_InCheck).Equals(IO_VALUE.LOW) && !InLine_InProcess && name.Equals(InLine_Name))
            {
                MayEnter(InLine_Name);
                Task.Factory.StartNew(delegate
                {
                    Feeder_In_Msg = "Feeder In: 等待 L1_InCheck=HIGH";
                    LogUtil.info(Feeder_In_Msg);
                    try
                    {
                        WaitUtil.Wait(60000, delegate
                        {
                            return IOManager.IOValue(IO_Type.L1_InCheck).Equals(IO_VALUE.HIGH);
                        }, "等待L1_InCheck=HIGH");
                    }
                    catch (Exception ex)
                    {
                        LogUtil.error("Feeder In:" + ex.ToString());
                    }

                    //五秒后改为离开状态
                    Thread.Sleep(10000);
                    Feeder_In_Msg = "Feeder In: 调用  FinishEnter ";
                    LogUtil.info(Feeder_In_Msg);
                    FinishEnter(InLine_Name);
                    Feeder_In_Msg = "Feeder In: 处理结束  更新状态为None ";
                    LogUtil.info(Feeder_In_Msg);
                    InLine_None();

                });
            }

            else
            {
                if (IOManager.IOValue(IO_Type.L1_InCheck).Equals(IO_VALUE.HIGH))
                    Feeder_In_Msg = "Feeder In: L1_InCheck 检测到有料架,AGV的料架无法进入";
                LogUtil.info(Feeder_In_Msg);
                InLine_None();
            }
            LogUtil.info("收到 AgvClient_ReadyEnter [" + name + "]");
        }

        /// <summary>
        ///料架准备离开
        /// </summary>
        /// <param name="name">节点名称</param>
        private void AgvClient_ReadyLeave(string name)
        {

            //SetStatus(name, "", ClientAction.ReadyLeave);
            //if (name.Equals("D22"))
            //{
            //    D22_InProcess = true;
            //    D22_ReadyLeave = true;
            //}
            if (IOManager.IOValue(IO_Type.L2_OutCheck).Equals(IO_VALUE.HIGH) && !OutLine_InProcess && name.Equals(OutLine_Name))
            {
                MayLeave(OutLine_Name, OutLine_RFID);
                //LineManager.feederLine.UpdateSleep(false);
                LineManager.feederLine.StopIOMove(IO_Type.L2_OutStopDown, 1500);
                //agvClient.MayLeave(id);
                //  SetStatus(id, shefId, ClientAction.MayLeave);
                Feeder_Out_Msg = "Feeder Out: 允许流出料架";
                LogUtil.info(Feeder_Out_Msg);

                Task.Factory.StartNew(delegate
                {
                    //十秒后改为完成状态
                    Thread.Sleep(10000);
                    Feeder_Out_Msg = "Feeder Out: 调用  FinishLeave ";
                    LogUtil.info(Feeder_Out_Msg);
                    FinishLeave(OutLine_Name, OutLine_RFID);

                    Thread.Sleep(5000);
                    Feeder_Out_Msg = "Feeder Out: 处理结束  更新状态为None ";
                    LogUtil.info(Feeder_Out_Msg);
                    OutLine_None();
                });
            }
            else
            {
                if (IOManager.IOValue(IO_Type.L2_OutCheck).Equals(IO_VALUE.LOW))
                    Feeder_Out_Msg = "Feeder Out: L2_OutCheck 未检测到料架,无法将料架进入AGV";
                LogUtil.info(Feeder_Out_Msg);
                OutLine_None();
            }

            LogUtil.info("收到 AgvClient_ReadyLeave [" + name + "] ");

        }

        /// <summary>
        /// 料架离开小车完成
        /// </summary>
        /// <param name="name"></param>
        private void AgvClient_FinishLeave(string name)
        {
            if (name.Equals(InLine_Name))
            {
                InLine_InProcess = false;
            }
            else if (name.Equals(OutLine_Name))
            {
                OutLine_InProcess = false;
            }
            LogUtil.info("收到 AgvClient_FinishLeave [" + name + "] ");
        }
        /// <summary>
        /// 料架进入小车完成
        /// </summary>
        /// <param name="name"></param>
        private void AgvClient_FinishEnter(string name)
        {
            //if (name.Equals("D21"))
            //{
            //    D21_InProcess = false;
            //}
            //else if (name.Equals("D22"))
            //{
            //    D22_InProcess = false;
            //}
            LogUtil.info("收到 AgvClient_FinishEnter [" + name + "] ");
        }

        public void MayEnter(string name)
        {
            SetStatus(name, "", ClientAction.MayEnter);
            if (name.Equals(InLine_Name))
            {
                InLine_InProcess = true;
            }
            LogUtil.info("MayEnter [" + name + "] ");
        }

        public void MayLeave(string name, string rfid)
        {
            SetStatus(name, rfid, ClientAction.MayLeave);
            if (name.Equals(OutLine_Name))
            {
                OutLine_InProcess = true;
            }
            LogUtil.info("MayLeave [" + name + "] ");
        }

        /// <summary>
        /// 料架进入产线完成
        /// </summary>
        /// <param name="name"></param>
        public void FinishEnter(string name)
        {
            Task.Factory.StartNew(delegate
            {
                SetStatus(name, "", ClientAction.FinishEnter);

                Thread.Sleep(15000);
                if (name.Equals(InLine_Name))
                {
                    InLine_InProcess = false;
                }
                else if (name.Equals(OutLine_Name))
                {
                    OutLine_InProcess = false;
                }
            });

        }
        /// <summary>
        /// 料架离开产线完成
        /// </summary>
        /// <param name="name"></param>
        public void FinishLeave(string name, string rfid = "")
        {
            Task.Factory.StartNew(delegate
            {
                SetStatus(name, rfid, ClientAction.FinishLeave);
                Thread.Sleep(15000);
                if (name.Equals(InLine_Name))
                {
                    InLine_InProcess = false;
                }
                else if (name.Equals(OutLine_Name))
                {
                    OutLine_InProcess = false;

                }
            });

        }

        private bool SetStatus(string name, string shelfId = "", ClientAction action = ClientAction.None, ClientLevel level = ClientLevel.Low)
        {
            //    if (!agvClient.IsConn)
            //    {
            //        LogUtil.error("SetStatus AGV服务未连接!");
            //        return false;
            //    }

            if (actionMap.ContainsKey(name))
            {
                ClientAction currA = actionMap[name]; //相同状态就设置一次
                if (currA.Equals(action) && (shelfId == "000"))
                {
                    return false;
                }
                actionMap[name] = action;
                agvClient.SetStatus(name, shelfId, action, level);
                LogUtil.info("设置 " + name + " [" + shelfId + "] " + action.ToString());
                return true;
            }
            agvClient.SetStatus(name, shelfId, action, level);
            actionMap.Add(name, action);
            LogUtil.info("设置 " + name + " ["+ shelfId + "] "+ action.ToString());
            return true;
        }

        public bool ISConnected()
        {
            if (agvClient == null)
            {
                return false;
            }
            return agvClient.IsConn;
        }
        public static ClientAction GetAction(string NodeName)
        {
            if (actionMap.ContainsKey(NodeName))
            {
                return actionMap[NodeName];
            }
            return ClientAction.None;
        }
        public void Dispose()
        {
            try
            {
                if (agvClient != null)
                {
                    agvClient.Close();
                    LogUtil.info("关闭AGV服务");
                }
            }
            catch (Exception ex)
            {
                LogUtil.error("关闭AGV服务 " + ServerIp + " 出错:", ex);
            }
        }
    }
}