云平台制作(1)-OPC Client取数模块的制作
近来由于工程需要,基于OPC DA 2.0搭建通用的取数模块,与远程webscoket服务端连接,并传输数据。在网上找了些资料,修改相应网友公开的源代码,基本达到要求,特供大家参考。
1.实体类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OPC_DEMO
{
public class MyOPCItem
{
public string key{ get; set; }
public string Value { get; set; }
}
}
2.源代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OPCAutomation;
using System.Threading;
using System.IO;
using WebSocketSharp;
using Newtonsoft.Json;
namespace OPC_DEMO
{
public partial class Form1 : Form
{
private OPCServer KepServer;
private OPCGroups KepGroups;
private OPCGroup KepGroup;
private OPCItems KepItems;
public WebSocket wsc;
private string JsonStr;
private MyOPCItem opc;
Dictionary<string, string> MAP_CLIENTHANDLE_TAG;
public OPCItem[] OPC_ITEMS_ADDED { get; private set; }
public Form1()
{
InitializeComponent();
}
#region OPC Client
/// <summary>
/// 自动连接OPC Server,并websocket连接服务器。
/// </summary>
private void KepServerLoad()
{
try
{
KepServer = new OPCServer();
//KepServer.Connect("FBoxOpcServer", "127.0.0.1");
KepServer.Connect("Kepware.KEPServerEx.V6","127.0.0.1");
// KepServer.Connect("Kepware.KEPServerEx.V5","127.0.0.1");
if (KepServer.ServerState == (int)OPCServerState.OPCRunning)
{
wsc = new WebSocket("ws://10.0.0.128:6690/WsServices");
wsc.Connect();
richTextBox1.Text = "OPC Server连接成功";
}
else
{
richTextBox1.Text = "OPC Server连接失败";
return;
}
}
catch (Exception ex)
{
richTextBox1.Text = "OPC Server连接失败," + ex.Message;
return;
}
KepGroups = KepServer.OPCGroups;
Thread t1; // 开1个线程用于读取数据
t1 = new Thread(new ThreadStart(KepProcess));
t1.Start();
}
/// <summary>
/// 新建OPC Group并设置相应的属性,和触发改变事件
/// </summary>
public void KepProcess()
{
//KepGroup = KepGroups.Add("Channel.Device.Group");
KepGroup = KepGroups.Add("Channel1.Device1.Group");
KepGroup.UpdateRate = 1000;
KepGroup.IsActive = true;
KepGroup.IsSubscribed = true;
KepItems = KepGroup.OPCItems;
AddGroupItems();
//当KepGroup中数据发生改变的触发事件
KepGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(KepGroup_DataChange);
// //item1 = KepItems.AddItem("My FBox.外泵站1.AI.流量1", 1);
// item1 = KepItems.AddItem("通道 1.设备 1.标记 1", 1);
////item2 = KepItems.AddItem("My FBox.外泵站1.DI.格栅运行", 2);
//item2 = KepItems.AddItem("通道 1.设备 1.标记 2", 2);
//item3 = KepItems.AddItem("通道 1.设备 1.test",3);
}
/// <summary>
/// 单独设立添加OPCItem方法,用来添加OPCItem
/// </summary>
public void AddGroupItems()
{
List<string> str = new List<string>();
str.Add("通道 1.设备 1.标记 1");
str.Add("通道 1.设备 1.标记 2");
str.Add("通道 1.设备 1.test");
List<OPCItem> ItemsAdd = new List<OPCItem>();
MAP_CLIENTHANDLE_TAG = new Dictionary<string, string>();
int n = 0;
foreach (string tag in str)
{
ItemsAdd.Add(KepItems.AddItem(tag, n));
MAP_CLIENTHANDLE_TAG.Add(n + "", tag);
n++;
}
OPC_ITEMS_ADDED = ItemsAdd.ToArray();
}
//当数据改变时触发的事件
//public delegate void DelegateShowMessage(string str);
public delegate void DelegateShowMessage(MyOPCItem str);
/// <summary>
/// 数据改变事件触发编写,调用委托事件远程发送。
/// </summary>
/// <param name="TransactionID"></param>
/// <param name="NumItems"></param>
/// <param name="ClientHandles"></param>
/// <param name="ItemValues"></param>
/// <param name="Qualities"></param>
/// <param name="TimeStamps"></param>
public void KepGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
{
Dictionary<string, string> tagValueMap = new Dictionary<string, string>();
string str = "";
// DelegateShowMessage show1 = new DelegateShowMessage(ShowMessage);
DelegateShowMessage show1 = new DelegateShowMessage(ShowMessage);
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);
//for (int i = 1; i <= NumItems; i++)
//{
// if (ClientHandles.GetValue(i).Equals(1))
// {
// str = "通道 1.设备 1.标记 1:" + ItemValues.GetValue(i).ToString();
// }
// if (ClientHandles.GetValue(i).Equals(2))
// {
// str = "通道 1.设备 1.标记 2:" + ItemValues.GetValue(i).ToString();
// }
// if (ClientHandles.GetValue(i).Equals(3))
// {
// str = "通道 1.设备 1.test:" + ItemValues.GetValue(i).ToString();
// }
}
//str = tagValueMap["通道 1.设备 1.标记 1"];
// str = tagValueMap["通道 1.设备 1.标记 2"];
//str = tagValueMap["通道 1.设备 1.标记 test"];
// BeginInvoke(show1, new string[] { str });
MyOPCItem json =ParseOPCData(tagValueMap);
BeginInvoke(show1, json);
}
//public string ParseOPCData(Dictionary<string,string> tagValueMap)
//{
// foreach (var item in tagValueMap)
// {
// string key = item.Key;
// var value = item.Value;
// return "{"+"key:"+ key + "," + "Value:"+ value+"}";
// }
// return "";
//}
/// <summary>
/// 读Dictionary中的值,并传递给实体类。
/// </summary>
/// <param name="tagValueMap"></param>
/// <returns></returns>
public MyOPCItem ParseOPCData(Dictionary<string, string> tagValueMap)
{
opc = new MyOPCItem();
foreach (var item in tagValueMap)
{
opc.key = item.Key;
opc.Value = item.Value;
return opc;
}
return null;
}
//public void ShowMessage(string str)
//{
// //wsc.Send(JsonConvert.SerializeObject(str));
// // wsc.Send(str);
// richTextBox1.AppendText(str + System.Environment.NewLine);
//}
/// <summary>
/// websocket传递数据,和测试客户端显示。
/// </summary>
/// <param name="opc"></param>
public void ShowMessage(MyOPCItem opc)
{
wsc.Send(JsonConvert.SerializeObject(opc));
richTextBox1.AppendText(opc.Value + System.Environment.NewLine);
}
#endregion
private void Form1_Load_1(object sender, EventArgs e)
{
KepServerLoad();
}
private void Form1_FormClosing_1(object sender, FormClosingEventArgs e)
{
KepServer.Disconnect();
}
}
}
3.结论
初步实现与websocket的数据对接,以json对象的形式传递,还需要websocket服务端将其反序列化为json字符串,并解析给前端使用。当然,这只是一个初步的Demo,其性能优化,线程占有的内存,以及稳定性都有待测试。
云平台制作(1)-OPC Client取数模块的制作的更多相关文章
- 重磅发布丨乐维监控:全面兼容云平台,助力企业DevOps转型升级!
2019年伊始,我们迎来了乐维监控的又一重大功能更新——云平台监控,这将有效帮助企业将云上.云下数据聚合,方便统一化的监控管理与维护!未来,乐维监控每一次的产品功能及版本更新,我们都将第一时间于此发布 ...
- 完整部署CentOS7.2+OpenStack+kvm 云平台环境(4)--用OZ工具制作openstack镜像
在部署openstack云平台环境的时候,需要上传镜像到glance. 首先下载iso镜像,这里下载了centos6.5镜像,放到/usr/local/src目录下然后用OZ工具制作openstack ...
- Redis之高可用、集群、云平台搭建(非原创)
文章大纲 一.基础知识学习二.Redis常见的几种架构及优缺点总结三.Redis之Redis Sentinel(哨兵)实战四.Redis之Redis Cluster(分布式集群)实战五.Java之Je ...
- Redis之高可用、集群、云平台搭建
原文:Redis之高可用.集群.云平台搭建 文章大纲 一.基础知识学习二.Redis常见的几种架构及优缺点总结三.Redis之Redis Sentinel(哨兵)实战四.Redis之Redis Clu ...
- 使用 Velero 跨云平台迁移集群资源到 TKE
概述 Velero 是一个非常强大的开源工具,可以安全地备份和还原,执行灾难恢复以及迁移Kubernetes群集资源和持久卷,可以在 TKE 平台上使用 Velero 备份.还原和迁移集群资源,关于如 ...
- 完整部署CentOS7.2+OpenStack+kvm 云平台环境(1)--基础环境搭建
公司在IDC机房有两台很高配置的服务器,计划在上面部署openstack云平台虚拟化环境,用于承载后期开发测试和其他的一些对内业务.以下对openstack的部署过程及其使用做一详细介绍,仅仅依据本人 ...
- A亚马逊WS网上系列讲座——怎么样AWS云平台上千万用户的应用建设
用户选择云计算平台构建应用程序的一个重要原因是高弹性的云平台和可扩展性. 面向Internet应用程序通常需要支持用户使用大量,但要建立一个高度可扩展.具有一定的挑战,高度可用的应用程序,只有立足AW ...
- 腾讯基于Kubernetes的企业级容器云平台GaiaStack (转)
GaiaStack介绍 GaiaStack是腾讯基于Kubernetes打造的容器私有云平台.这里有几个关键词: 腾讯:GaiaStack可服务腾讯内部所有BG的业务: Kubernetes:Gaia ...
- OpenStack(二)——使用Kolla部署OpenStack-allinone云平台
(1).Kolla概述 Kolla是OpenStack下用于自动化部署的一个项目,它基于docker和ansible来实现,其中docker主要负责镜像制作和容器管理,ansible主要负责环境的部署 ...
随机推荐
- [非专业翻译] 高性能对象映射框架 - Mapster
[非专业翻译] 高性能对象映射框架 - Mapster 系列介绍 [非专业翻译] 是对没有中文文档进行翻译的系列博客,文章由机翻和译者自己理解构成,和原文相比有所有不通,但意思基本一致. 因个人能力有 ...
- Android Gradle插件
目录 什么是Gradle 编写方法 buildSrc 基础概念 Extension 自定义Task Plugin Transformer Gradle用处 好文章 常见问题 Gradle插件练习地址: ...
- 飞(fly)(数学推导,liu_runda的神题)
大概看了两三个小时的题解,思考量很大,实现简单........ 20分: 明显看出,每个点的贡献是x*(x-1)/2;即组合数C(x,2),从x个线段中选出2个的方案数,显然每次相交贡献为1,n^2枚 ...
- 永恒之蓝MS17-010漏洞复现
永恒之蓝MS17-010漏洞复现 1.漏洞描述: 起因: 永恒之蓝(Eternalblue)是指2017年4月14日晚,黑客团体Shadow Brokers(影子经纪人)公布一大批网络攻击工具,其中包 ...
- Centos7.5使用SSH密钥登录
12.1.查看操作系统版本 # cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) 12.2.在服务器端创建密钥 # ssh-ke ...
- POJ 1696 Space Ant 点积计算夹角
题意: 一只特别的蚂蚁,只能直走或者左转.在一个平面上,有很多株植物,这只蚂蚁每天需要进食一株,这只蚂蚁从起点为(0,miny)的点开始出发.求最多能活多少天 分析: 肯定是可以吃到所有植物的,以当前 ...
- Redis 底层数据结构之字典
文章参考 <Redis 设计与实现>黄建宏 字典 在字典中,每个键都是独一无二的,程序可以在字典中根据键查找与之相关联的值,或者通过键来更新和删除值. 字典在 Redis 中的应用相当广泛 ...
- 精尽Spring Boot源码分析 - @ConfigurationProperties 注解的实现
该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...
- 面试题五:Spring
Spring IoC 什么是IoC? 容器创建Bean对象,将他们装配在一起,配置并且管理它们的完整生命周期. Spring容器使用依赖注入来管理组成应用程序的Bean对象: 容器通过提供的配置元数据 ...
- SpringMVC(2)经典的HelloWorld实现
我机器的开发环境为: Ubuntu12.04(不同操作系统对本系列项目没有影响): 开发工具:Eclipse For JavaEE: 数据库:MySql5.5.35; 运行环境:TomCat V7.0 ...