In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article is to share with you about the process of using java's milo framework to access OPCUA services. The editor thinks it is very practical, so I share it with you. I hope you can get something after reading this article. Let's take a look at it.
This time, the KEPServerEX5 simulation server is adopted, and the program developed by milo is used as the client.
First, set up the server, omitting the installation of KEPServerEX5, and the following is the configuration process
Set channels, devices, labels
Set the user name and password for access
Set up nodes accessed through opc-ua
Second, use the framework of milo to develop clients to access opcua services
1. Track down the following dependencies in the pom file
Org.eclipse.milo sdk-client 0.2.4 org.bouncycastle bcpkix-jdk15on 1.57 org.eclipse.milo sdk-server 0.2.4
2. OPC UA protocol object interface
Package com.jndj.platform.common.milo;import org.eclipse.milo.opcua.sdk.client.OpcUaClient;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.stack.core.security.SecurityPolicy;import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;import java.util.concurrent.CompletableFuture;import java.util.function.Predicate / * * @ author yaohj * @ date 2020-7-30 * OPC UA protocol object interface * / public interface OpcUAClientService {/ * OPC UA server address and interface * / default String getEndpointUrl () {return "opc.tcp://127.0.0.1:49320" } / * filter returned server endpoint * / default Predicate endpointFilter () {return e-> true;} / * connection server security policy * None, Basic128Rsa15, Basic256, Basic256Sha256, Aes128_Sha256_RsaOaep, Aes256_Sha256_RsaPss * / default SecurityPolicy getSecurityPolicy () {return SecurityPolicy.None } / * provide authentication * / default IdentityProvider getIdentityProvider () {return new AnonymousProvider ();} / * actual operation service, rewritten by implementation class to implement * / void run (OpcUaClient client, CompletableFuture future) throws Exception;}
3. OPC UA protocol object entity class
Package com.jndj.platform.common.milo;import com.google.common.collect.ImmutableList;import org.eclipse.milo.opcua.sdk.client.OpcUaClient;import org.eclipse.milo.opcua.stack.core.types.builtin.*;import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;import org.springframework.stereotype.Service;import java.util.List;import java.util.concurrent.CompletableFuture @ Service ("OpcUAClientService") public class OpcUAClientServiceImpl implements OpcUAClientService {/ * override the interface and establish a service with OPC UA * / @ Override public void run (OpcUaClient client, CompletableFuture future) throws Exception {/ / synchronously establish a connection to client.connect () .get () / / Asynchronous read data readTagData (client) .thenAccept (values-> {DataValue nodeId_Tag1 = values.get (0); DataValue nodeId_Tag2 = values.get (1); System.out.println ("# Tag1=" + nodeId_Tag1.getValue () .getValue () System.out.println ("# Tag2=" + nodeId_Tag2.getValue (). GetValue ()); future.complete (client);});} / * read data from the tag point * / private CompletableFuture readTagData (OpcUaClient client) {NodeId nodeId_Tag1 = new NodeId (2, "Channel1.Device1.Tag1") NodeId nodeId_Tag2 = new NodeId (2, "Channel1.Device1.Tag2"); List nodeIds = ImmutableList.of (nodeId_Tag1, nodeId_Tag2); return client.readValues (0.0, TimestampsToReturn.Both, nodeIds);}}
4. OPC UA protocol running object
Package com.jndj.platform.common.milo;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.UaTcpStackClient;import org.eclipse.milo.opcua.stack.core.Stack;import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription Import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Service;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;import java.util.Arrays;import java.util.concurrent.CompletableFuture;import java.util.concurrent.ExecutionException;import java.util.concurrent.TimeUnit;import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint @ Service ("OpcUAClientRunner") public class OpcUAClientRunner {private final Logger logger = LoggerFactory.getLogger (getClass ()); private final CompletableFuture future = new CompletableFuture (); private final OpcUAClientService opcUAClientService; public OpcUAClientRunner (OpcUAClientService opcUAClientService) {this.opcUAClientService = opcUAClientService } / * OPC UA's run entry program * / public void run () {try {/ / create OPC UA client OpcUaClient opcUaClient = createClient () / / after the execution of future, asynchronously judge the status of future.whenCompleteAsync ((c, ex)-> {if (ex! = null) {logger.error ("connection OPC UA service error: {}", ex.getMessage (), ex) } / / close OPC UA client try {opcUaClient.disconnect (). Get (); Stack.releaseSharedResources ();} catch (InterruptedException | ExecutionException e) {logger.error ("OPC UA service shutdown error: {}", e.getMessage (), e) }}); try {/ / get the data of OPC UA server opcUAClientService.run (opcUaClient, future); future.get (5, TimeUnit.SECONDS) } catch (Throwable t) {logger.error ("OPC UA client run error: {}", t.getMessage (), t); future.completeExceptionally (t);}} catch (Throwable t) {logger.error ("OPC UA client creation error: {}", t.getMessage (), t) Future.completeExceptionally (t);}} / * create a service connection object for OPC UA * / private OpcUaClient createClient () throws Exception {Path securityTempDir = Paths.get (System.getProperty ("java.io.tmpdir"), "security"); Files.createDirectories (securityTempDir) If (! Files.exists (securityTempDir)) {throw new Exception ("unable to create security path:" + securityTempDir);} KeyStoreLoader loader = new KeyStoreLoader () .load (securityTempDir); / / get OPC UA server node EndpointDescription [] endpoints = UaTcpStackClient.getEndpoints (opcUAClientService.getEndpointUrl ()) .get () EndpointDescription endpoint = Arrays.stream (endpoints) .filter (e-> e.getEndpointUrl () .equals (opcUAClientService.getEndpointUrl () .findFirst () .orElseThrow (()-> new Exception ("No node returns")) / / set OPC UA configuration information OpcUaClientConfig config = OpcUaClientConfig.builder () .setApplicationName (LocalizedText.english ("OPC UA SCREEN")) .setApplicationUri ("urn:DATA-TRANSFER:OPC UA SCREEN") .set Certificate (loader.getClientCertificate ()) .setKeyPair (loader.getClientKeyPair ()) .setEndpoint (endpoint) .setIdentityProvider (new UsernameProvider ("Administrator") "123456") .setRequestTimeout (uint (5000)) .build () / / create OPC UA client return new OpcUaClient (config);}}
5. OPC UA access certificate class
Package com.jndj.platform.common.milo;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 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;class KeyStoreLoader {private final Logger logger = LoggerFactory.getLogger (getClass ()); 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]) $") / / Certificate alias private static final String CLIENT_ALIAS = "client-ai"; / / obtain the password of the private key private static final char [] PASSWORD = "password" .toCharArray (); / / Certificate object private X509Certificate clientCertificate; / / key pair object private KeyPair clientKeyPair; KeyStoreLoader load (Path baseDir) throws Exception {/ / create a KeyStore using the `PKCS12` encryption standard. KeyStore will be used later as the object for reading and generating certificates. KeyStore keyStore = KeyStore.getInstance ("PKCS12"); / / the file suffix of PKCS12's encryption standard is .pfx, which contains both public and private keys. Other formats such as .der contain only the public key and the private key in a separate file. Path serverKeyStore = baseDir.resolve ("example-client.pfx"); logger.info ("Loading KeyStore at {}", serverKeyStore); / / create a .pfx certificate file if the file does not exist. If (! Files.exists (serverKeyStore)) {keyStore.load (null, PASSWORD); / / uses the 2048-bit RAS algorithm. `SelfSignedCertificateGenerator` is an object of the Milo library. KeyPair keyPair = SelfSignedCertificateGenerator.generateRsaKeyPair (2048); / / SelfSignedCertificateBuilder` is also an object of the Milo library and is used to generate certificates. / / the certificate properties set in the middle can be modified by yourself. SelfSignedCertificateBuilder builder = new SelfSignedCertificateBuilder (keyPair) .setCommonName ("Eclipse Milo Example Client") .setOrganization ("digitalpetri") .setOrganizationalUnit ("dev") .setLocali tyName ("Folsom") .setStateName ("CA") .setCountryCode ("US") .setApplicationUri ("urn:eclipse:milo:examples") : client ") .addDnsName (" localhost ") .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) }} / / create certificate X509Certificate certificate = builder.build (); / / set alias, password, certificate chain keyStore.setKeyEntry (CLIENT_ALIAS, keyPair.getPrivate (), PASSWORD, new X509Certificate [] {certificate}) corresponding to the private key Try (OutputStream out = Files.newOutputStream (serverKeyStore)) {/ / Save the certificate to the output stream keyStore.store (out, PASSWORD);}} else {try (InputStream in = Files.newInputStream (serverKeyStore)) {/ / read keyStore.load (in, PASSWORD) if the file exists Get the private key of the corresponding alias with a password. Key serverPrivateKey = keyStore.getKey (CLIENT_ALIAS, PASSWORD); if (serverPrivateKey instanceof PrivateKey) {/ / gets the certificate object corresponding to the alias. ClientCertificate = (X509Certificate) keyStore.getCertificate (CLIENT_ALIAS); / / get the public key PublicKey serverPublicKey = clientCertificate.getPublicKey (); / / create the Keypair object. ClientKeyPair = new KeyPair (serverPublicKey, (PrivateKey) serverPrivateKey);} return this;} / / return certificate X509Certificate getClientCertificate () {return clientCertificate;} / / return key pair KeyPair getClientKeyPair () {return clientKeyPair;}}
6. Business service class
Package com.jndj.platform.phase2.service.impl;import com.jndj.platform.common.milo.OpcUAClientRunner;import com.jndj.platform.common.milo.OpcUAClientService;import com.jndj.platform.phase2.service.Phase2Service;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service / * * @ author yaohj * @ date 2020-7-22 * obtain the second phase power generation data (units 3 and 4) * / @ Service ("phase2Service") public class Phase2ServiceImpl implements Phase2Service {@ Autowired private OpcUAClientService opcUAClientService; / * * obtain the second phase power generation data (units 3 and 4) and save them in the database * / @ Override public void searchPhase2ElectricData () {new OpcUAClientRunner (opcUAClientService). Run ();}}
7. Service Controller class, timing scheduling
Package com.jndj.platform.phase2.controller;import com.jndj.platform.phase2.service.Phase2Service;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.stereotype.Controller;import java.text.SimpleDateFormat;import java.util.Date / * * @ author yaohj * @ date 2020-7-22 * obtain secondary power generation data (Units 3 and 4) * / @ Controllerpublic class Phase2Controller {private static final Logger logger = LoggerFactory.getLogger (Phase2Controller.class); private static final SimpleDateFormat dateFormat = new SimpleDateFormat ("yyyy:mm:dd HH:mm:ss"); @ Autowired private Phase2Service phase2Service / * obtain the second phase power generation data (units 3 and 4) and save them in the database (once every x minutes) * / @ Scheduled (initialDelay = 30000, fixedRate = 30000) public void searchGasData () {logger.info ("# obtain the second phase power generation data (units 3 and 4)-timing task execution time:" + dateFormat.format (new Date () Phase2Service.searchPhase2ElectricData ();}}
8. Run the result and obtain the data in the opcua service on a regular basis
OK, the above is all the source code, everyone's problems can basically be solved.
This is the process of using java's milo framework to access OPCUA services. The editor believes that there are some knowledge points that we may see or use in our daily work. I hope you can learn more from this article. For more details, please follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.