TrayManager.cs 12.6 KB
using Asa;
using OnlineStore.Common;
using OnlineStore.LoadCSVLibrary;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace OnlineStore.DeviceLibrary
{
    public class TrayManager
    {

        public static bool DisTraySave = ConfigAppSettings.GetIntValue(Setting_Init.DisTraySave).Equals(1);
        /// <summary>
        /// 进仓5RFID缓存
        /// </summary>
        public static int Move5TrayNum = 0;
        public static bool  HasCheck1(int deviceId)
        {
            bool move5pro = (!deviceId.Equals(5)) || (LineManager.Line.DisableShunt2);
            return move5pro;
        }
      

        public static int StopDTime = 1500;//2000
        public static int mTimeOut = 20;
        public static int SwTrayWaitTime = 500;
        public static int StopDownWaitTime = 500;
        /// <summary>
        /// 托盘集合,key=托盘编号,value=托盘详细信息
        /// </summary>
        private static ConcurrentDictionary<int, TrayInfo> TrayInfoMap = new ConcurrentDictionary<int, TrayInfo>();
         
        /// <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);
        }
     
        /// <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;
        }

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

            return tray;
        }
        /// <summary>
        /// 获取已在托盘的,指定虚拟料架号剩余任务
        /// </summary>
        /// <param name="lastXuniRfid"></param>
        /// <returns></returns>
        internal static int GetOutTaskByRfid(string lastXuniRfid)
        {
            List<TrayInfo> alltray = new List<TrayInfo>(TrayInfoMap.Values);
            int count = (from m in alltray where m.IsFull && m.InOrOutStore.Equals(2) && m.InoutPar.rfid.Equals(lastXuniRfid) select m).Count();
            return count;
        }

        public static void UpdateTrayInfo(int trayNum, bool isFull = false, int inOrOut = 0, InOutParam param = null, string ngMsg = "")
        {
            if (TrayInfoMap.ContainsKey(trayNum))
            {
                TrayInfoMap[trayNum].IsFull = isFull;
                TrayInfoMap[trayNum].InOrOutStore = inOrOut;
                TrayInfoMap[trayNum].LastUpdateTime = DateTime.Now;
                if (param == null)
                {
                    param = new InOutParam();
                }
                TrayInfoMap[trayNum].InoutPar = param;
                TrayInfoMap[trayNum].ShowMsg = ngMsg;
            }
            else
            {
                TrayInfo fixture = new TrayInfo(trayNum, isFull, inOrOut, param,ngMsg); 
                TrayInfoMap.TryAdd(trayNum, fixture);
            }
            SaveMapToFile();
        }

        public static void UpdateInStoreNG(int trayNum, bool isNg, string msg)
        {
            LogUtil.info("更新托盘【" + trayNum + "】InStoreNG=【" + isNg + "】NgMsg=【" + msg + "】");
            if (TrayInfoMap.ContainsKey(trayNum))
            {
                TrayInfoMap[trayNum].InoutPar.InStoreNg = isNg;
                TrayInfoMap[trayNum].ShowMsg = msg;
                TrayInfoMap[trayNum].LastUpdateTime = DateTime.Now;

                SaveMapToFile();
            }
        }

        /// <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;
        }
        public  static bool NeedCheckTray = ConfigAppSettings.GetIntValue(Setting_Init.NeedCheckTray).Equals(1);
        internal static bool CheckIsRightNum(int trayNum, int preTrayNum, bool isCanUpdateMax = true)
        {
            if (!NeedCheckTray)
            {
                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 bool RightTrayCode(int trayNum, int preTrayNum, bool isCanUpdateMax=true)
        {
            return true;
            return CheckIsRightNum(trayNum,preTrayNum,isCanUpdateMax);
        }

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

        public static void ClearTrayInfo()
        {
            List<TrayInfo> tray = TrayManager.getTrayList();
            LogUtil.info("-------------------点击:清空托盘。清空前打印托盘信息:");
            foreach (TrayInfo t in tray)
            {
                LogUtil.info(t.ToStr());
            }
            TrayInfoMap = new ConcurrentDictionary<int, TrayInfo>();
            SaveMapToFile();
            LogUtil.info("-------------------点击:清空托盘。托盘内容已清空");
        }
        /// <summary>
        /// 只清空托盘的  入库任务,会取消入库任务
        /// </summary>
        /// <param name="tray">托盘信息</param>
        /// <param name="msg">清理说明</param>
        public static void ClearInstore(TrayInfo tray,string msg = "手动清空托盘")
        {
            if (tray == null)
            {
                return;
            }

            //如果是入库托盘,需要清理入库消息
            if (tray.InOrOutStore.Equals(1) && tray.InoutPar.InStoreNg.Equals(false) && (!tray.InoutPar.PosId.Equals("")))
            {
                int storeId = tray.InoutPar.GetStoreId();
                MoveEquip moveEquip = LineManager.Line.GetMoveByDId(storeId);
                if (storeId > 0 && (moveEquip != null))
                {
                    //MoveEquip moveEquip = LineManager.Line.MoveEquipMap[storeId];
                    moveEquip.RemoveInStore(tray.InoutPar, msg,true);
                }
            }
        }
        #region 横移状态缓存 
        internal static bool LineCanMoveSW(int 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 (swNum.Equals(2).Equals(false)&& 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 (swNum.Equals(4).Equals(false) && equip.SecondMoveInfo.MoveType.Equals(LineMoveType.None))
                    {
                        return true;
                    }
                    break;
                }
            }
            return false;
        }
        #endregion
        public static bool checkWatch(Stopwatch watch, int targetMs, bool isStop = true)
        {
            if (!watch.IsRunning)
            {
                watch.Restart();
                return false;
            }
            else if (watch.ElapsedMilliseconds >= targetMs)
            {
                if (isStop)
                {
                    watch.Stop();
                }
                return true;
            }
            return false;
        }
        private static string FilePath = "";
        public static void InitFileData()
        {
            TrayInfoMap = new ConcurrentDictionary<int, TrayInfo>();
            if (DisTraySave)
            {
                LogUtil.error("禁用了托盘保存功能,不需要从文件夹加载托盘");
                return;
            }
            FilePath = Application.StartupPath + ConfigAppSettings.GetValue(Setting_Init.ConfigPath_TrayList);
            if (File.Exists(FilePath))
            {
                LogUtil.info("开始加载文件缓存托盘:" + FilePath);
                string[] lines = FileEncoding.GetFileLines(FilePath);
                foreach (string line in lines)
                {
                    TrayInfo tray = JsonHelper.DeserializeJsonToObject<TrayInfo>(line);
                    if (tray != null && tray.TrayCode > 0 && tray.IsFull)
                    {

                        LogUtil.info("加载到缓存托盘:" + tray.ToStr());
                        TrayInfoMap.TryAdd(tray.TrayCode, tray);
                        if (tray.InOrOutStore.Equals(1) && tray.InoutPar.InStoreNg.Equals(false) && (!tray.InoutPar.PosId.Equals("")))
                        {
                            int storeId = tray.InoutPar.GetStoreId();
                            MoveEquip moveEquip = LineManager.Line.GetMoveByDId(storeId);
                            if (storeId > 0 && moveEquip != null)
                            {
                                lock (moveEquip.waitInListLock)
                                {
                                    //如果当前正在出入库中,需要记录下来,等待空闲时执行
                                    LogUtil.info(moveEquip.Name + " 将托盘入库任务[" + tray.TrayCode + "]: " + tray.InoutPar.ToStr() + "加入等待列表中!");
                                    moveEquip.waitInStoreList.Add(tray.InoutPar);
                                }
                            }
                        }
                    }
                }
                LogUtil.info("托盘加载完成");
            }
        }

        public static void SaveMapToFile()
        {
            try
            {
                List<TrayInfo> trayList = new List<TrayInfo>(TrayInfoMap.Values);
                List<string> lineList = new List<string>();
                foreach (TrayInfo tray in trayList)
                {
                    string line = JsonHelper.SerializeObject(tray);
                    if (!string.IsNullOrEmpty(line))
                    {
                        lineList.Add(line);
                    }
                }
                FileEncoding.WritteFile(FilePath, lineList.ToArray());
            }
            catch (Exception ex)
            {
                LogUtil.error("SaveTrayToFile出错:" + ex.ToString());
            }
        }
    }
}