1. 使用OPC UA
1.1OPC UA概述
1.OPC UA前身是OPC DA(只支持WINDOWS,基于COM/DCOM组件,远程访问比较麻烦),支持系统例如:SIEMNES 840D(WIN XP)。
2.OPC DA服务器如SIMATIC NET(连接 SIMATIC SERVER->连接PLC(S7),配置麻烦,需要组态),集成OPC DA,本机一定安装SIMATIC NET(很大,冗余、容易系统环境干扰,比如很多服务不启动)。
3.OPC UA不受系统影响,系统自己集成,安全性更好,集成方法、事件。
4.厂家希望我们用OPC UA做的数据采集,在通讯系统庞大,连接、重连,对象很多情况下,比较卡占用很多资源,整个软件都卡,异步,很多同步并发,并不是轻量级的。
1.2OPC UA(Client)在框架中使用(详见PeanutDemo例子)
对象:OpcUaSiemens
管理器:OpcUaDeviceOpr
连接资源(例如SIEMENS840D):
IP:OPC UA服务器IP
端口:默认4840 西门子CNC
用户名:默认OpcUaClient
密码:默认SUNRISE(低版本中没有),稍微新的系统都有
命名空间:默认SinumerikVarProvider
URI格式化:用于格式化URI
信息加密模式:MessageSecurityMode
安全加密模式:SecurityPolicies
创建OpcUaDevice
/// <summary>
/// URL
/// </summary>
private string _url;
/// <summary>
/// 发送失败再次尝试时间间隔
/// </summary>
public ushort AttempInterval{ get; set; } = 30;
/// <summary>
/// 发送失败后尝试再次发送次数
/// </summary>
public ushort AttempSendTimes{ get; set; } = 2;
/// <summary>
/// 网络设备操作对象
/// </summary>
public OpcUaDeviceOpr OpcUaDeviceOpr { get; set; }
/// <summary>
/// OPC UA
/// </summary>
public OpcUaSiemens OpcUaSie { get; set; }
/// <summary>
/// Ip
/// </summary>
public string IpAdr { get; set; }
/// <summary>
/// 端口
/// </summary>
public int Port { get; set; }
/// <summary>
/// URL格式化信息
/// </summary>
public string UrlFormat { get; set; } = "opc.tcp://{0}:{1}/OPCUA/SimulationServer";
/// <summary>
/// 默认url格式
/// </summary>
public string UrlFormatDefault { get; set; } = "opc.tcp://{0}:{1}";
/// <summary>
/// 命名空间
/// </summary>
public string Namespace { get; set; } = "SinumerikVarProvider";//"http://localhost/VarIF_Bridge";
/// <summary>
/// simotionD连接状态
/// </summary>
public bool IsConnected => OpcUaSie?.IsConnected == true;
/// <summary>
/// 连接超时
/// </summary>
public int ConTimeout { get; set; } = 50000;
/// <summary>
/// 读写超时
/// </summary>
public int ReadWriteTimeout { get; set; } = 3000;
/// <summary>
/// 用户名
/// </summary>
public string UserName { get; set; } = "";
/// <summary>
/// 密码
/// </summary>
public string Pwd { get; set; }
/// <summary>
/// 安全策略
/// </summary>
public string SecPolicy { get; set; } = SecurityPolicies.None;
/// <summary>
/// 信息加密模式
/// </summary>
public MessageSecurityMode MsgSecuMode { get; set; } = MessageSecurityMode.None;
/// <summary>
/// 通讯实体
/// </summary>
public EntityDemo1 Entity { get; set; }
= new EntityDemo1();
public OpcUaDevice()
{
OpcUaSie = new OpcUaSiemens();
}
/// <summary>
/// 初始化建立连接
/// 使用必要的属性设置(IpAdr、Port、UrlFormat)/Url、Namespace、(UserName、Pwd根据实际需要配置)
/// </summary>
public OperateResult Connect()
{
try
{
if (OpcUaSie == null)
OpcUaSie = new OpcUaSiemens();
if (string.IsNullOrWhiteSpace(_url))
_url = string.Format(UrlFormat, IpAdr, Port);
if (OpcUaDeviceOpr == null)
OpcUaDeviceOpr = new OpcUaDeviceOpr(OpcUaSie) { EndianMode =EndianModeEnum.Little };
var endPoints = OpcUaSie.GetEndpoints(_url);
var result = OpcUaSie.Connect(_url, Namespace, ConTimeout, UserName, Pwd,SecPolicy, MsgSecuMode);
return result;
}
catch (Exception ex)
{
throw new Exception("OPC UA连接失败BaseIni", ex);
}
}
/// <summary>
/// Server Url格式化
/// </summary>
/// <param name="ip"></param>
/// <param name="port"></param>
/// <param name="urlFormat"></param>
/// <returns></returns>
public string GetUrl(string ip,int port,string urlFormat=null)
{
var urlF = urlFormat ?? UrlFormat;
return string.Format(urlF, ip, port);
}
/// <summary>
/// 手动连接输入必要的所有参数
/// </summary>
/// <param name="ipAdr">ip地址</param>
/// <param name="port">端口</param>
/// <param name="namespaceStr">命名空间</param>
/// <param name="urlFormat">URL连接格式化如:"opc.tcp://{IpAdr}:{Port}"</param>
/// <param name="userName">用户名</param>
/// <param name="pwd">密码</param>
/// <param name="timeout">超时</param>
/// <returns></returns>
public OperateResult Connect(string ipAdr, int port, string namespaceStr, string urlFormat, string userName,
string pwd, int timeout)
{
Namespace = namespaceStr ?? throw new ArgumentNullException(nameof(namespaceStr));
UserName = userName;
Pwd = pwd;
_url = string.Format(UrlFormat, IpAdr, Port);
return Connect(_url, namespaceStr, UserName, Pwd, timeout);
}
/// <summary>
/// 手动连接输入必要的所有参数
/// </summary>
/// <param name="url">连接资源地址</param>
/// <param name="namespaceStr">命名空间地址</param>
/// <param name="userName">用户名</param>
/// <param name="pwd">密码</param>
/// <param name="timeout">连接超时设定</param>
/// <returns></returns>
public OperateResult Connect(string url, string namespaceStr, string userName, string pwd, int timeout)
{
_url = url ?? throw new ArgumentNullException(nameof(url));
Namespace = namespaceStr ?? throw new ArgumentNullException(nameof(namespaceStr));
UserName = userName;
Pwd = pwd;
OperateResult result = new OperateResult {IsSuccess = true, Message = "连接成功"};
OpcUaDeviceOpr = new OpcUaDeviceOpr(OpcUaSie);
if (!IsConnected) result = OpcUaSie.Connect(_url, Namespace, ConTimeout, UserName, Pwd);
return result;
}
/// <summary>
/// 实时读取初始化
/// </summary>
private void ReadHighIni()
{
//do...
}
/// <summary>
/// 实时读任务
/// </summary>
[TaskCom(true, 100, deleyTime: 3000)]
private void ReadHigh()
{
try
{
if (!IsConnected)
{
var ret = Connect();
//创建变量监控数据结构
OpcUaDeviceOpr.CreateDsSchema<EntityDemo1, ComOpcUaDataAttribute>();
if (!ret.IsSuccess)
{
Thread.Sleep(3000);
}
return;
}
else
{
var ret=OpcUaDeviceOpr.ReadEntityMuti(Entity);
}
}
catch (Exception ex)
{
//log
}
}
实体
ComOpcUaData修饰
public class EntityDemo1
{
[ComOpcUaData("/Channel/Parameter/R[u1,1]", "测试R", OprTypeEnum.Read| OprTypeEnum.Write)]///Channel/Parameter/R[u1,1]
public double TestParamR { get; set; }
[ComOpcUaData("/Plc/DB9000.DBB12", "测试DBB", OprTypeEnum.Read | OprTypeEnum.Write)]
public byte TestParamDbb{ get; set; }
[ComOpcUaData("/Plc/DB9000.DBD12", "类型解析测试", OprTypeEnum.Read | OprTypeEnum.Write, ByteReverse = true, WriteDataType = "UInt32")]
public float TestDbFloatSimple { get; set; }
[ComOpcUaData("/Plc/DB9000.DBD12","类型解析测试",OprTypeEnum.Read|OprTypeEnum.Write,ByteReverse =true,ReverseFormat ="0123", WriteDataType = "UInt32")]
}
1.3SIEMENS840D OPC UA DEMO说明

