RFIDManagercs.cs 13.2 KB

using Asa.RFID;
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;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace OnlineStore.DeviceLibrary
{
    public class RFIDManager
    {
        public static int DefaultTrayNum = ConfigAppSettings.GetIntValue(Setting_Init.DefaultTrayNum);
        private static Asa.RFID.ReadAll readHao;
        private static Asa.RFID.ReadAll readPu;
        private static bool IsOpen = false;
        private static ConcurrentDictionary<string, List<RfidCacheInfo>> LastRfidMap = new ConcurrentDictionary<string, List<RfidCacheInfo>>(); 
        public static void Open()
        {
            if (IsOpen)
            {
                return;
            }
            try
            {
                int port = ConfigAppSettings.GetIntValue(Setting_Init.RfidServer_Port);
                if (port <= 0)
                {
                    port = 13000;
                }
                LogUtil.info($"RFID Server Open,HaoBin port={port},PuYue port={port+1}");
                readHao = new Asa.RFID.ReadAll("TheRFID") { Type = Asa.RFID.DeviceType.HaoBin };
                readHao.Received += ReadAll_Received;
                readHao.Start(port);
                readPu = new Asa.RFID.ReadAll("TheRFID") { Type = Asa.RFID.DeviceType.PuYue };
                readPu.Received += ReadAll_Received;
                readPu.Start(port+1);
                IsOpen = true;
            }
            catch (Exception ex)
            {
                LogUtil.error("Open 出错:" + ex.ToString());
            }
        }

          
        private static void ReadAll_Received(string ip, string id)
        {
            List<RfidCacheInfo> list = LastRfidMap.GetOrAdd(ip, new List<RfidCacheInfo>());
            int count = list.Count;
            if (count > 0)
            {
                RfidCacheInfo last = list[count - 1];
                if (!last.Data.StrData.Equals(id))
                {
                    RFIDData data = new RFIDData(id);
                    list.Add(new RfidCacheInfo(data));
                    if (list.Count > 3)
                    {
                        list.RemoveAt(0);
                    }
                    LogUtil.debug("ReadAll_Received["+ip+"]["+id+"]加入缓存");
                    LastRfidMap.AddOrUpdate(ip, list,(key,value)=>value);
                }
            }
            else
            {
                RFIDData data = new RFIDData(id);
                list.Add(new RfidCacheInfo(data));
                if (list.Count > 3)
                {
                    list.RemoveAt(0);
                }
                LogUtil.debug("ReadAll_Received[" + ip + "][" + id + "]加入缓存");
                LastRfidMap.AddOrUpdate(ip, list, (key, value) => value);
            }
        }


        private static bool CheckTrayNum(string ip, int num)
        {
            RFIDData data = new RFIDData(ip);
            List<RfidCacheInfo> list = LastRfidMap.GetOrAdd(ip, new List<RfidCacheInfo>());

            if (list.Count > 0)
            {

                int readNumIndex = -1;

                string listStr = "";
                for (int i = 0; i < list.Count; i++)
                {
                    RfidCacheInfo cacheInfo = list[i];
                    if (cacheInfo.Data.Num.Equals(num))
                    {
                        listStr += "【" + cacheInfo.Data.Num + "," + cacheInfo.Used + "," + cacheInfo.UpdateTime.ToLongTimeString() + "】";
                        readNumIndex = i;
                    }   
                }
                if (readNumIndex == -1)
                {
                    list.Add(new RfidCacheInfo(data, true));
                    if (list.Count > 3)
                    {
                        list.RemoveAt(0);
                    }
                    LastRfidMap.AddOrUpdate(ip, list, (key, value) => value);
                    LogUtil.error("CheckTrayNum托盘号验证: [" + ip + "][" + num + "],未找到此托盘缓存,增加次托盘到缓存。缓存数据:" + listStr);
                    return true;
                }
                else if (readNumIndex == (list.Count - 1))
                {
                    //是最后一个
                    if (list[readNumIndex].Used)
                    {
                        LogUtil.error("CheckTrayNum托盘号验证失败: [" + ip + "][" + num + "],缓存记录当前托盘已使用。缓存数据:" + listStr);
                        return false;
                    }
                    else
                    {
                        //更改状态
                        list[readNumIndex].Used = true;
                        LastRfidMap.AddOrUpdate(ip, list, (key, value) => value);
                        //上一个已使用
                        if (list.Count > readNumIndex - 1)
                        {
                            if (!list[readNumIndex - 1].Used)
                            {
                                LogUtil.error("CheckTrayNum托盘号验证失败: [" + ip + "][" + num + "],缓存记录上一个托盘未使用,更新当前托盘为已用。缓存数据:" + listStr);
                                return false;
                            }
                        }
                    }
                }
                //不是最后一个
                else
                {
                    //更改状态
                    list[readNumIndex].Used = true;
                    LastRfidMap.AddOrUpdate(ip, list, (key, value) => value);
                    LogUtil.error("CheckTrayNum托盘号验证失败: [" + ip + "][" + num + "],当前托盘索引=" + readNumIndex + ",总缓存托盘数=" + list.Count + ",不是最后一个缓存托盘号,更新当前托盘为已用。缓存数据:" + listStr);
                    return false;
                }

            }
            return true;
        }

        public static int GetTrayNum(int subType, bool isClear = false)
        {
            if (DefaultTrayNum > 0)
            {
                return DefaultTrayNum;
            }
            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);
            string rfidT = DeviceConfig.RFIP_Str + "_" + subType.ToString().PadLeft(3, '0');
            if (data != null)
            {
                if (data.RFType.Equals('E'))
                {

                    bool result = CheckTrayNum(ip, data.Num);
                    if (!result)
                    {
                        LogUtil.error("RFID [ " + ip + " ] 读到数据 " + data.NumStr() + " 缓存验证失败,返回盘号  0");
                        ExceptionMsgManager.updateMsg(rfidT, ip, "读到数据 " + data.NumStr() + " 缓存验证失败,返回盘号  0");
                        return 0;
                    }
                    else
                    {
                        ExceptionMsgManager.updateMsg(rfidT, ip);
                        return data.Num;
                    } 
                }
                else if (data.RFType > 0)
                {
                    LogUtil.error("RFID [ " + ip + " ] 读到数据 " + data.NumStr() + " 返回盘号  0");
                }
                else
                {
                    LogUtil.debug("RFID [ " + ip + " ] 读到数据 " + data.NumStr() + " 返回盘号  0");
                }

                ExceptionMsgManager.updateMsg(rfidT, ip, "读到数据 " + data.NumStr() + " 返回盘号  0");
                return 0;
            }
            else
            { 
                ExceptionMsgManager.updateMsg(rfidT, ip, "读到数据为空,返回盘号 0");
            }
            
            return 0;
        }
        public static void ClearTrayNum(int subType)
        {
            try
            {
                if (subType.Equals(104))
                {
                    return;
                }
                else if (subType.Equals(101))
                {
                    return;
                }

                string ip = GetRFIP(subType);
                RFIDData data = ReadRFID(ip, true);
            }
            catch (Exception ex)
            {
                LogUtil.error("ClearTrayNum【" + subType + "】出错:" + ex.ToString());
            }
        }
        public static RFIDData GetShelfId(int subType)
        {
            string ip = GetRFIP(subType, 1);
            return ReadRFID(ip, true);
        }

        public 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;
        }

        public static RFIDData ReadRFID(string ip, bool isClear = false)
        {
            try
            {
                if (String.IsNullOrEmpty(ip).Equals(false))
                {
                    Dictionary<string,string> allHao= readHao.Read();
                    string outValue = "";
                    if (allHao.ContainsKey(ip))
                    {
                        outValue = allHao[ip];
                        if (isClear)
                        {
                            readHao.Clear(ip,"00");
                        }
                    }
                    else
                    {
                        Dictionary<string, string> allPu = readPu.Read();
                        if (allPu.ContainsKey(ip))
                        {
                            outValue = allPu[ip];
                            if (isClear)
                            {
                                readPu.Clear(ip,"00");
                            }
                        }
                    }
                    if (outValue.Equals("000"))
                    {
                        //    LogUtil.error("ReadRFID[" + ip + "]=" + outValue);
                    }
                    RFIDData data = new RFIDData(outValue);
                    return data;
                }
            }
            catch (Exception ex)
            {
                LogUtil.error("ReadRFID[" + ip + "] [" + isClear + "] 出错:" + ex.ToString());
            }
            return new RFIDData();
        }

        public static void Close()
        {
            try
            {
                IsOpen = false;
                readPu.Stop();
                readHao.Stop();
            }
            catch (Exception ex)
            {
                LogUtil.error("关闭RFID出错:" + ex.ToString());
            }
        }

    }
    public class RFIDBuff
    {
        public RFIDData FIDData { get; set; }
        public int TrayNum { get { return FIDData.Num; } }
    }
    public class RFIDData
    {
        public string StrData = "";

        public char RFType
        {
            get
            {
                char[] charArray = StrData.ToCharArray();
                if (charArray.Length > 0)
                {
                    return charArray[0];
                }
                return '0';
            }
        }
        public int Num
        {
            get
            {
                try
                {
                    if (StrData.Length >= 2)
                    {
                        return Convert.ToInt32(StrData.Substring(1, StrData.Length - 1));
                    }
                }
                catch (Exception ex)
                {
                }
                return 0;
            }
        }

        public RFIDData(string data = "00")
        {
            if (String.IsNullOrEmpty(data))
            {
                data = "00";
            }
            this.StrData = data;
        }

        public string NumStr()
        {
            return StrData;
        }

        internal static bool IsRealRfid(string shelfRfid)
        {
            //判断料架号是否是真实的料架号
            if (shelfRfid.StartsWith("C") || shelfRfid.StartsWith("D"))
            {
                int num = -1;
                try
                {
                    num = Convert.ToInt32(shelfRfid.Substring(1, shelfRfid.Length - 1));
                }
                catch (Exception ex)
                {
                }
                if (num > 0)
                {
                    return true;
                }
            }
            return false;
        }
    }

    public class RfidCacheInfo
    {
        public RfidCacheInfo(RFIDData data,bool userd=false)
        {
            this.Data = data;
            this.Used = false;
            this.UpdateTime = DateTime.Now;

        }
        public RFIDData Data { get; set; }

        public bool Used = false;

        public DateTime UpdateTime = DateTime.Now;
    }
}