SpringBoot集成OPC协议,批量读取数据

SpringBoot集成OPC协议

1. 使用的OPC server软件

  1. KEPServer V6,官网下载
  2. windows10专业版虚拟机,1903版本以前,下载地址https://msdn.itellyou.cn/

2. 使用OPC server软件

安装和使用:https://www.cnblogs.com/ioufev/p/9366877.html

3. DCOM配置

DCOM配置:https://www.cnblogs.com/ioufev/p/9365919.html

4. 代码编写

4.1 jar包

		<parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.5.7</version>
            <relativePath/> <!-- lookup parent from repository -->
    	</parent>
		
		<!-- OPC服务 -->
        <dependency>
            <groupId>org.kohsuke.jinterop</groupId>
            <artifactId>j-interop</artifactId>
            <version>2.0.5</version>
        </dependency>
        <dependency>
            <groupId>org.openscada.external</groupId>
            <artifactId>org.openscada.external.jcifs</artifactId>
            <version>1.2.25</version>
        </dependency>
        <dependency>
            <groupId>org.openscada.jinterop</groupId>
            <artifactId>org.openscada.jinterop.core</artifactId>
            <version>2.1.8</version>
        </dependency>
        <dependency>
            <groupId>org.openscada.jinterop</groupId>
            <artifactId>org.openscada.jinterop.deps</artifactId>
            <version>1.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.openscada.utgard</groupId>
            <artifactId>org.openscada.opc.dcom</artifactId>
            <version>1.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.openscada.utgard</groupId>
            <artifactId>org.openscada.opc.lib</artifactId>
            <version>1.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.59</version>
        </dependency>

4.2 代码

opc:
  host: 192.168.51.17   # opcServer ip
  domain:   #
  user: OPCServer  # opcServer主机有DCOM权限的用户名
  password: 123456  # opcServer主机有DCOM权限的密码
  clsId: 7BC0CC8E-482C-47CA-ABDC-0FE7F9C6E729
package com.liming.app.opc;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * @Author:liming.she
 * @Date:2023/11/21 17:07
 * @Description:
 */
@Configuration
@ConfigurationProperties(prefix = "opc")
@Data
public class OPCConfig {
    private String host;
    private String domain;
    private String user;
    private String password;
    private String clsId;
}
package com.liming.app.opc.v2;

import com.liming.app.common.cache.CacheSingleton;
import com.liming.app.common.config.ApplicationContextGetBeanHelper;
import com.liming.app.common.config.DeviceNameConfig;
import com.liming.app.common.config.RegisterConfig;
import com.liming.app.common.config.RegisterInfo;
import com.liming.app.modbusTcp.HexUtil;
import com.liming.app.opc.OPCConfig;
import lombok.extern.slf4j.Slf4j;
import org.openscada.opc.lib.common.ConnectionInformation;
import org.openscada.opc.lib.da.Group;
import org.openscada.opc.lib.da.Item;
import org.openscada.opc.lib.da.ItemState;
import org.openscada.opc.lib.da.Server;
import org.openscada.opc.lib.da.browser.FlatBrowser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

/**
 * @Author:liming.she
 * @Date:2023/11/22 10:47
 * @Description:  批量读取items值
 */
@Slf4j
@Component
public class OPCClientV2 implements CommandLineRunner {

    @Autowired
    private RegisterConfig registerConfig;

    @Autowired
    private DeviceNameConfig deviceNameConfig;

