Merge branch 'iec61850' into iec104

iec104
huangfeng 6 months ago
commit 7e83ef38d5

@ -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;
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `i2sync_field` ADD COLUMN `attach` VARCHAR(45) NULL COMMENT 'sensorid尾部附加' AFTER `dest_field_name`;

@ -0,0 +1 @@
ALTER TABLE `warn_rule` ADD COLUMN `notify_com` INT(11) NULL DEFAULT NULL COMMENT '0:不通知; 1:通知' AFTER `active`;

@ -193,11 +193,19 @@
<artifactId>asn1bean</artifactId>
<version>1.14.0</version>
</dependency>
<dependency>
<groupId>org.openmuc</groupId>
<artifactId>j60870</artifactId>
<version>1.7.2</version>
</dependency>
<!--jSerialComm库串口通讯-->
<dependency>
<groupId>com.fazecast</groupId>
<artifactId>jSerialComm</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
<build>

@ -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<String> prewXml(Integer modevtypeId) throws Exception {
ModevType modevType = modevTypeService.detail(modevtypeId);
List<ModevTypePoint> points = modevTypePointService.listAll(modevtypeId);
List<I2syncField> fieldList = service.listFieldConfig(modevType.getTablename());
List<Attr> 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<Map<String, Object>> dataList = new ArrayList<>();
Map<String, Object> 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<Datanode> 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<String> resp = Response.success(xml);
if (StringUtils.isBlank(node.getType())) {
if (StringUtils.isBlank(modevType.getTypeCode())) {
resp.setWarnMsg("该类型还未配置对应的类型编码将导致type为空");
}
return resp;

@ -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<IcdIed> 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);
return Response.fail(ex.getMessage());
}
}
@PostMapping("stopCollect")
@ -174,7 +192,14 @@ public class IcdConfigController extends BasicController {
if (RealTimeDataService.inDoing) {
throw new BusinessException("请稍后再操作");
}
realTimeDataService.stopCollect(iedId);
Optional<IcdIed> 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");
}

@ -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<List<IcdTransform>> listTransform() throws Exception {
List<IcdTransform> 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);

@ -2,6 +2,7 @@ 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.socket.WebSocketServer;
import io.swagger.annotations.Api;
@ -12,11 +13,12 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
@RestController
@Api(tags = {"测试接口"})
@Api(tags = {"测试接口文档"})
@RequestMapping("test")
@Slf4j
public class TestController extends BasicController {
@ -26,6 +28,9 @@ public class TestController extends BasicController {
@Resource
WebSocketServer webSocketServer;
@Resource
SerialPortServer serialPortService;
@GetMapping("compare61850")
@ApiOperation("比对61850的不同点")
public Response<List<String>> compare61850() throws Exception {
@ -57,10 +62,52 @@ public class TestController extends BasicController {
return Response.success(StaticVariable.sensorLastDataMap);
}
@GetMapping("iecServerMap")
@ApiOperation("iecServerMap")
public Response<HashMap> iecServerMap() {
return Response.success(StaticVariable.iecServerMap);
}
@GetMapping("rptFromActiveMap")
@ApiOperation("rptFromActiveMap")
public Response<HashMap> rptFromActiveMap() {
return Response.success(StaticVariable.rptFromActiveMap);
}
@GetMapping("rptToActiveMap")
@ApiOperation("rptToActiveMap")
public Response<HashMap> rptToActiveMap() {
return Response.success(StaticVariable.rptToActiveMap);
}
@GetMapping("clearMap")
@ApiOperation("clearMap")
public void clearMap() {
StaticVariable.sensorLastDataMap.clear();
StaticVariable.paramRelationMap.clear();
}
@GetMapping("/discover")
public Response<String> discoverSerialPort() {
serialPortService.discoverSerialPort();
return Response.fail("未找到");
}
@GetMapping("/open")
public Response<Boolean> openSerialPort() {
return Response.success(serialPortService.openSerialPort());
}
@GetMapping("/send")
public String sendData() throws IOException {
//发送数据注意,提前与接收设备沟通好协议,发送什么样类型的数据设备才可以进行响应,否则设备无响应
serialPortService.sendData();
return "Data sent>>>";
}
@GetMapping("/close")
public String closeSerialPort() {
serialPortService.closeSerialPort();
return "Serial port closed";
}
}

@ -33,4 +33,7 @@ public class I2syncField {
@Column(name = "dest_field_name")
private String destFieldName;
@Column(name = "attach")
private String attach;
}

@ -46,4 +46,11 @@ public class IcdIed {
@ApiModelProperty(name = "端口")
@Column(name = "port")
private Integer port;
@Transient
private boolean connected;
@Transient
private int retry;
@Transient
private int seconds;
}

@ -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;

@ -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;
@ -55,7 +56,8 @@ public class IEDCollectService {
}
public void connect() throws Exception {
iecClient.connect(ied, xml);
iecClient.init(ied, xml);
iecClient.connect();
}
public void disconnect() {
@ -87,7 +89,10 @@ public class IEDCollectService {
StaticVariable.doneWarnMap.put(key, "1");
_webSocketServer.sendMessage(err, null);
}
RealTimeDataService.onErrorCheck(ied.getId());
if (ex instanceof SocketException) {
NetErrorThread thread = new NetErrorThread(ied.getId());
thread.start();
}
} finally {
iecClient.disconnect();
}
@ -116,23 +121,36 @@ 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);
if ("NaN".equalsIgnoreCase(value)) {
return;
}
time = DateUtil.fromZoneUTCToLocal(time);
if (time == null) {
return;
}
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 +247,4 @@ public class IEDCollectService {
}
}
public static void updateLastData(Integer eqmid, String colname, String value, String time) {
HashMap<String, String> 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) {
}
}
}

