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