【计算机网络 14】C# 使用OPCAutomation实现对opc数据的访问

本文详述了如何利用C#与OPCAutomation类实现对OPCServer数据的读取,包括创建连接、初始化组设置、添加items及数据读取、解析与存储等关键步骤。

最近项目中需要 C#通过OPC方式获取数据,折腾了一段时间,第三方提供OPCServer虚拟环境,我创建C#客户端。

服务端是力控电子系统,第三方软件,不多做赘述,本文主要讲解OPC客户端的搭建和OPC连接步骤。

调用OPCAutomation类访问OPCServer端,并进行可控制读取间隔的OPC数据读取、存储工作。

本文主要介绍OPCAutomation类的使用。

简单流程如下:

1.创建OPC server的连接

2.创建OPC组对象并初始化设置

3.获取组的OPCItems对象,为读取数据做准备

4.opcltem的操作

5.退出程序的资源释放

创建连接很简单,需要指定OPCServer所在的服务器(内网可以指定IP或者计算机名),指定OPC服务的名称(同一服务器可能运行多个OPC服务以适配不同的下位机)

//通过timer获取OPCServer端数据
void TimerTick(object sender, EventArgs e)
{
	//连接OPCServer
	KepServer.Connect(remoteServerName, remoteServerIP);
	if (KepServer.ServerState == (int)OPCServerState.OPCRunning)
	{
	    label1.Text = "已连接到-" + KepServer.ServerName + "   ,starttime:" + KepServer.StartTime.ToString();
		//创建并设置组
        bool bSucce = this.CreateAndSetGroup();
        //goup添加items
        AddGroupItems();
		//采集opc数据
			GetOPCData();
	    }else{
            label1.Text = "OPC服务器状态异常: " + KepServer.ServerState.ToString();
        }
}

其中KepServer.Connect(remoteServerName, remoteServerIP);即OPCAutomation类提供的连接方法。

需要注意的是,在实际配置时,需要完全对OPC服务端所在服务器上配置防火墙出入站规则后,OPC服务才能够被其它服务器上的中间件访问到。

创建组相当于读取OPC上特定的项目,而具体的数据值是在每个项目下根据开发人员的定义而确定。

//创建组并设置组信息
private bool CreateAndSetGroup()
{
	try
	{
		KepGroups = KepServer.OPCGroups;
		KepGroup = KepGroups.Add("PCAuto.OPCServer");
		KepServer.OPCGroups.DefaultGroupIsActive = true;//激活组
		KepServer.OPCGroups.DefaultGroupDeadband = 0;// 死区值,设为0时,服务器端该组内任何数据变化都通知组
		KepGroup.IsSubscribed = true;//使用订阅功能,即可以异步,默认false
		//绑定写操作的事件
		KepGroup.AsyncReadComplete += new DIOPCGroupEvent_AsyncReadCompleteEventHandler(GroupAsyncReadComplete);
		KepItems = KepGroup.OPCItems;
	}
	catch (Exception ex)
	{
	}
	return true;
}

这段代码是为OPCGroup对象进行初始化。PCAuto.OPCServer为组名,激活组,使用订阅功能,绑定写操作的时间等等。

异步读完成 运行时,Array数组从下标1开始而非0!

//异步读完成 运行时,Array数组从下标1开始而非0!
void GroupAsyncReadComplete(int TransactionID, int NumItems, ref System.Array ClientHandles, ref System.Array ItemValues, ref System.Array Qualities, ref System.Array TimeStamps, ref System.Array Errors)
{
	try
	{
		//C# Dictionary 字典 
		Dictionary<string, string> tagValueMap = new Dictionary<string, string>();
		for (int i = 1; i <= NumItems; i++)
		{
			string clientHandle = ClientHandles.GetValue(i).ToString();
			string tag = MAP_CLIENTHANDLE_TAG[clientHandle];
			string val = ItemValues.GetValue(i).ToString();
			//C# Dictionary 字典 添加数据
			tagValueMap.Add(tag, val);
		}
		//构建json
		string json = ParseOPCData(tagValueMap);
	}
	catch (Exception ex)
	{
		
	}
}