@ -29,9 +29,12 @@ 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;
private boolean inRetry = false;
public Date lastReportTime;
public IecClient() {
@ -42,16 +45,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 +76,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,22 +95,31 @@ 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 {
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;
}
@ -119,7 +136,6 @@ public class IecClient implements ClientEventListener {
}
}
log.info("61850订阅成功, ied=" + ied.getName() + ", ip=" + ied.getIp() + ", port=" + ied.getPort());
keep = true;
}
public void disableReporting() {
@ -144,7 +160,6 @@ public class IecClient implements ClientEventListener {
} else {
log.info("61850停止订阅, ied=" + ied.getName() + ", ip=" + ied.getIp() + ", port=" + ied.getPort());
}
keep = false;
}
public List<FileInformation> listFile(String path) throws Exception {
@ -170,36 +185,31 @@ public class IecClient implements ClientEventListener {
@Override
public void associationClosed(IOException e) {
if (keep) {
if (keep && !inRetry) {
inRetry = true;
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);
Thread.sleep(1000);
seconds++;
if (retry < 10 && seconds > 60) {
this.reconnect();
} else if (retry == 4) {
log.warn("61850订阅断线重连已失败5次, ied=" + ied.getName() + ", ip=" + ied.getIp() + ", port=" + ied.getPort());
StaticVariable.wait(60);
} else if (seconds > 60 * 60) {
this.reconnect();
} else if (retry >= 1) {
StaticVariable.wait(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);
}
}
}
inRetry = false;
}
}
@ -211,7 +221,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");

@ -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<BasicDataAttribute> bdas = new ArrayList<>();
bdas.add(node);
IcdTransformServiceImpl.rptToActiveMap.put(rptTo, "1");
StaticVariable.rptToActiveMap.put(rptTo, "1");
serverSap.setValues(bdas);
} else {
StaticVariable.rptToActiveMap.remove(rptTo);
}
}

@ -83,6 +83,7 @@ public class IecServerService {
@PreDestroy
private void stop() {
StaticVariable.shutdown = 1;
Iterator<Integer> it = StaticVariable.iecServerMap.keySet().iterator();
while (it.hasNext()) {
Integer key = it.next();

@ -0,0 +1,19 @@
package com.xydl.cac.iec;
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);
if (iecClient != null) {
iecClient.associationClosed(null);
}
}
}

