From 32b5a1fd43e600be3fa74ddcec6de709c19ac417 Mon Sep 17 00:00:00 2001 From: caixiang <939387484@qq.com> Date: Thu, 30 Sep 2021 17:00:30 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20=E6=8E=A8=E9=80=81?= =?UTF-8?q?=E6=96=B0=E5=A2=9Estatus=20+=20time?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dc/opcua/config/LocalMulPLCConfig.java | 119 +++++++++++++++++- .../opcua/controller/OperateController.java | 79 ++++++++---- .../qgs/dc/opcua/selfunion/Enum/PLCVar.java | 14 +++ .../com/qgs/dc/opcua/selfunion/UAService.java | 14 ++- .../entity/SubscribeVarArgEntity.java | 21 ++++ .../entity/SubscribeVarOfConfigEntity.java | 66 ++++++++++ .../dc/opcua/taskPool/MultiWorkRunnable.java | 58 +++++++++ .../qgs/dc/opcua/taskPool/QGSThreadPool.java | 39 ++++++ .../qgs/dc/s7/controller/S7Controller.java | 51 +------- .../com/qgs/dc/s7/enums/S7DriveManage.java | 28 +++++ .../java/com/qgs/dc/s7/service/S7Service.java | 75 +++++++++-- 11 files changed, 476 insertions(+), 88 deletions(-) create mode 100644 src/main/java/com/qgs/dc/opcua/selfunion/entity/SubscribeVarOfConfigEntity.java create mode 100644 src/main/java/com/qgs/dc/opcua/taskPool/MultiWorkRunnable.java create mode 100644 src/main/java/com/qgs/dc/opcua/taskPool/QGSThreadPool.java create mode 100644 src/main/java/com/qgs/dc/s7/enums/S7DriveManage.java diff --git a/src/main/java/com/qgs/dc/opcua/config/LocalMulPLCConfig.java b/src/main/java/com/qgs/dc/opcua/config/LocalMulPLCConfig.java index df3499f..6b46ee2 100644 --- a/src/main/java/com/qgs/dc/opcua/config/LocalMulPLCConfig.java +++ b/src/main/java/com/qgs/dc/opcua/config/LocalMulPLCConfig.java @@ -4,11 +4,14 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.qgs.dc.common.utils.CommonFunction; import com.qgs.dc.opcua.constant.PLCConstant; +import com.qgs.dc.opcua.selfunion.entity.SubscribeVarArgEntity; +import com.qgs.dc.opcua.selfunion.entity.SubscribeVarOfConfigEntity; import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy; import java.io.*; import java.nio.charset.StandardCharsets; -import java.util.HashMap; +import java.util.*; +import java.util.stream.Collectors; public class LocalMulPLCConfig { @@ -21,7 +24,7 @@ public class LocalMulPLCConfig { if (!jsonFile.exists()) { boolean b= jsonFile.createNewFile(); JSONObject json = new JSONObject(); - json =JSON.parseObject("{\"config\": []}"); + json =JSON.parseObject("{\"config\": [],\"subscribedForVisit\":{}}"); FileWriter fw = new FileWriter(jsonFile.getAbsoluteFile()); BufferedWriter bw = new BufferedWriter(fw); json.writeJSONString(bw); @@ -45,8 +48,120 @@ public class LocalMulPLCConfig { } } + public static void main(String[] args) throws IOException { +// SubscribeVarOfConfigEntity subscribeVarOfConfigEntity1 = new SubscribeVarOfConfigEntity(5,"Boolean",3000,"plc2"); +// SubscribeVarOfConfigEntity subscribeVarOfConfigEntity2 = new SubscribeVarOfConfigEntity(5,"Byte",2000,"plc2"); +// SubscribeVarOfConfigEntity subscribeVarOfConfigEntity3 = new SubscribeVarOfConfigEntity(5,"Double",1000,"plc2"); +// SubscribeVarOfConfigEntity subscribeVarOfConfigEntity4 = new SubscribeVarOfConfigEntity(5,"Float",1000,"plc2"); +// ArrayList objects = new ArrayList<>(); +// objects.add(subscribeVarOfConfigEntity1); +// objects.add(subscribeVarOfConfigEntity2); +// objects.add(subscribeVarOfConfigEntity3); +// objects.add(subscribeVarOfConfigEntity4); +// writeIntoFileOfSubscribeVar(objects); + //read + ArrayList plc1 = getSubscribedVarOfConfig("plc2"); + Map> map = plc1.stream().collect(Collectors.groupingBy(t -> t.getPeriod())); + System.out.println("period"+map); + /*然后再对map处理,这样就方便取出自己要的数据*/ + for(Map.Entry> entry : map.entrySet()){ + System.out.println("key:"+entry.getKey()); + System.out.println("value:"+entry.getValue()); + } + System.out.println(); + } + + //把修改了的变量 全量替换到文件 + public static void writeIntoFileOfSubscribeVar(List subscribeVars) throws IOException { + String s = ""; + String ss = ""; + if(CommonFunction.isLinux()){ + s = readJsonFile(PLCConstant.localURLForLinux); + ss = PLCConstant.localURLForLinux; + + }else if(CommonFunction.isWindows()){ + s = readJsonFile(PLCConstant.localURLForWindows); + ss = PLCConstant.localURLForWindows; + } + + JSONObject jobj = JSON.parseObject(s); + + //JSONArray subscribedForVisits = jobj.getJSONArray("subscribedForVisit");//构建JSONArray数组 + JSONObject subscribedForVisit = jobj.getJSONObject("subscribedForVisit"); + if(subscribeVars.size() <= 0){ + return; + } + + + String plcName = subscribeVars.get(0).getPlcName(); + JSONArray objects = new JSONArray(); + + + + for (SubscribeVarOfConfigEntity entity:subscribeVars){ + Map newValue = new LinkedHashMap(); + newValue.put("plc_name", entity.getPlcName()); + newValue.put("ns", entity.getNameSpace()); + newValue.put("period", entity.getPeriod()); + newValue.put("identity", entity.getIdentifier()); + objects.add(newValue); + } + subscribedForVisit.put(plcName,objects); + + + JSONObject json = jobj; + + + File file = new File(ss); + + + if (!file.exists()) { + boolean b= file.createNewFile(); + + } + FileWriter fw = new FileWriter(file.getAbsoluteFile()); + BufferedWriter bw = new BufferedWriter(fw); + json.writeJSONString(bw); + bw.close(); + System.out.println("end"); + //写入json 结束 + } + + //todo here 把订阅的信息 存储到本地文件(CURD + 比对(重复问题)) + public static ArrayList getSubscribedVarOfConfig(String plcName){ + //String path = LocalMulPLCConfig.class.getClassLoader().getResource("mulPLCConfig.json").getPath(); + String s = ""; + if(CommonFunction.isLinux()){ + CommonFunction.createDirIfNotExit(PLCConstant.localURLDirForLinux); + s = readJsonFile(PLCConstant.localURLForLinux); + }else if(CommonFunction.isWindows()){ + CommonFunction.createDirIfNotExit(PLCConstant.localURLDirForWindows); + s = readJsonFile(PLCConstant.localURLForWindows); + } + + JSONObject jobj = JSON.parseObject(s); + + + + JSONObject subscribedForVisit = jobj.getJSONObject("subscribedForVisit");//构建JSONArray数组 + JSONArray jsonObject = subscribedForVisit.getJSONArray(plcName); + if(jsonObject == null){ + return new ArrayList<>(); + } + ArrayList res = new ArrayList<>(); + for (int i = 0 ; i < jsonObject.size();i++){ + JSONObject key = (JSONObject)jsonObject.get(i); + + Integer period = (Integer)key.get("period"); + Integer ns = (Integer)key.get("ns"); + String identity =(String)key.get("identity"); + res.add(new SubscribeVarOfConfigEntity(ns,identity,period,plcName)); + } + return res; + } + public static HashMap getPLCConfig(){ //String path = LocalMulPLCConfig.class.getClassLoader().getResource("mulPLCConfig.json").getPath(); String s = ""; diff --git a/src/main/java/com/qgs/dc/opcua/controller/OperateController.java b/src/main/java/com/qgs/dc/opcua/controller/OperateController.java index bfd8181..20aa98c 100644 --- a/src/main/java/com/qgs/dc/opcua/controller/OperateController.java +++ b/src/main/java/com/qgs/dc/opcua/controller/OperateController.java @@ -3,15 +3,16 @@ package com.qgs.dc.opcua.controller; import com.qgs.dc.opcua.Consumer.EventReceivedCallBack; import com.qgs.dc.opcua.arg.*; import com.qgs.dc.common.utils.CommonFunction; +import com.qgs.dc.opcua.config.LocalMulPLCConfig; import com.qgs.dc.opcua.constant.PLCConstant; import com.qgs.dc.opcua.selfunion.Enum.PLCType; +import com.qgs.dc.opcua.selfunion.Enum.PLCVar; import com.qgs.dc.opcua.selfunion.NodeIdKey; import com.qgs.dc.opcua.selfunion.UAService; -import com.qgs.dc.opcua.selfunion.entity.CurrentSubEntity; -import com.qgs.dc.opcua.selfunion.entity.DelSubscribeEntity; -import com.qgs.dc.opcua.selfunion.entity.SubscribeEventArgEntity; -import com.qgs.dc.opcua.selfunion.entity.SubscribeVarArgEntity; +import com.qgs.dc.opcua.selfunion.entity.*; import com.qgs.dc.common.websocket.WebSocketServer; +import com.qgs.dc.opcua.taskPool.MultiWorkRunnable; +import com.qgs.dc.opcua.taskPool.QGSThreadPool; import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaMonitoredItem; import org.eclipse.milo.opcua.stack.core.StatusCodes; import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; @@ -29,6 +30,9 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Map; +import java.util.concurrent.Future; +import java.util.stream.Collectors; @RestController @RequestMapping("/opcua") @@ -42,22 +46,6 @@ public class OperateController { @Autowired WebSocketServer webSocketServer; - @PostMapping("/testForWeight") - public R testForWeight(){ - //压力测试 - try { - DataValue dv = uaService.getValue(5,"Boolean", "plc1"); - Object value = dv.getValue().getValue(); - - logger.info(CommonFunction.judgeVarType(value)); - return R.ok().put("result", CommonFunction.var(value)); - }catch (Exception e){ - String s = uaService.extractError(e.getMessage()); - s = s+";详细:"+e.getMessage(); - return R.error().put("result",s); - } - } - @PostMapping("/addThisPlc") /** * @Description @@ -173,7 +161,40 @@ public class OperateController { return R.error().put("result", e.getMessage()); } + } +// @PostMapping("/readwriteForTest") +// //public R read(Integer nameSpace,String identifier,String plcName) { +// public R readwriteForTest() { +// for(int i = 0;i<50;i++){ +// MultiWorkRunnable multiWorkRunnable1 = new MultiWorkRunnable<>(uaService); +// Future submit1 = QGSThreadPool.executor.submit(multiWorkRunnable1); +// } +// return R.ok(); +// } + + + //获取这台plc 所有订阅的变量 + @PostMapping("getAllSubscribeVarOfPlcNameWithLocal") + public R getAllSubscribeVarOfPlcNameWithLocal(@RequestBody SubscribeVarArgEntity subscribeVarArgEntity) throws Exception { + if(subscribeVarArgEntity.getPlcName()==null){ + return R.error("plcName 不能为空"); + } + ArrayList subscribedVarOfConfig = LocalMulPLCConfig.getSubscribedVarOfConfig(subscribeVarArgEntity.getPlcName()); + for(SubscribeVarOfConfigEntity entity: subscribedVarOfConfig){ + Object value = uaService.getValue(entity.getNameSpace(), entity.getIdentifier(), entity.getPlcName()).getValue().getValue(); + entity.setNowValue(value.toString()); + } + Map> map = subscribedVarOfConfig.stream().collect(Collectors.groupingBy(t -> t.getPeriod())); + + return R.ok().put("result",map); + } + + @PostMapping("saveAllSubscribeVarOfPlcNameToLocal") + public R saveAllSubscribeVarOfPlcNameToLocal(@RequestBody List subscribeVars) throws Exception { + + LocalMulPLCConfig.writeIntoFileOfSubscribeVar(subscribeVars); + return R.ok().put("result","成功"); } //todo 1.订阅变量数组...(并且把数据类型返还给前端) @@ -183,6 +204,7 @@ public class OperateController { * listNameSpace List * listIdentifier List * plcName String + * period Integer * 注意 : ns 和 identify 必须位置上相互对应,,判断是否数组依据就是看几组数据 * 返回: * 这边是通过websocket 返回的 是一个字符串 @@ -190,13 +212,13 @@ public class OperateController { * 第二组 是变量值 * 第三组 是变量值 的类型(如果是数组 那就是QArray) * 第四组 是变量值 的类型(如果是数组 那这组就存在,代表数组里面变量的数据类型) - * 3,Byte|8,7,7,7,8|QArray|QShort - * 3,Byte|0|QUByte + * 3,Byte|8,7,7,7,8|QArray|QShort|status|time + * 3,Byte|0|QUByte|status|time * */ @PostMapping("subscribeVarForFunction") public R subscribeVarForFunction(@RequestBody SubscribeVarArgEntity subscribeVarArgEntity) throws Exception { - Integer integer = uaService.subscribeValues(subscribeVarArgEntity.getListNameSpace(), subscribeVarArgEntity.getListIdentifier(), new Double(1000), + Integer integer = uaService.subscribeValues(subscribeVarArgEntity.getListNameSpace(), subscribeVarArgEntity.getListIdentifier(), new Double(subscribeVarArgEntity.getPeriod()==null?1000:subscribeVarArgEntity.getPeriod()), (item, dataValue) -> { System.err.println("(测试是否 每隔intervel 都会执行这个回调方法) subscription value received: item:NodeId : " + @@ -231,6 +253,7 @@ public class OperateController { * listNameSpace List * listIdentifier List * plcName String + * period Integer * 注意 : ns 和 identify 必须位置上相互对应,,判断是否数组依据就是看几组数据 * 返回: * 1 <===> 你要订阅的这个Node 订阅成功(包括这个变量已存在 然后你再次去订阅) @@ -243,14 +266,14 @@ public class OperateController { * 第三组 是变量值 的类型(如果是数组 那就是QArray) * 第四组 是变量值 的类型(如果是数组 那这组就存在,代表数组里面变量的数据类型) * 第五组 是这个变量所属 的plc,,是哪个plc - * 3,Byte|8,7,7,7,8|QArray|QShort|plcName - * 3,Byte|0|QUByte|plcName + * 3,Byte|8,7,7,7,8|QArray|QShort|plcName|status|time + * 3,Byte|0|QUByte|plcName|status|time * */ @PostMapping("subscribeVarForVisit") public R subscribeVarForVisit(@RequestBody SubscribeVarArgEntity subscribeVarArgEntity){ try { - Integer integer = uaService.subscribeForVisit(subscribeVarArgEntity.getListNameSpace(), subscribeVarArgEntity.getListIdentifier(), new Double(1000), (item, dataValue) -> { + Integer integer = uaService.subscribeForVisit(subscribeVarArgEntity.getListNameSpace(), subscribeVarArgEntity.getListIdentifier(), new Double(subscribeVarArgEntity.getPeriod()==null?1000:subscribeVarArgEntity.getPeriod()), (item, dataValue) -> { UInteger attributeId = item.getReadValueId().getAttributeId(); System.err.println("(测试是否 每隔intervel 都会执行这个回调方法) subscription value received: item:NodeId : " + @@ -264,7 +287,7 @@ public class OperateController { String status = CommonFunction.quality(dataValue.getStatusCode()); String time = dataValue.getSourceTime().getJavaDate().toString(); - String res = namespaceIndex + "," + identifier + "|" + CommonFunction.var2String(value) + "|" + varType+ "|" +subscribeVarArgEntity.getPlcName()+"|"+status+"|"+time; + String res = namespaceIndex + "," + identifier + "|" + CommonFunction.var2String(value) + "|" + varType+ "|" +subscribeVarArgEntity.getPlcName()+"|"+status+"|"+time ; try { webSocketServer.sendtoAll(res); @@ -288,6 +311,7 @@ public class OperateController { } } /** + * 状态: 暂时还未用到 * 含义 : 订阅一个或者多个事件 * 参数 : SubscribeArgEntity * listNameSpace List @@ -410,6 +434,7 @@ public class OperateController { //todo 测试 try { List currentSubscribeVarForVisited = uaService.getCurrentSubscribeVarForVisited(currentSubArgEntity.getPlcName()); + if(currentSubscribeVarForVisited == null){ return R.error().put("result",currentSubArgEntity.getPlcName()+"这台plc不存在 或是 订阅不存在"); } diff --git a/src/main/java/com/qgs/dc/opcua/selfunion/Enum/PLCVar.java b/src/main/java/com/qgs/dc/opcua/selfunion/Enum/PLCVar.java index 4393c32..bda418f 100644 --- a/src/main/java/com/qgs/dc/opcua/selfunion/Enum/PLCVar.java +++ b/src/main/java/com/qgs/dc/opcua/selfunion/Enum/PLCVar.java @@ -19,6 +19,20 @@ public enum PLCVar implements PLCVarEnum { Int64_5(3,"Int64"), Int32_5(3,"Int32"), Int16_5(3,"Int16"), + Byte(5,"Byte"), + Boolean(5,"Boolean"), + ByteString(5,"ByteString"), + DateTime(5,"DateTime"), + Double(5,"Double"), + Float(5,"Float"), + Int16(5,"Int16"), + Int32(5,"Int32"), + Int64(5,"Int64"), + Integer(5,"Integer"), + String(5,"String"), + Time(5,"Time"), + + RealPLC(3,"@LOCALSERVER.db1.0,b"), diff --git a/src/main/java/com/qgs/dc/opcua/selfunion/UAService.java b/src/main/java/com/qgs/dc/opcua/selfunion/UAService.java index dcfc4a9..ddf1af1 100644 --- a/src/main/java/com/qgs/dc/opcua/selfunion/UAService.java +++ b/src/main/java/com/qgs/dc/opcua/selfunion/UAService.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.google.common.collect.ImmutableList; +import com.qgs.dc.common.websocket.WebSocketServer; import com.qgs.dc.opcua.config.LocalMulPLCConfig; import com.qgs.dc.opcua.config.PLCConfig; import com.qgs.dc.common.utils.CommonFunction; @@ -11,6 +12,7 @@ import com.qgs.dc.opcua.constant.PLCConstant; import com.qgs.dc.opcua.selfunion.Enum.PLCVar; import com.qgs.dc.opcua.selfunion.entity.CurrentSubEntity; import com.qgs.dc.opcua.selfunion.entity.SubscribeEntity; +import com.qgs.dc.opcua.selfunion.entity.SubscribeVarOfConfigEntity; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.eclipse.milo.opcua.sdk.client.OpcUaClient; import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig; @@ -35,6 +37,7 @@ import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn; import org.eclipse.milo.opcua.stack.core.types.structured.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.io.BufferedWriter; @@ -54,6 +57,7 @@ import java.util.function.Predicate; import static com.qgs.dc.opcua.config.LocalMulPLCConfig.readJsonFile; import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint; import static org.eclipse.milo.opcua.stack.core.util.ConversionUtil.l; +import static org.eclipse.milo.opcua.stack.core.util.ConversionUtil.s; /** * @Author: 蔡翔 @@ -100,6 +104,8 @@ public class UAService { Security.addProvider(new BouncyCastleProvider()); } + @Autowired + WebSocketServer webSocketServer; private final Logger logger = LoggerFactory.getLogger(getClass()); private boolean flag = true; @@ -727,7 +733,8 @@ public class UAService { //SubscribeEntity 不存在的时候新建一个SubscribeEntity,并且UaSubscription也要新建一个 if(currentNow == null){ try { - subscription = client.getSubscriptionManager().createSubscription(1000.0).get(); + Double rquestedPubilshInterval = listenTimeInterval; + subscription = client.getSubscriptionManager().createSubscription(rquestedPubilshInterval).get(); }catch (Exception e){ throw new Exception("在 subscribeForVisit 的时候出现异常,,具体异常是: "+e.getMessage()); } @@ -880,8 +887,8 @@ public class UAService { //SubscribeEntity 不存在的时候新建一个SubscribeEntity,并且UaSubscription也要新建一个 if(currentNow == null){ try { - - subscription = client.getSubscriptionManager().createSubscription(1000.0).get(); + Double rquestedPubilshInterval = samplingInterval; + subscription = client.getSubscriptionManager().createSubscription(rquestedPubilshInterval).get(); }catch (Exception e){ throw new Exception("在 subscribeForVisit 的时候出现异常,,具体异常是: "+e.getMessage()); } @@ -1704,6 +1711,7 @@ public class UAService { OpcUaClient op = null; try { op = createClient(hashMap.get(key)); + }catch (Exception e){ logger.error("采集程序启动的时候,尝试连接 "+key +"失败,,可能是网络问题 或者 OPC SERVER问题"); continue; diff --git a/src/main/java/com/qgs/dc/opcua/selfunion/entity/SubscribeVarArgEntity.java b/src/main/java/com/qgs/dc/opcua/selfunion/entity/SubscribeVarArgEntity.java index 4ffba2e..1874a78 100644 --- a/src/main/java/com/qgs/dc/opcua/selfunion/entity/SubscribeVarArgEntity.java +++ b/src/main/java/com/qgs/dc/opcua/selfunion/entity/SubscribeVarArgEntity.java @@ -10,8 +10,29 @@ import java.util.List; public class SubscribeVarArgEntity { List listNameSpace; List listIdentifier; + //采集频率 单位 ms ;2000ms = 2s 采集一次 + Integer period; + String plcName; + public Integer getPeriod() { + return period; + } + + public SubscribeVarArgEntity() { + } + + public SubscribeVarArgEntity(List listNameSpace, List listIdentifier, Integer period, String plcName) { + this.listNameSpace = listNameSpace; + this.listIdentifier = listIdentifier; + this.period = period; + this.plcName = plcName; + } + + public void setPeriod(Integer period) { + this.period = period; + } + public List getListNameSpace() { return listNameSpace; } diff --git a/src/main/java/com/qgs/dc/opcua/selfunion/entity/SubscribeVarOfConfigEntity.java b/src/main/java/com/qgs/dc/opcua/selfunion/entity/SubscribeVarOfConfigEntity.java new file mode 100644 index 0000000..ab92950 --- /dev/null +++ b/src/main/java/com/qgs/dc/opcua/selfunion/entity/SubscribeVarOfConfigEntity.java @@ -0,0 +1,66 @@ +package com.qgs.dc.opcua.selfunion.entity; + +/** + * @Desc: "" + * @Author: caixiang + * @DATE: 2020/7/23 14:51 + */ +public class SubscribeVarOfConfigEntity { + Integer nameSpace; + String identifier; + //采集频率 单位 ms ;2000ms = 2s 采集一次 + Integer period; + + String plcName; + String nowValue; + + public String getNowValue() { + return nowValue; + } + + public void setNowValue(String nowValue) { + this.nowValue = nowValue; + } + + public Integer getPeriod() { + return period; + } + + public SubscribeVarOfConfigEntity() { + } + + public SubscribeVarOfConfigEntity(Integer nameSpace, String identifier, Integer period, String plcName) { + this.nameSpace = nameSpace; + this.identifier = identifier; + this.period = period; + this.plcName = plcName; + } + + public void setPeriod(Integer period) { + this.period = period; + } + + public Integer getNameSpace() { + return nameSpace; + } + + public void setNameSpace(Integer nameSpace) { + this.nameSpace = nameSpace; + } + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + public String getPlcName() { + return plcName; + } + + public void setPlcName(String plcName) { + this.plcName = plcName; + } +} diff --git a/src/main/java/com/qgs/dc/opcua/taskPool/MultiWorkRunnable.java b/src/main/java/com/qgs/dc/opcua/taskPool/MultiWorkRunnable.java new file mode 100644 index 0000000..f92453f --- /dev/null +++ b/src/main/java/com/qgs/dc/opcua/taskPool/MultiWorkRunnable.java @@ -0,0 +1,58 @@ +package com.qgs.dc.opcua.taskPool; + + +import com.qgs.dc.opcua.selfunion.Enum.PLCVar; +import com.qgs.dc.opcua.selfunion.UAService; +import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.Callable; + +/** + * @Author: 蔡翔 + * @Date: 2019/10/30 16:23 + * @Version 1.0 + */ +public class MultiWorkRunnable implements Callable { + private final static Logger logger = LoggerFactory.getLogger(MultiWorkRunnable.class); + private UAService uaService; + public MultiWorkRunnable(UAService uaService){ + this.uaService = uaService; + } + public MultiWorkRunnable(){ + + } + public synchronized void initialMultiWorkRunnable(UAService uaService){ + this.uaService = uaService; + } + + public static void main(String[] args) { + + } + + @Override + public T call() throws Exception { + Long start = System.currentTimeMillis(); + //10000/200 + for (int i = 0; i < 60; i++) { + DataValue Byte = uaService.getValue(PLCVar.Byte, "plc2"); + DataValue Boolean = uaService.getValue(PLCVar.Boolean, "plc2"); + DataValue ByteString = uaService.getValue(PLCVar.ByteString, "plc2"); + DataValue plc11 = uaService.getValue(PLCVar.DateTime, "plc2"); + DataValue plc12 = uaService.getValue(PLCVar.Double, "plc2"); + DataValue plc13 = uaService.getValue(PLCVar.Float, "plc2"); + DataValue plc14 = uaService.getValue(PLCVar.Int16, "plc2"); + DataValue plc15 = uaService.getValue(PLCVar.Int32, "plc2"); + DataValue plc16 = uaService.getValue(PLCVar.Int64, "plc2"); + DataValue plc17 = uaService.getValue(PLCVar.Integer, "plc2"); + DataValue plc18 = uaService.getValue(PLCVar.String, "plc2"); + DataValue plc19 = uaService.getValue(PLCVar.Time, "plc2"); + } + Long end = System.currentTimeMillis(); + Long res = end-start; + System.out.println(res); + return (T)res; + //return (T(1)); + } +} diff --git a/src/main/java/com/qgs/dc/opcua/taskPool/QGSThreadPool.java b/src/main/java/com/qgs/dc/opcua/taskPool/QGSThreadPool.java new file mode 100644 index 0000000..759b72e --- /dev/null +++ b/src/main/java/com/qgs/dc/opcua/taskPool/QGSThreadPool.java @@ -0,0 +1,39 @@ +package com.qgs.dc.opcua.taskPool; + +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @Author: 蔡翔 + * @Date: 2019/9/23 9:32 + * @Version 1.0 + */ +public class QGSThreadPool { + public static AtomicInteger threadCount = new AtomicInteger(); + public static ThreadPoolExecutor executor = new ThreadPoolExecutor( + 200, //核心线程数 + 400, //最大线程数。 + 1L, // 空闲线程存活时间 (这里是一分钟) + TimeUnit.MINUTES, // 空闲线程存货的时间单位 + new ArrayBlockingQueue<>(200), //一个指定上限的的阻塞队列,这个队列中存放着待执行的任务 + new ThreadFactory() { + // 自定义一个线程工厂来给线程池里面的线程取名字 + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "threadPool-opc-" + threadCount.incrementAndGet()); + } + }, + new RejectedExecutionHandler() { + // 自定义一个拒绝处理策略,安慰被线程池拒之门外的任务 + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + System.out.println("opc read err:"+r); + } + } + ); + ExecutorService executorService = Executors.newSingleThreadExecutor(); + + /*public ExecutorService getExecutor(){ + return this.executor; + }*/ +} diff --git a/src/main/java/com/qgs/dc/s7/controller/S7Controller.java b/src/main/java/com/qgs/dc/s7/controller/S7Controller.java index 6b2aedb..8a9772a 100644 --- a/src/main/java/com/qgs/dc/s7/controller/S7Controller.java +++ b/src/main/java/com/qgs/dc/s7/controller/S7Controller.java @@ -28,59 +28,12 @@ public class S7Controller { @PostMapping("/addThisPlc") public R addThisPlc() throws PlcConnectionException { - Integer plc1 = s7Service.addPlc("plc1", "s7://192.168.0.200"); - return R.ok().put("res",plc1); + //s7://192.168.1.51?remote-rack=0&remote-slot=3&controller-type=S7_400,如果参数不是默认的 要向这样往url 后面加。 + return R.ok().put("res",s7Service.addPlc("s7://192.168.0.200")); } @PostMapping("/getValue") public R getValue() throws PlcConnectionException { - try(PlcConnection conn = s7Service.getConnection("s7://192.168.0.200")) { - if(conn.isConnected()){ - if(conn.getMetadata().canRead()){ - try { - PlcReadRequest.Builder builder = conn.readRequestBuilder(); - //builder.addItem("INT_1", "%DB10:4:INT"); - //builder.addItem("Byte-array", "%DB10:312:BYTE[20]"); - builder.addItem("STRING", "%DB10:10.0:STRING(20)"); - PlcReadRequest readRequest = builder.build(); - //PlcReadResponse response = readRequest.execute().get(); - CompletableFuture execute = readRequest.execute(); - PlcReadResponse response = execute.get(); - - for (String fieldName : response.getFieldNames()) { - if(response.getResponseCode(fieldName) == PlcResponseCode.OK) { - int numValues = response.getNumberOfValues(fieldName); - PlcValue asPlcValue = response.getAsPlcValue(); - if(numValues == 1) { - Object obj = response.getObject(fieldName); - - logger.info("Value[" + fieldName + "]: " + response.getObject(fieldName)); - } - else { - logger.info("Value[" + fieldName + "]:"); - for(int i = 0; i < numValues; i++) { - logger.info(" - " + response.getObject(fieldName, i)); - } - } - } - else { - logger.error("Error[" + fieldName + "]: " + response.getResponseCode(fieldName).name()); - } - } - - }catch (Exception e){ - logger.error(e.getMessage()); - } - }else { - System.out.println("断线后 不能 read"); - } - }else { - System.out.println("conn 为 connected"); - } - - }catch (Exception e){ - System.out.println(e.getMessage()); - } return R.ok().put("res",1); diff --git a/src/main/java/com/qgs/dc/s7/enums/S7DriveManage.java b/src/main/java/com/qgs/dc/s7/enums/S7DriveManage.java new file mode 100644 index 0000000..c97d1fd --- /dev/null +++ b/src/main/java/com/qgs/dc/s7/enums/S7DriveManage.java @@ -0,0 +1,28 @@ +package com.qgs.dc.s7.enums; + +import org.apache.plc4x.java.PlcDriverManager; +import org.apache.plc4x.java.api.PlcConnection; +import org.apache.plc4x.java.api.exceptions.PlcConnectionException; +import org.apache.plc4x.java.utils.connectionpool.PooledPlcDriverManager; + +/** + * @Author: 蔡翔 + * @Date: 2019/12/5 14:53 + * @Version 1.0 + */ +public enum S7DriveManage { + INSTANCE("driverManagerPool", new PooledPlcDriverManager()) + ; + PlcDriverManager driverManager; + private String desc; + + S7DriveManage(String desc, PooledPlcDriverManager object){ + this.driverManager = object; + this.desc = desc; + } + + public PlcDriverManager getInstance(){ + return this.driverManager; + } + +} diff --git a/src/main/java/com/qgs/dc/s7/service/S7Service.java b/src/main/java/com/qgs/dc/s7/service/S7Service.java index 7979690..222d2e0 100644 --- a/src/main/java/com/qgs/dc/s7/service/S7Service.java +++ b/src/main/java/com/qgs/dc/s7/service/S7Service.java @@ -1,8 +1,13 @@ package com.qgs.dc.s7.service; +import com.qgs.dc.s7.enums.S7DriveManage; import org.apache.plc4x.java.PlcDriverManager; import org.apache.plc4x.java.api.PlcConnection; import org.apache.plc4x.java.api.exceptions.PlcConnectionException; +import org.apache.plc4x.java.api.messages.PlcReadRequest; +import org.apache.plc4x.java.api.messages.PlcReadResponse; +import org.apache.plc4x.java.api.types.PlcResponseCode; +import org.apache.plc4x.java.api.value.PlcValue; import org.apache.plc4x.java.utils.connectionpool.PooledPlcDriverManager; import org.apache.plc4x.java.utils.connectionpool2.CachedDriverManager; import org.eclipse.milo.opcua.sdk.client.OpcUaClient; @@ -10,7 +15,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; +import java.util.concurrent.CompletableFuture; /** * @Desc: "" @@ -27,17 +35,70 @@ public class S7Service { public S7Service(){ - driverManager = new PooledPlcDriverManager(); - + driverManager = S7DriveManage.INSTANCE.getInstance(); } - public Integer addPlc(String plcName,String url) throws PlcConnectionException { - - - return 1; + public boolean addPlc(String url) throws PlcConnectionException { + PlcConnection connection = driverManager.getConnection(url); + return connection.isConnected(); } - public PlcConnection getConnection(String url) throws PlcConnectionException { + //url : s7://192.168.0.200 + //address : %DB10:10.0:STRING(20) + //get 一个或者多个value + public Object getValue(String url,HashMap listAddress) throws PlcConnectionException { + try(PlcConnection conn = driverManager.getConnection(url)) { + if(conn.isConnected()){ + if(conn.getMetadata().canRead()){ + try { + PlcReadRequest.Builder builder = conn.readRequestBuilder(); + for(String key:listAddress.keySet()){ + builder.addItem(key, listAddress.get(key)); + } + + PlcReadRequest readRequest = builder.build(); + CompletableFuture execute = readRequest.execute(); + + PlcReadResponse response = execute.get(); + + for (String fieldName : response.getFieldNames()) { + if(response.getResponseCode(fieldName) == PlcResponseCode.OK) { + int numValues = response.getNumberOfValues(fieldName); + PlcValue asPlcValue = response.getAsPlcValue(); + if(numValues == 1) { + Object obj = response.getObject(fieldName); + logger.info("Value[" + fieldName + "]: " + response.getObject(fieldName)); + return obj; + } + else { + logger.info("Value[" + fieldName + "]:"); + List res = new ArrayList<>(); + for(int i = 0; i < numValues; i++) { + logger.info(" - " + response.getObject(fieldName, i)); + res.add(response.getObject(fieldName,i)); + } + } + } + else { + logger.error("Error[" + fieldName + "]: " + response.getResponseCode(fieldName).name()); + } + } + + }catch (Exception e){ + logger.error(e.getMessage()); + } + }else { + System.out.println("can not read"); + } + }else { + System.out.println("conn not connected"); + } + + }catch (Exception e){ + System.out.println(e.getMessage()); + } + + return driverManager.getConnection(url); } }