TrayManager.cs 12.4 KB
using OnlineStore;
using OnlineStore.Common;
using OnlineStore.LoadCSVLibrary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DeviceLibrary
{
    public static partial class TrayManager
    {
        public static Dictionary<string,TrayInfo> Traylist = new Dictionary<string,TrayInfo>();
        /// <summary>
        /// 处理更新托盘信息
        /// </summary>
        /// <param name="rfid"></param>
        /// <param name="addr"></param>
        /// <param name="trayInfo"></param>
        /// <returns>是否放行 放行true, 拦截false</returns>
        public static bool Process(string rfid, int addr, out TrayInfo trayInfo) {
            lock (Traylist)
            {
                LogUtil.info($"处理RFID:{rfid},地址{addr},设备:{(AddrDesc.ContainsKey(addr)? AddrDesc[addr]:"")}");
                if (!Traylist.ContainsKey(rfid))
                {
                    Traylist.Add(rfid, new TrayInfo());
                    Traylist[rfid].RFID = rfid;
                }
                Traylist[rfid].LastUpdateTime = DateTime.Now;
                Traylist[rfid].LastAddr = addr;
                Traylist[rfid].Destination = TrayManager.AddrDesc[Traylist[rfid].DestinationAddr];
                Traylist[rfid].LastPosition = TrayManager.AddrDesc[Traylist[rfid].LastAddr];
                trayInfo = Traylist[rfid];
                //Statistics();
            }
            return true;
        }
        public static void SetTrayLoadInfo(string rfid, RequestLoadInfo  requestLoadInfo)
        {
            lock (Traylist)
            {
                LogUtil.info($"SetTrayLoadInfo:{rfid},{requestLoadInfo?.LoadParam?.ToStr()},{requestLoadInfo?.DeviceGroupName}");
                if (requestLoadInfo == null)
                {
                    Traylist[rfid].SetToEmpty();
                }
                else
                {
                    Traylist[rfid].LoadType = (TrayTypeE)Enum.Parse(typeof(TrayTypeE), requestLoadInfo.TrayType);
                    Traylist[rfid].TrayParam = requestLoadInfo.LoadParam.clone();
                    Traylist[rfid].DestinationAddr = GetAddrByGroupName(requestLoadInfo.DeviceGroupName);
                }
            }
        }

        /// <summary>
        /// deviceGroupName,RequestLoadInfo
        /// </summary>
        public static Dictionary<string, RequestLoadInfo> TrayRequest = new Dictionary<string, RequestLoadInfo>();
        public static bool HasTrayRequest(string deviceGroupName,string rfid,out ReelParam reelParam)
        {
            reelParam = null;
            LogUtil.info($"HasTrayRequest:{deviceGroupName},{rfid},{TrayRequest.ContainsKey(deviceGroupName)}");
            lock (TrayRequest)
            {
                if (!TrayRequest.ContainsKey(deviceGroupName))
                    return false;

                bool hasrequest = rfid.StartsWith(TrayRequest[deviceGroupName].TrayType, true, null);
                if (hasrequest)
                {
                    reelParam = TrayRequest[deviceGroupName].LoadParam?.clone();
                    TrayRequest.Remove(deviceGroupName);
                    return true;
                }
                else
                    return false;
            }
        }
        public static void ClearTrayRequest(string deviceGroupName)
        {
            lock (TrayRequest)
            { TrayRequest.Remove(deviceGroupName); }
            }
        /// <summary>
        /// 设置托盘需求
        /// </summary>
        /// <param name="requestLoadInfo"></param>
        public static void SetTrayRequest(RemoteLoad remoteLoad)
        {

            LogUtil.info($"SetTrayRequest:{remoteLoad.GroupName}=>{remoteLoad.RequestLoadInfo.DeviceGroupName},{remoteLoad.RequestLoadInfo.TrayType}");
            lock (TrayRequest)
            {
                if (!TrayRequest.ContainsKey(remoteLoad.GroupName))
                    TrayRequest.Add(remoteLoad.GroupName, remoteLoad.RequestLoadInfo);

                TrayRequest[remoteLoad.GroupName] = remoteLoad.RequestLoadInfo;
            }
        }
        public static bool CalcNeedTrans(int curaddr1, int destaddr1, bool hasload) {
            if (!hasload)
            {
                var addrs = TrayRequest.Values.Select(x => new { TaryType = x.GetTrayType, Addr = GetAddrByGroupName(x.DeviceGroupName) }).ToList();
                foreach (var a in addrs)
                {
                    var trayaddrs = TrayManager.Traylist.Values.Where(t => (DateTime.Now - t.LastUpdateTime).TotalSeconds < 30 && t.TrayType == a.TaryType && !hasload).Select(t => t.LastAddr).ToList();
                    if (trayaddrs.Count == 0)
                        return false;


                    var ttt = 0;
                    if (curaddr1 == 9)
                        ttt = 15;
                    else if (curaddr1 == 4)
                        ttt = 19;
                    else if (curaddr1 == 19)
                        ttt = 4;
                    //当前托盘到需求距离
                    var ts = dis(a.Addr, ttt);
                    return !(trayaddrs.Where(t1 => dis(a.Addr, t1) < ts).Count() > 0);


                };
                
                return false;
            }
            else
                return calc(curaddr1, destaddr1);

            bool calc(int curaddr, int destaddr)
            {
                if (destaddr == -1)
                    return false;
                if (curaddr == 9 && (destaddr > 15 || destaddr < 9))
                    return true;

                if (curaddr == 4 && (destaddr > 19 || destaddr < 4))
                    return true;
                if (curaddr == 19 && (destaddr > 4 && destaddr < 19))
                    return true;
                return false;
            }
            int dis(int needa,int trayb) {

                var d = needa - trayb;
                if (d >= 0)
                    return d;
                else
                    return d + 20;
            }


        }
        public static void SetToEmpty(string rfid)
        {
            lock (Traylist)
            {
                LogUtil.info("清空托盘信息 RFID:" + rfid);
                Traylist[rfid].SetToEmpty();
            }
        }
        /// <summary>
        /// 托盘释放
        /// </summary>
        /// <param name="requestLoadInfo"></param>
        public static void TrayRelease(RemoteLoad remoteLoad)
        {
            var requestLoadInfo = remoteLoad.RequestLoadInfo;
            LogUtil.info($"TrayRelease:{remoteLoad.GroupName}{requestLoadInfo.DeviceGroupName},{requestLoadInfo?.LoadParam.ToStr()}");
            lock (requestLoadInfo)
            {
                var device = TrayStop.DeviceList[remoteLoad.GroupName];
                if (requestLoadInfo.IsEmpty)
                {
                    SetTrayLoadInfo(device.CurrrentRFID, null);
                    ServerCommunication.UpdateRobotStatus(requestLoadInfo.LoadParam.WareCode, RobotStatusE.FINISHED, remoteLoad.GroupName);
                }
                else { 
                    SetTrayLoadInfo(device.CurrrentRFID, requestLoadInfo);
                }
                LogUtil.info("释放设备:"+device.GroupName);
                device.TrayRelease();
            }
        }

        /// <summary>
        /// 空托盘数量
        /// </summary>
        public static int EmptyCount;
        /// <summary>
        /// 入库托盘数量
        /// </summary>
        public static int InStoreCount;
        /// <summary>
        /// 出库托盘数量
        /// </summary>
        public static int OutStoreCount;
        /// <summary>
        /// 离线托盘数量
        /// </summary>
        public static int OfflineCount;
        public static int TotalCount{ get => EmptyCount + InStoreCount + OutStoreCount; }

        static DateTime lastrefresh;
        public static void Statistics() {
            EmptyCount = 0;
            InStoreCount = 0;
            OutStoreCount = 0;
            OfflineCount = 0;
            lastrefresh = DateTime.Now;
            Traylist.Values.ToList().ForEach(ti=> {
                if ((lastrefresh - ti.LastUpdateTime).TotalSeconds > 15)
                {
                    ti.isOnline = false;
                    OfflineCount++;
                }
                if (ti.HasLoad) {
                    if (ti.Direction == DirectionE.In)
                        InStoreCount++;
                    else
                        OutStoreCount++;
                } else {
                    EmptyCount++;
                }            
            });
        }
    }
    
    public class TrayInfo {
        string _rfid;
        public string RFID { get => _rfid; set {
                try
                {
                    var ss = Enum.GetNames(typeof(TrayTypeE));
                    TrayType = (TrayTypeE)Enum.Parse(typeof(TrayTypeE), ss.ToList().Find(s => value.StartsWith(s)));
                    _rfid = value;
                }
                catch (Exception ex) {
                    LogUtil.error($"获取RFID的类型时出错:{value}");
                }
            }
        }
        public string Destination;
        public int DestinationAddr=-1;
        public int LastAddr=-1;
        public string LastPosition;
        public bool HasLoad { get => LoadType != TrayTypeE.None; }
        public TrayTypeE LoadType = TrayTypeE.None;
        public TrayTypeE TrayType;
        public DateTime LastUpdateTime;
        public ReelParam TrayParam;
        public bool SenSorStatus = false;
        public DirectionE Direction { get => (Destination ==StoreCID.AMH_ML5_1 || Destination == StoreCID.AMH_ML5_2) ? DirectionE.Out : DirectionE.In; }
        public bool isOnline = true;
        public void SetToEmpty() {
            LoadType = TrayTypeE.None;
            DestinationAddr = -1;
            TrayParam = new ReelParam();
            SenSorStatus = false;
        }
    }

    public enum MagzineTypeE {
        C01,    //PCB治具
        C02,    //Pizza治具
        C03,    //Tray治具
        C04,    //ShoeBOX治具
    }
    public enum DirectionE
    {
        In,Out
    }
    public static partial class TrayManager
    {
        public static Dictionary<TrayTypeE, string> TrayTypeDesc = new Dictionary<TrayTypeE, string>();
        public static Dictionary<int, string> AddrDesc = new Dictionary<int, string>();
        static TrayManager() {
            TrayTypeDesc.Add(TrayTypeE.None, crc.GetString("Res0002","空"));
            TrayTypeDesc.Add(TrayTypeE.MTP1, crc.GetString("Res0003","流水线治具托盘"));
            TrayTypeDesc.Add(TrayTypeE.MTP2, crc.GetString("Res0004","流水线料盘托盘"));
            TrayTypeDesc.Add(TrayTypeE.S007, crc.GetString("Res0005","料串"));
            TrayTypeDesc.Add(TrayTypeE.M03, crc.GetString("Res0006","Tray料格"));
            TrayTypeDesc.Add(TrayTypeE.M02, crc.GetString("Res0007","PCB料格"));
            TrayTypeDesc.Add(TrayTypeE.M01, crc.GetString("Res0008","PizzaBOX料格"));
            TrayTypeDesc.Add(TrayTypeE.M04, crc.GetString("Res0009","ShoeBOX料格"));
            //TrayTypeDesc.Add(TrayTypeE.C01, crc.GetString("Res0010","PCB治具"));
            //TrayTypeDesc.Add(TrayTypeE.C02, crc.GetString("Res0011","Pizza治具"));
            //TrayTypeDesc.Add(TrayTypeE.C03, crc.GetString("Res0012","Tray治具"));
            //TrayTypeDesc.Add(TrayTypeE.C04, crc.GetString("Res0013","ShoeBOX治具"));

        }
        public static void Init(Dictionary<string, DeviceGroup> deviceGroup) {
            if (!AddrDesc.ContainsKey(-1))
                AddrDesc.Add(-1, crc.GetString("Res0014", "未知"));
            foreach (var dg in deviceGroup) {
                
                if (dg.Value.addr_2 >= 0)
                {
                    if (!AddrDesc.ContainsKey(dg.Value.addr_1))
                        AddrDesc.Add(dg.Value.addr_1, dg.Value.GroupName + "-1");
                    if (!AddrDesc.ContainsKey(dg.Value.addr_2))
                        AddrDesc.Add(dg.Value.addr_2, dg.Value.GroupName + "-2");
                }
                else {
                    if (!AddrDesc.ContainsKey(dg.Value.addr_1))
                        AddrDesc.Add(dg.Value.addr_1, dg.Value.GroupName);
                }
            }
        }
        /// <summary>
        /// 获取设备地址
        /// </summary>
        /// <returns></returns>
        public static int GetAddrByGroupName(string groupname) {
            var addr = AddrDesc.Where(a => a.Value == groupname).First();

            return addr.Key;
        }
    }
}