Merge branch 'iec61850' into iec104

dev
huangfeng 7 months ago
commit 73d23f7a82

@ -0,0 +1,37 @@
DROP TABLE IF EXISTS `admin`;
CREATE TABLE `admin` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT COMMENT '管理员id',
`name` varchar(45) NOT NULL COMMENT '管理员名称',
`password` varchar(45) NOT NULL COMMENT '管理员密码',
`menus` varchar(45) DEFAULT NULL COMMENT '菜单配置1:显示 0:隐藏',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
LOCK TABLES `admin` WRITE;
INSERT INTO `admin` VALUES (1,'admin','e10adc3949ba59abbe56e057f20f883e','1,1,1,1,1,1,1');
INSERT INTO `admin` VALUES (2,'user','e10adc3949ba59abbe56e057f20f883e','1,1,1,1,0,0,0');
UNLOCK TABLES;
DROP TABLE IF EXISTS `ied_dl_record`;
CREATE TABLE `ied_dl_record` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`config_id` int(11) DEFAULT NULL,
`remote_path` varchar(200) DEFAULT NULL COMMENT '源路径',
`filename` varchar(45) DEFAULT NULL COMMENT '文件名',
`path` varchar(200) DEFAULT NULL COMMENT '本地路径',
`create_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `ied_dl_config`;
CREATE TABLE `ied_dl_config` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ied_id` int(11) DEFAULT NULL,
`dev_id` int(11) DEFAULT NULL COMMENT '装置ID',
`path` varchar(2000) DEFAULT NULL COMMENT '目录',
`contain` varchar(45) DEFAULT NULL COMMENT '包含文字',
`suffix` varchar(45) DEFAULT NULL COMMENT '后缀名',
`todel` int(11) DEFAULT NULL COMMENT '下载后删除',
`active` int(11) DEFAULT NULL COMMENT '0:停用; 1:启用;',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

