立体仓库WCS系统-输送机(Convery)控制

using WCS.Common;
using WCS.Entity;
using WCS.Entity.Convery;
using WCS.Entity.SRM;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Data;
using System.Threading.Tasks;
using Common.Log;

namespace Core.Library.PLCManager
{
    /// <summary>
    /// 输送机PLC
    /// </summary>
    public class ConveryPLC : PLCHelper
    {
        public LogHelper stalog = new LogHelper("Convery");
        public static List<ConveryEntity> lsRFID = new List<ConveryEntity>();
        public static List<ConveryEntity> StationsInfo = new List<ConveryEntity>();
        public List<ConveryGroupEntity> lstRead1 = new List<ConveryGroupEntity>();
        public List<ConveryGroupEntity> lstRead2 = new List<ConveryGroupEntity>();
        public static List<ConveryItemCode> lstItemCode = new List<ConveryItemCode>();
        public static bool IsInit = false;
        private string local_ip;
        private readonly object objLoc = new object();
        public Dictionary<string,bool> PLCConnectStatus = new Dictionary<string,bool>();

        private delegate void ReadOPCInfos(object info);
        private event ReadOPCInfos ReadEquipOPCInfo;
        private delegate void ReConnetPLC(string ip, int retryCount);
        private event ReConnetPLC STAReConnectPLC;

        public delegate  void ModeOf1200();
        public event ModeOf1200 mode1200;

        private string _GuidID;
        private static readonly object obj = new object();


        public string GuidID
        {
            get
            {
                if (string.IsNullOrEmpty(_GuidID))
                {
                    _GuidID = Guid.NewGuid().ToString();
                }
                return _GuidID;
            }
            set { _GuidID = value; }
        }

        public void InitData(List<ConveryEntity> lst, ref string error)
        {
            try
            {
                foreach (var item in lst as List<ConveryEntity>)
                {
                    local_ip = item.Key_ip;
                    if (!PLCList.ContainsKey(local_ip))
                    {
                        PLCList.Add(local_ip, new OPCServer(local_ip, 1));
                        if (PLCList[local_ip].Connect())
                        {
                            if (!PLCConnectStatus.ContainsKey(item.Key_ip))
                            {
                                PLCConnectStatus.Add(item.Key_ip, true);
                            }
                        }
                        else
                        {
                            if (!PLCConnectStatus.ContainsKey(item.Key_ip))
                            {
                                PLCConnectStatus.Add(item.Key_ip, false);
                            }
                        }
                    }
                    ConveryInit(item, local_ip);
                }
                ShowMsg("Init", "输送机初始化化完成");
                IsInit = true;
            }
            catch (Exception ex)
            {
                error = ex.Message + ex.Source + ex.StackTrace;
            }
        }

     