为全局变量OPCGroup添加items,在OPC中,每个opcltem会被分配一个客户端句柄值,同时会被配置上服务器句柄。几乎所有有关获取指定Opcltem对象的方法均要求指定客户端句柄值。

上图中有一C# Dictionary 字典,暂不做赘述,待下回分解。

关于C# dictionary字典

//goup添加items
string[] sensorIdArray;
void  AddGroupItems()
{
	List<string> l_str = new List<string>();
	//读取配置文件,获取需要的传感器ID
	string sensorIdList = getSensorId();
	sensorIdArray = sensorIdList.Replace("\r\n","").Split(',');
	foreach (string sensorId in sensorIdArray){
		l_str.Add(sensorId+"_COS");
		l_str.Add(sensorId+"_DL1");
		l_str.Add(sensorId+"_DL2");
		l_str.Add(sensorId+"_DL3");
		l_str.Add(sensorId+"_DL4");
		l_str.Add(sensorId+"_IA");
		l_str.Add(sensorId+"_IB");
		l_str.Add(sensorId+"_IC");
		l_str.Add(sensorId+"_P");
		l_str.Add(sensorId+"_Q");
		l_str.Add(sensorId+"_UAB");
		l_str.Add(sensorId+"_UBC");
		l_str.Add(sensorId+"_UCA");
	}
	List<OPCItem> ItemsAdded = new List<OPCItem>();
	int n = 0;
	MAP_CLIENTHANDLE_TAG = new Dictionary<string, string>();
	foreach (string tag in l_str){
		ItemsAdded.Add(KepItems.AddItem(tag + ".PV", n));
		//clientHandle tag关系
		MAP_CLIENTHANDLE_TAG.Add(n + "", tag);
		n++;
	}
	OPC_ITEMS_ADDED = ItemsAdded.ToArray();
}

OPCServer服务端数据源item

5d779ca4750f9a8f1971203f48bd4819bff.jpg

这段代码设计为了获取到全部的OPCltem所添加到所创建的OPCGroup对象的opcitem集合中,得到添加到goup中的item(OPC_ITEMS_ADDED)。

通过OPC_ITEMS_ADDED采集opc数据

//采集opc数据
private void GetOPCData()
{
	try
	{
		//异步读opc数据
		int[] temp = new int[OPC_ITEMS_ADDED.Length + 1];
		temp[0] = 0;
		for (int i = 1; i <= OPC_ITEMS_ADDED.Length; i++)
		{
			temp[i] = OPC_ITEMS_ADDED[i - 1].ServerHandle;
		}
		Array serverHandles = (Array)temp;
		Array Errors;
		int cancelID;
		Random rd = new Random();
		int TransactionID = rd.Next(1, 10);
		KepGroup.AsyncRead(serverHandles.Length - 1, ref serverHandles, out Errors, TransactionID, out cancelID);//第一参数为item数量
	}
	catch (Exception ex)
	{       	
		MessageBox.Show(ex.Message);
	}
}

解析OPC数据并以json格式存储在本地

//解析opc数据
private string ParseOPCData(Dictionary<string, string> tagValueMap)
{
	string filename = "E:\\mine\\下峪口\\data\\electric_data.txt";
	StringBuilder builder = new StringBuilder();
	string rowStr = "";
	string time = ConvertDateTimeToInt(DateTime.Now).ToString();
	rowStr += "[";
	foreach (string sensorId in sensorIdArray){
		rowStr += "{\r\n\"id\":"+ "\"" + sensorId + "\",\r\n";
		rowStr += "\"substation\":"+"\"假变电所\""+",\r\n";
		rowStr += "\"timestamp\":"+time+",\r\n";
		foreach (var item in tagValueMap)
		{
			string key = item.Key;
			string[] data = item.Key.Split('_');
			string title = data[0];
			string word = data[1];
			if(title.Equals(sensorId)){
				rowStr += "\""+ word + "\""+ ":" + item.Value + ",\r\n";
			}
		}
		rowStr += "},";
	}
	rowStr += "]";
	rowStr = rowStr.Replace(",\r\n}","\r\n}").Replace(",]","]");
	builder.Append(rowStr);
	File.WriteAllText(@filename, builder.ToString(), Encoding.GetEncoding("gb2312"));
	return "";
}

