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
{
///
/// PLC连接名称
///
public string PLCName { get; set; }
///
/// PLC类型
///
public string PLCType { get; set; }
///
/// 西门子 PLC
///
public SiemensPLCClient SiemensPLCClient { get; set; }
///
/// 欧姆龙 PLC
///
public OmronPLCClient OmronPLCClient { get; set; }
///
/// 三菱 PLC
///
public MelsecPLCClient MelsecPLCClient { get; set; }
///
/// Modbus PLC
///
public ModbusPLCClient ModbusPLCClient { get; set; }
///
/// 上料口
///
public string EquipType { get; set; }
///
/// 下料口1
///
public string PLCDescroption { get; set; }
///
/// 下料口2
///
public string PLCDownLoc { get; set; }
///
/// 心跳
///
public bool Heart { get; set; }
///
/// 是否已连接
///
public bool IsConnected { get; set; } = false;
public dt_plcinfohead Head { get; set; }
public List Plcinfodetails { get; set; }
public PLCClient(dt_plcinfohead head, List plcinfodetails)
{
PLCType = head.plcinfo_type;
Head = head;
Plcinfodetails = plcinfodetails;
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,将短连接切换成长连接模式
///
/// 连接PLC
///
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的连接,将短连接切换成长连接模式
///
/// 断开与PLC的连接
///
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数据
///
/// 根据名称/描述读取PLC数据
///
/// 名称/描述(数据库中plcdetail_name列)
///
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数据
///
/// 根据PLCDBItem读取PLC数据
///
///
///
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数据
///
/// 根据设备编号读取PLC数据
///
/// 设备编号
/// json字符串
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字符串
///
/// 根据名称/描述读取PLC数据返回设备编号和值的JSON字符串
///
/// 名称/描述(数据库中plcdetail_name列)
/// json字符串
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数据
///
/// 根据名称/描述和设备编号读取PLC数据
///
/// 名称/描述(数据库中plcdetail_name列)
/// 设备编号
///
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中
///
/// 将数据写入到PLC中
///
/// 名称/描述(数据库中plcdetail_name列)
/// 写入的值
///
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;
}
///
/// 将数据写入到PLC中
///
/// 名称/描述(数据库中plcdetail_name列)
/// 写入的值
///
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;
}
///
/// 将数据写入PLC,并查询是否成功
///
/// 指令代码
/// 值
/// 重试次数
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中
///
/// 将数据写入到PLC中
///
/// 名称/描述(数据库中plcdetail_name列)
/// 写入的值
///
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
}
}