        public ConveryPLC()
        {
            ReadEquipOPCInfo += new ReadOPCInfos(BatchReadConveryInfo);
            this.STAReConnectPLC += new ReConnetPLC(ReConnect);
            QueueSpeech.Start();

          
        }
        /// <summary>
        /// 初始化输送机
        /// </summary>
        /// <param name="si"></param>
        private void ConveryInit(ConveryEntity si, string strlocal_ip)
        {
            if (si.config == "Convery" || si.config == "SetInfo" || si.config == "Other")
            {
                if (int.Parse(si.Belong) < 24)
                {
                    if (lstRead1.Exists(it => it.key_ip.ToString().Trim() == si.Key_ip && it.Belong == si.Belong))
                    {
                        ConveryGroupEntity cr = lstRead1.Find(it => it.key_ip.ToString().Trim() == strlocal_ip && it.Belong == si.Belong.Trim());
                        if (cr != null)
                        {
                            int index = ((int.Parse(si.StationNo) - cr.currentStatioNo));
                            if (index > 1)  index = index - 1;
                            cr.length += si.length * index;
                            cr.currentStatioNo = int.Parse(si.StationNo);
                            cr.lststation.Add(si);
                        }
                    }
                    else
                    {
                        ConveryGroupEntity cr = new ConveryGroupEntity();
                        cr.value = si.value;
                        cr.length = si.length;
                        cr.key_ip = si.Key_ip;
                        cr.DBAddress = si.DBAddress;
                        cr.lststation.Add(si);
                        cr.currentStatioNo = int.Parse(si.StationNo);
                        cr.Belong = si.Belong;
                        lstRead1.Add(cr);
                    }
                }
                else
                {
                    if (lstRead2.Exists(it => it.key_ip.ToString().Trim() == si.Key_ip && it.Belong == si.Belong))
                    {
                        ConveryGroupEntity cr = lstRead2.Find(it => it.key_ip.ToString().Trim() == strlocal_ip && it.Belong == si.Belong.Trim());
                        if (cr != null)
                        {
                            int index = ((int.Parse(si.StationNo) - cr.currentStatioNo));
                            if (index > 1)
                                index = index - 1;
                            cr.length += si.length * index;

                            cr.currentStatioNo = int.Parse(si.StationNo);
                            cr.lststation.Add(si);
                        }
                    }
                    else
                    {
                        ConveryGroupEntity cr = new ConveryGroupEntity();
                        cr.value = si.value;
                        cr.length = si.length;
                        cr.key_ip = si.Key_ip;
                        cr.DBAddress = si.DBAddress;
                        cr.lststation.Add(si);
                        cr.currentStatioNo = int.Parse(si.StationNo);
                        cr.Belong = si.Belong;
                        lstRead2.Add(cr);
                    }
                }
                if (!StationsInfo.Exists(it => it.StationNo == si.StationNo && it.Key_ip.ToString().Trim() == si.Key_ip && it.DBAddress == it.DBAddress))
                  StationsInfo.Add(si);
            }
            else if(si.config == "RFID")
            {
                if (!lsRFID.Exists(it => it.StationNo == si.StationNo && it.Key_ip.ToString().Trim() == si.Key_ip && it.DBAddress == it.DBAddress))
                    lsRFID.Add(si);
            }
        }

        //烟包条码读取初始化
        public void ItemCodeInit(DataRow[] drs)
        {
            lstItemCode = new List<ConveryItemCode>();
            foreach (var v in drs)
            {
                DataRow row = (DataRow)v;
                ConveryItemCode coi = new ConveryItemCode();
                coi.stationno = int.Parse(row["stationno"].ToString());
                coi.value = int.Parse(row["value"].ToString());
                coi.length = int.Parse(row["signaltype"].ToString());
                coi.key_ip = row["userid"].ToString();
                coi.DBAddress = int.Parse(row["objects"].ToString());
                lstItemCode.Add(coi);
            }
        }

        public void Run(object i_Index)
        {
            Thread threadCom = new Thread(new ParameterizedThreadStart(TimeScan1));
            threadCom.IsBackground = true;
            threadCom.Start(1);

            Thread threadCom2 = new Thread(new ParameterizedThreadStart(TimeScan2));
            threadCom2.IsBackground = true;
            threadCom2.Start(2);
        }

        private void TimeScan1(object belong)
        {
            while (true)
            {
                try
                {
                    lock (obj)
                    {
                        pft.Start();
                        bool flag = true;
                        foreach (ConveryGroupEntity csi in lstRead1)
                        {
                            BatchReadConveryInfo(csi);
                        }
                        pft.Stop();

                        foreach (var key in PLCConnectStatus.Keys)
                        {
                            ShowEquipmentPLCStatus(new PLCStatus() { _connectStatus = PLCConnectStatus[key], _elapsedMilliseconds = pft.Duration, _IP = key });
                        }
                    }
                }
                catch (Exception ex)
                {
                    ShowMsg("Break", "轮询PLC数据异常:"+ex.ToString()+",位置:"+ex.StackTrace.ToString());
                }
                Thread.Sleep(600);
            }
        }

