feat: 把订阅到的数据更新到服务端上

dev
huangfeng 8 months ago
parent 2ceaadb1e2
commit 711d9616cd

@ -2,6 +2,7 @@ package com.xydl.cac.controller;
import com.xydl.cac.iec.IecServerService; import com.xydl.cac.iec.IecServerService;
import com.xydl.cac.model.Response; import com.xydl.cac.model.Response;
import com.xydl.cac.service.RealTimeService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -20,17 +21,21 @@ public class IecServerController extends BasicController {
@Resource @Resource
IecServerService iecServerService; IecServerService iecServerService;
@Resource
RealTimeService realTimeService;
@GetMapping("start") @GetMapping("start")
@ApiOperation("启动IEC服务端") @ApiOperation("启动IEC服务端")
public Response<String> start() throws Exception { public Response<String> start() throws Exception {
iecServerService.startServer(); iecServerService.startServer();
realTimeService.start();
return Response.success("OK"); return Response.success("OK");
} }
@GetMapping("stop") @GetMapping("stop")
@ApiOperation("停止IEC服务端") @ApiOperation("停止IEC服务端")
public Response<String> stop() throws Exception { public Response<String> stop() throws Exception {
realTimeService.stop();
iecServerService.stop(); iecServerService.stop();
return Response.success("OK"); return Response.success("OK");
} }

@ -1,6 +1,7 @@
package com.xydl.cac.iec; package com.xydl.cac.iec;
import com.beanit.iec61850bean.*; import com.beanit.iec61850bean.*;
import com.xydl.cac.service.impl.RealTimeServiceImpl;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -19,6 +20,7 @@ public class IecClient implements ClientEventListener {
ClientSap clientSap = new ClientSap(); ClientSap clientSap = new ClientSap();
ClientAssociation clientAssociation = null; ClientAssociation clientAssociation = null;
ServerModel serverModel; ServerModel serverModel;
Urcb urcb = null;
public void connect(String host, int port, String apTitle, String xml) throws Exception { public void connect(String host, int port, String apTitle, String xml) throws Exception {
InputStream in = IOUtils.toInputStream(xml, StandardCharsets.UTF_8); InputStream in = IOUtils.toInputStream(xml, StandardCharsets.UTF_8);
@ -64,21 +66,25 @@ public class IecClient implements ClientEventListener {
public void enableReporting() throws Exception { public void enableReporting() throws Exception {
if (!CollectionUtils.isEmpty(serverModel.getUrcbs())) { if (!CollectionUtils.isEmpty(serverModel.getUrcbs())) {
Optional<Urcb> optional = serverModel.getUrcbs().stream().findFirst(); Optional<Urcb> optional = serverModel.getUrcbs().stream().findAny();
Urcb urcb = optional.get(); urcb = optional.get();
clientAssociation.enableReporting(urcb); clientAssociation.enableReporting(urcb);
} }
} }
public void disableReporting() {
if (urcb != null) {
try {
clientAssociation.disableReporting(urcb);
} catch (Exception ignore) {
}
}
}
@Override @Override
public void newReport(Report report) { public void newReport(Report report) {
if (report != null && report.getValues() != null) { if (report != null) {
for (FcModelNode node : report.getValues()) { RealTimeServiceImpl.processReport(report);
if (node instanceof FcDataObject) {
String str = ((FcDataObject) node).toString();
log.info(str);
}
}
} }
} }

@ -6,22 +6,26 @@ import org.apache.commons.io.IOUtils;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List; import java.util.List;
@Slf4j @Slf4j
public class IecServer extends Thread implements ServerEventListener { public class IecServer implements ServerEventListener {
ServerSap serverSap = null; ServerSap serverSap = null;
ServerModel serversServerModel = null; ServerModel serversServerModel = null;
public boolean started = false;
public void startServer(String xml, int port) throws Exception {
InputStream in = IOUtils.toInputStream(xml, StandardCharsets.UTF_8); public void start(String xml, int port) throws Exception {
serverSap = new ServerSap(port, 0, null, SclParser.parse(in).get(0), null); if (!started) {
InputStream in = IOUtils.toInputStream(xml, StandardCharsets.UTF_8);
serverSap.setPort(port); serverSap = new ServerSap(port, 0, null, SclParser.parse(in).get(0), null);
serverSap.startListening(this);
serversServerModel = serverSap.getModelCopy(); serverSap.setPort(port);
this.start(); serverSap.startListening(this);
log.info("已启动IEC61850服务端."); serversServerModel = serverSap.getModelCopy();
started = true;
log.info("已启动IEC61850服务端在" + port + "端口");
}
} }
public void close() { public void close() {
@ -29,6 +33,15 @@ public class IecServer extends Thread implements ServerEventListener {
serverSap.stop(); serverSap.stop();
log.info("已停止IEC61850服务端."); log.info("已停止IEC61850服务端.");
} }
started = false;
}
public void updateBda(BasicDataAttribute bda) {
BasicDataAttribute node = (BasicDataAttribute) serversServerModel.findModelNode(bda.getReference(), bda.getFc());
node.setValueFrom(bda);
List<BasicDataAttribute> bdas = new ArrayList<>();
bdas.add(node);
serverSap.setValues(bdas);
} }
@Override @Override

@ -2,7 +2,7 @@ package com.xydl.cac.iec;
import com.xydl.cac.entity.IcdFile; import com.xydl.cac.entity.IcdFile;
import com.xydl.cac.repository.IcdFileRepository; import com.xydl.cac.repository.IcdFileRepository;
import com.xydl.cac.service.RealTimeService; import com.xydl.cac.service.impl.RealTimeServiceImpl;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@ -18,42 +18,34 @@ public class IecServerService {
@Resource @Resource
IcdFileRepository fileRepository; IcdFileRepository fileRepository;
@Resource
RealTimeService realTimeService;
IecServer iecServer = new IecServer(); IecServer iecServer = new IecServer();
boolean started = false;
public void startServer() { public void startServer() {
if (!started) { List<IcdFile> icdFileList = fileRepository.findAll();
List<IcdFile> icdFileList = fileRepository.findAll(); if (!CollectionUtils.isEmpty(icdFileList)) {
if (!CollectionUtils.isEmpty(icdFileList)) { IcdFile icdFile = icdFileList.get(0);
IcdFile icdFile = icdFileList.get(0); try {
try { iecServer.start(icdFile.getXml(), 102);
iecServer.startServer(icdFile.getXml(), 102); RealTimeServiceImpl.iecServer = iecServer;
started = true; } catch (Exception e) {
log.error("启动IEC61850服务端异常.", e);
realTimeService.start();
} catch (Exception e) {
log.error("启动IEC61850服务端异常.", e);
}
} }
} }
} }
@PreDestroy @PreDestroy
public void stop() { public void stop() {
realTimeService.stop(); RealTimeServiceImpl.iecServer = null;
if (iecServer != null) { if (iecServer != null) {
iecServer.close(); iecServer.close();
started = false;
} }
} }
public HashMap<String, Object> status() { public HashMap<String, Object> status() {
HashMap<String, Object> map = new HashMap<>(); HashMap<String, Object> map = new HashMap<>();
map.put("port", 102); map.put("port", 102);
map.put("started", started); map.put("started", iecServer.started);
return map; return map;
} }
} }

@ -1,8 +1,10 @@
package com.xydl.cac.service.impl; package com.xydl.cac.service.impl;
import com.beanit.iec61850bean.*;
import com.xydl.cac.entity.IcdFile; import com.xydl.cac.entity.IcdFile;
import com.xydl.cac.entity.IcdIed; import com.xydl.cac.entity.IcdIed;
import com.xydl.cac.iec.IecClient; import com.xydl.cac.iec.IecClient;
import com.xydl.cac.iec.IecServer;
import com.xydl.cac.repository.*; import com.xydl.cac.repository.*;
import com.xydl.cac.service.RealTimeService; import com.xydl.cac.service.RealTimeService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -25,6 +27,8 @@ public class RealTimeServiceImpl implements RealTimeService {
@Resource @Resource
IcdIedRepository iedRepository; IcdIedRepository iedRepository;
public static HashMap<String, String> dataMap = new HashMap<>();
public static IecServer iecServer = null;
HashMap<String, IecClient> clientMap = new HashMap<>(); HashMap<String, IecClient> clientMap = new HashMap<>();
@Override @Override
@ -57,8 +61,50 @@ public class RealTimeServiceImpl implements RealTimeService {
while (it.hasNext()) { while (it.hasNext()) {
String key = it.next(); String key = it.next();
IecClient iecClient = clientMap.get(key); IecClient iecClient = clientMap.get(key);
iecClient.disableReporting();
iecClient.disconnect(); iecClient.disconnect();
clientMap.remove(key); clientMap.remove(key);
} }
} }
public static void processReport(Report report) {
if (!CollectionUtils.isEmpty(report.getValues())) {
for (FcModelNode node : report.getValues()) {
processNodeValue(node);
}
}
}
private static void processNodeValue(FcModelNode node) {
if (node instanceof FcDataObject) {
FcDataObject fcnode = (FcDataObject) node;
if (!CollectionUtils.isEmpty(fcnode.getChildren())) {
for (ModelNode child : fcnode.getChildren()) {
if (child instanceof BasicDataAttribute) {
BasicDataAttribute bda = (BasicDataAttribute) child;
processBdaNodeValue(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);
}
}
}
}
}
}
}
}
private static void processBdaNodeValue(BasicDataAttribute bda) {
String ref = bda.getReference().toString();
String value = bda.getValueString();
dataMap.put(ref, value);
if (iecServer != null) {
iecServer.updateBda(bda);
}
}
} }

Loading…
Cancel
Save