springboot整合milo库实现对opc ua连接配置的动态修改

时间:2024-11-04 19:49:05
import lombok.extern.slf4j.Slf4j; 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.Identifiers; import org.eclipse.milo.opcua.stack.core.UaException; import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy; import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText; import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId; import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger; import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseDirection; import org.eclipse.milo.opcua.stack.core.types.enumerated.BrowseResultMask; import org.eclipse.milo.opcua.stack.core.types.enumerated.NodeClass; import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn; import org.eclipse.milo.opcua.stack.core.types.structured.BrowseDescription; import org.eclipse.milo.opcua.stack.core.types.structured.BrowseResult; import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription; import org.eclipse.milo.opcua.stack.core.types.structured.ReferenceDescription; import org.springblade.coalface.listener.OpcSubscriptionListener; import org.springblade.coalface.modules.communicate.entity.OpcUaCommunicate; import org.springblade.coalface.modules.communicate.service.CommunicateService; import org.springblade.coalface.modules.opcua.dto.OpcKey; import org.springblade.core.tool.utils.CollectionUtil; import org.springblade.core.tool.utils.StringUtil; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.concurrent.ExecutionException; import java.util.function.Function; @Slf4j @Service public class OpcUaTemplate { @Resource private CommunicateService communicateService; private OpcUaClient opcUaClient; @PostConstruct private void init() { try { OpcUaCommunicate opcUaCommunicate= communicateService.getOpcUaCommunicate(); System.out.println(opcUaCommunicate); if(opcUaCommunicate.getEnabled()){ opcUaClient=createClient(opcUaCommunicate.getEndPointUrl(),opcUaCommunicate.getUsername(),opcUaCommunicate.getPassword()); this.connect(); opcUaClient.getSubscriptionManager().createSubscription(1000.0).get(); opcUaClient.getSubscriptionManager().addSubscriptionListener(new OpcSubscriptionListener(opcUaClient)); } } catch (UaException e) { log.error(e.getMessage()); throw new RuntimeException(e); } catch (ExecutionException | InterruptedException e) { throw new RuntimeException(e); } } public OpcUaClient createClient(String endPointUrl,String username,String password) throws UaException { Function<List<EndpointDescription>, Optional<EndpointDescription>> selectEndpoint = endpoints -> { final Optional<EndpointDescription> endpoint = endpoints .stream() .filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getUri())) .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); }; IdentityProvider identityProvider=new AnonymousProvider(); if(StringUtil.isNotBlank(username)&&StringUtil.isNotBlank(password)){ identityProvider=new UsernameProvider(username,password); } return OpcUaClient.create(endPointUrl, selectEndpoint, configBuilder -> configBuilder .setApplicationName(LocalizedText.english("eclipse milo coalface client")) .setApplicationUri("urn:eclipse:milo:coalface:client") //访问方式 .setIdentityProvider(identityProvider) .setRequestTimeout(UInteger.valueOf(60000)) .build() ); } public void connect() { try { opcUaClient.connect().whenComplete((result, ex) -> { if (ex != null) { log.error(ex.getMessage()); } else { log.info("{} 连接成功!", opcUaClient.getConfig().getApplicationUri()); } }).get(); } catch (InterruptedException | ExecutionException e) { throw new RuntimeException(e); } } public void disconnect() { if(Objects.nonNull(opcUaClient)) { try { opcUaClient.disconnect().whenComplete((result, ex) -> { if (ex != null) { log.error(ex.getMessage()); } else { log.info("{} 断开连接成功!", opcUaClient.getConfig().getApplicationUri()); } }).get(); } catch (InterruptedException | ExecutionException e) { throw new RuntimeException(e); } } } public List<String> getBrowseKeys(String identifier) { List<String> keys = new ArrayList<>(1000); try { opcUaClient.connect().get(); browse(identifier, keys, opcUaClient); opcUaClient.disconnect().get(); } catch (Exception e) { log.error(e.getMessage()); } keys.remove(null); return keys; } private void browse(String identifier, List<String> keys, UaClient client) throws Exception { NodeId nodeId = Identifiers.ObjectsFolder; if (!StringUtils.isEmpty(identifier)) { nodeId = new NodeId(2, identifier); } BrowseDescription browse = new BrowseDescription( nodeId, BrowseDirection.Forward, Identifiers.References, true, UInteger.valueOf(NodeClass.Object.getValue() | NodeClass.Variable.getValue()), UInteger.valueOf(BrowseResultMask.All.getValue()) ); BrowseResult browseResult = client.browse(browse).get(); ReferenceDescription[] references = browseResult.getReferences(); for (ReferenceDescription reference : references) { if (reference.getNodeClass().getValue() == NodeClass.Variable.getValue()) { keys.add(reference.getNodeId().getIdentifier().toString()); } browse(reference.getNodeId().getIdentifier().toString(), keys, client); } } public List<DataValue> readValues(List<OpcKey> keys) { // List<String> keyNames = getKeyNames(keys); /* List<DataValue> res= BatchUtil.protectBach(keyNames, idList->{ return this.readValues(idList, client); },1000);*/ List<DataValue> dataValues = new ArrayList<>(1000); if (Objects.isNull(opcUaClient)) { return dataValues; } if (CollectionUtil.isNotEmpty(keys)) { List<NodeId> nodeIds = new ArrayList<>(1000); keys.forEach(e -> { NodeId nodeId = new NodeId(2, e.getPointAddress()); nodeIds.add(nodeId); }); try { dataValues = opcUaClient.readValues(0.0, TimestampsToReturn.Neither, nodeIds).get(); } catch (InterruptedException | ExecutionException e) { log.error("{} {}", opcUaClient.getConfig().getApplicationUri(), e.getMessage()); } } return dataValues; } public void updateConfig(OpcUaCommunicate opcUaCommunicate) { this.disconnect(); if(opcUaCommunicate.getEnabled()){ try { opcUaClient=createClient(opcUaCommunicate.getEndPointUrl()); this.connect(); opcUaClient.getSubscriptionManager().createSubscription(1000.0).get(); opcUaClient.getSubscriptionManager().addSubscriptionListener(new OpcSubscriptionListener(opcUaClient)); } catch (UaException | ExecutionException | InterruptedException e) { throw new RuntimeException(e); } }else{ opcUaClient=null; } } }