@ -36,36 +36,32 @@ public class RealTimeDataService {
if (!CollectionUtils.isEmpty(list)) {
for (IcdIed ied : list) {
try {
this.startCollect(ied.getId());
this.startCollect(ied);
} catch (Exception ignore) {
NetErrorThread thread = new NetErrorThread(ied.getId());
thread.start();
}
}
}
}
public void startCollect(Integer iedId) throws BusinessException {
Optional<IcdIed> optional = iedRepository.findById(iedId);
if (!optional.isPresent()) {
throw new BusinessException("未找到该IED");
}
IcdIed ied = optional.get();
public void startCollect(IcdIed ied) throws BusinessException {
Optional<IcdFile> 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);
throw new BusinessException(err);
} finally {
inDoing = false;
@ -73,29 +69,12 @@ public class RealTimeDataService {
}
public void stopCollect(Integer iedId) {
this.onlyStop(iedId);
Optional<IcdIed> 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) {
iecClient.associationClosed(null);
}
}
private void onlyStop(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 +88,7 @@ public class RealTimeDataService {
idList.add(it.next());
}
for (Integer iedId : idList) {
this.onlyStop(iedId);
this.stopCollect(iedId);
}
}
@ -131,14 +110,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 +129,4 @@ public class RealTimeDataService {
}
}
private static void processBdaNodeValue(BasicDataAttribute bda) {
Iterator<Integer> it = StaticVariable.iecServerMap.keySet().iterator();
while (it.hasNext()) {
Integer key = it.next();
IecServer iecServer = StaticVariable.iecServerMap.get(key);
iecServer.updateBda(bda);
}
IEDCollectService.updateLastData(bda);
}
}

@ -1,14 +1,16 @@
package com.xydl.cac.model;
import com.fazecast.jSerialComm.SerialPort;
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.List;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class StaticVariable {
@ -19,6 +21,8 @@ public class StaticVariable {
public static HashMap<String, String> doneWarnMap = new HashMap<>();
public static HashMap<Integer, IecClient> realTimeClientMap = new HashMap<>();
public static int shutdown = 0;
public static HashMap<String, String> rptFromActiveMap = new HashMap<>();
public static HashMap<String, String> rptToActiveMap = new HashMap<>();
public static HashMap<String, String> unit_Cache = new HashMap<>();
public static List<ModevType> modevType_Cache = null;
@ -26,6 +30,8 @@ public class StaticVariable {
public static List<Zsb> zsb_Cache = null;
public static ConcurrentHashMap<Integer, WarnRule> rule_Cache = new ConcurrentHashMap<>();
public static void wait(int seconds) throws InterruptedException {
for (int i = 0; i < seconds; i++) {
if (shutdown == 1) {
@ -34,4 +40,50 @@ public class StaticVariable {
Thread.sleep(1000);
}
}
// 更新服务端
public static void updateServerNodeValue(BasicDataAttribute bda) {
Iterator<Integer> 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<String, String> 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);
if (value == null) {
return;
}
}
updateLastData(eqmid, colname, value, null);
}
} catch (Exception ignore) {
}
}
}

@ -0,0 +1,39 @@
package com.xydl.cac.serialport;
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));
}
}

@ -0,0 +1,151 @@
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;
import org.springframework.stereotype.Service;
import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@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;
public SerialPort currentPort;//当前可用串口
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<SerialPort> 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());
String systemPortName = port.getSystemPortName();
if (systemPortName != null) {
if (systemPortName.startsWith(portname)) {
currentPort = port;
log.info("获取到硬接点告警串口: " + port.getSystemPortName());
}
}
}
}
} else {
log.error("硬接点串口存在!");
}
}
public void closeSerialPort() {
if (currentPort != null) {
log.info("断开串口成功!");
currentPort.closePort();
} else {
log.error("断开串口失败,没有对应的硬接点告警串口!");
}
}
//发送数据到串口
@Async
public void sendData() {
if (!started) {
started = true;
if (openSerialPort()) {
SerialPort port = currentPort;
if (port != null) {
long l = System.currentTimeMillis();
if (LastWarningTime == 0) {
LastWarningTime = l;
} 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) {
try {
Thread.sleep(1000);
seconds++;
} catch (Exception ignore) {
}
}
log.info("开始关闭告警!");
port.writeBytes(stopbuffer, stopbuffer.length);
}
}
started = false;
closeSerialPort();
}
}
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;
}
}
@PreDestroy
private void stop() {
closeSerialPort();
}
}

