c# 使用OPC服务 读取数据

本文介绍了如何在C#中通过.NETFramework4.5.2连接OPC协议,包括使用MatrikonOPCServer获取必要的dll,以及提供代码示例来实现服务器连接、调试和数据读取功能。
摘要由CSDN通过智能技术生成

c#连接opc协议,基础配置搞定后,即可进行编码开发
推荐开发前可以使用可视化工具进行测试下,确定下OPC Client端是否和服务器网络是否通常
可以使用 OPCExplorer.exe工具来进行测试,免费的工具
而且网上资料也挺多的

调用OPC,解决方案需要添加如下的dll,我的c# 开发环境是.net FrameWork4.5.2

这两个dll的获取方式,推荐大家安装免费的MatrikonOPC Server for Simulation
安装完成后,在这个程序的目录包中即可找到这两个dll,而且这个软件还会为你注册这几个dll和对应的服务,大大省事!!!

下来就是贴代码了,

Helper帮助类

using System;
using System.Collections.Generic;
using OPCAutomation;//需要手动添加
using System.Security.Cryptography;
using System.Linq;
using Newtonsoft.Json;

namespace OPCAPI
{
    class OPC_client
    {
        public OPCServer Server;//服务器对象
        public OPCGroups Groups;//组列表
        public OPCGroup Group;//组对象
        public OPCItems Items;//节点列表
                              //public OPCItem Item;//节点对象
        public bool ConnectedState { get; private set; }
        public delegate string ServerShutDown(string Reason);
        /// <summary>
        /// 服务器断开连接事件
        /// </summary>
        public event ServerShutDown OnServerShutDown;
        /// <summary>
        /// 连接
        /// </summary>
        /// <param name="ServerName"></param>
        /// <param name="ServerIP"></param>
        /// <returns></returns>
        public bool Connect(string ServerName, string ServerIP, out string Message)
        {
            try
            {
                if (Server == null) Server = new OPCServer();
                Server.Connect(ServerName, ServerIP);
                if (Server.ServerState == (int)OPCServerState.OPCRunning)
                {
                    Server.ServerShutDown += Server_ServerShutDown;
                    Message = "连接成功";
                    ConnectedState = true;
                    IniServer();
                    return true;
                }
                else
                {
                    Message = "连接失败。状态码:" + Server.ServerState.ToString();
                    ConnectedState = false;
                    return false;
                }
            }
            catch (Exception ex)
            {
                Message = ex.Message;
                return false;
            }
        }
        /// <summary>
        /// 服务器异常断开连接
        /// </summary>
        /// <param name="Reason"></param>
        private void Server_ServerShutDown(string Reason)
        {
            ConnectedState = false;
            OnServerShutDown?.Invoke(Reason);
        }
        /// <summary>
        /// 断开连接
        /// </summary>
        public void DisConnect()
        {
            Server?.Disconnect();
        }
        /// <summary>
        /// 添加一个测试组,之后读取都在这个测试组中添加或者删除item
        /// </summary>
        private void IniServer()
        {
            Groups = Server.OPCGroups;
            Group = Server.OPCGroups.Add("AncnRobot");
            Items = Group.OPCItems;
        }
        /// <summary>
        /// 获取OPCDA服务器中所有的节点<br/>
        /// 有一些节点服务器自带有Write的,不能读取。
        /// </summary>
        /// <returns></returns>
        public List<string> GetBrowser()
        {
            try
            {
                List<string> result = new List<string>();
                OPCBrowser browser = Server.CreateBrowser();
                browser.ShowBranches();
                browser.ShowLeafs(true);
                foreach (var item in browser)
                {
                    result.Add(item.ToString());
                }
                return result;
            }
            catch (Exception)
            {
                return null;
            }
        }
        /// <summary>
        /// 读取一条数据
        /// </summary>
        /// <param name="tagAddress"></param>
        /// <returns></returns>
        public OPCResponse ReadOne(string tagAddress)
        {
            try
            {
                var model = Items.AddItem(tagAddress, 1);
                model.Read(1,
                                out object ItemValues,
                                out object Qualities,
                                out object TimeStamps);
                var read_ = new OPCResponse()
                {
                    Tag = tagAddress,
                    Value = ItemValues.ToString(),
                    Quanlity = Qualities.ToString(),
                    Time = TimeStamps.ToString()
                };
                return read_;
            }
            catch (Exception ex)
            {
                Logger.Info($"读取指定数据异常,读取的数据内容是:{tagAddress}错误原因是:{JsonConvert.SerializeObject(ex)}");
            }
            return null;
        }

