TrayManager.cs 11.1 KB
using Asa;
using OnlineStore.Common;
using OnlineStore.LoadCSVLibrary;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace OnlineStore.DeviceLibrary
{
    public class TrayManager
    {
        public static int SwTrayWaitTime = 500;
        public static int StopDownWaitTime = 500;
        public static RFID RfidReader = new RFID(); 
        /// <summary>
        /// 托盘集合,key=托盘编号,value=托盘详细信息
        /// </summary>
        private static ConcurrentDictionary<int, TrayInfo> TrayInfoMap = new ConcurrentDictionary<int, TrayInfo>();

        /// <summary>
        /// 流水线需要的空盘数量
        /// </summary>
        internal static int LineNeedEmptyTrayNum = 0;
        /// <summary>
        /// 最大托盘号,必须按照顺序从1到6走过
        /// </summary>
        internal static int MaxTrayNum = 0;
        /// <summary>
        /// 托盘错误消息
        /// </summary>
        public static string TrayErrorMsg = "";
        /// <summary>
        /// 盘错乱的StoreID
        /// </summary>
        public static int ErrorDeviceId = -1;
         
        static TrayManager()
        { 
        }
        public static List<TrayInfo> getTrayList()
        {
            return new List<TrayInfo>(TrayInfoMap.Values);
        }
        internal static void AddNeedEmptyTrayNum()
        {
            Interlocked.Increment(ref LineNeedEmptyTrayNum);
        }

        internal static void DelNeedEmptyTrayNum()
        {
            Interlocked.Decrement(ref LineNeedEmptyTrayNum);
        }
        /// <summary>
        /// 对应的盘号(1-6)是否有料盘
        /// </summary>
        /// <param name="trayNum">盘号1-6</param>
        /// <returns>盘上是否有料盘</returns>
        internal static bool TrayIsFull(int trayNum)
        {
            if (TrayInfoMap.ContainsKey(trayNum))
            {
                return TrayInfoMap[trayNum].IsFull;
            }
            return false;
        }

        internal static TrayInfo GetTrayInfo(int trayNum)
        {
            if (TrayInfoMap.ContainsKey(trayNum))
            {
                return TrayInfoMap[trayNum];
            }
            TrayInfo tray = new TrayInfo(trayNum, false, 0);

            return tray;
        }


        internal static void UpdateTrayInfo(int trayNum, bool isFull = false, int inOrOut = 0, string wareCode = "", string posId = "", int plateH = 0, int plateW = 0)
        {
            if (TrayInfoMap.ContainsKey(trayNum))
            {
                TrayInfoMap[trayNum].IsFull = isFull;
                TrayInfoMap[trayNum].InOrOutStore = inOrOut;

                TrayInfoMap[trayNum].WareCode = wareCode;
                TrayInfoMap[trayNum].PosId = posId;
                TrayInfoMap[trayNum].PlateH = plateH;
                TrayInfoMap[trayNum].PlateW = plateW;
            }
            else
            {
                TrayInfo fixture = new TrayInfo(trayNum, isFull, inOrOut, wareCode, posId, plateH, plateW);
                TrayInfoMap.TryAdd(trayNum, fixture);
            }
        }

        internal static void UpdateInStoreNG(int trayNum, bool isNg, string msg)
        {
            LogUtil.info("更新托盘【" + trayNum + "】InStoreNG=【" + isNg + "】NgMsg=【" + msg + "】");
            if (TrayInfoMap.ContainsKey(trayNum))
            {
                TrayInfoMap[trayNum].InStoreNG = isNg;
                TrayInfoMap[trayNum].NgMsg = msg;
            }
        }
        internal static void UpdateEmergencyOut(int trayNum, bool isEmp)
        {
            LogUtil.info("更新托盘【" + trayNum + "】EmergencyOut=【" + isEmp + "】 ");
            if (TrayInfoMap.ContainsKey(trayNum))
            {
                TrayInfoMap[trayNum].EmergencyOut = isEmp;
            }
        }


        /// <summary>
        /// 是否还有有料仓的盘
        /// </summary> 
        internal static bool IsHasFullTray()
        {
            foreach (int key in TrayInfoMap.Keys)
            {
                if (TrayInfoMap[key].IsFull)
                {
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 是否还有有料仓正在出库的盘
        /// </summary> 
        internal static bool IsHasFullOutFixture()
        {
            foreach (int key in TrayInfoMap.Keys)
            {
                if (TrayInfoMap[key].IsFull && TrayInfoMap[key].InOrOutStore.Equals(2))
                {
                    return true;
                }
            }
            return false;
        }

        internal static bool RightTrayCode(int trayNum, int preTrayNum, bool isCanUpdateMax)
        {
            return true;
            int defNext = preTrayNum + 1;
            if (preTrayNum.Equals(0) || MaxTrayNum.Equals(0) || trayNum.Equals(defNext))
            {
                if (isCanUpdateMax && trayNum > MaxTrayNum)
                {
                    MaxTrayNum = trayNum;
                    LogUtil.info("更新MaxTrayNum=" + preTrayNum);
                }
                return true;
            }
            else if (trayNum.Equals(1) && preTrayNum >= MaxTrayNum)
            {
                return true;
            }
            return false;
        }

        internal static void UpdateTrayNumError(int errorStoreID, string errorMsg)
        {
            TrayErrorMsg = errorMsg;
            ErrorDeviceId = errorStoreID;
        }

        public static void ClearTrayInfo()
        {
            TrayInfoMap = new ConcurrentDictionary<int, TrayInfo>();
        }
        /// <summary>
        /// 获取托盘编码
        /// </summary> 
        public static int GetTrayNum(int subType, bool isClear = false)
        {
          //  return 9;
            if (subType.Equals(104))
            {
                return LineManager.Line.Sw23TrayNum;
            }
            else if (subType.Equals(101))
            {
                return LineManager.Line.Sw41TrayNum;
            }

            string ip = GetRFIP(subType);
            //获取盘号
            RFIDData data = ReadRFID(ip,isClear);
            if (data != null)
            {
                if (data.RFType.Equals((byte)'E'))
                {
                    return data.Num;
                }
                return 0;
            }
          
            return 0;
        }
        public static RFIDData GetShelfData(int subType)
        {
            string ip = GetRFIP(subType, 1);
             return ReadRFID(ip);
        }


        public static RFIDData ReadRFID(string ip,bool isClear=false)
        {
            try
            {
                if (String.IsNullOrEmpty(ip).Equals(false) && LineManager.Line.rfidList.Contains(ip))
                { 
                    RFIDData data= new RFIDData(RfidReader.Read(ip));
                    if (isClear)
                    {
                        RfidReader.Clear(ip);
                    }
                    return data;
                } 
            }
            catch (Exception ex)
            {
                //LogUtil.error("ReadRFID["+ip+"]出错:" + ex.ToString());
            }
            return new RFIDData(-1, -1);
        }

        private static string GetRFIP(int subType, int rtType = 0)
        {
            string ip = "";
            string rtName = DeviceConfig.RFIP_Str + "_" + subType.ToString().PadLeft(3, '0');
            if (rtType > 0)
            {
                rtName += "-" + rtType.ToString();
            }
            if (DeviceConfig.ProRFIpMap.ContainsKey(rtName))
            {
                ip = DeviceConfig.ProRFIpMap[rtName];
            }
            return ip;
        }

        #region 横移状态缓存

      //  internal static ConcurrentDictionary<int, int> SidesWayStateMap = new ConcurrentDictionary<int, int>();
        internal static int GetSwStatus(int swNum)
        {
            //if (SidesWayStateMap.ContainsKey(swNum))
            //{
            //    return SidesWayStateMap[swNum];
            //}
            return 0;
        }
        internal static bool LineCanMoveSW(int swNum)
        {

            int status = GetSwStatus(swNum);
            //若此横移对应的设备未启动,直接可处理
            foreach (FeedingEquip equip in LineManager.Line.FeedingEquipMap.Values)
            {
                if (equip.Config.SidesWayNum.Equals(swNum))
                {
                    if (equip.runStatus <= LineRunStatus.Wait || equip.isInSuddenDown || equip.isNoAirCheck)
                    {
                        return true;
                    }
                    if (equip.SecondMoveInfo.MoveType.Equals(LineMoveType.None))
                    {
                        return true;
                    }
                    break;
                }
            }
            foreach (ProvidingEquip equip in LineManager.Line.ProvidingEquipMap.Values)
            {
                if (equip.Config.SidesWayNum.Equals(swNum))
                {
                    if (equip.runStatus <= LineRunStatus.Wait || equip.isInSuddenDown || equip.isNoAirCheck)
                    {
                        return true;
                    }
                    if (equip.SecondMoveInfo.MoveType.Equals(LineMoveType.None))
                    {
                        return true;
                    }
                    break;
                }
            }
            return false;
        }

        /// <summary>
        /// 更新横移托盘的处理状态
        /// </summary>
        /// <param name="swNum">横移编号</param>
        /// <param name="value">0=未处理等待中,1=托盘处理完成,可处理横移,2=托盘检测处理中</param>
        internal static void UpdateSWState(int swNum, int value)
        {
            //if (swNum <= 0)
            //{
            //    return;
            //}

            //if (SidesWayStateMap.ContainsKey(swNum))
            //{
            //    SidesWayStateMap[swNum] = value;
            //}
            //else
            //{
            //    SidesWayStateMap.TryAdd(swNum, value);
            //}
        }

      
        #endregion

    }

    public class RFIDData
    {
        /// <summary>
        /// RFID类型,区分是料架还是托盘,托盘E=69,A=65
        /// </summary>
        public int  RFType=0;
        /// <summary>
        /// 托盘编号,从1-32
        /// </summary>
        public int Num = 0;

        public RFIDData(int num, int  t )
        {
            this.RFType = t;
            this.Num = num;
        }

        public RFIDData(byte[] data)
        {
            try
            {
                if (data != null && data.Length > 2)
                {
                    RFType = data[1];
                    Num = Convert.ToInt32(data[2]);
                }
            }
            catch (Exception ex)
            {
                LogUtil.error("RFIP 数据【" + data + "】 获取编码失败");
            }
        }
        public byte[] ToData()
        {
            return new byte[] { (byte)RFType, (byte)Num };
        }
        public string ToStr()
        {
            return "  [" + RFType + "],[" + Num + "] ";
        }
    }
}