From 734747240ce6ebcc24ce6292e792dcad53d8d5c3 Mon Sep 17 00:00:00 2001 From: huangfeng Date: Thu, 5 Dec 2024 10:20:39 +0800 Subject: [PATCH 01/30] =?UTF-8?q?feat:=20i2=E5=90=8C=E6=AD=A5=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=8F=AF=E9=85=8D=E7=BD=AE=E4=B8=80=E6=9D=A1=E6=8B=86?= =?UTF-8?q?=E5=88=86=E6=88=90=E5=A4=9A=E6=9D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/upgrade1128.sql | 4 +- .../java/com/xydl/cac/entity/I2syncField.java | 3 + .../cac/service/impl/DataServiceImpl.java | 2 +- .../xydl/cac/transform/I2DataTransformer.java | 105 ++++++++++++------ 4 files changed, 80 insertions(+), 34 deletions(-) diff --git a/db/upgrade1128.sql b/db/upgrade1128.sql index 07180b1..e6b05b3 100644 --- a/db/upgrade1128.sql +++ b/db/upgrade1128.sql @@ -34,4 +34,6 @@ CREATE TABLE `ied_dl_config` ( `todel` int(11) DEFAULT NULL COMMENT '下载后删除', `active` int(11) DEFAULT NULL COMMENT '0:停用; 1:启用;', PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `i2sync_field` ADD COLUMN `attach` VARCHAR(45) NULL COMMENT 'sensorid尾部附加' AFTER `dest_field_name`; \ No newline at end of file diff --git a/src/main/java/com/xydl/cac/entity/I2syncField.java b/src/main/java/com/xydl/cac/entity/I2syncField.java index 76bb7be..98d1a05 100644 --- a/src/main/java/com/xydl/cac/entity/I2syncField.java +++ b/src/main/java/com/xydl/cac/entity/I2syncField.java @@ -33,4 +33,7 @@ public class I2syncField { @Column(name = "dest_field_name") private String destFieldName; + @Column(name = "attach") + private String attach; + } \ No newline at end of file diff --git a/src/main/java/com/xydl/cac/service/impl/DataServiceImpl.java b/src/main/java/com/xydl/cac/service/impl/DataServiceImpl.java index 5619341..29fa793 100644 --- a/src/main/java/com/xydl/cac/service/impl/DataServiceImpl.java +++ b/src/main/java/com/xydl/cac/service/impl/DataServiceImpl.java @@ -244,7 +244,7 @@ public class DataServiceImpl implements DataService { @Override public List> getLatestData(String tableName, Integer devId, List points, Date start) throws Exception { ConditionModel model = new ConditionModel(); - model.setPageSize(1000); + model.setPageSize(500); model.setPageNum(1); model.setStartTime(start); model.setExcludeStartTime(true); diff --git a/src/main/java/com/xydl/cac/transform/I2DataTransformer.java b/src/main/java/com/xydl/cac/transform/I2DataTransformer.java index f355a8e..28bd9ba 100644 --- a/src/main/java/com/xydl/cac/transform/I2DataTransformer.java +++ b/src/main/java/com/xydl/cac/transform/I2DataTransformer.java @@ -1,6 +1,5 @@ package com.xydl.cac.transform; -import com.alibaba.excel.util.StringUtils; import com.xydl.cac.entity.*; import com.xydl.cac.model.StaticVariable; import com.xydl.cac.model.i2sync.Attr; @@ -9,12 +8,10 @@ import com.xydl.cac.model.i2sync.Monitordata; import com.xydl.cac.model.i2sync.Request; import com.xydl.cac.util.DateUtil; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; @Component @Slf4j @@ -34,23 +31,42 @@ public class I2DataTransformer { } } + LinkedHashMap> fieldMap = this.sortFieldList(fieldList); + List nodeList = new ArrayList<>(); for (Map map : dataList) { - String date = (String) map.get("acquisitionTime"); - Datanode node = new Datanode(); - node.setSensorid(sensor.getSensorCode()); - node.setEquipmentid(sensor.getEquipmentId()); - node.setTimestamp(date); - List attrs = new ArrayList<>(); - Attr attr = new Attr(); - attr.setName("Phase"); - attr.setValue(sensor.getPhase()); - attr.setAlarm("FALSE"); - attrs.add(attr); - for (I2syncField field : fieldList) { - Object value = map.get(field.getFieldName()); - attr = new Attr(); + Iterator fit = fieldMap.keySet().iterator(); + while (it.hasNext()) { + String attach = fit.next(); + List fieldListNew = fieldMap.get(attach); + + Datanode node = this.buildDatanode(sensor, config.getTypeCode(), attach, + fieldListNew, map, ruleList); + if (node != null) { + nodeList.add(node); + record.setLastDTime(DateUtil.parse(node.getTimestamp())); + } + } + } + + Monitordata monitordata = new Monitordata(); + monitordata.setCacid(sensor.getSensorCode()); + monitordata.setDatanodenum(nodeList.size()); + monitordata.setDatanode(nodeList); + Request request = new Request(); + request.setMonitordata(monitordata); + return request; + } + + private Datanode buildDatanode(NSensor sensor, String typeCode, String attach, + List fieldList, Map dataMap, + List ruleList) { + List attrs = new ArrayList<>(); + for (I2syncField field : fieldList) { + Object value = dataMap.get(field.getFieldName()); + if (value != null) { + Attr attr = new Attr(); attr.setName(field.getDestFieldName()); attr.setValue(String.valueOf(value)); if (this.triggerRule(ruleList, field.getFieldName(), value)) { @@ -58,24 +74,49 @@ public class I2DataTransformer { } else { attr.setAlarm("FALSE"); } - if (StringUtils.isBlank(node.getType())) { - node.setType(config.getTypeCode()); - } attrs.add(attr); } - node.setAttr(attrs); + } + if (attrs.size() < 1) { + return null; + } + String date = (String) dataMap.get("acquisitionTime"); + Datanode node = new Datanode(); + node.setType(typeCode); + node.setTimestamp(date); + node.setAttr(attrs); - nodeList.add(node); - record.setLastDTime(DateUtil.parse(date)); + Attr attr = new Attr(); + attr.setName("Phase"); + attr.setAlarm("FALSE"); + attrs.add(attr); + if (StringUtils.isBlank(attach)) { + attr.setValue(sensor.getPhase()); + node.setSensorid(sensor.getSensorCode()); + node.setEquipmentid(sensor.getEquipmentId()); + } else { + attr.setValue(""); + node.setSensorid(sensor.getSensorCode() + attach); + node.setEquipmentid(sensor.getEquipmentId() + attach); } + return node; + } - Monitordata monitordata = new Monitordata(); - monitordata.setCacid(sensor.getSensorCode()); - monitordata.setDatanodenum(nodeList.size()); - monitordata.setDatanode(nodeList); - Request request = new Request(); - request.setMonitordata(monitordata); - return request; + private LinkedHashMap> sortFieldList(List fieldList) { + LinkedHashMap> map = new LinkedHashMap<>(); + for (I2syncField item : fieldList) { + String attach = item.getAttach(); + if (attach == null) { + attach = ""; + } + List list = map.get(attach); + if (list == null) { + list = new ArrayList<>(); + map.put(attach, list); + } + list.add(item); + } + return map; } private boolean triggerRule(List ruleList, String fieldName, Object value) { From 1ae46c69aeb547e7cf9a57322a41b91804cba33a Mon Sep 17 00:00:00 2001 From: huangfeng Date: Thu, 5 Dec 2024 13:36:14 +0800 Subject: [PATCH 02/30] =?UTF-8?q?feat:=20=E9=87=87=E9=9B=86=E7=9A=84?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=B9=9F=E6=9B=B4=E6=96=B0=E5=88=B0=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/xydl/cac/iec/IEDCollectService.java | 57 ++++++------------- src/main/java/com/xydl/cac/iec/IecClient.java | 11 +++- .../com/xydl/cac/iec/RealTimeDataService.java | 15 ++--- .../com/xydl/cac/model/StaticVariable.java | 46 +++++++++++++++ 4 files changed, 76 insertions(+), 53 deletions(-) diff --git a/src/main/java/com/xydl/cac/iec/IEDCollectService.java b/src/main/java/com/xydl/cac/iec/IEDCollectService.java index 5d81d77..ba525e6 100644 --- a/src/main/java/com/xydl/cac/iec/IEDCollectService.java +++ b/src/main/java/com/xydl/cac/iec/IEDCollectService.java @@ -116,23 +116,30 @@ public class IEDCollectService { } private void collectAndSaveValue(String paramindexNew, String paramindexT, String fc, Rptparamindex rpt) throws Exception { - String value = iecClient.getValue(paramindexNew, fc); - String time = iecClient.getValue(paramindexT, fc); + // 更新关联关系缓存 + String key = paramindexNew + "_" + fc; + String value = rpt.getEqmid() + "," + rpt.getColname(); + StaticVariable.paramRelationMap.put(key, value); + key = paramindexT + "_" + fc; + value = rpt.getEqmid() + ",acquisitionTime"; + StaticVariable.paramRelationMap.put(key, value); + + // 采集数据 + BasicDataAttribute valueNode = iecClient.getNode(paramindexNew, fc); + BasicDataAttribute timeNode = iecClient.getNode(paramindexT, fc); + value = valueNode.getValueString(); + String time = timeNode.getValueString(); log.info("采集到" + fc + " " + paramindexNew + "=" + value + ", t=" + time); time = DateUtil.fromZoneUTCToLocal(time); time = this.makeSameTime(rpt.getEqmid(), time); _dataService.insertData(rpt.getTablename(), rpt.getEqmid(), time, rpt.getColname(), value); // 更新最新数据缓存 - updateLastData(rpt.getEqmid(), rpt.getColname(), value, time); + StaticVariable.updateLastData(rpt.getEqmid(), rpt.getColname(), value, time); - // 更新关联关系缓存 - String key = paramindexNew + "_" + fc; - value = rpt.getEqmid() + "," + rpt.getColname(); - StaticVariable.paramRelationMap.put(key, value); - key = paramindexT + "_" + fc; - value = rpt.getEqmid() + ",acquisitionTime"; - StaticVariable.paramRelationMap.put(key, value); + // 更新服务端 + StaticVariable.updateServerNodeValue(valueNode); + StaticVariable.updateServerNodeValue(timeNode); } private String makeSameTime(Integer eqmid, String time) { @@ -229,34 +236,4 @@ public class IEDCollectService { } } - public static void updateLastData(Integer eqmid, String colname, String value, String time) { - HashMap map = StaticVariable.sensorLastDataMap.get(eqmid); - if (map == null) { - map = new HashMap<>(); - StaticVariable.sensorLastDataMap.put(eqmid, map); - } - map.put(colname, value); - if (time != null) { - map.put("acquisitionTime", time); - } - } - - public static void updateLastData(BasicDataAttribute bda) { - try { - String ref = bda.getReference().toString(); - String key = ref + "_" + bda.getFc().toString(); - if (StaticVariable.paramRelationMap.containsKey(key)) { - String value = StaticVariable.paramRelationMap.get(key); - String[] str = value.split(","); - Integer eqmid = Integer.parseInt(str[0]); - String colname = str[1]; - value = bda.getValueString(); - if ("acquisitionTime".equals(colname)) { - value = DateUtil.fromZoneUTCToLocal(value); - } - updateLastData(eqmid, colname, value, null); - } - } catch (Exception ignore) { - } - } } diff --git a/src/main/java/com/xydl/cac/iec/IecClient.java b/src/main/java/com/xydl/cac/iec/IecClient.java index 025aeca..bb76c7a 100644 --- a/src/main/java/com/xydl/cac/iec/IecClient.java +++ b/src/main/java/com/xydl/cac/iec/IecClient.java @@ -95,14 +95,21 @@ public class IecClient implements ClientEventListener { } public String getValue(String paramindex, String fc) throws Exception { + BasicDataAttribute node = this.getNode(paramindex, fc); + if (node != null) { + return node.getValueString(); + } + return null; + } + + public BasicDataAttribute getNode(String paramindex, String fc) throws Exception { FcModelNode node = (FcModelNode) serverModel.findModelNode(paramindex, Fc.valueOf(fc)); if (node == null) { throw new BusinessException("icd文件里未找到该节点, " + fc + " " + paramindex); } clientAssociation.getDataValues(node); if (node instanceof BasicDataAttribute) { - String value = ((BasicDataAttribute) node).getValueString(); - return value; + return (BasicDataAttribute) node; } return null; } diff --git a/src/main/java/com/xydl/cac/iec/RealTimeDataService.java b/src/main/java/com/xydl/cac/iec/RealTimeDataService.java index 65d5378..f12f63c 100644 --- a/src/main/java/com/xydl/cac/iec/RealTimeDataService.java +++ b/src/main/java/com/xydl/cac/iec/RealTimeDataService.java @@ -131,14 +131,16 @@ public class RealTimeDataService { for (ModelNode child : fcnode.getChildren()) { if (child instanceof BasicDataAttribute) { BasicDataAttribute bda = (BasicDataAttribute) child; - processBdaNodeValue(bda); + StaticVariable.updateServerNodeValue(bda); + StaticVariable.updateLastData(bda); } else if (child instanceof ConstructedDataAttribute) { ConstructedDataAttribute cda = (ConstructedDataAttribute) child; if (!CollectionUtils.isEmpty(cda.getChildren())) { for (ModelNode cchild : cda.getChildren()) { if (cchild instanceof BasicDataAttribute) { BasicDataAttribute bda = (BasicDataAttribute) cchild; - processBdaNodeValue(bda); + StaticVariable.updateServerNodeValue(bda); + StaticVariable.updateLastData(bda); } } } @@ -148,13 +150,4 @@ public class RealTimeDataService { } } - private static void processBdaNodeValue(BasicDataAttribute bda) { - Iterator it = StaticVariable.iecServerMap.keySet().iterator(); - while (it.hasNext()) { - Integer key = it.next(); - IecServer iecServer = StaticVariable.iecServerMap.get(key); - iecServer.updateBda(bda); - } - IEDCollectService.updateLastData(bda); - } } diff --git a/src/main/java/com/xydl/cac/model/StaticVariable.java b/src/main/java/com/xydl/cac/model/StaticVariable.java index 7789776..a890995 100644 --- a/src/main/java/com/xydl/cac/model/StaticVariable.java +++ b/src/main/java/com/xydl/cac/model/StaticVariable.java @@ -1,13 +1,16 @@ package com.xydl.cac.model; +import com.beanit.iec61850bean.BasicDataAttribute; import com.xydl.cac.entity.Jg; import com.xydl.cac.entity.ModevType; import com.xydl.cac.entity.WarnRule; import com.xydl.cac.entity.Zsb; import com.xydl.cac.iec.IecClient; import com.xydl.cac.iec.IecServer; +import com.xydl.cac.util.DateUtil; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.concurrent.ConcurrentHashMap; @@ -34,4 +37,47 @@ public class StaticVariable { Thread.sleep(1000); } } + + // 更新服务端 + public static void updateServerNodeValue(BasicDataAttribute bda) { + Iterator it = StaticVariable.iecServerMap.keySet().iterator(); + while (it.hasNext()) { + Integer key = it.next(); + IecServer iecServer = StaticVariable.iecServerMap.get(key); + iecServer.updateBda(bda); + } + } + + // 更新最新数据缓存 + public static void updateLastData(Integer eqmid, String colname, String value, String time) { + HashMap map = StaticVariable.sensorLastDataMap.get(eqmid); + if (map == null) { + map = new HashMap<>(); + StaticVariable.sensorLastDataMap.put(eqmid, map); + } + map.put(colname, value); + if (time != null) { + map.put("acquisitionTime", time); + } + } + + // 更新最新数据缓存 + public static void updateLastData(BasicDataAttribute bda) { + try { + String ref = bda.getReference().toString(); + String key = ref + "_" + bda.getFc().toString(); + if (StaticVariable.paramRelationMap.containsKey(key)) { + String value = StaticVariable.paramRelationMap.get(key); + String[] str = value.split(","); + Integer eqmid = Integer.parseInt(str[0]); + String colname = str[1]; + value = bda.getValueString(); + if ("acquisitionTime".equals(colname)) { + value = DateUtil.fromZoneUTCToLocal(value); + } + updateLastData(eqmid, colname, value, null); + } + } catch (Exception ignore) { + } + } } From 72f65ab4cb95b4b9152e75a6493b9851cdcd3c11 Mon Sep 17 00:00:00 2001 From: huangfeng Date: Thu, 5 Dec 2024 14:26:59 +0800 Subject: [PATCH 03/30] =?UTF-8?q?feat:=20=E8=B0=83=E6=95=B4i2=E5=AF=BC?= =?UTF-8?q?=E5=87=BA=E7=B1=BB=E5=9E=8B=E6=95=B0=E6=8D=AExml=E9=A2=84?= =?UTF-8?q?=E8=A7=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xydl/cac/controller/I2syncController.java | 61 +++++++++---------- .../xydl/cac/transform/I2DataTransformer.java | 2 +- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/src/main/java/com/xydl/cac/controller/I2syncController.java b/src/main/java/com/xydl/cac/controller/I2syncController.java index 3542d3d..84f4fcf 100644 --- a/src/main/java/com/xydl/cac/controller/I2syncController.java +++ b/src/main/java/com/xydl/cac/controller/I2syncController.java @@ -2,10 +2,7 @@ package com.xydl.cac.controller; import com.alibaba.excel.util.StringUtils; import com.xydl.cac.adapter.BusiAdapter; -import com.xydl.cac.entity.I2syncConfig; -import com.xydl.cac.entity.I2syncField; -import com.xydl.cac.entity.I2syncRecord; -import com.xydl.cac.entity.ModevType; +import com.xydl.cac.entity.*; import com.xydl.cac.exception.BusinessException; import com.xydl.cac.model.Response; import com.xydl.cac.model.i2sync.Attr; @@ -13,7 +10,9 @@ import com.xydl.cac.model.i2sync.Datanode; import com.xydl.cac.model.i2sync.Monitordata; import com.xydl.cac.model.i2sync.Request; import com.xydl.cac.service.I2syncService; +import com.xydl.cac.service.ModevTypePointService; import com.xydl.cac.service.ModevTypeService; +import com.xydl.cac.transform.I2DataTransformer; import com.xydl.cac.util.DateUtil; import com.xydl.cac.util.JSONUtil; import io.swagger.annotations.Api; @@ -37,7 +36,11 @@ public class I2syncController extends BasicController { @Resource ModevTypeService modevTypeService; @Resource + ModevTypePointService modevTypePointService; + @Resource BusiAdapter busiAdapter; + @Resource + I2DataTransformer dataTransformer; @GetMapping("status") @ApiOperation("查询状态") @@ -107,37 +110,33 @@ public class I2syncController extends BasicController { @ApiOperation("预览xml结构") public Response prewXml(Integer modevtypeId) throws Exception { ModevType modevType = modevTypeService.detail(modevtypeId); + List points = modevTypePointService.listAll(modevtypeId); List fieldList = service.listFieldConfig(modevType.getTablename()); - List attrs = new ArrayList<>(); - Attr attr = new Attr(); - attr.setName("Phase"); - attr.setValue("A相"); - attr.setAlarm("FALSE"); - attrs.add(attr); - for (I2syncField field : fieldList) { - attr = new Attr(); - attr.setName(field.getDestFieldName()); - attr.setValue("100.0"); - attr.setAlarm("FALSE"); - attrs.add(attr); + NSensor sensor = NSensor.builder() + .id(12) + .typeId(modevtypeId) + .sensorCode("HNHFT001Q1W000104") + .equipmentId("HNHFT001Q1W000104") + .phase("ABC相") + .build(); + I2syncRecord record = I2syncRecord.builder() + .build(); + I2syncConfig config = I2syncConfig.builder() + .typeCode(modevType.getTypeCode()) + .build(); + List> dataList = new ArrayList<>(); + Map map = new HashMap<>(); + map.put("acquisitionTime", DateUtil.format(new Date())); + for (ModevTypePoint point : points) { + map.put(point.getField(), 1.25); } - Datanode node = new Datanode(); - node.setSensorid("HNHFT001Q1W000104"); - node.setType(modevType.getTypeCode()); - node.setEquipmentid("HNHFT001Q1W000104"); - node.setTimestamp(DateUtil.format(new Date())); - node.setAttr(attrs); - List nodeList = new ArrayList<>(); - nodeList.add(node); - Monitordata monitordata = new Monitordata(); - monitordata.setCacid("HNHFT001Q1W000104"); - monitordata.setDatanodenum(1); - monitordata.setDatanode(nodeList); - Request request = new Request(); - request.setMonitordata(monitordata); + dataList.add(map); + + Request request = dataTransformer.transform(sensor, record, config, fieldList, dataList); + String xml = JSONUtil.object2Xml(request); Response resp = Response.success(xml); - if (StringUtils.isBlank(node.getType())) { + if (StringUtils.isBlank(modevType.getTypeCode())) { resp.setWarnMsg("该类型还未配置对应的类型编码将导致type为空"); } return resp; diff --git a/src/main/java/com/xydl/cac/transform/I2DataTransformer.java b/src/main/java/com/xydl/cac/transform/I2DataTransformer.java index 28bd9ba..ee11093 100644 --- a/src/main/java/com/xydl/cac/transform/I2DataTransformer.java +++ b/src/main/java/com/xydl/cac/transform/I2DataTransformer.java @@ -37,7 +37,7 @@ public class I2DataTransformer { for (Map map : dataList) { Iterator fit = fieldMap.keySet().iterator(); - while (it.hasNext()) { + while (fit.hasNext()) { String attach = fit.next(); List fieldListNew = fieldMap.get(attach); From 3f1d8eab845bb040f9096c77a26ad70b54eac202 Mon Sep 17 00:00:00 2001 From: huangfeng Date: Thu, 5 Dec 2024 15:36:13 +0800 Subject: [PATCH 04/30] =?UTF-8?q?perf:=20=E8=BD=AC=E6=8D=A2=E9=80=9A?= =?UTF-8?q?=E7=9A=84=E5=92=8C=E4=B8=8D=E9=80=9A=E7=9A=84=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E5=8F=98=E5=8C=96=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cac/controller/IecServerController.java | 10 +++++++--- .../xydl/cac/controller/TestController.java | 18 ++++++++++++++++++ src/main/java/com/xydl/cac/iec/IecServer.java | 7 +++++-- .../com/xydl/cac/model/StaticVariable.java | 2 ++ .../service/impl/IcdTransformServiceImpl.java | 4 ---- 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/xydl/cac/controller/IecServerController.java b/src/main/java/com/xydl/cac/controller/IecServerController.java index 7997a2a..23fc49b 100644 --- a/src/main/java/com/xydl/cac/controller/IecServerController.java +++ b/src/main/java/com/xydl/cac/controller/IecServerController.java @@ -7,9 +7,9 @@ import com.xydl.cac.entity.constants.Constants; import com.xydl.cac.exception.BusinessException; import com.xydl.cac.iec.IecServerService; import com.xydl.cac.model.Response; +import com.xydl.cac.model.StaticVariable; import com.xydl.cac.service.IcdFileConfigService; import com.xydl.cac.service.IcdTransformService; -import com.xydl.cac.service.impl.IcdTransformServiceImpl; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; @@ -128,11 +128,15 @@ public class IecServerController extends BasicController { public Response> listTransform() throws Exception { List result = transformService.listTransform(); for (IcdTransform item : result) { - if (IcdTransformServiceImpl.rptFromActiveMap.containsKey(item.getRptFrom())) { + if (StaticVariable.rptFromActiveMap.containsKey(item.getRptFrom())) { item.setFromActive(true); + } else { + item.setFromActive(false); } - if (IcdTransformServiceImpl.rptToActiveMap.containsKey(item.getRptTo())) { + if (StaticVariable.rptToActiveMap.containsKey(item.getRptTo())) { item.setToActive(true); + } else { + item.setToActive(false); } } return Response.success(result); diff --git a/src/main/java/com/xydl/cac/controller/TestController.java b/src/main/java/com/xydl/cac/controller/TestController.java index d0c881d..e2a619d 100644 --- a/src/main/java/com/xydl/cac/controller/TestController.java +++ b/src/main/java/com/xydl/cac/controller/TestController.java @@ -57,6 +57,24 @@ public class TestController extends BasicController { return Response.success(StaticVariable.sensorLastDataMap); } + @GetMapping("iecServerMap") + @ApiOperation("iecServerMap") + public Response iecServerMap() { + return Response.success(StaticVariable.iecServerMap); + } + + @GetMapping("rptFromActiveMap") + @ApiOperation("rptFromActiveMap") + public Response rptFromActiveMap() { + return Response.success(StaticVariable.rptFromActiveMap); + } + + @GetMapping("rptToActiveMap") + @ApiOperation("rptToActiveMap") + public Response rptToActiveMap() { + return Response.success(StaticVariable.rptToActiveMap); + } + @GetMapping("clearMap") @ApiOperation("clearMap") public void clearMap() { diff --git a/src/main/java/com/xydl/cac/iec/IecServer.java b/src/main/java/com/xydl/cac/iec/IecServer.java index 86a8e4f..59fd140 100644 --- a/src/main/java/com/xydl/cac/iec/IecServer.java +++ b/src/main/java/com/xydl/cac/iec/IecServer.java @@ -2,6 +2,7 @@ package com.xydl.cac.iec; import com.beanit.iec61850bean.*; import com.xydl.cac.entity.IcdTransform; +import com.xydl.cac.model.StaticVariable; import com.xydl.cac.service.IcdTransformService; import com.xydl.cac.service.impl.IcdTransformServiceImpl; import lombok.extern.slf4j.Slf4j; @@ -57,7 +58,7 @@ public class IecServer implements ServerEventListener { if (ref.startsWith(item.getRptFrom())) { ref = ref.replace(item.getRptFrom(), item.getRptTo()); rptTo = item.getRptTo(); - IcdTransformServiceImpl.rptFromActiveMap.put(item.getRptFrom(), "1"); + StaticVariable.rptFromActiveMap.put(item.getRptFrom(), "1"); break; } } @@ -67,8 +68,10 @@ public class IecServer implements ServerEventListener { node.setValueFrom(bda); List bdas = new ArrayList<>(); bdas.add(node); - IcdTransformServiceImpl.rptToActiveMap.put(rptTo, "1"); + StaticVariable.rptToActiveMap.put(rptTo, "1"); serverSap.setValues(bdas); + } else { + StaticVariable.rptToActiveMap.remove(rptTo); } } diff --git a/src/main/java/com/xydl/cac/model/StaticVariable.java b/src/main/java/com/xydl/cac/model/StaticVariable.java index a890995..74f9b90 100644 --- a/src/main/java/com/xydl/cac/model/StaticVariable.java +++ b/src/main/java/com/xydl/cac/model/StaticVariable.java @@ -22,6 +22,8 @@ public class StaticVariable { public static HashMap doneWarnMap = new HashMap<>(); public static HashMap realTimeClientMap = new HashMap<>(); public static int shutdown = 0; + public static HashMap rptFromActiveMap = new HashMap<>(); + public static HashMap rptToActiveMap = new HashMap<>(); public static HashMap unit_Cache = new HashMap<>(); public static List modevType_Cache = null; diff --git a/src/main/java/com/xydl/cac/service/impl/IcdTransformServiceImpl.java b/src/main/java/com/xydl/cac/service/impl/IcdTransformServiceImpl.java index f4eadc1..3799fec 100644 --- a/src/main/java/com/xydl/cac/service/impl/IcdTransformServiceImpl.java +++ b/src/main/java/com/xydl/cac/service/impl/IcdTransformServiceImpl.java @@ -11,8 +11,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; -import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Optional; @@ -24,8 +22,6 @@ public class IcdTransformServiceImpl implements IcdTransformService { @Resource IcdTransformRepository transformRepository; - public static HashMap rptFromActiveMap = new HashMap<>(); - public static HashMap rptToActiveMap = new HashMap<>(); @Override @CacheEvict(cacheNames = {"listTransform"}, allEntries = true) From b2c80558f0dce3c028f5db7289fdc1ce39ae588d Mon Sep 17 00:00:00 2001 From: liuguijing <123456> Date: Mon, 9 Dec 2024 09:55:18 +0800 Subject: [PATCH 05/30] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=A1=AC=E6=8E=A5?= =?UTF-8?q?=E7=82=B9=E7=BB=A7=E7=94=B5=E5=99=A8=E4=B8=B2=E5=8F=A3=E9=80=9A?= =?UTF-8?q?=E8=AE=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 7 + .../xydl/cac/controller/TestController.java | 56 +++ .../com/xydl/cac/model/StaticVariable.java | 4 + .../xydl/cac/service/SerialPortService.java | 16 + .../xydl/cac/service/impl/DataListener.java | 39 ++ .../service/impl/SerialPortServiceImpl.java | 82 ++++ src/main/java/com/xydl/cac/util/ByteUtil.java | 377 ++++++++++++++++++ 7 files changed, 581 insertions(+) create mode 100644 src/main/java/com/xydl/cac/service/SerialPortService.java create mode 100644 src/main/java/com/xydl/cac/service/impl/DataListener.java create mode 100644 src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java create mode 100644 src/main/java/com/xydl/cac/util/ByteUtil.java diff --git a/pom.xml b/pom.xml index 82485c4..6ce58cc 100644 --- a/pom.xml +++ b/pom.xml @@ -193,6 +193,13 @@ asn1bean 1.14.0 + + + + com.fazecast + jSerialComm + 2.6.2 + diff --git a/src/main/java/com/xydl/cac/controller/TestController.java b/src/main/java/com/xydl/cac/controller/TestController.java index d0c881d..ad69e67 100644 --- a/src/main/java/com/xydl/cac/controller/TestController.java +++ b/src/main/java/com/xydl/cac/controller/TestController.java @@ -1,8 +1,10 @@ package com.xydl.cac.controller; +import com.fazecast.jSerialComm.SerialPort; import com.xydl.cac.model.Response; import com.xydl.cac.model.StaticVariable; import com.xydl.cac.service.IcdFileConfigService; +import com.xydl.cac.service.SerialPortService; import com.xydl.cac.socket.WebSocketServer; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -10,8 +12,11 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.socket.WebSocketSession; import javax.annotation.Resource; +import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -26,6 +31,9 @@ public class TestController extends BasicController { @Resource WebSocketServer webSocketServer; + @Resource + SerialPortService serialPortService; + @GetMapping("compare61850") @ApiOperation("比对61850的不同点") public Response> compare61850() throws Exception { @@ -63,4 +71,52 @@ public class TestController extends BasicController { StaticVariable.sensorLastDataMap.clear(); StaticVariable.paramRelationMap.clear(); } + + @GetMapping("/discover") + public Response> discoverSerialPort() { + List list1 = serialPortService.discoverSerialPort(); + StaticVariable.serialPorts = list1; + List list = new ArrayList<>(); + list1.forEach(item -> { + list.add(item.getSystemPortName()); + }); + Response> response = Response.success(list); + return response; + } + + @GetMapping("/open") + public Response openSerialPort(String portname) { + for (SerialPort port : StaticVariable.serialPorts) { + if (port.getSystemPortName().equals(portname)) { + return Response.success(serialPortService.openSerialPort(port)); + } + } + return Response.fail("Failed to find port "); + } + + @GetMapping("/send") + public String sendData(int data,String portname) throws IOException { + //发送数据注意,提前与接收设备沟通好协议,发送什么样类型的数据设备才可以进行响应,否则设备无响应 + for (SerialPort port : StaticVariable.serialPorts) { + if (port.getSystemPortName().equals(portname)) { + if (data == 0) { + serialPortService.sendData(port, false); + } else { + serialPortService.sendData(port, true); + } + + } + } + return "Data sent>>>"; + } + + @GetMapping("/close") + public String closeSerialPort(String portname) { + for (SerialPort port : StaticVariable.serialPorts) { + if (port.getSystemPortName().equals(portname)) { + serialPortService.closeSerialPort(port,portname); + } + } + return "Serial port closed"; + } } diff --git a/src/main/java/com/xydl/cac/model/StaticVariable.java b/src/main/java/com/xydl/cac/model/StaticVariable.java index 7789776..71e43f4 100644 --- a/src/main/java/com/xydl/cac/model/StaticVariable.java +++ b/src/main/java/com/xydl/cac/model/StaticVariable.java @@ -1,5 +1,6 @@ package com.xydl.cac.model; +import com.fazecast.jSerialComm.SerialPort; import com.xydl.cac.entity.Jg; import com.xydl.cac.entity.ModevType; import com.xydl.cac.entity.WarnRule; @@ -7,6 +8,7 @@ import com.xydl.cac.entity.Zsb; import com.xydl.cac.iec.IecClient; import com.xydl.cac.iec.IecServer; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.concurrent.ConcurrentHashMap; @@ -26,6 +28,8 @@ public class StaticVariable { public static List zsb_Cache = null; public static ConcurrentHashMap rule_Cache = new ConcurrentHashMap<>(); + public static List serialPorts = new ArrayList<>(); + public static void wait(int seconds) throws InterruptedException { for (int i = 0; i < seconds; i++) { if (shutdown == 1) { diff --git a/src/main/java/com/xydl/cac/service/SerialPortService.java b/src/main/java/com/xydl/cac/service/SerialPortService.java new file mode 100644 index 0000000..eb6bfbb --- /dev/null +++ b/src/main/java/com/xydl/cac/service/SerialPortService.java @@ -0,0 +1,16 @@ +package com.xydl.cac.service; + +import com.fazecast.jSerialComm.SerialPort; + +import java.io.IOException; +import java.util.List; + +public interface SerialPortService { + List discoverSerialPort(); + + boolean closeSerialPort(SerialPort port, String portname); + + Boolean openSerialPort(SerialPort port); + + void sendData(SerialPort port, boolean data) throws IOException; +} diff --git a/src/main/java/com/xydl/cac/service/impl/DataListener.java b/src/main/java/com/xydl/cac/service/impl/DataListener.java new file mode 100644 index 0000000..4306f3e --- /dev/null +++ b/src/main/java/com/xydl/cac/service/impl/DataListener.java @@ -0,0 +1,39 @@ +package com.xydl.cac.service.impl; + +import com.fazecast.jSerialComm.SerialPort; +import com.fazecast.jSerialComm.SerialPortDataListener; +import com.fazecast.jSerialComm.SerialPortEvent; +import com.xydl.cac.util.ByteUtil; +import lombok.SneakyThrows; +import org.apache.commons.compress.utils.ByteUtils; +import org.springframework.web.socket.TextMessage; +import org.springframework.web.socket.WebSocketSession; + +public class DataListener implements SerialPortDataListener { + private WebSocketSession session; + private String portName; + + //通过websocket打开监听设备的时候绑定session返回给前端数据 + public DataListener(String portName) { + this.portName = portName; + } + + @Override + public int getListeningEvents() { + return SerialPort.LISTENING_EVENT_DATA_WRITTEN; + } + + @SneakyThrows + @Override + public void serialEvent(SerialPortEvent event) { + String hexString = ""; + if (event.getEventType() == SerialPort.LISTENING_EVENT_DATA_WRITTEN) { + byte[] newData = new byte[event.getSerialPort().bytesAvailable()]; + int numRead = event.getSerialPort().readBytes(newData, newData.length); + hexString = ByteUtil.bytesToHexString(newData); + } + System.out.println("监听接收串口" + portName + ";数据:" + hexString); + session.sendMessage(new TextMessage(hexString)); + } +} + diff --git a/src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java b/src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java new file mode 100644 index 0000000..3365feb --- /dev/null +++ b/src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java @@ -0,0 +1,82 @@ +package com.xydl.cac.service.impl; + +import com.fazecast.jSerialComm.SerialPort; +import com.xydl.cac.service.SerialPortService; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +@Service +public class SerialPortServiceImpl implements SerialPortService { + public List serialPortList; + + @Override + public List discoverSerialPort() { + serialPortList = Arrays.asList(SerialPort.getCommPorts()); + // 遍历串口列表并打印每个串口的名称 + for (SerialPort port : serialPortList) { + System.out.println("获取串口: " + port.getSystemPortName()); + } + return serialPortList; + } + + //关闭串口 + @Override + public boolean closeSerialPort(SerialPort port, String portname) { + for (SerialPort portItem : serialPortList) { + if (portItem.getSystemPortName().equals(portname)) { + if (portItem != null) { + System.out.println("断开端口" + portItem.getSystemPortName() + "连接"); + return portItem.closePort(); + } + } + } + return false; + } + + + //发送数据到串口 + @Override + public void sendData(SerialPort port, boolean data) throws IOException { + byte[] buffer2; + if (data) { + buffer2 = new byte[]{00, (byte) 0xf1, (byte) 0xff}; + } else { + buffer2 = new byte[]{00, (byte) 0x01, (byte) 0xff}; + } + port.writeBytes(buffer2, buffer2.length); + } + + + @Override + public Boolean openSerialPort(SerialPort port) { + if (port.getSystemPortName().equals("COM6")) { + int baudRate = 9600; // 波特率 + int parity = SerialPort.EVEN_PARITY; // 校验位 + int dataBits = 8; // 数据位 + int stopBits = SerialPort.ONE_STOP_BIT; // 停止位 + try { + boolean setComResult = port.setComPortParameters(baudRate, dataBits, stopBits, parity); // 设置参数 + boolean setComTimes = port.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 20000, 0); // 设置超时 + if (setComResult && setComTimes) { + port.addDataListener(new DataListener(port.getSystemPortName())); + } + boolean b = port.openPort(); + if (b) { + return true; + } else { + return false; + } + } catch (Exception e) { + e.printStackTrace(); +// return ResponseResult.getErrorResult("Failed to open port " + port.getSystemPortName() + e.getMessage().toString()); + return false; + } +// return ResponseResult.getSuccessResult("COM10 Serial port open"); + } +// return ResponseResult.getErrorResult("Failed to find port " + port.getSystemPortName()); + return false; + } +} diff --git a/src/main/java/com/xydl/cac/util/ByteUtil.java b/src/main/java/com/xydl/cac/util/ByteUtil.java new file mode 100644 index 0000000..244bddf --- /dev/null +++ b/src/main/java/com/xydl/cac/util/ByteUtil.java @@ -0,0 +1,377 @@ +package com.xydl.cac.util; + +import java.io.IOException; +import java.math.BigInteger; +import java.net.Socket; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.springframework.util.StringUtils; + +public class ByteUtil { + public static byte[] uintToBytes(long value) { + byte[] src = new byte[4]; + src[3] = ((byte) (int) (value >> 24 & 0xFF)); + src[2] = ((byte) (int) (value >> 16 & 0xFF)); + src[1] = ((byte) (int) (value >> 8 & 0xFF)); + src[0] = ((byte) (int) (value & 0xFF)); + return src; + } + + public static byte[] uint16ToBytes(int value) { + byte[] src = new byte[2]; + src[1] = ((byte) (value >> 8 & 0xFF)); + src[0] = ((byte) (value & 0xFF)); + return src; + } + + public static byte[] uint8ToBytes(short value) { + byte[] src = new byte[1]; + src[0] = ((byte) (value & 0xFF)); + return src; + } + + /** + * ascii 转 十六进制 + * + * @param str + * @return + */ + public static String convertStringToHex(String str) { + + char[] chars = str.toCharArray(); + + StringBuffer hex = new StringBuffer(); + for (int i = 0; i < chars.length; i++) { + hex.append(Integer.toHexString((int) chars[i])); + } + + return hex.toString(); + } + + /** + * 十六进制转 ascii + * + * @param hex + * @return + */ + public static String convertHexToString(String hex) { + + StringBuilder sb = new StringBuilder(); + StringBuilder temp = new StringBuilder(); + + // 49204c6f7665204a617661 split into two characters 49, 20, 4c... + for (int i = 0; i < hex.length() - 1; i += 2) { + + // grab the hex in pairs + String output = hex.substring(i, (i + 2)); + // convert hex to decimal + int decimal = Integer.parseInt(output, 16); + // convert the decimal to character + sb.append((char) decimal); + + temp.append(decimal); + } + + return sb.toString(); + } + + /** + * 十六进制字符串高低位互换 + *

+ * 如:12345678 -> 78563412 + * 00 5f 8d c2 + * c28d5f00 + * + * @param str + * @return float + */ + public static float hexStrTofloat(String str) { + try { + String s = str.substring(6, 8) + str.substring(4, 6) + str.substring(2, 4) + str.substring(0, 2); + return Float.intBitsToFloat(new BigInteger(s, 16).intValue()); + } catch (NumberFormatException e) { + e.printStackTrace(); + System.err.println("errrrr.."); + return 0L; + } + } + + public static float hexStrTofloat1(String str) { + try { + int i = Integer.parseInt(str, 16); + byte byte4 = (byte) (i & 0xff); + byte byte3 = (byte) ((i & 0xff00) >> 8); + byte byte2 = (byte) ((i & 0xff0000) >> 16); + byte byte1 = (byte) ((i & 0xff000000) >> 24); // 拼装成 "高字节在后,低字节在前"的格式 + int realint = (byte1 & 0xff) << 0 | (byte2 & 0xff) << 8 | (byte3 & 0xff) << 16 | (byte4 & 0xff) << 24; + return Float.intBitsToFloat(realint); + } catch (NumberFormatException e) { + System.err.println("errrrr.."); + return 0L; + } + + } + + public static int bytesToInt(byte[] src, int startPos) { + if ((src == null) || (src.length <= 0) || (src.length < startPos + 4) || (startPos < 0)) { + return -1; + } + int result = (int) ((src[(startPos + 3)] & 0xFF) * 16777216 + (src[(startPos + 2)] & 0xFF) * 65536L + + (src[(startPos + 1)] & 0xFF) * 256L + (src[startPos] & 0xFF)); + return result; + } + + public static int bytesToIntHL(byte[] src, int startPos, int len) { + if ((src == null) || (src.length <= 0) || (src.length < startPos + len) || (startPos < 0)) { + return -1; + } + int result = 0; + for (int i = 0; i < len; i++) { + result += (int) ((src[(startPos + i)] & 0xFF) * (1 << (len - 1 - i) * 8)); + } + return result; + } + + public static void printHexString(byte[] b) { + for (int i = 0; i < b.length; i++) { + String hex = Integer.toHexString(b[i] & 0xFF); + if (hex.length() == 1) { + hex = '0' + hex; + } + System.out.print(hex.toUpperCase() + " "); + } + System.out.println(); + } + + /** + * 字节数组转为十六进制字符串 + * + * @param src + * @return + */ + public static String bytesToHexString(byte[] src) { + StringBuilder stringBuilder = new StringBuilder(""); + if ((src == null) || (src.length <= 0)) { + return null; + } + for (int i = 0; i < src.length; i++) { + int v = src[i] & 0xFF; + String hv = Integer.toHexString(v); + if (hv.length() < 2) { + stringBuilder.append(0); + } + stringBuilder.append(hv); + } + return stringBuilder.toString(); + } + + public static String bytesToDecString(byte[] src) { + if ((src == null) || (src.length <= 0)) { + return null; + } + int result = (int) ((src[3] & 0xFF) * 16777216 + (src[2] & 0xFF) * 65536L + (src[1] & 0xFF) * 256L + + (src[0] & 0xFF)); + return Integer.toString(result); + } + + public static String bytesToHexString(byte[] src, int len) { + StringBuilder stringBuilder = new StringBuilder(""); + StringBuilder temp = new StringBuilder(""); + if ((src == null) || (src.length <= 0)) { + return null; + } + for (int i = 0; i < src.length; i++) { + int v = src[i] & 0xFF; + if (v != 0) { + String hv = Integer.toHexString(v); + StringBuilder temp1 = new StringBuilder(""); + if (hv.length() < 2) { + temp1.append(0); + } + temp1.append(hv); + temp1.append(temp); + temp = temp1; + } + } + if (len / 2 > temp.length()) { + String result = temp.toString(); + for (int k = 0; k < (len - result.length()) / 2; k++) { + stringBuilder.append("00"); + } + stringBuilder.append(result); + } else { + stringBuilder = temp; + } + return stringBuilder.toString(); + } + + public static String bytesToDecString(byte[] src, int len) { + if ((src == null) || (src.length <= 0)) { + return null; + } + int result = (int) (src[3] * 16777216 + src[2] * 65536L + src[1] * 256L + src[0]); + String temp = Integer.toString(result); + if (temp.length() < len) { + StringBuilder finalString = new StringBuilder(""); + for (int k = 0; k < len - temp.length(); k++) { + finalString.append(0); + } + finalString.append(result); + return finalString.toString(); + } + return temp; + } + + public static float byte2float(byte[] b, int index) { + int l = b[(index + 0)]; + l &= 0xFF; + l = (int) (l | b[(index + 1)] << 8); + l &= 0xFFFF; + l = (int) (l | b[(index + 2)] << 16); + l &= 0xFFFFFF; + l = (int) (l | b[(index + 3)] << 24); + return Float.intBitsToFloat(l); + } + + public static int ASCIIToInt(byte[] b, int len) { + int result = 0; + for (int i = 0; i < len; i++) { + char temp = (char) b[i]; + int i_temp; + switch (temp) { + case 'A': + i_temp = 10; + break; + case 'B': + i_temp = 11; + break; + case 'C': + i_temp = 12; + break; + case 'D': + i_temp = 13; + break; + case 'E': + i_temp = 14; + break; + case 'F': + i_temp = 15; + break; + default: + i_temp = Integer.valueOf(temp).intValue(); + } + result = i_temp + result * 16; + } + return result; + } + + public static String ASCIIToString(byte[] b, int len) { + String result = ""; + for (int i = 0; i < len; i++) { + result = result + (char) b[i]; + } + return result; + } + + + /** + * 将16进制字符串转换为byte[] + * + * @param str + * @return + */ + public static byte[] toBytes(String str) { + if (str == null || str.trim().equals("")) { + return new byte[0]; + } + + byte[] bytes = new byte[str.length() / 2]; + for (int i = 0; i < str.length() / 2; i++) { + String subStr = str.substring(i * 2, i * 2 + 2); + bytes[i] = (byte) Integer.parseInt(subStr, 16); + } + + return bytes; + } + + + /** + * 带符号的16进制字符串转float + */ + public static float SigneHexToFloat(String str) { + String s = str.substring(2, 4) + str.substring(0, 2); + float x = (float) Integer.valueOf(s, 16).shortValue(); + return x; + } + + /** + * 有符号16进制转10进制 + * + * @param strHex + * @return + */ + public static int signedHexToDec(String strHex) { + if (strHex.length() == 0) { + return 0; + } + int x = 0; + //带符号十六进制转换十进制 + String fristNum = strHex.substring(0, 1); + String hexStr2Byte = parseHexStr2Byte(fristNum); + String flag = hexStr2Byte.substring(0, 1); + if ("1".equals(flag)) { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < strHex.length(); i++) { + String num = strHex.substring(i, i + 1); + int decNum = Integer.parseInt(num, 16); + int a = decNum ^ 15; + sb.append(intToHex(a)); + } + x = -Integer.parseInt(sb.toString(), 16) - 1; + } else { + x = Integer.parseInt(strHex, 16); + } + + return x; + + } + + //十进制转16进制 + private static String intToHex(int n) { + StringBuffer s = new StringBuffer(); + String a; + char[] b = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + while (n != 0) { + s = s.append(b[n % 16]); + n = n / 16; + } + a = s.reverse().toString(); + return a; + } + + /** + * 将16进制转换为二进制 + * + * @param hexStr + * @return + */ + public static String parseHexStr2Byte(String hexStr) { + if (hexStr.length() == 0) { + return null; + } + int sint = Integer.valueOf(hexStr, 16); + //十进制在转换成二进制的字符串形式输出! + String bin = Integer.toBinaryString(sint); + for (int i = bin.length(); i < 4; i++) { + bin = "0" + bin; + } + return bin; + } +} + From e596b5622207a41e189d90a31d96480106886311 Mon Sep 17 00:00:00 2001 From: huangfeng Date: Mon, 9 Dec 2024 10:10:53 +0800 Subject: [PATCH 06/30] =?UTF-8?q?fix:=20i2=E5=AF=BC=E5=87=BA=E6=8B=86?= =?UTF-8?q?=E5=88=86=E6=9B=BF=E6=8D=A2sensorId=E5=B1=80=E9=83=A8=E7=BC=96?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xydl/cac/transform/I2DataTransformer.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/xydl/cac/transform/I2DataTransformer.java b/src/main/java/com/xydl/cac/transform/I2DataTransformer.java index ee11093..3dab3fe 100644 --- a/src/main/java/com/xydl/cac/transform/I2DataTransformer.java +++ b/src/main/java/com/xydl/cac/transform/I2DataTransformer.java @@ -96,8 +96,22 @@ public class I2DataTransformer { node.setEquipmentid(sensor.getEquipmentId()); } else { attr.setValue(""); - node.setSensorid(sensor.getSensorCode() + attach); - node.setEquipmentid(sensor.getEquipmentId() + attach); + String code = sensor.getSensorCode(); + node.setSensorid(code); + if (code != null && code.length() > attach.length() + 2) { + int len = code.length() - 2; + String tail = code.substring(len); + String first = code.substring(0, len - attach.length()); + node.setSensorid(first + attach + tail); + } + String equipmentid = sensor.getEquipmentId(); + node.setEquipmentid(equipmentid); + if (equipmentid != null && equipmentid.length() > attach.length() + 2) { + int len = equipmentid.length() - 2; + String tail = equipmentid.substring(len); + String first = equipmentid.substring(0, len - attach.length()); + node.setEquipmentid(first + attach + tail); + } } return node; } From 02db7284cb1c40b624dfcd5220027795a30809a6 Mon Sep 17 00:00:00 2001 From: huangfeng Date: Mon, 9 Dec 2024 11:42:03 +0800 Subject: [PATCH 07/30] =?UTF-8?q?fix:=20=E5=A6=82=E6=9E=9C=E9=87=87?= =?UTF-8?q?=E9=9B=86=E7=9A=84=E6=97=B6=E9=97=B4=E5=B0=8F=E4=BA=8E2000?= =?UTF-8?q?=E5=B9=B4=EF=BC=8C=E5=BF=BD=E7=95=A5=E8=AF=A5=E6=9D=A1=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/xydl/cac/iec/IEDCollectService.java | 3 +++ src/main/java/com/xydl/cac/model/StaticVariable.java | 3 +++ src/main/java/com/xydl/cac/util/DateUtil.java | 7 +++++++ 3 files changed, 13 insertions(+) diff --git a/src/main/java/com/xydl/cac/iec/IEDCollectService.java b/src/main/java/com/xydl/cac/iec/IEDCollectService.java index ba525e6..c8beed9 100644 --- a/src/main/java/com/xydl/cac/iec/IEDCollectService.java +++ b/src/main/java/com/xydl/cac/iec/IEDCollectService.java @@ -131,6 +131,9 @@ public class IEDCollectService { String time = timeNode.getValueString(); log.info("采集到" + fc + " " + paramindexNew + "=" + value + ", t=" + time); time = DateUtil.fromZoneUTCToLocal(time); + if (time == null) { + return; + } time = this.makeSameTime(rpt.getEqmid(), time); _dataService.insertData(rpt.getTablename(), rpt.getEqmid(), time, rpt.getColname(), value); diff --git a/src/main/java/com/xydl/cac/model/StaticVariable.java b/src/main/java/com/xydl/cac/model/StaticVariable.java index 74f9b90..a9bf35a 100644 --- a/src/main/java/com/xydl/cac/model/StaticVariable.java +++ b/src/main/java/com/xydl/cac/model/StaticVariable.java @@ -76,6 +76,9 @@ public class StaticVariable { value = bda.getValueString(); if ("acquisitionTime".equals(colname)) { value = DateUtil.fromZoneUTCToLocal(value); + if (value == null) { + return; + } } updateLastData(eqmid, colname, value, null); } diff --git a/src/main/java/com/xydl/cac/util/DateUtil.java b/src/main/java/com/xydl/cac/util/DateUtil.java index d033d15..f5c5d44 100644 --- a/src/main/java/com/xydl/cac/util/DateUtil.java +++ b/src/main/java/com/xydl/cac/util/DateUtil.java @@ -1,5 +1,7 @@ package com.xydl.cac.util; +import lombok.extern.slf4j.Slf4j; + import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.*; @@ -8,6 +10,7 @@ import java.time.temporal.ChronoUnit; import java.util.Calendar; import java.util.Date; +@Slf4j public class DateUtil { public final static String defaultDatePattern = "yyyy-MM-dd HH:mm:ss"; public static DateTimeFormatter defaultFormatter = DateTimeFormatter.ofPattern(defaultDatePattern); @@ -109,6 +112,10 @@ public class DateUtil { Date date = parse(time); time = format(date); LocalDateTime localtime = LocalDateTime.parse(time, defaultFormatter); + if (localtime.getYear() < 2000) { + log.warn("该时间小于2000年: " + str); + return null; + } ZonedDateTime zonedDateTime = localtime.atZone(ZoneOffset.UTC); ZonedDateTime convertedDateTime = zonedDateTime.withZoneSameInstant(ZoneId.systemDefault()); String result = convertedDateTime.format(defaultFormatter); From 3706e22c00bd2afa0fe0cd68d63e87cfc82ec815 Mon Sep 17 00:00:00 2001 From: liuguijing <123456> Date: Mon, 9 Dec 2024 13:27:15 +0800 Subject: [PATCH 08/30] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E7=A1=AC=E6=8E=A5?= =?UTF-8?q?=E7=82=B9=E8=A3=85=E7=BD=AE=E5=A2=9E=E5=8A=A0=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/xydl/cac/service/impl/SerialPortServiceImpl.java | 7 ++++++- src/main/resources/application-dev.yml | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java b/src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java index 3365feb..ca60093 100644 --- a/src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java +++ b/src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java @@ -2,6 +2,7 @@ package com.xydl.cac.service.impl; import com.fazecast.jSerialComm.SerialPort; import com.xydl.cac.service.SerialPortService; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.io.IOException; @@ -10,6 +11,10 @@ import java.util.List; @Service public class SerialPortServiceImpl implements SerialPortService { + + @Value("${cac.warnport.name}") + public boolean warnportname; + public List serialPortList; @Override @@ -52,7 +57,7 @@ public class SerialPortServiceImpl implements SerialPortService { @Override public Boolean openSerialPort(SerialPort port) { - if (port.getSystemPortName().equals("COM6")) { + if (port.getSystemPortName().equals(warnportname)) { int baudRate = 9600; // 波特率 int parity = SerialPort.EVEN_PARITY; // 校验位 int dataBits = 8; // 数据位 diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index ef5c1d6..becb583 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -40,7 +40,7 @@ spring: cac: datapath: /home/xydl/ncac/data 61850: - enable: true + enable: false i2: enable: false url: http://192.168.1.190:8080/busi-back-ws/service/XydlService @@ -49,3 +49,5 @@ cac: token: e65e730cba22e320e16926fd4ff19ce787fa2162d065792bb6562c6d4a4cf328 secret: SEC72e5fb1b4ce7f9fed55386040d599035c50f8d2a181ad66bd1277549f0716124 rsakey: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKNPuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gAkM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWowcSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99EcvDQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthhYhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3UP8iWi1Qw0Y= + warnport: + name: ttyCH341USB0 From 7acb7e4d9cac5b14715e97878e045c25e11aebc5 Mon Sep 17 00:00:00 2001 From: huangfeng Date: Mon, 9 Dec 2024 14:34:20 +0800 Subject: [PATCH 09/30] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E8=AE=A2?= =?UTF-8?q?=E9=98=85=E7=9A=84=E6=B0=B8=E8=BF=9C=E6=96=AD=E7=BA=BF=E9=87=8D?= =?UTF-8?q?=E8=BF=9E=E4=BB=A5=E5=8F=8A=E9=97=B4=E9=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cac/controller/IcdConfigController.java | 31 ++++++++- .../com/xydl/cac/iec/IEDCollectService.java | 3 +- src/main/java/com/xydl/cac/iec/IecClient.java | 65 ++++++++++--------- .../com/xydl/cac/iec/RealTimeDataService.java | 37 ++++------- .../service/impl/IedDlConfigServiceImpl.java | 3 +- 5 files changed, 76 insertions(+), 63 deletions(-) diff --git a/src/main/java/com/xydl/cac/controller/IcdConfigController.java b/src/main/java/com/xydl/cac/controller/IcdConfigController.java index 5946c4b..c710145 100644 --- a/src/main/java/com/xydl/cac/controller/IcdConfigController.java +++ b/src/main/java/com/xydl/cac/controller/IcdConfigController.java @@ -10,6 +10,7 @@ import com.xydl.cac.iec.RealTimeDataService; import com.xydl.cac.model.ColumnModel; import com.xydl.cac.model.IcdAttUpdateModel; import com.xydl.cac.model.Response; +import com.xydl.cac.repository.IcdIedRepository; import com.xydl.cac.service.DataService; import com.xydl.cac.service.IcdFileConfigService; import io.swagger.annotations.Api; @@ -25,6 +26,7 @@ import javax.annotation.Resource; import javax.validation.constraints.NotNull; import java.nio.charset.Charset; import java.util.List; +import java.util.Optional; @RestController @Api(tags = {"IcdConfig相关接口"}) @@ -38,6 +40,8 @@ public class IcdConfigController extends BasicController { DataService dataService; @Resource RealTimeDataService realTimeDataService; + @Resource + IcdIedRepository iedRepository; @PostMapping("upload") @ApiOperation("上传客户端icd文件") @@ -161,8 +165,22 @@ public class IcdConfigController extends BasicController { if (RealTimeDataService.inDoing) { throw new BusinessException("请稍后再操作"); } - realTimeDataService.startCollect(iedId); - return Response.success("OK"); + Optional optional = iedRepository.findById(iedId); + if (!optional.isPresent()) { + throw new BusinessException("未找到该IED"); + } + IcdIed ied = optional.get(); + try { + realTimeDataService.startCollect(ied); + ied.setStart(Constants.TRUE); + iedRepository.save(ied); + return Response.success("OK"); + } catch (Exception ex) { + realTimeDataService.stopCollect(ied.getId()); + ied.setStart(Constants.FALSE); + iedRepository.save(ied); + throw ex; + } } @PostMapping("stopCollect") @@ -174,7 +192,14 @@ public class IcdConfigController extends BasicController { if (RealTimeDataService.inDoing) { throw new BusinessException("请稍后再操作"); } - realTimeDataService.stopCollect(iedId); + Optional optional = iedRepository.findById(iedId); + if (!optional.isPresent()) { + throw new BusinessException("未找到该IED"); + } + IcdIed ied = optional.get(); + ied.setStart(Constants.FALSE); + iedRepository.save(ied); + realTimeDataService.stopCollect(ied.getId()); return Response.success("OK"); } diff --git a/src/main/java/com/xydl/cac/iec/IEDCollectService.java b/src/main/java/com/xydl/cac/iec/IEDCollectService.java index c8beed9..e0a2c03 100644 --- a/src/main/java/com/xydl/cac/iec/IEDCollectService.java +++ b/src/main/java/com/xydl/cac/iec/IEDCollectService.java @@ -55,7 +55,8 @@ public class IEDCollectService { } public void connect() throws Exception { - iecClient.connect(ied, xml); + iecClient.init(ied, xml); + iecClient.connect(); } public void disconnect() { diff --git a/src/main/java/com/xydl/cac/iec/IecClient.java b/src/main/java/com/xydl/cac/iec/IecClient.java index bb76c7a..958e789 100644 --- a/src/main/java/com/xydl/cac/iec/IecClient.java +++ b/src/main/java/com/xydl/cac/iec/IecClient.java @@ -29,9 +29,11 @@ public class IecClient implements ClientEventListener { ServerModel serverModel; public boolean keep = false; + public boolean connected = false; private RealTimeDataService realTimeDataService; private WebSocketServer webSocketServer; - public int retry = 10; + public int retry = 0; + public int seconds = 0; public Date lastReportTime; public IecClient() { @@ -42,16 +44,20 @@ public class IecClient implements ClientEventListener { webSocketServer = _webSocketServer; } - public void connect(IcdIed _ied, String xml) throws Exception { + public void init(IcdIed _ied, String xml) throws Exception { InputStream in = IOUtils.toInputStream(xml, StandardCharsets.UTF_8); - this.connect(_ied, in); + this.init(_ied, in); } - public void connect(IcdIed _ied, InputStream in) throws Exception { + public void init(IcdIed _ied, InputStream in) throws Exception { ied = _ied; + serverModel = SclParser.parse(in).get(0); + } + + public void connect() throws Exception { title = new int[]{1, 3, 9999, 33}; - if (StringUtils.isNotBlank(_ied.getApTitle())) { - String[] strs = _ied.getApTitle().replaceAll(" ", ",").split(","); + if (StringUtils.isNotBlank(ied.getApTitle())) { + String[] strs = ied.getApTitle().replaceAll(" ", ",").split(","); if (strs.length == 4) { title[0] = Integer.parseInt(strs[0]); title[1] = Integer.parseInt(strs[1]); @@ -69,14 +75,15 @@ public class IecClient implements ClientEventListener { clientSap.setTSelRemote(new byte[]{0, 1}); clientSap.setTSelLocal(new byte[]{0, 0}); clientSap.setApTitleCalled(title); - serverModel = SclParser.parse(in).get(0); clientAssociation = clientSap.associate(InetAddress.getByName(ied.getIp()), ied.getPort(), null, this); clientAssociation.setServerModel(serverModel); + connected = true; } public void disconnect() { try { + connected = false; clientAssociation.disconnect(); clientAssociation = null; } catch (Exception ignore) { @@ -87,11 +94,13 @@ public class IecClient implements ClientEventListener { if (StaticVariable.shutdown == 1) { return; } + retry++; + seconds = 0; clientAssociation = clientSap.associate(InetAddress.getByName(ied.getIp()), ied.getPort(), null, this); clientAssociation.setServerModel(serverModel); log.info("61850订阅断线重连成功, ied=" + ied.getName() + ", ip=" + ied.getIp() + ", port=" + ied.getPort()); - retry = 10; - keep = true; + connected = true; + retry = 0; } public String getValue(String paramindex, String fc) throws Exception { @@ -126,7 +135,6 @@ public class IecClient implements ClientEventListener { } } log.info("61850订阅成功, ied=" + ied.getName() + ", ip=" + ied.getIp() + ", port=" + ied.getPort()); - keep = true; } public void disableReporting() { @@ -151,7 +159,6 @@ public class IecClient implements ClientEventListener { } else { log.info("61850停止订阅, ied=" + ied.getName() + ", ip=" + ied.getIp() + ", port=" + ied.getPort()); } - keep = false; } public List listFile(String path) throws Exception { @@ -178,33 +185,26 @@ public class IecClient implements ClientEventListener { @Override public void associationClosed(IOException e) { if (keep) { + retry = 0; + seconds = 0; this.disableReporting(); this.disconnect(); - while (retry > 0 && StaticVariable.shutdown == 0) { - retry--; + while (!connected && StaticVariable.shutdown == 0) { try { - if (retry >= 5) { - StaticVariable.wait(10); - this.reconnect(); - } else if (retry == 4) { - log.warn("61850订阅断线重连已失败5次, ied=" + ied.getName() + ", ip=" + ied.getIp() + ", port=" + ied.getPort()); - StaticVariable.wait(60); + Thread.sleep(1000); + seconds++; + if (retry < 10 && seconds > 60) { this.reconnect(); - } else if (retry >= 1) { - StaticVariable.wait(60); + } else if (seconds > 60 * 60) { this.reconnect(); - } else { - String err = "61850订阅断线重连已失败多次不再重连. ied=" + ied.getName() + ", ip=" + ied.getIp() + ", port=" + ied.getPort(); - log.warn(err); - if (realTimeDataService != null && ied != null) { - realTimeDataService.stopCollect(ied.getId()); - } - if (webSocketServer != null) { - webSocketServer.sendMessage(err, null); - } } - break; } catch (Exception ignore) { + String err = "61850订阅断线重连失败" + retry + "次, ied=" + + ied.getName() + ", ip=" + ied.getIp() + ", port=" + ied.getPort(); + log.warn(err); + if (webSocketServer != null && retry >= 10) { + webSocketServer.sendMessage(err, null); + } } } } @@ -218,7 +218,8 @@ public class IecClient implements ClientEventListener { .port(102) .apTitle("1 3 9999 33") .build(); - iecClient.connect(ied, new FileInputStream("C:/资料/om.SCD")); + iecClient.init(ied, new FileInputStream("C:/资料/om.SCD")); + iecClient.connect(); String str = iecClient.getValue("OMDLMONT/SPDC1.MaxDsch.mag.f", "MX"); System.out.println(str); str = iecClient.getValue("OMDLMONT/SPDC1.MaxDsch.t", "MX"); diff --git a/src/main/java/com/xydl/cac/iec/RealTimeDataService.java b/src/main/java/com/xydl/cac/iec/RealTimeDataService.java index f12f63c..439fadf 100644 --- a/src/main/java/com/xydl/cac/iec/RealTimeDataService.java +++ b/src/main/java/com/xydl/cac/iec/RealTimeDataService.java @@ -36,52 +36,37 @@ public class RealTimeDataService { if (!CollectionUtils.isEmpty(list)) { for (IcdIed ied : list) { try { - this.startCollect(ied.getId()); + this.startCollect(ied); } catch (Exception ignore) { } } } } - public void startCollect(Integer iedId) throws BusinessException { - Optional optional = iedRepository.findById(iedId); - if (!optional.isPresent()) { - throw new BusinessException("未找到该IED"); - } - IcdIed ied = optional.get(); + public void startCollect(IcdIed ied) throws BusinessException { Optional optionalFile = fileRepository.findById(ied.getIcdFileId()); if (!optionalFile.isPresent()) { throw new BusinessException("未找到该icd文件"); } inDoing = true; IcdFile icdFile = optionalFile.get(); + IecClient iecClient = new IecClient(this, webSocketServer); try { - IecClient iecClient = new IecClient(this, webSocketServer); - iecClient.connect(ied, icdFile.getXml()); - iecClient.enableReporting(); - ied.setStart(Constants.TRUE); - iedRepository.save(ied); + iecClient.init(ied, icdFile.getXml()); + iecClient.keep = true; StaticVariable.realTimeClientMap.put(ied.getId(), iecClient); + iecClient.connect(); + iecClient.enableReporting(); } catch (Exception ex) { String err = "61850订阅异常, ied=" + ied.getName() + ", ip=" + ied.getIp() + ", port=" + ied.getPort(); log.error(err, ex); - this.stopCollect(iedId); + iecClient.associationClosed(null); throw new BusinessException(err); } finally { inDoing = false; } } - public void stopCollect(Integer iedId) { - this.onlyStop(iedId); - Optional optional = iedRepository.findById(iedId); - if (optional.isPresent()) { - IcdIed ied = optional.get(); - ied.setStart(Constants.FALSE); - iedRepository.save(ied); - } - } - public static void onErrorCheck(Integer iedId) { IecClient iecClient = StaticVariable.realTimeClientMap.get(iedId); if (iecClient != null) { @@ -89,13 +74,13 @@ public class RealTimeDataService { } } - private void onlyStop(Integer iedId) { + public void stopCollect(Integer iedId) { IecClient iecClient = StaticVariable.realTimeClientMap.get(iedId); if (iecClient != null) { + StaticVariable.realTimeClientMap.remove(iedId); iecClient.keep = false; iecClient.disableReporting(); iecClient.disconnect(); - StaticVariable.realTimeClientMap.remove(iedId); } } @@ -109,7 +94,7 @@ public class RealTimeDataService { idList.add(it.next()); } for (Integer iedId : idList) { - this.onlyStop(iedId); + this.stopCollect(iedId); } } diff --git a/src/main/java/com/xydl/cac/service/impl/IedDlConfigServiceImpl.java b/src/main/java/com/xydl/cac/service/impl/IedDlConfigServiceImpl.java index 0a80e7e..4e4c367 100644 --- a/src/main/java/com/xydl/cac/service/impl/IedDlConfigServiceImpl.java +++ b/src/main/java/com/xydl/cac/service/impl/IedDlConfigServiceImpl.java @@ -100,7 +100,8 @@ public class IedDlConfigServiceImpl implements IedDlConfigService { IcdFile icdFile = optionalFile.get(); IecClient iecClient = new IecClient(); try { - iecClient.connect(ied, icdFile.getXml()); + iecClient.init(ied, icdFile.getXml()); + iecClient.connect(); return iecClient.listFile(path); } catch (Exception ex) { throw new BusinessException(ex.getMessage()); From c107970bef13b971dd76a03e3eaf3ba80d320d16 Mon Sep 17 00:00:00 2001 From: huangfeng Date: Mon, 9 Dec 2024 15:16:39 +0800 Subject: [PATCH 10/30] =?UTF-8?q?perf:=20=E5=A2=9E=E5=8A=A0=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E8=BF=9E=E6=8E=A5=E7=8A=B6=E6=80=81=E5=92=8C=E9=87=8D?= =?UTF-8?q?=E8=BF=9E=E6=AC=A1=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/xydl/cac/controller/IcdConfigController.java | 2 +- src/main/java/com/xydl/cac/entity/IcdIed.java | 5 +++++ src/main/java/com/xydl/cac/iec/IecClient.java | 5 ++++- src/main/java/com/xydl/cac/iec/IecServerService.java | 1 + src/main/java/com/xydl/cac/iec/RealTimeDataService.java | 1 - src/main/java/com/xydl/cac/model/StaticVariable.java | 9 --------- .../xydl/cac/service/impl/IcdFileConfigServiceImpl.java | 9 +++++++++ 7 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/xydl/cac/controller/IcdConfigController.java b/src/main/java/com/xydl/cac/controller/IcdConfigController.java index c710145..9714c6f 100644 --- a/src/main/java/com/xydl/cac/controller/IcdConfigController.java +++ b/src/main/java/com/xydl/cac/controller/IcdConfigController.java @@ -179,7 +179,7 @@ public class IcdConfigController extends BasicController { realTimeDataService.stopCollect(ied.getId()); ied.setStart(Constants.FALSE); iedRepository.save(ied); - throw ex; + return Response.fail(ex.getMessage()); } } diff --git a/src/main/java/com/xydl/cac/entity/IcdIed.java b/src/main/java/com/xydl/cac/entity/IcdIed.java index 818be12..3c23efc 100644 --- a/src/main/java/com/xydl/cac/entity/IcdIed.java +++ b/src/main/java/com/xydl/cac/entity/IcdIed.java @@ -46,4 +46,9 @@ public class IcdIed { @ApiModelProperty(name = "端口") @Column(name = "port") private Integer port; + + @Transient + private boolean connected; + @Transient + private int retry; } \ No newline at end of file diff --git a/src/main/java/com/xydl/cac/iec/IecClient.java b/src/main/java/com/xydl/cac/iec/IecClient.java index 958e789..d87fbb0 100644 --- a/src/main/java/com/xydl/cac/iec/IecClient.java +++ b/src/main/java/com/xydl/cac/iec/IecClient.java @@ -34,6 +34,7 @@ public class IecClient implements ClientEventListener { private WebSocketServer webSocketServer; public int retry = 0; public int seconds = 0; + private boolean inRetry = false; public Date lastReportTime; public IecClient() { @@ -184,7 +185,8 @@ public class IecClient implements ClientEventListener { @Override public void associationClosed(IOException e) { - if (keep) { + if (keep && !inRetry) { + inRetry = true; retry = 0; seconds = 0; this.disableReporting(); @@ -207,6 +209,7 @@ public class IecClient implements ClientEventListener { } } } + inRetry = false; } } diff --git a/src/main/java/com/xydl/cac/iec/IecServerService.java b/src/main/java/com/xydl/cac/iec/IecServerService.java index 9a38960..38cc22b 100644 --- a/src/main/java/com/xydl/cac/iec/IecServerService.java +++ b/src/main/java/com/xydl/cac/iec/IecServerService.java @@ -83,6 +83,7 @@ public class IecServerService { @PreDestroy private void stop() { + StaticVariable.shutdown = 1; Iterator it = StaticVariable.iecServerMap.keySet().iterator(); while (it.hasNext()) { Integer key = it.next(); diff --git a/src/main/java/com/xydl/cac/iec/RealTimeDataService.java b/src/main/java/com/xydl/cac/iec/RealTimeDataService.java index 439fadf..7c59672 100644 --- a/src/main/java/com/xydl/cac/iec/RealTimeDataService.java +++ b/src/main/java/com/xydl/cac/iec/RealTimeDataService.java @@ -60,7 +60,6 @@ public class RealTimeDataService { } catch (Exception ex) { String err = "61850订阅异常, ied=" + ied.getName() + ", ip=" + ied.getIp() + ", port=" + ied.getPort(); log.error(err, ex); - iecClient.associationClosed(null); throw new BusinessException(err); } finally { inDoing = false; diff --git a/src/main/java/com/xydl/cac/model/StaticVariable.java b/src/main/java/com/xydl/cac/model/StaticVariable.java index a9bf35a..de05964 100644 --- a/src/main/java/com/xydl/cac/model/StaticVariable.java +++ b/src/main/java/com/xydl/cac/model/StaticVariable.java @@ -31,15 +31,6 @@ public class StaticVariable { public static List zsb_Cache = null; public static ConcurrentHashMap rule_Cache = new ConcurrentHashMap<>(); - public static void wait(int seconds) throws InterruptedException { - for (int i = 0; i < seconds; i++) { - if (shutdown == 1) { - break; - } - Thread.sleep(1000); - } - } - // 更新服务端 public static void updateServerNodeValue(BasicDataAttribute bda) { Iterator it = StaticVariable.iecServerMap.keySet().iterator(); diff --git a/src/main/java/com/xydl/cac/service/impl/IcdFileConfigServiceImpl.java b/src/main/java/com/xydl/cac/service/impl/IcdFileConfigServiceImpl.java index 1a02435..87ab193 100644 --- a/src/main/java/com/xydl/cac/service/impl/IcdFileConfigServiceImpl.java +++ b/src/main/java/com/xydl/cac/service/impl/IcdFileConfigServiceImpl.java @@ -3,7 +3,9 @@ package com.xydl.cac.service.impl; import com.xydl.cac.entity.*; import com.xydl.cac.entity.constants.Constants; import com.xydl.cac.exception.BusinessException; +import com.xydl.cac.iec.IecClient; import com.xydl.cac.model.IcdAttUpdateModel; +import com.xydl.cac.model.StaticVariable; import com.xydl.cac.repository.*; import com.xydl.cac.service.DataService; import com.xydl.cac.service.IcdFileConfigService; @@ -108,6 +110,13 @@ public class IcdFileConfigServiceImpl implements IcdFileConfigService { List iedList = iedRepository.findByIcdFileId(icdFile.getId()); for (IcdIed ied : iedList) { if (StringUtils.isNotBlank(ied.getIp())) { + ied.setConnected(false); + ied.setRetry(0); + IecClient iecClient = StaticVariable.realTimeClientMap.get(ied.getId()); + if (iecClient != null) { + ied.setRetry(iecClient.retry); + ied.setConnected(iecClient.connected); + } result.add(ied); } } From 5e475d8f9ba4a2515e6409122404c67ae05d3ccd Mon Sep 17 00:00:00 2001 From: huangfeng Date: Mon, 9 Dec 2024 16:05:28 +0800 Subject: [PATCH 11/30] =?UTF-8?q?fix:=20=E6=B8=85=E7=A9=BA=E6=98=AF?= =?UTF-8?q?=E4=B8=80=E8=B5=B7=E6=B8=85=E7=A9=BA=E9=87=87=E9=9B=86=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/xydl/cac/service/impl/IcdFileConfigServiceImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/xydl/cac/service/impl/IcdFileConfigServiceImpl.java b/src/main/java/com/xydl/cac/service/impl/IcdFileConfigServiceImpl.java index 87ab193..d1a5abe 100644 --- a/src/main/java/com/xydl/cac/service/impl/IcdFileConfigServiceImpl.java +++ b/src/main/java/com/xydl/cac/service/impl/IcdFileConfigServiceImpl.java @@ -42,6 +42,8 @@ public class IcdFileConfigServiceImpl implements IcdFileConfigService { RptparamindexRepository rptparamindexRepository; @Resource DataService dataService; + @Resource + IedDlConfigRepository iedDlConfigRepository; @Override public void upload(String xml, String filename, int srv) throws Exception { @@ -229,6 +231,7 @@ public class IcdFileConfigServiceImpl implements IcdFileConfigService { configRepository.deleteAll(); fileRepository.deleteAll(); iedRepository.deleteAll(); + iedDlConfigRepository.deleteAll(); } @Override From 94277eaebb6018e4cd0b54382c3fa5fc9d222bfb Mon Sep 17 00:00:00 2001 From: huangfeng Date: Tue, 10 Dec 2024 09:46:01 +0800 Subject: [PATCH 12/30] =?UTF-8?q?perf:=20=E5=A2=9E=E5=8A=A0=E7=AD=89?= =?UTF-8?q?=E5=BE=85=E7=A7=92=E6=95=B0=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/xydl/cac/entity/IcdIed.java | 2 ++ .../com/xydl/cac/service/impl/IcdFileConfigServiceImpl.java | 2 ++ src/main/java/com/xydl/cac/util/DateUtil.java | 1 - 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/xydl/cac/entity/IcdIed.java b/src/main/java/com/xydl/cac/entity/IcdIed.java index 3c23efc..405896e 100644 --- a/src/main/java/com/xydl/cac/entity/IcdIed.java +++ b/src/main/java/com/xydl/cac/entity/IcdIed.java @@ -51,4 +51,6 @@ public class IcdIed { private boolean connected; @Transient private int retry; + @Transient + private int seconds; } \ No newline at end of file diff --git a/src/main/java/com/xydl/cac/service/impl/IcdFileConfigServiceImpl.java b/src/main/java/com/xydl/cac/service/impl/IcdFileConfigServiceImpl.java index d1a5abe..fd91fe4 100644 --- a/src/main/java/com/xydl/cac/service/impl/IcdFileConfigServiceImpl.java +++ b/src/main/java/com/xydl/cac/service/impl/IcdFileConfigServiceImpl.java @@ -114,10 +114,12 @@ public class IcdFileConfigServiceImpl implements IcdFileConfigService { if (StringUtils.isNotBlank(ied.getIp())) { ied.setConnected(false); ied.setRetry(0); + ied.setSeconds(0); IecClient iecClient = StaticVariable.realTimeClientMap.get(ied.getId()); if (iecClient != null) { ied.setRetry(iecClient.retry); ied.setConnected(iecClient.connected); + ied.setSeconds(iecClient.seconds); } result.add(ied); } diff --git a/src/main/java/com/xydl/cac/util/DateUtil.java b/src/main/java/com/xydl/cac/util/DateUtil.java index f5c5d44..9825e48 100644 --- a/src/main/java/com/xydl/cac/util/DateUtil.java +++ b/src/main/java/com/xydl/cac/util/DateUtil.java @@ -113,7 +113,6 @@ public class DateUtil { time = format(date); LocalDateTime localtime = LocalDateTime.parse(time, defaultFormatter); if (localtime.getYear() < 2000) { - log.warn("该时间小于2000年: " + str); return null; } ZonedDateTime zonedDateTime = localtime.atZone(ZoneOffset.UTC); From ef38aa267574fabc74ece4f85029faa6b79c878a Mon Sep 17 00:00:00 2001 From: huangfeng Date: Tue, 10 Dec 2024 10:19:27 +0800 Subject: [PATCH 13/30] =?UTF-8?q?perf:=20=E4=BD=BF=E7=94=A8=E5=BC=82?= =?UTF-8?q?=E6=AD=A5=E7=BA=BF=E7=A8=8B=E6=9D=A5=E9=87=8D=E8=BF=9E61850?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/xydl/cac/iec/IEDCollectService.java | 7 ++++++- .../java/com/xydl/cac/iec/NetErrorThread.java | 15 +++++++++++++++ .../com/xydl/cac/iec/RealTimeDataService.java | 7 ------- 3 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/xydl/cac/iec/NetErrorThread.java diff --git a/src/main/java/com/xydl/cac/iec/IEDCollectService.java b/src/main/java/com/xydl/cac/iec/IEDCollectService.java index e0a2c03..7f360f5 100644 --- a/src/main/java/com/xydl/cac/iec/IEDCollectService.java +++ b/src/main/java/com/xydl/cac/iec/IEDCollectService.java @@ -15,6 +15,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.util.CollectionUtils; +import java.net.SocketException; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -88,7 +89,11 @@ public class IEDCollectService { StaticVariable.doneWarnMap.put(key, "1"); _webSocketServer.sendMessage(err, null); } - RealTimeDataService.onErrorCheck(ied.getId()); + if (ex instanceof SocketException) { + NetErrorThread thread = new NetErrorThread(); + thread.iedId = ied.getId(); + thread.run(); + } } finally { iecClient.disconnect(); } diff --git a/src/main/java/com/xydl/cac/iec/NetErrorThread.java b/src/main/java/com/xydl/cac/iec/NetErrorThread.java new file mode 100644 index 0000000..de210c4 --- /dev/null +++ b/src/main/java/com/xydl/cac/iec/NetErrorThread.java @@ -0,0 +1,15 @@ +package com.xydl.cac.iec; + +import com.xydl.cac.model.StaticVariable; + +public class NetErrorThread extends Thread { + public int iedId; + + @Override + public void run() { + IecClient iecClient = StaticVariable.realTimeClientMap.get(iedId); + if (iecClient != null) { + iecClient.associationClosed(null); + } + } +} diff --git a/src/main/java/com/xydl/cac/iec/RealTimeDataService.java b/src/main/java/com/xydl/cac/iec/RealTimeDataService.java index 7c59672..8216e96 100644 --- a/src/main/java/com/xydl/cac/iec/RealTimeDataService.java +++ b/src/main/java/com/xydl/cac/iec/RealTimeDataService.java @@ -66,13 +66,6 @@ public class RealTimeDataService { } } - public static void onErrorCheck(Integer iedId) { - IecClient iecClient = StaticVariable.realTimeClientMap.get(iedId); - if (iecClient != null) { - iecClient.associationClosed(null); - } - } - public void stopCollect(Integer iedId) { IecClient iecClient = StaticVariable.realTimeClientMap.get(iedId); if (iecClient != null) { From fc720c93896dc5eb86a494b1483634e2475f4b36 Mon Sep 17 00:00:00 2001 From: liuguijing <123456> Date: Tue, 10 Dec 2024 11:33:20 +0800 Subject: [PATCH 14/30] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E7=A1=AC=E6=8E=A5?= =?UTF-8?q?=E7=82=B9=E8=A3=85=E7=BD=AE=E5=A2=9E=E5=8A=A0=E5=81=9C=E9=A1=BF?= =?UTF-8?q?=E4=BA=94=E7=A7=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/xydl/cac/model/StaticVariable.java | 2 +- .../xydl/cac/service/SerialPortService.java | 8 +- .../service/impl/SerialPortServiceImpl.java | 110 ++++++++++++------ src/main/resources/application-prod.yml | 2 + 4 files changed, 80 insertions(+), 42 deletions(-) diff --git a/src/main/java/com/xydl/cac/model/StaticVariable.java b/src/main/java/com/xydl/cac/model/StaticVariable.java index 3306050..f54fcbb 100644 --- a/src/main/java/com/xydl/cac/model/StaticVariable.java +++ b/src/main/java/com/xydl/cac/model/StaticVariable.java @@ -33,7 +33,7 @@ public class StaticVariable { public static List zsb_Cache = null; public static ConcurrentHashMap rule_Cache = new ConcurrentHashMap<>(); - public static List serialPorts = new ArrayList<>(); + public static SerialPort currentPort; public static void wait(int seconds) throws InterruptedException { for (int i = 0; i < seconds; i++) { diff --git a/src/main/java/com/xydl/cac/service/SerialPortService.java b/src/main/java/com/xydl/cac/service/SerialPortService.java index eb6bfbb..45fe2d4 100644 --- a/src/main/java/com/xydl/cac/service/SerialPortService.java +++ b/src/main/java/com/xydl/cac/service/SerialPortService.java @@ -6,11 +6,11 @@ import java.io.IOException; import java.util.List; public interface SerialPortService { - List discoverSerialPort(); + Boolean discoverSerialPort(); - boolean closeSerialPort(SerialPort port, String portname); + void closeSerialPort(); - Boolean openSerialPort(SerialPort port); + Boolean openSerialPort(); - void sendData(SerialPort port, boolean data) throws IOException; + void sendData(boolean data) throws IOException; } diff --git a/src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java b/src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java index ca60093..74aee93 100644 --- a/src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java +++ b/src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java @@ -1,67 +1,99 @@ package com.xydl.cac.service.impl; import com.fazecast.jSerialComm.SerialPort; +import com.xydl.cac.model.StaticVariable; import com.xydl.cac.service.SerialPortService; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; -import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @Service +@Slf4j public class SerialPortServiceImpl implements SerialPortService { @Value("${cac.warnport.name}") - public boolean warnportname; - - public List serialPortList; + public String warnportname; @Override - public List discoverSerialPort() { - serialPortList = Arrays.asList(SerialPort.getCommPorts()); - // 遍历串口列表并打印每个串口的名称 - for (SerialPort port : serialPortList) { - System.out.println("获取串口: " + port.getSystemPortName()); + public Boolean discoverSerialPort() { + List serialPortList = new ArrayList<>(); + SerialPort[] commPorts = SerialPort.getCommPorts(); + if (commPorts != null && commPorts.length > 0) { + serialPortList = Arrays.asList(commPorts); + for (SerialPort port : serialPortList) { + log.info("获取串口: " + port.getSystemPortName()); + if (port.getSystemPortName().equals(warnportname)) { + StaticVariable.currentPort = port; + log.info("获取到硬接点告警串口: " + port.getSystemPortName()); + return true; + } + } + return false; + } else { + log.error("未获取到硬接点告警串口!"); + return false; } - return serialPortList; } - //关闭串口 @Override - public boolean closeSerialPort(SerialPort port, String portname) { - for (SerialPort portItem : serialPortList) { - if (portItem.getSystemPortName().equals(portname)) { - if (portItem != null) { - System.out.println("断开端口" + portItem.getSystemPortName() + "连接"); - return portItem.closePort(); - } - } + public void closeSerialPort() { + if (StaticVariable.currentPort != null) { + SerialPort port = StaticVariable.currentPort; + port.closePort(); + } else { + log.error("断开串口失败,没有对应的硬接点告警串口!"); } - return false; } //发送数据到串口 @Override - public void sendData(SerialPort port, boolean data) throws IOException { - byte[] buffer2; - if (data) { - buffer2 = new byte[]{00, (byte) 0xf1, (byte) 0xff}; - } else { - buffer2 = new byte[]{00, (byte) 0x01, (byte) 0xff}; + @Async + public void sendData(boolean data) { + if (openSerialPort()) { + byte[] openbuffer = new byte[]{00, (byte) 0xf1, (byte) 0xff}; + byte[] stopbuffer = new byte[]{00, (byte) 0x01, (byte) 0xff}; + SerialPort port = StaticVariable.currentPort; + if (port != null) { + if (data) { + port.writeBytes(openbuffer, openbuffer.length); + } else { + port.writeBytes(stopbuffer, stopbuffer.length); + } + try { + Thread.sleep(5000); + port.writeBytes(stopbuffer, stopbuffer.length); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } } - port.writeBytes(buffer2, buffer2.length); } @Override - public Boolean openSerialPort(SerialPort port) { - if (port.getSystemPortName().equals(warnportname)) { - int baudRate = 9600; // 波特率 - int parity = SerialPort.EVEN_PARITY; // 校验位 - int dataBits = 8; // 数据位 - int stopBits = SerialPort.ONE_STOP_BIT; // 停止位 + public Boolean openSerialPort() { + Boolean discover = false; + if (StaticVariable.currentPort == null) { + discover = discoverSerialPort(); + } else { + discover = true; + } + if (discover) { + SerialPort port = StaticVariable.currentPort; + if (port.isOpen()) { + log.info("硬接点告警串口已经打开!"); + return true; + } else { + int baudRate = 9600; // 波特率 + int parity = SerialPort.EVEN_PARITY; // 校验位 + int dataBits = 8; // 数据位 + int stopBits = SerialPort.ONE_STOP_BIT; // 停止位 try { boolean setComResult = port.setComPortParameters(baudRate, dataBits, stopBits, parity); // 设置参数 boolean setComTimes = port.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 20000, 0); // 设置超时 @@ -70,18 +102,22 @@ public class SerialPortServiceImpl implements SerialPortService { } boolean b = port.openPort(); if (b) { + log.info("打开硬接点告警串口成功!"); return true; } else { + log.error("打开串口失败!"); return false; } } catch (Exception e) { e.printStackTrace(); -// return ResponseResult.getErrorResult("Failed to open port " + port.getSystemPortName() + e.getMessage().toString()); + log.error("打开串口失败" + e.getMessage()); return false; } -// return ResponseResult.getSuccessResult("COM10 Serial port open"); + } + } else { + log.error("打开串口失败,找不到硬接点串口!"); + return false; } -// return ResponseResult.getErrorResult("Failed to find port " + port.getSystemPortName()); - return false; } + } diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 33cd6df..3adb91b 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -49,3 +49,5 @@ cac: token: e65e730cba22e320e16926fd4ff19ce787fa2162d065792bb6562c6d4a4cf328 secret: SEC72e5fb1b4ce7f9fed55386040d599035c50f8d2a181ad66bd1277549f0716124 rsakey: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKNPuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gAkM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWowcSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99EcvDQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthhYhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3UP8iWi1Qw0Y= + warnport: + name: ttyCH341USB0 \ No newline at end of file From 08654185ca2a99d6b7c4760dd7179cde22304791 Mon Sep 17 00:00:00 2001 From: huangfeng Date: Tue, 10 Dec 2024 11:34:29 +0800 Subject: [PATCH 15/30] =?UTF-8?q?feat:=20=E5=91=8A=E8=AD=A6=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E9=80=9A=E7=9F=A5=E4=B8=B2=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/upgrade1210.sql | 1 + src/main/java/com/xydl/cac/entity/WarnRule.java | 4 ++++ .../java/com/xydl/cac/service/impl/WarnRuleServiceImpl.java | 1 + src/main/java/com/xydl/cac/task/RuleCheckTask.java | 5 +++++ 4 files changed, 11 insertions(+) create mode 100644 db/upgrade1210.sql diff --git a/db/upgrade1210.sql b/db/upgrade1210.sql new file mode 100644 index 0000000..9c613ee --- /dev/null +++ b/db/upgrade1210.sql @@ -0,0 +1 @@ +ALTER TABLE `warn_rule` ADD COLUMN `notify_com` INT(11) NULL DEFAULT NULL COMMENT '0:不通知; 1:通知' AFTER `active`; diff --git a/src/main/java/com/xydl/cac/entity/WarnRule.java b/src/main/java/com/xydl/cac/entity/WarnRule.java index 9464296..9bfac57 100644 --- a/src/main/java/com/xydl/cac/entity/WarnRule.java +++ b/src/main/java/com/xydl/cac/entity/WarnRule.java @@ -77,6 +77,10 @@ public class WarnRule { @Column(name = "active") private Integer active; + @ApiModelProperty("状态 0:不通知 1:通知") + @Column(name = "notify_com") + private Integer notifyCom; + @ApiModelProperty("最后数据采集时间") @Column(name = "last_d_time") private Date lastDTime; diff --git a/src/main/java/com/xydl/cac/service/impl/WarnRuleServiceImpl.java b/src/main/java/com/xydl/cac/service/impl/WarnRuleServiceImpl.java index dd00896..acdeec2 100644 --- a/src/main/java/com/xydl/cac/service/impl/WarnRuleServiceImpl.java +++ b/src/main/java/com/xydl/cac/service/impl/WarnRuleServiceImpl.java @@ -86,6 +86,7 @@ public class WarnRuleServiceImpl implements WarnRuleService { rule.setThreshold(item.getThreshold()); rule.setLevel(item.getLevel()); rule.setActive(item.getActive()); + rule.setNotifyCom(item.getNotifyCom()); repository.save(rule); StaticVariable.rule_Cache.remove(rule.getId()); } diff --git a/src/main/java/com/xydl/cac/task/RuleCheckTask.java b/src/main/java/com/xydl/cac/task/RuleCheckTask.java index d7a7b5d..c12159b 100644 --- a/src/main/java/com/xydl/cac/task/RuleCheckTask.java +++ b/src/main/java/com/xydl/cac/task/RuleCheckTask.java @@ -4,6 +4,7 @@ import com.xydl.cac.entity.ModevTypePoint; import com.xydl.cac.entity.NSensor; import com.xydl.cac.entity.WarnRule; import com.xydl.cac.entity.Warning; +import com.xydl.cac.entity.constants.Constants; import com.xydl.cac.model.StaticVariable; import com.xydl.cac.model.TriggerModel; import com.xydl.cac.repository.WarnRuleRepository; @@ -73,6 +74,10 @@ public class RuleCheckTask { for (TriggerModel model : warnList) { this.sendWarning(rule, model); } + if (rule.getNotifyCom() != null && rule.getNotifyCom().intValue() == Constants.TRUE) { + // 通知串口 + + } } } catch (Exception e) { log.error("RuleCheckTask.ruleCheck error.", e); From b094504dc8319e8bb6242e6fdaa578eebbfddde4 Mon Sep 17 00:00:00 2001 From: liuguijing <123456> Date: Tue, 10 Dec 2024 13:24:31 +0800 Subject: [PATCH 16/30] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E7=A1=AC=E6=8E=A5?= =?UTF-8?q?=E7=82=B9=E8=A3=85=E7=BD=AE=E5=A2=9E=E5=8A=A0=E5=81=9C=E9=A1=BF?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E9=85=8D=E7=BD=AE=EF=BC=8C=E5=92=8C=E5=91=8A?= =?UTF-8?q?=E8=AD=A6=E9=97=B4=E9=9A=94=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/xydl/cac/model/StaticVariable.java | 6 ++-- .../service/impl/SerialPortServiceImpl.java | 28 ++++++++++++++----- src/main/resources/application-dev.yml | 2 ++ 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/xydl/cac/model/StaticVariable.java b/src/main/java/com/xydl/cac/model/StaticVariable.java index f54fcbb..708cd51 100644 --- a/src/main/java/com/xydl/cac/model/StaticVariable.java +++ b/src/main/java/com/xydl/cac/model/StaticVariable.java @@ -10,10 +10,7 @@ import com.xydl.cac.iec.IecClient; import com.xydl.cac.iec.IecServer; import com.xydl.cac.util.DateUtil; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; public class StaticVariable { @@ -34,6 +31,7 @@ public class StaticVariable { public static ConcurrentHashMap rule_Cache = new ConcurrentHashMap<>(); public static SerialPort currentPort; + public static Date LastWarningTime;//最后一次硬接点告警时间 public static void wait(int seconds) throws InterruptedException { for (int i = 0; i < seconds; i++) { diff --git a/src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java b/src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java index 74aee93..efd069e 100644 --- a/src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java +++ b/src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java @@ -3,6 +3,7 @@ package com.xydl.cac.service.impl; import com.fazecast.jSerialComm.SerialPort; import com.xydl.cac.model.StaticVariable; import com.xydl.cac.service.SerialPortService; +import com.xydl.cac.util.DateUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Async; @@ -10,6 +11,7 @@ import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Arrays; +import java.util.Date; import java.util.List; @Service @@ -18,6 +20,10 @@ public class SerialPortServiceImpl implements SerialPortService { @Value("${cac.warnport.name}") public String warnportname; + @Value("${cac.warnport.intervaltime:60000}") + public Integer intervaltime; + @Value("${cac.warnport.warntime:5000}") + public Integer warntime; @Override public Boolean discoverSerialPort() { @@ -56,20 +62,28 @@ public class SerialPortServiceImpl implements SerialPortService { @Async public void sendData(boolean data) { if (openSerialPort()) { - byte[] openbuffer = new byte[]{00, (byte) 0xf1, (byte) 0xff}; - byte[] stopbuffer = new byte[]{00, (byte) 0x01, (byte) 0xff}; + byte[] openbuffer = new byte[]{00, (byte) 0xf1, (byte) 0xff};//发送串口告警 + byte[] stopbuffer = new byte[]{00, (byte) 0x01, (byte) 0xff};//关闭串口告警 SerialPort port = StaticVariable.currentPort; if (port != null) { - if (data) { - port.writeBytes(openbuffer, openbuffer.length); + Date date = new Date(); + if (StaticVariable.LastWarningTime == null) { + StaticVariable.LastWarningTime = new Date(); } else { - port.writeBytes(stopbuffer, stopbuffer.length); + long lastWarningTimeTime = StaticVariable.LastWarningTime.getTime(); + long time = date.getTime(); + if (time - lastWarningTimeTime <= intervaltime) { + return; + } } + StaticVariable.LastWarningTime = date; + port.writeBytes(openbuffer, openbuffer.length); try { - Thread.sleep(5000); - port.writeBytes(stopbuffer, stopbuffer.length); + Thread.sleep(warntime); } catch (InterruptedException e) { e.printStackTrace(); + } finally { + port.writeBytes(stopbuffer, stopbuffer.length); } } } diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index becb583..d6cface 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -51,3 +51,5 @@ cac: rsakey: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKNPuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gAkM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWowcSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99EcvDQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthhYhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3UP8iWi1Qw0Y= warnport: name: ttyCH341USB0 + intervaltime: 60000 + warntime: 5000 From 56a11cc5fb8698cbb33825cbb3be7e33cce43446 Mon Sep 17 00:00:00 2001 From: liuguijing <123456> Date: Tue, 10 Dec 2024 13:24:58 +0800 Subject: [PATCH 17/30] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E7=A1=AC=E6=8E=A5?= =?UTF-8?q?=E7=82=B9=E8=A3=85=E7=BD=AE=E5=A2=9E=E5=8A=A0=E5=81=9C=E9=A1=BF?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E9=85=8D=E7=BD=AE=EF=BC=8C=E5=92=8C=E5=91=8A?= =?UTF-8?q?=E8=AD=A6=E9=97=B4=E9=9A=94=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application-prod.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 3adb91b..4fdf61a 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -50,4 +50,6 @@ cac: secret: SEC72e5fb1b4ce7f9fed55386040d599035c50f8d2a181ad66bd1277549f0716124 rsakey: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKNPuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gAkM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWowcSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99EcvDQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthhYhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3UP8iWi1Qw0Y= warnport: - name: ttyCH341USB0 \ No newline at end of file + name: ttyCH341USB0 + intervaltime: 60000 + warntime: 5000 \ No newline at end of file From ee8b0a32b2f658b4a45fe3da4cbc13ce2fd33ffb Mon Sep 17 00:00:00 2001 From: liuguijing <123456> Date: Tue, 10 Dec 2024 13:25:18 +0800 Subject: [PATCH 18/30] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E7=A1=AC=E6=8E=A5?= =?UTF-8?q?=E7=82=B9=E8=A3=85=E7=BD=AE=E5=A2=9E=E5=8A=A0=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xydl/cac/controller/TestController.java | 48 +++++-------------- 1 file changed, 13 insertions(+), 35 deletions(-) diff --git a/src/main/java/com/xydl/cac/controller/TestController.java b/src/main/java/com/xydl/cac/controller/TestController.java index 7842986..f77711d 100644 --- a/src/main/java/com/xydl/cac/controller/TestController.java +++ b/src/main/java/com/xydl/cac/controller/TestController.java @@ -1,6 +1,5 @@ package com.xydl.cac.controller; -import com.fazecast.jSerialComm.SerialPort; import com.xydl.cac.model.Response; import com.xydl.cac.model.StaticVariable; import com.xydl.cac.service.IcdFileConfigService; @@ -16,12 +15,11 @@ import org.springframework.web.socket.WebSocketSession; import javax.annotation.Resource; import java.io.IOException; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; @RestController -@Api(tags = {"测试接口"}) +@Api(tags = {"测试接口文档"}) @RequestMapping("test") @Slf4j public class TestController extends BasicController { @@ -91,50 +89,30 @@ public class TestController extends BasicController { } @GetMapping("/discover") - public Response> discoverSerialPort() { - List list1 = serialPortService.discoverSerialPort(); - StaticVariable.serialPorts = list1; - List list = new ArrayList<>(); - list1.forEach(item -> { - list.add(item.getSystemPortName()); - }); - Response> response = Response.success(list); - return response; + public Response discoverSerialPort() { + Boolean aBoolean = serialPortService.discoverSerialPort(); + if (aBoolean) { + return Response.success("发现了"); + } else { + return Response.fail("未找到"); + } } @GetMapping("/open") - public Response openSerialPort(String portname) { - for (SerialPort port : StaticVariable.serialPorts) { - if (port.getSystemPortName().equals(portname)) { - return Response.success(serialPortService.openSerialPort(port)); - } - } - return Response.fail("Failed to find port "); + public Response openSerialPort() { + return Response.success(serialPortService.openSerialPort()); } @GetMapping("/send") - public String sendData(int data,String portname) throws IOException { + public String sendData(boolean data) throws IOException { //发送数据注意,提前与接收设备沟通好协议,发送什么样类型的数据设备才可以进行响应,否则设备无响应 - for (SerialPort port : StaticVariable.serialPorts) { - if (port.getSystemPortName().equals(portname)) { - if (data == 0) { - serialPortService.sendData(port, false); - } else { - serialPortService.sendData(port, true); - } - - } - } + serialPortService.sendData(data); return "Data sent>>>"; } @GetMapping("/close") public String closeSerialPort(String portname) { - for (SerialPort port : StaticVariable.serialPorts) { - if (port.getSystemPortName().equals(portname)) { - serialPortService.closeSerialPort(port,portname); - } - } + serialPortService.closeSerialPort(); return "Serial port closed"; } } From dfbb28af3df2df1d84ff7f6a251bfb1c5751965e Mon Sep 17 00:00:00 2001 From: liuguijing <123456> Date: Tue, 10 Dec 2024 14:27:16 +0800 Subject: [PATCH 19/30] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E7=A1=AC=E6=8E=A5?= =?UTF-8?q?=E7=82=B9=E8=A3=85=E7=BD=AE=E4=BB=A3=E7=A0=81=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E5=92=8C=E5=88=A4=E6=96=AD=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xydl/cac/controller/TestController.java | 17 +-- .../com/xydl/cac/model/StaticVariable.java | 3 +- .../impl => serialport}/DataListener.java | 2 +- .../xydl/cac/serialport/SerialPortServer.java | 137 ++++++++++++++++++ .../xydl/cac/service/SerialPortService.java | 16 -- .../service/impl/SerialPortServiceImpl.java | 137 ------------------ src/main/resources/application-dev.yml | 4 +- 7 files changed, 147 insertions(+), 169 deletions(-) rename src/main/java/com/xydl/cac/{service/impl => serialport}/DataListener.java (97%) create mode 100644 src/main/java/com/xydl/cac/serialport/SerialPortServer.java delete mode 100644 src/main/java/com/xydl/cac/service/SerialPortService.java delete mode 100644 src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java diff --git a/src/main/java/com/xydl/cac/controller/TestController.java b/src/main/java/com/xydl/cac/controller/TestController.java index f77711d..78c8927 100644 --- a/src/main/java/com/xydl/cac/controller/TestController.java +++ b/src/main/java/com/xydl/cac/controller/TestController.java @@ -2,8 +2,8 @@ package com.xydl.cac.controller; import com.xydl.cac.model.Response; import com.xydl.cac.model.StaticVariable; +import com.xydl.cac.serialport.SerialPortServer; import com.xydl.cac.service.IcdFileConfigService; -import com.xydl.cac.service.SerialPortService; import com.xydl.cac.socket.WebSocketServer; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -11,7 +11,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.socket.WebSocketSession; import javax.annotation.Resource; import java.io.IOException; @@ -30,7 +29,7 @@ public class TestController extends BasicController { WebSocketServer webSocketServer; @Resource - SerialPortService serialPortService; + SerialPortServer serialPortService; @GetMapping("compare61850") @ApiOperation("比对61850的不同点") @@ -90,12 +89,8 @@ public class TestController extends BasicController { @GetMapping("/discover") public Response discoverSerialPort() { - Boolean aBoolean = serialPortService.discoverSerialPort(); - if (aBoolean) { - return Response.success("发现了"); - } else { + serialPortService.discoverSerialPort(); return Response.fail("未找到"); - } } @GetMapping("/open") @@ -104,14 +99,14 @@ public class TestController extends BasicController { } @GetMapping("/send") - public String sendData(boolean data) throws IOException { + public String sendData() throws IOException { //发送数据注意,提前与接收设备沟通好协议,发送什么样类型的数据设备才可以进行响应,否则设备无响应 - serialPortService.sendData(data); + serialPortService.sendData(); return "Data sent>>>"; } @GetMapping("/close") - public String closeSerialPort(String portname) { + public String closeSerialPort() { serialPortService.closeSerialPort(); return "Serial port closed"; } diff --git a/src/main/java/com/xydl/cac/model/StaticVariable.java b/src/main/java/com/xydl/cac/model/StaticVariable.java index 708cd51..e8baf76 100644 --- a/src/main/java/com/xydl/cac/model/StaticVariable.java +++ b/src/main/java/com/xydl/cac/model/StaticVariable.java @@ -30,8 +30,7 @@ public class StaticVariable { public static List zsb_Cache = null; public static ConcurrentHashMap rule_Cache = new ConcurrentHashMap<>(); - public static SerialPort currentPort; - public static Date LastWarningTime;//最后一次硬接点告警时间 + public static void wait(int seconds) throws InterruptedException { for (int i = 0; i < seconds; i++) { diff --git a/src/main/java/com/xydl/cac/service/impl/DataListener.java b/src/main/java/com/xydl/cac/serialport/DataListener.java similarity index 97% rename from src/main/java/com/xydl/cac/service/impl/DataListener.java rename to src/main/java/com/xydl/cac/serialport/DataListener.java index 4306f3e..c46e87a 100644 --- a/src/main/java/com/xydl/cac/service/impl/DataListener.java +++ b/src/main/java/com/xydl/cac/serialport/DataListener.java @@ -1,4 +1,4 @@ -package com.xydl.cac.service.impl; +package com.xydl.cac.serialport; import com.fazecast.jSerialComm.SerialPort; import com.fazecast.jSerialComm.SerialPortDataListener; diff --git a/src/main/java/com/xydl/cac/serialport/SerialPortServer.java b/src/main/java/com/xydl/cac/serialport/SerialPortServer.java new file mode 100644 index 0000000..91356e5 --- /dev/null +++ b/src/main/java/com/xydl/cac/serialport/SerialPortServer.java @@ -0,0 +1,137 @@ +package com.xydl.cac.serialport; + +import com.fazecast.jSerialComm.SerialPort; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; + +@Service +@Slf4j +public class SerialPortServer { + + @Value("${cac.warnport.name}") + public String warnportname; + @Value("${cac.warnport.intervaltime:60}") + public Integer intervaltime; + @Value("${cac.warnport.warntime:5}") + public Integer warntime; + + public SerialPort currentPort;//当前可用串口 + public long LastWarningTime;//最后一次硬接点告警时间 + public boolean started = false; + + public void discoverSerialPort() { + if (currentPort == null) { + List serialPortList = new ArrayList<>(); + SerialPort[] commPorts = SerialPort.getCommPorts(); + if (commPorts != null && commPorts.length > 0) { + serialPortList = Arrays.asList(commPorts); + for (SerialPort port : serialPortList) { + log.info("获取串口: " + port.getSystemPortName()); + Pattern pattern = Pattern.compile("ttyCH341."); + String systemPortName = port.getSystemPortName(); + if (systemPortName != null) { + if (pattern.matcher(systemPortName).matches()) { + currentPort = port; + log.info("获取到硬接点告警串口: " + port.getSystemPortName()); + } + } + } + } else { + log.error("未获取到硬接点告警串口!"); + } + } + } + + public void closeSerialPort() { + if (currentPort != null) { + SerialPort port = currentPort; + port.closePort(); + } else { + log.error("断开串口失败,没有对应的硬接点告警串口!"); + } + } + + + //发送数据到串口 + @Async + public void sendData() { + if (!started) { + started = true; + if (openSerialPort()) { + byte[] openbuffer = new byte[]{00, (byte) 0xf1, (byte) 0xff};//发送串口告警 + byte[] stopbuffer = new byte[]{00, (byte) 0x01, (byte) 0xff};//关闭串口告警 + SerialPort port = currentPort; + if (port != null) { + long l = System.currentTimeMillis(); + if (LastWarningTime == 0) { + LastWarningTime = l; + } else { + if (l - LastWarningTime <= (intervaltime * 1000)) { + started = false; + return; + } + } + LastWarningTime = l; + port.writeBytes(openbuffer, openbuffer.length); + try { + Thread.sleep(warntime * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + port.writeBytes(stopbuffer, stopbuffer.length); + started = false; + } + } + } + started = false; + } + } + + + public Boolean openSerialPort() { + discoverSerialPort(); + if (currentPort != null) { + if (currentPort.isOpen()) { + log.info("硬接点告警串口已经打开!"); + return true; + } else { + int baudRate = 9600; // 波特率 + int parity = SerialPort.EVEN_PARITY; // 校验位 + int dataBits = 8; // 数据位 + int stopBits = SerialPort.ONE_STOP_BIT; // 停止位 + try { + boolean setComResult = currentPort.setComPortParameters(baudRate, dataBits, stopBits, parity); // 设置参数 + boolean setComTimes = currentPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 20000, 0); // 设置超时 + if (setComResult && setComTimes) { + currentPort.addDataListener(new DataListener(currentPort.getSystemPortName())); + } + boolean b = currentPort.openPort(); + if (b) { + log.info("打开硬接点告警串口成功!"); + return true; + } else { + currentPort = null; + log.error("打开串口失败!"); + return false; + } + } catch (Exception e) { + e.printStackTrace(); + currentPort = null; + log.error("打开串口失败" + e.getMessage()); + return false; + } + } + } else { + log.error("打开串口失败,找不到硬接点串口!"); + return false; + } + } + +} diff --git a/src/main/java/com/xydl/cac/service/SerialPortService.java b/src/main/java/com/xydl/cac/service/SerialPortService.java deleted file mode 100644 index 45fe2d4..0000000 --- a/src/main/java/com/xydl/cac/service/SerialPortService.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.xydl.cac.service; - -import com.fazecast.jSerialComm.SerialPort; - -import java.io.IOException; -import java.util.List; - -public interface SerialPortService { - Boolean discoverSerialPort(); - - void closeSerialPort(); - - Boolean openSerialPort(); - - void sendData(boolean data) throws IOException; -} diff --git a/src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java b/src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java deleted file mode 100644 index efd069e..0000000 --- a/src/main/java/com/xydl/cac/service/impl/SerialPortServiceImpl.java +++ /dev/null @@ -1,137 +0,0 @@ -package com.xydl.cac.service.impl; - -import com.fazecast.jSerialComm.SerialPort; -import com.xydl.cac.model.StaticVariable; -import com.xydl.cac.service.SerialPortService; -import com.xydl.cac.util.DateUtil; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Service; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.List; - -@Service -@Slf4j -public class SerialPortServiceImpl implements SerialPortService { - - @Value("${cac.warnport.name}") - public String warnportname; - @Value("${cac.warnport.intervaltime:60000}") - public Integer intervaltime; - @Value("${cac.warnport.warntime:5000}") - public Integer warntime; - - @Override - public Boolean discoverSerialPort() { - List serialPortList = new ArrayList<>(); - SerialPort[] commPorts = SerialPort.getCommPorts(); - if (commPorts != null && commPorts.length > 0) { - serialPortList = Arrays.asList(commPorts); - for (SerialPort port : serialPortList) { - log.info("获取串口: " + port.getSystemPortName()); - if (port.getSystemPortName().equals(warnportname)) { - StaticVariable.currentPort = port; - log.info("获取到硬接点告警串口: " + port.getSystemPortName()); - return true; - } - } - return false; - } else { - log.error("未获取到硬接点告警串口!"); - return false; - } - } - - @Override - public void closeSerialPort() { - if (StaticVariable.currentPort != null) { - SerialPort port = StaticVariable.currentPort; - port.closePort(); - } else { - log.error("断开串口失败,没有对应的硬接点告警串口!"); - } - } - - - //发送数据到串口 - @Override - @Async - public void sendData(boolean data) { - if (openSerialPort()) { - byte[] openbuffer = new byte[]{00, (byte) 0xf1, (byte) 0xff};//发送串口告警 - byte[] stopbuffer = new byte[]{00, (byte) 0x01, (byte) 0xff};//关闭串口告警 - SerialPort port = StaticVariable.currentPort; - if (port != null) { - Date date = new Date(); - if (StaticVariable.LastWarningTime == null) { - StaticVariable.LastWarningTime = new Date(); - } else { - long lastWarningTimeTime = StaticVariable.LastWarningTime.getTime(); - long time = date.getTime(); - if (time - lastWarningTimeTime <= intervaltime) { - return; - } - } - StaticVariable.LastWarningTime = date; - port.writeBytes(openbuffer, openbuffer.length); - try { - Thread.sleep(warntime); - } catch (InterruptedException e) { - e.printStackTrace(); - } finally { - port.writeBytes(stopbuffer, stopbuffer.length); - } - } - } - } - - - @Override - public Boolean openSerialPort() { - Boolean discover = false; - if (StaticVariable.currentPort == null) { - discover = discoverSerialPort(); - } else { - discover = true; - } - if (discover) { - SerialPort port = StaticVariable.currentPort; - if (port.isOpen()) { - log.info("硬接点告警串口已经打开!"); - return true; - } else { - int baudRate = 9600; // 波特率 - int parity = SerialPort.EVEN_PARITY; // 校验位 - int dataBits = 8; // 数据位 - int stopBits = SerialPort.ONE_STOP_BIT; // 停止位 - try { - boolean setComResult = port.setComPortParameters(baudRate, dataBits, stopBits, parity); // 设置参数 - boolean setComTimes = port.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 20000, 0); // 设置超时 - if (setComResult && setComTimes) { - port.addDataListener(new DataListener(port.getSystemPortName())); - } - boolean b = port.openPort(); - if (b) { - log.info("打开硬接点告警串口成功!"); - return true; - } else { - log.error("打开串口失败!"); - return false; - } - } catch (Exception e) { - e.printStackTrace(); - log.error("打开串口失败" + e.getMessage()); - return false; - } - } - } else { - log.error("打开串口失败,找不到硬接点串口!"); - return false; - } - } - -} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index d6cface..e3ccde9 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -51,5 +51,5 @@ cac: rsakey: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKNPuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gAkM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWowcSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99EcvDQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthhYhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3UP8iWi1Qw0Y= warnport: name: ttyCH341USB0 - intervaltime: 60000 - warntime: 5000 + intervaltime: 60 + warntime: 5 From 9232abfa743066362fdb9b7d455041f2ac879f97 Mon Sep 17 00:00:00 2001 From: liuguijing <123456> Date: Tue, 10 Dec 2024 14:50:46 +0800 Subject: [PATCH 20/30] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E7=A1=AC=E6=8E=A5?= =?UTF-8?q?=E7=82=B9=E8=A3=85=E7=BD=AE=E7=9D=A1=E7=9C=A0=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xydl/cac/serialport/SerialPortServer.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/xydl/cac/serialport/SerialPortServer.java b/src/main/java/com/xydl/cac/serialport/SerialPortServer.java index 91356e5..1fbd079 100644 --- a/src/main/java/com/xydl/cac/serialport/SerialPortServer.java +++ b/src/main/java/com/xydl/cac/serialport/SerialPortServer.java @@ -1,6 +1,7 @@ package com.xydl.cac.serialport; import com.fazecast.jSerialComm.SerialPort; +import com.xydl.cac.model.StaticVariable; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Async; @@ -80,14 +81,17 @@ public class SerialPortServer { } LastWarningTime = l; port.writeBytes(openbuffer, openbuffer.length); - try { - Thread.sleep(warntime * 1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } finally { - port.writeBytes(stopbuffer, stopbuffer.length); - started = false; + int seconds = 0; + while (StaticVariable.shutdown == 0 && seconds > warntime) { + try { + Thread.sleep(1000); + seconds++; + } catch (Exception ignore) { + port.writeBytes(stopbuffer, stopbuffer.length); + started = false; + } } + port.writeBytes(stopbuffer, stopbuffer.length); } } started = false; From 00779bb90fc3edaca943c801d6cfca90e2efe0fa Mon Sep 17 00:00:00 2001 From: liuguijing <123456> Date: Tue, 10 Dec 2024 14:51:10 +0800 Subject: [PATCH 21/30] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E7=A1=AC=E6=8E=A5?= =?UTF-8?q?=E7=82=B9=E8=A3=85=E7=BD=AE=E7=9D=A1=E7=9C=A0=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application-prod.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 4fdf61a..b9815c4 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -51,5 +51,5 @@ cac: rsakey: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKNPuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gAkM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWowcSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99EcvDQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthhYhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3UP8iWi1Qw0Y= warnport: name: ttyCH341USB0 - intervaltime: 60000 - warntime: 5000 \ No newline at end of file + intervaltime: 60 + warntime: 5 \ No newline at end of file From d93dcc1aa641ae20d4365ff8dab0864ba5f7939b Mon Sep 17 00:00:00 2001 From: huangfeng Date: Tue, 10 Dec 2024 15:26:56 +0800 Subject: [PATCH 22/30] =?UTF-8?q?feat:=20=E8=A7=84=E5=88=99=E8=A7=A6?= =?UTF-8?q?=E5=8F=91=E6=98=AF=E9=80=9A=E7=9F=A5=E4=B8=B2=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/xydl/cac/task/RuleCheckTask.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/xydl/cac/task/RuleCheckTask.java b/src/main/java/com/xydl/cac/task/RuleCheckTask.java index c12159b..148d448 100644 --- a/src/main/java/com/xydl/cac/task/RuleCheckTask.java +++ b/src/main/java/com/xydl/cac/task/RuleCheckTask.java @@ -9,6 +9,7 @@ import com.xydl.cac.model.StaticVariable; import com.xydl.cac.model.TriggerModel; import com.xydl.cac.repository.WarnRuleRepository; import com.xydl.cac.repository.WarningRepository; +import com.xydl.cac.serialport.SerialPortServer; import com.xydl.cac.service.DataService; import com.xydl.cac.socket.WebSocketServer; import com.xydl.cac.util.DateUtil; @@ -34,6 +35,8 @@ public class RuleCheckTask { DingTalkPushUtil dingTalkPushUtil; @Resource WebSocketServer webSocketServer; + @Resource + SerialPortServer serialPortServer; int shutdown = 0; @@ -76,7 +79,7 @@ public class RuleCheckTask { } if (rule.getNotifyCom() != null && rule.getNotifyCom().intValue() == Constants.TRUE) { // 通知串口 - + serialPortServer.sendData(); } } } catch (Exception e) { From 5dd76bdf1f7c6ea0cfbdd3dea9c03b5967b41306 Mon Sep 17 00:00:00 2001 From: liuguijing <123456> Date: Tue, 10 Dec 2024 16:07:42 +0800 Subject: [PATCH 23/30] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E7=A1=AC=E6=8E=A5?= =?UTF-8?q?=E7=82=B9=E8=A3=85=E7=BD=AE=E6=8F=90=E7=A4=BA=E6=96=87=E5=AD=97?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xydl/cac/serialport/SerialPortServer.java | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/xydl/cac/serialport/SerialPortServer.java b/src/main/java/com/xydl/cac/serialport/SerialPortServer.java index 1fbd079..795f1f2 100644 --- a/src/main/java/com/xydl/cac/serialport/SerialPortServer.java +++ b/src/main/java/com/xydl/cac/serialport/SerialPortServer.java @@ -7,8 +7,10 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import javax.annotation.PreDestroy; import java.util.ArrayList; import java.util.Arrays; +import java.util.Iterator; import java.util.List; import java.util.regex.Pattern; @@ -16,8 +18,6 @@ import java.util.regex.Pattern; @Slf4j public class SerialPortServer { - @Value("${cac.warnport.name}") - public String warnportname; @Value("${cac.warnport.intervaltime:60}") public Integer intervaltime; @Value("${cac.warnport.warntime:5}") @@ -27,6 +27,9 @@ public class SerialPortServer { public long LastWarningTime;//最后一次硬接点告警时间 public boolean started = false; + byte[] openbuffer = new byte[]{00, (byte) 0xf1, (byte) 0xff};//发送串口告警 + byte[] stopbuffer = new byte[]{00, (byte) 0x01, (byte) 0xff};//关闭串口告警 + public void discoverSerialPort() { if (currentPort == null) { List serialPortList = new ArrayList<>(); @@ -35,25 +38,25 @@ public class SerialPortServer { serialPortList = Arrays.asList(commPorts); for (SerialPort port : serialPortList) { log.info("获取串口: " + port.getSystemPortName()); - Pattern pattern = Pattern.compile("ttyCH341."); String systemPortName = port.getSystemPortName(); if (systemPortName != null) { - if (pattern.matcher(systemPortName).matches()) { + if (systemPortName.startsWith("ttyCH341")) { currentPort = port; log.info("获取到硬接点告警串口: " + port.getSystemPortName()); } } } - } else { - log.error("未获取到硬接点告警串口!"); } + } else { + log.error("硬接点串口存在!"); } + } public void closeSerialPort() { if (currentPort != null) { - SerialPort port = currentPort; - port.closePort(); + log.info("断开串口成功!"); + currentPort.closePort(); } else { log.error("断开串口失败,没有对应的硬接点告警串口!"); } @@ -66,8 +69,6 @@ public class SerialPortServer { if (!started) { started = true; if (openSerialPort()) { - byte[] openbuffer = new byte[]{00, (byte) 0xf1, (byte) 0xff};//发送串口告警 - byte[] stopbuffer = new byte[]{00, (byte) 0x01, (byte) 0xff};//关闭串口告警 SerialPort port = currentPort; if (port != null) { long l = System.currentTimeMillis(); @@ -82,13 +83,11 @@ public class SerialPortServer { LastWarningTime = l; port.writeBytes(openbuffer, openbuffer.length); int seconds = 0; - while (StaticVariable.shutdown == 0 && seconds > warntime) { + while (StaticVariable.shutdown == 0 && seconds < warntime) { try { Thread.sleep(1000); seconds++; } catch (Exception ignore) { - port.writeBytes(stopbuffer, stopbuffer.length); - started = false; } } port.writeBytes(stopbuffer, stopbuffer.length); @@ -138,4 +137,9 @@ public class SerialPortServer { } } + @PreDestroy + private void stop() { + closeSerialPort(); + } + } From 7628e2d5f201df37660eed9f8763ed48e1fe2a9c Mon Sep 17 00:00:00 2001 From: liuguijing <123456> Date: Tue, 10 Dec 2024 16:24:38 +0800 Subject: [PATCH 24/30] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E7=A1=AC=E6=8E=A5?= =?UTF-8?q?=E7=82=B9=E8=A3=85=E7=BD=AE=E4=BE=9D=E8=B5=96=E5=8D=87=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6ce58cc..5528693 100644 --- a/pom.xml +++ b/pom.xml @@ -198,7 +198,7 @@ com.fazecast jSerialComm - 2.6.2 + 2.11.0 From 7eb4ab682dc11716edcc664b333cb1fae51c11b9 Mon Sep 17 00:00:00 2001 From: huangfeng Date: Tue, 10 Dec 2024 16:26:06 +0800 Subject: [PATCH 25/30] =?UTF-8?q?perf:=20=E5=BC=80=E6=9C=BA=E8=AE=A2?= =?UTF-8?q?=E9=98=85=E5=A4=B1=E8=B4=A5=E5=B0=B1=E5=BC=80=E5=A7=8B=E9=87=8D?= =?UTF-8?q?=E8=BF=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/xydl/cac/iec/RealTimeDataService.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/xydl/cac/iec/RealTimeDataService.java b/src/main/java/com/xydl/cac/iec/RealTimeDataService.java index 8216e96..7f2ca3b 100644 --- a/src/main/java/com/xydl/cac/iec/RealTimeDataService.java +++ b/src/main/java/com/xydl/cac/iec/RealTimeDataService.java @@ -38,6 +38,9 @@ public class RealTimeDataService { try { this.startCollect(ied); } catch (Exception ignore) { + NetErrorThread thread = new NetErrorThread(); + thread.iedId = ied.getId(); + thread.run(); } } } From 11731782f34e0cda9058c2e76b00306275cc607d Mon Sep 17 00:00:00 2001 From: huangfeng Date: Tue, 10 Dec 2024 16:47:00 +0800 Subject: [PATCH 26/30] =?UTF-8?q?Revert=20"perf:=20=E5=BC=80=E6=9C=BA?= =?UTF-8?q?=E8=AE=A2=E9=98=85=E5=A4=B1=E8=B4=A5=E5=B0=B1=E5=BC=80=E5=A7=8B?= =?UTF-8?q?=E9=87=8D=E8=BF=9E"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 7eb4ab682dc11716edcc664b333cb1fae51c11b9. --- src/main/java/com/xydl/cac/iec/RealTimeDataService.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/xydl/cac/iec/RealTimeDataService.java b/src/main/java/com/xydl/cac/iec/RealTimeDataService.java index 7f2ca3b..8216e96 100644 --- a/src/main/java/com/xydl/cac/iec/RealTimeDataService.java +++ b/src/main/java/com/xydl/cac/iec/RealTimeDataService.java @@ -38,9 +38,6 @@ public class RealTimeDataService { try { this.startCollect(ied); } catch (Exception ignore) { - NetErrorThread thread = new NetErrorThread(); - thread.iedId = ied.getId(); - thread.run(); } } } From 3f7b3a0dc62d04c658e69b2e21c949fc73fc9d95 Mon Sep 17 00:00:00 2001 From: huangfeng Date: Wed, 11 Dec 2024 09:46:01 +0800 Subject: [PATCH 27/30] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E5=BC=80?= =?UTF-8?q?=E6=9C=BA=E6=97=B6=E5=80=99=E5=92=8C=E9=87=87=E9=9B=86=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E8=A7=A6=E5=8F=91=E7=9A=84=E6=96=AD=E7=BA=BF=E9=87=8D?= =?UTF-8?q?=E8=BF=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/xydl/cac/iec/IEDCollectService.java | 5 ++--- src/main/java/com/xydl/cac/iec/NetErrorThread.java | 4 ++++ src/main/java/com/xydl/cac/iec/RealTimeDataService.java | 2 ++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/xydl/cac/iec/IEDCollectService.java b/src/main/java/com/xydl/cac/iec/IEDCollectService.java index 7f360f5..dfefe1e 100644 --- a/src/main/java/com/xydl/cac/iec/IEDCollectService.java +++ b/src/main/java/com/xydl/cac/iec/IEDCollectService.java @@ -90,9 +90,8 @@ public class IEDCollectService { _webSocketServer.sendMessage(err, null); } if (ex instanceof SocketException) { - NetErrorThread thread = new NetErrorThread(); - thread.iedId = ied.getId(); - thread.run(); + NetErrorThread thread = new NetErrorThread(ied.getId()); + thread.start(); } } finally { iecClient.disconnect(); diff --git a/src/main/java/com/xydl/cac/iec/NetErrorThread.java b/src/main/java/com/xydl/cac/iec/NetErrorThread.java index de210c4..accfbdf 100644 --- a/src/main/java/com/xydl/cac/iec/NetErrorThread.java +++ b/src/main/java/com/xydl/cac/iec/NetErrorThread.java @@ -5,6 +5,10 @@ import com.xydl.cac.model.StaticVariable; public class NetErrorThread extends Thread { public int iedId; + public NetErrorThread(Integer iedid) { + iedId = iedid; + } + @Override public void run() { IecClient iecClient = StaticVariable.realTimeClientMap.get(iedId); diff --git a/src/main/java/com/xydl/cac/iec/RealTimeDataService.java b/src/main/java/com/xydl/cac/iec/RealTimeDataService.java index 8216e96..b34eb52 100644 --- a/src/main/java/com/xydl/cac/iec/RealTimeDataService.java +++ b/src/main/java/com/xydl/cac/iec/RealTimeDataService.java @@ -38,6 +38,8 @@ public class RealTimeDataService { try { this.startCollect(ied); } catch (Exception ignore) { + NetErrorThread thread = new NetErrorThread(ied.getId()); + thread.start(); } } } From fa1037a674c66838bf93f9bee9d159af7615c543 Mon Sep 17 00:00:00 2001 From: liuguijing <123456> Date: Wed, 11 Dec 2024 13:51:20 +0800 Subject: [PATCH 28/30] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E7=A1=AC=E6=8E=A5?= =?UTF-8?q?=E7=82=B9=E8=A3=85=E7=BD=AE=E9=87=8D=E8=BF=9E=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/xydl/cac/serialport/SerialPortServer.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/xydl/cac/serialport/SerialPortServer.java b/src/main/java/com/xydl/cac/serialport/SerialPortServer.java index 795f1f2..0cd89d7 100644 --- a/src/main/java/com/xydl/cac/serialport/SerialPortServer.java +++ b/src/main/java/com/xydl/cac/serialport/SerialPortServer.java @@ -10,16 +10,18 @@ import org.springframework.stereotype.Service; import javax.annotation.PreDestroy; import java.util.ArrayList; import java.util.Arrays; -import java.util.Iterator; import java.util.List; -import java.util.regex.Pattern; @Service @Slf4j public class SerialPortServer { + @Value("${cac.warnport.name}") + public String portname; + @Value("${cac.warnport.intervaltime:60}") public Integer intervaltime; + @Value("${cac.warnport.warntime:5}") public Integer warntime; @@ -40,7 +42,7 @@ public class SerialPortServer { log.info("获取串口: " + port.getSystemPortName()); String systemPortName = port.getSystemPortName(); if (systemPortName != null) { - if (systemPortName.startsWith("ttyCH341")) { + if (systemPortName.startsWith(portname)) { currentPort = port; log.info("获取到硬接点告警串口: " + port.getSystemPortName()); } @@ -50,7 +52,6 @@ public class SerialPortServer { } else { log.error("硬接点串口存在!"); } - } public void closeSerialPort() { @@ -77,10 +78,12 @@ public class SerialPortServer { } else { if (l - LastWarningTime <= (intervaltime * 1000)) { started = false; + log.info("告警频繁,取消告警!"); return; } } LastWarningTime = l; + log.info("开始发送告警!"); port.writeBytes(openbuffer, openbuffer.length); int seconds = 0; while (StaticVariable.shutdown == 0 && seconds < warntime) { @@ -90,10 +93,13 @@ public class SerialPortServer { } catch (Exception ignore) { } } + log.info("开始关闭告警!"); port.writeBytes(stopbuffer, stopbuffer.length); + } } started = false; + closeSerialPort(); } } From bdae1b220d2255ad926ea296701550020e417a40 Mon Sep 17 00:00:00 2001 From: huangfeng Date: Wed, 11 Dec 2024 15:28:41 +0800 Subject: [PATCH 29/30] =?UTF-8?q?fix:=20=E8=A1=A5=E5=85=85=E5=AF=B9icd?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E9=87=8C=E7=9A=84prefix=E7=9A=84=E8=A7=A3?= =?UTF-8?q?=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/xydl/cac/util/IcdXmlUtil.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/com/xydl/cac/util/IcdXmlUtil.java b/src/main/java/com/xydl/cac/util/IcdXmlUtil.java index c59961a..5da9067 100644 --- a/src/main/java/com/xydl/cac/util/IcdXmlUtil.java +++ b/src/main/java/com/xydl/cac/util/IcdXmlUtil.java @@ -98,6 +98,13 @@ public class IcdXmlUtil { String lnInst = fcdaNode.get("lnInst").asText(); String doName = fcdaNode.get("doName").asText(); String fc = fcdaNode.get("fc").asText(); + JsonNode preNode = fcdaNode.get("prefix"); + if (preNode != null) { + String prefix = preNode.asText(); + if (StringUtils.isNotBlank(prefix)) { + lnClass = prefix + lnClass; + } + } JsonNode lnNode = mapLN.get(lnClass + lnInst); String lnType = lnNode.get("lnType").asText(); @@ -154,6 +161,13 @@ public class IcdXmlUtil { for (JsonNode node : list) { String lnClass = node.get("lnClass").asText(); String inst = node.get("inst").asText(); + JsonNode preNode = node.get("prefix"); + if (preNode != null) { + String prefix = preNode.asText(); + if (StringUtils.isNotBlank(prefix)) { + lnClass = prefix + lnClass; + } + } map.put(lnClass + inst, node); } return map; From 2f7465d765ec6afa8d723ca0c47b5024b0bcfafa Mon Sep 17 00:00:00 2001 From: huangfeng Date: Thu, 19 Dec 2024 11:17:30 +0800 Subject: [PATCH 30/30] =?UTF-8?q?fix:=20=E9=87=87=E9=9B=86=E5=88=B0NaN?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BF=BD=E7=95=A5=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/xydl/cac/iec/IEDCollectService.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/xydl/cac/iec/IEDCollectService.java b/src/main/java/com/xydl/cac/iec/IEDCollectService.java index dfefe1e..5543849 100644 --- a/src/main/java/com/xydl/cac/iec/IEDCollectService.java +++ b/src/main/java/com/xydl/cac/iec/IEDCollectService.java @@ -135,6 +135,9 @@ public class IEDCollectService { value = valueNode.getValueString(); String time = timeNode.getValueString(); log.info("采集到" + fc + " " + paramindexNew + "=" + value + ", t=" + time); + if ("NaN".equalsIgnoreCase(value)) { + return; + } time = DateUtil.fromZoneUTCToLocal(time); if (time == null) { return;