From e4c3b0f2afc59f7d7037b196d9f90266e2255608 Mon Sep 17 00:00:00 2001
From: yyt <306727702@qq.com>
Date: 星期六, 13 一月 2024 09:45:45 +0800
Subject: [PATCH] 新增OPC

---
 jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/cert/MethodName.java                       |   69 ++
 jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/init/OpcusConfigInit.java                  |   51 +
 jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/client/ClientHandler.java                  |  301 +++++++++++
 jcdm-main/pom.xml                                                                               |   32 +
 jcdm-main/src/main/resources/opcua.properties                                                   |   20 
 jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/service/impl/DaOpcuaConfigServiceImpl.java |   94 +++
 jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/mapper/DaOpcuaConfigMapper.java            |   62 ++
 jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/domain/DaOpcuaConfig.java                  |  163 ++++++
 jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/init/BeanUtils.java                        |   30 +
 jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/cert/KeyStoreLoader.java                   |  127 ++++
 jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/service/IDaOpcuaConfigService.java         |   62 ++
 jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/init/Properties.java                       |   57 ++
 jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/controller/DaOpcuaConfigController.java    |  109 ++++
 jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/client/ClientRunner.java                   |  146 +++++
 jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/domain/OpcuaConf.java                      |  177 ++++++
 jcdm-main/src/main/resources/mapper/da/opcuaconfig/DaOpcuaConfigMapper.xml                      |   97 +++
 jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/domain/NodeEntity.java                     |   19 
 17 files changed, 1,616 insertions(+), 0 deletions(-)

diff --git a/jcdm-main/pom.xml b/jcdm-main/pom.xml
index f609140..29139b2 100644
--- a/jcdm-main/pom.xml
+++ b/jcdm-main/pom.xml
@@ -37,6 +37,38 @@
             </exclusions>
         </dependency>
 