        private void TimeScan2(object belong)
        {
            while (true)
            {
                try
                {
                    lock (obj)
                    {
                        pft.Start();
                        bool flag = true;
                        foreach (ConveryGroupEntity csi in lstRead2)
                        {
                            BatchReadConveryInfo(csi);
                        }
                        pft.Stop();

                        foreach (var key in PLCConnectStatus.Keys)
                        {
                            ShowEquipmentPLCStatus(new PLCStatus() { _connectStatus = PLCConnectStatus[key], _elapsedMilliseconds = pft.Duration, _IP = key });
                        }
                    }
                }
                catch (Exception ex)
                {
                    ShowMsg("Break", "轮询PLC数据异常:" + ex.ToString() + ",位置:" + ex.StackTrace.ToString());
                }
                Thread.Sleep(600);
            }
        }

        /// <summary>
        /// 读取所属线程所有站台信息
        /// </summary>
        /// <param name="stationinfo"></param>
        private void BatchReadConveryInfo(object obj)
        {
            if (ReadEquipOPCInfo != null)
            {
                ConveryGroupEntity stat = (ConveryGroupEntity)obj;
                int length = stat.length;
                Byte[] ConveryBuffer = new byte[length];
                if (PLCList[stat.key_ip].Read(stat.DBAddress, stat.value, length, ref ConveryBuffer))//读多个站台数据
                {
                    stat.cFlag = true;
                    BindListStation(ConveryBuffer, stat);
                }
                else
                {
                    stat.cFlag = false;
                    ReConnect(stat.key_ip, 3);
                }
                if (!PLCConnectStatus.ContainsKey(stat.key_ip))
                    PLCConnectStatus.Add(stat.key_ip, stat.cFlag);
                else
                    PLCConnectStatus[stat.key_ip] = stat.cFlag;
                if (StationsInfo != null)
                    ShowUI(StationsInfo);
            }
        }

        #region 数据解析
        /// <summary>
        /// 绑定任务信息
        /// </summary>
        /// <param name="stationno"></param>
        /// <param name="byt"></param>
        private void BindStation(string stationno, byte[] byt)
        {
            ConveryEntity si = StationsInfo.Find(
              delegate(ConveryEntity ss)
              {
                  return ss.StationNo == stationno;
              });
            if (si != null)
            {
                si.C_TaskInfo.tasknum = byt[0] * 256 + byt[1];//任务信息1
                si.C_TaskInfo.barcode = ((byt[2] * 256 + byt[3]) * 65536 + byt[4] * 256 + byt[5]).ToString().PadLeft(8, '0');//托盘条码23
                si.C_TaskInfo.gooodstype = byt[6] * 256 + byt[7];//托盘类型4
                si.C_TaskInfo.fromstation = byt[8] * 256 + byt[9];//起始地址5
                si.C_TaskInfo.tostation = byt[10] * 256 + byt[11];//目标地址6
                si.C_TaskInfo.checkinfo = byt[12] * 256 + byt[13];//故障位7
                si.C_TaskInfo.stvtaskno = byt[14] * 256 + byt[15] + byt[16] * 256 + byt[17];//重量
                si.C_TaskInfo.stvposition = byt[18];// *256 + byt[16]; //高度
                si.C_TaskInfo.Error = (byt[19]).ToString();// 站台是否有报错:1-是,0-否
               // si.C_TaskInfo.islastone = byt[17] * 256 + byt[18]; //尾箱信号10

            }

            if (si.C_TaskInfo.tostation == 2038)
            {
            }
            if ((si.C_TaskInfo.tasknum > 0 && si.C_TaskInfo.stationno == si.C_TaskInfo.tostation.ToString() && si.StationType > 0) || (si.C_TaskInfo.fromstation == 0 && si.StationType == 5 && si.C_TaskInfo.tasknum==0))// || (si.StationType == 2 && si.C_TaskInfo.tasknum < 1&&si.C_TaskInfo.tostation==1))
            {
                stalog.Fatal($"测试#第一次收到PLC申请信息:任务号={si.C_TaskInfo.tasknum},托盘号={si.C_TaskInfo.barcode}");              
                ShowEquipmentTaskInfo(si);//业务处理
            }

        }

