正式检测-收取数据、原始数据组装和入库、配对关系入库、误差计算逻辑

This commit is contained in:
caozehui
2025-08-18 16:15:35 +08:00
parent 257d0b3af8
commit c9bf604a33
48 changed files with 1429 additions and 964 deletions

View File

@@ -9,7 +9,6 @@ import com.njcn.gather.detection.pojo.param.SimulateDetectionParam;
import com.njcn.gather.detection.service.PreDetectionService;
import com.njcn.web.controller.BaseController;
import com.njcn.web.utils.HttpResultUtil;
import com.njcn.web.utils.RequestUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
@@ -18,6 +17,8 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
* @author chendaofei
@@ -143,4 +144,20 @@ public class PreDetectionController extends BaseController {
preDetectionService.startContrastTest(param);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
}
/**
* 获取比对检测的监测次数信息
*
* @param planId
* @return
*/
@GetMapping("/getContrastTestNumInfo")
@OperateInfo
@ApiOperation("获取比对检测的检测次数信息")
@ApiImplicitParam(name = "planId", value = "计划ID", required = true)
public HttpResult<Map<Integer, Integer>> getContrastTestNumInfo(@RequestParam("planId") String planId) {
String methodDescribe = getMethodDescribe("getContrastTestNumInfo");
Map<Integer, Integer> result = preDetectionService.getContrastTestNumInfo(planId);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
}
}

View File

