| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620 | using SqlSugar;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using WCS.Data;using WCS.Data.Models;using WCS.Data.Utils;using WCS.PLC.Model.Equipment;namespace WCS.PLC{    public class WCS_PLC    {        #region 变量        private int _readSignals = 0;        #endregion;        #region 属性        [SugarColumn(IsPrimaryKey = true)]        public string PLC_NAME { get; set; }        public string PLC_IP { get; set; }        public string PLC_EQUIPMENTTYPE { get; set; }        public bool PLC_ISENABLE { get; set; }        public bool PLC_CONNECTSTATUS { get; set; }        public int PLC_PORT { get; set; }        public int PLC_SLOT { get; set; }        public int PLC_RACK { get; set; }        /// <summary>        /// WCS系统        /// </summary>        public string PLC_WCSSYSTEM { get; set; }        /// <summary>        /// plc实例数量        /// </summary>        public int PLC_INSTANCECOUNT { get; set; }        public string PLC_NOTES { get; set; }        /// <summary>        /// 未完成任务        /// </summary>        public int? PLC_UNEXECUTETASK { get; set; }        /// <summary>        /// 最后完成时间        /// </summary>        public DateTime? PLC_LASTFINISHTIME { get; set; }        [SugarColumn(IsIgnore = true)]        public PLC Plc        {            get            {                return PlcInstanceSet.FirstOrDefault();            }        }        /// <summary>        /// PLC实例列表        /// </summary>        public List<PLC> PlcInstanceSet = new List<PLC>();        [SugarColumn(IsIgnore = true)]        public PLC Plc2 { get; set; }        //PLC是否连接成功        [SugarColumn(IsIgnore = true)]        public bool IsConnSuccess { get; set; }        //DB集合        public List<WCS_DBDEFINITION> WCS_DBSet = new List<WCS_DBDEFINITION>();        //扫描的条码集合        [SugarColumn(IsIgnore = true)]        public List<WCS_SCANN> WCS_ScannSet { get; set; }        //设备信号集合        [SugarColumn(IsIgnore = true)]        public List<WCS_EQUIPMENTINFO> WCS_EquipmentInfoSet { get; set; }        //DB名称        [SugarColumn(IsIgnore = true)]        public int WriteDBName        {            get            {                return WCS_DBSet.FirstOrDefault(v => v.DB_TypeCh == DB_TypeEnum.WCS可读可写DB).DB_NAME;            }        }        [SugarColumn(IsIgnore = true)]        public Base_EquPlc EquPlc { get; set; }        #endregion;        #region 函数        public void Init()        {            //foreach (var item in WCS_DBSet)            //{            //    item.DB_EQUDATA = new byte[item.DB_TOLLENGTH];            //}        }        /// <summary>        /// 读取PLC信号        /// </summary>        public void ExecuteWcs_Workflow()        {            if (Interlocked.Exchange(ref _readSignals, 1) == 0)            {                try                {                    //连接PLC                    //ThreadHelper.TaskThread(ConnectPLC);                    ConnectPLCS();                    //更新plc连接状态                    UpdatePLCConnStatus();                    if (IsConnSuccess == false) return;                    //Log4netHelper.Logger_Info.InfoFormat(string.Format("开始:PLC[{0}]读取信号到数据库。",PLC_NAME));                    //读取Plc到缓存                    ReadPlcToCache();                    //Log4netHelper.Logger_Info.InfoFormat(string.Format("结束:PLC[{0}]读取信号到数据库。", PLC_NAME));                    //读取扫码缓存数据到实体                    ReadScannBarCodeCacheToEntity();                    //读取PLC信号到数据库                    ThreadHelper.TaskThread(ReadPlcInfoToDataBase);                    if (EquPlc != null) EquPlc.Run();                }                catch (Exception ex)                {                    LogMessageHelper.RecordLogMessage(ex);                    //Log4netHelper.Logger_Error.ErrorFormat(ex.ToString());                }                finally                {                    Interlocked.Exchange(ref _readSignals, 0);                }            }        }        private void StopPlcAction()        {            IsConnSuccess = false;        }        /// <summary>        /// 连接电控设备        /// </summary>        //private void ConnectPLC()        //{        //    try        //    {        //        if (Plc == null || Plc._splc.Connected == false || IsConnSuccess == false)        //        {        //            if (Plc != null)        //            {        //                Plc.PlcStop();        //                Plc = null;        //            }        //            IsConnSuccess = false;        //            Plc = new PLC();        //            if (Plc.Connect(PLC_IP, PLC_RACK, PLC_SLOT, PLC_NAME))        //            {        //                Plc.RegisterStopPlcEvent(StopPlcAction);        //                Log4netHelper.Logger_Info.InfoFormat(string.Format("连接PLC_IP:[{0}]成功!", PLC_IP));        //                IsConnSuccess = true;        //            }        //            else        //            {        //                LogMessageHelper.RecordLogMessage(string.Format("连接PLC_IP:[{0}]失败!", PLC_IP));        //                //Log4netHelper.Logger_Error.ErrorFormat();        //                if (Plc != null)        //                {        //                    Plc.PlcStop();        //                    Plc = null;        //                }        //                Thread.Sleep(300);        //            }        //        }        //        else        //        {        //            IsConnSuccess = true;        //        }        //    }        //    catch (Exception ex)        //    {        //        IsConnSuccess = false;        //        Log4netHelper.Logger_Error.ErrorFormat(ex.ToString());        //    }        //}        private void ConnectPLCS()        {            for (int i = 0; i < PlcInstanceSet.Count; i++)            {                var plcitem = PlcInstanceSet[i];                PlcInstanceSet[i] = ConnectPLC(plcitem, i);            }        }        /// <summary>        /// 连接电控设备        /// </summary>        private PLC ConnectPLC(PLC plcitem,int index)        {            try            {                if (plcitem == null || plcitem._splc.Connected == false || IsConnSuccess == false)                {                    if (plcitem != null)                    {                        plcitem.PlcStop();                        plcitem = null;                    }                    IsConnSuccess = false;                    plcitem = new PLC();                    if (plcitem.Connect(PLC_IP, PLC_RACK, PLC_SLOT, PLC_NAME))                    {                        plcitem.RegisterStopPlcEvent(StopPlcAction);                        Log4netHelper.Logger_Info.InfoFormat(string.Format("连接PLC_IP:[{0}]实例[{1}]成功!", PLC_IP, index));                        IsConnSuccess = true;                    }                    else                    {                        LogMessageHelper.RecordLogMessage(string.Format("连接PLC_IP:[{0}]实例[{1}]失败!", PLC_IP, index));                        //Log4netHelper.Logger_Error.ErrorFormat();                        if (plcitem != null)                        {                            plcitem.PlcStop();                            plcitem = null;                        }                        Thread.Sleep(300);                    }                }                else                {                    IsConnSuccess = true;                }            }            catch (Exception ex)            {                IsConnSuccess = false;                Log4netHelper.Logger_Error.ErrorFormat(ex.ToString());            }            return plcitem;        }        /// <summary>        /// 连接电控设备        /// </summary>        private void ConnectPLC2()        {            try            {                if (PLC_NAME != "conveyor02") return;                if (Plc2 == null || Plc2._splc.Connected == false || IsConnSuccess == false)                {                    if (Plc2 != null)                    {                        Plc2.PlcStop();                        Plc2 = null;                    }                    IsConnSuccess = false;                    Plc2 = new PLC();                    if (Plc2.Connect(PLC_IP, PLC_RACK, PLC_SLOT, PLC_NAME))                    {                        Plc2.RegisterStopPlcEvent(StopPlcAction);                        Log4netHelper.Logger_Info.InfoFormat(string.Format("连接PLC2_IP:[{0}]成功!", PLC_IP));                        IsConnSuccess = true;                    }                    else                    {                        Log4netHelper.Logger_Error.ErrorFormat(string.Format("连接PLC2_IP:[{0}]失败!", PLC_IP));                        if (Plc2 != null)                        {                            Plc2.PlcStop();                            Plc2 = null;                        }                        Thread.Sleep(300);                    }                }                else                {                    IsConnSuccess = true;                }            }            catch (Exception ex)            {                IsConnSuccess = false;                Log4netHelper.Logger_Error.ErrorFormat(ex.ToString());            }        }        private void UpdatePLCConnStatus()        {            if (PLC_CONNECTSTATUS != IsConnSuccess)            {                PLC_CONNECTSTATUS = IsConnSuccess;                SugarBase.DB.Updateable<WCS_PLC>(it => new WCS_PLC() { PLC_CONNECTSTATUS = IsConnSuccess }).Where(it => it.PLC_NAME == PLC_NAME).ExecuteCommand();            }        }        private void ReadPlcToCache()        {            foreach (var item in WCS_DBSet)            {                byte[] DB_Data = null;//new byte[item.DB_EQUDATA.Length];                bool result = Plc.ReadByteArea((ushort)item.DB_NAME, (ushort)item.DB_STARTADDRESS, (ushort)item.DB_TOLLENGTH, ref DB_Data);                if (result == false)                {                    Log4netHelper.Logger_Error.ErrorFormat(string.Format("PLC[{0}]DB[{1}]读取失败。", item.DB_PLCNAME, item.DB_NAME));                }                else                {                    //if (item.DB_NAME == 537)                    //{                    //    string alaram = PlcHelper.ReadAlaramCodeByBytes(DB_Data);                    //    Current.Logger_Info.InfoFormat(string.Format("报警信息:[{0}]", alaram));                    //}                    if (item.DB_EQUDATA != DB_Data) item.DB_EQUDATA = DB_Data;                }            }        }        /// <summary>        /// 读取缓存信号到实体        /// </summary>        private void ReadScannBarCodeCacheToEntity()        {            //扫码PLC            var WCS_DBSCAN = WCS_DBSet.Where(it => it.DB_TypeCh == DB_TypeEnum.WCS读取扫码DB).ToList();            foreach (var item in WCS_DBSCAN)            {                var scannSet = WCS_ScannSet.Where(v => v.SCANN_DB_ID == item.DB_ID).OrderBy(v => v.SCANN_SEQUENCE);                foreach (var scann in scannSet)                {                    byte[] dbsann = item.DB_EQUDATA.Skip(scann.SCANN_STARTADDRESS).Take(scann.SCANN_LENGTH).ToArray();                    string barcode = ExtendsUtil.GetBarCodeStr(dbsann).Replace("\r", "").Replace("\0", "").Trim();                    if (scann.SCANN_BARCODE != barcode)                    {                        scann.SCANN_BARCODE = barcode;                        scann.SCANN_UPDATETIME = DateTime.Now;                    }                }            }        }        private int readPlcInfoToDataBase = 0;        public void ReadPlcInfoToDataBase()        {            if (Interlocked.Exchange(ref readPlcInfoToDataBase, 1) == 0)            {                try                {                    Thread.Sleep(1000);//1秒中更新一次                    SugarBase.Exec((db) => {                        #region 更新PLC DB信息                        var dbdefinitionSet = db.Queryable<WCS_DBDEFINITION>().Where(v => v.DB_PLCNAME == PLC_NAME).ToList();                        foreach (var item in WCS_DBSet)                        {                            var dbdefinition = dbdefinitionSet.FirstOrDefault(v => v.DB_ID == item.DB_ID);                            if (dbdefinition.DB_EQUDATA == item.DB_EQUDATA) continue;                            dbdefinition.DB_EQUDATA = item.DB_EQUDATA;                            db.Updateable(dbdefinition).UpdateColumns(it => new { it.DB_EQUDATA }).ExecuteCommand();                        }                        #endregion;                        #region 写入设备实时报警和条码信息                        var equipmentInfoSet = db.Queryable<WCS_EQUIPMENTINFO>().Where(v => v.Equ_PlcName == PLC_NAME).ToList();                        foreach (var item in WCS_EquipmentInfoSet)                        {                            var equipmentInfo = equipmentInfoSet.FirstOrDefault(v => v.Equ_No == item.Equ_No && v.Equ_Area == item.Equ_Area);                            if (item.Equ_Type == EquipmentType.srm.ToString())                            {                                try                                {                                    var srmMode = (SrmMode)Enum.Parse(typeof(SrmMode), item.EquSignal_Srm.DB521_Auto_status.ToString());                                    var srmStatus = (SrmStatus)Enum.Parse(typeof(SrmStatus), item.EquSignal_Srm.DB521_Srm_Status.ToString());                                    if (equipmentInfo.Equ_AlaramsMsg == item.EquSignal_Srm.SrmFault &&                                        equipmentInfo.Equ_WorkMode == srmMode.ToString() &&                                        equipmentInfo.Equ_SystemStatus == srmStatus.ToString())                                        continue;                                    equipmentInfo.Equ_WorkMode = srmMode.ToString();                                    equipmentInfo.Equ_SystemStatus = srmStatus.ToString();                                }                                catch (Exception ex)                                {                                    Log4netHelper.Logger_Error.ErrorFormat(ex.ToString());                                }                                equipmentInfo.Equ_AlaramsMsg = item.EquSignal_Srm.SrmFault;                                db.Updateable(equipmentInfo).UpdateColumns(it => new { it.Equ_AlaramsMsg, it.Equ_SystemStatus, it.Equ_WorkMode }).ExecuteCommand();                            }                            if (item.Equ_Type == EquipmentType.conveyor.ToString())                            {                                string fault = string.Empty;                                if (item.Equ_No == "1044")                                {                                    if (item.EquSignal_Conv.Conv1044Fault > 0)                                    {                                        fault = item.EquSignal_Conv.Conv1044Fault.ToString();                                    }                                }                                else                                {                                    if (item.EquSignal_Conv.ConvFault > 0)                                    {                                        fault = item.EquSignal_Conv.ConvFault.ToString();                                    }                                }                                if (equipmentInfo.Equ_AlaramsMsg == fault &&                                    equipmentInfo.Equ_BarCode == item.EquSignal_Conv.BarCodeStr)                                     continue;                                equipmentInfo.Equ_AlaramsMsg = fault;                                equipmentInfo.Equ_BarCode = item.EquSignal_Conv.BarCodeStr;                                db.Updateable(equipmentInfo).UpdateColumns(it => new { it.Equ_AlaramsMsg, it.Equ_BarCode }).ExecuteCommand();                            }                            if (item.Equ_Type == EquipmentType.rgv.ToString())                            {                                try                                {                                    var rgvMode = (RgvMode)Enum.Parse(typeof(RgvMode), item.EquSignal_Rgv.DB521_WorkMode.ToString());                                    var rgvStatus = (RgvStatus)Enum.Parse(typeof(RgvStatus), item.EquSignal_Rgv.DB521_SystemStatus.ToString());                                    if (equipmentInfo.Equ_AlaramsMsg == item.EquSignal_Rgv.AlarmFault &&                                        equipmentInfo.Equ_WorkMode == rgvMode.ToString() &&                                        equipmentInfo.Equ_SystemStatus == rgvStatus.ToString())                                        continue;                                    equipmentInfo.Equ_WorkMode = rgvMode.ToString();                                    equipmentInfo.Equ_SystemStatus = rgvStatus.ToString();                                }                                catch (Exception ex)                                {                                    Log4netHelper.Logger_Error.ErrorFormat(ex.ToString());                                }                                                                equipmentInfo.Equ_AlaramsMsg = item.EquSignal_Rgv.AlarmFault;                                db.Updateable(equipmentInfo).UpdateColumns(it => new { it.Equ_AlaramsMsg,it.Equ_SystemStatus,it.Equ_WorkMode }).ExecuteCommand();                            }                            //插入报警记录                            WriteAlaram(db, item);                            //插入超宽超高等报警                            WriteLedAlaram(db, item);                        }                        #endregion;                        #region 写入读码信息到数据库                        var scannSet = db.Queryable<WCS_SCANN>().Where(v => v.SCANN_PLCNAME == PLC_NAME).ToList();                        foreach (var item in scannSet)                        {                            var scannitem = WCS_ScannSet.FirstOrDefault(v => v.SCANN_ID == item.SCANN_ID);                            if (scannitem.SCANN_BARCODE == item.SCANN_BARCODE) continue;                            item.SCANN_BARCODE = scannitem.SCANN_BARCODE;                            item.SCANN_UPDATETIME = DateTime.Now;                            db.Updateable(item).UpdateColumns(it => new { it.SCANN_BARCODE, it.SCANN_UPDATETIME }).ExecuteCommand();                        }                        #endregion;                        return string.Empty;                    });                }                catch (Exception ex)                {                    Log4netHelper.Logger_Error.ErrorFormat(ex.ToString());                }                finally                {                    Interlocked.Exchange(ref readPlcInfoToDataBase, 0);                }            }        }        /// <summary>        /// 记录报警信息        /// </summary>        private void WriteAlaram(SqlSugarClient db, WCS_EQUIPMENTINFO item)        {            // 查询报警记录信息            var alaramRecord = db.Queryable<WCS_ALARAMRECORD>().First(v => v.ALARAMR_EQUNO == item.Equ_No && v.ALARAMR_EQUSTATUS == 2);            if (string.IsNullOrWhiteSpace(item.Equ_AlaramsMsg))            {                if (alaramRecord != null)                {                    //结束报警消息                    alaramRecord.ALARAMR_EQUSTATUS = 1;                    alaramRecord.ALARAMR_ALARAMENDTIME = db.GetDate();                    db.Updateable(alaramRecord).UpdateColumns(it => new { it.ALARAMR_EQUSTATUS, it.ALARAMR_ALARAMENDTIME }).ExecuteCommand();                }            }            else            {                bool isInsert = false;                if(alaramRecord == null)                {                    isInsert = true;                                 }                else                {                    if (alaramRecord.ALARAMR_ALARAMMSG != item.Equ_AlaramsMsg)                    {                        //结束上一个报警消息                        alaramRecord.ALARAMR_EQUSTATUS = 1;                        alaramRecord.ALARAMR_ALARAMENDTIME = db.GetDate();                        db.Updateable(alaramRecord).UpdateColumns(it => new { it.ALARAMR_EQUSTATUS, it.ALARAMR_ALARAMENDTIME }).ExecuteCommand();                        isInsert = true;                    }                }                if (isInsert)                 {                    //添加新的报警消息                    var alaramrecord = new WCS_ALARAMRECORD();                    alaramrecord.ALARAMR_ID = Guid.NewGuid().ToString();                    alaramrecord.ALARAMR_TYPE = "0";                    alaramrecord.ALARAMR_EQUNO = item.Equ_No;                    alaramrecord.ALARAMR_EQUTYPE = item.Equ_Type;                    alaramrecord.ALARAMR_EQUSTATUS = 2;                    alaramrecord.ALARAMR_ALARAMMSG = item.Equ_AlaramsMsg;                    alaramrecord.ALARAMR_ALARAMSTARTTIME = DateTime.Now;                    if (item.Equ_Type == EquipmentType.srm.ToString())                        alaramrecord.ALARAMR_WCSTASKID = Convert.ToInt32(item.EquSignal_Srm.DB520_TaskID);                    else if (item.Equ_Type == EquipmentType.conveyor.ToString())                        alaramrecord.ALARAMR_WCSTASKID = Convert.ToInt32(item.EquSignal_Conv.DB521_Tasknum);                    else if (item.Equ_Type == EquipmentType.rgv.ToString())                        alaramrecord.ALARAMR_WCSTASKID = Convert.ToInt32(item.EquSignal_Rgv.DB521_TaskID_1 == 0 ? item.EquSignal_Rgv.DB521_TaskID_2 : item.EquSignal_Rgv.DB521_TaskID_1);                    db.Insertable(alaramrecord).ExecuteCommand();                }            }        }        private void WriteLedAlaram(SqlSugarClient db, WCS_EQUIPMENTINFO item)        {            int task_no = 0;            string alaram = string.Empty;            if (item.Equ_Type.ToLower() == EquipmentType.conveyor.ToString())            {                if (item.Equ_No == "1104") return;                task_no = Convert.ToInt32(item.EquSignal_Conv.DB521_Tasknum);                StringBuilder sb = new StringBuilder();                if (item.EquSignal_Conv.DB521_Goods_Err)                {                    sb.Append(",外形/条码故障");                }                if (item.EquSignal_Conv.DB521_F_Outside)                {                    sb.Append(",前超长");                }                if (item.EquSignal_Conv.DB521_B_Outside)                {                    sb.Append(",后超长");                }                if (item.EquSignal_Conv.DB521_L_Outside)                {                    sb.Append(",左超宽");                }                if (item.EquSignal_Conv.DB521_R_Outside)                {                    sb.Append(",右超宽");                }                //if (item.StackerData.DB521_H_Outside)                //{                //    sb.Append(",超高");                //}                if (item.EquSignal_Conv.DB521_BCR_Noread)                {                    sb.Append(",条码未读出");                }                if (item.EquSignal_Conv.DB521_Overload)                {                    sb.Append(",超重");                }                alaram = sb.ToString().TrimStart(',');            }            //else if (item.STA_TYPE.ToLower() == EquipmentType.rgv.ToString())            //{            //    task_no = item.RGVSignalItem.DB521_TaskID_1;            //    StringBuilder sb = new StringBuilder();            //    if ((int)item.RGVSignalItem.AlarmFault1 != 0)            //    {            //        sb.Append(string.Format(",{0}", item.RGVSignalItem.AlarmFault1));            //    }            //    if ((int)item.RGVSignalItem.AlarmFault2 != 0)            //    {            //        sb.Append(string.Format(",{0}", item.RGVSignalItem.AlarmFault2));            //    }            //    if ((int)item.RGVSignalItem.AlarmFault3 != 0)            //    {            //        sb.Append(string.Format(",{0}", item.RGVSignalItem.AlarmFault3));            //    }            //}            if (!string.IsNullOrWhiteSpace(alaram))            {                string msg = string.Format("[{0}][{1}]", item.Equ_No, alaram);                BaseWorkflow.AddLedErrorMsg(db, item.Equ_No, msg, task_no);                //ThreadHelper.TaskThread(BaseWorkflow.UploadExcTask, new { EquipmentNo = item.STA_EQUIPMENTNO, Alaram = alaram });            }        }        #endregion;    }    public class WCS_PLCList    {        public static void ExecuteWcs_Workflow()        {            foreach (var item in Current.PlcSet)            {                if (item.PLC_ISENABLE)                {                    //不同PLC CPU多线程读取信号                    ThreadHelper.TaskThread(item.ExecuteWcs_Workflow);                }            }        }    }}
 |