下载opcua服务器(有PLC可以直连),UaAnsiCServer下载路径
双击运行如下,Endpoint显示opcua服务路径 opc.tcp://DESKTOP-9SD7K4B:48020
下载opcua客户端(类似编写代码连接操作),UaExpert下载路径
如果连接失败,有一个授权认证,点击同意就行
java代码实现连接opcUA操作
pom.xml依赖
<!--start milo-->
<dependency>
<groupId>org.eclipse.milo</groupId>
<artifactId>sdk-client</artifactId>
<version>0.6.3</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.eclipse.milo</groupId>-->
<!-- <artifactId>sdk-server</artifactId>-->
<!-- <version>0.6.3</version>-->
<!-- </dependency>-->
<!-- 这个有认证账号密码才开启,不然开启运行会报错-->
<!-- <dependency>-->
<!-- <groupId>org.bouncycastle</groupId>-->
<!-- <artifactId>bcpkix-jdk15on</artifactId>-->
<!-- <version>1.57</version>-->
<!-- </dependency>-->
<!--end milo-->
java示例一,没有验证
package com.example.opcua.util;
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort;
import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
/**
* @Description:
* @Author: xu
* @Data: 2024-2024/9/7-17
* @Version: V1.0
*/
public class Test {
public static void main(String[] args) throws Exception {
// 连接地址端口号
String EndPointUrl = "opc.tcp://192.168.11.199:4840";
OpcUaClient opcClient = OpcUaClient.create(EndPointUrl);// 准备连接
//开启连接
opcClient.connect().get();
// namespaceIndex: 是获取的的下标 identifier: 是名称
NodeId nodeId_Tag1 = new NodeId(3, "\"Tag_1\"");
// 获取值
DataValue value = opcClient.readValue(0.0, TimestampsToReturn.Both, nodeId_Tag1).get();
// 输出值
System.out.println(value.getValue().getValue());
// 写入值
//注意identifier是字符串,要看是否带“,带”就需要使用转义\
NodeId nodeId = new NodeId(3, "\"Tag_1\"");//"OPC_Test.设备 1.TAG1"
//创建Variant对象和DataValue对象,ua变量名里的dateType映射关系,uint16--UShort,uint32--UInteger
UShort value3 = UShort.valueOf(1);
// 写入类型根据DateType判断
// 警告: 写入类型要看opc ua变量名里的dateType是什么类型 否则写入失败 false
Variant v = new Variant(value3);
DataValue dataValue = new DataValue(v, null, null);
StatusCode statusCode = opcClient.writeValue(nodeId, dataValue).get();
System.out.println(statusCode.isGood());// 写入成功返回值
}
}
java示例二,动态策略
package com.example.opcua.util;
import io.netty.util.internal.StringUtil;
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.sdk.client.api.UaClient;
import org.eclipse.milo.opcua.sdk.client.api.identity.AnonymousProvider;
import org.eclipse.milo.opcua.sdk.client.api.identity.IdentityProvider;
import org.eclipse.milo.opcua.sdk.client.api.identity.UsernameProvider;
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
import org.eclipse.milo.opcua.stack.core.types.builtin.*;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort;
import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
/**
* @Description:
* @Author: xu
* @Data: 2024-2024/9/7-17
* @Version: V1.0
*/
public class Test2 {
public static void main(String[] args) throws Exception {
// 连接地址端口号
String endPointUrl = "opc.tcp://192.168.11.199:4840";
OpcUaClient opcClient = null;
//更加是否要账号密码执行不同的策略
String username = null;
String password = null;
//安全权限
Path securityTempDir = Paths.get(System.getProperty("java.io.tmpdir"), "security");
Files.createDirectories(securityTempDir);
if (!Files.exists(securityTempDir)) {
throw new Exception("unable to create security dir: " + securityTempDir);
}
String uri = SecurityPolicy.None.getUri();
IdentityProvider identityProvider;
if (!StringUtil.isNullOrEmpty(username) && !StringUtil.isNullOrEmpty(password)) {
identityProvider = new UsernameProvider(username, password);
} else {
identityProvider = new AnonymousProvider();
}
opcClient = OpcUaClient.create(endPointUrl,
endpoints -> {
final Optional<EndpointDescription> endpoint = endpoints
.stream()
.filter(e -> e.getSecurityPolicyUri().equals(uri))
.findFirst();
EndpointDescription newEndpoint = new EndpointDescription(endPointUrl, endpoint.get().getServer(), endpoint.get().getServerCertificate(),
endpoint.get().getSecurityMode(), endpoint.get().getSecurityPolicyUri(), endpoint.get().getUserIdentityTokens(),
endpoint.get().getTransportProfileUri(), endpoint.get().getSecurityLevel());
return Optional.of(newEndpoint);
},
configBuilder ->
configBuilder
.setApplicationName(LocalizedText.english("eclipse milo opc-ua client"))
.setApplicationUri("urn:eclipse:milo:examples:client")
.setIdentityProvider(identityProvider)
.setRequestTimeout(UInteger.valueOf(500))
.build()
);
try {
CompletableFuture<UaClient> connect = opcClient.connect();
connect.get();
//Thread.sleep(2000);
} catch (ExecutionException e) {
System.out.println("连接失败opc opcUaClientConnect方法");
//e.printStackTrace();
}
//开启连接
opcClient.connect().get();
// namespaceIndex: 是获取的的下标 identifier: 是名称
NodeId nodeId_Tag1 = new NodeId(3, "\"Tag_1\"");
// 获取值
DataValue value = opcClient.readValue(0.0, TimestampsToReturn.Both, nodeId_Tag1).get();
// 输出值
System.out.println(value.getValue().getValue());
// 写入值
//注意identifier是字符串,要看是否带“,带”就需要使用转义\
NodeId nodeId = new NodeId(3, "\"Tag_1\"");//"OPC_Test.设备 1.TAG1"
//创建Variant对象和DataValue对象,ua变量名里的dateType映射关系,uint16--UShort,uint32--UInteger
UShort value3 = UShort.valueOf(1);
// 写入类型根据DateType判断
// 警告: 写入类型要看opc ua变量名里的dateType是什么类型 否则写入失败 false
Variant v = new Variant(value3);
DataValue dataValue = new DataValue(v, null, null);
StatusCode statusCode = opcClient.writeValue(nodeId, dataValue).get();
System.out.println(statusCode.isGood());// 写入成功返回值
}
}
java示例三,springboot动态策略,推荐
private OpcUaDto dto;
private static OpcUaClient opcUaClient;
private OpcUaClient getOpcUaClient() {
if (opcUaClient == null) {
log.info("初始化OPC UA Client......");
try {
IdentityProvider identityProvider;
if (!StringUtil.isNull(dto.getUsername()) && !StringUtil.isNull(dto.getPassword())) {
identityProvider = new UsernameProvider(dto.getUsername(), dto.getPassword());
} else {
identityProvider = new AnonymousProvider();
}
opcUaClient = OpcUaClient.create(
dto.getEndPointUrl(),
endpoints ->
endpoints.stream()
.findFirst(),
configBuilder ->
configBuilder
.setIdentityProvider(identityProvider)
.setRequestTimeout(uint(dto.getRequestTimeout()))
.build()
);
log.info("初始化OPC UA Client......成功");
} catch (Exception e) {
log.error("初始化OPC UA Client失败, {}", e.getMessage());
return null;
}
}
if (!opcUaClient.getSession().isDone()) {
try {
// synchronous connect
opcUaClient.connect().get();
log.info("OPC UA Client连接connect成功");
} catch (Exception e) {
log.error("OPC UA Client连接connect失败, {}", e.getMessage());
opcUaClient.disconnect();
opcUaClient = null;
return null;
}
}
return opcUaClient;
}
public void read() {
String item = "tongdao.tag1.aaa";
NodeId nodeId = new NodeId(dto.getNamespaceIndex(),
Item);
DataValue value = opcUaClient.readValue(0.0, TimestampsToReturn.Both, nodeId).get();
if (value.getValue() == null) {
log.error("OPC UA字段读取为空, code={}", Item);
}
System.out.println(value.getValue().getValue());
}
public void write() {
//写入值
int v = 1;
String item = "tongdao.tag1.aaa";
NodeId nodeId = new NodeId(dto.getNamespaceIndex(), item);
Variant value = new Variant(v);
DataValue dataValue = new DataValue(value,null,null);
StatusCode statusCode = opcUaClient.writeValue(nodeId,dataValue).get();
System.out.println(statusCode.isGood());
}
package com.example.opcua.util;
/**
* @Description:
* @Author: xu
* @Data: 2024-2024/9/8-22
* @Version: V1.0
*/
public class OpcUaDto {
private String appUri = "";
private String appName = "";
private String password = "opcua";
private String username = "opcua";
private String endPointUrl = "opc.tcp://192.168.3.5:49320";
private String namespaceIndex = "2";
private String requestTimeout = "5000";
}