Java对接OPC UA

一、需求

使用java对接西门子S7-1500,之前都是通过偏移量直接读取寄存器地址,通过注解 @S7Variable(address = “DB800.8.0”, type = EDataType.BOOL) 就完成。

<dependency>
    <groupId>com.github.xingshuangs</groupId>
    <artifactId>iot-communication</artifactId>
    <version>1.4.4</version>
</dependency>

现在PLC方说使用符号的方式,如下图:
在这里插入图片描述
于是技术栈选型使用Milo库的方式进行对接。

二、PLC需要提供的内容

  1. 连接地址:opc.tcp://10.19.171.XX:4840。
  2. NodeId:一般不改的话默认是3。
  3. Identifier:对应实际接口里的完整字段路径,PLC可以在他们的软件中找到或者Java开发根据接口自己拼接都可以。
    在这里插入图片描述

三、Java程序开发准备

  1. 引入依赖,在pom.xml文件中新增
        <dependency>
           <groupId>org.eclipse.milo</groupId>
           <artifactId>sdk-client</artifactId>
           <version>0.6.8</version>
       </dependency>
  1. 创建连接(以下是无安全验证方式连接),以下的连接只是为了拿到opcUaClient对象,后续的所有读写订阅都是通过opcUaClient进行操作的。

   private static final String endpointUrl = "opc.tcp://10.19.171.xx:4840";
   public static OpcUaClient opcUaClient;
   public static void main(String[] args) {
       try {
           SecurityPolicy securityPolicy = SecurityPolicy.None;
           List<EndpointDescription> endpoints;
           try {
               endpoints = DiscoveryClient.getEndpoints(endpointUrl).get();
           } catch (Throwable ex) {
               // 发现服务
               String discoveryUrl = endpointUrl;
               if (!discoveryUrl.endsWith("/")) {
                   discoveryUrl += "/";
               }
               discoveryUrl += "discovery";
               endpoints = DiscoveryClient.getEndpoints(discoveryUrl).get();
           }
           EndpointDescription endpoint = endpoints.stream()
                   .filter(e -> e.getSecurityPolicyUri().equals(securityPolicy.getUri()))
                   .findFirst()
                   .orElseThrow(() -> new Exception("没有连接上端点"));

           OpcUaClientConfig config = OpcUaClientConfig.builder()
                   .setApplicationName(LocalizedText.english("eclipse milo opc-ua client"))
                   .setApplicationUri("urn:eclipse:milo:examples:client")
                   //.setCertificate(loader.getClientCertificate())
                   //.setKeyPair(loader.getClientKeyPair())
                   .setEndpoint(endpoint)
                   //根据匿名验证和第三个用户名验证方式设置传入对象 AnonymousProvider(匿名方式)UsernameProvider(账户密码)new UsernameProvider("admin","123456")
                   .setIdentityProvider(new AnonymousProvider())
                   .setRequestTimeout(UInteger.valueOf(5000))
                   .build();
           opcUaClient = OpcUaClient.create(config);
       } catch (Exception e) {
           System.out.println("创建客户端失败");
       }
   }
  1. 数据读取
    public static void readValue() throws ExecutionException, InterruptedException {
        // 获取全局opcUaClient创建连接
        opcUaClient.connect().get();
        // 注意这里"\"LES_DB\".\"OP30_materialShel01\".\"Rec\".\"TakeCmpl\""里面需要用双引号,最终效果就是这样
        NodeId nodeId = new NodeId(3, "\"LES_DB\".\"OP30_materialShel01\".\"Rec\".\"TakeCmpl\"");
        DataValue value = opcUaClient.readValue(0.0, TimestampsToReturn.Both, nodeId).get();
        System.out.println("数据读取,值为:" + value.getValue().getValue());
    }
    
  1. 数据写入
 public static void writeValue(boolean value) throws ExecutionException, InterruptedException {
     // 获取全局opcUaClient创建连接
     opcUaClient.connect().get();
     //创建变量节点
     NodeId nodeId = new NodeId(3, "\"LES_DB\".\"OP30_materialShel01\".\"Rec\".\"TakeCmpl\"");
     //创建Variant对象和DataValue对象
     Variant v = new Variant(value);
     DataValue dataValue = new DataValue(v, null, null);
     StatusCode statusCode = opcUaClient.writeValue(nodeId, dataValue).get();
     System.out.println("写入结果:" + statusCode.isGood());
 }
  1. 数据订阅,如果你有当数据变化时候进行事件触发时候则可以使用订阅的方式
    public static void createSubscription() throws ExecutionException, InterruptedException {
        //创建连接
        opcUaClient.connect().get();
        //创建发布间隔1000ms的订阅对象
        UaSubscription subscription = opcUaClient.getSubscriptionManager().createSubscription(1000.0).get();
        //创建订阅的变量
        NodeId nodeId = new NodeId(3, "\"LES_DB\".\"OP30_materialShel01\".\"Rec\".\"TakeCmpl\"");
        ReadValueId readValueId = new ReadValueId(nodeId, AttributeId.Value.uid(), null, null);
        //创建监控的参数
        MonitoringParameters parameters = new MonitoringParameters(
                uint(1),
                1000.0,     // sampling interval
                null,       // filter, null means use default
                uint(10),   // queue size
                true        // discard oldest
        );
        //创建监控项请求
        //该请求最后用于创建订阅。
        MonitoredItemCreateRequest request = new MonitoredItemCreateRequest(readValueId, MonitoringMode.Reporting, parameters);
        List<MonitoredItemCreateRequest> requests = new ArrayList<>();
        requests.add(request);
        //创建监控项,并且注册变量值改变时候的回调函数。
        List<UaMonitoredItem> items = subscription.createMonitoredItems(
                TimestampsToReturn.Both,
                requests,
                (item, id) -> {
                    item.setValueConsumer((item2, value) -> {
                        System.out.println("nodeid :" + item.getReadValueId().getNodeId());
                        System.out.println("value :" + value.getValue().getValue());
                    });
                }
        ).get();
    }
    

