Revert "微调"

This reverts commit 4110a835c8.
This commit is contained in:
caozehui
2026-04-13 15:39:15 +08:00
parent f0857b7c46
commit c148bddfc9
26 changed files with 34 additions and 1265 deletions

View File

@@ -176,26 +176,4 @@ public class PreDetectionController extends BaseController {
preDetectionService.startCoefficient();
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
}
@OperateInfo(info = LogEnum.SYSTEM_COMMON)
@GetMapping("/startFreqConverter")
@ApiOperation("开启变频器测试")
public HttpResult<String> 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<String> 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);
}
}

View File

@@ -1,268 +0,0 @@
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<String> 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<PreDetection> preDetections = pqDevService.getDevInfo(Collections.singletonList(split[0]));
if (CollUtil.isEmpty(preDetections)) {
return null;
}
PreDetection preDetection = preDetections.get(0);
List<PreDetection.MonitorListDTO> monitorList = preDetection.getMonitorList();
if (CollUtil.isEmpty(monitorList)) {
return null;
}
List<PreDetection.MonitorListDTO> matchedMonitorList = monitorList.stream()
.filter(item -> split[1].equals(item.getLineId()))
.collect(Collectors.toList());
if (CollUtil.isEmpty(matchedMonitorList)) {
return null;
}
preDetection.setMonitorList(matchedMonitorList);
Map<String, List<PreDetection>> payload = new HashMap<>(1);
payload.put("deviceList", Collections.singletonList(preDetection));
return JSON.toJSONString(payload);
}
private void sendGetDipDataMsg(String monitorId) {
SocketMsg<String> 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<String> 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);
}
}
}

View File

@@ -1,221 +0,0 @@
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<Map<String, Object>> socketMsg = new SocketMsg<>();
socketMsg.setOperateCode(SourceOperateCodeEnum.CMD_INIT_SERIAL.getValue());
String requestId = IdUtil.fastSimpleUUID();
socketMsg.setRequestId(requestId);
PqFreqConverterConfig freqConverterConfig = pqFreqConverterConfigService.getById(converterId);
Map<String, Object> 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<Map<String, Object>> socketMsg = new SocketMsg<>();
socketMsg.setOperateCode(SourceOperateCodeEnum.CMD_GET_DEVICE_STATUS.getValue());
String requestId = IdUtil.fastSimpleUUID();
socketMsg.setRequestId(requestId);
Map<String, Object> map = new HashMap<>();
socketMsg.setData(map);
SocketManager.sendMsg(converterId, JSON.toJSONString(socketMsg));
}
private void sendClose(String converterId) {
SocketMsg<Map<String, Object>> socketMsg = new SocketMsg<>();
socketMsg.setOperateCode(SourceOperateCodeEnum.CMD_CLOSE_SERIAL.getValue());
String requestId = IdUtil.fastSimpleUUID();
socketMsg.setRequestId(requestId);
Map<String, Object> 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;
}
}
}

View File

@@ -1,42 +0,0 @@
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;
}

View File

@@ -70,6 +70,9 @@ public enum SourceOperateCodeEnum {
FLICKER_DATA_CHECK("flicker_data_check","闪变数据校验"),
/**
*
*/
@@ -97,17 +100,12 @@ 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", "启动录波"),
CMD_PING("ping", "检查 TCP 服务是否在线"),
CMD_INIT_SERIAL("initSerial", "初始化并打开串口连接"),
CMD_GET_SERIAL_CONFIG("getSerialConfig", "获取当前串口配置"),
CMD_GET_DEVICE_STATUS("getDeviceStatus", "读取变频器运行状态"),
CMD_CLOSE_SERIAL("closeSerial", "关闭串口"),;
RDRE$01("RDRE$01", "启动录波");
private final String value;
private final String msg;

View File

@@ -3,7 +3,6 @@ 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;
@@ -69,8 +68,4 @@ public interface PreDetectionService {
boolean getCanCoefficient();
void startCoefficient();
void startFreqConverter(String converterId, String monitorId);
void stopFreqConverter(String converterId,String monitorId);
}

View File

@@ -6,7 +6,9 @@ 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.*;
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.pojo.constant.DetectionCommunicateConstant;
import com.njcn.gather.detection.pojo.enums.DetectionResponseEnum;
import com.njcn.gather.detection.pojo.enums.SourceOperateCodeEnum;
@@ -74,8 +76,6 @@ 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,27 +393,6 @@ 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);
}
/**
* 比对式-与通信模块进行连接
*
@@ -472,4 +451,4 @@ public class PreDetectionServiceImpl implements PreDetectionService {
}
}
}
}

View File

@@ -31,9 +31,6 @@ public class FormalTestManager {
// 当前步骤
public static SourceOperateCodeEnum currentStep;
public static SourceOperateCodeEnum freqConverterStep;
public static SourceOperateCodeEnum freqConverterDevStep;
/**
* key:设备ip,value:当前设备下面的监测点ID(ip_通道号)
*/