1.4Peanut OPC UA DEMO说明

1.发现模式
在初始化连接服务器的情况下,推荐使用此模式,用于查找服务器和节点使用,可以快速的建立连接并确认连接信息。
(1)输入IP和端口信息,点击“FindServer”,这时候如果成功会在Server中出现服务器地址;
(2)选择Endpoints后,填写用户名密码(如果有)和命名空间后点击手动练级即可;
2.自定义模式
自定义模式是通过设置现有属性和信息(部分信息可以通过发现模式确认)后进行连接,常用于项目。
(1)输入IP和端口信息;
(2)根据发现模式确认的Server,填写UrlFormat即string.Format格式;
(3)填写用户名密码(如果有);
(4)填写加密模式Secpolicy和MsgSecuMode,通常设置为None;
(5)填写NameSpace点击手动连接即可;
1.5OPC UA(Server)在框架中使用
1.初始化
(1)确保PeanutServer已经完成注册
container.RegisterSystemIni<PeanutServer, IServiceIni>();
(2)在PeanutServer中启动OPC UA Server
//登录成功以后启动OPC UA服务器
ServiceStart.StartOpcUaService<OpcUaNodeManager>(4840, "SinumerikVarProvider","OpcUaClient","SUNRISE");
2.OpcUaServer节点配置
默认地址的根节点是通过OpcUaNodeManager的CreateRootNode()方法来完成的,当调用base.CreateRootNode()基类方法时候默认添加PeanutOpcUa根节点,如果不需要则返回new OpcUaNode()即可
/// <summary>
/// 创建根节点
/// </summary>
/// <returns></returns>
protected override OpcUaNode CreateRootNode()
{
//return base.CreateRootNode();
return new OpcUaNode();
}
方式1:通过配置文件OpcUaNodeConfig.config配置
如
/Variables/Config/Adr1
/Variables/Config/Root1/Adr101
PLC/DB300/DBX620.0
1.6OPC UA虚拟服务器Prosys OPC UA Simulation Server

