程序结构:
配置文件resources:
opcua.properties
西门子PLC端口号为4840,kepserver为49320
#opcua服务端配置参数
#opcua.server.endpoint.url=opc.tcp://192.168.2.102:49320
opcua.server.endpoint.url=opc.tcp://192.168.2.11:4840
opcua.server.idp.username=Administrator
opcua.server.idp.password=123456
#opcua客户端配置参数
opcua.client.app.name=zgOpcUaClient
opcua.client.app.uri=urn:Shanghai:Kx:KxAutomation:Zg
opcua.client.cert.path=D:/zhengshu/
opcua.client.cert.file=zg-client.pfx
opcua.client.cert.alias=zgclient-ai
opcua.client.cert.common.name=KxZg
opcua.client.cert.organization=Kaixin
opcua.client.cert.organization.unit=Kx
opcua.client.cert.locality.name=Terran
opcua.client.cert.state.name=Shanghai
opcua.client.cert.country.code=CN
opcua.client.cert.dns.name=Zg
opcua.client.cert.ip.address=127.0.0.1
opcua.client.cert.keystore.password=123456
它对应的实体类调用:
package com.zg.mymes.myConnPLC.myOPCUA.config;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
/**
* @Auther: Zg
* @Date: 2022/11/23 - 11 - 23 - 15:07
* @Description: com.zg.mymes.myConnPLC.myOPCUA.config
* @version: 1.0
*/
@Getter
@Configuration
@PropertySource("classpath:opcua.properties")
public class MyOPCUAProperties {
@Value("${opcua.server.endpoint.url}")
private String endpointUrl;
@Value("${opcua.server.idp.username}")
private String idpUsername;
@Value("${opcua.server.idp.password}")
private String idpPassword;
@Value("${opcua.client.app.name}")
private String appName;
@Value("${opcua.client.app.uri}")
private String appUri;
@Value("${opcua.client.cert.path}")
private String certPath;
@Value("${opcua.client.cert.file}")
private String certFile;
@Value("${opcua.client.cert.alias}")
private String certAlias;
@Value("${opcua.client.cert.common.name}")
private String commonName;
@Value("${opcua.client.cert.organization}")
private String organization;
@Value("${opcua.client.cert.organization.unit}")
private String orgUnit;
@Value("${opcua.client.cert.locality.name}")
private String localityName;
@Value("${opcua.client.cert.state.name}")
private String stateName;
@Value("${opcua.client.cert.country.code}")
private String countryCode;
@Value("${opcua.client.cert.dns.name}")
private String dnsName;
@Value("${opcua.client.cert.ip.address}")
private String ipAddress;
@Value("${opcua.client.cert.keystore.password}")
private String keyPassword;
}
opcnode.properties:
opcnode.index,西门子PLC为3,kepserver为2
opcnode.index=3
opcnode.var.var0="S7MesData"."S7Real"[0]
opcnode.var.var1="S7MesData"."S7Real"[1]
opcnode.var.var2="S7MesData"."S7Real"[2]
opcnode.var.var3="S7MesData"."S7Real"[3]
opcnode.var.var4="S7MesData"."S7Real"[4]
opcnode.var.var5="S7MesData"."S7Real"[5]
opcnode.var.var6="S7MesData"."S7Real"[100]
opcnode.var.var7="S7MesData"."S7String"[0]
opcnode.var.var8="S7MesData"."S7Int"[0]
它对应的实体类调用:
package com.zg.mymes.myConnPLC.myOPCUA.config;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
/**
* @Auther: Zg
* @Date: 2022/11/23 - 11 - 23 - 15:27
* @Description: com.zg.mymes.myConnPLC.myOPCUA.config
* @version: 1.0
*
* 相当于点表
* */
@Getter
@Configuration
@PropertySource("classpath:opcnode.properties")
public class MyOPCNode {
@Value("${opcnode.index}")
private String index;
@Value("${opcnode.var.var0}")
private String var0;
@Value("${opcnode.var.var1}")
private String var1;
@Value("${opcnode.var.var2}")
private String var2;
@Value("${opcnode.var.var3}")
private String var3;
@Value("${opcnode.var.var4}")
private String var4;
@Value("${opcnode.var.var5}")
private String var5;
@Value("${opcnode.var.var6}")
private String var6;
@Value("${opcnode.var.var7}")
private String var7;
@Value("${opcnode.var.var8}")
private String var8;
}
生成证书类:KeyStoreLoader
package com.zg.mymes.myConnPLC.myOPCUA.cert;
import org.eclipse.milo.opcua.sdk.server.util.HostnameUtil;
import org.eclipse.milo.opcua.stack.core.util.SelfSignedCertificateBuilder;
import org.eclipse.milo.opcua.stack.core.util.SelfSignedCertificateGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.*;
import java.security.cert.X509Certificate;
import java.util.regex.Pattern;
/**
* @Auther: Zg
* @Date: 2022/11/23 - 11 - 23 - 15:01
* @Description: com.zg.mymes.myConnPLC.myOPCUA.cert
* @version: 1.0
*/
@Component
public class KeyStoreLoader {
private static final Pattern IP_ADDR_PATTERN = Pattern
.compile("^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");
// 证书别名
private static final String CLIENT_ALIAS = "jlclient-ai";
// 获取私钥的密码
private static final char[] PASSWORD = "123456".toCharArray();
private final Logger logger = LoggerFactory.getLogger(getClass());
// 证书对象
private X509Certificate clientCertificate;
// 密钥对对象
private KeyPair clientKeyPair;
/**
* @MethodName: load
* @Description: load
* @param baseDir
* @return
* @throws Exception
* @CreateTime 2019年12月11日 下午4:02:43
*/
public KeyStoreLoader load(Path baseDir) throws Exception {
// 创建一个使用`PKCS12`加密标准的KeyStore。KeyStore在后面将作为读取和生成证书的对象。
KeyStore keyStore = KeyStore.getInstance("PKCS12");
// PKCS12的加密标准的文件后缀是.pfx,其中包含了公钥和私钥。
// 而其他如.der等的格式只包含公钥,私钥在另外的文件中。
Path serverKeyStore = baseDir.resolve("zg-client.pfx");
logger.info("Loading KeyStore at {}", serverKeyStore);
// 如果文件不存在则创建.pfx证书文件。
if (!Files.exists(serverKeyStore)) {
keyStore.load(null, PASSWORD);
// 用2048位的RAS算法。`SelfSignedCertificateGenerator`为Milo库的对象。
KeyPair keyPair = SelfSignedCertificateGenerator.generateRsaKeyPair(2048);
// `SelfSignedCertificateBuilder`也是Milo库的对象,用来生成证书。
// 中间所设置的证书属性可以自行修改。
SelfSignedCertificateBuilder builder = new SelfSignedCertificateBuilder(keyPair)
.setCommonName("KxZg")
.setOrganization("Kaixin")
.setOrganizationalUnit("Kx")
.setLocalityName("Terran")
.setStateName("Shanghai")
.setCountryCode("CN")
.setApplicationUri("urn:Shanghai:Kx:KxAutomation:Zg")
.addDnsName("Zg")
.addIpAddress("127.0.0.1");
// Get as many hostnames and IP addresses as we can listed in the certificate.
for (String hostname : HostnameUtil.getHostnames("0.0.0.0")) {
if (IP_ADDR_PATTERN.matcher(hostname).matches()) {
builder.addIpAddress(hostname);
} else {
builder.addDnsName(hostname);
}
}
// 创建证书
X509Certificate certificate = builder.build();
// 设置对应私钥的别名,密码,证书链
keyStore.setKeyEntry(CLIENT_ALIAS, keyPair.getPrivate(), PASSWORD, new X509Certificate[] { certificate });
try (OutputStream out = Files.newOutputStream(serverKeyStore)) {
// 保存证书到输出流
keyStore.store(out, PASSWORD);
}
} else {
try (InputStream in = Files.newInputStream(serverKeyStore)) {
// 如果文件存在则读取
keyStore.load(in, PASSWORD);
}
}
// 用密码获取对应别名的私钥。
Key serverPrivateKey = keyStore.getKey(CLIENT_ALIAS, PASSWORD);
if (serverPrivateKey instanceof PrivateKey) {
// 获取对应别名的证书对象。
clientCertificate = (X509Certificate) keyStore.getCertificate(CLIENT_ALIAS);
// 获取公钥
PublicKey serverPublicKey = clientCertificate.getPublicKey();
// 创建Keypair对象。
clientKeyPair = new KeyPair(serverPublicKey, (PrivateKey) serverPrivateKey);
}
return this;
}
// 返回证书
public X509Certificate getClientCertificate() {
return clientCertificate;
}
// 返回密钥对
public KeyPair getClientKeyPair() {
return clientKeyPair;
}
}
OPCUA订阅,写入,读取等工具类:
ClientRunner:
package com.zg.mymes.myConnPLC.myOPCUA.client;
import com.zg.mymes.myConnPLC.myOPCUA.cert.KeyStoreLoader;
import com.zg.mymes.myConnPLC.myOPCUA.config.MyOPCUAProperties;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig;
import org.eclipse.milo.opcua.sdk.client.api.identity.UsernameProvider;
import org.eclipse.milo.opcua.stack.client.DiscoveryClient;
import org.eclipse.milo.opcua.stack.core.Stack;
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned;
import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.function.Predicate;
/**
* @Auther: Zg
* @Date: 2022/11/23 - 11 - 23 - 15:04
* @Description: com.zg.mymes.myConnPLC.myOPCUA.client
* @version: 1.0
*/
@Slf4j
@Component
public class ClientRunner {
private final CompletableFuture<OpcUaClient> future = new CompletableFuture<>();
@Autowired
private MyOPCUAProperties properties;
@Autowired
private KeyStoreLoader keyStoreLoader;
/**
* @MethodName: run
* @Description: 启动
* @return
* @throws Exception
* @CreateTime 2019年12月18日 下午4:03:47
*/
public OpcUaClient run() throws Exception {
OpcUaClient client = createClient();
future.whenCompleteAsync((c, ex) -> {
if (ex != null) {
log.error("Error running example: {}", ex.getMessage(), ex);
}
try {
c.disconnect().get();
Stack.releaseSharedResources();
} catch (InterruptedException | ExecutionException e) {
log.error("Error disconnecting:", e.getMessage(), e);
}
});
return client;
}
/**
* @MethodName: createClient
* @Description: 创建客户端
* @return
* @throws Exception
* @CreateTime 2019年12月18日 下午4:02:54
*/
private OpcUaClient createClient() throws Exception {
Path securityTempDir = Paths.get(properties.getCertPath(), "security");
Files.createDirectories(securityTempDir);
if (!Files.exists(securityTempDir)) {
log.error("unable to create security dir: " + securityTempDir);
return null;
}
KeyStoreLoader loader = keyStoreLoader.load(securityTempDir);
// 搜索OPC节点
List<EndpointDescription> endpoints = null;
try {
endpoints = DiscoveryClient.getEndpoints(properties.getEndpointUrl()).get();
} catch (Throwable e) {
// try the explicit discovery endpoint as well
String discoveryUrl = properties.getEndpointUrl();
if (!discoveryUrl.endsWith("/")) {
discoveryUrl += "/";
}
discoveryUrl += "discovery";
log.info("Trying explicit discovery URL: {}", discoveryUrl);
endpoints = DiscoveryClient.getEndpoints(discoveryUrl).get();
}
//OPC服务器地址
EndpointDescription endpoint = endpoints.stream()
.filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getUri())).filter(endpointFilter())
.findFirst().orElseThrow(() -> new Exception("no desired endpoints returned"));
//setKeyPair()接受一个KeyPair对象表示密匙对。
//setEndpoint()接受一个EndpointDescription对象,就是设置刚刚我们选择的节点就可以了。
//setIdentityProvider()该方法表示指定客户端使用的访问验证方式
OpcUaClientConfig config = OpcUaClientConfig.builder()
.setApplicationName(LocalizedText.english("zgOpcUaClient"))
.setApplicationUri("urn:Shanghai:Kx:KxAutomation:Zg")
.setCertificate(loader.getClientCertificate())
.setKeyPair(loader.getClientKeyPair())
.setEndpoint(endpoint)
.setIdentityProvider(new UsernameProvider("Administrator", "123456"))
// .setIdentityProvider(new AnonymousProvider()) // 匿名验证
.setRequestTimeout(Unsigned.uint(5000)).build();
return OpcUaClient.create(config);
}
/**
* @MethodName: endpointFilter
* @Description: endpointFilter
* @return
* @CreateTime 2019年12月18日 下午4:06:22
*/
private Predicate<EndpointDescription> endpointFilter() {
return e -> true;
}
/**
* @return the future
*/
public CompletableFuture<OpcUaClient> getFuture() {
return future;
}
}
ClientHandler:
package com.zg.mymes.myConnPLC.myOPCUA.client;
import com.google.common.collect.ImmutableList;
import com.zg.mymes.myConnPLC.myOPCUA.opcEntities.NodeEntity;
import com.zg.mymes.myConnPLC.myOPCUA.opcEntities.SubscriptNode;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.sdk.client.api.nodes.VariableNode;
import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscription;
import org.eclipse.milo.opcua.stack.core.AttributeId;
import org.eclipse.milo.opcua.stack.core.BuiltinDataType;
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.UByte;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned;
import org.eclipse.milo.opcua.stack.core.types.enumerated.MonitoringMode;
import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
import org.eclipse.milo.opcua.stack.core.types.structured.MonitoredItemCreateRequest;
import org.eclipse.milo.opcua.stack.core.types.structured.MonitoringParameters;
import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
/**
* @Auther: Zg
* @Date: 2022/11/23 - 11 - 23 - 15:10
* @Description: com.zg.mymes.myConnPLC.myOPCUA.client
* @version: 1.0
*/
@Slf4j
@Service
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ClientHandler {
// 客户端实例
private OpcUaClient client = null;
@Autowired
private ClientRunner clientRunner;
private SubscriptNode myNode = new SubscriptNode();
private List<NodeEntity> nodeEntities = new ArrayList<NodeEntity>();
/**
*
* @MethodName: connect
* @Description: connect
* @throws Exception
* @CreateTime 2019年12月18日 上午10:41:09
*/
public String connect() throws Exception {
if (client != null) {
return "客户端已创建";
}
client = clientRunner.run();
if (client == null) {
return "客户端配置实例化失败";
}
// 创建连接
client.connect().get();
return "创建连接成功";
}
/**
* @MethodName: disconnect
* @Description: 断开连接
* @return
* @throws Exception
* @CreateTime 2019年12月18日 上午10:45:21
*/
public String disconnect() throws Exception {
if (client == null) {
return "连接已断开";
}
// 断开连接
clientRunner.getFuture().complete(client);
client = null;
return "断开连接成功";
}
/**
* @MethodName: subscribe
* @Description: 订阅节点变量
* @throws Exception
* @CreateTime 2019年12月18日 上午10:38:11
*/
public String subscribe(List<NodeEntity> nodes) throws Exception {
this.nodeEntities = nodes;
if (client == null) {
return "找不到客户端,操作失败";
}
// List<Node> ns = client.getAddressSpace().browse(new NodeId(2, "模拟通道一.模拟设备一")).get();
// 查询订阅对象,没有则创建
UaSubscription subscription = null;
ImmutableList<UaSubscription> subscriptionList = client.getSubscriptionManager().getSubscriptions();
if (CollectionUtils.isEmpty(subscriptionList)) {
subscription = client.getSubscriptionManager().createSubscription(1000.0).get();
} else {
subscription = subscriptionList.get(0);
}
// 监控项请求列表
List<MonitoredItemCreateRequest> requests = new ArrayList<>();
if (!CollectionUtils.isEmpty(nodes)) {
for (NodeEntity node : nodes) {
// 创建监控的参数
MonitoringParameters parameters = new MonitoringParameters(subscription.nextClientHandle(), 1000.0, // sampling
// interval
null, // filter, null means use default
Unsigned.uint(10), // queue size
true // discard oldest
);
// 创建订阅的变量, 创建监控项请 求
MonitoredItemCreateRequest request = new MonitoredItemCreateRequest(
new ReadValueId(new NodeId(node.getIndex(), node.getIdentifier()), AttributeId.Value.uid(),
null, null),
MonitoringMode.Reporting, parameters);
requests.add(request);
}
}
// 创建监控项,并且注册变量值改变时候的回调函数
subscription.createMonitoredItems(TimestampsToReturn.Both, requests, (item, id) -> {
item.setValueConsumer((i, v) -> {
log.info("========+++==========");
log.info("item={}, value={}", i.getReadValueId(), v.getValue().getValue());
log.info("========+++==========");
// NodeId nodeId = i.getReadValueId().getNodeId();
// Variant value = v.getValue();
//将OPC读取的数据存入nodeEntities
for (NodeEntity nodeEntity:this.nodeEntities
) {
if (i.getReadValueId().getNodeId().getIdentifier().equals(nodeEntity.getIdentifier())){
nodeEntity.setValue(v.getValue().getValue());
}
}
});
}).get();
return "订阅成功";
}
/**
* @MethodName: write
* @Description: 变节点量写入
* @param node
* @throws Exception
* @CreateTime 2019年12月18日 上午9:51:40
*/
public String write(NodeEntity node) throws Exception {
if (client == null) {
return "找不到客户端,操作失败";
}
NodeId nodeId = new NodeId(node.getIndex(), node.getIdentifier());
Variant value = null;
switch (node.getType()) {
case "int":
value = new Variant(Integer.parseInt(node.getValue().toString()));
break;
case "boolean":
value = new Variant(Boolean.parseBoolean(node.getValue().toString()));
break;
case "Short":
value = new Variant(Short.parseShort(node.getValue().toString()));
break;
case "String":
value = new Variant(node.getValue().toString());
break;
case "Float":
value = new Variant(Float.parseFloat(node.getValue().toString()));
break;
case "UByte":
value = new Variant(UByte.valueOf(node.getValue().toString()));
break;
}
DataValue dataValue = new DataValue(value, null, null);
StatusCode statusCode = client.writeValue(nodeId, dataValue).get();
return "节点【" + node.getIdentifier() + "】写入状态:" + statusCode.isGood();
}
/**
* @MethodName: read
* @Description: 读取
* @param node
* @return
* @throws Exception
* @CreateTime 2019年12月19日 下午2:40:34
*/
public String read(NodeEntity node) throws Exception {
if (client == null) {
return "找不到客户端,操作失败";
}
NodeId nodeId = new NodeId(node.getIndex(), node.getIdentifier());
VariableNode vnode = client.getAddressSpace().createVariableNode(nodeId);
DataValue value = vnode.readValue().get();
log.info("Value={}", value);
Variant variant = value.getValue();
log.info("Variant={}", variant.getValue());
log.info("BackingClass={}", BuiltinDataType.getBackingClass(variant.getDataType().get()));
return "节点【" + node.getIdentifier() + "】:" + variant.getValue();
}
}
生成证书,读,写,验证等操作:
package com.zg.mymes.controller;
import com.zg.mymes.myConnPLC.myOPCUA.opcEntities.NodeEntity;
import com.zg.mymes.myConnPLC.myOPCUA.cert.KeyStoreLoader;
import com.zg.mymes.myConnPLC.myOPCUA.client.ClientHandler;
import com.zg.mymes.myConnPLC.myOPCUA.config.MyOPCNode;
import com.zg.mymes.myConnPLC.myOPCUA.config.MyOPCUAProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @Auther: Zg
* @Date: 2022/11/23 - 11 - 23 - 15:32
* @Description: com.zg.mymes.controller
* @version: 1.0
*/
@Controller
@Slf4j
public class OPCUAController {
@Autowired
private ClientHandler clientHandler;
@Autowired
public KeyStoreLoader keyStoreLoader;
@Autowired
private MyOPCUAProperties properties;
@Autowired
private MyOPCNode myOPCNode;
/**
*connect
* @return
*/
@RequestMapping("/connect")
@ResponseBody
public String connect() {
try {
return clientHandler.connect();
} catch (Exception e) {
e.printStackTrace();
return "fail";
}
}
@RequestMapping("/disconnect")
@ResponseBody
public String disconnect() {
try {
return clientHandler.disconnect();
} catch (Exception e) {
e.printStackTrace();
return "fail";
}
}
@RequestMapping("/subscribe")
@ResponseBody
public String subscribe(HttpServletRequest request) {
try {
List<NodeEntity> nodes = Stream.of(request.getParameter("id").split(","))
.map(id -> NodeEntity.builder().index(2).identifier(id).build()).collect(Collectors.toList());
return clientHandler.subscribe(nodes);
} catch (Exception e) {
e.printStackTrace();
return "fail";
}
}
@RequestMapping("/write")
@ResponseBody
public String write(HttpServletRequest request) {
NodeEntity node = NodeEntity.builder().index(2).identifier(request.getParameter("id"))
.value(request.getParameter("value")).type(request.getParameter("type")).build();
try {
return clientHandler.write(node);
} catch (Exception e) {
e.printStackTrace();
return "fail";
}
}
@RequestMapping("/read")
@ResponseBody
public String read(HttpServletRequest request) {
NodeEntity node = NodeEntity.builder().index(2).identifier(request.getParameter("id")).build();
try {
return clientHandler.read(node);
} catch (Exception e) {
e.printStackTrace();
return "fail";
}
}
//创建证书
@RequestMapping("/createCert")
@ResponseBody
public String Created() throws Exception {
Path securityTempDir = Paths.get(properties.getCertPath(), "security");
keyStoreLoader.load(securityTempDir);
log.info("==========+++++");
log.info(securityTempDir.toString());
return securityTempDir.toString();
}
}
开启定时器,订阅模式读取变量:
package com.zg.mymes.helper;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import com.zg.mymes.entities.ActualData;
import com.zg.mymes.myConnPLC.myOPCUA.opcEntities.NodeEntity;
import com.zg.mymes.myConnPLC.myOPCUA.cert.KeyStoreLoader;
import com.zg.mymes.myConnPLC.myOPCUA.client.ClientHandler;
import com.zg.mymes.myConnPLC.myOPCUA.config.MyOPCNode;
import com.zg.mymes.myConnPLC.myS7.S7ConnHelper;
import com.zg.mymes.myConnPLC.myS7.myS7entities.MyS7Entity;
import com.zg.mymes.service.ActualDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.ExceptionHandler;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.lang.reflect.Field;
import java.sql.Timestamp;
import java.util.*;
import java.util.function.Consumer;
/**
* @Auther: Zg
* @Date: 2022/11/23 - 11 - 23 - 16:56
* @Description: com.zg.mymes.helper
* @version: 1.0
*/
@Service
@Slf4j
public class Listener {
@Autowired
private ClientHandler clientHandler;
@Autowired
public KeyStoreLoader keyStoreLoader;
@Autowired
private MyOPCNode myOPCNode;
@Autowired
public S7ConnHelper s7ConnHelper;
@Autowired
public ActualDataService actualDataService;
Integer errorTimes = 0;
Boolean last = false;
Boolean trigIn = false;
Boolean trigQ = false;
//OPC
@PostConstruct
public void OpcUAConn() throws Exception {
String connect = clientHandler.connect();
log.info(connect);
log.info("==========");
ArrayList<NodeEntity> nodeEntities = new ArrayList<>();
NodeEntity build0 = NodeEntity.builder()
.identifier(myOPCNode.getVar0())
.index(Integer.parseInt(myOPCNode.getIndex())).build();
NodeEntity build1 = NodeEntity.builder()
.identifier(myOPCNode.getVar1())
.index(Integer.parseInt(myOPCNode.getIndex())).build();
NodeEntity build2 = NodeEntity.builder()
.identifier(myOPCNode.getVar2())
.index(Integer.parseInt(myOPCNode.getIndex())).build();
NodeEntity build3 = NodeEntity.builder()
.identifier(myOPCNode.getVar3())
.index(Integer.parseInt(myOPCNode.getIndex())).build();
NodeEntity build4 = NodeEntity.builder()
.identifier(myOPCNode.getVar4())
.index(Integer.parseInt(myOPCNode.getIndex())).build();
NodeEntity build5 = NodeEntity.builder()
.identifier(myOPCNode.getVar5())
.index(Integer.parseInt(myOPCNode.getIndex())).build();
NodeEntity build6 = NodeEntity.builder()
.identifier(myOPCNode.getVar6())
.index(Integer.parseInt(myOPCNode.getIndex())).build();
NodeEntity build7 = NodeEntity.builder()
.identifier(myOPCNode.getVar7())
.index(Integer.parseInt(myOPCNode.getIndex())).build();
NodeEntity build8 = NodeEntity.builder()
.identifier(myOPCNode.getVar8())
.index(Integer.parseInt(myOPCNode.getIndex())).build();
nodeEntities.add(build0);
nodeEntities.add(build1);
nodeEntities.add(build2);
nodeEntities.add(build3);
nodeEntities.add(build4);
nodeEntities.add(build5);
nodeEntities.add(build6);
nodeEntities.add(build7);
nodeEntities.add(build8);
String subscribe = clientHandler.subscribe(nodeEntities);
log.info(subscribe);
//写入,注意类型
// NodeEntity build = NodeEntity.builder()
// .identifier(myOPCNode.getVar8())
// .index(Integer.parseInt(myOPCNode.getIndex()))
// .type("Short")
// .value("19")
// .build(); //整数
// NodeEntity buildFloat = NodeEntity.builder()
// .identifier(myOPCNode.getVar6())
// .index(Integer.parseInt(myOPCNode.getIndex()))
// .type("Float")
// .value("55.5")
// .build(); //浮点数
// NodeEntity build = NodeEntity.builder()
// .identifier(myOPCNode.getVar7())
// .index(Integer.parseInt(myOPCNode.getIndex()))
// .type("String")
// .value("abcde")
// .build(); //字符
// clientHandler.write(build);
}
//OPC
@Async
@Scheduled(cron = "*/1 * * * * *")
public void OpcUATestPlc() throws Exception {
log.info("===========-------============");
log.info(clientHandler.getNodeEntities().toString());
log.info("===========-------============");
}