        /// <summary>
        /// 解析数据
        /// </summary>
        /// <param name="byt"></param>
        /// <param name="cr"></param>
        private void BindListStation(byte[] byt, ConveryGroupEntity cr)
        {
            try
            {
                lock (obj)
                {
                    int i_Length = cr.length;
                    int currentStation = 0;
                    foreach (var item in cr.lststation)
                    {
                        ConveryEntity convery = item as ConveryEntity;
                        ConveryEntity si = StationsInfo.Find(
                              delegate (ConveryEntity ss)
                              {
                                  return ss != null && ss.StationNo == convery.StationNo;
                              }
                         );
                        if (si != null)
                        {
                            byte[] bytetemp = new byte[si.length];
                            Array.Copy(byt, cr.length - i_Length, bytetemp, 0, si.length);
                            if (bytetemp != null)
                            {
                                //可采用异步方式
                                BindStation(si.StationNo, bytetemp);//绑定信息
                            }
                        }
                        i_Length = i_Length - si.length;
                        currentStation = int.Parse(si.StationNo);
                    }
                    Thread.Sleep(50);
                }
            }
            catch(Exception ex)
            {
                ShowMsg("Break", "绑定数据异常:"+ex.Message.ToString()+",位置:"+ex.StackTrace.ToString());
            }


        }

        #endregion

        /// <summary>
        /// 重新连接
        /// </summary>
        /// <param name="strIP"></param>
        /// <param name="retryCount"></param>
        private void ReConnect(string strIP, int retryCount = 3)
        {
            if (STAReConnectPLC != null)
            {
                lock (objLoc)
                {
                    ShowMsg("Break",string.Format("PLC:{0},连接断开,系统开始自动重连...",strIP));
                    QueueSpeech.AddQueue("与PLC连接断开,系统开始尝试重连");
                    if (PLCList.ContainsKey(strIP))
                    {
                        bool flag = true;
                        int i_Count = 1;
                        while (flag)
                        {
                            if (i_Count > retryCount)
                                break;
                            PLCList[strIP].DisConnect();
                            ShowMsg("Break", string.Format("PLC:{0},尝试连接次数:{1}", strIP, i_Count));
                            if (PLCList[strIP].Connect())
                            {
                                ShowMsg("Break", string.Format("PLC:{0},连接成功", strIP, i_Count));
                                QueueSpeech.AddQueue("与PLC重连成功");
                                flag = false;
                                break;
                            }
                            else
                            {
                                i_Count++;
                            }
                        }
                    }
                }
            }
        }

        public override string[] ReadPLCInfo(string EquipNum, int index = 0)
        {

            ConveryEntity si = StationsInfo.Find(
                 delegate(ConveryEntity ss)
                 {
                     return ss.StationNo == EquipNum.ToString();
                 }
             );
            if (si != null)
            {
                string[] info = new string[8];
                Byte[] ConveryBuffer = new byte[si.length];
                if (PLCList[si.Key_ip].Read(si.DBAddress, si.value, si.length, ref ConveryBuffer))//读多个站台数据
                {
                    //if (ConveryBuffer == null)
                    //{
                    //    return null;
                    //}
                    si.CFlag = true;

                    si.C_TaskInfo.tasknum = ConveryBuffer[0] * 256 + ConveryBuffer[1];//任务信息
                    si.C_TaskInfo.barcode = ((ConveryBuffer[2] * 256 + ConveryBuffer[3]) * 65536 + ConveryBuffer[4] * 256 + ConveryBuffer[5]).ToString().PadLeft(8, '0');//托盘条码
                    si.C_TaskInfo.gooodstype = ConveryBuffer[6] * 256 + ConveryBuffer[7];//托盘类型
                    si.C_TaskInfo.fromstation = ConveryBuffer[8] * 256 + ConveryBuffer[9];//起始地址
                    si.C_TaskInfo.tostation = ConveryBuffer[10] * 256 + ConveryBuffer[11];//目标地址
                    si.C_TaskInfo.checkinfo = ConveryBuffer[12] * 256 + ConveryBuffer[13];//故障位
                    si.C_TaskInfo.srmflag = ConveryBuffer[18] * 256 + ConveryBuffer[19];//堆垛机放货站台

                    info[0] = si.C_TaskInfo.stationno.ToString();
                    info[1] = si.C_TaskInfo.tasknum.ToString();
                    info[2] = si.C_TaskInfo.barcode;
                    info[3] = si.C_TaskInfo.gooodstype.ToString();
                    info[4] = si.C_TaskInfo.fromstation.ToString();
                    info[5] = si.C_TaskInfo.tostation.ToString();
                    info[6] = si.C_TaskInfo.checkinfo.ToString();
                    info[7] = si.C_TaskInfo.srmflag.ToString();
                }
                else
                {
                    si.CFlag = false;
                    //if (!PLCReLink.Contains(si.Key_ip))
                    //    PLCReLink.Add(si.Key_ip);
                }
                return info;
            }
            return null;
        }

