当前位置:   article > 正文

Java连接KepserverEX6,DA方式读写_java从kepserver中读取数据

java从kepserver中读取数据

操作系统:windows10  版本1909
注意:与kepserver的通讯对windows版本的要求很高,目前所了解到的必须是1909版本以前,或者1903版本,windows11 使用21H2的版本。

原因是:微软给修复了docm的安全漏洞,发了补丁的原因,导致了一些新版本的windows不支持opcda的写法。

开始
1、第一步:创建一个新的windows用户,用于给访问kepserver使用。

用户名:OPCServer  【自定义即可】

密码:123456  【自定义即可】

将新增的用户添加到DOCM组

然后把新增用户移出普通用户组【Users就是刚刚新增的用户】

添加用户步骤完成

2、配置防火墙

找到DCOM-IN

上面两个DOCM-IN都是一样的操作。

3、创建OPC程序规则:允许程序OPCEnum

新建入站规则

然后一直下一步,直到【名称】,然后点击完成

 4、添加 OPC 服务器程序的规则:允许程序 KEPServer的server_runtime

新建入站规则--程序--找到server_runtime.exe

其他步骤同上一个规则一样即可。

5、组件服务

  

6、OpcEnum的安全选项

因为自定义的编辑都是一样的,所以我下面只演示一个。

   

     

7、组件服务:KEPServer的安全选项

和上面一样,这三个都点自定义,编辑中把新增的用户添加进去,把允许的权限全部打开

8、本地安全策略

配置工作全部完成

下面是JAVA代码

所需依赖

  1. <dependency>
  2. <groupId>org.openscada.utgard</groupId>
  3. <artifactId>org.openscada.opc.lib</artifactId>
  4. <version>1.5.0</version>
  5. <exclusions>
  6. <exclusion>
  7. <groupId>org.bouncycastle</groupId>
  8. <artifactId>bcprov-jdk15on</artifactId>
  9. </exclusion>
  10. </exclusions>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.bouncycastle</groupId>
  14. <artifactId>bcprov-jdk15on</artifactId>
  15. <version>1.65</version>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.openscada.utgard</groupId>
  19. <artifactId>org.openscada.opc.dcom</artifactId>
  20. <version>1.5.0</version>
  21. </dependency>

连接配置

  1. @Configuration
  2. @ConfigurationProperties(prefix = "kep-server")
  3. @Slf4j
  4. @Data
  5. public class KepServerConfig implements Serializable {
  6. private String host;
  7. private String domain;
  8. private String user;
  9. private String password;
  10. private String clsid;
  11. @Bean(name = "opcServer")
  12. public Server server() {
  13. ConnectionInformation connectionInformation = new ConnectionInformation();
  14. connectionInformation.setHost(host);
  15. connectionInformation.setDomain(domain);
  16. connectionInformation.setUser(user);
  17. connectionInformation.setPassword(password);
  18. connectionInformation.setClsid(clsid);
  19. // 连接到服务
  20. Server server = new Server(connectionInformation, null);
  21. try {
  22. server.connect();
  23. log.info("opc 服务端连接成功........");
  24. } catch (UnknownHostException e) {
  25. log.error("opc 地址错误:", e);
  26. } catch (JIException e) {
  27. log.error("opc 连接失败:", e);
  28. }catch (AlreadyConnectedException e) {
  29. log.error("opc 已连接:", e);
  30. }
  31. return server;
  32. }
  33. }

【注意:为了不误人子弟,下面的读取方法是有BUG的,正确代码有空修改,当你看见这句话时,还没有修改】

