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<string, int> ItemHandleDict;
|
|
/// <summary>
|
/// 默认ProgId为"OPC.SimaticNET"的构造函数
|
/// </summary>
|
/// <param name="ip">连接ip</param>
|
public OpcAccessService(string ip)
|
{
|
this.ProgId = "OPC.SimaticNET";
|
this.Ip = ip;
|
}
|
|
/// <summary>
|
/// /构造函数
|
/// </summary>
|
/// <param name="prodId">程序名</param>
|
/// <param name="ip">地址</param>
|
public OpcAccessService(string prodId, string ip)
|
{
|
this.ProgId = prodId;
|
this.Ip = ip;
|
}
|
|
|
/// <summary>
|
/// 连接OPC服务器
|
/// </summary>
|
/// <returns>是否连接成功</returns>
|
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;
|
}
|
}
|
|
/// <summary>
|
/// 销毁OPC服务
|
/// </summary>
|
public void DisConnect()
|
{
|
if (this.Server == null)
|
{
|
return;
|
}
|
this.Server.OPCGroups.RemoveAll();
|
this.Server.Disconnect();
|
this.Server = null;
|
}
|
|
/// <summary>
|
/// 根据OPC组来初始化OPC访问
|
/// </summary>
|
/// <param name="groups">opc组</param>
|
/// <returns>是否初始化成功</returns>
|
public bool Init(List<OpcGroupEntity> groups)
|
{
|
if (!Connect()) { return false; }
|
ItemHandleDict = new Dictionary<string, int>();
|
var groupNames = new List<string>();
|
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;
|
}
|
|
/// <summary>
|
/// 添加地址组
|
/// </summary>
|
/// <param name="groupName">地址组</param>
|
private bool AddGroup(string groupName)
|
{
|
if (this.Server != null)
|
{
|
this.Server.OPCGroups.Add(groupName);
|
return true;
|
}
|
return false;
|
}
|
|
/// <summary>
|
/// 批量添加地址组
|
/// </summary>
|
/// <param name="groupNames">地址组列表</param>
|
private bool AddGroup(List<string> groupNames)
|
{
|
if (this.Server != null)
|
{
|
groupNames.ForEach(x => this.Server.OPCGroups.Add(x));
|
return true;
|
}
|
return false;
|
}
|
|
|
/// <summary>
|
/// 添加地址项
|
/// </summary>
|
/// <param name="itemName">地址项</param>
|
/// <param name="clientHandle">地址项的客户端句柄</param>
|
/// <returns>添加项在服务器上的句柄</returns>
|
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;
|
}
|
}
|
|
/// <summary>
|
/// 批量添加地址项
|
/// </summary>
|
/// <param name="itemNames">地址项列表</param>
|
/// <param name="clientHandles">地址项的客户端句柄列表</param>
|
/// <returns>添加项在服务器上的句柄列表</returns>
|
private List<int> AddItem(string groupName, List<string> itemNames, List<int> clientHandles)
|
{
|
var itemIds = new List<int>();
|
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;
|
}
|
}
|
|
/// <summary>
|
/// 写入单点地址的值
|
/// </summary>
|
/// <param name="groupName">组名</param>
|
/// <param name="serverHandle">值的句柄</param>
|
/// <param name="value">值</param>
|
/// <returns>是否写入成功</returns>
|
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;
|
}
|
}
|
|
/// <summary>
|
/// 批量写入地址的值
|
/// </summary>
|
/// <param name="groupName">组名</param>
|
/// <param name="serverHandles">值的句柄列表</param>
|
/// <param name="values">写入值列表</param>
|
/// <returns>是否写入成功</returns>
|
private bool WriteValuePoint(string groupName, List<int> serverHandles, List<object> 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;
|
}
|
}
|
|
/// <summary>
|
/// 单值读取
|
/// </summary>
|
/// <param name="itemName">服务器地址句柄</param>
|
/// <returns>读到的值</returns>
|
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
|
};
|
|
}
|
|
/// <summary>
|
/// 批量读取OPC的值
|
/// </summary>
|
/// <param name="serverHandles">服务器地址句柄</param>
|
/// <returns>读到的值</returns>
|
private List<OpcDataValue> ReadValuePoint(string groupName, List<int> serverHandles)
|
{
|
var values = new List<OpcDataValue>();
|
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;
|
}
|
}
|
|
/// <summary>
|
/// 写入单点地址的值
|
/// </summary>
|
/// <param name="groupName">组名</param>
|
/// <param name="itemName">db块</param>
|
/// <param name="value">值</param>
|
/// <returns>是否写入成功</returns>
|
public bool WriteValuePoint(string groupName, string itemName, object value)
|
{
|
if (!ItemHandleDict.ContainsKey(groupName + "_" + itemName))
|
{
|
return false;
|
}
|
|
return WriteValuePoint(groupName, ItemHandleDict[groupName + "_" + itemName], value);
|
}
|
|
|
/// <summary>
|
/// 批量写入地址的值
|
/// </summary>
|
/// <param name="itemNames">组名</param>
|
/// <param name="clientHandles">值的句柄列表</param>
|
/// <param name="values">写入值列表</param>
|
/// <returns>是否写入成功</returns>
|
public bool WriteValuePoint(string groupName, List<string> itemNames, List<object> values)
|
{
|
foreach(var itemName in itemNames)
|
{
|
if (!ItemHandleDict.ContainsKey(groupName + "_" + itemName))
|
{
|
return false;
|
}
|
}
|
var serverHandles = new List<int>();
|
itemNames.ForEach(x => serverHandles.Add(ItemHandleDict[groupName + "_" + x]));
|
return WriteValuePoint(groupName, serverHandles, values);
|
}
|
|
/// <summary>
|
/// 单值读取
|
/// </summary>
|
/// <param name="itemName">db块地址</param>
|
/// <returns>读到的值</returns>
|
public OpcDataValue ReadValuePoint(string groupName, string itemName)
|
{
|
if (!ItemHandleDict.ContainsKey(groupName + "_" + itemName))
|
{
|
return null;
|
}
|
return ReadValuePoint(groupName, ItemHandleDict[groupName + "_" + itemName]);
|
|
}
|
|
/// <summary>
|
/// 批量读取OPC的值
|
/// </summary>
|
/// <param name="itemNames">服务器地址句柄</param>
|
/// <returns>读到的值</returns>
|
public List<OpcDataValue> ReadValuePoint(string groupName, List<string> itemNames)
|
{
|
foreach (var itemName in itemNames)
|
{
|
if (!ItemHandleDict.ContainsKey(groupName + "_" + itemName))
|
{
|
return new List<OpcDataValue>();
|
}
|
}
|
var serverHandles = new List<int>();
|
itemNames.ForEach(x => serverHandles.Add(ItemHandleDict[groupName + "_" + x]));
|
return ReadValuePoint(groupName, serverHandles);
|
}
|
}
|
}
|