四、总结

用符号的方式来对接PLC操作还是比较零碎的,主要是没有现成的框架能够将plc接口内容直接映射成java对象,当大量接口需要对接时体会尤为明显,这就需要java开发对接口内容再进行封装使得满足自己的业务需求。
我试过接口路径拿到LES_DB.OP30_materialShel01.Rec,打印结果如下:
在这里插入图片描述

### 回答1: Java对接OPC传输协议时,可以使用一些开源库或者框架来实现。 目前比较常用的是Java开源库jOpc,它是一个基于Java的开放式连接(OPC)通信库,可用于与OPC服务器进行数据通信。使用jOpc库可以方便地进行OPC数据读取和写入操作。 另外,Java也可以使用Native接口来直接对接OPC传输协议。通过Java的JNI(Java Native Interface)技术,可以调用OPC服务器提供的原生C/C++库或者DLL,进而实现与OPC服务器的通信。 无论是使用jOpc库还是Native接口,Java对接OPC传输协议的步骤大致相似。首先,需要建立与OPC服务器的连接,获取服务器的相关信息,例如服务器地址、端口号等。然后,根据需要,可以进行数据的读取或写入操作。读取操作可以获取OPC服务器上的数据值或者状态信息,写入操作可以向OPC服务器发送指令或者修改数据。最后,需要关闭与OPC服务器的连接,释放资源。 需要注意的是,在Java对接OPC传输协议之前,需要先了解OPC的相关知识和基本原理,熟悉OPC数据模型和OPC服务器的功能。另外,还需要了解所使用的OPC传输协议的规范和要求,以便正确配置和设置与OPC服务器的通信参数。 总之,Java对接OPC传输协议需要借助相关的开源库或者Native接口,并且需要根据OPC服务器的要求和规范进行配置和设置,以实现与OPC服务器的数据交互。 ### 回答2: Java对接OPC传输协议可以通过使用相关的第三方库或框架来实现。常用的是使用Apache NiFi、OPC Ua Java Stack或jopc等库。 首先,需要导入相应的第三方库或框架。例如,使用Apache NiFi时,需要下载并导入NiFi的jar包。然后可以在Java代码中引入相关的类和接口。 其次,需要建立与OPC服务器的连接。可以通过配置OPC服务器的IP地址和端口号来建立连接。使用相应的类和方法可以创建OPC存储库对象,并调用连接方法来建立连接。 连接建立后,可以对OPC服务器进行读写操作。例如,读取OPC服务器中的变量值,可以使用相应的方法来获取变量的值。而写操作可以使用相应的方法来设置变量的值。 在进行读写操作时,可以根据需要设置相应的参数。例如,可以设置读取或写入的变量的数据类型,或者设置操作的超时时间等。 在操作完成后,需要关闭与OPC服务器的连接。可以通过调用相应的方法来关闭连接,并释放相关的资源。 此外,还可以根据需要进行其他操作,例如订阅OPC服务器的数据变化或事件,以及处理相关的通知或异常等。 总之,Java对接OPC传输协议可以通过使用第三方库或框架来实现。通过建立连接、读写操作、参数设置、连接关闭等步骤,可以实现与OPC服务器的数据交互。 ### 回答3: Java对接OPC传输协议时,主要通过使用OPC规范和Java OPC库来实现。 首先,OPC(OLE for Process Control)是一种通信协议,它允许软件应用程序与过程控制领域的设备和系统进行通信。OPC分为两个部分:OPC数据访问(OPC DA)和OPC统一架构(OPC UA)。其中,OPC DA是早期的版本,主要用于实时数据传输,而OPC UA是基于Web服务的新一代协议,具备更强大的功能和更高的安全性。 在Java对接OPC传输协议时,我们可以使用一些第三方的Java OPC库来简化开发流程。这些库提供了与OPC服务器建立连接、读取和写入OPC服务器中的数据的功能。 具体步骤如下: 1. 导入Java OPC库:使用Maven或其他构建工具,将所需的Java OPC库添加到项目依赖中。 2. 建立连接:使用Java OPC库提供的API,通过指定OPC服务器的URL或IP地址、用户名和密码等信息,与OPC服务器建立连接。 3. 浏览OPC服务器:使用Java OPC库提供的方法,可以浏览OPC服务器上的节点,获取节点的详细信息,以便后续读取或写入数据。 4. 读取数据:使用Java OPC库的读取方法,可以读取OPC服务器上的数据,可以根据节点的路径或标签等信息进行读取操作。 5. 写入数据:使用Java OPC库的写入方法,可以将数据写入到OPC服务器中指定的节点上。 6. 断开连接:在使用完毕后,使用Java OPC库提供的方法,显式地关闭与OPC服务器的连接。 总结来说,在Java对接OPC传输协议,需要使用相应的Java OPC库来提供与OPC服务器的交互功能。通过建立连接、浏览节点、读取和写入数据等操作,可以实现与OPC服务器的通信,并实现数据的传输。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十五001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值