Options->Switch To Expert Mode,切换到专家模式;
1.6.1设置EndPoint
Port:URI端口;
Server Name:服务器名称,我们连接的时候的URI是包含服务器名称的,是可以不设置的;
Security Mode:加密方式;
Security Policies:加密策略;
Bind Address:服务器绑定地址,默认本机所有IP也可以Custom指定;
1.6.2设置Namepaces
添加命名空间,在以后新增变量的时候会指定命名空间,比如我们测试西门子CNC可以添加相同的命名空间,以后模拟和实际切换更加方便。
1.6.3添加变量
在根节点上右键添加节点,可以选择文件夹或者变量;
注意这里我们设置的是当前变量的NodeId信息,即访问信息,如果设置不对容易访问不到。
1.命名空间我们就选择我们已经设置好的;
2.NodeId Type:节点ID的类型,默认情况是Numeric,如果我们设置的是Numeric即NodeId Value是整形,当我们客户端访问的时候(例如我们使用OpcUa.Client访问)节点的初始化如下,这时候DisplayName与NodeIdvalue是不相同的,而通常我们访问的地址都为String,所以这里我们测试(根据实际设备情况而定)选择String类型,并设置NodeIdValue与DisplayName相同,这样访问起来更容易理解。
ushort nameSapceIndex = 7;
int nodeValue = 1004;
//节点类型为Numeric
NodeId node1 = new NodeId($"ns={nameSapceIndex};i={nodeValue}");
//节点类型为String
string nodeValueStr = "DB9000.DBB8";
NodeId node2 = new NodeId(nodeValueStr, nameSapceIndex);