往期精彩内容:

Java知识体系总结(2021版)

Java多线程基础知识总结(绝对经典)

超详细的springBoot学习笔记

常见数据结构与算法整理总结

Java设计模式:23种设计模式全面解析(超级详细)

Java面试题总结(附答案)

内容概要:本文围绕“面向高精度电流控制的PMSM多参数PSO辨识模型研究”,系统阐述了基于Simulink的永磁同步电机(PMSM)多参数辨识方法,重点采用粒子群优化算法(PSO)实现对电机关键内部参数的高精度辨识。研究构建了完整的PMSM控制系统仿真模型,结合智能优化算法,解决了传统参数辨识中精度低、收敛慢的问题,有效提升了电流环控制的动态性能与稳态精度。该方法特别适用于对控制精度和响应速度要求较高的工业应用场景,如高性能伺服系统、电动汽车驱动系统等,具有较强的工程实用价值和科研参考意义。文中提供了完整的Simulink仿真模型与配套代码,确保了研究内容的可复现性和实践操作性。; 适合人群:具备电机控制、自动化或电气工程等相关专业背景,熟悉MATLAB/Simulink仿真环境,从事电机驱动系统研发、控制算法设计或相关领域科研工作的工程师及研究生,尤其适合工作1-5年、希望深入理解先进参数辨识技术的研发人员。; 使用场景及目标:①开展高精度PMSM控制系统的设计与参数辨识研究;②学习并掌握PSO等智能优化算法在电机系统参数辨识中的具体实现与调优技巧;③完成学术论文复现、科研项目验证、毕业设计或工程原型开发,提升对现代电机控制核心技术的理解与应用能力。; 阅读建议:建议读者结合提供的Simulink模型与源代码进行动手实践,按照文档逻辑逐步搭建与调试仿真系统,重点关注PSO算法与电机模型的交互机制、目标函数设计及参数收敛过程,通过对比不同工况下的辨识结果,深入理解算法性能与控制精度之间的内在联系。
内容概要:本文档详细介绍了基于Simulink的双机并联虚拟同步发电机(VSG)系统仿真模型,重点涵盖微电网黑启动、有功/无功功率分配、虚拟阻抗控制及预同步并网控制等核心技术的实现方法。通过构建完整的VSG控制系统,实现了在孤岛模式下微电网的安全启动与稳定运行,有效解决了多逆变器并联系统中的功率均分问题。采用虚拟阻抗技术优化输出阻抗特性,提升了系统的稳定性与动态响应能力;同时引入预同步控制策略,确保并网前电压、频率和相位的高度匹配,显著降低并网冲击电流。该仿真平台为研究微电网自治运行、提升可再生能源消纳能力以及VSG关键控制技术的验证提供了高可信度的实验环境。; 适合人群:电力系统、电气工程及其自动化等相关专业的高校研究生、科研人员,以及从事微电网、分布式能源系统、新能源并网技术开发的工程技术人员。; 使用场景及目标:①用于教学与科研中对虚拟同步机控制策略的理解与验证;②支撑微电网黑启动过程的建模仿真与优化研究;③开展多逆变器并联运行下的功率协调控制算法设计与性能测试;④为实际工程中微电网控制器的开发与调试提供理论依据与仿真支持。; 阅读建议:建议结合MATLAB/Simulink环境动手搭建模型,对照文档逐步实现各功能模块,重点关注控制环路设计、参数整定及仿真结果分析,可进一步扩展至多机多场景复杂工况以深化对系统动态行为的理解。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值