        /// <summary>
        /// 读取节点数据
        /// </summary>
        /// <param name="tagAddress">需要读取的节点</param>
        /// <returns></returns>
        public List<OPCResponse> Read(List<string> tagAddress)
        {
            List<OPCResponse> results = new List<OPCResponse>();
            try
            {
                OPCItem[] items = new OPCItem[tagAddress.Count];
                int[] temp = new int[items.Length + 1];
                temp[0] = 0;//这个第一个数据一定不能为空,索引是从1开始的
                for (int i = 0; i < items.Length; i++)
                {
                    items[i] = Items.AddItem(tagAddress[i], i);
                    OPCResponse read_;
                    try
                    {
                        items[i].Read(1,
                            out object ItemValues,
                            out object Qualities,
                            out object TimeStamps);
                        read_ = new OPCResponse()
                        {
                            Tag = tagAddress[i],
                            Value = ItemValues.ToString(),
                            Quanlity = Qualities.ToString(),
                            Time = TimeStamps.ToString()
                        };
                    }
                    catch (Exception)
                    {
                        read_ = new OPCResponse()
                        {
                            Tag = tagAddress[i],
                            Value = "--",
                            Quanlity = "--",
                            Time = "--"
                        };
                        results.Add(read_);
                        continue;
                    }
                    results.Add(read_);
                    temp[i + 1] = items[i].ServerHandle;
                }
                try
                {
                    Array serverHandles = (Array)temp;
                    Array errors;
                    Items.Remove(1, serverHandles, out errors);
                }
                catch (Exception) { }
                return results;
            }
            catch (Exception ee)
            {
                return null;
            }
        }
        /// <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>
        private void Group_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
        {
            Console.ForegroundColor = ConsoleColor.Green;
            for (int i = 1; i <= NumItems; i++)
            {
                int tmpClientHandle = Convert.ToInt32(ClientHandles.GetValue(i));
                string tmpValue = ItemValues.GetValue(i).ToString();
                string tmpTime = ((DateTime)(TimeStamps.GetValue(i))).ToString();
                Console.WriteLine("Time:" + tmpTime);
                Console.WriteLine("ClientHandle : " + tmpClientHandle.ToString());
                Console.WriteLine("tag value " + tmpValue);
            }
        }
    }
}

返回参数数据(我这个是业务上要求写的,大家参考就行)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OPCAPI.Models
{
    public class OPCRequest
    {
        public string TagId { get; set; }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OPCAPI
{
    public class OPCResponse
    {
        /// <summary>
        /// OPCIterm变量名称
        /// </summary>
        public string Tag { get; set; }
        /// <summary>
        /// OPCIterm数值
        /// </summary>
        public string Value { get; set; }
        /// <summary>
        /// OPCIterm质量
        /// </summary>
        public string Quanlity { get; set; }
        /// <summary>
        /// OPCIterm时间戳
        /// </summary>
        public string Time { get; set; }
    }
}

调用去读取一条数据

static bool OPCInit()
        {
            try
            {
                if (_client == null || !_client.ConnectedState)
                {
                    if (_client != null)
                    {
                        Logger.Info($"当前连接状态是:{_client.ConnectedState},准备重新初始化!");
                    }
                    _client = new OPC_client();
                    var config = AppConfig.GetInstance();
                    if (config != null)
                    {
                    	//这里需要修改 去填 组id,opc服务器ip
                        bool con = _client.Connect(config.ProgId, config.OPCIp, out string msg);
                        Logger.Info($"连接结果是:{con},连接返回内容是:{msg}");
                        return con;
                    }
                }
                else
                {

                    Logger.Info($"当前连接状态是:{_client.ConnectedState},初始化成功!");
                    return _client.ConnectedState;
                }

            }
            catch (Exception ex)
            {
                Logger.Info("初始化OPC服务异常:" + JsonConvert.SerializeObject(ex));
            }
            return false;
        }
 public static OPCResponse Read(OPCRequest request)
        {
            OPCResponse response = null;
            try
            {
                if (OPCInit())
                {//opc初始化
                    var config = AppConfig.GetInstance();
                    //这里需要修改 key改为dcs系统中的唯一主键,我这里是我自己业务逻辑的拼接
                    string key = config.TagPrefix + request.TagId + config.TagValueAttribute;
                    var result = _client.ReadOne(key);
                    if (result != null)
                    {
                        return result;
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Info("opc服务读取异常:" + JsonConvert.SerializeObject(ex));
                response = null;
            }
            return response;
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值