@@ -57,8 +57,6 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.njcn.gather.detection.util.socket.FormalTestManager.harmonicRelationMap;
@Service
@RequiredArgsConstructor
@@ -1715,9 +1713,6 @@ public class SocketDevResponseService {
if (param.getTestItemList().get(1)) {
initXiManager(param);
}
harmonicRelationMap.put(DetectionCodeEnum.V2_50.getCode(), DetectionCodeEnum.U1.getCode());
harmonicRelationMap.put(DetectionCodeEnum.I2_50.getCode(), DetectionCodeEnum.I1.getCode());
}
//初始化系数校验参数
@@ -1782,6 +1777,9 @@ public class SocketDevResponseService {
System.out.println("原始数据插入数据库开始执行=========================================");
List<SimAndDigNonHarmonicResult> simAndDigNonHarmonicResultList = new ArrayList<>();
List<SimAndDigHarmonicResult> adHarmonicResultList = new ArrayList<>();
Map<String, String> harmonicRelationMap = new HashMap<>();
harmonicRelationMap.put(DetectionCodeEnum.V2_50.getCode(), DetectionCodeEnum.U1.getCode());
harmonicRelationMap.put(DetectionCodeEnum.I2_50.getCode(), DetectionCodeEnum.I1.getCode());
for (DevData data : devDataList) {
LocalDateTime localDateTime = DetectionUtil.timeFormat(data.getTime(), DetectionUtil.FORMATTER);
if (Objects.nonNull(localDateTime)) {

View File

@@ -0,0 +1,11 @@
package com.njcn.gather.detection.mapper;
import com.github.yulichang.base.MPJBaseMapper;
import com.njcn.gather.detection.pojo.po.AdPair;
/**
* @author caozehui
* @data 2025-08-18
*/
public interface AdPairMapper extends MPJBaseMapper<AdPair> {
}

View File

@@ -0,0 +1,29 @@
package com.njcn.gather.detection.pojo.dto;
import com.njcn.gather.err.pojo.po.PqErrSysDtls;
import lombok.Data;
/**
* @author caozehui
* @data 2025-08-12
*/
@Data
public class ConditionDataDTO {
/**
* 某一相别且某一个误差条件范围内的被检色设备数据
*/
private Double devData;
/**
* 某一相别且某一个误差条件范围内的标准设备数据
*/
private Double stdDevData;
/**
* 与上面数据所对应的误差体系详情
*/
private PqErrSysDtls pqErrSysDtls;
}

View File

@@ -0,0 +1,16 @@
package com.njcn.gather.detection.pojo.dto;
import lombok.Data;
/**
* @author caozehui
* @data 2025-08-12
*/
@Data
public class HarmonicConditionDataDTO extends ConditionDataDTO {
/**
* (间谐波)谐波次数
*/
private Double harmonicNum;
}

View File

@@ -13,6 +13,7 @@ public enum DetectionCodeEnum {
FREQ("FREQ", "频率"),
VRMS("VRMS", "相电压有效值"),
LINE_VRMS("LINE_VRMS", "线电压有效值"),
DELTA_V("DELTA_V", "电压偏差"),
VA("VA", "电压相角"),
U1("U1", "基波电压"),
@@ -34,7 +35,9 @@ public enum DetectionCodeEnum {
STAR("Star","星型接线"),
DELTA("Delta","角型接线");
DELTA("Delta","角型接线"),
REAL_PREFIX("real$", "实时数据前缀");
private final String code;
private final String message;

View File

@@ -0,0 +1,24 @@
package com.njcn.gather.detection.pojo.enums;
import lombok.Getter;
/**
* @author caozehui
* @data 2025-08-13
*/
@Getter
public enum ResultEnum {
QUALIFIED(1, "符合"),
NOT_QUALIFIED(2, "不符合"),
NETWORK_TIMEOUT(3, "网络超时"),
NO_ERROR_SYS(4, "不在误差条件范围内"),
NO_COMPARE_ERROR_SYS(5, "不参与误差比较");
private int value;
private String msg;
ResultEnum(int value, String msg) {
this.value = value;
this.msg = msg;
}
}

View File

@@ -41,4 +41,9 @@ public class ContrastDetectionParam {
* 检测项列表。第一个元素为预检测、第二个元素为系数校准、第三个元素为正式检测
*/
private List<Boolean> testItemList;
/**
* 当前检测次数
*/
private Integer num;
}

View File

@@ -73,4 +73,9 @@ public class PreDetectionParam {
* 检测项列表。第一个元素为预检测、第二个元素为系数校准、第三个元素为正式检测
*/
private List<Boolean> testItemList;
/**
* 第几次监测
*/
private Integer num;
}

View File

@@ -0,0 +1,24 @@
package com.njcn.gather.detection.pojo.po;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
/**
* @author caozehui
* @data 2025-08-18
*/
@Data
@TableName("ad_pair")
public class AdPair implements Serializable {
private String id;
private String planId;
private Integer num;
private String devMonitorId;
private String stdDevMonitorId;
}

View File

@@ -13,7 +13,7 @@ import java.util.List;
@Data
public class AlignDataVO {
private String devName;
private String stdDevName;
private List<ChannelData> channelDataList;
@@ -24,11 +24,11 @@ public class AlignDataVO {
@NoArgsConstructor
public static class ChannelData {
// 被检设备通道号
private String devNum;
// 标准设备通道号
private String stdDevNum;
// 与之对应的标准设备名称_通道号
private String standardDevInfo;
// 与之对应的被检设备名称_通道号
private String devInfo;
// 数据
private List<RawData> dataList;

View File

@@ -48,4 +48,9 @@ public class DetectionData {
* 单位
*/
private String unit;
/**
* 误差体系详情ID(比对式使用)
*/
private String errorDtlId;
}

View File

@@ -1,10 +1,7 @@
package com.njcn.gather.detection.pojo.vo;
import io.swagger.models.auth.In;
import lombok.Data;
import java.util.List;
/**
* @Author: cdf
* @CreateTime: 2024-12-26
@@ -13,6 +10,11 @@ import java.util.List;
@Data
public class DevLineTestResult {
/**
* 检测项code
*/
private String scriptName;
private String deviceId;
private String deviceName;

View File

@@ -0,0 +1,11 @@
package com.njcn.gather.detection.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.njcn.gather.detection.pojo.po.AdPair;
/**
* @author caozehui
* @data 2025-08-18
*/
public interface IAdPariService extends IService<AdPair> {
}

View File

@@ -4,6 +4,8 @@ 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 java.util.Map;
/**
* @author wr
@@ -56,4 +58,12 @@ public interface PreDetectionService {
* @param param
*/
void startContrastTest(ContrastDetectionParam param);
/**
* 获取比对式检测次数信息
*
* @param planId
* @return
*/
Map<Integer, Integer> getContrastTestNumInfo(String planId);
}

View File

@@ -0,0 +1,17 @@
package com.njcn.gather.detection.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.gather.detection.mapper.AdPairMapper;
import com.njcn.gather.detection.pojo.po.AdPair;
import com.njcn.gather.detection.service.IAdPariService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
/**
* @author caozehui
* @data 2025-08-18
*/
@Service
@RequiredArgsConstructor
public class AdPairServiceImpl extends ServiceImpl<AdPairMapper, AdPair> implements IAdPariService {
}

View File

@@ -6,6 +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.db.mybatisplus.handler.DynamicTableNameHandler;
import com.njcn.gather.detection.handler.SocketContrastResponseService;
import com.njcn.gather.detection.handler.SocketDevResponseService;
import com.njcn.gather.detection.handler.SocketSourceResponseService;
@@ -22,7 +23,6 @@ import com.njcn.gather.detection.util.socket.CnSocketUtil;
import com.njcn.gather.detection.util.socket.FormalTestManager;
import com.njcn.gather.detection.util.socket.SocketManager;
import com.njcn.gather.detection.util.socket.websocket.WebServiceManager;
import com.njcn.web.utils.RequestUtil;
import com.njcn.gather.device.pojo.po.PqDev;
import com.njcn.gather.device.pojo.vo.PreDetection;
import com.njcn.gather.device.service.IPqDevService;
@@ -37,8 +37,15 @@ import com.njcn.gather.script.service.IPqScriptCheckDataService;
import com.njcn.gather.script.service.IPqScriptDtlsService;
import com.njcn.gather.source.pojo.po.SourceInitialize;
import com.njcn.gather.source.service.IPqSourceService;
import com.njcn.gather.storage.pojo.po.ContrastHarmonicResult;
import com.njcn.gather.storage.pojo.po.ContrastNonHarmonicResult;
import com.njcn.gather.storage.service.ContrastHarmonicService;
import com.njcn.gather.storage.service.ContrastNonHarmonicService;
import com.njcn.gather.system.cfg.pojo.po.SysTestConfig;
import com.njcn.gather.system.cfg.service.ISysTestConfigService;
import com.njcn.gather.system.dictionary.pojo.enums.DictDataEnum;
import com.njcn.gather.system.dictionary.service.IDictDataService;
import com.njcn.web.utils.RequestUtil;
import io.netty.channel.Channel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -55,7 +62,6 @@ import java.util.stream.Collectors;
public class PreDetectionServiceImpl implements PreDetectionService {
private final String stepTag = "&&";
private final String handlerSourceStr = "_Source";
private final IPqDevService iPqDevService;
private final IDictDataService dictDataService;
@@ -63,11 +69,14 @@ public class PreDetectionServiceImpl implements PreDetectionService {
private final IAdPlanSourceService adPlanSourceService;
private final IPqSourceService pqSourceService;
private final IPqScriptDtlsService pqScriptDtlsService;
private final ISysTestConfigService testConfigService;
private final SocketDevResponseService socketDevResponseService;
private final SocketSourceResponseService socketSourceResponseService;
private final SocketContrastResponseService socketContrastResponseService;
private final IPqScriptCheckDataService iPqScriptCheckDataService;
private final ContrastNonHarmonicService contrastNonHarmonicService;
private final ContrastHarmonicService contrastHarmonicService;
private final SocketManager socketManager;
@@ -293,7 +302,7 @@ public class PreDetectionServiceImpl implements PreDetectionService {
socketMsg.setOperateCode(SourceOperateCodeEnum.OPER_GATHER.getValue());
socketMsg.setRequestId(SourceOperateCodeEnum.FORMAL_REAL.getValue() + stepTag + sourceIssue.getType());
socketMsg.setData(JSON.toJSONString(sourceIssues.get(0)));
SocketManager.sendMsg(param.getUserPageId() + handlerSourceStr, JSON.toJSONString(socketMsg));
SocketManager.sendMsg(param.getUserPageId() + CnSocketUtil.SOURCE_TAG, JSON.toJSONString(socketMsg));
}
@Override
@@ -315,13 +324,44 @@ public class PreDetectionServiceImpl implements PreDetectionService {
// 参数校验目前仅检查IP是否重复后续可在里面扩展
checkDevIp(param.getDevIds());
socketContrastResponseService.init(param);
//用于处理异常导致的socket通道未关闭socket交互异常
//DetectionCommunicateUtil.checkContrastCommunicateChannel(param.getLoginName());
// 和通信模块进行连接
this.sendContrastSocket(param);
}
@Override
public Map<Integer, Integer> getContrastTestNumInfo(String planId) {
AdPlan plan = iAdPlanService.getById(planId);
SysTestConfig oneConfig = testConfigService.getOneConfig();
Integer maxNum = 1;
String code = String.valueOf(plan.getCode());
String adNonTable = "ad_non_harmonic_";
String adTable = "ad_harmonic_";
DynamicTableNameHandler.setTableName(adNonTable + code);
ContrastNonHarmonicResult result1 = contrastNonHarmonicService.lambdaQuery().select(ContrastNonHarmonicResult::getNum).orderByDesc().last("LIMIT 1").one();
if (ObjectUtil.isNotNull(result1)) {
if (result1.getNum().compareTo(maxNum) > 0) {
maxNum = result1.getNum() + 1;
}
}
DynamicTableNameHandler.remove();
DynamicTableNameHandler.setTableName(adTable + code);
ContrastHarmonicResult result2 = contrastHarmonicService.lambdaQuery().select(ContrastHarmonicResult::getNum).orderByDesc().last("LIMIT 1").one();
if (ObjectUtil.isNotNull(result2)) {
if (result2.getNum().compareTo(maxNum) > 0) {
maxNum = result2.getNum() + 1;
}
}
DynamicTableNameHandler.remove();
Map<Integer, Integer> map = new HashMap<>();
map.put(oneConfig.getMaxTime(), maxNum);
return map;
}
/**
* 比对式-与通信模块进行连接
*

View File

@@ -12,7 +12,9 @@ import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -385,4 +387,24 @@ public class DetectionUtil {
return indexList;
}
/**
* 根据idxList索引列表从oldList中获取新数组
*
* @param oldList
* @param idxList
* @return
*/
public static List<Double> getNewArray(List<Double> oldList, List<Integer> idxList) {
if (CollUtil.isNotEmpty(oldList) && CollUtil.isNotEmpty(idxList)) {
if (CollUtil.max(idxList) > oldList.size() - 1 || CollUtil.min(idxList) < 0) {
return null;
}
List<Double> newList = new ArrayList<>();
for (int i = 0; i < idxList.size(); i++) {
newList.add(oldList.get(idxList.get(i)));
}
return newList;
}
return null;
}
}

View File

@@ -79,11 +79,6 @@ public class FormalTestManager {
*/
public static Integer stopTime = 0;
/**
* 强行赋值关系
*/
public static Map<String, String> harmonicRelationMap = new HashMap<>();
/**
* 当前正在检测的计划
*/
@@ -95,9 +90,9 @@ public class FormalTestManager {
public static PatternEnum patternEnum;
/**
* 比对式检测-检测项。
* 比对式检测-检测项。key为检测项id,value为检测项code
*/
public static List<String> testItemCodeList = new ArrayList<>();
public static Map<String,String> testItemMap = new HashMap<>();
/**
* 数据处理原则

View File

@@ -10,15 +10,10 @@ import com.njcn.gather.detection.util.socket.MsgUtil;
import com.njcn.gather.detection.util.socket.SocketManager;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import java.time.LocalDateTime;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.*;
/**
* Netty心跳处理器
@@ -26,7 +21,7 @@ import java.util.concurrent.TimeUnit;
* 负责维护Socket长连接的心跳检测机制通过定期发送心跳包来检测连接状态
* 当连续多次未收到心跳响应时自动断开连接并清理相关资源。
* </p>
*
*
* <h3>核心功能:</h3>
* <ul>
* <li>定时发送心跳包 (默认10秒间隔3秒后开始)</li>
@@ -35,7 +30,7 @@ import java.util.concurrent.TimeUnit;
* <li>异步处理断开操作,避免阻塞心跳线程</li>
* <li>优雅关闭资源,防止内存泄漏</li>
* </ul>
*
*
* <h3>心跳机制流程:</h3>
* <pre>
* 连接建立 → 启动心跳定时任务(3秒后开始每10秒执行)
@@ -46,60 +41,72 @@ import java.util.concurrent.TimeUnit;
* ↓
* 连接断开 → 优雅关闭定时任务和线程池
* </pre>
*
*
* <h3>线程安全设计:</h3>
* <p>
* 使用单线程的ScheduledExecutorService处理心跳发送避免并发问题。
* 超时处理使用CompletableFuture异步执行不阻塞心跳发送线程。
* Future引用使用volatile修饰确保多线程环境下的可见性。
* </p>
*
*
* <h3>设备类型支持:</h3>
* <ul>
* <li>程控源设备 (CnSocketUtil.SOURCE_TAG): "_Source"</li>
* <li>被检设备 (CnSocketUtil.DEV_TAG): "_Dev"</li>
* </ul>
*
*
* <h3>使用示例:</h3>
* <pre>{@code
* // 创建心跳处理器
* HeartbeatHandler handler = new HeartbeatHandler(param, CnSocketUtil.SOURCE_TAG);
*
*
* // 添加到Netty管道中
* pipeline.addLast(handler);
* }</pre>
*
*
* @author cdf
* @since 2025-02-11
* @version 1.2
* @since 2025-02-11
*/
@Slf4j
public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
/** 心跳定时任务执行器,使用单线程池避免并发问题 */
/**
* 心跳定时任务执行器,使用单线程池避免并发问题
*/
private final ScheduledExecutorService heartbeatExecutor = Executors.newScheduledThreadPool(1);
/** 检测参数包含用户页面ID等信息 */
/**
* 检测参数包含用户页面ID等信息
*/
private final PreDetectionParam param;
/** 处理器类型标识("_Source" 或 "_Dev" */
/**
* 处理器类型标识("_Source" 或 "_Dev"
*/
private final String handlerType;
/** 保存定时任务的Future引用便于取消和管理 */
/**
* 保存定时任务的Future引用便于取消和管理
*/
private ScheduledFuture<?> heartbeatFuture;
/** 允许连续未收到心跳响应的最大次数 */
/**
* 允许连续未收到心跳响应的最大次数
*/
private static final int MAX_HEARTBEAT_MISSES = 3;
/** 连续未收到心跳响应的次数 */
/**
* 连续未收到心跳响应的次数
*/
private int consecutiveHeartbeatMisses = 0;
/**
* 构造函数
*
*
* @param param 检测参数包含用户页面ID等信息
* @param type 处理器类型CnSocketUtil.SOURCE_TAG 或 CnSocketUtil.DEV_TAG
* @param type 处理器类型CnSocketUtil.SOURCE_TAG 或 CnSocketUtil.DEV_TAG
*/
public HeartbeatHandler(PreDetectionParam param, String type) {
this.param = param;
@@ -110,7 +117,7 @@ public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
/**
* 通道激活时的回调方法
* 在Socket连接建立成功后被调用启动心跳机制
*
*
* @param ctx Netty的通道上下文对象
*/
@Override
@@ -125,7 +132,7 @@ public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
/**
* 通道断开时的回调方法
* 在Socket连接断开时被调用负责清理相关资源
*
*
* @param ctx Netty的通道上下文对象
* @throws Exception 异常情况
*/
@@ -139,7 +146,7 @@ public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
/**
* 启动心跳定时任务
* 每10秒发送一次心跳包3秒后开始执行
*
*
* @param ctx Netty的通道上下文对象
*/
private void scheduleHeartbeat(ChannelHandlerContext ctx) {
@@ -156,8 +163,8 @@ public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
consecutiveHeartbeatMisses++;
if (consecutiveHeartbeatMisses >= MAX_HEARTBEAT_MISSES) {
// 连续三次未收到心跳响应,异步处理断开逻辑,避免阻塞心跳线程
log.warn("心跳响应超时 - 设备类型: {}, 连续失败次数: {}/{}, 执行断开连接",
handlerType, consecutiveHeartbeatMisses, MAX_HEARTBEAT_MISSES);
log.warn("心跳响应超时 - 设备类型: {}, 连续失败次数: {}/{}, 执行断开连接",
handlerType, consecutiveHeartbeatMisses, MAX_HEARTBEAT_MISSES);
handleHeartbeatTimeoutAsync();
consecutiveHeartbeatMisses = 0; // 重置连续心跳丢失次数
}
@@ -182,8 +189,10 @@ public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
// 根据设备类型发送对应的退出指令
if (CnSocketUtil.DEV_TAG.equals(handlerType)) {
CnSocketUtil.quitSend(param);
} else {
} else if (CnSocketUtil.SOURCE_TAG.equals(handlerType)) {
CnSocketUtil.quitSendSource(param);
} else {
CnSocketUtil.contrastSendquit(param.getUserPageId(), true);
}
log.debug("退出指令已发送等待3秒后清理连接 - 设备类型: {}", handlerType);
} catch (Exception e) {
@@ -194,9 +203,9 @@ public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
// 延迟3秒后清理连接给退出指令留出处理时间
Thread.sleep(3000);
// 构建连接Key并从SocketManager中移除
String key = CnSocketUtil.DEV_TAG.equals(handlerType) ?
param.getUserPageId() + CnSocketUtil.DEV_TAG :
param.getUserPageId() + CnSocketUtil.SOURCE_TAG;
String key = CnSocketUtil.DEV_TAG.equals(handlerType) ?
param.getUserPageId() + CnSocketUtil.DEV_TAG :
param.getUserPageId() + CnSocketUtil.SOURCE_TAG;
SocketManager.removeUser(key);
log.info("心跳超时断开处理完成 - 设备类型: {}, 连接已清理", handlerType);
} catch (InterruptedException e) {
@@ -254,7 +263,7 @@ public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
* 1. 过滤心跳响应包,重置失败计数器
* 2. 业务消息传递给后续处理器
* </p>
*
*
* @param ctx Netty的通道上下文对象
* @param msg 接收到的消息内容
* @throws Exception 异常情况
@@ -278,7 +287,7 @@ public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
* 通过解析消息的operateCode字段来判断是否为心跳响应。
* 心跳包的操作码为SourceOperateCodeEnum.HEARTBEAT。
* </p>
*
*
* @param msg 需要判断的消息内容
* @return true:心跳包, false:业务消息
*/
@@ -287,9 +296,9 @@ public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
// 解析消息为SocketDataMsg对象
SocketDataMsg socketDataMsg = MsgUtil.socketDataMsg(msg);
// 检查操作码是否为心跳类型
return socketDataMsg != null &&
socketDataMsg.getOperateCode() != null &&
socketDataMsg.getOperateCode().equals(SourceOperateCodeEnum.HEARTBEAT.getValue());
return socketDataMsg != null &&
socketDataMsg.getOperateCode() != null &&
socketDataMsg.getOperateCode().equals(SourceOperateCodeEnum.HEARTBEAT.getValue());
} catch (Exception e) {
// 消息解析失败,可能不是标准格式的心跳包
log.debug("消息解析失败,可能不是心跳包: {}", msg, e);

View File

@@ -127,6 +127,7 @@ public class NettyClient {
PreDetectionParam preDetectionParam = new PreDetectionParam();
preDetectionParam.setUserPageId(param.getLoginName());
preDetectionParam.setTestItemList(param.getTestItemList());
preDetectionParam.setNum(param.getNum());
NettyContrastClientHandler handler = new NettyContrastClientHandler(preDetectionParam, socketContrastResponseService);
executeSocketConnection(ip, port, preDetectionParam, msg, handler);
}

View File

@@ -3,6 +3,7 @@ package com.njcn.gather.detection.util.socket.cilent;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.njcn.gather.detection.handler.SocketDevResponseService;
import com.njcn.gather.detection.pojo.enums.ResultEnum;
import com.njcn.gather.detection.pojo.enums.SourceOperateCodeEnum;
import com.njcn.gather.detection.pojo.param.PreDetectionParam;
import com.njcn.gather.detection.pojo.vo.DevLineTestResult;
@@ -71,11 +72,6 @@ public class NettyDevClientHandler extends SimpleChannelInboundHandler<String> {
*/
private static final long STOP_TIMEOUT = 600L;
/**
* 超时时默认结果标志3表示超时失败
*/
private static final int DEFAULT_RESULT_FLAG = 3;
private final PreDetectionParam param;
private final SocketDevResponseService socketResponseService;
@@ -247,7 +243,7 @@ public class NettyDevClientHandler extends SimpleChannelInboundHandler<String> {
log.warn("当前进入暂停操作超时函数,停止时间: {}", FormalTestManager.stopTime);
if (FormalTestManager.stopTime > STOP_TIMEOUT) {
CnSocketUtil.quitSend(param);
WebServiceManager.sendDetectionErrorMessage(param.getUserPageId(),SourceOperateCodeEnum.FORMAL_REAL.getValue(), SourceOperateCodeEnum.STOP_TIMEOUT);
WebServiceManager.sendDetectionErrorMessage(param.getUserPageId(), SourceOperateCodeEnum.FORMAL_REAL.getValue(), SourceOperateCodeEnum.STOP_TIMEOUT);
}
}
@@ -285,13 +281,13 @@ public class NettyDevClientHandler extends SimpleChannelInboundHandler<String> {
// 根据不同检测类型使用不同的超时阈值
if (DicDataEnum.F.getCode().equals(type)) {
// 闪变检测需要更长时间20分钟超时
return currentTime > FLICKER_TIMEOUT;
return currentTime >= FLICKER_TIMEOUT;
} else if (DicDataEnum.VOLTAGE.getCode().equals(type) || DicDataEnum.HP.getCode().equals(type)) {
// 统计数据类型电压、谐波中等时间3分钟超时
return currentTime > STATISTICS_TIMEOUT;
return currentTime >= STATISTICS_TIMEOUT;
} else {
// 实时数据类型短时间1分钟超时
return currentTime > REALTIME_TIMEOUT;
return currentTime >= REALTIME_TIMEOUT;
}
}
@@ -340,7 +336,7 @@ public class NettyDevClientHandler extends SimpleChannelInboundHandler<String> {
devLineTestResult.setDeviceName(dev.getDevName());
Integer[] resultFlags = dev.getMonitorList().stream()
.map(monitor -> DEFAULT_RESULT_FLAG)
.map(monitor -> ResultEnum.NETWORK_TIMEOUT)
.toArray(Integer[]::new);
devLineTestResult.setChnResult(resultFlags);

View File

@@ -1,6 +1,5 @@
package com.njcn.gather.device.controller;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.annotation.OperateInfo;
@@ -10,12 +9,10 @@ import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.LogUtil;
import com.njcn.gather.device.pojo.enums.CommonEnum;
import com.njcn.gather.device.pojo.param.PqDevParam;
import com.njcn.gather.device.pojo.vo.PqDevVO;
import com.njcn.gather.device.service.IPqDevService;
import com.njcn.gather.plan.pojo.po.AdPlan;
import com.njcn.gather.type.pojo.po.DevType;
import com.njcn.gather.monitor.pojo.po.PqMonitor;
import com.njcn.gather.type.service.IDevTypeService;
import com.njcn.web.controller.BaseController;
import com.njcn.web.utils.FileUtil;
@@ -147,7 +144,7 @@ public class PqDevController extends BaseController {
if (!fileType) {
throw new BusinessException(CommonResponseEnum.FILE_XLSX_ERROR);
}
if("null".equals(planId)){
if ("null".equals(planId)) {
planId = null;
}
Boolean result = pqDevService.importDev(file, patternId, planId, response);

View File

@@ -7,6 +7,7 @@ import com.njcn.gather.device.pojo.enums.TimeCheckResultEnum;
import com.njcn.gather.device.pojo.param.PqDevParam;
import com.njcn.gather.device.pojo.po.PqDev;
import com.njcn.gather.device.pojo.vo.*;
import com.njcn.gather.monitor.pojo.po.PqMonitor;
import org.apache.ibatis.annotations.Param;
import org.springframework.web.multipart.MultipartFile;

View File

@@ -209,7 +209,7 @@ public class PqDevServiceImpl extends ServiceImpl<PqDevMapper, PqDev> implements
public boolean deletePqDev(PqDevParam.DeleteParam param) {
if (PatternEnum.CONTRAST.getValue().equals(dictDataService.getDictDataById(param.getPattern()).getCode())) {
for (String id : param.getIds()) {
if (ObjectUtils.isNotEmpty(pqMonitorService.listPqMonitorByDevId(id))) {
if (ObjectUtils.isNotEmpty(pqMonitorService.listPqMonitorByDevIds(Collections.singletonList(id)))) {
throw new BusinessException(DetectionResponseEnum.PQ_DEV_HAS_MONITOR);
}
}
@@ -363,7 +363,7 @@ public class PqDevServiceImpl extends ServiceImpl<PqDevMapper, PqDev> implements
pqDevVO.setDevVolt(devType.getDevVolt());
}
List<PqMonitor> monitorList = pqMonitorService.listPqMonitorByDevId(id);
List<PqMonitor> monitorList = pqMonitorService.listPqMonitorByDevIds(Collections.singletonList(id));
if (ObjectUtil.isNotEmpty(monitorList)) {
pqDevVO.setMonitorList(monitorList);
}
@@ -1384,7 +1384,7 @@ public class PqDevServiceImpl extends ServiceImpl<PqDevMapper, PqDev> implements
this.visualizeProvinceDev(pqDevVOList);
contrastDevExcels.addAll(BeanUtil.copyToList(pqDevVOList, ContrastDevExcel.class));
contrastDevExcels.forEach(contrastDevExcel -> {
List<PqMonitor> monitorList = pqMonitorService.listPqMonitorByDevId(contrastDevExcel.getId());
List<PqMonitor> monitorList = pqMonitorService.listPqMonitorByDevIds(Collections.singletonList(contrastDevExcel.getId()));
pqMonitorService.visualizeMonitor(monitorList);
List<PqMonitorExcel> pqMonitorExcelList = BeanUtil.copyToList(monitorList, PqMonitorExcel.class);
contrastDevExcel.setPqMonitorExcelList(pqMonitorExcelList);

View File

@@ -162,7 +162,7 @@ public class PqErrSysDtlsServiceImpl extends ServiceImpl<PqErrSysDtlsMapper, PqE
wrapper.selectAll(PqErrSysDtls.class)
.leftJoin(DictTree.class, DictTree::getId, PqErrSysDtls::getScriptType)
.eq(PqErrSysDtls::getErrorSysId, errSysId)
.eq(DictTree::getId, scriptType);
.eq(DictTree::getCode, scriptType);
return this.list(wrapper);
}
}

View File

@@ -19,6 +19,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
import java.util.List;
@@ -41,7 +42,7 @@ public class PqMonitorController extends BaseController {
public HttpResult<List<PqMonitor>> list(@RequestBody PqMonitorParam.QueryParam queryParam) {
String methodDescribe = getMethodDescribe("list");
LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, queryParam);
List<PqMonitor> result = pqMonitorService.listPqMonitorByDevId(queryParam.getDevId());
List<PqMonitor> result = pqMonitorService.listPqMonitorByDevIds(queryParam.getDevIds());
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
}
}

View File

@@ -15,11 +15,23 @@ public interface PqMonitorMapper extends MPJBaseMapper<PqMonitor> {
/**
* 根据终端id获取监测点集合
*
* @param devId
* @return: java.util.List<com.njcn.gather.device.pojo.vo.PreDetection.MonitorListDTO>
* @Author: wr
* @Date: 2024/12/12 13:15
*/
List<PreDetection.MonitorListDTO> selectMonitorInfo(@Param("devId") String devId);
/**
* 根据被检设备id和线路号获取监测点信息
*
* @param devId 被检设备id
* @param num 线路号
* @return
*/
PqMonitor getByDevIdAndNum(@Param("devId") String devId, @Param("num") Integer num);
List<PqMonitor> listByDevIds(@Param("devIds") List<String> devIds);
}

View File

@@ -16,5 +16,39 @@
WHERE Dev_Id = #{devId}
</select>
<select id="getByDevIdAndNum" resultType="com.njcn.gather.monitor.pojo.po.PqMonitor">
select pq_monitor.Id,
pq_monitor.Dev_Id,
pq_monitor.Name,
pq_monitor.Busbar,
pq_monitor.Num,
pq_monitor.Pt,
pq_monitor.Ct,
pq_monitor.Stat_Interval,
pq_monitor.Harm_Sys_Id,
sys_dict_data.Code as `Connection`
from pq_monitor
inner join sys_dict_data on pq_monitor.Connection = sys_dict_data.id
where Dev_Id = #{devId}
and Num = #{num}
</select>
<select id="listByDevIds" resultType="com.njcn.gather.monitor.pojo.po.PqMonitor">
select pq_monitor.Id,
pq_monitor.Dev_Id,
pq_monitor.Name,
pq_monitor.Busbar,
pq_monitor.Num,
pq_monitor.Pt,
pq_monitor.Ct,
pq_monitor.Stat_Interval,
pq_monitor.Harm_Sys_Id,
sys_dict_data.Code as `Connection`
from pq_monitor
inner join sys_dict_data on pq_monitor.Connection = sys_dict_data.id
where Dev_Id in
<foreach collection="devIds" item="devId" open="(" separator="," close=")">
#{devId}
</foreach>
</select>
</mapper>

View File

@@ -9,6 +9,7 @@ import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.util.List;
/**
* @author caozehui
@@ -62,18 +63,6 @@ public class PqMonitorParam {
public static class QueryParam {
@ApiModelProperty(value = "所属设备id")
@NotBlank(message = DetectionValidMessage.DEVICE_ID_NOT_BLANK)
private String devId;
private List<String> devIds;
}
/**
* 修改实体
*/
// @Data
// @EqualsAndHashCode(callSuper = true)
// public static class UpdateParam extends PqMonitorParam {
// @ApiModelProperty(value = "监测点id", required = true)
// @NotBlank(message = DetectionValidMessage.ID_NOT_BLANK)
// @Pattern(regexp = PatternRegex.SYSTEM_ID, message = DetectionValidMessage.ID_FORMAT_ERROR)
// private String id;
// }
}

View File

@@ -17,10 +17,10 @@ public interface IPqMonitorService extends IService<PqMonitor> {
/**
* 根据设备id获取所有监测点信息
*
* @param devId 被检设备id
* @param devIds 被检设备id列表
* @return 监测点信息列表
*/
List<PqMonitor> listPqMonitorByDevId(String devId);
List<PqMonitor> listPqMonitorByDevIds(List<String> devId);
/**
* 根据设备id批量新增监测点信息
@@ -62,6 +62,14 @@ public interface IPqMonitorService extends IService<PqMonitor> {
*/
void reverseVisualizeMonitor(List<PqMonitor> monitorList);
/**
* 根据被检设备监测点id获取监测点信息
*
* @param devMonitorId 被检设备监测点id
* @return
*/
PqMonitor getByDevMonitorId(String devMonitorId);
/**
* 根据被检设备id获取额定电流
* @param devMonitorId 被检设备监测点id

View File

@@ -1,6 +1,7 @@
package com.njcn.gather.monitor.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -32,8 +33,11 @@ public class PqMonitorServiceImpl extends ServiceImpl<PqMonitorMapper, PqMonitor
private final IDictDataService dictDataService;
@Override
public List<PqMonitor> listPqMonitorByDevId(String devId) {
return this.lambdaQuery().eq(PqMonitor::getDevId, devId).list();
public List<PqMonitor> listPqMonitorByDevIds(List<String> devIds) {
if (CollUtil.isNotEmpty(devIds)) {
return this.baseMapper.listByDevIds(devIds);
}
return CollUtil.empty(PqMonitor.class);
}
@Override
@@ -86,12 +90,18 @@ public class PqMonitorServiceImpl extends ServiceImpl<PqMonitorMapper, PqMonitor
});
}
@Override
public PqMonitor getByDevMonitorId(String devMonitorId) {
String[] split = devMonitorId.split("_");
return this.baseMapper.getByDevIdAndNum(split[0], Integer.valueOf(split[1]));
}
@Override
public Double getRatedCurrent(String devMonitorId) {
PqMonitor pqMonitor = this.baseMapper.selectById(devMonitorId);
PqMonitor pqMonitor = this.getByDevMonitorId(devMonitorId);
if (ObjectUtil.isNotNull(pqMonitor)) {
String ct = pqMonitor.getCt();
if(StrUtil.isNotBlank(ct) && ct.contains(StrUtil.COLON)){
if (StrUtil.isNotBlank(ct) && ct.contains(StrUtil.COLON)) {
String[] ctArray = ct.split(StrUtil.COLON);
return Double.parseDouble(ctArray[1]);
}
@@ -101,10 +111,10 @@ public class PqMonitorServiceImpl extends ServiceImpl<PqMonitorMapper, PqMonitor
@Override
public Double getRatedVoltage(String devMonitorId) {
PqMonitor pqMonitor = this.baseMapper.selectById(devMonitorId);
PqMonitor pqMonitor = this.getByDevMonitorId(devMonitorId);
if (ObjectUtil.isNotNull(pqMonitor)) {
String pt = pqMonitor.getPt();
if(StrUtil.isNotBlank(pt) && pt.contains(StrUtil.COLON)){
if (StrUtil.isNotBlank(pt) && pt.contains(StrUtil.COLON)) {
String[] ptArray = pt.split(StrUtil.COLON);
return Double.parseDouble(ptArray[1]);
}

View File

@@ -171,7 +171,7 @@ public class AdPlanController extends BaseController {
public HttpResult<List<Map<String, String>>> getBigTestItem(@RequestBody AdPlanParam.CheckParam checkParam) {
String methodDescribe = getMethodDescribe("getBigTestItem");
LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, checkParam);
List<Map<String, String>> result = adPlanService.getBigTestItem(checkParam.getReCheckType(), checkParam.getPlanId(), checkParam.getDevIds());
List<Map<String, String>> result = adPlanService.getBigTestItem(checkParam.getReCheckType(), checkParam.getPlanId(), checkParam.getDevIds(), checkParam.getPatternId());
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
}

View File

@@ -118,5 +118,6 @@ public class AdPlanParam {
private Integer reCheckType;
private String planId;
private List<String> devIds;
private String patternId;
}
}

View File

@@ -45,12 +45,11 @@ public interface IAdPlanService extends IService<AdPlan> {
/**
* 删除检测计划
*
* @param ids 检测计划id列表
* @param ids 检测计划id列表
* @param pattern 模式Id
*
* @return 删除成功则返回true否则返回false
*/
boolean deleteAdPlan(List<String> ids,String pattern);
boolean deleteAdPlan(List<String> ids, String pattern);
/**
* 根据模式查询检测计划
@@ -70,12 +69,13 @@ public interface IAdPlanService extends IService<AdPlan> {
/**
* 获取检测大项
*
* @param reCheckType 0:不合格项复检 1:全部复检
* @param planId 检测计划Id
* @param devIds 设备Id列表
* @param reCheckType 0:不合格项复检 1:全部复检
* @param planId 检测计划Id
* @param devIds 设备Id列表
* @param patternId 模式Id
* @return
*/
List<Map<String, String>> getBigTestItem(Integer reCheckType, String planId, List<String> devIds);
List<Map<String, String>> getBigTestItem(Integer reCheckType, String planId, List<String> devIds, String patternId);
/**
* 修改计划状态
@@ -150,7 +150,6 @@ public interface IAdPlanService extends IService<AdPlan> {
*
* @param planId
* @param name
*
* @return
*/
boolean updateSubPlanName(String planId, String name);

View File

@@ -510,18 +510,30 @@ public class AdPlanServiceImpl extends ServiceImpl<AdPlanMapper, AdPlan> impleme
}
@Override
public List<Map<String, String>> getBigTestItem(Integer reCheckType, String planId, List<String> devIds) {
public List<Map<String, String>> getBigTestItem(Integer reCheckType, String planId, List<String> devIds, String patternId) {
List<Map<String, String>> result = new ArrayList<>();
AdPlan adPlan = this.getById(planId);
if (ObjectUtil.isNull(adPlan)) {
throw new BusinessException(DetectionResponseEnum.PLAN_NOT_EXIST);
}
String scriptId = adPlan.getScriptId();
DictData dictData = dictDataService.getById(patternId);
if (PatternEnum.CONTRAST.getValue().equals(dictData.getCode())) {
String[] split = adPlan.getTestItem().split(StrUtil.COMMA);
List<DictTree> dictTreeList = dictTreeService.list(new QueryWrapper<DictTree>().in("id", split).eq("state", DataStateEnum.DELETED.getCode()));
List<PqScriptDtls> scriptDtlsList = pqScriptDtlsService.listPqScriptDtlByScriptId(scriptId);
for (DictTree dictTree : dictTreeList) {
Map<String, String> map = new HashMap<>();
map.put("id", dictTree.getId());
map.put("code", dictTree.getCode());
map.put("scriptName", dictTree.getName());
result.add(map);
}
} else {
String scriptId = adPlan.getScriptId();
List<PqScriptDtls> scriptDtlsList = pqScriptDtlsService.listPqScriptDtlByScriptId(scriptId);
// 不合格项复检
if (reCheckType == 0) {
// 不合格项复检
if (reCheckType == 0) {
// List<SimAndDigBaseResult> allResultList = new ArrayList<>();
// allResultList.addAll(adHarmonicService.get(scriptId, null, devId, "-1", adPlan.getCode()));
// allResultList.addAll(adNonHarmonicService.get(scriptId, null, devId, "-1", adPlan.getCode()));
@@ -532,33 +544,35 @@ public class AdPlanServiceImpl extends ServiceImpl<AdPlanMapper, AdPlan> impleme
//
// scriptDtlsList = scriptDtlsList.stream().filter(obj -> !sortSet.contains(obj.getScriptIndex())).collect(Collectors.toList());
// }
Set<Integer> indexes = new HashSet<>();
StorageParam storageParam = new StorageParam();
storageParam.setCode(adPlan.getCode() + "");
storageParam.setScriptId(adPlan.getScriptId());
devIds.forEach(devId -> {
storageParam.setDevId(devId);
indexes.addAll(adHarmonicService.getIndex(storageParam));
Set<Integer> indexes = new HashSet<>();
StorageParam storageParam = new StorageParam();
storageParam.setCode(adPlan.getCode() + "");
storageParam.setScriptId(adPlan.getScriptId());
devIds.forEach(devId -> {
storageParam.setDevId(devId);
indexes.addAll(adHarmonicService.getIndex(storageParam));
});
scriptDtlsList = scriptDtlsList.stream().filter(obj -> indexes.contains(obj.getScriptIndex())).collect(Collectors.toList());
}
Map<String, List<PqScriptDtls>> collect = scriptDtlsList.stream()
.sorted(Comparator.comparing(PqScriptDtls::getScriptIndex))
.collect(Collectors.groupingBy(PqScriptDtls::getScriptType, LinkedHashMap::new, Collectors.toList()));
collect.forEach((key, value) -> {
Map<String, String> map = new HashMap<>();
map.put("id", key);
DictTree dictTree = dictTreeService.getById(key);
if (ObjectUtil.isNotNull(dictTree)) {
map.put("code", dictTree.getCode());
map.put("scriptName", dictTree.getName());
} else {
throw new BusinessException(DetectionResponseEnum.SCRIPT_RELATE_DICT_NOT_EXIST);
}
result.add(map);
});
scriptDtlsList = scriptDtlsList.stream().filter(obj -> indexes.contains(obj.getScriptIndex())).collect(Collectors.toList());
}
Map<String, List<PqScriptDtls>> collect = scriptDtlsList.stream()
.sorted(Comparator.comparing(PqScriptDtls::getScriptIndex))
.collect(Collectors.groupingBy(PqScriptDtls::getScriptType, LinkedHashMap::new, Collectors.toList()));
collect.forEach((key, value) -> {
Map<String, String> map = new HashMap<>();
map.put("id", key);
DictTree dictTree = dictTreeService.getById(key);
if (ObjectUtil.isNotNull(dictTree)) {
map.put("code", dictTree.getCode());
map.put("scriptName", dictTree.getName());
} else {
throw new BusinessException(DetectionResponseEnum.SCRIPT_RELATE_DICT_NOT_EXIST);
}
result.add(map);
});
return result;
}

View File

@@ -16,6 +16,7 @@ public enum PowerIndexEnum {
FREQ("FREQ", "频率"),
V("V", "电压"),
I("I", "电流"),
P("P", "功率"),
IMBV("IMBV", "负序电压不平衡度"),
IMBA("IMBA", "负序电流不平衡度"),
F("F", "短时电压闪变"),

View File

@@ -1500,57 +1500,58 @@ public class ResultServiceImpl implements IResultService {
List<Map<String, Object>> sheetsList = new ArrayList<>();
// key为被检设备的ip, value为该ip下所有通道的设备数据
Map<String, List<DevData>> ipDevDataMap = FormalTestManager.devDataMap.values().stream().flatMap(List::stream).collect(Collectors.groupingBy(obj -> obj.getId().split(CnSocketUtil.SPLIT_TAG)[0]));
Map<String, List<DevData>> ipDevDataMap = FormalTestManager.standardDevDataMap.values().stream().flatMap(List::stream).collect(Collectors.groupingBy(obj -> obj.getId().split(CnSocketUtil.SPLIT_TAG)[0]));
ipDevDataMap.forEach((ip, devDataList) -> {
ipDevDataMap.forEach((ip, stdDevDataList) -> {
// 按照通道号分组。key为通道号value为该通道号下所有设备数据
Map<String, List<DevData>> channelDataMap = devDataList.stream().collect(Collectors.groupingBy(obj -> obj.getId().split(CnSocketUtil.SPLIT_TAG)[1]));
Map<String, List<DevData>> channelDataMap = stdDevDataList.stream().collect(Collectors.groupingBy(obj -> obj.getId().split(CnSocketUtil.SPLIT_TAG)[1]));
channelDataMap.forEach((channel, channelDevDataList) -> {
String standardDevMonitorId = FormalTestManager.pairsMap.get(ip + channel);
List<DevData> standarDevDataList = BeanUtil.copyToList(FormalTestManager.standardDevDataMap.get(standardDevMonitorId), DevData.class);
String standardDevMonitorId = ip + CnSocketUtil.SPLIT_TAG + channel;
String devMonitorId = FormalTestManager.pairsMap.inverse().get(standardDevMonitorId);
List<DevData> devDataList = BeanUtil.copyToList(FormalTestManager.devDataMap.get(standardDevMonitorId), DevData.class);
channelDevDataList.sort(Comparator.comparing(obj -> DetectionUtil.getMillis(obj.getTime())));
HashMap sheet = new HashMap<>();
ExportParams exportParams = new ExportParams();
String devName = FormalTestManager.devNameMapComm.get(ip);
String[] split = standardDevMonitorId.split(CnSocketUtil.SPLIT_TAG);
String standardDevName = FormalTestManager.devNameMapComm.get(split[0]);
String standardDevName = FormalTestManager.devNameMapComm.get(ip);
String[] split = devMonitorId.split(CnSocketUtil.SPLIT_TAG);
String devName = FormalTestManager.devNameMapComm.get(split[0]);
exportParams.setSheetName(devName + "通道" + channel);
sheet.put("title", exportParams);
List<AlignDataExcel> dataList = new ArrayList<>();
channelDevDataList.stream().forEach(obj -> {
AlignDataExcel alignDataExcel = new AlignDataExcel();
alignDataExcel.getDevDataConfig().setName(devName + "通道" + channel);
alignDataExcel.getStandardDevDataConfig().setName(standardDevName + "通道" + split[1]);
alignDataExcel.getDevDataConfig().setName(devName + "通道" + split[1]);
alignDataExcel.getStandardDevDataConfig().setName(standardDevName + "通道" + channel);
DevData.SqlDataDTO.ListDTO list1 = obj.getSqlData().get(0).getList();
alignDataExcel.setTimeDev(obj.getTime());
alignDataExcel.setUaDev(list1.getA());
alignDataExcel.setUbDev(list1.getB());
alignDataExcel.setUcDev(list1.getC());
alignDataExcel.setTimeStdDev(obj.getTime());
alignDataExcel.setUaStdDev(list1.getA());
alignDataExcel.setUbStdDev(list1.getB());
alignDataExcel.setUcStdDev(list1.getC());
DevData devData = standarDevDataList.stream().filter(obj1 -> DetectionUtil.isAlignData(obj1, obj)).findFirst().get();
DevData devData = devDataList.stream().filter(obj1 -> DetectionUtil.isAlignData(obj1, obj)).findFirst().get();
if (ObjectUtil.isNotNull(devData)) {
DevData.SqlDataDTO.ListDTO list2 = devData.getSqlData().get(0).getList();
alignDataExcel.setTimeStdDev(devData.getTime());
alignDataExcel.setUaStdDev(list2.getA());
alignDataExcel.setUbStdDev(list2.getB());
alignDataExcel.setUcStdDev(list2.getC());
standarDevDataList.remove(devData);
alignDataExcel.setTimeDev(devData.getTime());
alignDataExcel.setUaDev(list2.getA());
alignDataExcel.setUbDev(list2.getB());
alignDataExcel.setUcDev(list2.getC());
devDataList.remove(devData);
}
dataList.add(alignDataExcel);
});
standarDevDataList.sort(Comparator.comparing(obj -> DetectionUtil.getMillis(obj.getTime())));
standarDevDataList.stream().forEach(obj -> {
devDataList.sort(Comparator.comparing(obj -> DetectionUtil.getMillis(obj.getTime())));
devDataList.stream().forEach(obj -> {
AlignDataExcel alignDataExcel = new AlignDataExcel();
alignDataExcel.getDevDataConfig().setName(devName + "通道" + channel);
alignDataExcel.getStandardDevDataConfig().setName(standardDevName + "通道" + split[1]);
alignDataExcel.getDevDataConfig().setName(devName + "通道" + split[1]);
alignDataExcel.getStandardDevDataConfig().setName(standardDevName + "通道" + channel);
DevData.SqlDataDTO.ListDTO list2 = obj.getSqlData().get(0).getList();
alignDataExcel.setTimeStdDev(obj.getTime());
alignDataExcel.setUaStdDev(list2.getA());
alignDataExcel.setUbStdDev(list2.getB());
alignDataExcel.setUcStdDev(list2.getC());
alignDataExcel.setTimeDev(obj.getTime());
alignDataExcel.setUaDev(list2.getA());
alignDataExcel.setUbDev(list2.getB());
alignDataExcel.setUcDev(list2.getC());
dataList.add(alignDataExcel);
});