@ -244,7 +244,7 @@ public class DataServiceImpl implements DataService {
@Override
public List<Map<String, Object>> getLatestData(String tableName, Integer devId, List<ModevTypePoint> points, Date start) throws Exception {
ConditionModel model = new ConditionModel();
model.setPageSize(1000);
model.setPageSize(500);
model.setPageNum(1);
model.setStartTime(start);
model.setExcludeStartTime(true);

@ -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;
@ -40,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 {
@ -108,6 +112,15 @@ public class IcdFileConfigServiceImpl implements IcdFileConfigService {
List<IcdIed> iedList = iedRepository.findByIcdFileId(icdFile.getId());
for (IcdIed ied : iedList) {
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);
}
}
@ -220,6 +233,7 @@ public class IcdFileConfigServiceImpl implements IcdFileConfigService {
configRepository.deleteAll();
fileRepository.deleteAll();
iedRepository.deleteAll();
iedDlConfigRepository.deleteAll();
}
@Override

@ -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<String, String> rptFromActiveMap = new HashMap<>();
public static HashMap<String, String> rptToActiveMap = new HashMap<>();
@Override
@CacheEvict(cacheNames = {"listTransform"}, allEntries = true)

@ -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());

@ -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());
}

@ -4,10 +4,12 @@ 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;
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;
@ -33,6 +35,8 @@ public class RuleCheckTask {
DingTalkPushUtil dingTalkPushUtil;
@Resource
WebSocketServer webSocketServer;
@Resource
SerialPortServer serialPortServer;
int shutdown = 0;
@ -73,6 +77,10 @@ public class RuleCheckTask {
for (TriggerModel model : warnList) {
this.sendWarning(rule, model);
}
if (rule.getNotifyCom() != null && rule.getNotifyCom().intValue() == Constants.TRUE) {
// 通知串口
serialPortServer.sendData();
}
}
} catch (Exception e) {
log.error("RuleCheckTask.ruleCheck error.", e);

@ -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<String, List<I2syncField>> fieldMap = this.sortFieldList(fieldList);
List<Datanode> nodeList = new ArrayList<>();
for (Map<String, Object> map : dataList) {
String date = (String) map.get("acquisitionTime");
Datanode node = new Datanode();
node.setSensorid(sensor.getSensorCode());
node.setEquipmentid(sensor.getEquipmentId());
node.setTimestamp(date);
List<Attr> 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<String> fit = fieldMap.keySet().iterator();
while (fit.hasNext()) {
String attach = fit.next();
List<I2syncField> 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<I2syncField> fieldList, Map<String, Object> dataMap,
List<WarnRule> ruleList) {
List<Attr> 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,63 @@ 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("");
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;
}
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<String, List<I2syncField>> sortFieldList(List<I2syncField> fieldList) {
LinkedHashMap<String, List<I2syncField>> map = new LinkedHashMap<>();
for (I2syncField item : fieldList) {
String attach = item.getAttach();
if (attach == null) {
attach = "";
}
List<I2syncField> list = map.get(attach);
if (list == null) {
list = new ArrayList<>();
map.put(attach, list);
}
list.add(item);
}
return map;
}
private boolean triggerRule(List<WarnRule> ruleList, String fieldName, Object value) {

@ -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();
}
/**
*
* <p>
* 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;
}
/**
* 16byte[]
*
* @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;
}
/**
* 16float
*/
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;
}
/**
* 1610
*
* @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;
}
}

@ -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,9 @@ public class DateUtil {
Date date = parse(time);
time = format(date);
LocalDateTime localtime = LocalDateTime.parse(time, defaultFormatter);
if (localtime.getYear() < 2000) {
return null;
}
ZonedDateTime zonedDateTime = localtime.atZone(ZoneOffset.UTC);
ZonedDateTime convertedDateTime = zonedDateTime.withZoneSameInstant(ZoneId.systemDefault());
String result = convertedDateTime.format(defaultFormatter);

@ -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;

@ -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,7 @@ cac:
token: e65e730cba22e320e16926fd4ff19ce787fa2162d065792bb6562c6d4a4cf328
secret: SEC72e5fb1b4ce7f9fed55386040d599035c50f8d2a181ad66bd1277549f0716124
rsakey: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKNPuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gAkM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWowcSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99EcvDQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthhYhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3UP8iWi1Qw0Y=
warnport:
name: ttyCH341USB0
intervaltime: 60
warntime: 5

@ -49,3 +49,7 @@ cac:
token: e65e730cba22e320e16926fd4ff19ce787fa2162d065792bb6562c6d4a4cf328
secret: SEC72e5fb1b4ce7f9fed55386040d599035c50f8d2a181ad66bd1277549f0716124
rsakey: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKNPuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gAkM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWowcSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99EcvDQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthhYhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3UP8iWi1Qw0Y=
warnport:
name: ttyCH341USB0
intervaltime: 60
warntime: 5
Loading…
Cancel
Save