1.6.4建立连接
关于连接失败验证的几种情况;
情况1:
找到本地存储OPC UA证书的路径,例如
C:\ProgramData\OPC Foundation\CertificateStores\并打开RejectedCertificates\certs文件夹,将其中证书删除,以后就可以连接成功,理论上这只是存储被拒绝证书的路径删除并不一定起到作用,但是有一种情况确实是删除以后可以连接成功了;
情况2:
在使用Prosys OPC UA Simulation Server,默认加密请求证书都会被拒绝,在软件中手动进行信任就可以;
情况3:将客户端证书设置为信任证书-可能某些情况下会有效
1.6.5读写操作
操作“读地址”和“写地址”直接对地址进行操作即可;写地址的时候要选择正确的变量类型;
如果写操作出现如下问题,表示发送数据与定义变量类型不符,发送指定类型即可;
1.6.6用户设置
如果需要用户名与密码验证那么选择“Users”标签直接在里面“AddUser”即可;
验证方式Ser Authentication Methods选择Anonymous(任何人),UserName&Password即可;
1.6.7 x509 Certificate has expired or is not yet valid
如错误描述信息所示,证书过期,在证书管理中找到客户端配置的证书信息,将其移除,这样下次连接的时候找不到证书就会重新创建(取决于客户端程序是如何设计的),同时可以考虑创建证书的时候设置较长的过期时间或移除以后重建等方式;
2. SIEMNS CNC HMI OPC UA配置
2.1添加授权
搜索OPC UA或P60选项。
只有设置了OPC UA选项,才会出现OPC UA菜单。
只有OPC UA服务管理员才能修改用户权限。初始状态下,系统管理员只具有读系统参数的权限
2.2OPC UA服务器配置
2.2.1配置 OPC UA 功能

1.状态,进入OPC UA相关配置界面
显示关于服务器的网络信息。若配置正确则服务器状态为“确认”。
若有客户端与本服务器相连接,则客户端信息显示在“相连接的客户端”。
2.设置
3.证书管理
默认情况下,“服务”器选键界面下有一个证书,“接收”选件下有两个证书 。
设置OPC UA时,如果勾选自动接收证书,则各配置界面中不显示自动接收的证书信息;如果选择不勾选自动接收证书,则客户端在利用签名加密方式连接服务器时,在“拒绝”选键界面中,会显示接收的客户端证书信息。点击“接收”,则在“接收”界面会显示接收到的证书信息。
2.2.2配置说明
1、IP地址和端口
OPC UA服务器NCU所有以太网接口(X130,X127,X120)的通讯。(840Dsl)
OPC UA服务器PPU可使用X130/X127以太网接口。(828D)
(1)TCP端口
缺省:4840,根据硬件配置开放防火墙端口配置。
(2)密码
密码必须符合如下规则:
创建密码时要确保不是可被猜出来的密码,例如:很容易被猜出的简单的单词和按键组合等。
密码中必须含有大写字母、小写字母以及数字和特殊字符。密码至少必须包含八个字符。
服务器不支持少于八个字符的密码。PIN 码必须包含任意顺序的数字。
只要条件允许、IT 系统支持,密码的字符顺序必须尽可能的复杂。
2、客户证书管理
证书是保证加密传输的前提,必要时需移动、删除用户证书。
拒绝证书的存储位置
NCU:“System CF Card/addon/SINUMERIK/hmi/opcua/pki/rejected”
PCU:“System harddisk/C:System/ProgramData/Siemens/MotionControl/addon/SINUMERIK/hmi/opcua/pki/rejected”
信任证书的存储位置
NCU:“System CF Card/addon/SINUMERIK/hmi/opcua/pki/trusted/certs”
PCU:“System harddisk/C:System/ProgramData/Siemens/MotionControl/addon/SINUMERIK/hmi/opcua/pki/ trusted/certs”
3、激活
开机后,自动启动OPC UA服务器。
2.2.3技术参数
