吉林安睿特调度
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

506 lines
21 KiB

using System;
using System.Collections.Generic;
using System.Text;
using Opc.Ua;
using Opc.Ua.Client;
using System.Threading;
using System.Data;
using DBFactory;
using CommonLib;
using Siemens.OpcUA;
namespace OPCClient
{
public static class CCommonOPCClient
{
private static Model.MDevice devinfo;
private static Object thisLock = new Object();
public static event CUpdateDBEventHandler UpdateDB;
public static void OnUpdateDB(object sender,CUpdateDBChangeEventArgs e)
{
if (UpdateDB != null)
{
UpdateDB(sender, e);
}
}
public static DBOperator dbo = CommonClassLib.AppSettings.dbo; //20130510
//20110726
private static Dictionary<string, int> _connectCount = new Dictionary<string, int>();
//20110726
public static Dictionary<string, int> ConnectCount
{
get { return CCommonOPCClient._connectCount; }
set { CCommonOPCClient._connectCount = value; }
}
private static int[] _plcStates=null ;
public static int[] PlcStates
{
get { return CCommonOPCClient._plcStates; }
//set { CCommonOPCClient._plcStates = value; }
}
private static Server m_Server = null;
private static Siemens.OpcUA.Subscription m_Subscription;
/// <summary>
/// 20110309���ĵ����ڱ�ǩ���ݱ仯�¼�
/// </summary>
/// <param name="subscriptionHandle">�ͻ��˾���</param>
/// <param name="requestHandle">��������</param>
/// <param name="values">��ǩֵ����</param>
public static void OnDataChange(object clientHandle, DataValue value)
{
lock (thisLock)
{
//����subscriptionHandle��Ӧ�豸�����������豸���ࣨ��ͬ�����豸ͨѶ����֡��ͬ��
//�ֱ����������ɣ����������翪�أ�PLC����������
int deviceindex = 0;
try
{
if (clientHandle.ToString().IndexOf("split") >= 0)
{
deviceindex = System.Convert.ToInt32(clientHandle.ToString().Substring(5));
}
else
{
deviceindex = System.Convert.ToInt32(clientHandle);
}
devinfo = Model.CGetInfo.GetDeviceInfo(deviceindex);
if (!StatusCode.IsGood(value.StatusCode))
{
if (devinfo == null)
{
OpcError = string.Format("�豸����{0}�����ݿⲻ���ڣ�", clientHandle);
return;
}
//if (value.StatusCode.ToString() == "BadNoCommunication")
//{
// CCommonOPCClient.Hostname = CommonClassLib.AppSettings.GetValue("HostName");//20090922 devinfo.RemoteIP;
// CCommonOPCClient.ProgID = CommonClassLib.AppSettings.GetValue("OPCProgID");
// CCommonOPCClient.PlcConnectionID = devinfo.S7Connection;//20110216
// StringBuilder[] itemnames = new StringBuilder[1] { new StringBuilder("") };
// itemnames[0].Append(Model.CGeneralFunction.DBGet).Append(".").Append(Convert.ToString(devinfo.Dbw2Address)).Append(",b");
// DataValueCollection dvc= SyncReadAllItemValue(itemnames);
// if (dvc.Count > 0)
// {
// value = dvc[0];
// }
// OpcError = string.Format("{0}���ڵ�PLC�Ѿ����ߣ��Զ����¶�ȡ���ݣ����ı�ǩ״̬��" + value.StatusCode.ToString(), clientHandle);
// //return;
//}
//����һ�������¼���ʾPLC�Ͽ�����
if (ConnectCount.ContainsKey(devinfo.S7Connection) == false)//20110726
{
ConnectCount.Add(devinfo.S7Connection, 0);
}
ConnectCount[devinfo.S7Connection]++;
OpcError = string.Format("{0}���ڵ�PLC�Ѿ����ߣ����ı�ǩ״̬��" + value.StatusCode.ToString(), clientHandle);
return;
}
ConnectCount[devinfo.S7Connection] = 0;
if (clientHandle.ToString().IndexOf("split") >= 0)
{
Array arr = (Array)value.Value;
byte[] GDKG = null;
GDKG = new byte[arr.GetLength(0)];
Array.Copy(arr, GDKG, arr.GetLength(0));
CUpdateDBChangeEventArgs udbe = new CUpdateDBChangeEventArgs(deviceindex, GDKG, null);
OnUpdateDB("OPCClient.CCommonOPCClient.OnDataChange", udbe);
}
else
{
Array arr = (Array)value.Value;
byte[] itemnamevalue = new byte[arr.GetLength(0)];
Array.Copy(arr, itemnamevalue, arr.GetLength(0));
int head = 0;
head = itemnamevalue[0];//��д��־
CUpdateDBChangeEventArgs udbe = new CUpdateDBChangeEventArgs(deviceindex, null, itemnamevalue);
OnUpdateDB("OPCClient.CCommonOPCClient.OnDataChange", udbe);
}
}
catch (Exception ex)
{//20120420
OpcError = string.Format("OPC�����������¼��쳣��{0},{1}", ex.Message, ex.StackTrace);
}
}
}
static private string _PLCconnectionID = "S7 connection_1";//OPC.UA����д��"ns=2,S7 connection_1.db2.0,b,5"��ʾ��"S7:[S7 connection_1]��db2.DBB0��ʼ5���ֽ�"
/// <summary>
/// ����PLC���ӵ�ID�����磺"S7:[S7 connection_1]"
/// ����"S7:[@LOCALSERVER]"
/// </summary>
public static string PlcConnectionID
{
get { return CCommonOPCClient._PLCconnectionID; }
set { CCommonOPCClient._PLCconnectionID = value; }
}
static private string _opcError;
static private bool _IfConnectOPCServer=false ;
static private string _hostname;
/// <summary>
/// OPC Server�Ļ������ƻ���IP��ַ
/// </summary>
public static string Hostname
{
get { return CCommonOPCClient._hostname; }
set { CCommonOPCClient._hostname = value; }
}
static private string _progID;
/// <summary>
/// OPC Server�ij�����ʶ�����磺OPC.SimaticNET
/// </summary>
public static string ProgID
{
get { return CCommonOPCClient._progID; }
set { CCommonOPCClient._progID = value; }
}
public static string OpcError
{
get { return CCommonOPCClient._opcError; }
set {
CCommonOPCClient._opcError = value;
CUpdateDBChangeEventArgs udbe = new CUpdateDBChangeEventArgs(0, null, null);
OnUpdateDB("OPCClient.CCommonOPCClient.OnDataChange", udbe);
}
}
/// <summary>
/// ���豸��������Ӧ�豸���ġ�
/// </summary>
public static SubscriptionCollection SubscriptionGroup = new SubscriptionCollection();//���������󼯺ϣ������߼��ϣ�//20110309
/// <summary>
/// 20110309ÿ���豸����һ�����ĺ�DataChange�¼�
/// </summary>
public static void CreateSubscriptionGroup()
{
if (_IfConnectOPCServer == false)
{
_hostname = CommonClassLib.AppSettings.GetValue("HostName");
_progID = CommonClassLib.AppSettings.GetValue("OPCProgID");
if (ConnectOPCServer(_hostname, _progID) == false) return ;
}
DataView dv = dbo.ExceSQL("SELECT F_ReadSubscription, F_DeviceIndex, F_DBW2Address, F_DBWGetLength, F_S7Connection, F_SplitByte FROM T_Base_Device WHERE (F_ReadSubscription IS NOT NULL) AND (F_ReadSubscription =F_DeviceIndex) ORDER BY F_ReadSubscription").Tables[0].DefaultView;
if (dv.Count > 0)
{
if (dv.Count < SubscriptionGroup.Count) return;
}
DataView dvx;
for (int i = 0; i < dv.Count; i++)
{
string dt = DateTime.Now.Minute.ToString() + "-" + DateTime.Now.Second.ToString() + "-" + DateTime.Now.Millisecond.ToString();
dvx = dbo.ExceSQL(string.Format("SELECT (MAX(F_DBW2Address) + F_DBWGetLength) as maxdbw2 FROM T_Base_Device WHERE (F_ReadSubscription = {0}) AND (F_DeviceKindIndex <> 33) GROUP BY F_DBWGetLength ORDER BY maxdbw2 DESC", dv[i]["F_ReadSubscription"])).Tables[0].DefaultView;
if (dvx.Count > 0)
{
NodeId nodeId = new NodeId(dv[i]["F_S7Connection"].ToString() +"."+
Model.CGeneralFunction.DBGet +"."+
dv[i]["F_DBW2Address"].ToString() + ",b," +
(System.Convert.ToInt32(System.Convert.ToInt32(dvx[0]["maxdbw2"]) - System.Convert.ToInt32(dv[i]["F_DBW2Address"]))).ToString(), 3);//richard.liu20140824 xp:����NameSpaceIndex=2��win7:����NameSpaceIndex=3
// Add the attribute name/value to the list view.
object serverHandle = null;
try
{
// Add the item and apply any changes to it.
m_Subscription.AddDataMonitoredItem(nodeId, dv[i]["F_ReadSubscription"].ToString(), OnDataChange, 300, out serverHandle);
}
catch (ServiceResultException monitoredItemResult)
{
OpcError = "����OPC������ʱ��" + monitoredItemResult.Message;
}
}
}
dv = dbo.ExceSQL("SELECT F_ReadSubscription, F_DeviceIndex, F_DBW2Address, F_DBWGetLength, F_S7Connection, F_SplitByte FROM T_Base_Device WHERE (F_ReadSubscription IS NOT NULL) AND (F_DeviceKindIndex=33) ORDER BY F_ReadSubscription").Tables[0].DefaultView;
for (int i = 0; i < dv.Count; i++)
{
NodeId nodeId = new NodeId(dv[i]["F_S7Connection"].ToString() + "." +
Model.CGeneralFunction.DBGet + "." +
dv[i]["F_DBW2Address"].ToString() + ",b," + System.Convert.ToInt32(dv[i]["F_DBWGetLength"]).ToString(), 3);//richard.liu20140824 xp:����NameSpaceIndex=2��win7:����NameSpaceIndex=3
// Add the attribute name/value to the list view.
object serverHandle = null;
try
{
// Add the item and apply any changes to it.
m_Subscription.AddDataMonitoredItem(nodeId, "split" + dv[i]["F_ReadSubscription"].ToString(), OnDataChange, 100, out serverHandle);
}
catch (ServiceResultException monitoredItemResult)
{
OpcError = "����OPC������ʱ��" + monitoredItemResult.Message;
}
}
}
public static void kkk()
{
DisConnectOPCServer();
_IfConnectOPCServer = false;
_hostname = CommonClassLib.AppSettings.GetValue("HostName");
_progID = CommonClassLib.AppSettings.GetValue("OPCProgID");
if (ConnectOPCServer(_hostname, _progID) == false) return;
CreateSubscriptionGroup();
//for (int i = 0; i < 20; i++)
//{
// //object ooo = severhandel[i];
// m_Subscription.RemoveMonitoredItem(severhandel[i]);
//}
}
/// <summary>
/// ����ָ��������OPC������
/// </summary>
/// <param name="hostname">��������</param>
/// <param name="ProgID">OPC������������ʶ���磺"OPC.SimaticNET"</param>
/// <returns></returns>
public static bool ConnectOPCServer(string hostname, string ProgID)
{
try
{
Uri discoveryUrl = new Uri("opc.tcp://" + hostname + ":55101");
Discovery discovery = new Discovery();
EndpointDescriptionCollection endpoints = null;
string rr = discovery.GetEndpoints(discoveryUrl, ref endpoints);
for (int i = 0; i < endpoints.Count; i++)
{
endpoints[i].EndpointUrl=discoveryUrl.ToString();
//richard.liu20140824
//xp: if ((endpoints[i].Server.ApplicationName.Text == ProgID + "@" + hostname.ToUpper())
//win7: if ((endpoints[i].Server.ApplicationName.Text == ProgID )
if ((endpoints[i].Server.ApplicationName.Text == ProgID )
&& (endpoints[i].SecurityMode == MessageSecurityMode.None))//OPC.SimaticNET.S7@LIU-SHAOPENG
{
m_Server = new Server();
m_Server.CertificateEvent += new certificateValidation(m_Server_CertificateEvent);
m_Server.Connect(endpoints[i]);
_IfConnectOPCServer = true;
if (m_Subscription == null)
{
m_Subscription = m_Server.AddSubscription(100);
}
return true;
}
}
OpcError = "����OPC���ݴ�ȡ������ʱ��������OPCProgID��HostName��׼ȷ��";
_IfConnectOPCServer = false;
return false;
}
catch (Exception ex)
{
OpcError = "����OPC���ݴ�ȡ������ʱ��" + ex.Message;
_IfConnectOPCServer = false;
return false;
}
}
public static DataValueCollection SyncReadAllItemValue(StringBuilder[] itemnames)
{
DataValueCollection m_currentValues;
if (_IfConnectOPCServer == false)
{
if (ConnectOPCServer(_hostname, _progID) == false) return null;
}
if (ConnectCount.ContainsKey(_PLCconnectionID) == false)//20110726
{
ConnectCount.Add(_PLCconnectionID, 0);
}
if (ConnectCount[_PLCconnectionID] > 1)//20110726
{
ConnectCount[_PLCconnectionID]++;//20110726
return null;
}
NodeIdCollection nodesToRead = new NodeIdCollection(itemnames.GetLength(0));
foreach (StringBuilder item in itemnames)
{
// NodeIds.
String sNodeId = _PLCconnectionID + "." + item.ToString();
NodeId nodeId = new NodeId(sNodeId,3);//richard.liu20140824 xp:����NameSpaceIndex=2��win7:����NameSpaceIndex=3
nodesToRead.Add(nodeId);
}
// Call to ClientAPI.
m_Server.ReadValues(
nodesToRead,
out m_currentValues);
return m_currentValues;
}
public static bool SyncWriteAllItemValue(StringBuilder[] itemnames, StringBuilder[] itemvalues)
{
try
{
if (_IfConnectOPCServer == false)
{
if (ConnectOPCServer(_hostname, _progID) == false) return false;
}
if (ConnectCount.ContainsKey(_PLCconnectionID) == false)//20110726
{
ConnectCount.Add(_PLCconnectionID, 0);
}
if (ConnectCount[_PLCconnectionID] > 1)//20110726
{
ConnectCount[_PLCconnectionID]++;//20110726
//_opcError = "ͬ������ʱ��OPC Serverû���ӵ�PLC:"+_PLCconnectionID.ToString()+"���˹�ȷ�Ϻ����С��豸��ʼ����";
return false;
}
NodeIdCollection nodesToWrite = new NodeIdCollection(itemnames.GetLength(0));
DataValueCollection values = new DataValueCollection(itemnames.GetLength(0));
StatusCodeCollection results = null;
int i = 0;
foreach (StringBuilder item in itemnames)
{
// Values to write.
String sValue = itemvalues[i].ToString();
// Leave current value if write value is empty.
if (sValue.Length == 0)
{
i++;
continue;
}
#region win7��64λ����ϵͳ��Ҫָ��ȷ�е���������//richard.liu20141118��������sValue����item
Type gt = typeof(byte);
if (item.ToString().IndexOf(",b") >= 0)//�޷����ֽ���0--255
{
gt = typeof(byte);
}
else if (item.ToString().IndexOf(",i") >= 0)//short���з��������ֽڵĵ���-32768��32767
{
gt = typeof(short);
}
else if (item.ToString().IndexOf(",w") >= 0)//ushort���޷��������ֽڵĵ���0��65535
{
gt = typeof(ushort);
}
else if (item.ToString().IndexOf(",di") >= 0)//int���з����ĸ��ֽڵ�˫��-2147483648��2147483647
{
gt = typeof(int);
}
else if (item.ToString().IndexOf(",dw") >= 0)//uint���޷����ĸ��ֽڵ�˫��0��4294967295
{
gt = typeof(uint);
}
Variant variant = new Variant(Convert.ChangeType(sValue, gt));
#endregion
DataValue value = new DataValue(variant);
values.Add(value);
// NodeIds.
String sNodeId =_PLCconnectionID+"."+ item.ToString();
NodeId nodeId = new NodeId(sNodeId, 3); //richard.liu20140824 xp:����NameSpaceIndex=2��win7:����NameSpaceIndex=3
nodesToWrite.Add(nodeId);
i++;
}
// Call to ClientAPI.
m_Server.WriteValues(
nodesToWrite,
values,
out results);
int ia = 0;//richard.liu20141110
foreach (StatusCode sc in results)
{//richard.liu20141110
if (sc.Code != StatusCodes.Good)
{
OpcError = "��OPC���ݴ�ȡ������д����ʱ��WriteValues:" + nodesToWrite[ia].ToString() + "�ķ���ֵ�д�����"+sc.ToString();
return false;
}
ia++;
}
return true;
}
catch (Exception ex)
{
OpcError = "��OPC���ݴ�ȡ������д����ʱ��" + ex.Message;
_IfConnectOPCServer = false;
return false;
}
}
/// <summary>
/// �����豸��������
/// </summary>
/// <param name="devIdx">�豸����</param>
/// <returns>�豸��������</returns>
static int GetDeviceKindIdx(int devIdx)
{
System.Object lockThis = new System.Object();
lock (lockThis)
{
try
{
DataView dv= dbo.ExceSQL(string.Format("SELECT F_DeviceKindIndex FROM T_Base_Device WHERE F_DeviceIndex={0}", devIdx)).Tables[0].DefaultView;
if (dv.Count > 0)
{
return System.Convert.ToInt32(dv[0]["F_DeviceKindIndex"]);
}
else
return 0;
}
catch (Exception ex)
{
throw ex;
}
}
}
public static void DisConnectOPCServer()
{
try
{
int result;
if (m_Server == null) return;
result = m_Server.Disconnect();
// Disconnect succeeded.
if (result == 0)
{
m_Server.RemoveSubscription(m_Subscription);
m_Subscription = null;
}
_IfConnectOPCServer = false;//20140514�Ų���ɽ���������ִ�����
}
catch (Exception ex)
{
OpcError = "�ر�OPC���ݴ�ȡ������ʱ��" + ex.Message;
}
}
static void m_Server_CertificateEvent(CertificateValidator validator, CertificateValidationEventArgs e)
{
e.Accept = true;
}
}
}