    @Override
    public void run(String... args) throws Exception {
        OPCConfig opcConfig = ApplicationContextGetBeanHelper.getBean(OPCConfig.class);
        while (true){
            try {
                // 连接server
                final ConnectionInformation connectionInfo = new ConnectionInformation();
                connectionInfo.setHost(opcConfig.getHost());
                connectionInfo.setClsid(opcConfig.getClsId());
                connectionInfo.setUser(opcConfig.getUser());
                connectionInfo.setPassword(opcConfig.getPassword());

                ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
                Server mServer = new Server(connectionInfo, executor);
                mServer.connect();

                //读取items
                FlatBrowser browser = mServer.getFlatBrowser();
                List<String> itemList = new ArrayList<>();
                Collection<String> browse = browser.browse();
                for (String name : browse) {
                    //匹配字符串获取想要的itemID
                    if (startWith(name,deviceNameConfig.getDeviceName()) && startWithout(name,deviceNameConfig.getSystemName())) {
                        itemList.add(name);
                    }
                }

                //读取values
                Group group = mServer.addGroup();
                String[] items = itemList.toArray(new String[]{});
                Map<String, Item> itemResult = group.addItems(items);
                Item[] itemArr = new Item[itemList.size()];
                for (int i = itemList.size() - 1; i >= 0; i--) {
                    itemArr[itemList.size()-1-i] = itemResult.get(itemList.get(i));
                }
                Map<Item, ItemState> resultMap = group.read(true, itemArr);

                //业务逻辑 解析并存放在寄存器中(内存)
                List<Integer> list = new ArrayList<>();
                for (Item item : itemArr) {
                    ItemState itemState = resultMap.get(item);
                    int type = itemState.getValue().getType();
                    Object val = getVal(itemState.getValue());
                    HexUtil.objectToInt2Arr(type, val, list);
                }
                List<RegisterInfo> registerInfos = registerConfig.getRegisterInfos();
                CacheSingleton cacheSingleton = CacheSingleton.getInstance();
                cacheSingleton.addCacheData(registerInfos.get(registerInfos.size()-1).getIdentity(),list);

                //todo 存库

                mServer.disconnect();
                Thread.sleep(1000);
            } catch (Exception e) {
                log.error("connectServer ERROR:",e);
                Thread.sleep(1000);
            }
        }
    }

    public boolean startWith(String name,String[] names){
        for (String s : names) {
            if (name.contains(s)){
                return true;
            }
        }
        return false;
    }

    public boolean startWithout(String name,String[] names){
        for (String s : names) {
            if (name.contains(s)){
                return false;
            }
        }
        return true;
    }

	public Object getVal(JIVariant var) throws JIException {
        Object value;
        int type = var.getType();
        switch (type) {
            case JIVariant.VT_I2:
                value = var.getObjectAsShort();
                break;
            case JIVariant.VT_I4:
                value = var.getObjectAsInt();
                break;
            case JIVariant.VT_I8:
                value = var.getObjectAsLong();
                break;
            case JIVariant.VT_R4:
                value = var.getObjectAsFloat();
                break;
            case JIVariant.VT_R8:
                value = var.getObjectAsDouble();
                break;
            case JIVariant.VT_BSTR:
                value = var.getObjectAsString2();
                break;
            case JIVariant.VT_BOOL:
                value = var.getObjectAsBoolean();
                break;
            case JIVariant.VT_UI2:
            case JIVariant.VT_UI4:
                value = var.getObjectAsUnsigned().getValue();
                break;
            case JIVariant.VT_EMPTY:
                throw new JIException(JIErrorCodes.JI_VARIANT_IS_NULL, "Variant is Empty.");
            case JIVariant.VT_NULL:
                throw new JIException(JIErrorCodes.JI_VARIANT_IS_NULL, "Variant is null.");
            default:
                throw new JIException(JIErrorCodes.JI_VARIANT_IS_NULL, "Unknown Type.");
        }

        return value;
    }
}
Java中,可以使用OPC (OLE for Process Control)协议根据地址读取数据OPC协议是一种用于实时控制和监视过程的通信协议,它允许不同的系统和设备之间进行连接和通信。 要根据地址读取数据,首先需要建立一个与OPC服务器的连接。可以使用Java OPC客户端库(如OPC Foundation提供的Java SDK)来实现与OPC服务器之间的通信。 在建立连接后,可以使用OPC服务器的API方法来读取数据。要根据地址读取数据,需要知道所需数据的地址。根据OPC的标准规范,地址通常由三个部分组成:组(Group)、项(Item)和属性(Property)。 首先,需要创建一个OPC组。组是一组相关的OPC项,可以使用组来执行类似的操作。然后,可以向组中添加OPC项,这些项代表服务器上的数据点或变量。每个OPC项有一个唯一的地址,可以使用这个地址来读取数据。 一旦建立了OPC组和添加了OPC项,就可以使用组的API方法来读取数据。通过指定OPC项的地址,可以调用合适的方法从服务器读取数据读取数据可以是数值、字符串或其他类型,具体取决于OPC项的属性和服务器的配置。 需要注意的是,OPC服务器的配置可能因厂商而异,因此根据具体的OPC服务器和数据源提供者的文档来了解使用地址读取数据的准确方法和API调用。 总的来说,使用JavaOPC客户端库,我们可以根据地址读取数据。这涉及到建立连接、创建OPC组、添加OPC项和调用适当的方法来读取数据。根据具体的OPC服务器和数据源提供者的文档,可以了解更多关于使用地址读取数据的详细信息。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值