        public  byte[] ReadRFIDInfo(string EquipNum)
        {
            Byte[] ConveryBuffer = null;
            ConveryEntity si = lsRFID.Find(
                 delegate(ConveryEntity ss)
                 {
                     return ss.StationNo == EquipNum.ToString();
                 }
             );
            if (si != null)
            {
                ConveryBuffer = new byte[si.length];
                if (PLCList[si.Key_ip].Read(si.DBAddress, si.value, si.length, ref ConveryBuffer))//读多个站台数据
                {
                    si.CFlag = true;
                }
                else si.CFlag = false;
            }
            return ConveryBuffer;
        }

        public bool WriteRFID(string equipnum,string filltime, string caseguid)
        {
            try
            {
                Byte[] byt = null;
                ConveryEntity si = lsRFID.Find(
                     delegate(ConveryEntity ss)
                     {
                         return ss.StationNo == equipnum.ToString();
                     }
                 );
                if (si != null)
                {
                    Array Sfilltime = filltime.ToArray();
                    Array Scaseguid = caseguid.ToArray();
                    byt = new byte[22];
                    byt[0] = 20;
                    byt[1] = 14;
                    for (int i = 0; i < Sfilltime.Length; i++)
                    {
                        byt[i + 2] = (byte)Convert.ToInt32(System.Text.ASCIIEncoding.ASCII.GetBytes(Sfilltime.GetValue(i).ToString())[0]);
                    }
                    if (PLCList[si.Key_ip].Write(si.DBAddress, si.value + 88, byt.Length, byt))
                    {
                        byt = new byte[34];
                        byt[0] = 32;
                        byt[1] = 32;
                        for (int i = 0; i < Scaseguid.Length; i++)
                        {
                            byt[i + 2] = (byte)Convert.ToInt32(System.Text.ASCIIEncoding.ASCII.GetBytes(Scaseguid.GetValue(i).ToString())[0]);
                        }
                        if (PLCList[si.Key_ip].Write(si.DBAddress, si.value + 2, byt.Length, byt))
                        {
                            return true;
                        }
                    }
                }
            }
            catch { return false; }
            return false;
        }

        private bool Write(string[] str, string equipmentno, int index = 0, int length = 0)
        {
            ConveryEntity si = StationsInfo.Find(
                 delegate(ConveryEntity ss)
                 {
                     return ss.StationNo == equipmentno;
                 }
             );
            if (si != null)
            {
                byte[] byt;
                if (length == 0)
                    byt = new byte[si.length];
                else
                    byt = new byte[length];

                string strLog = "";
                for (int i = 0; i < str.Length; i++)
                {
                    Array.Copy(GetHexBytes(str[i]), 0, byt, i * 2, 2);
                    strLog += str[i] + ",";
                }
                if (length == 0)
                {

                    if (PLCList[si.Key_ip].Write(si.DBAddress, si.value + index, si.length, byt))
                    {
                        return true;
                    }
                }
                else
                {
                    if (PLCList[si.Key_ip].Write(si.DBAddress, si.value + index, length, byt))
                    {
                        return true;
                    }
                }

            }
            return false;
        }

