using OpcAccess.Access.Entity; using OpcAccess.Properties; using OpcAccess.Utils; using OPCAutomation; using System; using System.Collections.Generic; namespace OpcAccess.Access.Service { public class OpcAccessService { private string ProgId; private string Ip; private OPCServer Server = null; //客户端句柄 private int ClientHander = 0; //以组名+db块名为键,以生存的db块在服务器上的句柄为值的字典 private Dictionary ItemHandleDict; /// /// 默认ProgId为"OPC.SimaticNET"的构造函数 /// /// 连接ip public OpcAccessService(string ip) { this.ProgId = "OPC.SimaticNET"; this.Ip = ip; } /// /// /构造函数 /// /// 程序名 /// 地址 public OpcAccessService(string prodId, string ip) { this.ProgId = prodId; this.Ip = ip; } /// /// 连接OPC服务器 /// /// 是否连接成功 public bool Connect() { try { this.Server = new OPCServer(); Server.Connect(ProgId, Ip); return true; } catch (Exception) { LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "Connect", "连接OPC服务器失败"); return false; } } /// /// 销毁OPC服务 /// public void DisConnect() { if (this.Server == null) { return; } this.Server.OPCGroups.RemoveAll(); this.Server.Disconnect(); this.Server = null; } /// /// 根据OPC组来初始化OPC访问 /// /// opc组 /// 是否初始化成功 public bool Init(List groups) { if (!Connect()) { return false; } ItemHandleDict = new Dictionary(); var groupNames = new List(); groups.ForEach(x => groupNames.Add(x.Name)); if (!AddGroup(groupNames)) { return false;} groups.ForEach(x => x.Items.ForEach(y => ItemHandleDict.Add(x.Name + "_" + y.Db, AddItem(x.Name, y.Db, ClientHander++)))); return true; } /// /// 添加地址组 /// /// 地址组 private bool AddGroup(string groupName) { if (this.Server != null) { this.Server.OPCGroups.Add(groupName); return true; } return false; } /// /// 批量添加地址组 /// /// 地址组列表 private bool AddGroup(List groupNames) { if (this.Server != null) { groupNames.ForEach(x => this.Server.OPCGroups.Add(x)); return true; } return false; } /// /// 添加地址项 /// /// 地址项 /// 地址项的客户端句柄 /// 添加项在服务器上的句柄 private int AddItem(string groupName, string itemName, int clientHandle) { try { var item = this.Server.OPCGroups.GetOPCGroup(groupName).OPCItems.AddItem(itemName, clientHandle); return item.ServerHandle; } catch (Exception ex) { LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "AddItem", ex.Message); return -1; } } /// /// 批量添加地址项 /// /// 地址项列表 /// 地址项的客户端句柄列表 /// 添加项在服务器上的句柄列表 private List AddItem(string groupName, List itemNames, List clientHandles) { var itemIds = new List(); try { for (int i = 0; i < itemNames.Count; i++) { var item = this.Server.OPCGroups.GetOPCGroup(groupName).OPCItems.AddItem(itemNames[i], clientHandles[i]); itemIds.Add(item.ServerHandle); } return itemIds; } catch (Exception ex) { LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "AddItem", ex.Message); return itemIds; } } /// /// 写入单点地址的值 /// /// 组名 /// 值的句柄 /// 值 /// 是否写入成功 private bool WriteValuePoint(string groupName, int serverHandle, object value) { try { var group = Server.OPCGroups.GetOPCGroup(groupName); var item = group.OPCItems.GetOPCItem(serverHandle); item.Write(value == null ? "" : value); return true; } catch (Exception ex) { LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "WriteValuePoint", ex.Message); return false; } } /// /// 批量写入地址的值 /// /// 组名 /// 值的句柄列表 /// 写入值列表 /// 是否写入成功 private bool WriteValuePoint(string groupName, List serverHandles, List values) { try { var group = Server.OPCGroups.GetOPCGroup(groupName); for(int i = 0; i< serverHandles.Count; i++) { var item = group.OPCItems.GetOPCItem(serverHandles[i]); item.Write(values[i] == null ? "" : values[i]); } return true; } catch (Exception ex) { LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "WriteValuePoint", ex.Message); return false; } } /// /// 单值读取 /// /// 服务器地址句柄 /// 读到的值 private OpcDataValue ReadValuePoint(string groupName, int serverHandle) { var group = Server.OPCGroups.GetOPCGroup(groupName); var item = group.OPCItems.GetOPCItem(serverHandle); object itemValue, quality, timeStamp; item.Read(2, out itemValue, out quality, out timeStamp); return new OpcDataValue { ItemValue = itemValue, Quality = quality, TimeStamp = timeStamp }; } /// /// 批量读取OPC的值 /// /// 服务器地址句柄 /// 读到的值 private List ReadValuePoint(string groupName, List serverHandles) { var values = new List(); var h = 0; try { var group = Server.OPCGroups.GetOPCGroup(groupName); foreach (var serverHandle in serverHandles) { var item = group.OPCItems.GetOPCItem(serverHandle); object itemValue, quality, timeStamp; h = serverHandle; item.Read(2, out itemValue, out quality, out timeStamp); values.Add(new OpcDataValue { ItemValue = itemValue, Quality = quality, TimeStamp = timeStamp }); } return values; } catch (Exception ex) { LogTextHelper.WriteLog(Resources.LogDir, this.ToString(), "ReadValuePoint", "msg={0},group={1},handle={1}",ex.Message,groupName,h); return values; } } /// /// 写入单点地址的值 /// /// 组名 /// db块 /// 值 /// 是否写入成功 public bool WriteValuePoint(string groupName, string itemName, object value) { if (!ItemHandleDict.ContainsKey(groupName + "_" + itemName)) { return false; } return WriteValuePoint(groupName, ItemHandleDict[groupName + "_" + itemName], value); } /// /// 批量写入地址的值 /// /// 组名 /// 值的句柄列表 /// 写入值列表 /// 是否写入成功 public bool WriteValuePoint(string groupName, List itemNames, List values) { foreach(var itemName in itemNames) { if (!ItemHandleDict.ContainsKey(groupName + "_" + itemName)) { return false; } } var serverHandles = new List(); itemNames.ForEach(x => serverHandles.Add(ItemHandleDict[groupName + "_" + x])); return WriteValuePoint(groupName, serverHandles, values); } /// /// 单值读取 /// /// db块地址 /// 读到的值 public OpcDataValue ReadValuePoint(string groupName, string itemName) { if (!ItemHandleDict.ContainsKey(groupName + "_" + itemName)) { return null; } return ReadValuePoint(groupName, ItemHandleDict[groupName + "_" + itemName]); } /// /// 批量读取OPC的值 /// /// 服务器地址句柄 /// 读到的值 public List ReadValuePoint(string groupName, List itemNames) { foreach (var itemName in itemNames) { if (!ItemHandleDict.ContainsKey(groupName + "_" + itemName)) { return new List(); } } var serverHandles = new List(); itemNames.ForEach(x => serverHandles.Add(ItemHandleDict[groupName + "_" + x])); return ReadValuePoint(groupName, serverHandles); } } }