php取FBOX数据,云平台制作(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 MAP_CLIENTHANDLE_TAG;

public OPCItem[] OPC_ITEMS_ADDED { get; private set; }

public Form1()

{

InitializeComponent();

}

#region OPC Client

///

/// 自动连接OPC Server,并websocket连接服务器。

///

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();

}

///

/// 新建OPC Group并设置相应的属性,和触发改变事件

///

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);

}

///

/// 单独设立添加OPCItem方法,用来添加OPCItem

///

public void AddGroupItems()

{

List str = new List();

str.Add("通道 1.设备 1.标记 1");

str.Add("通道 1.设备 1.标记 2");

str.Add("通道 1.设备 1.test");

List ItemsAdd = new List();

MAP_CLIENTHANDLE_TAG = new Dictionary();

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);

///

/// 数据改变事件触发编写,调用委托事件远程发送。

///

///

///

///

///

///

///

public void KepGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)

{

Dictionary tagValueMap = new Dictionary();

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 tagValueMap)

//{

// foreach (var item in tagValueMap)

// {

// string key = item.Key;

// var value = item.Value;

// return "{"+"key:"+ key + "," + "Value:"+ value+"}";

// }

// return "";

//}

///

/// 读Dictionary中的值,并传递给实体类。

///

///

///

public MyOPCItem ParseOPCData(Dictionary 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);

//}

///

/// websocket传递数据,和测试客户端显示。

///

///

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,其性能优化,线程占有的内存,以及稳定性都有待测试。

你可能感兴趣的:(php取FBOX数据)