@ -21,48 +21,13 @@ import com.beanit.asn1bean.ber.types.BerNull;
import com.beanit.asn1bean.ber.types.string.BerVisibleString;
import com.beanit.iec61850bean.internal.BerBoolean;
import com.beanit.iec61850bean.internal.NamedThreadFactory;
import com.beanit.iec61850bean.internal.mms.asn1.AccessResult;
import com.beanit.iec61850bean.internal.mms.asn1.ConfirmedErrorPDU;
import com.beanit.iec61850bean.internal.mms.asn1.ConfirmedRequestPDU;
import com.beanit.iec61850bean.internal.mms.asn1.ConfirmedResponsePDU;
import com.beanit.iec61850bean.internal.mms.asn1.ConfirmedServiceRequest;
import com.beanit.iec61850bean.internal.mms.asn1.ConfirmedServiceResponse;
import com.beanit.iec61850bean.internal.mms.asn1.Data;
import com.beanit.iec61850bean.internal.mms.asn1.DataAccessError;
import com.beanit.iec61850bean.internal.mms.asn1.DefineNamedVariableListRequest;
import com.beanit.iec61850bean.internal.mms.asn1.DefineNamedVariableListResponse;
import com.beanit.iec61850bean.internal.mms.asn1.DeleteNamedVariableListRequest;
import com.beanit.iec61850bean.internal.mms.asn1.DeleteNamedVariableListResponse;
import com.beanit.iec61850bean.internal.mms.asn1.GetNameListRequest;
import com.beanit.iec61850bean.internal.mms.asn1.GetNameListResponse;
import com.beanit.iec61850bean.internal.mms.asn1.*;
import com.beanit.iec61850bean.internal.mms.asn1.GetNameListResponse.ListOfIdentifier;
import com.beanit.iec61850bean.internal.mms.asn1.GetNamedVariableListAttributesResponse;
import com.beanit.iec61850bean.internal.mms.asn1.GetVariableAccessAttributesRequest;
import com.beanit.iec61850bean.internal.mms.asn1.GetVariableAccessAttributesResponse;
import com.beanit.iec61850bean.internal.mms.asn1.Identifier;
import com.beanit.iec61850bean.internal.mms.asn1.InitiateRequestPDU;
import com.beanit.iec61850bean.internal.mms.asn1.InitiateResponsePDU;
import com.beanit.iec61850bean.internal.mms.asn1.Integer16;
import com.beanit.iec61850bean.internal.mms.asn1.Integer32;
import com.beanit.iec61850bean.internal.mms.asn1.Integer8;
import com.beanit.iec61850bean.internal.mms.asn1.MMSpdu;
import com.beanit.iec61850bean.internal.mms.asn1.ObjectName;
import com.beanit.iec61850bean.internal.mms.asn1.ObjectName.DomainSpecific;
import com.beanit.iec61850bean.internal.mms.asn1.ParameterSupportOptions;
import com.beanit.iec61850bean.internal.mms.asn1.ReadRequest;
import com.beanit.iec61850bean.internal.mms.asn1.ReadResponse;
import com.beanit.iec61850bean.internal.mms.asn1.ReadResponse.ListOfAccessResult;
import com.beanit.iec61850bean.internal.mms.asn1.ServiceError.ErrorClass;
import com.beanit.iec61850bean.internal.mms.asn1.ServiceSupportOptions;
import com.beanit.iec61850bean.internal.mms.asn1.TypeDescription;
import com.beanit.iec61850bean.internal.mms.asn1.TypeDescription.Structure;
import com.beanit.iec61850bean.internal.mms.asn1.TypeDescription.Structure.Components;
import com.beanit.iec61850bean.internal.mms.asn1.TypeSpecification;
import com.beanit.iec61850bean.internal.mms.asn1.Unsigned32;
import com.beanit.iec61850bean.internal.mms.asn1.VariableAccessSpecification;
import com.beanit.iec61850bean.internal.mms.asn1.VariableDefs;
import com.beanit.iec61850bean.internal.mms.asn1.WriteRequest;
import com.beanit.iec61850bean.internal.mms.asn1.WriteResponse;
import com.beanit.josistack.AcseAssociation;
import com.beanit.josistack.ByteBufferInputStream;
import com.beanit.josistack.DecodingException;
@ -353,6 +318,12 @@ final class ServerAssociation {
handleDeleteDataSetRequest(confirmedServiceRequest.getDeleteNamedVariableList());
confirmedServiceResponse.setDeleteNamedVariableList(response);
} else if (confirmedServiceRequest.getFileDirectory() != null) {
logger.debug("Got a FileDirectory request");
FileDirectoryResponse response =
handleFileDirectoryRequest(confirmedServiceRequest.getFileDirectory());
confirmedServiceResponse.setFileDirectory(response);
} else {
throw new ServiceError(
ServiceError.FAILED_DUE_TO_COMMUNICATIONS_CONSTRAINT,
@ -618,6 +589,16 @@ final class ServerAssociation {
return getNameListResponse;
}
private FileDirectoryResponse handleFileDirectoryRequest(FileDirectoryRequest request) {
FileName fileSpecification = request.getFileSpecification();
String path = fileSpecification.getBerGraphicString().get(0).toString();
FileDirectoryResponse response = new FileDirectoryResponse();
FileDirectoryResponse.ListOfDirectoryEntry list = new FileDirectoryResponse.ListOfDirectoryEntry();
list.getDirectoryEntry();
response.setListOfDirectoryEntry(list);
return response;
}
/**
* GetVariableAccessAttributes (GetDataDefinition/GetDataDirectory) can be called with different
* kinds of references. Examples: 1. DGEN1 2. DGEN1$CF 3. DGEN1$CF$GnBlk

@ -1,6 +1,5 @@
package com.xydl.cac.controller;
import com.xydl.cac.iec.IecClient;
import com.xydl.cac.model.Response;
import com.xydl.cac.model.StaticVariable;
import com.xydl.cac.service.IcdFileConfigService;
@ -40,9 +39,28 @@ public class TestController extends BasicController {
webSocketServer.sendMessage(msg, warningId);
}
@GetMapping("realTimeMap")
@ApiOperation("实时订阅Map")
public Response<HashMap<Integer, IecClient>> realTimeMap() {
@GetMapping("realTimeClientMap")
@ApiOperation("realTimeClientMap")
public Response<HashMap> realTimeClientMap() {
return Response.success(StaticVariable.realTimeClientMap);
}
@GetMapping("paramRelationMap")
@ApiOperation("paramRelationMap")
public Response<HashMap> paramRelationMap() {
return Response.success(StaticVariable.paramRelationMap);
}
@GetMapping("sensorLastDataMap")
@ApiOperation("sensorLastDataMap")
public Response<HashMap> sensorLastDataMap() {
return Response.success(StaticVariable.sensorLastDataMap);
}
@GetMapping("clearMap")
@ApiOperation("clearMap")
public void clearMap() {
StaticVariable.sensorLastDataMap.clear();
StaticVariable.paramRelationMap.clear();
}
}

@ -35,4 +35,8 @@ public class Admin {
@Column(name = "password")
private String password;
@ApiModelProperty("菜单配置 1:显示 0:隐藏")
@Column(name = "menus")
private String menus;
}

@ -40,6 +40,10 @@ public class IedDlConfig {
@Column(name = "path")
private String path;
@ApiModelProperty("包含名字")
@Column(name = "contain")
private String contain;
@ApiModelProperty("后缀名")
@Column(name = "suffix")
private String suffix;

@ -30,7 +30,11 @@ public class IedDlRecord {
@Column(name = "config_id")
private Integer configId;
@ApiModelProperty("路径")
@ApiModelProperty("源路径")
@Column(name = "remote_path")
private String remotePath;
@ApiModelProperty("本地路径")
@Column(name = "path")
private String path;

@ -30,11 +30,11 @@ public class RemoteDownload {
@Column(name = "config_id")
private Integer configId;
@ApiModelProperty("路径")
@ApiModelProperty("路径")
@Column(name = "remote_path")
private String remotePath;
@ApiModelProperty("路径")
@ApiModelProperty("本地路径")
@Column(name = "path")
private String path;

@ -10,6 +10,7 @@ import com.xydl.cac.repository.*;
import com.xydl.cac.service.DataService;
import com.xydl.cac.service.IedDlRecordService;
import com.xydl.cac.socket.WebSocketServer;
import com.xydl.cac.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
@ -33,6 +34,7 @@ public class IEDCollectService {
BizConfig _bizConfig;
String folder = "/record";
HashMap<Integer, String> eqmidTimeMap = new HashMap<>();
public IEDCollectService(IcdConfigTypeRepository configRepository, IcdConfigTypeAttRepository attRepository,
IcdConfigTypeInstRepository instRepository, RptparamindexRepository rptparamindexRepository,
@ -69,6 +71,7 @@ public class IEDCollectService {
try {
log.info("61850开始采集数据, ied=" + ied.getName() + ", ip=" + ied.getIp() + ", port=" + ied.getPort());
this.connect();
eqmidTimeMap.clear();
if (!CollectionUtils.isEmpty(rptList)) {
this.doCollectAndSave(configTypeList, rptList);
}
@ -116,7 +119,8 @@ public class IEDCollectService {
String value = iecClient.getValue(paramindexNew, fc);
String time = iecClient.getValue(paramindexT, fc);
log.info("采集到" + fc + " " + paramindexNew + "=" + value + ", t=" + time);
time = time.replace("T", " ").replace("Z", "").replace("z", "");
time = DateUtil.fromZoneUTCToLocal(time);
time = this.makeSameTime(rpt.getEqmid(), time);
_dataService.insertData(rpt.getTablename(), rpt.getEqmid(), time, rpt.getColname(), value);
// 更新最新数据缓存
@ -131,6 +135,15 @@ public class IEDCollectService {
StaticVariable.paramRelationMap.put(key, value);
}
private String makeSameTime(Integer eqmid, String time) {
String sameTime = eqmidTimeMap.get(eqmid);
if (StringUtils.isBlank(sameTime)) {
sameTime = time;
eqmidTimeMap.put(eqmid, sameTime);
}
return sameTime;
}
private Rptparamindex findRpt(List<Rptparamindex> rptList, String paramindex) {
for (Rptparamindex rpt : rptList) {
if (rpt.getParamindex().equals(paramindex)) {
@ -153,6 +166,9 @@ public class IEDCollectService {
if (StringUtils.isBlank(config.getPath())) {
return;
}
if (!config.getPath().endsWith("/")) {
config.setPath(config.getPath() + "/");
}
if (config.getDevId() == null) {
return;
}
@ -162,18 +178,20 @@ public class IEDCollectService {
for (FileInformation file : fileList) {
String filename = file.getFilename();
if (!filename.endsWith("/")) {
if (StringUtils.isBlank(config.getSuffix()) ||
filename.toLowerCase().endsWith(config.getSuffix().toLowerCase())) {
if (matchSuffix(filename, config.getSuffix())
&& matchContain(filename, config.getContain())) {
IedDlRecord record = new IedDlRecord();
record.setConfigId(config.getId());
record.setFilename(filename);
record.setRemotePath(config.getPath() + filename);
boolean exist = _dlRecordService.exist(record);
if (!exist) {
String localFilePath = localPath + "/" + filename;
iecClient.getFile(config.getPath(), filename, _bizConfig.getDatapath() + localFilePath, config.getTodel());
iecClient.getFile(record.getRemotePath(), _bizConfig.getDatapath() + localFilePath, config.getTodel());
record.setPath(_bizConfig.getDataNginxPath() + localFilePath);
record.setCreateTime(new Date());
_dlRecordService.add(record);
log.info("采集到" + record.getRemotePath());
}
}
}
@ -189,6 +207,28 @@ public class IEDCollectService {
}
}
private boolean matchSuffix(String filename, String suffix) {
if (StringUtils.isBlank(suffix)) {
return true;
} else {
if (filename.toLowerCase().endsWith(suffix.toLowerCase())) {
return true;
}
return false;
}
}
private boolean matchContain(String filename, String contain) {
if (StringUtils.isBlank(contain)) {
return true;
} else {
if (filename.toLowerCase().contains(contain.toLowerCase())) {
return true;
}
return false;
}
}
public static void updateLastData(Integer eqmid, String colname, String value, String time) {
HashMap<String, String> map = StaticVariable.sensorLastDataMap.get(eqmid);
if (map == null) {
@ -212,7 +252,7 @@ public class IEDCollectService {
String colname = str[1];
value = bda.getValueString();
if ("acquisitionTime".equals(colname)) {
value = value.replace("T", " ").replace("Z", "").replace("z", "");
value = DateUtil.fromZoneUTCToLocal(value);
}
updateLastData(eqmid, colname, value, null);
}

@ -3,6 +3,7 @@ package com.xydl.cac.iec;
import com.beanit.iec61850bean.*;
import com.xydl.cac.entity.IcdIed;
import com.xydl.cac.entity.constants.Constants;
import com.xydl.cac.exception.BusinessException;
import com.xydl.cac.model.StaticVariable;
import com.xydl.cac.socket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
@ -95,6 +96,9 @@ public class IecClient implements ClientEventListener {
public String getValue(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();
@ -148,11 +152,11 @@ public class IecClient implements ClientEventListener {
return list;
}
public void getFile(String remotePath, String filename, String localPath, Integer todel) throws Exception {
public void getFile(String remotePath, String localPath, Integer todel) throws Exception {
GetFileAction gfa = new GetFileAction(localPath);
clientAssociation.getFile(remotePath + filename, gfa);
clientAssociation.getFile(remotePath, gfa);
if (todel != null && todel == Constants.TRUE) {
clientAssociation.deleteFile(remotePath + filename);
clientAssociation.deleteFile(remotePath);
}
}
@ -213,7 +217,7 @@ public class IecClient implements ClientEventListener {
str = iecClient.getValue("OMDLMONT/SPDC1.MaxDsch.t", "MX");
System.out.println(str);
List<FileInformation> list = iecClient.listFile("/fdata");
iecClient.getFile("/fdata/web/comtrade/1/18/6/", "20241021_113736_703_0_0.dat", "/eqmid/20241021_113736_703_0_0.dat", 1);
iecClient.getFile("/fdata/web/comtrade/1/18/6/20241021_113736_703_0_0.dat", "/eqmid/20241021_113736_703_0_0.dat", 1);
} catch (Exception ex) {
ex.printStackTrace();

@ -17,17 +17,20 @@ public class CacheTask {
@Resource
WarnRuleService ruleService;
@Scheduled(cron = "0 0 9 * * ?")
private void clearCache() {
@Scheduled(cron = "0 0 1 * * ?")
private void clearCache1() {
StaticVariable.unit_Cache.clear();
StaticVariable.modevType_Cache = null;
StaticVariable.jg_Cache = null;
StaticVariable.zsb_Cache = null;
StaticVariable.rule_Cache.clear();
StaticVariable.doneWarnMap.clear();
StaticVariable.paramRelationMap.clear();
}
@Scheduled(cron = "0 30 9 * * ?")
private void clearCache9() {
StaticVariable.doneWarnMap.clear();
}
@Scheduled(initialDelay = 30 * 1000, fixedDelay = 60 * 1000)
private void refreshRule() {

@ -2,14 +2,15 @@ package com.xydl.cac.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;
public class DateUtil {
public final static String defaultDatePattern = "yyyy-MM-dd HH:mm:ss";
public static DateTimeFormatter defaultFormatter = DateTimeFormatter.ofPattern(defaultDatePattern);
/**
* date pattern
@ -89,10 +90,47 @@ public class DateUtil {
return cal.getTime();
}
public static Date addHour(Date date, int n) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.HOUR, n);
return cal.getTime();
}
public static long getDifferenceInDays(Date startDate, Date endDate) {
LocalDate startLocalDate = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate endLocalDate = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
return ChronoUnit.DAYS.between(startLocalDate, endLocalDate);
}
public static String fromZoneUTCToLocal(String str) throws ParseException {
String time = str.replace("T", " ")
.replace("Z", "").replace("z", "");
Date date = parse(time);
time = format(date);
LocalDateTime localtime = LocalDateTime.parse(time, defaultFormatter);
ZonedDateTime zonedDateTime = localtime.atZone(ZoneOffset.UTC);
ZonedDateTime convertedDateTime = zonedDateTime.withZoneSameInstant(ZoneId.systemDefault());
String result = convertedDateTime.format(defaultFormatter);
return result;
}
public static long secondDiff(String str1, String str2) {
try {
Date date1 = parse(str1);
Date date2 = parse(str2);
long sec1 = date1.getTime();
long sec2 = date2.getTime();
if (sec1 >= sec2) {
long sec = sec1 - sec2;
return sec / 1000;
} else {
long sec = sec2 - sec1;
return sec / 1000;
}
} catch (Exception e) {
return -1;
}
}
}

@ -10,9 +10,9 @@ spring:
time-zone: GMT+8
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/iec104?charset=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&connectTimeout=60000&socketTimeout=60000
username: iec
password: Iec@1043
url: jdbc:mysql://127.0.0.1:3306/cacdb?charset=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&connectTimeout=60000&socketTimeout=60000
username: root
password: 123456
data:
jdbc:
repositories:

Loading…
Cancel
Save