批量读取kepserver中的数据

  1. package com.hangcheng.opc.common.scheduledTasks;
  2. import com.hangcheng.opc.common.constant.CommonConstant;
  3. import com.hangcheng.opc.common.constant.DictTagsConstant;
  4. import com.hangcheng.opc.common.constant.KepServerConstant;
  5. import com.hangcheng.opc.common.constant.RedisKeyConstant;
  6. import com.hangcheng.opc.common.pojo.DataTags;
  7. import com.hangcheng.opc.common.pojo.EarlyWarning;
  8. import com.hangcheng.opc.common.utils.opc.OpcTypeConversionUtils;
  9. import com.hangcheng.opc.common.utils.redis.RedisCacheUtils;
  10. import com.hangcheng.opc.service.EarlyWarningService;
  11. import com.hangcheng.opc.service.TagsDataService;
  12. import lombok.extern.slf4j.Slf4j;
  13. import org.jinterop.dcom.core.JIVariant;
  14. import org.openscada.opc.dcom.da.OPCSERVERSTATE;
  15. import org.openscada.opc.lib.da.*;
  16. import org.springframework.beans.factory.annotation.Qualifier;
  17. import org.springframework.stereotype.Service;
  18. import javax.annotation.Resource;
  19. import java.util.*;
  20. import java.util.stream.Collectors;
  21. @Service
  22. @Slf4j
  23. public class OpcDaClient {
  24. @Resource
  25. private TagsDataService tagsDataService;
  26. @Resource
  27. @Qualifier("opcServer")
  28. private Server server;
  29. @Resource
  30. private RedisCacheUtils redisCacheUtils;
  31. @Resource
  32. private EarlyWarningService earlyWarningService;
  33. /**
  34. * PLC批量读操作
  35. */
  36. public void configureTasks() {
  37. //下面这段是为了解决断线重连的问题
  38. try {
  39. // 这里会出现空是应为 OPCServer 为 null,但是单独拿OPCServer来判断null并不严谨,因为还有一些其他报错会导致OPCServer为空,
  40. // 并不是只有连接失败导致,所以这里进行多次判断
  41. if (server.getServerState() == null) {
  42. log.info("OPCServer为空,尝试一次连接");
  43. // 尝试一次连接,一般情况连接失败就直接被下面的catch捕获了
  44. server.connect();
  45. } else if (server.getServerState() != null && server.getServerState().getServerState().equals(OPCSERVERSTATE.OPC_STATUS_RUNNING)) {
  46. log.info("与服务端的连接是正常的,继续执行业务代码");
  47. } else {
  48. return;
  49. }
  50. // 创建组
  51. Group group = server.addGroup();
  52. // 转数组
  53. String[] items = keyList.toArray(new String[]{});
  54. // 把所有的标记添加到组里
  55. Map<String, Item> itemResult = group.addItems(items);
  56. // map转set,避免重复
  57. Set<Item> itemSet = new HashSet<>(itemResult.values());
  58. // 创建一个 itemSet 大小的数组
  59. Item[] itemArr = new Item[itemSet.size()];
  60. // 将 itemSet集合 复制到 itemArr数组
  61. itemSet.toArray(itemArr);
  62. // 一次性读取全部标记的值,非常滴爽
  63. Map<Item, ItemState> resultMap = group.read(true, itemArr);
  64. // resultMap 就是读出来的所有数据
  65. } catch (Exception e) {
  66. e.printStackTrace();
  67. }
  68. }
  69. }

写操作

  1. /**
  2. * PLC批量写操作
  3. *
  4. * @param tagValueMap 指定标识与指定值集合
  5. */
  6. public void writePlcValues(Map<String, String> tagValueMap) {
  7. try {
  8. // 添加一个Group
  9. Group group = server.addGroup();
  10. Map<String, String> itemIdAndRWMap = redisCacheUtils.hmEntries(RedisKeyConstant.ITEM_ID_AND_R_W_MAP);
  11. Iterator<String> iterator = tagValueMap.keySet().iterator();
  12. while (iterator.hasNext()) {
  13. String tag = iterator.next();
  14. String key = itemIdAndRWMap.get(tag);
  15. // 如果标识不存在那么代表传参有误,直接去除即可
  16. if (key == null || !key.equals(RedisKeyConstant.R_W)) {
  17. iterator.remove();
  18. }
  19. }
  20. int i = 0;
  21. WriteRequest[] writeRequests = new WriteRequest[tagValueMap.size()];
  22. for (Map.Entry<String, String> entry : tagValueMap.entrySet()) {
  23. String key = entry.getKey();
  24. String value = entry.getValue();
  25. WriteRequest writeRequest = new WriteRequest(group.addItem(key), new JIVariant(value));
  26. writeRequests[i++] = writeRequest;
  27. }
  28. group.write(writeRequests);
  29. } catch (Exception e) {
  30. throw new RuntimeException(e);
  31. }
  32. }

完毕,剩下的再补,没时间写了

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/948256
推荐阅读
相关标签
  

闽ICP备14008679号