From 4110a835c84844dbaa296653d0aaf9e0bb969cfd Mon Sep 17 00:00:00 2001 From: caozehui <2427765068@qq.com> Date: Fri, 10 Apr 2026 14:13:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BE=AE=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/PreDetectionController.java | 22 ++ .../SocketFreqConverterDevService.java | 268 ++++++++++++++++++ .../handler/SocketFreqConverterService.java | 221 +++++++++++++++ .../pojo/dto/FreqConverterRespDTO.java | 42 +++ .../pojo/enums/SourceOperateCodeEnum.java | 12 +- .../service/PreDetectionService.java | 5 + .../service/impl/PreDetectionServiceImpl.java | 29 +- .../util/socket/FormalTestManager.java | 3 + .../detection/util/socket/SocketManager.java | 13 +- .../util/socket/cilent/NettyClient.java | 103 +++++++ .../NettyFreqConverterClientHandler.java | 124 ++++++++ .../NettyFreqConverterDevClientHandler.java | 67 +++++ .../socket/config/SocketConnectionConfig.java | 52 ++-- .../gather/dip/mapper/PqDipDataMapper.java | 11 + .../njcn/gather/dip/pojo/po/PqDipData.java | 44 +++ .../gather/dip/service/IPqDipDataService.java | 11 + .../service/impl/PqDipDataServiceImpl.java | 15 + .../mapper/FreqConverterStatusMapper.java | 11 + .../mapper/PqFreqConverterConfigMapper.java | 12 + .../pojo/po/FreqConverterStatus.java | 43 +++ .../pojo/po/PqFreqConverterConfig.java | 53 ++++ .../service/IFreqConverterService.java | 37 +++ .../IPqFreqConverterConfigService.java | 11 + .../impl/FreqConverterServiceImpl.java | 64 +++++ .../PqFreqConverterConfigServiceImpl.java | 15 + entrance/src/main/resources/application.yml | 17 +- 26 files changed, 1268 insertions(+), 37 deletions(-) create mode 100644 detection/src/main/java/com/njcn/gather/detection/handler/SocketFreqConverterDevService.java create mode 100644 detection/src/main/java/com/njcn/gather/detection/handler/SocketFreqConverterService.java create mode 100644 detection/src/main/java/com/njcn/gather/detection/pojo/dto/FreqConverterRespDTO.java create mode 100644 detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettyFreqConverterClientHandler.java create mode 100644 detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettyFreqConverterDevClientHandler.java create mode 100644 detection/src/main/java/com/njcn/gather/dip/mapper/PqDipDataMapper.java create mode 100644 detection/src/main/java/com/njcn/gather/dip/pojo/po/PqDipData.java create mode 100644 detection/src/main/java/com/njcn/gather/dip/service/IPqDipDataService.java create mode 100644 detection/src/main/java/com/njcn/gather/dip/service/impl/PqDipDataServiceImpl.java create mode 100644 detection/src/main/java/com/njcn/gather/freqConverter/mapper/FreqConverterStatusMapper.java create mode 100644 detection/src/main/java/com/njcn/gather/freqConverter/mapper/PqFreqConverterConfigMapper.java create mode 100644 detection/src/main/java/com/njcn/gather/freqConverter/pojo/po/FreqConverterStatus.java create mode 100644 detection/src/main/java/com/njcn/gather/freqConverter/pojo/po/PqFreqConverterConfig.java create mode 100644 detection/src/main/java/com/njcn/gather/freqConverter/service/IFreqConverterService.java create mode 100644 detection/src/main/java/com/njcn/gather/freqConverter/service/IPqFreqConverterConfigService.java create mode 100644 detection/src/main/java/com/njcn/gather/freqConverter/service/impl/FreqConverterServiceImpl.java create mode 100644 detection/src/main/java/com/njcn/gather/freqConverter/service/impl/PqFreqConverterConfigServiceImpl.java diff --git a/detection/src/main/java/com/njcn/gather/detection/controller/PreDetectionController.java b/detection/src/main/java/com/njcn/gather/detection/controller/PreDetectionController.java index f3b2700a..39117106 100644 --- a/detection/src/main/java/com/njcn/gather/detection/controller/PreDetectionController.java +++ b/detection/src/main/java/com/njcn/gather/detection/controller/PreDetectionController.java @@ -176,4 +176,26 @@ public class PreDetectionController extends BaseController { preDetectionService.startCoefficient(); return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe); } + + @OperateInfo(info = LogEnum.SYSTEM_COMMON) + @GetMapping("/startFreqConverter") + @ApiOperation("开启变频器测试") + public HttpResult startFreqConverter(@RequestParam("converterId") String converterId, @RequestParam("monitorId") String monitorId) { + String methodDescribe = getMethodDescribe("startFreqConverter"); + LogUtil.njcnDebug(log, "{}", methodDescribe); + + preDetectionService.startFreqConverter(converterId, monitorId); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe); + } + + @OperateInfo(info = LogEnum.SYSTEM_COMMON) + @GetMapping("/stopFreqConverter") + @ApiOperation("关闭变频器测试") + public HttpResult stopFreqConverter(@RequestParam("converterId") String converterId, @RequestParam("monitorId") String monitorId) { + String methodDescribe = getMethodDescribe("stopFreqConverter"); + LogUtil.njcnDebug(log, "{}", methodDescribe); + + preDetectionService.stopFreqConverter(converterId, monitorId); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe); + } } diff --git a/detection/src/main/java/com/njcn/gather/detection/handler/SocketFreqConverterDevService.java b/detection/src/main/java/com/njcn/gather/detection/handler/SocketFreqConverterDevService.java new file mode 100644 index 00000000..19caeb6f --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/detection/handler/SocketFreqConverterDevService.java @@ -0,0 +1,268 @@ +package com.njcn.gather.detection.handler; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.njcn.gather.detection.pojo.enums.DetectionCodeEnum; +import com.njcn.gather.detection.pojo.enums.SourceOperateCodeEnum; +import com.njcn.gather.detection.pojo.enums.SourceResponseCodeEnum; +import com.njcn.gather.detection.pojo.param.DevPhaseSequenceParam; +import com.njcn.gather.detection.pojo.po.DevData; +import com.njcn.gather.detection.pojo.vo.SocketDataMsg; +import com.njcn.gather.detection.pojo.vo.SocketMsg; +import com.njcn.gather.detection.util.socket.CnSocketUtil; +import com.njcn.gather.detection.util.socket.FormalTestManager; +import com.njcn.gather.detection.util.socket.MsgUtil; +import com.njcn.gather.detection.util.socket.SocketManager; +import com.njcn.gather.detection.util.socket.cilent.NettyClient; +import com.njcn.gather.detection.util.socket.cilent.NettyFreqConverterDevClientHandler; +import com.njcn.gather.detection.util.socket.config.SocketConnectionConfig; +import com.njcn.gather.device.pojo.vo.PreDetection; +import com.njcn.gather.device.service.IPqDevService; +import com.njcn.gather.dip.pojo.po.PqDipData; +import com.njcn.gather.dip.service.IPqDipDataService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; + +@Slf4j +@Service +@RequiredArgsConstructor +public class SocketFreqConverterDevService { + + private final SocketConnectionConfig socketConnectionConfig; + private final IPqDevService pqDevService; + private final IPqDipDataService pqDipDataService; + + /** + * 连接设备Socket + * + * @param monitorId 监测点Id + */ + public void connectSocket(String monitorId) { + if (SocketManager.isChannelActive(monitorId)) { + return; + } + String ip = socketConnectionConfig.getDevice().getIp(); + Integer port = socketConnectionConfig.getDevice().getPort(); + + NettyFreqConverterDevClientHandler handler = new NettyFreqConverterDevClientHandler(monitorId, this); + CompletableFuture.runAsync(() -> { + NettyClient.commonConnect(ip, port, monitorId, handler); + }); + } + + private void init(String converterId, String monitorId) { + FormalTestManager.freqConverterDevStep = null; + FormalTestManager.stopFlag = false; + } + + /** + * 连接设备 + */ + public void connectionDev(String converterId, String monitorId) { + this.init(converterId, monitorId); + + String payload = buildSingleMonitorPayload(monitorId); + if (StrUtil.isBlank(payload)) { + return; + } + + SocketMsg socketMsg = new SocketMsg<>(); + socketMsg.setRequestId(SourceOperateCodeEnum.YJC_SBTXJY.getValue()); + socketMsg.setOperateCode(SourceOperateCodeEnum.DEV_INIT_GATHER_03.getValue()); + socketMsg.setData(payload); + SocketManager.sendMsg(monitorId, JSON.toJSONString(socketMsg)); + FormalTestManager.freqConverterDevStep = SourceOperateCodeEnum.YJC_SBTXJY; + } + + public void handleRead(String monitorId, String msg) { + SocketDataMsg socketDataMsg = MsgUtil.socketDataMsg(msg); + + switch (FormalTestManager.freqConverterDevStep) { + case YJC_SBTXJY: + handleYjcSbtxjy(monitorId, socketDataMsg); + break; + case FORMAL_REAL: + handleFormalReal(monitorId, socketDataMsg); + break; + case QUITE: + handleQuit(monitorId, socketDataMsg); + break; + } + } + + private void handleYjcSbtxjy(String monitorId, SocketDataMsg socketDataMsg) { + SourceResponseCodeEnum responseCodeEnum = SourceResponseCodeEnum.getDictDataEnumByCode(socketDataMsg.getCode()); + switch (Objects.requireNonNull(responseCodeEnum)) { + case SUCCESS: + this.sendGetDipDataMsg(monitorId); + FormalTestManager.freqConverterDevStep = SourceOperateCodeEnum.FORMAL_REAL; + break; + default: + log.info("设备响应异常,monitorId={}, operateCode={}, code={}, data={}", monitorId, socketDataMsg.getOperateCode(), socketDataMsg.getCode(), socketDataMsg.getData()); + break; + } + } + + private void handleFormalReal(String monitorId, SocketDataMsg socketDataMsg) { + SourceResponseCodeEnum responseCodeEnum = SourceResponseCodeEnum.getDictDataEnumByCode(socketDataMsg.getCode()); + + switch (responseCodeEnum) { + case UNPROCESSED_BUSINESS: + break; + case SUCCESS: + case NORMAL_RESPONSE: + DevData devData = JSON.parseObject(socketDataMsg.getData(), DevData.class); + // 如果变频器不是处于 “故障中” 状态,就保存数据,反之,这段时期内的数据不保存 + if (!FormalTestManager.stopFlag) { + saveDipData(devData); + } + break; + case DEV_ERROR: + case DEV_TARGET: + case COMMUNICATION_ERR: + case DATA_RESOLVE: + case NO_INIT_DEV: + default: + log.info("设备响应异常,monitorId={}, operateCode={}, code={}, data={}", monitorId, socketDataMsg.getOperateCode(), socketDataMsg.getCode(), socketDataMsg.getData()); + break; + } + } + + private void handleQuit(String monitorId, SocketDataMsg socketDataMsg) { + SourceResponseCodeEnum responseCodeEnum = SourceResponseCodeEnum.getDictDataEnumByCode(socketDataMsg.getCode()); + + switch (responseCodeEnum) { + case SUCCESS: + cleanup(monitorId, true); + break; + default: + log.warn("设备关闭响应失败,monitorId={}, operateCode={}, code={}, data={}", monitorId, socketDataMsg.getOperateCode(), socketDataMsg.getCode(), socketDataMsg.getData()); + break; + } + } + + public void stopTest(String converterId, String monitorId) { + FormalTestManager.freqConverterDevStep = SourceOperateCodeEnum.QUITE; + sendQuitMsg(monitorId, SourceOperateCodeEnum.QUIT_INIT_03); + } + + + private String buildSingleMonitorPayload(String monitorId) { + String[] split = monitorId.split(CnSocketUtil.SPLIT_TAG); + if (split.length < 2 || StrUtil.isBlank(split[0]) || StrUtil.isBlank(split[1])) { + return null; + } + + List preDetections = pqDevService.getDevInfo(Collections.singletonList(split[0])); + if (CollUtil.isEmpty(preDetections)) { + return null; + } + + PreDetection preDetection = preDetections.get(0); + List monitorList = preDetection.getMonitorList(); + if (CollUtil.isEmpty(monitorList)) { + return null; + } + + List matchedMonitorList = monitorList.stream() + .filter(item -> split[1].equals(item.getLineId())) + .collect(Collectors.toList()); + if (CollUtil.isEmpty(matchedMonitorList)) { + return null; + } + + preDetection.setMonitorList(matchedMonitorList); + Map> payload = new HashMap<>(1); + payload.put("deviceList", Collections.singletonList(preDetection)); + return JSON.toJSONString(payload); + } + + private void sendGetDipDataMsg(String monitorId) { + SocketMsg socketMsg = new SocketMsg<>(); + socketMsg.setRequestId(SourceOperateCodeEnum.FORMAL_REAL.getValue()); + socketMsg.setOperateCode(SourceOperateCodeEnum.OPER_GATHER.getValue()); + + DevPhaseSequenceParam phaseSequenceParam = new DevPhaseSequenceParam(); + // 设置监测点ID列表 + phaseSequenceParam.setMoniterIdList(ListUtil.of(monitorId)); + + // 设置数据类型列表 + phaseSequenceParam.setDataType(ListUtil.of("avg$MAG", "avg$DUR")); + // 设置读取次数 + phaseSequenceParam.setReadCount(0); + // 设置忽略次数 + phaseSequenceParam.setIgnoreCount(0); + socketMsg.setData(JSON.toJSONString(phaseSequenceParam)); + socketMsg.setOperateCode(SourceOperateCodeEnum.DEV_DATA_REQUEST_03.getValue()); + SocketManager.sendMsg(monitorId, JSON.toJSONString(socketMsg)); + } + + private void sendQuitMsg(String monitorId, SourceOperateCodeEnum operateCodeEnum) { + SocketMsg socketMsg = new SocketMsg<>(); + socketMsg.setRequestId(SourceOperateCodeEnum.QUITE.getValue()); + socketMsg.setOperateCode(operateCodeEnum.getValue()); + SocketManager.sendMsg(monitorId, JSON.toJSONString(socketMsg)); + log.info("已向设备发送关闭指令,monitorId={}, operateCode={}", monitorId, operateCodeEnum.getValue()); + } + + private void saveDipData(DevData devData) { + if (Objects.isNull(devData) || CollUtil.isEmpty(devData.getSqlData())) { + return; + } + + Double residualVoltage = null; + Integer durationMs = null; + for (DevData.SqlDataDTO sqlDataDTO : devData.getSqlData()) { + if (Objects.isNull(sqlDataDTO) || Objects.isNull(sqlDataDTO.getList())) { + continue; + } + + Double value = getSqlDataValue(sqlDataDTO.getList()); + if (Objects.isNull(value)) { + continue; + } + + if (DetectionCodeEnum.MAG.getCode().equalsIgnoreCase(sqlDataDTO.getDesc())) { + residualVoltage = value; + } else if (DetectionCodeEnum.DUR.getCode().equalsIgnoreCase(sqlDataDTO.getDesc())) { + durationMs = (int) Math.round(value * 1000); + } + } + + PqDipData pqDipData = new PqDipData(); + pqDipData.setStartTime(LocalDateTime.parse(devData.getTime())); + pqDipData.setResidualVoltage(residualVoltage); + pqDipData.setDurationMs(durationMs); + pqDipDataService.save(pqDipData); + } + + private Double getSqlDataValue(DevData.SqlDataDTO.ListDTO listDTO) { + if (Objects.nonNull(listDTO.getA())) { + return listDTO.getA(); + } + if (Objects.nonNull(listDTO.getB())) { + return listDTO.getB(); + } + if (Objects.nonNull(listDTO.getC())) { + return listDTO.getC(); + } + return listDTO.getT(); + } + + public void cleanup(String monitorId, boolean removeSocket) { + FormalTestManager.freqConverterDevStep = null; + if (removeSocket) { + SocketManager.removeUser(monitorId); + } else { + SocketManager.clearUser(monitorId); + } + } +} diff --git a/detection/src/main/java/com/njcn/gather/detection/handler/SocketFreqConverterService.java b/detection/src/main/java/com/njcn/gather/detection/handler/SocketFreqConverterService.java new file mode 100644 index 00000000..b91da325 --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/detection/handler/SocketFreqConverterService.java @@ -0,0 +1,221 @@ +package com.njcn.gather.detection.handler; + +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSON; +import com.njcn.gather.detection.pojo.dto.FreqConverterRespDTO; +import com.njcn.gather.detection.pojo.enums.SourceOperateCodeEnum; +import com.njcn.gather.detection.pojo.vo.SocketMsg; +import com.njcn.gather.detection.util.socket.FormalTestManager; +import com.njcn.gather.detection.util.socket.SocketManager; +import com.njcn.gather.detection.util.socket.cilent.NettyClient; +import com.njcn.gather.detection.util.socket.cilent.NettyFreqConverterClientHandler; +import com.njcn.gather.detection.util.socket.config.SocketConnectionConfig; +import com.njcn.gather.freqConverter.pojo.po.FreqConverterStatus; +import com.njcn.gather.freqConverter.pojo.po.PqFreqConverterConfig; +import com.njcn.gather.freqConverter.service.IFreqConverterService; +import com.njcn.gather.freqConverter.service.IPqFreqConverterConfigService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * @author czh + * @version 1.0 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class SocketFreqConverterService { + private final IFreqConverterService freqConverterService; + + private final SocketConnectionConfig socketConnectionConfig; + + private final IPqFreqConverterConfigService pqFreqConverterConfigService; + + /** + * 连接变频器Socket + * + * @param converterId 变频器id + */ + public void connectSocket(String converterId) { + if (SocketManager.isChannelActive(converterId)) { + return; + } + String ip = socketConnectionConfig.getFreqConverter().getIp(); + Integer port = socketConnectionConfig.getFreqConverter().getPort(); + + NettyFreqConverterClientHandler handler = new NettyFreqConverterClientHandler(converterId, this); + + CompletableFuture.runAsync(() -> { + NettyClient.commonConnect(ip, port, converterId, handler); + }); + } + + private void init(String converterId, String monitorId) { + FormalTestManager.freqConverterStep = null; + FormalTestManager.pairsIpMap.put(converterId, monitorId); + clearScheduleTask(); + } + + /** + * 连接变频器 + */ + public void connectionFreqConverter(String converterId, String monitorId) { + this.init(converterId, monitorId); + + SocketMsg> socketMsg = new SocketMsg<>(); + socketMsg.setOperateCode(SourceOperateCodeEnum.CMD_INIT_SERIAL.getValue()); + String requestId = IdUtil.fastSimpleUUID(); + socketMsg.setRequestId(requestId); + + PqFreqConverterConfig freqConverterConfig = pqFreqConverterConfigService.getById(converterId); + + Map map = new HashMap<>(); + map.put("portName", freqConverterConfig.getPortName()); + map.put("slaveAddress", freqConverterConfig.getSlaveAddress()); + map.put("baudRate", freqConverterConfig.getBaudRate()); + map.put("parity", freqConverterConfig.getParity()); + map.put("dataBits", freqConverterConfig.getDataBits()); + map.put("stopBits", freqConverterConfig.getStopBits()); + map.put("timeoutMs", freqConverterConfig.getTimeoutMs()); + socketMsg.setData(map); + + SocketManager.sendMsg(converterId, JSON.toJSONString(socketMsg)); + FormalTestManager.freqConverterStep = SourceOperateCodeEnum.CMD_INIT_SERIAL; + } + + public void handleRead(String converterId, String msg) { + FreqConverterRespDTO respDTO = JSON.parseObject(msg, FreqConverterRespDTO.class); + + switch (FormalTestManager.freqConverterStep) { + case CMD_PING: + handlePing(converterId, respDTO); + break; + case CMD_INIT_SERIAL: + handleInitSerial(converterId, respDTO); + break; + case CMD_GET_SERIAL_CONFIG: + handleGetSerialConfig(converterId, respDTO); + break; + case CMD_GET_DEVICE_STATUS: + handleGetDeviceStatus(converterId, respDTO); + break; + case CMD_CLOSE_SERIAL: + handleCloseSerial(converterId, respDTO); + break; + } + } + + public void stopTest(String converterId, String monitorId) { + FormalTestManager.freqConverterStep = SourceOperateCodeEnum.CMD_CLOSE_SERIAL; + this.sendClose(converterId); + } + + + private void handlePing(String converterId, FreqConverterRespDTO respDTO) { + if (respDTO.getCode() == 0 && respDTO.getSuccess() && respDTO.getMessage().equals("pong")) { + return; + } else { + + } + } + + private void handleInitSerial(String converterId, FreqConverterRespDTO respDTO) { + if (respDTO.getCode() == 0 && respDTO.getSuccess()) { + + FormalTestManager.freqConverterStep = SourceOperateCodeEnum.CMD_GET_DEVICE_STATUS; + freqConverterService.clearAllData(); + if (Objects.isNull(FormalTestManager.scheduler)) { + FormalTestManager.scheduler = Executors.newScheduledThreadPool(1); + FormalTestManager.scheduledFuture = FormalTestManager.scheduler.scheduleAtFixedRate(() -> { + this.sendGetDeviceStatusMsg(converterId); + }, 0l, 200l, TimeUnit.MILLISECONDS); + } + } + } + + private void handleGetSerialConfig(String converterId, FreqConverterRespDTO respDTO) { + } + + private void handleGetDeviceStatus(String converterId, FreqConverterRespDTO respDTO) { + JSONObject obj = JSONUtil.parseObj(respDTO.getData().toString()); + String timestamp = (String) obj.get("Timestamp"); + timestamp = timestamp.replace("+08:00", StrUtil.EMPTY); + obj.set("Timestamp", timestamp); + + FreqConverterStatus freqConverterStatus = JSON.parseObject(obj.toString(), FreqConverterStatus.class); + freqConverterStatus.setConverterId(converterId); + // 变频器故障中,移除这段时期内的设备数据 + if (freqConverterStatus.getStatusWord1() == 4) { + FormalTestManager.stopFlag = true; + } else { + FormalTestManager.stopFlag = false; + } + freqConverterService.saveFreqConverterStatus(freqConverterStatus); + } + + private void handleCloseSerial(String converterId, FreqConverterRespDTO respDTO) { + if (respDTO.getCode() == 0 && respDTO.getSuccess()) { + cleanup(converterId, true); + } + } + + + private void sendGetDeviceStatusMsg(String converterId) { + SocketMsg> socketMsg = new SocketMsg<>(); + socketMsg.setOperateCode(SourceOperateCodeEnum.CMD_GET_DEVICE_STATUS.getValue()); + String requestId = IdUtil.fastSimpleUUID(); + socketMsg.setRequestId(requestId); + + Map map = new HashMap<>(); + socketMsg.setData(map); + SocketManager.sendMsg(converterId, JSON.toJSONString(socketMsg)); + } + + private void sendClose(String converterId) { + SocketMsg> socketMsg = new SocketMsg<>(); + socketMsg.setOperateCode(SourceOperateCodeEnum.CMD_CLOSE_SERIAL.getValue()); + String requestId = IdUtil.fastSimpleUUID(); + socketMsg.setRequestId(requestId); + + Map map = new HashMap<>(); + socketMsg.setData(map); + SocketManager.sendMsg(converterId, JSON.toJSONString(socketMsg)); + } + + public void cleanup(String converterId, boolean removeSocket) { + clearScheduleTask(); + FormalTestManager.freqConverterStep = null; + FormalTestManager.stopFlag = false; + FormalTestManager.pairsIpMap.remove(converterId); + if (removeSocket) { + SocketManager.removeUser(converterId); + } else { + SocketManager.clearUser(converterId); + } + } + + private void clearScheduleTask() { + if (FormalTestManager.scheduledFuture != null) { + FormalTestManager.scheduledFuture.cancel(true); + FormalTestManager.scheduledFuture = null; + } + if (FormalTestManager.scheduler != null) { + FormalTestManager.scheduler.shutdown(); + FormalTestManager.scheduler = null; + } + } + +} + + diff --git a/detection/src/main/java/com/njcn/gather/detection/pojo/dto/FreqConverterRespDTO.java b/detection/src/main/java/com/njcn/gather/detection/pojo/dto/FreqConverterRespDTO.java new file mode 100644 index 00000000..95a95b13 --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/detection/pojo/dto/FreqConverterRespDTO.java @@ -0,0 +1,42 @@ +package com.njcn.gather.detection.pojo.dto; + +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * @author caozehui + * @data 2026-04-08 + */ +@Data +public class FreqConverterRespDTO { + /** + * 请求编号 + */ + @JsonAlias({"RequestId"}) + private String requestId; + + /** + * 是否成功 + */ + @JsonAlias({"Success"}) + private Boolean success; + + /** + * 状态码 + */ + @JsonAlias({"Code"}) + private Integer code; + + /** + * 消息 + */ + @JsonAlias({"Message"}) + private String message; + + /** + * 数据 + */ + @JsonAlias({"Data"}) + private Object data; +} diff --git a/detection/src/main/java/com/njcn/gather/detection/pojo/enums/SourceOperateCodeEnum.java b/detection/src/main/java/com/njcn/gather/detection/pojo/enums/SourceOperateCodeEnum.java index 8a5fd050..2945d410 100644 --- a/detection/src/main/java/com/njcn/gather/detection/pojo/enums/SourceOperateCodeEnum.java +++ b/detection/src/main/java/com/njcn/gather/detection/pojo/enums/SourceOperateCodeEnum.java @@ -70,9 +70,6 @@ public enum SourceOperateCodeEnum { FLICKER_DATA_CHECK("flicker_data_check","闪变数据校验"), - - - /** * */ @@ -100,12 +97,17 @@ public enum SourceOperateCodeEnum { small_comp_start("small_comp_start","小电压校准开始"), small_comp_end("small_comp_end","小电压校准结束"), - /** * ftp文件传送指令 */ FTP_SEND_01("FTP_SEND$01", "发送文件"), - RDRE$01("RDRE$01", "启动录波"); + RDRE$01("RDRE$01", "启动录波"), + + CMD_PING("ping", "检查 TCP 服务是否在线"), + CMD_INIT_SERIAL("initSerial", "初始化并打开串口连接"), + CMD_GET_SERIAL_CONFIG("getSerialConfig", "获取当前串口配置"), + CMD_GET_DEVICE_STATUS("getDeviceStatus", "读取变频器运行状态"), + CMD_CLOSE_SERIAL("closeSerial", "关闭串口"),; private final String value; private final String msg; diff --git a/detection/src/main/java/com/njcn/gather/detection/service/PreDetectionService.java b/detection/src/main/java/com/njcn/gather/detection/service/PreDetectionService.java index 0dd75a53..269fa9a2 100644 --- a/detection/src/main/java/com/njcn/gather/detection/service/PreDetectionService.java +++ b/detection/src/main/java/com/njcn/gather/detection/service/PreDetectionService.java @@ -3,6 +3,7 @@ package com.njcn.gather.detection.service; import com.njcn.gather.detection.pojo.param.ContrastDetectionParam; import com.njcn.gather.detection.pojo.param.PreDetectionParam; import com.njcn.gather.detection.pojo.param.SimulateDetectionParam; +import org.springframework.web.bind.annotation.RequestParam; import java.util.List; import java.util.Map; @@ -68,4 +69,8 @@ public interface PreDetectionService { boolean getCanCoefficient(); void startCoefficient(); + + void startFreqConverter(String converterId, String monitorId); + + void stopFreqConverter(String converterId,String monitorId); } diff --git a/detection/src/main/java/com/njcn/gather/detection/service/impl/PreDetectionServiceImpl.java b/detection/src/main/java/com/njcn/gather/detection/service/impl/PreDetectionServiceImpl.java index 87cd8833..b654a15b 100644 --- a/detection/src/main/java/com/njcn/gather/detection/service/impl/PreDetectionServiceImpl.java +++ b/detection/src/main/java/com/njcn/gather/detection/service/impl/PreDetectionServiceImpl.java @@ -6,9 +6,7 @@ import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.njcn.common.pojo.exception.BusinessException; -import com.njcn.gather.detection.handler.SocketContrastResponseService; -import com.njcn.gather.detection.handler.SocketDevResponseService; -import com.njcn.gather.detection.handler.SocketSourceResponseService; +import com.njcn.gather.detection.handler.*; import com.njcn.gather.detection.pojo.constant.DetectionCommunicateConstant; import com.njcn.gather.detection.pojo.enums.DetectionResponseEnum; import com.njcn.gather.detection.pojo.enums.SourceOperateCodeEnum; @@ -76,6 +74,8 @@ public class PreDetectionServiceImpl implements PreDetectionService { private final SocketDevResponseService socketDevResponseService; private final SocketSourceResponseService socketSourceResponseService; private final SocketContrastResponseService socketContrastResponseService; + private final SocketFreqConverterService socketFreqConverterService; + private final SocketFreqConverterDevService socketFreqConverterDevService; private final IPqScriptCheckDataService iPqScriptCheckDataService; private final SocketManager socketManager; private final ISysTestConfigService sysTestConfigService; @@ -393,6 +393,27 @@ public class PreDetectionServiceImpl implements PreDetectionService { } } + @Override + public void startFreqConverter(String converterId, String monitorId) { + socketFreqConverterService.connectSocket(converterId); + socketFreqConverterDevService.connectSocket(monitorId); + + while (true) { + if (SocketManager.isChannelActive(converterId) && SocketManager.isChannelActive(monitorId)) { + socketFreqConverterService.connectionFreqConverter(converterId, monitorId); + socketFreqConverterDevService.connectionDev(converterId, monitorId); + break; + } + } + + } + + @Override + public void stopFreqConverter(String converterId, String monitorId) { + socketFreqConverterService.stopTest(converterId, monitorId); + socketFreqConverterDevService.stopTest(converterId, monitorId); + } + /** * 比对式-与通信模块进行连接 * @@ -451,4 +472,4 @@ public class PreDetectionServiceImpl implements PreDetectionService { } } -} \ No newline at end of file +} diff --git a/detection/src/main/java/com/njcn/gather/detection/util/socket/FormalTestManager.java b/detection/src/main/java/com/njcn/gather/detection/util/socket/FormalTestManager.java index 9ce8d743..7e310de0 100644 --- a/detection/src/main/java/com/njcn/gather/detection/util/socket/FormalTestManager.java +++ b/detection/src/main/java/com/njcn/gather/detection/util/socket/FormalTestManager.java @@ -31,6 +31,9 @@ public class FormalTestManager { // 当前步骤 public static SourceOperateCodeEnum currentStep; + public static SourceOperateCodeEnum freqConverterStep; + public static SourceOperateCodeEnum freqConverterDevStep; + /** * key:设备ip,value:当前设备下面的监测点ID(ip_通道号) */ diff --git a/detection/src/main/java/com/njcn/gather/detection/util/socket/SocketManager.java b/detection/src/main/java/com/njcn/gather/detection/util/socket/SocketManager.java index f8b813c2..4e7cca67 100644 --- a/detection/src/main/java/com/njcn/gather/detection/util/socket/SocketManager.java +++ b/detection/src/main/java/com/njcn/gather/detection/util/socket/SocketManager.java @@ -81,6 +81,17 @@ public class SocketManager { socketGroup.remove(userId); } + public static void clearUser(String userId) { + Channel channel = socketSessions.remove(userId); + NioEventLoopGroup eventExecutors = socketGroup.remove(userId); + if (ObjectUtil.isNotNull(eventExecutors)) { + eventExecutors.shutdownGracefully(); + } + if (ObjectUtil.isNotNull(channel)) { + log.info("{}__{}已清理客户端会话", userId, channel.id()); + } + } + public static Channel getChannelByUserId(String userId) { return socketSessions.get(userId); } @@ -315,4 +326,4 @@ public class SocketManager { } - \ No newline at end of file + diff --git a/detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettyClient.java b/detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettyClient.java index eb74ccb3..9c3c4d70 100644 --- a/detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettyClient.java +++ b/detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettyClient.java @@ -56,6 +56,109 @@ public class NettyClient { */ private static NettyClient instance; + /** + * 静态方法:智能连接变频器设备(兼容性包装) + * + * @param ip IP地址 + * @param port 端口号 + * @param id 唯一标识id + * @param handler 变频器处理器 + */ + public static void commonConnect(String ip, Integer port, String id, + SimpleChannelInboundHandler handler) { + if (instance != null) { + instance.executeCommonConnect(ip, port, id, handler); + } else { + log.error("NettyClient未初始化,无法创建连接"); + } + } + + /** + * 执行变频器Socket连接建立流程 + * + * @param ip 目标服务器IP地址 + * @param port 目标服务器端口号 + * @param id 唯一标识id + * @param handler 变频器业务处理器 + */ + private static void executeCommonConnect(String ip, Integer port, + String id, + SimpleChannelInboundHandler handler) { + NioEventLoopGroup group = createEventLoopGroup(); + + try { + Bootstrap bootstrap = configureBootstrap(group); + ChannelInitializer initializer = createCommonChannelInitializer(id, handler); + bootstrap.handler(initializer); + ChannelFuture channelFuture = bootstrap.connect(ip, port).sync(); + handleCommonConnectionResult(channelFuture, id, handler, group); + } catch (Exception e) { + handleCommonConnectionException(e, id, handler, group); + } + } + + /** + * 创建通用通道初始化器 + * + * @param id 唯一标识id + * @param handler 通用业务处理器 + * @return ChannelInitializer 通道初始化器 + */ + private static ChannelInitializer createCommonChannelInitializer( + String id, SimpleChannelInboundHandler handler) { + return new ChannelInitializer() { + @Override + protected void initChannel(NioSocketChannel ch) { + ch.pipeline() + .addLast(new LineBasedFrameDecoder(10240 * 2)) + .addLast(new StringDecoder(CharsetUtil.UTF_8)) + .addLast(new StringEncoder(CharsetUtil.UTF_8)) + .addLast(new IdleStateHandler(60, 0, 0, TimeUnit.SECONDS)) + .addLast(handler); + } + }; + } + + /** + * 处理通用连接结果 + * + * @param channelFuture 连接Future对象 + * @param id id + * @param handler 通用业务处理器 + * @param group 事件循环组 + */ + private static void handleCommonConnectionResult(ChannelFuture channelFuture, + String id, + SimpleChannelInboundHandler handler, + NioEventLoopGroup group) { + channelFuture.addListener((ChannelFutureListener) ch -> { + if (!ch.isSuccess()) { + log.error("连接Socket失败,id={}", id); + group.shutdownGracefully(); + } else { + log.info("连接Socket成功,id={}, channelId={}", + id, channelFuture.channel().id()); + SocketManager.addGroup(id, group); + SocketManager.addUser(id, channelFuture.channel()); + } + }); + } + + /** + * 处理通用连接异常 + * + * @param e 异常对象 + * @param id 唯一标识id + * @param handler 通用业务处理器 + * @param group 事件循环组 + */ + private static void handleCommonConnectionException(Exception e, String id, + SimpleChannelInboundHandler handler, + NioEventLoopGroup group) { + log.error("连接Socket服务端发生异常,id={}, error={}", id, e.getMessage(), e); + group.shutdownGracefully(); + } + @PostConstruct public void init() { diff --git a/detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettyFreqConverterClientHandler.java b/detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettyFreqConverterClientHandler.java new file mode 100644 index 00000000..ec1857eb --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettyFreqConverterClientHandler.java @@ -0,0 +1,124 @@ +package com.njcn.gather.detection.util.socket.cilent; + +import cn.hutool.core.util.StrUtil; +import com.njcn.gather.detection.handler.SocketFreqConverterService; +import com.njcn.gather.detection.util.socket.SocketManager; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.handler.timeout.IdleState; +import io.netty.handler.timeout.IdleStateEvent; +import lombok.extern.slf4j.Slf4j; + +/** + * 变频器Netty客户端处理器 + */ +@Slf4j +public class NettyFreqConverterClientHandler extends SimpleChannelInboundHandler { + + /** + * 变频器ID + */ + private final String converterId; + + + /** + * 变频器Socket响应服务 + */ + private final SocketFreqConverterService socketFreqConverterService; + + /** + * 重连次数 + */ + private int reconnectAttempts = 0; + + /** + * 最大重连次数 + */ + private static final int MAX_RECONNECT_ATTEMPTS = 3; + + /** + * 重连间隔(毫秒) + */ + private static final long RECONNECT_INTERVAL_MS = 5000; + + /** + * 构造方法 + * + * @param converterId 变频器ID + * @param socketFreqConverterService 变频器Socket响应服务 + */ + public NettyFreqConverterClientHandler(String converterId, SocketFreqConverterService socketFreqConverterService) { + this.converterId = converterId; + this.socketFreqConverterService = socketFreqConverterService; + } + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("变频器连接已建立,converterId={}, channelId={}", converterId, ctx.channel().id()); + + // 注册Channel到SocketManager + SocketManager.addUser(converterId, ctx.channel()); + + super.channelActive(ctx); + } + + @Override + protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { + if (StrUtil.isBlank(msg)) { + log.debug("收到空消息,忽略,converterId={}", converterId); + return; + } + + log.info("收到变频器消息,converterId={}, msg={}", converterId, msg); + + // 处理状态数据 + socketFreqConverterService.handleRead(converterId, msg); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.warn("变频器连接已断开,converterId={}", converterId); + + // 移除Channel + socketFreqConverterService.cleanup(converterId, false); + + // 尝试重连 + if (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) { + reconnectAttempts++; + log.info("尝试重连变频器,converterId={}, 第{}次重连", converterId, reconnectAttempts); + + ctx.executor().schedule(() -> { + try { + // 获取连接信息并重连 + // 注意:这里需要根据实际情况实现重连逻辑 + log.info("变频器重连逻辑待实现,converterId={}", converterId); + } catch (Exception e) { + log.error("变频器重连失败,converterId={}, error={}", converterId, e.getMessage(), e); + } + }, RECONNECT_INTERVAL_MS, java.util.concurrent.TimeUnit.MILLISECONDS); + } else { + log.error("变频器重连失败,已达到最大重连次数,converterId={}", converterId); + } + + super.channelInactive(ctx); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + log.error("变频器连接发生异常,converterId={}, error={}", converterId, cause.getMessage(), cause); + ctx.close(); + } + + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + if (evt instanceof IdleStateEvent) { + IdleStateEvent event = (IdleStateEvent) evt; + if (event.state() == IdleState.READER_IDLE) { + log.warn("变频器连接读空闲,converterId={}", converterId); + // 可以选择发送心跳或关闭连接 + } + } + super.userEventTriggered(ctx, evt); + } +} + diff --git a/detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettyFreqConverterDevClientHandler.java b/detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettyFreqConverterDevClientHandler.java new file mode 100644 index 00000000..7c2a1d1a --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/detection/util/socket/cilent/NettyFreqConverterDevClientHandler.java @@ -0,0 +1,67 @@ +package com.njcn.gather.detection.util.socket.cilent; + +import cn.hutool.core.util.StrUtil; +import com.njcn.gather.detection.handler.SocketFreqConverterDevService; +import com.njcn.gather.detection.util.socket.SocketManager; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.handler.timeout.IdleState; +import io.netty.handler.timeout.IdleStateEvent; +import lombok.extern.slf4j.Slf4j; + +/** + * 设备 Netty 客户端处理器 + */ +@Slf4j +public class NettyFreqConverterDevClientHandler extends SimpleChannelInboundHandler { + + private final String monitorId; + private final SocketFreqConverterDevService socketFreqConverterDevService; + + public NettyFreqConverterDevClientHandler(String monitorId, SocketFreqConverterDevService socketFreqConverterDevService) { + this.monitorId = monitorId; + this.socketFreqConverterDevService = socketFreqConverterDevService; + } + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("设备连接已建立,monitorId={}, channelId={}", monitorId, ctx.channel().id()); + SocketManager.addUser(monitorId, ctx.channel()); + super.channelActive(ctx); + } + + @Override + protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { + if (StrUtil.isBlank(msg)) { + log.debug("收到空消息,忽略,monitorId={}", monitorId); + return; + } + + log.info("收到设备消息,monitorId={}, msg={}", monitorId, msg); + socketFreqConverterDevService.handleRead(monitorId, msg); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.warn("设备连接已断开,monitorId={}", monitorId); + socketFreqConverterDevService.cleanup(monitorId, false); + super.channelInactive(ctx); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + log.error("设备连接发生异常,monitorId={}, error={}", monitorId, cause.getMessage(), cause); + ctx.close(); + } + + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + if (evt instanceof IdleStateEvent) { + IdleStateEvent event = (IdleStateEvent) evt; + if (event.state() == IdleState.READER_IDLE) { + log.warn("设备连接读空闲,monitorId={}", monitorId); + } + } + super.userEventTriggered(ctx, evt); + } +} diff --git a/detection/src/main/java/com/njcn/gather/detection/util/socket/config/SocketConnectionConfig.java b/detection/src/main/java/com/njcn/gather/detection/util/socket/config/SocketConnectionConfig.java index f053029e..8c3565d5 100644 --- a/detection/src/main/java/com/njcn/gather/detection/util/socket/config/SocketConnectionConfig.java +++ b/detection/src/main/java/com/njcn/gather/detection/util/socket/config/SocketConnectionConfig.java @@ -18,29 +18,21 @@ import java.util.Set; @Component @ConfigurationProperties(prefix = "socket") public class SocketConnectionConfig { + /** + * 被检设备配置 + */ + private DeviceConfig device = new DeviceConfig(); /** * 程控源设备配置 */ private SourceConfig source = new SourceConfig(); - /** - * 被检设备配置 - */ - private DeviceConfig device = new DeviceConfig(); - @Data - public static class SourceConfig { - /** - * 程控源IP地址 - */ - private String ip; - - /** - * 程控源端口号 - */ - private Integer port; - } + /** + * 变频器配置 + */ + private DeviceConfig freqConverter = new DeviceConfig(); @Data public static class DeviceConfig { @@ -48,13 +40,33 @@ public class SocketConnectionConfig { * 被检设备IP地址 */ private String ip; - + /** * 被检设备端口号 */ private Integer port; } + @Data + public static class SourceConfig { + /** + * 程控源IP地址 + */ + private String ip; + + /** + * 程控源端口号 + */ + private Integer port; + } + + /** + * 获取被检设备配置 + */ + public DeviceConfig getDevice() { + return device; + } + /** * 获取程控源配置 */ @@ -63,10 +75,10 @@ public class SocketConnectionConfig { } /** - * 获取被检设备配置 + * 获取变频器配置 */ - public DeviceConfig getDevice() { - return device; + public DeviceConfig getFreqConverter() { + return freqConverter; } /** diff --git a/detection/src/main/java/com/njcn/gather/dip/mapper/PqDipDataMapper.java b/detection/src/main/java/com/njcn/gather/dip/mapper/PqDipDataMapper.java new file mode 100644 index 00000000..83ac7cf6 --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/dip/mapper/PqDipDataMapper.java @@ -0,0 +1,11 @@ +package com.njcn.gather.dip.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.njcn.gather.dip.pojo.po.PqDipData; + +/** + * @author caozehui + * @date 2026-04-09 + */ +public interface PqDipDataMapper extends BaseMapper { +} diff --git a/detection/src/main/java/com/njcn/gather/dip/pojo/po/PqDipData.java b/detection/src/main/java/com/njcn/gather/dip/pojo/po/PqDipData.java new file mode 100644 index 00000000..9f72dc7f --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/dip/pojo/po/PqDipData.java @@ -0,0 +1,44 @@ +package com.njcn.gather.dip.pojo.po; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.njcn.db.mybatisplus.bo.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 电压暂降数据 + * + * @author caozehui + * @date 2026-04-09 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("pq_dip_data") +public class PqDipData extends BaseEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + private String id; + + /** + * 起始时间戳 + */ + private LocalDateTime startTime; + + /** + * 残余电压,单位:%Ur + */ + private Double residualVoltage; + + /** + * + * 持续时间,单位:ms + */ + private Integer durationMs; +} diff --git a/detection/src/main/java/com/njcn/gather/dip/service/IPqDipDataService.java b/detection/src/main/java/com/njcn/gather/dip/service/IPqDipDataService.java new file mode 100644 index 00000000..d851f0c1 --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/dip/service/IPqDipDataService.java @@ -0,0 +1,11 @@ +package com.njcn.gather.dip.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.njcn.gather.dip.pojo.po.PqDipData; + +/** + * @author caozehui + * @date 2026-04-09 + */ +public interface IPqDipDataService extends IService { +} diff --git a/detection/src/main/java/com/njcn/gather/dip/service/impl/PqDipDataServiceImpl.java b/detection/src/main/java/com/njcn/gather/dip/service/impl/PqDipDataServiceImpl.java new file mode 100644 index 00000000..1111c307 --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/dip/service/impl/PqDipDataServiceImpl.java @@ -0,0 +1,15 @@ +package com.njcn.gather.dip.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.njcn.gather.dip.mapper.PqDipDataMapper; +import com.njcn.gather.dip.pojo.po.PqDipData; +import com.njcn.gather.dip.service.IPqDipDataService; +import org.springframework.stereotype.Service; + +/** + * @author caozehui + * @date 2026-04-09 + */ +@Service +public class PqDipDataServiceImpl extends ServiceImpl implements IPqDipDataService { +} diff --git a/detection/src/main/java/com/njcn/gather/freqConverter/mapper/FreqConverterStatusMapper.java b/detection/src/main/java/com/njcn/gather/freqConverter/mapper/FreqConverterStatusMapper.java new file mode 100644 index 00000000..b28803d7 --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/freqConverter/mapper/FreqConverterStatusMapper.java @@ -0,0 +1,11 @@ +package com.njcn.gather.freqConverter.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.njcn.gather.freqConverter.pojo.po.FreqConverterStatus; + +/** + * @author caozehui + * @data 2026-04-07 + */ +public interface FreqConverterStatusMapper extends BaseMapper { +} diff --git a/detection/src/main/java/com/njcn/gather/freqConverter/mapper/PqFreqConverterConfigMapper.java b/detection/src/main/java/com/njcn/gather/freqConverter/mapper/PqFreqConverterConfigMapper.java new file mode 100644 index 00000000..442e4ef8 --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/freqConverter/mapper/PqFreqConverterConfigMapper.java @@ -0,0 +1,12 @@ +package com.njcn.gather.freqConverter.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.njcn.gather.freqConverter.pojo.po.FreqConverterStatus; +import com.njcn.gather.freqConverter.pojo.po.PqFreqConverterConfig; + +/** + * @author caozehui + * @data 2026-04-08 + */ +public interface PqFreqConverterConfigMapper extends BaseMapper { +} diff --git a/detection/src/main/java/com/njcn/gather/freqConverter/pojo/po/FreqConverterStatus.java b/detection/src/main/java/com/njcn/gather/freqConverter/pojo/po/FreqConverterStatus.java new file mode 100644 index 00000000..ebcb19ed --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/freqConverter/pojo/po/FreqConverterStatus.java @@ -0,0 +1,43 @@ +package com.njcn.gather.freqConverter.pojo.po; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonAlias; +import com.njcn.db.mybatisplus.bo.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * @author caozehui + * @data 2026-04-07 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("pq_freq_converter_status") +public class FreqConverterStatus extends BaseEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + private String id; + + /** + * 变频器ID(用于区分不同变频器) + */ + private String converterId; + + private Integer slaveAddress; + + private Integer statusWord1; + + private String statusWord1Hex; + + /** + * 状态记录时刻(时间戳) + */ + private LocalDateTime timestamp; +} \ No newline at end of file diff --git a/detection/src/main/java/com/njcn/gather/freqConverter/pojo/po/PqFreqConverterConfig.java b/detection/src/main/java/com/njcn/gather/freqConverter/pojo/po/PqFreqConverterConfig.java new file mode 100644 index 00000000..38a8ed3c --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/freqConverter/pojo/po/PqFreqConverterConfig.java @@ -0,0 +1,53 @@ +package com.njcn.gather.freqConverter.pojo.po; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.njcn.db.mybatisplus.bo.BaseEntity; +import lombok.Data; + +/** + * 变频器配置实体类 + */ +@Data +@TableName("pq_freq_converter_config") +public class PqFreqConverterConfig extends BaseEntity { + + /** + * 主键ID + */ + private String id; + + /** + * 电脑串口名,如COM1 + */ + private String portName; + + /** + * 变频器设置从机地址,范围1~127 + */ + private Integer slaveAddress; + + /** + * 变频器设置波特率,如19200 + */ + private Integer baudRate; + + /** + * 奇偶校验类型: None, Even, Odd + */ + private String parity; + + /** + * 变频器数据位 + */ + private Integer dataBits; + + /** + * 变频器停止位,当前只支持 1 或 2 + */ + private Integer stopBits; + + /** + * 串口读写超时,单位毫秒 + */ + private Integer timeoutMs; +} \ No newline at end of file diff --git a/detection/src/main/java/com/njcn/gather/freqConverter/service/IFreqConverterService.java b/detection/src/main/java/com/njcn/gather/freqConverter/service/IFreqConverterService.java new file mode 100644 index 00000000..c31d1e53 --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/freqConverter/service/IFreqConverterService.java @@ -0,0 +1,37 @@ +package com.njcn.gather.freqConverter.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.njcn.gather.freqConverter.pojo.po.FreqConverterStatus; + +import java.util.List; + +/** + * @author caozehui + * @data 2026-04-07 + */ +public interface IFreqConverterService extends IService { + + /** + * 保存变频器状态数据 + * + * @param status 变频器状态数据 + * @return 是否保存成功 + */ + boolean saveFreqConverterStatus(FreqConverterStatus status); + + + /** + * 查询指定变频器的状态历史 + * + * @param converterId 变频器ID + * @return 状态数据列表 + */ + List listStatusHistory(String converterId); + + /** + * 清空所有数据 + * + * @return + */ + boolean clearAllData(); +} \ No newline at end of file diff --git a/detection/src/main/java/com/njcn/gather/freqConverter/service/IPqFreqConverterConfigService.java b/detection/src/main/java/com/njcn/gather/freqConverter/service/IPqFreqConverterConfigService.java new file mode 100644 index 00000000..a4535350 --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/freqConverter/service/IPqFreqConverterConfigService.java @@ -0,0 +1,11 @@ +package com.njcn.gather.freqConverter.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.njcn.gather.freqConverter.pojo.po.PqFreqConverterConfig; + +/** + * @author caozehui + * @data 2026-04-08 + */ +public interface IPqFreqConverterConfigService extends IService { +} diff --git a/detection/src/main/java/com/njcn/gather/freqConverter/service/impl/FreqConverterServiceImpl.java b/detection/src/main/java/com/njcn/gather/freqConverter/service/impl/FreqConverterServiceImpl.java new file mode 100644 index 00000000..1cfa7a5f --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/freqConverter/service/impl/FreqConverterServiceImpl.java @@ -0,0 +1,64 @@ +package com.njcn.gather.freqConverter.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.njcn.gather.freqConverter.mapper.FreqConverterStatusMapper; +import com.njcn.gather.freqConverter.pojo.po.FreqConverterStatus; +import com.njcn.gather.freqConverter.service.IFreqConverterService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 变频器状态数据Service实现类 + *

+ * 实现变频器状态数据的存储、查询和清理功能。 + * 当数据量超过阈值时,自动清理无效或过期数据,避免内存和数据库资源浪费。 + *

+ * + * @author CN_Gather Detection Team + * @version 1.0 + * @since 2026 + */ +@Slf4j +@Service +public class FreqConverterServiceImpl extends ServiceImpl implements IFreqConverterService { + + /** + * 默认最大数据量阈值 + */ + private static final int DEFAULT_MAX_DATA_COUNT = 10000; + + /** + * 默认数据过期天数 + */ + private static final int DEFAULT_EXPIRE_DAYS = 30; + + /** + * 默认每个变频器保留的最新数据条数 + */ + private static final int DEFAULT_KEEP_LATEST_COUNT = 100; + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean saveFreqConverterStatus(FreqConverterStatus status) { + return this.save(status); + } + + @Override + public List listStatusHistory(String converterId) { + return this.lambdaQuery().eq(FreqConverterStatus::getConverterId, converterId).list(); + } + + @Override + public boolean clearAllData() { + return this.remove(null); + } +} diff --git a/detection/src/main/java/com/njcn/gather/freqConverter/service/impl/PqFreqConverterConfigServiceImpl.java b/detection/src/main/java/com/njcn/gather/freqConverter/service/impl/PqFreqConverterConfigServiceImpl.java new file mode 100644 index 00000000..7e8a34b0 --- /dev/null +++ b/detection/src/main/java/com/njcn/gather/freqConverter/service/impl/PqFreqConverterConfigServiceImpl.java @@ -0,0 +1,15 @@ +package com.njcn.gather.freqConverter.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.njcn.gather.freqConverter.mapper.PqFreqConverterConfigMapper; +import com.njcn.gather.freqConverter.pojo.po.PqFreqConverterConfig; +import com.njcn.gather.freqConverter.service.IPqFreqConverterConfigService; +import org.springframework.stereotype.Service; + +/** + * @author caozehui + * @data 2026-04-08 + */ +@Service +public class PqFreqConverterConfigServiceImpl extends ServiceImpl implements IPqFreqConverterConfigService { +} diff --git a/entrance/src/main/resources/application.yml b/entrance/src/main/resources/application.yml index b812a8e6..c339c041 100644 --- a/entrance/src/main/resources/application.yml +++ b/entrance/src/main/resources/application.yml @@ -6,10 +6,10 @@ spring: datasource: druid: driver-class-name: com.mysql.cj.jdbc.Driver -# url: jdbc:mysql://192.168.1.24:13306/pqs91002?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true -# username: root -# password: njcnpqs - url: jdbc:mysql://192.168.1.24:13306/pqs9100_nx?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true + # url: jdbc:mysql://192.168.1.24:13306/pqs91002?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true + # username: root + # password: njcnpqs + url: jdbc:mysql://192.168.1.24:13306/pqs9100?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true username: root password: njcnpqs #初始化建立物理连接的个数、最小、最大连接数 @@ -46,12 +46,15 @@ mybatis-plus: socket: - source: - ip: 127.0.0.1 - port: 62000 device: ip: 127.0.0.1 port: 61000 + source: + ip: 127.0.0.1 + port: 63000 + freqConverter: + ip: 127.0.0.1 + port: 63000 # source: # ip: 192.168.1.121 # port: 10086