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