java对接西门子PLC(OPC UA方式) 模拟器调试

前情提要

网上搜了很多发现都是把软件介绍从官网贴过来了,于是自己摸索了下写了JAVA如何在没有PLC的情况下通过模拟器来进行OPC UA调试。

背景:PLC对接久了之前一直用寄存器的方式,通过电器工程师给的偏移量直接访问对应的寄存器地址来进行对接,突然有一天要对接西门子PLC,我拿到接口文档一看,懵逼了。

字段都是中文,问了下对方,人家说用字符的方式好,这样以后再加字段就不会没有偏移地址干扰了,我想了想,人家说的很有道理。需求变更很正常,加减字段也很正常。可是我没对接过呀。

于是去网上搜了搜“PLC字符对接”,网上要么是PLC对接也没讲什么字符的方式啊,感情是对方瞎编的方式。我把之前对接过的所有电器工程师都问了一遍,全都说没见过没用过,这种方式在圈内都这么罕见的么,感情科班不教这个啊。

然后我对甲方说:你这接口得改,java没有字符对接的。他说他们之前都是字符对接的啊,怎么到我这就不行了?于是我在VX群内里也告诉他们领导,这种方式不行,他们领导也是技术出身,表示之前都是字符方式对接的啊,后来一看代码全是C#的开发对接。

过了一会群里告诉我好像java确实不行,那他们换偏移量的方式。

这事我以为就这么翻篇了,后来又一个项目也是对接PLC的,又给了一份全是字段的对接文档,在项目会议上甲方工程师说PLC跟上位通过OPC UA的方式,后来一查还真有。感情之前一溜的技术都被我的无知给忽悠住了呀。

有了关键词那网上资料多了,于是确定了JAVA技术栈就使用milo,这时候问题来了,代码根据接口文档写好了,想网上搜个模拟器来试试的。

发现全网这方面的不可谓说是一篇都没,简直就是一篇都没。那就根据我的经验来写下了。

软件

模拟器我用的是 Prosys OPC UA Simulation Server

软件官方下载地址:https://downloads.prosysopc.com/opc-ua-simulation-server-downloads.php

如果你的电脑是Windows就把我圈出来的下载下来好了.

在这里插入图片描述

直接上手版本

JAVA代码部分:

  1. 引jar包,注意版本要跟我一样,版本高的方法不一样。
<dependency>
	<groupId>org.eclipse.milo</groupId>
	<artifactId>sdk-client</artifactId>
	<version>0.6.8</version>
</dependency>
  1. 项目启动时候进行连接,类似websocket,需要把连接信息记录下来,后续如果要读取和写拿到对应的连接进行操作就行了,我这里就不需要验证那些了,我也是贴网上的。
public static Map<String, OpcUaClient> opcUaClientMap = new ConcurrentHashMap<>();
public static void geOpcUaClient(String deviceName, String url) {
        try {
            SecurityPolicy securityPolicy = SecurityPolicy.None;
            List<EndpointDescription> endpoints;
            try {
                endpoints = DiscoveryClient.getEndpoints(url).get();
            } catch (Throwable ex) {
                // 发现服务
                String discoveryUrl = url;
                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();
            opcUaClientMap.put(deviceName, OpcUaClient.create(config));
        } catch (Exception e) {
            System.out.println("创建客户端失败");
        }
    }
  1. 读取不同PLC设备的不同字段名称(identifier),我这里是读string,你可以根据你的定义改为其他值,NodeId默认都是3,如果人家有变更你可以问人家。
    public static String readStrValue(String deviceName, String identifier) throws Exception {
        //创建连接
        opcUaClientMap.get(deviceName).connect().get();
        NodeId nodeId = new NodeId(3, identifier);
        DataValue value = opcUaClientMap.get(deviceName).readValue(0.0, TimestampsToReturn.Both, nodeId).get();
        String result = String.valueOf(value.getValue().getValue());
        log.info("opc_ua 值为 {} 读取字符: {} ", result, identifier);
        return result;
    }
  1. 根据identifier写入值。
    public static void writeValue(String deviceName, boolean value, String identifier) throws Exception {
        // 获取全局opcUaClient创建连接
        opcUaClientMap.get(deviceName).connect().get();
        StatusCode statusCode = opcUaClientMap.get(deviceName).writeValue(new NodeId(3, identifier), new DataValue(new Variant(value), null, null)).get();
        log.info("opc_ua: 写入值为 {} 写入字符: {} ", value, identifier);
        if (statusCode.isGood()) {
            log.info("opc_ua 写入回复成功!");
        }
    }
  1. 写个main测试下是否能读到值。opc.tcp://Kino:53530/OPCUA/SimulationServer这是要根据你模拟器的url贴过来,add也是模拟器创建的字段名称。
    public static void main(String[] args) throws Exception {
        geOpcUaClient("PLC1", "opc.tcp://Kino:53530/OPCUA/SimulationServer");
        String result = readStrValue("PLC1", "add");
        System.out.println("读取内容:" + result);
    }

模拟器Prosys OPC UA Simulation 准备

  1. 下载完后打开软,直接复制 链接地址,贴到上面Main函数中
    在这里插入图片描述

  2. 创建自己的对象,右击新增对象。
    在这里插入图片描述

  3. 新建对象时候这个NodeId Type可以根据你接口情况选择string或者数字啥的,这里的NodeId Value命名是全局唯一的。
    在这里插入图片描述

  4. 确定后再新建字段。
    在这里插入图片描述

  5. 字段NodeId Value命名为add,dataType为DataValue。
    在这里插入图片描述

  6. 最终字段的信息如图。
    在这里插入图片描述

  7. 设置值为十五001的家。

  8. 最终执行读取设置的内容。
    在这里插入图片描述

其他

这软件可能是我搜到的唯一有免费版本的模拟器了,值得吐槽的是他用一段时间会自动死掉,需要重启,其他都还可以。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

十五001

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

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

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

打赏作者

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

抵扣说明:

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

余额充值