+        <!--Server SDK渚濊禆-->
+        <dependency>
+            <groupId>org.eclipse.milo</groupId>
+            <artifactId>sdk-server</artifactId>
+            <version>0.3.6</version>
+        </dependency>
+
+        <!--Client SDK渚濊禆-->
+        <dependency>
+            <groupId>org.eclipse.milo</groupId>
+            <artifactId>sdk-client</artifactId>
+            <version>0.3.6</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.eclipse.milo</groupId>
+            <artifactId>stack-client</artifactId>
+            <version>0.3.6</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.eclipse.milo</groupId>
+            <artifactId>stack-client</artifactId>
+            <version>0.3.6</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.eclipse.milo</groupId>
+            <artifactId>stack-server</artifactId>
+            <version>0.3.6</version>
+        </dependency>
+
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
diff --git a/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/cert/KeyStoreLoader.java b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/cert/KeyStoreLoader.java
new file mode 100644
index 0000000..9b6a4e0
--- /dev/null
+++ b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/cert/KeyStoreLoader.java
@@ -0,0 +1,127 @@
+package com.jcdm.main.da.opcuaconfig.cert;
+
+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 org.springframework.stereotype.Component;
+
+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;
+
+/**
+ * @ClassName: KeyStoreLoader
+ * @Description: KeyStoreLoader
+ * @author yyt
+ * @date 2023骞�10鏈�13鏃�
+ */
+@Component
+public class KeyStoreLoader {
+
+	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])$");
+
+	// 璇佷功鍒悕
+	private static final String CLIENT_ALIAS = "jlclient-ai";
+	// 鑾峰彇绉侀挜鐨勫瘑鐮�
+	private static final char[] PASSWORD = "yyt@8888888888".toCharArray();
+
+	private final Logger logger = LoggerFactory.getLogger(getClass());
+
+	// 璇佷功瀵硅薄
+	private X509Certificate clientCertificate;
+	// 瀵嗛挜瀵瑰璞�
+	private KeyPair clientKeyPair;
+
+	/**
+	 * @MethodName: load
+	 * @Description: load
+	 * @param baseDir
+	 * @return
+	 * @throws Exception
+	 * @CreateTime 2023骞�10鏈�13鏃�
+	 */
+	public KeyStoreLoader load(Path baseDir) throws Exception {
+		// 鍒涘缓涓�涓娇鐢╜PKCS12`鍔犲瘑鏍囧噯鐨凨eyStore銆侹eyStore鍦ㄥ悗闈㈠皢浣滀负璇诲彇鍜岀敓鎴愯瘉涔︾殑瀵硅薄銆�
+		KeyStore keyStore = KeyStore.getInstance("PKCS12");
+
+		// PKCS12鐨勫姞瀵嗘爣鍑嗙殑鏂囦欢鍚庣紑鏄�.pfx锛屽叾涓寘鍚簡鍏挜鍜岀閽ャ��
+		// 鑰屽叾浠栧.der绛夌殑鏍煎紡鍙寘鍚叕閽ワ紝绉侀挜鍦ㄥ彟澶栫殑鏂囦欢涓��
+		Path serverKeyStore = baseDir.resolve("OPCUA-client.pfx");
+
+		logger.info("Loading KeyStore at {}", serverKeyStore);
+
+		// 濡傛灉鏂囦欢涓嶅瓨鍦ㄥ垯鍒涘缓.pfx璇佷功鏂囦欢銆�
+		if (!Files.exists(serverKeyStore)) {
+			keyStore.load(null, PASSWORD);
+
+			// 鐢�2048浣嶇殑RAS绠楁硶銆俙SelfSignedCertificateGenerator`涓篗ilo搴撶殑瀵硅薄銆�
+			KeyPair keyPair = SelfSignedCertificateGenerator.generateRsaKeyPair(2048);
+
+			// `SelfSignedCertificateBuilder`涔熸槸Milo搴撶殑瀵硅薄锛岀敤鏉ョ敓鎴愯瘉涔︺��
+			// 涓棿鎵�璁剧疆鐨勮瘉涔﹀睘鎬у彲浠ヨ嚜琛屼慨鏀广��
+			SelfSignedCertificateBuilder builder = new SelfSignedCertificateBuilder(keyPair)
+					.setCommonName("UaClient@Jellyleo")
+					.setOrganization("JL")
+					.setOrganizationalUnit("per")
+					.setLocalityName("jl")
+					.setStateName("JiangSu")
+					.setCountryCode("CN")
+					.setApplicationUri("urn:Yyt_PC:UnifiedAutomation:UaExpert")
+					.addDnsName("Yyt_PC")
+					.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);
+				}
+			}
+			// 鍒涘缓璇佷功
+			X509Certificate certificate = builder.build();
+
+			// 璁剧疆瀵瑰簲绉侀挜鐨勫埆鍚嶏紝瀵嗙爜锛岃瘉涔﹂摼
+			keyStore.setKeyEntry(CLIENT_ALIAS, keyPair.getPrivate(), PASSWORD, new X509Certificate[] { certificate });
+			try (OutputStream out = Files.newOutputStream(serverKeyStore)) {
+				// 淇濆瓨璇佷功鍒拌緭鍑烘祦
+				keyStore.store(out, PASSWORD);
+			}
+		} else {
+			try (InputStream in = Files.newInputStream(serverKeyStore)) {
+				// 濡傛灉鏂囦欢瀛樺湪鍒欒鍙�
+				keyStore.load(in, PASSWORD);
+			}
+		}
+
+		// 鐢ㄥ瘑鐮佽幏鍙栧搴斿埆鍚嶇殑绉侀挜銆�
+		Key serverPrivateKey = keyStore.getKey(CLIENT_ALIAS, PASSWORD);
+		if (serverPrivateKey instanceof PrivateKey) {
+			// 鑾峰彇瀵瑰簲鍒悕鐨勮瘉涔﹀璞°��
+			clientCertificate = (X509Certificate) keyStore.getCertificate(CLIENT_ALIAS);
+			// 鑾峰彇鍏挜
+			PublicKey serverPublicKey = clientCertificate.getPublicKey();
+			// 鍒涘缓Keypair瀵硅薄銆�
+			clientKeyPair = new KeyPair(serverPublicKey, (PrivateKey) serverPrivateKey);
+		}
+
+		return this;
+	}
+
+	// 杩斿洖璇佷功
+	public X509Certificate getClientCertificate() {
+		return clientCertificate;
+	}
+
+	// 杩斿洖瀵嗛挜瀵�
+	public KeyPair getClientKeyPair() {
+		return clientKeyPair;
+	}
+}
diff --git a/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/cert/MethodName.java b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/cert/MethodName.java
new file mode 100644
index 0000000..ec82a91
--- /dev/null
+++ b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/cert/MethodName.java
@@ -0,0 +1,69 @@
+package com.jcdm.main.da.opcuaconfig.cert;
+
+import com.jcdm.main.da.collectionParamConf.domain.DaCollectionParamConf;
+import com.jcdm.main.da.collectionParamConf.service.IDaCollectionParamConfService;
+import com.jcdm.main.da.opcuaconfig.client.ClientHandler;
+import com.jcdm.main.da.opcuaconfig.domain.NodeEntity;
+import com.jcdm.main.da.opcuaconfig.init.BeanUtils;
+import com.jcdm.main.da.paramCollection.domain.DaParamCollection;
+import lombok.extern.slf4j.Slf4j;
+import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
+import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.jcdm.main.da.opcuaconfig.client.ClientHandler.readValues;
+
+@Slf4j
+public class MethodName {
+    private IDaCollectionParamConfService collectionParamConfService = BeanUtils.getBean(IDaCollectionParamConfService.class);
+    public void getSn(String Node, String value) throws Exception {
+        log.info(Node+":"+value);
+        String[] parts = Node.split("[.]");
+        ClientHandler clientHandler=new ClientHandler();
+        switch (value) {
+            case "0":   //鍒濆
+                NodeEntity node= NodeEntity.builder().index(2).identifier(parts[0]+"."+parts[1]+".RecordDataDone").value("0").type("short").build();
+                Boolean out=clientHandler.write(node);
+                log.info("鑺傜偣:{},鍝嶅簲缁撴灉:{}", node.getIdentifier(),out);
+                break;
+            case "1":   //璇锋眰涓嬪彂杩涚珯鐘舵��
+                NodeEntity node1= NodeEntity.builder().index(2).identifier(parts[0]+"."+parts[1]+".RecordDataDone").value("11").type("short").build();
+                Boolean out1=clientHandler.write(node1);
+                log.info("鑺傜偣:{},鍝嶅簲缁撴灉:{}", node1.getIdentifier(),out1);
+                break;
+            case "2":   //璇锋眰璁板綍宸ヤ綅鏁版嵁
+                List<DaCollectionParamConf> b;
+                DaCollectionParamConf daCollectionParamConf=new DaCollectionParamConf();
+                daCollectionParamConf.setCollectParameterId(parts[0]+"."+parts[1]);
+                b=collectionParamConfService.selectDaCollectionParamConfList(daCollectionParamConf);
+                List<String> ids = b.stream().map(e -> e.getCollectParameterId()).collect(Collectors.toList());
+                Set<String> de=ListToSet(ids);
+                List<DataValue> s=readValues(de);
+//                s.forEach(element->{
+//                    DaParamCollection Config=new DaParamCollection();
+//                    String[] q = element.getIdentifier().split("[.]");
+//                    Config.setParamCode(q[2]);
+//                    Config.setLocationCode(q[1]);
+//                    Config.setParamValue(element.getValue().toString());
+//                    daParamCollectionService.insertDaParamCollection(Config);
+//                });
+                NodeEntity node2= NodeEntity.builder().index(2).identifier(parts[0]+"."+parts[1]+".RecordDataDone").value("21").type("short").build();
+                Boolean out2=clientHandler.write(node2);
+                log.info("鑺傜偣:{},鍝嶅簲缁撴灉:{}", node2.getIdentifier(),out2);
+                break;
+            default:
+                break;
+        }
+    }
+
+    public Set<String> ListToSet(List<String> list) {
+        Object[] objects = list.toArray();// 杩斿洖Object鏁扮粍
+        String[] strings1 = new String[list.size()];
+        list.toArray(strings1);// 灏嗚浆鍖栧悗鐨勬暟缁勬斁鍏ュ凡缁忓垱寤哄ソ鐨勫璞′腑
+        String[] strings2 = list.toArray(new String[0]);// 灏嗚浆鍖栧悗鐨勬暟缁勮祴缁欐柊瀵硅薄
+        Set<String> set = new HashSet<String>(Arrays.asList(strings2));
+        return set;
+    }
+}
diff --git a/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/client/ClientHandler.java b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/client/ClientHandler.java
new file mode 100644
index 0000000..7ccd646
--- /dev/null
+++ b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/client/ClientHandler.java
@@ -0,0 +1,301 @@
+package com.jcdm.main.da.opcuaconfig.client;
+
+import com.google.common.collect.ImmutableList;
+import com.jcdm.main.da.opcuaconfig.controller.DaOpcuaConfigController;
+import com.jcdm.main.da.opcuaconfig.domain.DaOpcuaConfig;
+import com.jcdm.main.da.opcuaconfig.domain.NodeEntity;
+import com.jcdm.main.da.opcuaconfig.service.IDaOpcuaConfigService;
+import lombok.extern.slf4j.Slf4j;
+import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
+import org.eclipse.milo.opcua.sdk.client.api.nodes.VariableNode;
+import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscription;
+import org.eclipse.milo.opcua.stack.core.AttributeId;
+import org.eclipse.milo.opcua.stack.core.BuiltinDataType;
+import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
+import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
+import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
+import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
+import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned;
+import org.eclipse.milo.opcua.stack.core.types.enumerated.MonitoringMode;
+import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
+import org.eclipse.milo.opcua.stack.core.types.structured.MonitoredItemCreateRequest;
+import org.eclipse.milo.opcua.stack.core.types.structured.MonitoringParameters;
+import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * @ClassName: ClientHandler
+ * @Description: 瀹㈡埛绔鐞�
+ * @author Jellyleo
+ * @date 2019骞�12鏈�12鏃�
+ */
+@Slf4j
+@Service
+public class ClientHandler {
+
+	// 瀹㈡埛绔疄渚�
+	public static OpcUaClient client = null;
+
+	public List<DaOpcuaConfig> b = null;
+
+	@Autowired
+	private ClientRunner clientRunner;
+
+	@Autowired
+	private IDaOpcuaConfigService daOpcuaConfigService;
+
+
+	/**
+	 * 
+	 * @MethodName: connect
+	 * @Description: connect
+	 * @throws Exception
+	 * @CreateTime 2019骞�12鏈�18鏃� 涓婂崍10:41:09
+	 */
+	public String connect() throws Exception {
+
+		if (client != null) {
+			return "瀹㈡埛绔凡鍒涘缓";
+		}
+
+		client = clientRunner.run();
+
+		if (client == null) {
+			return "瀹㈡埛绔厤缃疄渚嬪寲澶辫触";
+		}
+
+		// 鍒涘缓杩炴帴
+		client.connect().get();
+		return "鍒涘缓杩炴帴鎴愬姛";
+	}
+
+	/**
+	 * @MethodName: disconnect
+	 * @Description: 鏂紑杩炴帴
+	 * @return
+	 * @throws Exception
+	 * @CreateTime 2019骞�12鏈�18鏃� 涓婂崍10:45:21
+	 */
+	public String disconnect() throws Exception {
+
+		if (client == null) {
+			return "杩炴帴宸叉柇寮�";
+		}
+
+		// 鏂紑杩炴帴
+		clientRunner.getFuture().complete(client);
+		client = null;
+		return "鏂紑杩炴帴鎴愬姛";
+	}
+
+	/**
+	 * @MethodName: subscribe
+	 * @Description: 璁㈤槄鑺傜偣鍙橀噺
+	 * @throws Exception
+	 * @CreateTime 2019骞�12鏈�18鏃� 涓婂崍10:38:11
+	 */
+	public String subscribe(List<NodeEntity> nodes) throws Exception {
+
+		if (client == null) {
+			return "鎵句笉鍒板鎴风锛屾搷浣滃け璐�";
+		}
+
+		// 鏌ヨ璁㈤槄瀵硅薄锛屾病鏈夊垯鍒涘缓
+		UaSubscription subscription = null;
+		ImmutableList<UaSubscription> subscriptionList = client.getSubscriptionManager().getSubscriptions();
+		if (CollectionUtils.isEmpty(subscriptionList)) {
+			subscription = client.getSubscriptionManager().createSubscription(1000.0).get();
+		} else {
+			subscription = subscriptionList.get(0);
+		}
+
+		// 鐩戞帶椤硅姹傚垪琛�
+		List<MonitoredItemCreateRequest> requests = new ArrayList<>();
+
+		if (!CollectionUtils.isEmpty(nodes)) {
+			for (NodeEntity node : nodes) {
+				// 鍒涘缓鐩戞帶鐨勫弬鏁�
+				MonitoringParameters parameters = new MonitoringParameters(subscription.nextClientHandle(), 1000.0, // sampling
+						// interval
+						null, // filter, null means use default
+						Unsigned.uint(10), // queue size
+						true // discard oldest
+				);
+				// 鍒涘缓璁㈤槄鐨勫彉閲忥紝 鍒涘缓鐩戞帶椤硅 姹�
+				MonitoredItemCreateRequest request = new MonitoredItemCreateRequest(
+						new ReadValueId(new NodeId(node.getIndex(), node.getIdentifier()), AttributeId.Value.uid(),
+								null, null),
+						MonitoringMode.Reporting, parameters);
+				requests.add(request);
+			}
+		}
+
+		// 鍒涘缓鐩戞帶椤癸紝骞朵笖娉ㄥ唽鍙橀噺鍊兼敼鍙樻椂鍊欑殑鍥炶皟鍑芥暟
+		subscription.createMonitoredItems(TimestampsToReturn.Both, requests, (item, id) -> {
+			item.setValueConsumer((i, v) -> {
+				handle(i.getReadValueId().getNodeId(), v.getValue());
+			});
+		}).get();
+
+		return "璁㈤槄鎴愬姛";
+	}
+
+	/**
+	 * * @MethodName: write
+	 * @Description: 鍥炶皟鍑芥暟
+	 * @CreateTime 2023骞�10鏈�13鏃�
+	 */
+	public void handle(NodeId id, Variant value){
+		if (b == null || 0 > b.size()) {
+			DaOpcuaConfig opcuaConfParam=new DaOpcuaConfig();
+		    opcuaConfParam.setSubscribe(1L);
+		    b=daOpcuaConfigService.selectDaOpcuaConfigList(opcuaConfParam);
+		}
+		//浣跨敤Stream API鍦↙ist<T>涓煡鎵惧厓绱�
+		DaOpcuaConfig daOpcuaConfig = b.stream()
+				.filter(customer ->id.getIdentifier().toString().equals(customer.getNode()))
+				.findAny()
+				.orElse(null);
+		try {
+			Class<?> clazz = Class.forName(daOpcuaConfig.getrModule());
+			Method method = clazz.getMethod(daOpcuaConfig.getrFunction(), new Class[] { String.class, String.class });
+			method.invoke(clazz.newInstance(),new Object[] {
+					new String(id.getIdentifier().toString()), new String(value.getValue().toString()) });
+		} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InstantiationException |
+				 InvocationTargetException e) {
+			e.printStackTrace();
+		}
+	}
+
+
+	/**
+	 * @MethodName: write
+	 * @Description: 鍙樿妭鐐归噺鍐欏叆
+	 * @param node
+	 * @throws Exception
+	 * @CreateTime 2019骞�12鏈�18鏃� 涓婂崍9:51:40
+	 */
+	public static Boolean write(NodeEntity node) throws Exception {
+
+		if (client == null) {
+			log.info("鎵句笉鍒板鎴风锛屾搷浣滃け璐�");
+			return false;
+		}
+
+		NodeId nodeId = new NodeId(node.getIndex(), node.getIdentifier());
+		Variant value = null;
+		switch (node.getType()) {
+		case "int":
+			value = new Variant(Integer.parseInt(node.getValue().toString()));
+			break;
+		case "boolean":
+			value = new Variant(Boolean.parseBoolean(node.getValue().toString()));
+			break;
+		case "short":
+			value = new Variant(Short.parseShort(node.getValue().toString()));
+			break;
+		case "long":
+			value = new Variant(Long.parseLong(node.getValue().toString()));
+			break;
+		case "string":
+			value = new Variant(node.getValue().toString());
+			break;
+		case "char":
+			value = new Variant(node.getValue().toString().charAt(0));
+			break;
+		}
+		DataValue dataValue = new DataValue(value, null, null);
+
+		StatusCode statusCode = client.writeValue(nodeId, dataValue).get();
+
+		return statusCode.isGood();
+	}
+
+	/**
+	 * 鏂规硶鎻忚堪: 璇诲彇澶氫釜鐐逛綅鐨勫��
+	 *
+	 * @param keys 鐐逛綅闆嗗悎
+	 * @return {@link List<DataValue>}
+	 * @throws
+	 */
+	public static List<DataValue> readValues(Set<String> keys){
+		List<NodeId> nodeIdList=new ArrayList<>(500);
+		keys.forEach(e->{
+			NodeId nodeId = new NodeId(2, e);
+			nodeIdList.add(nodeId);
+		});
+		try {
+			List<DataValue> dataValues=client.readValues(0.0, TimestampsToReturn.Both,nodeIdList).get();
+			return dataValues;
+		} catch (InterruptedException | ExecutionException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	/**
+	 * @MethodName: read
+	 * @Description: 璇诲彇
+	 * @param node
+	 * @return
+	 * @throws Exception
+	 * @CreateTime 2019骞�12鏈�19鏃� 涓嬪崍2:40:34
+	 */
+	public String read(NodeEntity node) throws Exception {
+
+		if (client == null) {
+			return "鎵句笉鍒板鎴风锛屾搷浣滃け璐�";
+		}
+
+		NodeId nodeId = new NodeId(node.getIndex(), node.getIdentifier());
+		VariableNode vnode = client.getAddressSpace().createVariableNode(nodeId);
+		DataValue value = vnode.readValue().get();
+		log.info("Value={}", value);
+
+		Variant variant = value.getValue();
+		log.info("Variant={}", variant.getValue());
+
+		log.info("BackingClass={}", BuiltinDataType.getBackingClass(variant.getDataType().get()));
+
+		return variant.getValue().toString();
+	}
+
+
+	/**
+	 * 鏂规硶鎻忚堪:  鍐欏叆澶氫釜鑺傜偣鐨勫��
+	 *
+	 * @param keys  鑺傜偣闆嗗悎
+	 * @param values  鍊奸泦鍚�
+	 * @param client  瀹㈡埛绔�
+	 * @return {@link Object}
+	 * @throws
+	 */
+	public static Object writeValues(Set<String> keys, List<Object> values, OpcUaClient client){
+		List<NodeId> nodeIs=new ArrayList<>(keys.size());
+		keys.forEach(e->{
+			NodeId nodeId = new NodeId(2, e);
+			nodeIs.add(nodeId);
+		});
+		List<DataValue> dataValues=new ArrayList<>(values.size());
+		values.forEach(e->{
+			Variant value=new Variant(Double.parseDouble(e.toString()));
+			DataValue dataValue=new DataValue(value);
+			dataValues.add(dataValue);
+		});
+		try {
+			client.writeValues(nodeIs,dataValues).get();
+		} catch (InterruptedException | ExecutionException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+}
diff --git a/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/client/ClientRunner.java b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/client/ClientRunner.java
new file mode 100644
index 0000000..513a6dd
--- /dev/null
+++ b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/client/ClientRunner.java
@@ -0,0 +1,146 @@
+package com.jcdm.main.da.opcuaconfig.client;
+
+import com.jcdm.main.da.opcuaconfig.cert.KeyStoreLoader;
+import com.jcdm.main.da.opcuaconfig.init.Properties;
+import lombok.extern.slf4j.Slf4j;
+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.AnonymousProvider;
+import org.eclipse.milo.opcua.stack.client.DiscoveryClient;
+import org.eclipse.milo.opcua.stack.core.Stack;
+import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
+import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText;
+import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned;
+import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.function.Predicate;
+
+/**
+ * @ClassName: ClientRunner
+ * @Description: 瀹㈡埛绔惎鍔ㄧ被
+ * @author yyt
+ * @date 2023骞�10鏈�13鏃�
+ */
+@Slf4j
+@Component
+public class ClientRunner {
+
+	private final CompletableFuture<OpcUaClient> future = new CompletableFuture<>();
+
+	@Autowired
+	private Properties properties;
+
+	@Autowired
+	private KeyStoreLoader keyStoreLoader;
+
+	/**
+	 * @MethodName: run
+	 * @Description: 鍚姩
+	 * @return
+	 * @throws Exception
+	 * @CreateTime 2023骞�10鏈�13鏃�
+	 */
+	public OpcUaClient run() throws Exception {
+
+		OpcUaClient client = createClient();
+
+		future.whenCompleteAsync((c, ex) -> {
+			if (ex != null) {
+				log.error("Error running example: {}", ex.getMessage(), ex);
+			}
+
+			try {
+				c.disconnect().get();
+				Stack.releaseSharedResources();
+			} catch (InterruptedException | ExecutionException e) {
+				log.error("Error disconnecting:", e.getMessage(), e);
+			}
+		});
+
+		return client;
+	}
+
+	/**
+	 * @MethodName: createClient
+	 * @Description: 鍒涘缓瀹㈡埛绔�
+	 * @return
+	 * @throws Exception
+	 * @CreateTime 2023骞�10鏈�13鏃�
+	 */
+	private OpcUaClient createClient() throws Exception {
+
+		Path securityTempDir = Paths.get(properties.getCertPath(), "security");
+		Files.createDirectories(securityTempDir);
+		if (!Files.exists(securityTempDir)) {
+			log.error("unable to create security dir: " + securityTempDir);
+			return null;
+		}
+
+		KeyStoreLoader loader = keyStoreLoader.load(securityTempDir);
+
+		// 鎼滅储OPC鑺傜偣
+		List<EndpointDescription> endpoints = null;
+		try {
+			//鑾峰彇瀹夊叏绛栫暐
+			endpoints = DiscoveryClient.getEndpoints(properties.getEndpointUrl()).get();
+		} catch (Throwable e) {
+			// try the explicit discovery endpoint as well
+			String discoveryUrl = properties.getEndpointUrl();
+
+			if (!discoveryUrl.endsWith("/")) {
+				discoveryUrl += "/";
+			}
+			discoveryUrl += "discovery";
+
+			log.info("Trying explicit discovery URL: {}", discoveryUrl);
+			endpoints = DiscoveryClient.getEndpoints(discoveryUrl).get();
+		}
+
+		EndpointDescription endpoint = endpoints.stream()
+				.filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getUri())).filter(endpointFilter())
+				.findFirst().orElseThrow(() -> new Exception("no desired endpoints returned"));
+
+		OpcUaClientConfig config = OpcUaClientConfig.builder()
+				// opc ua鑷畾涔夌殑鍚嶇О
+				.setApplicationName(LocalizedText.english("plc"))
+				// 鍦板潃
+				.setApplicationUri(properties.getEndpointUrl())
+				.setCertificate(loader.getClientCertificate()).setKeyPair(loader.getClientKeyPair())
+				// 瀹夊叏绛栫暐绛夐厤缃�
+				//.setEndpoint(endpoint).setIdentityProvider(new UsernameProvider("OPCUA", "yyt@8888888888"))
+				.setEndpoint(endpoint)
+				// 鍖垮悕楠岃瘉
+				.setIdentityProvider(new AnonymousProvider())
+				//绛夊緟鏃堕棿
+				.setRequestTimeout(Unsigned.uint(5000)).build();
+
+		return OpcUaClient.create(config);
+
+	}
+
+	/**
+	 * @MethodName: endpointFilter
+	 * @Description: endpointFilter
+	 * @return
+	 * @CreateTime 2023骞�10鏈�13鏃�
+	 */
+	private Predicate<EndpointDescription> endpointFilter() {
+		return e -> true;
+	}
+
+	/**
+	 * @return the future
+	 */
+	public CompletableFuture<OpcUaClient> getFuture() {
+		return future;
+	}
+
+}
diff --git a/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/controller/DaOpcuaConfigController.java b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/controller/DaOpcuaConfigController.java
new file mode 100644
index 0000000..0c74d37
--- /dev/null
+++ b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/controller/DaOpcuaConfigController.java
@@ -0,0 +1,109 @@
+package com.jcdm.main.da.opcuaconfig.controller;
+
+import com.jcdm.common.annotation.Log;
+import com.jcdm.common.core.controller.BaseController;
+import com.jcdm.common.core.domain.AjaxResult;
+import com.jcdm.common.core.page.TableDataInfo;
+import com.jcdm.common.enums.BusinessType;
+import com.jcdm.common.utils.poi.ExcelUtil;
+import com.jcdm.main.da.opcuaconfig.domain.DaOpcuaConfig;
+import com.jcdm.main.da.opcuaconfig.service.IDaOpcuaConfigService;
+import com.jcdm.main.da.paramCollection.service.IDaParamCollectionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * OPCUA鍙傛暟璁剧疆Controller
+ * 
+ * @author yyt
+ * @date 2023-12-22
+ */
+@RestController
+@RequestMapping("/da/opcuaconfig")
+public class DaOpcuaConfigController extends BaseController
+{
+    @Autowired
+    private IDaOpcuaConfigService daOpcuaConfigService;
+
+    @Autowired
+    private IDaParamCollectionService daParamCollectionService;
+
+    /**
+     * 鏌ヨOPCUA鍙傛暟璁剧疆鍒楄〃
+     */
+    @PreAuthorize("@ss.hasPermi('da:opcuaconfig:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(DaOpcuaConfig daOpcuaConfig)
+    {
+        startPage();
+        List<DaOpcuaConfig> list = daOpcuaConfigService.selectDaOpcuaConfigList(daOpcuaConfig);
+        return getDataTable(list);
+    }
+
+    @PreAuthorize("@ss.hasPermi('da:opcuaconfig:getconfig')")
+    @GetMapping("/getconfig")
+    public List<DaOpcuaConfig> getconfig(DaOpcuaConfig daOpcuaConfig)
+    {
+        return daOpcuaConfigService.selectDaOpcuaConfigList(daOpcuaConfig);
+    }
+
+    /**
+     * 瀵煎嚭OPCUA鍙傛暟璁剧疆鍒楄〃
+     */
+    @PreAuthorize("@ss.hasPermi('da:opcuaconfig:export')")
+    @Log(title = "OPCUA鍙傛暟璁剧疆", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, DaOpcuaConfig daOpcuaConfig)
+    {
+        List<DaOpcuaConfig> list = daOpcuaConfigService.selectDaOpcuaConfigList(daOpcuaConfig);
+        ExcelUtil<DaOpcuaConfig> util = new ExcelUtil<DaOpcuaConfig>(DaOpcuaConfig.class);
+        util.exportExcel(response, list, "OPCUA鍙傛暟璁剧疆鏁版嵁");
+    }
+
+    /**
+     * 鑾峰彇OPCUA鍙傛暟璁剧疆璇︾粏淇℃伅
+     */
+    @PreAuthorize("@ss.hasPermi('da:opcuaconfig:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(daOpcuaConfigService.selectDaOpcuaConfigById(id));
+    }
+
+    /**
+     * 鏂板OPCUA鍙傛暟璁剧疆
+     */
+    @PreAuthorize("@ss.hasPermi('da:opcuaconfig:add')")
+    @Log(title = "OPCUA鍙傛暟璁剧疆", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody DaOpcuaConfig daOpcuaConfig)
+    {
+        return toAjax(daOpcuaConfigService.insertDaOpcuaConfig(daOpcuaConfig));
+    }
+
+    /**
+     * 淇敼OPCUA鍙傛暟璁剧疆
+     */
+    @PreAuthorize("@ss.hasPermi('da:opcuaconfig:edit')")
+    @Log(title = "OPCUA鍙傛暟璁剧疆", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody DaOpcuaConfig daOpcuaConfig)
+    {
+        return toAjax(daOpcuaConfigService.updateDaOpcuaConfig(daOpcuaConfig));
+    }
+
+    /**
+     * 鍒犻櫎OPCUA鍙傛暟璁剧疆
+     */
+    @PreAuthorize("@ss.hasPermi('da:opcuaconfig:remove')")
+    @Log(title = "OPCUA鍙傛暟璁剧疆", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(daOpcuaConfigService.deleteDaOpcuaConfigByIds(ids));
+    }
+}
diff --git a/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/domain/DaOpcuaConfig.java b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/domain/DaOpcuaConfig.java
new file mode 100644
index 0000000..c9faadc
--- /dev/null
+++ b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/domain/DaOpcuaConfig.java
@@ -0,0 +1,163 @@
+package com.jcdm.main.da.opcuaconfig.domain;
+
+import com.jcdm.common.annotation.Excel;
+import com.jcdm.common.core.domain.BaseEntity;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * OPCUA鍙傛暟璁剧疆瀵硅薄 da_opcua_config
+ * 
+ * @author yyt
+ * @date 2023-12-22
+ */
+public class DaOpcuaConfig extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** ID */
+    private Long id;
+
+    /** 鎵�灞炴ā鍧� */
+    @Excel(name = "鎵�灞炴ā鍧�")
+    private String module;
+
+    /** 鑺傜偣 */
+    @Excel(name = "鑺傜偣")
+    private String node;
+
+    /** 闀垮害 */
+    @Excel(name = "闀垮害")
+    private Long length;
+
+    /** 绫诲瀷 */
+    @Excel(name = "绫诲瀷")
+    private String sysTypes;
+
+    /** 鍔熻兘璇存槑 */
+    @Excel(name = "鍔熻兘璇存槑")
+    private String functionality;
+
+    /** 鏄惁璁㈤槄 */
+    @Excel(name = "鏄惁璁㈤槄")
+    private Long subscribe;
+
+    /** 璁㈤槄鍝嶅簲妯″潡 */
+    @Excel(name = "璁㈤槄鍝嶅簲妯″潡")
+    private String rModule;
+
+    /** 璁㈤槄鍝嶅簲鍑芥暟 */
+    @Excel(name = "璁㈤槄鍝嶅簲鍑芥暟")
+    private String rFunction;
+
+    /** 澶囨敞 */
+    @Excel(name = "澶囨敞")
+    private String remarks;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+    public void setModule(String module) 
+    {
+        this.module = module;
+    }
+
+    public String getModule() 
+    {
+        return module;
+    }
+    public void setNode(String node) 
+    {
+        this.node = node;
+    }
+
+    public String getNode() 
+    {
+        return node;
+    }
+    public void setLength(Long length) 
+    {
+        this.length = length;
+    }
+
+    public Long getLength() 
+    {
+        return length;
+    }
+    public void setSysTypes(String sysTypes) 
+    {
+        this.sysTypes = sysTypes;
+    }
+
+    public String getSysTypes() 
+    {
+        return sysTypes;
+    }
+    public void setFunctionality(String functionality) 
+    {
+        this.functionality = functionality;
+    }
+
+    public String getFunctionality() 
+    {
+        return functionality;
+    }
+    public void setSubscribe(Long subscribe) 
+    {
+        this.subscribe = subscribe;
+    }
+
+    public Long getSubscribe() 
+    {
+        return subscribe;
+    }
+    public void setrModule(String rModule) 
+    {
+        this.rModule = rModule;
+    }
+
+    public String getrModule() 
+    {
+        return rModule;
+    }
+    public void setrFunction(String rFunction) 
+    {
+        this.rFunction = rFunction;
+    }
+
+    public String getrFunction() 
+    {
+        return rFunction;
+    }
+    public void setRemarks(String remarks) 
+    {
+        this.remarks = remarks;
+    }
+
+    public String getRemarks() 
+    {
+        return remarks;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("module", getModule())
+            .append("node", getNode())
+            .append("length", getLength())
+            .append("sysTypes", getSysTypes())
+            .append("functionality", getFunctionality())
+            .append("subscribe", getSubscribe())
+            .append("rModule", getrModule())
+            .append("rFunction", getrFunction())
+            .append("remarks", getRemarks())
+            .toString();
+    }
+}
diff --git a/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/domain/NodeEntity.java b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/domain/NodeEntity.java
new file mode 100644
index 0000000..8d4ba5d
--- /dev/null
+++ b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/domain/NodeEntity.java
@@ -0,0 +1,19 @@
+package com.jcdm.main.da.opcuaconfig.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@Builder(toBuilder = true)
+@AllArgsConstructor
+@NoArgsConstructor
+public class NodeEntity {
+
+	private Integer index;
+	private String identifier;
+	private Object value;
+	private String type;
+	private Integer clientHandle;
+}
diff --git a/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/domain/OpcuaConf.java b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/domain/OpcuaConf.java
new file mode 100644
index 0000000..63688df
--- /dev/null
+++ b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/domain/OpcuaConf.java
@@ -0,0 +1,177 @@
+package com.jcdm.main.da.opcuaconfig.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author yyt
+ * @since 2023-10-17
+ */
+@TableName("sys_opcua_conf")
+public class OpcuaConf implements Serializable {
+    private static final long serialVersionUID=1L;
+
+    /**
+     * ID
+     */
+    @TableId(value = "id", type = IdType.ID_WORKER)
+    private Long id;
+
+    /**
+     * 鎵�灞炴ā鍧�
+     */
+    @TableField("module")
+    private String module;
+
+    /**
+     * 鑺傜偣
+     */
+    @TableField("node")
+    private String node;
+
+    /**
+     * 闀垮害
+     */
+    @TableField("length")
+    private Integer length;
+
+    /**
+     * 绫诲瀷
+     */
+    @TableField("sys_types")
+    private String sysTypes;
+
+    /**
+     * 鍔熻兘璇存槑
+     */
+    @TableField("functionality")
+    private String functionality;
+
+    /**
+     * 鏄惁璁㈤槄
+     */
+    @TableField("subscribe")
+    private Integer subscribe;
+
+    /**
+     * 璁㈤槄鍝嶅簲妯″潡
+     */
+    @TableField("r_module")
+    private String rModule;
+
+    /**
+     * 璁㈤槄鍝嶅簲鍑芥暟
+     */
+    @TableField("r_function")
+    private String rFunction;
+
+    /**
+     * 澶囨敞
+     */
+    @TableField("remarks")
+    private String remarks;
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getModule() {
+        return module;
+    }
+
+    public void setModule(String module) {
+        this.module = module;
+    }
+
+    public String getNode() {
+        return node;
+    }
+
+    public void setNode(String node) {
+        this.node = node;
+    }
+
+    public Integer getLength() {
+        return length;
+    }
+
+    public void setLength(Integer length) {
+        this.length = length;
+    }
+
+    public String getSysTypes() {
+        return sysTypes;
+    }
+
+    public void setSysTypes(String sysTypes) {
+        this.sysTypes = sysTypes;
+    }
+
+    public String getFunctionality() {
+        return functionality;
+    }
+
+    public void setFunctionality(String functionality) {
+        this.functionality = functionality;
+    }
+
+    public Integer getSubscribe() {
+        return subscribe;
+    }
+
+    public void setSubscribe(Integer subscribe) {
+        this.subscribe = subscribe;
+    }
+
+    public String getrModule() {
+        return rModule;
+    }
+
+    public void setrModule(String rModule) {
+        this.rModule = rModule;
+    }
+
+    public String getrFunction() {
+        return rFunction;
+    }
+
+    public void setrFunction(String rFunction) {
+        this.rFunction = rFunction;
+    }
+
+    public String getRemarks() {
+        return remarks;
+    }
+
+    public void setRemarks(String remarks) {
+        this.remarks = remarks;
+    }
+
+    @Override
+    public String toString() {
+        return "OpcuaConf{" +
+        "id=" + id +
+        ", module=" + module +
+        ", node=" + node +
+        ", length=" + length +
+        ", sysTypes=" + sysTypes + ", " + "functionality=" + functionality +
+        ", subscribe=" + subscribe +
+        ", rModule=" + rModule +
+        ", rFunction=" + rFunction +
+        ", remarks=" + remarks +
+        "}";
+    }
+}
diff --git a/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/init/BeanUtils.java b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/init/BeanUtils.java
new file mode 100644
index 0000000..b61e3b5
--- /dev/null
+++ b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/init/BeanUtils.java
@@ -0,0 +1,30 @@
+package com.jcdm.main.da.opcuaconfig.init;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+@Component
+public class BeanUtils implements ApplicationContextAware {
+    protected static ApplicationContext applicationContext ;
+
+    @Override
+    public void setApplicationContext(ApplicationContext arg0) throws BeansException {
+        if (applicationContext == null) {
+            applicationContext = arg0;
+        }
+
+    }
+    public static Object getBean(String name) {
+        //name琛ㄧず鍏朵粬瑕佹敞鍏ョ殑娉ㄨВname鍚�
+        return applicationContext.getBean(name);
+    }
+
+    /**
+     * 鎷垮埌ApplicationContext瀵硅薄瀹炰緥鍚庡氨鍙互鎵嬪姩鑾峰彇Bean鐨勬敞鍏ュ疄渚嬪璞�
+     */
+    public static <T> T getBean(Class<T> clazz) {
+        return applicationContext.getBean(clazz);
+    }
+}
diff --git a/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/init/OpcusConfigInit.java b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/init/OpcusConfigInit.java
new file mode 100644
index 0000000..66b271e
--- /dev/null
+++ b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/init/OpcusConfigInit.java
@@ -0,0 +1,51 @@
+package com.jcdm.main.da.opcuaconfig.init;
+
+import com.google.common.collect.Lists;
+import com.jcdm.main.da.opcuaconfig.client.ClientHandler;
+import com.jcdm.main.da.opcuaconfig.controller.DaOpcuaConfigController;
+import com.jcdm.main.da.opcuaconfig.domain.DaOpcuaConfig;
+import com.jcdm.main.da.opcuaconfig.domain.NodeEntity;
+import com.jcdm.main.da.opcuaconfig.service.IDaOpcuaConfigService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@Component
+@Slf4j
+public class OpcusConfigInit implements CommandLineRunner {
+
+    @Autowired
+    private ClientHandler clientHandler;
+
+    @Autowired
+    private IDaOpcuaConfigService daOpcuaConfigService;
+
+    @Override
+    public void run(String... args) throws Exception {
+        try {
+            DaOpcuaConfig daOpcuaConfig=new DaOpcuaConfig();
+            daOpcuaConfig.setSubscribe(1L); //璁剧疆鏌ヨ鏉′欢锛屾槸鍚﹁闃呯姸鎬佷负1鐨勬墍鏈夋暟鎹�.
+            List<DaOpcuaConfig> nodeslist=daOpcuaConfigService.selectDaOpcuaConfigList(daOpcuaConfig);
+            clientHandler.connect();
+            if (nodeslist != null && nodeslist.size() > 0) {
+                List<NodeEntity> NodeList = Lists.transform(nodeslist, (DaOpcuaConfig) -> {
+                    NodeEntity nodeEntity = new NodeEntity();
+                    nodeEntity.setIndex(2);
+                    nodeEntity.setIdentifier(DaOpcuaConfig.getNode());
+                    return nodeEntity;
+                });
+                clientHandler.subscribe(NodeList);
+                log.info("鍒濆鍖朞PC璁㈤槄" + nodeslist.size() + "鏉★紒");
+            }
+            log.info("绯荤粺鎻愮ず锛孫PCUA璁㈤槄鎴愬姛锛�");
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.info("绯荤粺鎻愮ず锛孫PCUA璁㈤槄澶辫触锛�");
+        }
+    }
+}
diff --git a/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/init/Properties.java b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/init/Properties.java
new file mode 100644
index 0000000..fc06c6b
--- /dev/null
+++ b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/init/Properties.java
@@ -0,0 +1,57 @@
+/**
+ * Created by Jellyleo on 2019骞�12鏈�19鏃�
+ * Copyright 漏 2019 jellyleo.com 
+ * All rights reserved. 
+ */
+package com.jcdm.main.da.opcuaconfig.init;
+
+import lombok.Getter;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+
+/**
+ * @ClassName: Properties
+ * @Description: OpcUa鍙傛暟
+ * @author yyt
+ * @date 2023骞�10鏈�13鏃�
+ */
+@Getter
+@Configuration
+@PropertySource("classpath:opcua.properties")
+public class Properties {
+	@Value("${opcua.server.endpoint.url}")
+	private String endpointUrl;
+	@Value("${opcua.server.idp.username}")
+	private String idpUsername;
+	@Value("${opcua.server.idp.password}")
+	private String idpPassword;
+	@Value("${opcua.client.app.name}")
+	private String appName;
+	@Value("${opcua.client.app.uri}")
+	private String appUri;
+	@Value("${opcua.client.cert.path}")
+	private String certPath;
+	@Value("${opcua.client.cert.file}")
+	private String certFile;
+	@Value("${opcua.client.cert.alias}")
+	private String certAlias;
+	@Value("${opcua.client.cert.common.name}")
+	private String commonName;
+	@Value("${opcua.client.cert.organization}")
+	private String organization;
+	@Value("${opcua.client.cert.organization.unit}")
+	private String orgUnit;
+	@Value("${opcua.client.cert.locality.name}")
+	private String localityName;
+	@Value("${opcua.client.cert.state.name}")
+	private String stateName;
+	@Value("${opcua.client.cert.country.code}")
+	private String countryCode;
+	@Value("${opcua.client.cert.dns.name}")
+	private String dnsName;
+	@Value("${opcua.client.cert.ip.address}")
+	private String ipAddress;
+	@Value("${opcua.client.cert.keystore.password}")
+	private String keyPassword;
+}
diff --git a/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/mapper/DaOpcuaConfigMapper.java b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/mapper/DaOpcuaConfigMapper.java
new file mode 100644
index 0000000..e5a6ca8
--- /dev/null
+++ b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/mapper/DaOpcuaConfigMapper.java
@@ -0,0 +1,62 @@
+package com.jcdm.main.da.opcuaconfig.mapper;
+
+import com.jcdm.main.da.opcuaconfig.domain.DaOpcuaConfig;
+
+import java.util.List;
+
+/**
+ * OPCUA鍙傛暟璁剧疆Mapper鎺ュ彛
+ * 
+ * @author yyt
+ * @date 2023-12-22
+ */
+public interface DaOpcuaConfigMapper 
+{
+    /**
+     * 鏌ヨOPCUA鍙傛暟璁剧疆
+     * 
+     * @param id OPCUA鍙傛暟璁剧疆涓婚敭
+     * @return OPCUA鍙傛暟璁剧疆
+     */
+    public DaOpcuaConfig selectDaOpcuaConfigById(Long id);
+
+    /**
+     * 鏌ヨOPCUA鍙傛暟璁剧疆鍒楄〃
+     * 
+     * @param daOpcuaConfig OPCUA鍙傛暟璁剧疆
+     * @return OPCUA鍙傛暟璁剧疆闆嗗悎
+     */
+    public List<DaOpcuaConfig> selectDaOpcuaConfigList(DaOpcuaConfig daOpcuaConfig);
+
+    /**
+     * 鏂板OPCUA鍙傛暟璁剧疆
+     * 
+     * @param daOpcuaConfig OPCUA鍙傛暟璁剧疆
+     * @return 缁撴灉
+     */
+    public int insertDaOpcuaConfig(DaOpcuaConfig daOpcuaConfig);
+
+    /**
+     * 淇敼OPCUA鍙傛暟璁剧疆
+     * 
+     * @param daOpcuaConfig OPCUA鍙傛暟璁剧疆
+     * @return 缁撴灉
+     */
+    public int updateDaOpcuaConfig(DaOpcuaConfig daOpcuaConfig);
+
+    /**
+     * 鍒犻櫎OPCUA鍙傛暟璁剧疆
+     * 
+     * @param id OPCUA鍙傛暟璁剧疆涓婚敭
+     * @return 缁撴灉
+     */
+    public int deleteDaOpcuaConfigById(Long id);
+
+    /**
+     * 鎵归噺鍒犻櫎OPCUA鍙傛暟璁剧疆
+     * 
+     * @param ids 闇�瑕佸垹闄ょ殑鏁版嵁涓婚敭闆嗗悎
+     * @return 缁撴灉
+     */
+    public int deleteDaOpcuaConfigByIds(Long[] ids);
+}
diff --git a/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/service/IDaOpcuaConfigService.java b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/service/IDaOpcuaConfigService.java
new file mode 100644
index 0000000..5f29de9
--- /dev/null
+++ b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/service/IDaOpcuaConfigService.java
@@ -0,0 +1,62 @@
+package com.jcdm.main.da.opcuaconfig.service;
+
+import com.jcdm.main.da.opcuaconfig.domain.DaOpcuaConfig;
+
+import java.util.List;
+
+/**
+ * OPCUA鍙傛暟璁剧疆Service鎺ュ彛
+ * 
+ * @author yyt
+ * @date 2023-12-22
+ */
+public interface IDaOpcuaConfigService 
+{
+    /**
+     * 鏌ヨOPCUA鍙傛暟璁剧疆
+     * 
+     * @param id OPCUA鍙傛暟璁剧疆涓婚敭
+     * @return OPCUA鍙傛暟璁剧疆
+     */
+    public DaOpcuaConfig selectDaOpcuaConfigById(Long id);
+
+    /**
+     * 鏌ヨOPCUA鍙傛暟璁剧疆鍒楄〃
+     * 
+     * @param daOpcuaConfig OPCUA鍙傛暟璁剧疆
+     * @return OPCUA鍙傛暟璁剧疆闆嗗悎
+     */
+    public List<DaOpcuaConfig> selectDaOpcuaConfigList(DaOpcuaConfig daOpcuaConfig);
+
+    /**
+     * 鏂板OPCUA鍙傛暟璁剧疆
+     * 
+     * @param daOpcuaConfig OPCUA鍙傛暟璁剧疆
+     * @return 缁撴灉
+     */
+    public int insertDaOpcuaConfig(DaOpcuaConfig daOpcuaConfig);
+
+    /**
+     * 淇敼OPCUA鍙傛暟璁剧疆
+     * 
+     * @param daOpcuaConfig OPCUA鍙傛暟璁剧疆
+     * @return 缁撴灉
+     */
+    public int updateDaOpcuaConfig(DaOpcuaConfig daOpcuaConfig);
+
+    /**
+     * 鎵归噺鍒犻櫎OPCUA鍙傛暟璁剧疆
+     * 
+     * @param ids 闇�瑕佸垹闄ょ殑OPCUA鍙傛暟璁剧疆涓婚敭闆嗗悎
+     * @return 缁撴灉
+     */
+    public int deleteDaOpcuaConfigByIds(Long[] ids);
+
+    /**
+     * 鍒犻櫎OPCUA鍙傛暟璁剧疆淇℃伅
+     * 
+     * @param id OPCUA鍙傛暟璁剧疆涓婚敭
+     * @return 缁撴灉
+     */
+    public int deleteDaOpcuaConfigById(Long id);
+}
diff --git a/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/service/impl/DaOpcuaConfigServiceImpl.java b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/service/impl/DaOpcuaConfigServiceImpl.java
new file mode 100644
index 0000000..f2902fb
--- /dev/null
+++ b/jcdm-main/src/main/java/com/jcdm/main/da/opcuaconfig/service/impl/DaOpcuaConfigServiceImpl.java
@@ -0,0 +1,94 @@
+package com.jcdm.main.da.opcuaconfig.service.impl;
+
+import com.jcdm.main.da.opcuaconfig.domain.DaOpcuaConfig;
+import com.jcdm.main.da.opcuaconfig.mapper.DaOpcuaConfigMapper;
+import com.jcdm.main.da.opcuaconfig.service.IDaOpcuaConfigService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * OPCUA鍙傛暟璁剧疆Service涓氬姟灞傚鐞�
+ * 
+ * @author yyt
+ * @date 2023-12-22
+ */
+@Service
+public class DaOpcuaConfigServiceImpl implements IDaOpcuaConfigService
+{
+    @Autowired
+    private DaOpcuaConfigMapper daOpcuaConfigMapper;
+
+    /**
+     * 鏌ヨOPCUA鍙傛暟璁剧疆
+     * 
+     * @param id OPCUA鍙傛暟璁剧疆涓婚敭
+     * @return OPCUA鍙傛暟璁剧疆
+     */
+    @Override
+    public DaOpcuaConfig selectDaOpcuaConfigById(Long id)
+    {
+        return daOpcuaConfigMapper.selectDaOpcuaConfigById(id);
+    }
+
+    /**
+     * 鏌ヨOPCUA鍙傛暟璁剧疆鍒楄〃
+     * 
+     * @param daOpcuaConfig OPCUA鍙傛暟璁剧疆
+     * @return OPCUA鍙傛暟璁剧疆
+     */
+    @Override
+    public List<DaOpcuaConfig> selectDaOpcuaConfigList(DaOpcuaConfig daOpcuaConfig)
+    {
+        return daOpcuaConfigMapper.selectDaOpcuaConfigList(daOpcuaConfig);
+    }
+
+    /**
+     * 鏂板OPCUA鍙傛暟璁剧疆
+     * 
+     * @param daOpcuaConfig OPCUA鍙傛暟璁剧疆
+     * @return 缁撴灉
+     */
+    @Override
+    public int insertDaOpcuaConfig(DaOpcuaConfig daOpcuaConfig)
+    {
+        return daOpcuaConfigMapper.insertDaOpcuaConfig(daOpcuaConfig);
+    }
+
+    /**
+     * 淇敼OPCUA鍙傛暟璁剧疆
+     * 
+     * @param daOpcuaConfig OPCUA鍙傛暟璁剧疆
+     * @return 缁撴灉
+     */
+    @Override
+    public int updateDaOpcuaConfig(DaOpcuaConfig daOpcuaConfig)
+    {
+        return daOpcuaConfigMapper.updateDaOpcuaConfig(daOpcuaConfig);
+    }
+
+    /**
+     * 鎵归噺鍒犻櫎OPCUA鍙傛暟璁剧疆
+     * 
+     * @param ids 闇�瑕佸垹闄ょ殑OPCUA鍙傛暟璁剧疆涓婚敭
+     * @return 缁撴灉
+     */
+    @Override
+    public int deleteDaOpcuaConfigByIds(Long[] ids)
+    {
+        return daOpcuaConfigMapper.deleteDaOpcuaConfigByIds(ids);
+    }
+
+    /**
+     * 鍒犻櫎OPCUA鍙傛暟璁剧疆淇℃伅
+     * 
+     * @param id OPCUA鍙傛暟璁剧疆涓婚敭
+     * @return 缁撴灉
+     */
+    @Override
+    public int deleteDaOpcuaConfigById(Long id)
+    {
+        return daOpcuaConfigMapper.deleteDaOpcuaConfigById(id);
+    }
+}
diff --git a/jcdm-main/src/main/resources/mapper/da/opcuaconfig/DaOpcuaConfigMapper.xml b/jcdm-main/src/main/resources/mapper/da/opcuaconfig/DaOpcuaConfigMapper.xml
new file mode 100644
index 0000000..9ad8e52
--- /dev/null
+++ b/jcdm-main/src/main/resources/mapper/da/opcuaconfig/DaOpcuaConfigMapper.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.jcdm.main.da.opcuaconfig.mapper.DaOpcuaConfigMapper">
+    
+    <resultMap type="DaOpcuaConfig" id="DaOpcuaConfigResult">
+        <result property="id"    column="id"    />
+        <result property="module"    column="module"    />
+        <result property="node"    column="node"    />
+        <result property="length"    column="length"    />
+        <result property="sysTypes"    column="sys_types"    />
+        <result property="functionality"    column="functionality"    />
+        <result property="subscribe"    column="subscribe"    />
+        <result property="rModule"    column="r_module"    />
+        <result property="rFunction"    column="r_function"    />
+        <result property="remarks"    column="remarks"    />
+    </resultMap>
+
+    <sql id="selectDaOpcuaConfigVo">
+        select id, module, node, length, sys_types, functionality, subscribe, r_module, r_function, remarks from da_opcua_config
+    </sql>
+
+    <select id="selectDaOpcuaConfigList" parameterType="DaOpcuaConfig" resultMap="DaOpcuaConfigResult">
+        <include refid="selectDaOpcuaConfigVo"/>
+        <where>  
+            <if test="module != null  and module != ''"> and module like concat('%', #{module}, '%')</if>
+            <if test="node != null  and node != ''"> and node like concat('%', #{node}, '%')</if>
+            <if test="length != null "> and length = #{length}</if>
+            <if test="sysTypes != null  and sysTypes != ''"> and sys_types = #{sysTypes}</if>
+            <if test="functionality != null  and functionality != ''"> and functionality like concat('%', #{functionality}, '%')</if>
+            <if test="subscribe != null "> and subscribe = #{subscribe}</if>
+            <if test="rModule != null  and rModule != ''"> and r_module like concat('%', #{rModule}, '%')</if>
+            <if test="rFunction != null  and rFunction != ''"> and r_function like concat('%', #{rFunction}, '%')</if>
+        </where>
+    </select>
+    
+    <select id="selectDaOpcuaConfigById" parameterType="Long" resultMap="DaOpcuaConfigResult">
+        <include refid="selectDaOpcuaConfigVo"/>
+        where id = #{id}
+    </select>
+        
+    <insert id="insertDaOpcuaConfig" parameterType="DaOpcuaConfig">
+        insert into da_opcua_config
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="id != null">id,</if>
+            <if test="module != null">module,</if>
+            <if test="node != null">node,</if>
+            <if test="length != null">length,</if>
+            <if test="sysTypes != null">sys_types,</if>
+            <if test="functionality != null">functionality,</if>
+            <if test="subscribe != null">subscribe,</if>
+            <if test="rModule != null">r_module,</if>
+            <if test="rFunction != null">r_function,</if>
+            <if test="remarks != null">remarks,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="id != null">#{id},</if>
+            <if test="module != null">#{module},</if>
+            <if test="node != null">#{node},</if>
+            <if test="length != null">#{length},</if>
+            <if test="sysTypes != null">#{sysTypes},</if>
+            <if test="functionality != null">#{functionality},</if>
+            <if test="subscribe != null">#{subscribe},</if>
+            <if test="rModule != null">#{rModule},</if>
+            <if test="rFunction != null">#{rFunction},</if>
+            <if test="remarks != null">#{remarks},</if>
+         </trim>
+    </insert>
+
+    <update id="updateDaOpcuaConfig" parameterType="DaOpcuaConfig">
+        update da_opcua_config
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="module != null">module = #{module},</if>
+            <if test="node != null">node = #{node},</if>
+            <if test="length != null">length = #{length},</if>
+            <if test="sysTypes != null">sys_types = #{sysTypes},</if>
+            <if test="functionality != null">functionality = #{functionality},</if>
+            <if test="subscribe != null">subscribe = #{subscribe},</if>
+            <if test="rModule != null">r_module = #{rModule},</if>
+            <if test="rFunction != null">r_function = #{rFunction},</if>
+            <if test="remarks != null">remarks = #{remarks},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteDaOpcuaConfigById" parameterType="Long">
+        delete from da_opcua_config where id = #{id}
+    </delete>
+
+    <delete id="deleteDaOpcuaConfigByIds" parameterType="String">
+        delete from da_opcua_config where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>
\ No newline at end of file
diff --git a/jcdm-main/src/main/resources/opcua.properties b/jcdm-main/src/main/resources/opcua.properties
new file mode 100644
index 0000000..bc25383
--- /dev/null
+++ b/jcdm-main/src/main/resources/opcua.properties
@@ -0,0 +1,20 @@
+#opcua server
+opcua.server.endpoint.url=opc.tcp://127.0.0.1:49320
+opcua.server.idp.username=
+opcua.server.idp.password=
+
+#opcua client
+opcua.client.app.name=plc
+opcua.client.app.uri=urn:Yyt_PC:UnifiedAutomation:UaExpert
+opcua.client.cert.path=C:/mes/
+opcua.client.cert.file=Yyt_PC-client.pfx
+opcua.client.cert.alias=jlclient-ai
+opcua.client.cert.common.name=UaClient@Jellyleo
+opcua.client.cert.organization=JL
+opcua.client.cert.organization.unit=per
+opcua.client.cert.locality.name=jl
+opcua.client.cert.state.name=JiangSu
+opcua.client.cert.country.code=CN
+opcua.client.cert.dns.name=Jellyleo
+opcua.client.cert.ip.address=administrator
+opcua.client.cert.keystore.password=yyt@8888888888

--
Gitblit v1.9.3