View File

@@ -81,17 +81,6 @@ 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);
}
@@ -326,4 +315,4 @@ public class SocketManager {
}

View File

@@ -56,109 +56,6 @@ 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<NioSocketChannel> 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<NioSocketChannel> createCommonChannelInitializer(
String id, SimpleChannelInboundHandler handler) {
return new ChannelInitializer<NioSocketChannel>() {
@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() {

View File

@@ -1,124 +0,0 @@
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<String> {
/**
* 变频器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);
}
}

View File

@@ -1,67 +0,0 @@
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<String> {
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);
}
}

View File

@@ -18,34 +18,16 @@ import java.util.Set;
@Component
@ConfigurationProperties(prefix = "socket")
public class SocketConnectionConfig {
/**
* 被检设备配置
*/
private DeviceConfig device = new DeviceConfig();
/**
* 程控源设备配置
*/
private SourceConfig source = new SourceConfig();
/**
* 变频器配置
* 被检设备配置
*/
private DeviceConfig freqConverter = new DeviceConfig();
@Data
public static class DeviceConfig {
/**
* 被检设备IP地址
*/
private String ip;
/**
* 被检设备端口号
*/
private Integer port;
}
private DeviceConfig device = new DeviceConfig();
@Data
public static class SourceConfig {
@@ -53,18 +35,24 @@ public class SocketConnectionConfig {
* 程控源IP地址
*/
private String ip;
/**
* 程控源端口号
*/
private Integer port;
}
/**
* 获取被检设备配置
*/
public DeviceConfig getDevice() {
return device;
@Data
public static class DeviceConfig {
/**
* 被检设备IP地址
*/
private String ip;
/**
* 被检设备端口号
*/
private Integer port;
}
/**
@@ -75,10 +63,10 @@ public class SocketConnectionConfig {
}
/**
* 获取变频器配置
* 获取被检设备配置
*/
public DeviceConfig getFreqConverter() {
return freqConverter;
public DeviceConfig getDevice() {
return device;
}
/**

View File

@@ -1,11 +0,0 @@
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<PqDipData> {
}

View File

@@ -1,44 +0,0 @@
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;
}

View File

@@ -1,11 +0,0 @@
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<PqDipData> {
}

View File

@@ -1,15 +0,0 @@
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<PqDipDataMapper, PqDipData> implements IPqDipDataService {
}

View File

@@ -1,11 +0,0 @@
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<FreqConverterStatus> {
}

View File

@@ -1,12 +0,0 @@
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<PqFreqConverterConfig> {
}

View File

@@ -1,43 +0,0 @@
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;
}

View File

@@ -1,53 +0,0 @@
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;
}

View File

@@ -1,37 +0,0 @@
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<FreqConverterStatus> {
/**
* 保存变频器状态数据
*
* @param status 变频器状态数据
* @return 是否保存成功
*/
boolean saveFreqConverterStatus(FreqConverterStatus status);
/**
* 查询指定变频器的状态历史
*
* @param converterId 变频器ID
* @return 状态数据列表
*/
List<FreqConverterStatus> listStatusHistory(String converterId);
/**
* 清空所有数据
*
* @return
*/
boolean clearAllData();
}

View File

@@ -1,11 +0,0 @@
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<PqFreqConverterConfig> {
}

View File

@@ -1,64 +0,0 @@
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实现类
* <p>
* 实现变频器状态数据的存储、查询和清理功能。
* 当数据量超过阈值时,自动清理无效或过期数据,避免内存和数据库资源浪费。
* </p>
*
* @author CN_Gather Detection Team
* @version 1.0
* @since 2026
*/
@Slf4j
@Service
public class FreqConverterServiceImpl extends ServiceImpl<FreqConverterStatusMapper, FreqConverterStatus> 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<FreqConverterStatus> listStatusHistory(String converterId) {
return this.lambdaQuery().eq(FreqConverterStatus::getConverterId, converterId).list();
}
@Override
public boolean clearAllData() {
return this.remove(null);
}
}

View File

@@ -1,15 +0,0 @@
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<PqFreqConverterConfigMapper, PqFreqConverterConfig> implements IPqFreqConverterConfigService {
}

View File

@@ -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?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_nx?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: root
password: njcnpqs
#初始化建立物理连接的个数、最小、最大连接数
@@ -46,15 +46,12 @@ 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