        private byte[] GetHexBytes(string info)
        {
            //将一个整数转化为长度为2的byte型数组
            byte[] Buffer = new byte[2];
            int i = int.Parse(info);
            try
            {
                i = int.Parse(info);
                Buffer[0] = (byte)(i / 256);
                Buffer[1] = (byte)(i % 256);
            }
            catch { }
            return Buffer;
        }

        public bool Write(STACommand cmd, string[] str, string equipmentno, int index, int length)
        {
            bool flag = false;
            switch (cmd)
            {
                case STACommand.ClearToStation:
                    flag = Write(str, equipmentno, index, 2);
                    break;
                case STACommand.ReWrite:
                    flag = Write(str, equipmentno);
                    break;
            }
            return flag;
        }

        public static string[] ReadPLCInfoByEquipNum(string EquipNum)
        {
            string[] info = new string[10];
            ConveryEntity si = StationsInfo.Find(
                 delegate(ConveryEntity ss)
                 {
                     return ss.StationNo == EquipNum.ToString() && IsInit;
                 }
             );
            //if (si != null && si.CFlag)
            if (si != null )
            {
                Byte[] byt = new byte[si.length];
                if (PLCList[si.Key_ip].Read(si.DBAddress, si.value, si.length, ref byt))//读多个站台数据
                {
                    si.CFlag = true;
                    si.C_TaskInfo.tasknum = byt[0] * 256 + byt[1];//任务信息1
                    si.C_TaskInfo.barcode = ((byt[2] * 256 + byt[3]) * 65536 + byt[4] * 256 + byt[5]).ToString().PadLeft(8, '0');//托盘条码23
                    si.C_TaskInfo.gooodstype = byt[6] * 256 + byt[7];//托盘类型4
                    si.C_TaskInfo.fromstation = byt[8] * 256 + byt[9];//起始地址
                    si.C_TaskInfo.tostation = byt[10] * 256 + byt[11];//目标地址
                    si.C_TaskInfo.checkinfo = byt[12] * 256 + byt[13];//故障位
                    si.C_TaskInfo.stvtaskno = byt[13] * 256 + byt[14]; //穿梭车任务号
                    si.C_TaskInfo.stvposition = byt[15] * 256 + byt[16]; //穿梭车位置
                    si.C_TaskInfo.islastone = byt[17] * 256 + byt[18]; //尾箱信号
                }
                else
                {
                    si.CFlag = false;
                }
                info[0] = si.C_TaskInfo.tasknum.ToString();
                info[1] = (int.Parse(si.C_TaskInfo.barcode) / 65536).ToString();
                info[2] = (int.Parse(si.C_TaskInfo.barcode) % 65536).ToString();
                info[3] = si.C_TaskInfo.gooodstype.ToString();
                info[4] = si.C_TaskInfo.fromstation.ToString();
                info[5] = si.C_TaskInfo.tostation.ToString();
                info[6] = si.C_TaskInfo.checkinfo.ToString();
                info[7] = si.C_TaskInfo.stvtaskno.ToString();
                info[8] = si.C_TaskInfo.stvposition.ToString();
                info[9] = si.C_TaskInfo.islastone.ToString();
            }
            return info;
        }

        public string GetItemCode(int stationno)
        {
            string str = "";
            ConveryItemCode coi = lstItemCode.Find(
                delegate (ConveryItemCode co)
                {
                    return co.stationno == stationno;
                }
            );
            if (coi != null)
            {
                byte[] byt = new byte[coi.length];
                if (PLCList[coi.key_ip].Read(coi.DBAddress, coi.value, coi.length, ref byt))
                {
                    if (byt.Length == 50)
                    {
                        str = System.Text.ASCIIEncoding.UTF8.GetString(byt);
                        str = str.TrimEnd('\0');
                    }
                }
            }
            return str;
        }
    }
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

!chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值