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; } /// /// WCS系统 /// public string PLC_WCSSYSTEM { get; set; } /// /// plc实例数量 /// public int PLC_INSTANCECOUNT { get; set; } public string PLC_NOTES { get; set; } /// /// 未完成任务 /// public int? PLC_UNEXECUTETASK { get; set; } /// /// 最后完成时间 /// public DateTime? PLC_LASTFINISHTIME { get; set; } [SugarColumn(IsIgnore = true)] public PLC Plc { get { return PlcInstanceSet.FirstOrDefault(); } } /// /// PLC实例列表 /// public List PlcInstanceSet = new List(); [SugarColumn(IsIgnore = true)] public PLC Plc2 { get; set; } //PLC是否连接成功 [SugarColumn(IsIgnore = true)] public bool IsConnSuccess { get; set; } //DB集合 public List WCS_DBSet = new List(); //扫描的条码集合 [SugarColumn(IsIgnore = true)] public List WCS_ScannSet { get; set; } //设备信号集合 [SugarColumn(IsIgnore = true)] public List 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]; //} } /// /// 读取PLC信号 /// 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; } /// /// 连接电控设备 /// //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); } } /// /// 连接电控设备 /// 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; } /// /// 连接电控设备 /// 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(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; } } } /// /// 读取缓存信号到实体 /// 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().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().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().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); } } } /// /// 记录报警信息 /// private void WriteAlaram(SqlSugarClient db, WCS_EQUIPMENTINFO item) { // 查询报警记录信息 var alaramRecord = db.Queryable().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); } } } } }