| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361 |
- using Opc.Ua;
- using Opc.Ua.Client;
- using OpcUaHelper;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using TeamAAS_VP.Enums;
- using TeamAAS_VP.Interfaces;
- using TeamAAS_VP.Models;
- namespace TeamAAS_VP.Core.PLCs
- {
- public class OpcUaClientPLC : IPlc
- {
- public Guid Id{ get; private set; }
- public CommunicationType CommunicationType { get; private set; }
- public string EndpointUrl { get; private set; }
- public int Index { get; set; }
- public string Name { get; private set; }
- public OpcUaClient OpcUaClient { get; private set; }
- public bool IsConnected { get { return OpcUaClient.Connected; } }
- /// <summary>
- /// 节点头
- /// </summary>
- public string NodeHeader { get; private set; }
- public event Action<object, bool> ConnectChangedEvent;
- public OpcUaClientPLC(Guid id,int index, string name, string endpointUrl,string nodeHeader, CommunicationType communicationType)
- {
- Id = id;
- Index = index;
- Name = name;
- EndpointUrl = endpointUrl;
- NodeHeader = nodeHeader;
- CommunicationType = communicationType;
- OpcUaClient = new OpcUaClient();
- // 初始化PLC连接
- OpcUaClient.UserIdentity = new UserIdentity(new AnonymousIdentityToken());
- // connect to server, this is a sample
- try
- {
- OpcUaClient.ConnectComplete += OpcUaClient_ConnectComplete;
- OpcUaClient.ReconnectStarting += OpcUaClient_ReconnectStarting;
- OpcUaClient.ReconnectComplete += OpcUaClient_ReconnectComplete;
- OpcUaClient.OpcStatusChange += OpcUaClient_OpcStatusChange;
- }
- catch (Exception)
- {
- return;
- }
- }
- public OpcUaClientPLC(PlcInfo plcInfo)
- {
- Id = plcInfo.Id;
- Index=plcInfo.Index;
- Name = plcInfo.Name;
- NodeHeader=plcInfo.NodeHeader;
- EndpointUrl = plcInfo.EndpointUrl;
- CommunicationType = plcInfo.CommunicationType;
- OpcUaClient = new OpcUaClient();
- // 初始化PLC连接
- OpcUaClient.UserIdentity = new UserIdentity(new AnonymousIdentityToken());
- // connect to server, this is a sample
- try
- {
- OpcUaClient.ConnectComplete += OpcUaClient_ConnectComplete;
- OpcUaClient.ReconnectStarting += OpcUaClient_ReconnectStarting;
- OpcUaClient.ReconnectComplete += OpcUaClient_ReconnectComplete;
- OpcUaClient.OpcStatusChange += OpcUaClient_OpcStatusChange;
- }
- catch (Exception)
- {
- return;
- }
- }
- public void Connect()
- {
- OpcUaClient.ConnectServer(EndpointUrl);
- }
- public Task ConnectAsync()
- {
- return OpcUaClient.ConnectServer(EndpointUrl);
- }
- public void Disconnect()
- {
- OpcUaClient.Disconnect();
- }
- public void Dispose()
- {
- OpcUaClient.Disconnect();
- OpcUaClient.ConnectComplete -= OpcUaClient_ConnectComplete;
- OpcUaClient.ReconnectStarting -= OpcUaClient_ReconnectStarting;
- OpcUaClient.ReconnectComplete -= OpcUaClient_ReconnectComplete;
- OpcUaClient.OpcStatusChange -= OpcUaClient_OpcStatusChange;
- }
- /// <summary>
- /// 读取多个节点的值
- /// </summary>
- /// <param name="nodeIds"></param>
- /// <returns></returns>
- public Dictionary<string, object> ReadNodes(string[] nodeIds)
- {
- var result = new Dictionary<string, object>();
- var readNodeIds = nodeIds.Select(s =>
- {
- if (s.StartsWith(NodeHeader))
- {
- return s;
- }
- else
- {
- return NodeHeader + s;
- }
- }).ToArray();
- List<NodeId> readNodeIdList = new List<NodeId>();
- foreach (var readNodeId in readNodeIds)
- {
- readNodeIdList.Add(new NodeId(readNodeId));
- }
- var values = OpcUaClient.ReadNodes(readNodeIdList.ToArray());
- for (int i = 0; i < nodeIds.Length; i++)
- {
- result[nodeIds[i]] = values[i].Value;
- }
- return result;
- }
- /// <summary>
- /// 异步读取多个节点的值
- /// </summary>
- /// <param name="nodeIds"></param>
- /// <returns></returns>
- public async Task<Dictionary<string, object>> ReadNodesAsync(string[] nodeIds)
- {
- var result = new Dictionary<string, object>();
- var readNodeIds = nodeIds.Select(s =>
- {
- if (s.StartsWith(NodeHeader))
- {
- return s;
- }
- else
- {
- return NodeHeader + s;
- }
- }).ToArray();
- List<NodeId> readNodeIdList = new List<NodeId>();
- foreach (var readNodeId in readNodeIds)
- {
- readNodeIdList.Add(new NodeId(readNodeId));
- }
- var values = await OpcUaClient.ReadNodesAsync(readNodeIdList.ToArray());
- for (int i = 0; i < nodeIds.Length; i++)
- {
- result[nodeIds[i]] = values[i].Value;
- }
- return result;
- }
- /// <summary>
- /// 读取单个节点的值
- /// </summary>
- /// <param name="nodeId"></param>
- /// <returns></returns>
- public object ReadNode(string nodeId)
- {
- string readNodeId = nodeId;
- if (!nodeId.StartsWith(NodeHeader))
- {
- readNodeId = NodeHeader + nodeId;
- }
- var value = OpcUaClient.ReadNode(new NodeId(readNodeId));
- return value.Value;
- }
- /// <summary>
- /// 异步读取单个节点的值
- /// </summary>
- /// <param name="nodeId"></param>
- /// <returns></returns>
- public Task<object> ReadNodeAsync(string nodeId)
- {
- return Task.Run(() =>
- {
- return ReadNode(nodeId);
- });
- }
- /// <summary>
- /// 读取单个节点的值
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="nodeId"></param>
- /// <returns></returns>
- public T ReadNode<T>(string nodeId)
- {
- string readNodeId = nodeId;
- if (!nodeId.StartsWith(NodeHeader))
- {
- readNodeId = NodeHeader + nodeId;
- }
- return OpcUaClient.ReadNode<T>(readNodeId);
- }
- /// <summary>
- /// 异步读取单个节点的值
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="nodeId"></param>
- /// <returns></returns>
- public async Task<T> ReadNodeAsync<T>(string nodeId)
- {
- string readNodeId = nodeId;
- if (!nodeId.StartsWith(NodeHeader))
- {
- readNodeId = NodeHeader + nodeId;
- }
- return await OpcUaClient.ReadNodeAsync<T>(readNodeId);
- }
- /// <summary>
- /// 写入单个节点的值
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="nodeId"></param>
- /// <param name="value"></param>
- /// <returns></returns>
- public bool WriteNode<T>(string nodeId, T value)
- {
- string writeNodeId = nodeId;
- if (!nodeId.StartsWith(NodeHeader))
- {
- writeNodeId = NodeHeader + nodeId;
- }
- return OpcUaClient.WriteNode<T>(writeNodeId, value);
- }
- /// <summary>
- /// 异步写入单个节点的值
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="nodeId"></param>
- /// <param name="value"></param>
- /// <returns></returns>
- public async Task<bool> WriteNodeAsync<T>(string nodeId, T value)
- {
- string writeNodeId = nodeId;
- if (!nodeId.StartsWith(NodeHeader))
- {
- writeNodeId = NodeHeader + nodeId;
- }
- return await OpcUaClient.WriteNodeAsync<T>(writeNodeId, value);
- }
- /// <summary>
- /// 写入多个节点
- /// </summary>
- /// <param name="nodeValues"></param>
- /// <returns></returns>
- public bool WriteNodes(Dictionary<string, object> nodeValues)
- {
- var writeNodeValues = new Dictionary<string, object>();
- foreach (var kvp in nodeValues)
- {
- string writeNodeId = kvp.Key;
- if (!kvp.Key.StartsWith(NodeHeader))
- {
- writeNodeId = NodeHeader + kvp.Key;
- }
- writeNodeValues[writeNodeId] = kvp.Value;
- }
- return OpcUaClient.WriteNodes(writeNodeValues.Keys.ToArray(), writeNodeValues.Values.ToArray());
- }
- /// <summary>
- /// 写入多个节点异步
- /// </summary>
- /// <param name="nodeValues"></param>
- /// <returns></returns>
- public Task<bool> WriteNodesAsync(Dictionary<string, object> nodeValues)
- {
- return Task.Run(() =>
- {
- return WriteNodes(nodeValues);
- });
- }
- /// <summary>
- /// 订阅多个节点
- /// </summary>
- /// <param name="key"></param>
- /// <param name="nodeIds"></param>
- /// <param name="dataChangeHandler"></param>
- public void SubscribeNodes(string key, List<string> nodeIds, Action<(string key,string nodeId,object value)> dataChangeHandler)
- {
- OpcUaClient.AddSubscription(key, nodeIds.Select(s =>
- {
- if (s.StartsWith(NodeHeader))
- {
- return s;
- }
- else
- {
- return NodeHeader + s;
- }
- }).ToArray(), (key1, monitoredItem, args) =>
- {
- MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;
- if (notification == null)
- {
- return;
- }
- string nodeId = monitoredItem.StartNodeId.ToString();
- if (nodeId.StartsWith(NodeHeader))
- {
- nodeId= nodeId.Substring(NodeHeader.Length);
- }
- // 触发数据变化事件
- dataChangeHandler?.Invoke((key1, nodeId, notification.Value.WrappedValue.Value));
- });
- }
- #region OPC事件
- private void OpcUaClient_OpcStatusChange(object sender, OpcUaStatusEventArgs e)
- {
- //LogHelper.WriteLogInfo($"OPC状态发生改变:Error:{e.Error},Time:{e.Time},Text:{e.Text}");
- }
- private void OpcUaClient_ReconnectComplete(object sender, EventArgs e)
- {
- ConnectChangedEvent?.Invoke(this, OpcUaClient.Connected);
- }
- private void OpcUaClient_ReconnectStarting(object sender, EventArgs e)
- {
- ConnectChangedEvent?.Invoke(this, OpcUaClient.Connected);
- }
- private void OpcUaClient_ConnectComplete(object sender, EventArgs e)
- {
- ConnectChangedEvent?.Invoke(this, OpcUaClient.Connected);
- }
- #endregion
- }
- }
|