本文记录JAVA使用Milo与PLC进行连接(PLC开启OPCUA),Milo有一个订阅的功能,订阅一个地址后,当地址中的数据发生变化的时候会主动通知,接下来记录一下Milo的用法:
public OpcUaClient createClient() {
if(opcUaClient != null){
return opcUaClient;
}
Path securityTempDir = Paths.get(System.getProperty("java.io.tmpdir"), "security");
try {
Files.createDirectories(securityTempDir);
} catch (IOException e) {
throw new RuntimeException(e);
}
if (!Files.exists(securityTempDir)) {
try {
throw new Exception("不能够创建安全路径: " + securityTempDir);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// KeyStoreLoader loader = new KeyStoreLoader().load(securityTempDir);
// 获取OPC UA的服务器端节点,OPCUA有多种加密方法(可在PLC中设置),当前只列出了不使用任何加密的方式进行连接,其他方式的连接会在以后进行补充
//applicationUri 可在PLC中查询到,applicationName为uri冒号后面的内容;
EndpointDescription[] endpoints =
new EndpointDescription[0];
try {
endpoints = UaTcpStackClient.getEndpoints(endpointUrl).get();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
EndpointDescription endpoint = null;
try {
endpoint = Arrays.stream(endpoints)
.filter(e -> e.getEndpointUrl().equals(endpointUrl))
.findFirst().orElseThrow(() -> new Exception("没有节点返回"));
} catch (Exception e) {
throw new RuntimeException(e);
}
// 设置OPC UA的配置信息
OpcUaClientConfig config =
OpcUaClientConfig.builder()
// .setApplicationName(LocalizedText.english("PLC_NAME"))
.setApplicationName(LocalizedText.english("KEPServerEX/UA Server")) //此处填Uri中冒号后面的字符串
// .setApplicationUri("urn:SIMATIC.S7-1500.OPC-UA.Application:PLC_APPNAME")
.setApplicationUri("urn:wang-PC:KEPServerEX/UA Server") //PLC连接信息
// .setCertificate(loader.getClientCertificate())
// .setKeyPair(loader.getClientKeyPair())
.setEndpoint(endpoint)
.setIdentityProvider(new AnonymousProvider())
.setRequestTimeout(uint(5000))
.build();
// 创建OPC UA客户端
opcUaClient = new OpcUaClient(config);
return opcUaClient;
}
节点名称:
Channel1.Device1.TAG1
枚举:
public class OpcNodeList {
public static String LINE_CYLINDER_SCAN ="Channel1.Device1.TAG1";
}
订阅节点:
public void createSubscription() {
OpcUaClient client = null;
try {
client = createClient();
} catch (Exception e) {
e.printStackTrace();
}
//创建连接
try {
client.connect().get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
//创建发布间隔1000ms的订阅对象
UaSubscription subscription = null;
try {
subscription = client.getSubscriptionManager().createSubscription(1000.0).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
//创建监控的参数
MonitoringParameters parameters1 = new MonitoringParameters(
uint(1),
1000.0, // sampling interval
null, // filter, null means use default
uint(10), // queue size
true // discard oldest
);
//创建订阅
NodeId nodeId1 = new NodeId(2, OpcNodeList.LINE_CYLINDER_SCAN);
ReadValueId readValueId1 = new ReadValueId(nodeId1, AttributeId.Value.uid(),null,null);
//该请求最后用于创建订阅。
MonitoredItemCreateRequest request1 = new MonitoredItemCreateRequest(readValueId1, MonitoringMode.Reporting, parameters1);
List<MonitoredItemCreateRequest> requests = new ArrayList<>();
requests.add(request1);
//创建监控项,并且注册变量值改变时候的回调函数。
try {
List<UaMonitoredItem> items = subscription.createMonitoredItems(
TimestampsToReturn.Both,
requests,
(item,id)->{
item.setValueConsumer((itemC, value)->{
System.out.println("id :"+id);
System.out.println("nodeid :"+itemC.getReadValueId().getNodeId());
System.out.println("value :"+value.getValue().getValue());
//todo 此处监听回调的地址以及数据
});
}
).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
https://gitee.com/kingrisingsun/opcuamilo-demo
{{ cmt.username }}
{{ cmt.content }}
{{ cmt.commentDate | formatDate('YYYY.MM.DD hh:mm') }}