using HslCommunication.ModBus;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Threading;
|
using WIDESEA_Core.Extensions;
|
using WIDESEA_Entity.DomainModels;
|
using WIDESEA_WCS.WCSClient.Melsec;
|
using WIDESEA_WCS.WCSClient.Modbus;
|
using WIDESEA_WCS.WCSClient.Omron;
|
using WIDESEA_WCS.WCSClient.Siemens;
|
|
namespace WIDESEA_WCS.WCSClient
|
{
|
public class PLCClient
|
{
|
/// <summary>
|
/// PLC连接名称
|
/// </summary>
|
public string PLCName { get; set; }
|
|
/// <summary>
|
/// PLC类型
|
/// </summary>
|
public string PLCType { get; set; }
|
|
/// <summary>
|
/// 西门子 PLC
|
/// </summary>
|
public SiemensPLCClient SiemensPLCClient { get; set; }
|
|
/// <summary>
|
/// 欧姆龙 PLC
|
/// </summary>
|
public OmronPLCClient OmronPLCClient { get; set; }
|
|
/// <summary>
|
/// 三菱 PLC
|
/// </summary>
|
public MelsecPLCClient MelsecPLCClient { get; set; }
|
|
|
/// <summary>
|
/// Modbus PLC
|
/// </summary>
|
public ModbusPLCClient ModbusPLCClient { get; set; }
|
|
/// <summary>
|
/// 上料口
|
/// </summary>
|
public string EquipType { get; set; }
|
|
/// <summary>
|
/// 下料口1
|
/// </summary>
|
public string PLCDescroption { get; set; }
|
/// <summary>
|
/// 下料口2
|
/// </summary>
|
public string PLCDownLoc { get; set; }
|
|
/// <summary>
|
/// 心跳
|
/// </summary>
|
public bool Heart { get; set; }
|
|
/// <summary>
|
/// 是否已连接
|
/// </summary>
|
public bool IsConnected { get; set; } = false;
|
|
public PLCClient(dt_plcinfohead head, List<dt_plcinfodetail> plcinfodetails)
|
{
|
PLCType = head.plcinfo_type;
|
switch (PLCType)
|
{
|
case "SiemensPLC":
|
SiemensPLCClient = new SiemensPLCClient(HslCommunication.Profinet.Siemens.SiemensPLCS.S1200)
|
{
|
PLCIPAddress = head.plcinfo_ip,
|
PLCName = head.plcinfo_name,
|
PLCDescroption = head.plcinfo_remark,
|
PLCDBItems = plcinfodetails.Where(x => x.plcdetail_opratortype == head.plcinfo_equiptype).Select(x => new DBItemGroup { ItemAddress = x.plcdetail_db.Trim() + "." + x.plcdetail_value.Trim(), ItemDataType = x.plcdetail_valtype.Trim(), ItemName = x.plcdetail_name.Trim(), ItemOperatorType = x.plcdetail_opratortype?.Trim(), EquipNum = x.plcdetail_number.Trim(), Remark = x.plcdetail_remark.Trim() }).ToList(),
|
Slot = 1
|
};
|
break;
|
case "OmronPLC":
|
OmronPLCClient = new OmronPLCClient()
|
{
|
PLCIPAddress = head.plcinfo_ip,
|
PLCName = head.plcinfo_name,
|
PLCDescroption = head.plcinfo_remark,
|
PLCDBItems = plcinfodetails.Where(x => x.plcdetail_opratortype == head.plcinfo_equiptype).Select(x => new DBItemGroup { ItemAddress = x.plcdetail_db.Trim() + "." + x.plcdetail_value.Trim(), ItemDataType = x.plcdetail_valtype.Trim(), ItemName = x.plcdetail_name.Trim(), ItemOperatorType = x.plcdetail_opratortype?.Trim(), EquipNum = x.plcdetail_number.Trim(), Remark = x.plcdetail_remark.Trim() }).ToList()
|
};
|
break;
|
case "MelsecPLC":
|
MelsecPLCClient = new MelsecPLCClient()
|
{
|
PLCIPAddress = head.plcinfo_ip,
|
PLCName = head.plcinfo_name,
|
PLCDescroption = head.plcinfo_remark,
|
PLCDBItems = plcinfodetails.Where(x => x.plcdetail_opratortype == head.plcinfo_equiptype)
|
.Select(x => new DBItemGroup
|
{
|
ItemAddress = x.plcdetail_db.Trim() +
|
(string.IsNullOrEmpty(x.plcdetail_value.Trim()) ? "" : "." + x.plcdetail_value.Trim()),
|
ItemDataType = x.plcdetail_valtype.Trim(),
|
ItemName = x.plcdetail_name.Trim(),
|
ItemOperatorType = x.plcdetail_opratortype?.Trim(),
|
EquipNum = x.plcdetail_number.Trim(),
|
Remark = x.plcdetail_remark.Trim()
|
}).ToList()
|
};
|
break;
|
case "ModbusPLCClient":
|
ModbusPLCClient = new ModbusPLCClient()
|
{
|
PLCIPAddress = head.plcinfo_ip,
|
PLCName = head.plcinfo_name,
|
PLCDescroption = head.plcinfo_remark,
|
PLCDBItems = plcinfodetails.Where(x => x.plcdetail_headid == head.plcinfo_id).Select(x => new DBItemGroup { ItemAddress = x.plcdetail_db.Trim() + "." + x.plcdetail_value.Trim(), ItemDataType = x.plcdetail_valtype.Trim(), ItemName = x.plcdetail_name.Trim(), ItemOperatorType = x.plcdetail_opratortype?.Trim(), EquipNum = x.plcdetail_number.Trim(), Remark = x.plcdetail_remark.Trim() }).ToList()
|
};
|
break;
|
}
|
}
|
|
#region 连接PLC,将短连接切换成长连接模式
|
/// <summary>
|
/// 连接PLC
|
/// </summary>
|
public string Connect()
|
{
|
string str = "";
|
switch (PLCType)
|
{
|
case "SiemensPLC":
|
str = SiemensPLCClient.Connect();
|
IsConnected = SiemensPLCClient.IsConnected;
|
break;
|
case "OmronPLC":
|
str = OmronPLCClient.Connect();
|
IsConnected = OmronPLCClient.IsConnected;
|
break;
|
case "MelsecPLC":
|
str = MelsecPLCClient.Connect();
|
IsConnected = MelsecPLCClient.IsConnected;
|
break;
|
case "ModbusPLCClient":
|
str = ModbusPLCClient.Connect();
|
IsConnected = ModbusPLCClient.IsConnected;
|
break;
|
default:
|
throw new Exception($"PLC,{PLCType}未定义该类型");
|
}
|
return str;
|
}
|
#endregion
|
|
#region 断开与PLC的连接,将短连接切换成长连接模式
|
/// <summary>
|
/// 断开与PLC的连接
|
/// </summary>
|
public void Disconnect()
|
{
|
switch (PLCType)
|
{
|
case "SiemensPLC":
|
SiemensPLCClient.Disconnect();
|
IsConnected = SiemensPLCClient.IsConnected;
|
break;
|
case "OmronPLC":
|
OmronPLCClient.Disconnect();
|
IsConnected = OmronPLCClient.IsConnected;
|
break;
|
case "MelsecPLC":
|
MelsecPLCClient.Disconnect();
|
IsConnected = MelsecPLCClient.IsConnected;
|
break;
|
case "ModbusPLCClient":
|
ModbusPLCClient.Disconnect();
|
IsConnected = ModbusPLCClient.IsConnected;
|
break;
|
}
|
}
|
#endregion
|
|
#region 根据名称/描述读取PLC数据
|
/// <summary>
|
/// 根据名称/描述读取PLC数据
|
/// </summary>
|
/// <param name="itemName">名称/描述(数据库中plcdetail_name列)</param>
|
/// <returns></returns>
|
public virtual object ReadValue(string itemName)
|
{
|
object result = null;
|
switch (PLCType)
|
{
|
case "SiemensPLC":
|
result = SiemensPLCClient.ReadValue(itemName);
|
break;
|
case "OmronPLC":
|
result = OmronPLCClient.ReadValue(itemName);
|
break;
|
case "MelsecPLC":
|
result = MelsecPLCClient.ReadValue(itemName);
|
break;
|
default:
|
throw new Exception($"PLC类型{PLCType}不存在");
|
}
|
return result;
|
|
}
|
|
public virtual object ReadDBValue(string itemName, int len = 1)
|
{
|
object result = null;
|
switch (PLCType)
|
{
|
case "SiemensPLC":
|
result = SiemensPLCClient.ReadDBValue(itemName, len);
|
break;
|
case "MelsecPLC":
|
result = MelsecPLCClient.ReadDBValue(itemName, len);
|
break;
|
default:
|
throw new Exception($"PLC类型{PLCType}不存在");
|
}
|
return result;
|
}
|
#endregion
|
|
#region 根据PLCDBItem读取PLC数据
|
/// <summary>
|
/// 根据PLCDBItem读取PLC数据
|
/// </summary>
|
/// <param name="item"></param>
|
/// <returns></returns>
|
public virtual object ReadValue(DBItemGroup item)
|
{
|
object result = null;
|
switch (PLCType)
|
{
|
case "SiemensPLC":
|
result = SiemensPLCClient.ReadValue(item);
|
break;
|
case "OmronPLC":
|
result = OmronPLCClient.ReadValue(item);
|
break;
|
case "MelsecPLC":
|
result = MelsecPLCClient.ReadValue(item);
|
break;
|
}
|
return result;
|
}
|
#endregion
|
|
#region 根据设备编号读取PLC数据
|
/// <summary>
|
/// 根据设备编号读取PLC数据
|
/// </summary>
|
/// <param name="equipNum">设备编号</param>
|
/// <returns>json字符串</returns>
|
public object ReadValues(string equipNum)
|
{
|
object result = null;
|
switch (PLCType)
|
{
|
case "SiemensPLC":
|
result = SiemensPLCClient.ReadValues(equipNum);
|
break;
|
case "OmronPLC":
|
result = OmronPLCClient.ReadValues(equipNum);
|
break;
|
case "MelsecPLC":
|
result = MelsecPLCClient.ReadValues(equipNum);
|
break;
|
}
|
return result;
|
|
}
|
#endregion
|
|
#region 根据名称/描述读取PLC数据返回设备编号和值的JSON字符串
|
/// <summary>
|
/// 根据名称/描述读取PLC数据返回设备编号和值的JSON字符串
|
/// </summary>
|
/// <param name="itemName">名称/描述(数据库中plcdetail_name列)</param>
|
/// <returns>json字符串</returns>
|
public string ReadValuesByItemName(string itemName)
|
{
|
object result = null;
|
switch (PLCType)
|
{
|
case "SiemensPLC":
|
result = SiemensPLCClient.ReadValues(itemName);
|
break;
|
case "OmronPLC":
|
result = OmronPLCClient.ReadValues(itemName);
|
break;
|
case "MelsecPLC":
|
result = MelsecPLCClient.ReadValues(itemName);
|
break;
|
}
|
return result.Serialize();
|
|
}
|
#endregion
|
|
#region 根据名称/描述和设备编号读取PLC数据
|
/// <summary>
|
/// 根据名称/描述和设备编号读取PLC数据
|
/// </summary>
|
/// <param name="itemName">名称/描述(数据库中plcdetail_name列)</param>
|
/// <param name="equipNum">设备编号</param>
|
/// <returns></returns>
|
public virtual object ReadValue(string itemName, string equipNum)
|
{
|
object result = null;
|
switch (PLCType)
|
{
|
case "SiemensPLC":
|
result = SiemensPLCClient.ReadValue(itemName, equipNum);
|
break;
|
case "OmronPLC":
|
result = OmronPLCClient.ReadValue(itemName, equipNum);
|
break;
|
case "MelsecPLC":
|
result = MelsecPLCClient.ReadValue(itemName, equipNum);
|
break;
|
}
|
return result.Serialize();
|
}
|
#endregion
|
|
#region 将数据写入到PLC中
|
/// <summary>
|
/// 将数据写入到PLC中
|
/// </summary>
|
/// <param name="itemName">名称/描述(数据库中plcdetail_name列)</param>
|
/// <param name="value">写入的值</param>
|
/// <returns></returns>
|
public virtual bool WriteValue(string itemName, object value)
|
{
|
bool result = false;
|
switch (PLCType)
|
{
|
case "SiemensPLC":
|
result = SiemensPLCClient.WriteValue(itemName, value);
|
break;
|
case "OmronPLC":
|
result = OmronPLCClient.WriteValue(itemName, value);
|
break;
|
case "MelsecPLC":
|
result = MelsecPLCClient.WriteValue(itemName, value);
|
break;
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 将数据写入到PLC中
|
/// </summary>
|
/// <param name="address">名称/描述(数据库中plcdetail_name列)</param>
|
/// <param name="value">写入的值</param>
|
/// <returns></returns>
|
public virtual bool WriteDBValue(string address, object value)
|
{
|
bool result = false;
|
switch (PLCType)
|
{
|
case "SiemensPLC":
|
result = SiemensPLCClient.WriteDBValue(address, value);
|
break;
|
case "MelsecPLC":
|
result = MelsecPLCClient.WriteDBValue(address, value);
|
break;
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 将数据写入PLC,并查询是否成功
|
/// </summary>
|
/// <param name="itemName">指令代码</param>
|
/// <param name="value">值</param>
|
/// <param name="tryTimes">重试次数</param>
|
public virtual void WriteValue(string itemName, object value, int tryTimes)
|
{
|
bool res = false;
|
tryTimes = tryTimes > 0 ? tryTimes : 1;
|
if (PLCType == "SiemensPLC")
|
{
|
for (int i = 0; i < tryTimes; i++)
|
{
|
SiemensPLCClient.WriteValue(itemName, value);
|
Thread.Sleep(1000);
|
|
var item = SiemensPLCClient.PLCDBItems.FirstOrDefault(t => t.ItemName == itemName);
|
var readValue = SiemensPLCClient.ReadValue(itemName);
|
if (value.ToString() == readValue.ToString())
|
{
|
res = true;
|
break;
|
}
|
}
|
}
|
if (!res)
|
{
|
throw new Exception($"{itemName},值{value}写入失败!");
|
}
|
}
|
#endregion
|
|
#region 将数据写入到PLC中
|
/// <summary>
|
/// 将数据写入到PLC中
|
/// </summary>
|
/// <param name="itemName">名称/描述(数据库中plcdetail_name列)</param>
|
/// <param name="value">写入的值</param>
|
/// <returns></returns>
|
public virtual bool WriteValue(string itemName, string equipNum, object value)
|
{
|
bool result = false;
|
switch (PLCType)
|
{
|
case "SiemensPLC":
|
result = SiemensPLCClient.WriteValue(itemName, equipNum, value);
|
break;
|
case "OmronPLC":
|
result = OmronPLCClient.WriteValue(itemName, equipNum, value);
|
break;
|
case "MelsecPLC":
|
result = MelsecPLCClient.WriteValue(itemName, equipNum, value);
|
break;
|
}
|
return result;
|
}
|
#endregion
|
|
}
|
}
|