feat(event): 添加暂态事件波形查看与导出功能
- 新增 getTransientEventWave 接口用于查看暂态事件波形 - 新增 exportTransientEventWaves 接口用于批量导出暂态事件波形 - 添加 EventWaveExportParam 参数类支持波形导出 - 在 EventListMapper 中增加 selectTransientDetailsByIds 查询方法 - 更新事件列表查询参数支持毫秒级时间格式 - 移除事件描述模糊查询条件优化查询性能 - 添加波形导出相关的常量和工具类集成
This commit is contained in:
@@ -1,28 +0,0 @@
|
||||
package com.njcn.gather.tool.adddata.component;
|
||||
|
||||
import com.njcn.gather.tool.adddata.pojo.bo.AddDataTableDefinition;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 表定义注册测试。
|
||||
*/
|
||||
class AddDataTableRegistryTest {
|
||||
|
||||
@Test
|
||||
void shouldLoadAllThirteenTablesFromSchema() throws Exception {
|
||||
AddDataTableRegistry registry = new AddDataTableRegistry();
|
||||
registry.afterPropertiesSet();
|
||||
|
||||
List<AddDataTableDefinition> definitions = registry.getTableDefinitions();
|
||||
|
||||
Assertions.assertEquals(13, definitions.size());
|
||||
Assertions.assertEquals("data_flicker", definitions.get(0).getTableName());
|
||||
Assertions.assertEquals("data_v", definitions.get(definitions.size() - 1).getTableName());
|
||||
Assertions.assertTrue(registry.getDefinition("data_v").getColumns().contains("V_THD"));
|
||||
Assertions.assertEquals(4, registry.getDefinition("data_v").getPhaseCodes().size());
|
||||
Assertions.assertTrue(registry.getDefinition("data_v").getPhaseCodes().contains("T"));
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.njcn.gather.tool.adddata.component;
|
||||
|
||||
import com.njcn.gather.tool.adddata.pojo.bo.AddDataTaskCommand;
|
||||
import com.njcn.gather.tool.adddata.pojo.vo.AddDataTaskStatusVO;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 补数任务状态持有器测试。
|
||||
*/
|
||||
class AddDataTaskStatusHolderTest {
|
||||
|
||||
private final AddDataTaskStatusHolder holder = new AddDataTaskStatusHolder(new AddDataTimeSlotCalculator());
|
||||
|
||||
@Test
|
||||
void shouldReturnHourlyTimeResultsWhenCreateTask() {
|
||||
AddDataTaskCommand command = new AddDataTaskCommand(
|
||||
Arrays.asList("1"),
|
||||
LocalDateTime.of(2026, 4, 28, 10, 7, 0),
|
||||
LocalDateTime.of(2026, 4, 28, 13, 0, 0),
|
||||
5);
|
||||
|
||||
AddDataTaskStatusVO status = holder.createWaitingTask(command);
|
||||
|
||||
Assertions.assertEquals(Arrays.asList(
|
||||
"2026-04-28 11:00:00",
|
||||
"2026-04-28 12:00:00",
|
||||
"2026-04-28 13:00:00"), status.getHourlyTimeResults());
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.njcn.gather.tool.adddata.component;
|
||||
|
||||
import com.njcn.gather.tool.adddata.pojo.vo.AddDataTemplateVO;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 模板注册测试。
|
||||
*/
|
||||
class AddDataTemplateRegistryTest {
|
||||
|
||||
@Test
|
||||
void shouldOnlyExposeABCTPhaseCodes() {
|
||||
AddDataTemplateRegistry registry = new AddDataTemplateRegistry();
|
||||
|
||||
List<AddDataTemplateVO> templates = registry.getTemplates();
|
||||
Set<String> allowedPhaseCodes = new HashSet<String>();
|
||||
allowedPhaseCodes.add("A");
|
||||
allowedPhaseCodes.add("B");
|
||||
allowedPhaseCodes.add("C");
|
||||
allowedPhaseCodes.add("T");
|
||||
|
||||
for (AddDataTemplateVO template : templates) {
|
||||
for (String phaseCode : template.getPhaseCodes()) {
|
||||
Assertions.assertTrue(allowedPhaseCodes.contains(phaseCode));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package com.njcn.gather.tool.adddata.component;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 时间槽计算测试。
|
||||
*/
|
||||
class AddDataTimeSlotCalculatorTest {
|
||||
|
||||
private final AddDataTimeSlotCalculator calculator = new AddDataTimeSlotCalculator();
|
||||
|
||||
@Test
|
||||
void shouldAlignToNextNaturalSlot() {
|
||||
LocalDateTime start = LocalDateTime.of(2026, 4, 28, 10, 7, 12);
|
||||
LocalDateTime end = LocalDateTime.of(2026, 4, 28, 10, 22, 0);
|
||||
|
||||
List<LocalDateTime> slots = calculator.buildTimeSlots(start, end, 5);
|
||||
|
||||
Assertions.assertEquals(3, slots.size());
|
||||
Assertions.assertEquals(LocalDateTime.of(2026, 4, 28, 10, 10, 0), slots.get(0));
|
||||
Assertions.assertEquals(LocalDateTime.of(2026, 4, 28, 10, 20, 0), slots.get(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnEmptyWhenRangeDoesNotContainAnySlot() {
|
||||
LocalDateTime start = LocalDateTime.of(2026, 4, 28, 10, 7, 0);
|
||||
LocalDateTime end = LocalDateTime.of(2026, 4, 28, 10, 9, 59);
|
||||
|
||||
List<LocalDateTime> slots = calculator.buildTimeSlots(start, end, 10);
|
||||
|
||||
Assertions.assertTrue(slots.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBuildHourlySlotsFromNextNaturalHour() {
|
||||
LocalDateTime start = LocalDateTime.of(2026, 4, 28, 10, 7, 0);
|
||||
LocalDateTime end = LocalDateTime.of(2026, 4, 28, 13, 0, 0);
|
||||
|
||||
List<LocalDateTime> slots = calculator.buildHourlyTimeSlots(start, end);
|
||||
|
||||
Assertions.assertEquals(3, slots.size());
|
||||
Assertions.assertEquals(LocalDateTime.of(2026, 4, 28, 11, 0, 0), slots.get(0));
|
||||
Assertions.assertEquals(LocalDateTime.of(2026, 4, 28, 13, 0, 0), slots.get(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldIncludeStartWhenAlreadyAtNaturalHour() {
|
||||
LocalDateTime start = LocalDateTime.of(2026, 4, 28, 10, 0, 0);
|
||||
LocalDateTime end = LocalDateTime.of(2026, 4, 28, 12, 30, 0);
|
||||
|
||||
List<LocalDateTime> slots = calculator.buildHourlyTimeSlots(start, end);
|
||||
|
||||
Assertions.assertEquals(3, slots.size());
|
||||
Assertions.assertEquals(LocalDateTime.of(2026, 4, 28, 10, 0, 0), slots.get(0));
|
||||
Assertions.assertEquals(LocalDateTime.of(2026, 4, 28, 12, 0, 0), slots.get(2));
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.njcn.gather.tool.adddata.component;
|
||||
|
||||
import com.njcn.gather.tool.adddata.pojo.bo.AddDataTableDefinition;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数值生成器测试。
|
||||
*/
|
||||
class AddDataValueGeneratorTest {
|
||||
|
||||
@Test
|
||||
void shouldGenerateStableDataVRowWithExpectedColumnCount() throws Exception {
|
||||
AddDataTableRegistry registry = new AddDataTableRegistry();
|
||||
registry.afterPropertiesSet();
|
||||
AddDataTableDefinition definition = registry.getDefinition("data_v");
|
||||
AddDataValueGenerator generator = new AddDataValueGenerator();
|
||||
|
||||
List<Object> row = generator.generateRow(definition, "f04a9d62e3d24e6580e4f32b40967505", LocalDateTime.of(2026, 4, 28, 10, 10, 0), "A");
|
||||
|
||||
Assertions.assertEquals(definition.getColumns().size(), row.size());
|
||||
Assertions.assertEquals("A", row.get(definition.getColumns().indexOf("PHASIC_TYPE")));
|
||||
Double rms = (Double) row.get(definition.getColumns().indexOf("RMS"));
|
||||
Double rmsMax = (Double) row.get(definition.getColumns().indexOf("RMS_MAX"));
|
||||
Double rmsMin = (Double) row.get(definition.getColumns().indexOf("RMS_MIN"));
|
||||
Assertions.assertTrue(rmsMax >= rms);
|
||||
Assertions.assertTrue(rmsMin <= rms);
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@
|
||||
project.name AS projectName,
|
||||
equipment.id AS equipmentId,
|
||||
equipment.name AS equipmentName,
|
||||
equipment.mac AS equipmentMac,
|
||||
line.line_id AS lineId,
|
||||
line.name AS lineName
|
||||
FROM cs_line line
|
||||
@@ -55,6 +56,7 @@
|
||||
project.name AS projectName,
|
||||
equipment.id AS equipmentId,
|
||||
equipment.name AS equipmentName,
|
||||
equipment.mac AS equipmentMac,
|
||||
line.line_id AS lineId,
|
||||
line.name AS lineName
|
||||
FROM cs_line line
|
||||
|
||||
@@ -24,6 +24,8 @@ public class AddLedgerLinePathVO implements Serializable {
|
||||
|
||||
private String equipmentName;
|
||||
|
||||
private String equipmentMac;
|
||||
|
||||
private String lineId;
|
||||
|
||||
private String lineName;
|
||||
|
||||
@@ -1,224 +0,0 @@
|
||||
/*
|
||||
Navicat/MySQL 初始化脚本
|
||||
|
||||
用途:
|
||||
1. 初始化 add-ledger 台账设备相关字典。
|
||||
2. 脚本可重复执行,按字典编码避免重复插入。
|
||||
|
||||
说明:
|
||||
- dev_type 对应 cs_equipment_delivery.dev_type,保存 sys_dict_data.id。
|
||||
- dev_model 对应 cs_equipment_delivery.dev_model,保存 sys_dict_data.id。
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
-- ----------------------------
|
||||
-- 字典类型:装置类型
|
||||
-- ----------------------------
|
||||
SET @ledger_device_type_type_id := (
|
||||
SELECT `id`
|
||||
FROM `sys_dict_type`
|
||||
WHERE `code` = 'ledger_device_type'
|
||||
AND `state` = 1
|
||||
LIMIT 1
|
||||
);
|
||||
|
||||
INSERT INTO `sys_dict_type` (
|
||||
`id`, `name`, `code`, `sort`, `open_level`, `open_describe`, `remark`, `state`,
|
||||
`create_by`, `create_time`, `update_by`, `update_time`
|
||||
)
|
||||
SELECT
|
||||
'7f91c2a1e9f44b47a6e7c8b227d00101',
|
||||
'装置类型',
|
||||
'ledger_device_type',
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
'数据台账设备装置类型',
|
||||
1,
|
||||
'system',
|
||||
NOW(),
|
||||
'system',
|
||||
NOW()
|
||||
WHERE @ledger_device_type_type_id IS NULL;
|
||||
|
||||
SET @ledger_device_type_type_id := (
|
||||
SELECT `id`
|
||||
FROM `sys_dict_type`
|
||||
WHERE `code` = 'ledger_device_type'
|
||||
AND `state` = 1
|
||||
LIMIT 1
|
||||
);
|
||||
|
||||
INSERT INTO `sys_dict_data` (
|
||||
`id`, `type_id`, `name`, `code`, `sort`, `level`, `algo_describe`, `value`, `open_value`, `state`,
|
||||
`create_by`, `create_time`, `update_by`, `update_time`
|
||||
)
|
||||
SELECT
|
||||
'7f91c2a1e9f44b47a6e7c8b227d10101',
|
||||
@ledger_device_type_type_id,
|
||||
'直连设备',
|
||||
'direct_device',
|
||||
1,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
1,
|
||||
'system',
|
||||
NOW(),
|
||||
'system',
|
||||
NOW()
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM `sys_dict_data`
|
||||
WHERE `type_id` = @ledger_device_type_type_id
|
||||
AND `code` = 'direct_device'
|
||||
AND `state` = 1
|
||||
);
|
||||
|
||||
INSERT INTO `sys_dict_data` (
|
||||
`id`, `type_id`, `name`, `code`, `sort`, `level`, `algo_describe`, `value`, `open_value`, `state`,
|
||||
`create_by`, `create_time`, `update_by`, `update_time`
|
||||
)
|
||||
SELECT
|
||||
'7f91c2a1e9f44b47a6e7c8b227d10102',
|
||||
@ledger_device_type_type_id,
|
||||
'网关',
|
||||
'gateway',
|
||||
2,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
1,
|
||||
'system',
|
||||
NOW(),
|
||||
'system',
|
||||
NOW()
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM `sys_dict_data`
|
||||
WHERE `type_id` = @ledger_device_type_type_id
|
||||
AND `code` = 'gateway'
|
||||
AND `state` = 1
|
||||
);
|
||||
|
||||
INSERT INTO `sys_dict_data` (
|
||||
`id`, `type_id`, `name`, `code`, `sort`, `level`, `algo_describe`, `value`, `open_value`, `state`,
|
||||
`create_by`, `create_time`, `update_by`, `update_time`
|
||||
)
|
||||
SELECT
|
||||
'7f91c2a1e9f44b47a6e7c8b227d10103',
|
||||
@ledger_device_type_type_id,
|
||||
'装置',
|
||||
'device',
|
||||
3,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
1,
|
||||
'system',
|
||||
NOW(),
|
||||
'system',
|
||||
NOW()
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM `sys_dict_data`
|
||||
WHERE `type_id` = @ledger_device_type_type_id
|
||||
AND `code` = 'device'
|
||||
AND `state` = 1
|
||||
);
|
||||
|
||||
-- ----------------------------
|
||||
-- 字典类型:装置型号
|
||||
-- ----------------------------
|
||||
SET @ledger_device_model_type_id := (
|
||||
SELECT `id`
|
||||
FROM `sys_dict_type`
|
||||
WHERE `code` = 'ledger_device_model'
|
||||
AND `state` = 1
|
||||
LIMIT 1
|
||||
);
|
||||
|
||||
INSERT INTO `sys_dict_type` (
|
||||
`id`, `name`, `code`, `sort`, `open_level`, `open_describe`, `remark`, `state`,
|
||||
`create_by`, `create_time`, `update_by`, `update_time`
|
||||
)
|
||||
SELECT
|
||||
'7f91c2a1e9f44b47a6e7c8b227d00201',
|
||||
'装置型号',
|
||||
'ledger_device_model',
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
'数据台账设备装置型号',
|
||||
1,
|
||||
'system',
|
||||
NOW(),
|
||||
'system',
|
||||
NOW()
|
||||
WHERE @ledger_device_model_type_id IS NULL;
|
||||
|
||||
SET @ledger_device_model_type_id := (
|
||||
SELECT `id`
|
||||
FROM `sys_dict_type`
|
||||
WHERE `code` = 'ledger_device_model'
|
||||
AND `state` = 1
|
||||
LIMIT 1
|
||||
);
|
||||
|
||||
INSERT INTO `sys_dict_data` (
|
||||
`id`, `type_id`, `name`, `code`, `sort`, `level`, `algo_describe`, `value`, `open_value`, `state`,
|
||||
`create_by`, `create_time`, `update_by`, `update_time`
|
||||
)
|
||||
SELECT
|
||||
'7f91c2a1e9f44b47a6e7c8b227d20101',
|
||||
@ledger_device_model_type_id,
|
||||
'PQS588',
|
||||
'pqs588',
|
||||
1,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
1,
|
||||
'system',
|
||||
NOW(),
|
||||
'system',
|
||||
NOW()
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM `sys_dict_data`
|
||||
WHERE `type_id` = @ledger_device_model_type_id
|
||||
AND `code` = 'pqs588'
|
||||
AND `state` = 1
|
||||
);
|
||||
|
||||
INSERT INTO `sys_dict_data` (
|
||||
`id`, `type_id`, `name`, `code`, `sort`, `level`, `algo_describe`, `value`, `open_value`, `state`,
|
||||
`create_by`, `create_time`, `update_by`, `update_time`
|
||||
)
|
||||
SELECT
|
||||
'7f91c2a1e9f44b47a6e7c8b227d20102',
|
||||
@ledger_device_model_type_id,
|
||||
'PQS680',
|
||||
'pqs680',
|
||||
2,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
1,
|
||||
'system',
|
||||
NOW(),
|
||||
'system',
|
||||
NOW()
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM `sys_dict_data`
|
||||
WHERE `type_id` = @ledger_device_model_type_id
|
||||
AND `code` = 'pqs680'
|
||||
AND `state` = 1
|
||||
);
|
||||
@@ -1,43 +0,0 @@
|
||||
package com.njcn.gather.tool.addledger.component;
|
||||
|
||||
import com.njcn.gather.tool.addledger.pojo.po.AddLedgerLedgerPO;
|
||||
import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerTreeNodeVO;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 台账树组装测试。
|
||||
*/
|
||||
class AddLedgerTreeBuilderTest {
|
||||
|
||||
private final AddLedgerTreeBuilder treeBuilder = new AddLedgerTreeBuilder();
|
||||
|
||||
@Test
|
||||
void shouldBuildFourLevelTreeFromFlatLedgerNodes() {
|
||||
AddLedgerLedgerPO engineering = buildLedger("engineering-1", "0", 0, "工程");
|
||||
AddLedgerLedgerPO project = buildLedger("project-1", "engineering-1", 1, "项目");
|
||||
AddLedgerLedgerPO equipment = buildLedger("equipment-1", "project-1", 2, "设备");
|
||||
AddLedgerLedgerPO line = buildLedger("line-1", "equipment-1", 3, "测点");
|
||||
|
||||
List<AddLedgerTreeNodeVO> result = treeBuilder.buildTree(Arrays.asList(line, equipment, project, engineering));
|
||||
|
||||
Assertions.assertEquals(1, result.size());
|
||||
Assertions.assertEquals("engineering-1", result.get(0).getId());
|
||||
Assertions.assertEquals("project-1", result.get(0).getChildren().get(0).getId());
|
||||
Assertions.assertEquals("equipment-1", result.get(0).getChildren().get(0).getChildren().get(0).getId());
|
||||
Assertions.assertEquals("line-1", result.get(0).getChildren().get(0).getChildren().get(0).getChildren().get(0).getId());
|
||||
}
|
||||
|
||||
private AddLedgerLedgerPO buildLedger(String id, String parentId, Integer level, String name) {
|
||||
AddLedgerLedgerPO ledger = new AddLedgerLedgerPO();
|
||||
ledger.setId(id);
|
||||
ledger.setPid(parentId);
|
||||
ledger.setLevel(level);
|
||||
ledger.setName(name);
|
||||
ledger.setSort(0);
|
||||
return ledger;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.njcn.gather.tool.addledger.util;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 台账测点线路号工具测试。
|
||||
*/
|
||||
class AddLedgerLineNoUtilTest {
|
||||
|
||||
@Test
|
||||
void shouldReturnOnlyUnusedLineNosWhenCreateLine() {
|
||||
List<Integer> result = AddLedgerLineNoUtil.resolveAvailableLineNos(Arrays.asList(1, 2, 20), null);
|
||||
|
||||
Assertions.assertEquals(17, result.size());
|
||||
Assertions.assertFalse(result.contains(1));
|
||||
Assertions.assertFalse(result.contains(2));
|
||||
Assertions.assertFalse(result.contains(20));
|
||||
Assertions.assertTrue(result.contains(3));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldKeepCurrentLineNoAvailableWhenEditLine() {
|
||||
List<Integer> result = AddLedgerLineNoUtil.resolveAvailableLineNos(Arrays.asList(1, 2, 20), 2);
|
||||
|
||||
Assertions.assertTrue(result.contains(2));
|
||||
Assertions.assertFalse(result.contains(1));
|
||||
Assertions.assertFalse(result.contains(20));
|
||||
}
|
||||
}
|
||||
@@ -196,7 +196,7 @@ curl.exe -X POST "http://localhost:8080/api/mms-mapping/get-icd-mms-json" `
|
||||
说明:
|
||||
|
||||
- `mappingJson` 是字符串字段,字段值本身也是一段 JSON 文本。
|
||||
- 当 `saveToDisk=true` 时,响应中还会返回 `savedPath`。
|
||||
- 当 `saveToDisk=true` 时,响应中还会返回 `savedPath`,落盘文件名按统一规则追加 `_yyyyMMdd`。
|
||||
|
||||
### 5.3 FAILED
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.njcn.gather.icd.mapping.component;
|
||||
|
||||
import com.njcn.gather.icd.mapping.utils.GeneratedFileNameUtil;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
@@ -26,7 +27,7 @@ public class FileStorageService {
|
||||
if (!dir.isDirectory()) {
|
||||
throw new IllegalStateException("输出路径不是目录:" + dir.getAbsolutePath());
|
||||
}
|
||||
File target = new File(dir, fileName);
|
||||
File target = new File(dir, GeneratedFileNameUtil.appendToday(fileName));
|
||||
try (FileOutputStream fos = new FileOutputStream(target)) {
|
||||
fos.write(content.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.njcn.gather.icd.mapping.pojo.vo.IndexCandidateReportItemResponse;
|
||||
import com.njcn.gather.icd.mapping.pojo.vo.IndexCandidateResponse;
|
||||
import com.njcn.gather.icd.mapping.pojo.vo.MappingDocumentResponse;
|
||||
import com.njcn.gather.icd.mapping.pojo.vo.XmlFileResponse;
|
||||
import com.njcn.gather.icd.mapping.utils.GeneratedFileNameUtil;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@@ -90,13 +91,13 @@ public class IcdToXmlResponseConverter {
|
||||
private String resolveXmlFileName(IcdToXmlGenerateResult result) {
|
||||
String iedName = result.getIedName();
|
||||
if (iedName == null || iedName.trim().isEmpty()) {
|
||||
return DEFAULT_XML_FILE_NAME;
|
||||
return GeneratedFileNameUtil.appendToday(DEFAULT_XML_FILE_NAME);
|
||||
}
|
||||
|
||||
String safeName = iedName.replaceAll("[\\\\/:*?\"<>|]+", "_").trim();
|
||||
if (safeName.isEmpty()) {
|
||||
return DEFAULT_XML_FILE_NAME;
|
||||
return GeneratedFileNameUtil.appendToday(DEFAULT_XML_FILE_NAME);
|
||||
}
|
||||
return safeName + ".xml";
|
||||
return GeneratedFileNameUtil.appendToday(safeName + ".xml");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.njcn.gather.icd.mapping.pojo.param.*;
|
||||
import com.njcn.gather.icd.mapping.pojo.vo.*;
|
||||
import com.njcn.gather.icd.mapping.pojo.enums.GenerateStatus;
|
||||
import com.njcn.gather.icd.mapping.pojo.bo.mapping.MappingDocument;
|
||||
import com.njcn.gather.icd.mapping.utils.GeneratedFileNameUtil;
|
||||
import lombok.var;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -17,6 +18,8 @@ import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -57,8 +60,9 @@ public class JsonToXmlConversionService {
|
||||
String xmlContent = buildXmlContentFromJson(mappingJson, templateStream, ruleStreams, indexMapping);
|
||||
|
||||
// 3. 保存为临时文件
|
||||
Path tempPath = Files.createTempFile("converted_", ".xml");
|
||||
Files.write(tempPath, xmlContent.getBytes(StandardCharsets.UTF_8));
|
||||
Path tempPath = Paths.get(System.getProperty("java.io.tmpdir"),
|
||||
GeneratedFileNameUtil.appendToday("converted_" + java.util.UUID.randomUUID().toString().replace("-", "") + ".xml"));
|
||||
Files.write(tempPath, xmlContent.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE_NEW);
|
||||
|
||||
return tempPath.toString();
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -20,6 +22,7 @@ import com.njcn.gather.icd.mapping.pojo.bo.*;
|
||||
import com.njcn.gather.icd.mapping.pojo.param.*;
|
||||
import com.njcn.gather.icd.mapping.pojo.vo.*;
|
||||
import com.njcn.gather.icd.mapping.pojo.enums.GenerateStatus;
|
||||
import com.njcn.gather.icd.mapping.utils.GeneratedFileNameUtil;
|
||||
@Component
|
||||
public class RuleBasedXmlMappingService {
|
||||
|
||||
@@ -104,8 +107,9 @@ public class RuleBasedXmlMappingService {
|
||||
|
||||
xmlContent = applyRulesToXml(xmlContent, applicableRules);
|
||||
|
||||
Path tempPath = Files.createTempFile("rule_mapped_", ".xml");
|
||||
Files.write(tempPath, xmlContent.getBytes(StandardCharsets.UTF_8));
|
||||
Path tempPath = Paths.get(System.getProperty("java.io.tmpdir"),
|
||||
GeneratedFileNameUtil.appendToday("rule_mapped_" + UUID.randomUUID().toString().replace("-", "") + ".xml"));
|
||||
Files.write(tempPath, xmlContent.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE_NEW);
|
||||
return tempPath.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.njcn.gather.icd.mapping.utils;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* 生成文件名处理工具。
|
||||
*/
|
||||
public final class GeneratedFileNameUtil {
|
||||
|
||||
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
|
||||
|
||||
private GeneratedFileNameUtil() {
|
||||
}
|
||||
|
||||
public static String appendToday(String fileName) {
|
||||
return appendDate(fileName, LocalDate.now());
|
||||
}
|
||||
|
||||
public static String appendDate(String fileName, LocalDate date) {
|
||||
if (fileName == null || date == null) {
|
||||
return fileName;
|
||||
}
|
||||
String dateText = DATE_FORMATTER.format(date);
|
||||
int separatorIndex = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\\'));
|
||||
int dotIndex = fileName.lastIndexOf('.');
|
||||
if (dotIndex > separatorIndex) {
|
||||
return fileName.substring(0, dotIndex) + "_" + dateText + fileName.substring(dotIndex);
|
||||
}
|
||||
return fileName + "_" + dateText;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,232 +0,0 @@
|
||||
package com.njcn.gather.icd.mapping.debug;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.njcn.gather.icd.mapping.component.MappingResponseConverter;
|
||||
import com.njcn.gather.icd.mapping.pojo.dto.GenerateFromIcdCommand;
|
||||
import com.njcn.gather.icd.mapping.pojo.dto.IndexBindingCommand;
|
||||
import com.njcn.gather.icd.mapping.pojo.dto.IndexSelectionGroupCommand;
|
||||
import com.njcn.gather.icd.mapping.pojo.vo.IndexCandidateReportItemResponse;
|
||||
import com.njcn.gather.icd.mapping.pojo.vo.IndexCandidateResponse;
|
||||
import com.njcn.gather.icd.mapping.pojo.vo.MappingTaskResponse;
|
||||
import com.njcn.gather.icd.mapping.service.MappingTaskService;
|
||||
import org.springframework.boot.Banner;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* `getIcdMmsJson` 本地调试入口。
|
||||
*
|
||||
* 使用方式:
|
||||
* 1. 先修改 ICD_FILE_PATH 指向本地真实 ICD/SCD 文件。
|
||||
* 2. 直接运行 main,先观察第一次调试返回的 indexCandidates。
|
||||
* 3. 按第一次返回结果补齐 buildSecondStepSelection() 中的绑定关系。
|
||||
* 4. 把 RUN_SECOND_STEP 改成 true,再次运行 main 获取最终 mappingJson。
|
||||
*/
|
||||
public class GetIcdMmsJsonDebugRunner {
|
||||
|
||||
/** 本地 ICD/SCD 文件路径,运行前请改成真实文件。 */
|
||||
private static final String ICD_FILE_PATH = "D:\\Work\\工作资料\\1灿能项目资料\\01自研\\01灿能\\09灿能C端功能\\01需求文档\\灿能工具箱开发\\icd\\PQS882_VX_BJ_1(V111).icd";
|
||||
|
||||
/** 调试时可固定版本号,便于对比输出。 */
|
||||
private static final String VERSION = "20260421";
|
||||
|
||||
/** 调试作者标识。 */
|
||||
private static final String AUTHOR = "debug-user";
|
||||
|
||||
/** 是否输出格式化 JSON,便于人工查看。 */
|
||||
private static final boolean PRETTY_JSON = true;
|
||||
|
||||
/** 是否把生成结果写入磁盘。 */
|
||||
private static final boolean SAVE_TO_DISK = false;
|
||||
|
||||
/** saveToDisk=true 时使用的输出目录。 */
|
||||
private static final String OUTPUT_DIR = "D:/temp/mms-output";
|
||||
|
||||
/**
|
||||
* 第二次正式生成开关。
|
||||
* 默认先只跑第一次,确认 groupKey/reportName/dataSetName/lnInst 候选值后再打开。
|
||||
*/
|
||||
private static final boolean RUN_SECOND_STEP = false;
|
||||
|
||||
public static void main(String[] args) {
|
||||
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(DebugApplication.class)
|
||||
.web(WebApplicationType.NONE)
|
||||
.bannerMode(Banner.Mode.OFF)
|
||||
.logStartupInfo(false)
|
||||
.run(args)) {
|
||||
MappingTaskService mappingTaskService = context.getBean(MappingTaskService.class);
|
||||
MappingResponseConverter responseConverter = context.getBean(MappingResponseConverter.class);
|
||||
ObjectMapper objectMapper = createObjectMapper();
|
||||
|
||||
MappingTaskResponse firstResponse = debugNeedIndexSelection(mappingTaskService, responseConverter);
|
||||
printResponse("第一次调试:获取索引候选", firstResponse, objectMapper);
|
||||
printIndexCandidatesJson(firstResponse, objectMapper);
|
||||
printIndexCandidateSummary(firstResponse);
|
||||
|
||||
if (!RUN_SECOND_STEP) {
|
||||
System.out.println("第二次调试未开启。请先根据第一次返回结果补齐 buildSecondStepSelection(),再把 RUN_SECOND_STEP 改成 true。");
|
||||
return;
|
||||
}
|
||||
|
||||
MappingTaskResponse secondResponse = debugGenerateMapping(mappingTaskService, responseConverter);
|
||||
printResponse("第二次调试:生成 MMS JSON", secondResponse, objectMapper);
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException("getIcdMmsJson 调试失败:" + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 第一次调试:不传 indexSelection,只获取 icdDocument 和 indexCandidates。
|
||||
*/
|
||||
private static MappingTaskResponse debugNeedIndexSelection(MappingTaskService mappingTaskService,
|
||||
MappingResponseConverter responseConverter) {
|
||||
GenerateFromIcdCommand command = buildBaseCommand();
|
||||
return responseConverter.fromSubmitResult(mappingTaskService.getIcdMmsJson(command));
|
||||
}
|
||||
|
||||
/**
|
||||
* 第二次调试:补齐 indexSelection 后直接生成最终 mappingJson。
|
||||
*/
|
||||
private static MappingTaskResponse debugGenerateMapping(MappingTaskService mappingTaskService,
|
||||
MappingResponseConverter responseConverter) {
|
||||
List<IndexSelectionGroupCommand> selectionGroups = buildSecondStepSelection();
|
||||
if (selectionGroups.isEmpty()) {
|
||||
throw new IllegalArgumentException("第二次调试缺少 indexSelection,请先补齐 buildSecondStepSelection()");
|
||||
}
|
||||
|
||||
GenerateFromIcdCommand command = buildBaseCommand();
|
||||
command.getIndexSelection().addAll(selectionGroups);
|
||||
return responseConverter.fromSubmitResult(mappingTaskService.getIcdMmsJson(command));
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装调试用基础命令,等价于接口中的 request 基础参数。
|
||||
*/
|
||||
private static GenerateFromIcdCommand buildBaseCommand() {
|
||||
Path icdPath = Paths.get(ICD_FILE_PATH);
|
||||
if (!Files.exists(icdPath)) {
|
||||
throw new IllegalArgumentException("ICD 文件不存在:" + icdPath.toAbsolutePath());
|
||||
}
|
||||
|
||||
try {
|
||||
GenerateFromIcdCommand command = new GenerateFromIcdCommand();
|
||||
command.setFileName(icdPath.getFileName().toString());
|
||||
command.setFileBytes(Files.readAllBytes(icdPath));
|
||||
command.setVersion(VERSION);
|
||||
command.setAuthor(AUTHOR);
|
||||
command.setPrettyJson(PRETTY_JSON);
|
||||
command.setSaveToDisk(SAVE_TO_DISK);
|
||||
command.setOutputDir(OUTPUT_DIR);
|
||||
return command;
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalArgumentException("读取 ICD 文件失败:" + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 第二次调试的索引绑定示例。
|
||||
*
|
||||
* 注意:
|
||||
* 1. groupKey/groupDesc/reportName/dataSetName/lnInst 必须使用第一次返回的真实值。
|
||||
* 2. 下面示例仅作占位,默认不参与运行。
|
||||
*/
|
||||
private static List<IndexSelectionGroupCommand> buildSecondStepSelection() {
|
||||
List<IndexSelectionGroupCommand> groups = new ArrayList<IndexSelectionGroupCommand>();
|
||||
|
||||
// 示例:
|
||||
// IndexSelectionGroupCommand group = createSelectionGroup("HARM__DSSTHARM", "谐波数据");
|
||||
// group.getBindings().add(createBinding("brcbStHarm", "dsStHarm", "A相", "1"));
|
||||
// group.getBindings().add(createBinding("brcbStHarm", "dsStHarm", "B相", "2"));
|
||||
// group.getBindings().add(createBinding("brcbStHarm", "dsStHarm", "C相", "3"));
|
||||
// groups.add(group);
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
private static IndexSelectionGroupCommand createSelectionGroup(String groupKey, String groupDesc) {
|
||||
IndexSelectionGroupCommand group = new IndexSelectionGroupCommand();
|
||||
group.setGroupKey(groupKey);
|
||||
group.setGroupDesc(groupDesc);
|
||||
return group;
|
||||
}
|
||||
|
||||
private static IndexBindingCommand createBinding(String reportName,
|
||||
String dataSetName,
|
||||
String label,
|
||||
String lnInst) {
|
||||
IndexBindingCommand binding = new IndexBindingCommand();
|
||||
binding.setReportName(reportName);
|
||||
binding.setDataSetName(dataSetName);
|
||||
binding.setLabel(label);
|
||||
binding.setLnInst(lnInst);
|
||||
return binding;
|
||||
}
|
||||
|
||||
/**
|
||||
* 控制台输出候选摘要,方便把第一次返回值填回第二次调试配置。
|
||||
*/
|
||||
private static void printIndexCandidateSummary(MappingTaskResponse response) {
|
||||
if (response == null || response.getIndexCandidates() == null || response.getIndexCandidates().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("===== 索引候选摘要 =====");
|
||||
for (IndexCandidateResponse candidate : response.getIndexCandidates()) {
|
||||
System.out.println("groupKey=" + candidate.getGroupKey() + ", groupDesc=" + candidate.getGroupDesc());
|
||||
if (candidate.getReports() == null) {
|
||||
continue;
|
||||
}
|
||||
for (IndexCandidateReportItemResponse report : candidate.getReports()) {
|
||||
System.out.println(" reportName=" + report.getReportName()
|
||||
+ ", dataSetName=" + report.getDataSetName()
|
||||
+ ", availableLnInstValues=" + report.getAvailableLnInstValues());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 单独输出 indexCandidates 的 JSON,便于直接复制做第二次调试绑定。
|
||||
*/
|
||||
private static void printIndexCandidatesJson(MappingTaskResponse response, ObjectMapper objectMapper) {
|
||||
try {
|
||||
System.out.println();
|
||||
System.out.println("===== indexCandidates JSON =====");
|
||||
if (response == null) {
|
||||
System.out.println("null");
|
||||
return;
|
||||
}
|
||||
System.out.println(objectMapper.writeValueAsString(response.getIndexCandidates()));
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalArgumentException("print indexCandidates JSON failed: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void printResponse(String title, MappingTaskResponse response, ObjectMapper objectMapper) {
|
||||
try {
|
||||
System.out.println();
|
||||
System.out.println("===== " + title + " =====");
|
||||
System.out.println(objectMapper.writeValueAsString(response));
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalArgumentException("打印调试响应失败:" + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static ObjectMapper createObjectMapper() {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
return objectMapper;
|
||||
}
|
||||
|
||||
@SpringBootApplication(scanBasePackages = "com.njcn.gather.icd.mapping")
|
||||
public static class DebugApplication {
|
||||
}
|
||||
}
|
||||
@@ -1,265 +0,0 @@
|
||||
package com.njcn.gather.tool.wave.component;
|
||||
|
||||
import com.njcn.gather.tool.wave.pojo.dto.EigenvalueDTO;
|
||||
import com.njcn.gather.tool.wave.pojo.dto.WaveCycleVectorDTO;
|
||||
import com.njcn.gather.tool.wave.pojo.dto.WaveHarmonicDTO;
|
||||
import com.njcn.gather.tool.wave.pojo.dto.WavePhaseVectorDTO;
|
||||
import com.njcn.gather.tool.wave.pojo.dto.WaveVectorGroupDTO;
|
||||
import com.njcn.gather.tool.wave.pojo.dto.WaveDataDTO;
|
||||
import com.njcn.gather.tool.wave.pojo.param.WaveComtradeParseParam;
|
||||
import com.njcn.gather.tool.wave.pojo.vo.WaveComtradeVectorResultVO;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 本地调试 getComtrade 的命令行入口。
|
||||
*/
|
||||
public final class WaveFileComponentTestMain {
|
||||
|
||||
/** 默认测试 CFG 文件路径。 */
|
||||
private static final String DEFAULT_CFG_PATH = "D:\\00-B7-8D-00-E4-09\\PQMonitor_PQM2_006970_20260320_175033_734.CFG";
|
||||
/** 默认测试 DAT 文件路径。 */
|
||||
private static final String DEFAULT_DAT_PATH = "D:\\00-B7-8D-00-E4-09\\PQMonitor_PQM2_006970_20260320_175033_734.DAT";
|
||||
/** 默认解析类型,1 表示普通展示。 */
|
||||
private static final int DEFAULT_PARSE_TYPE = 1;
|
||||
/** 向量调试固定使用原始波形。 */
|
||||
private static final int VECTOR_PARSE_TYPE = 3;
|
||||
/** 默认使用浮动门槛计算特征值。 */
|
||||
private static final boolean DEFAULT_DYNAMIC_THRESHOLD = true;
|
||||
|
||||
private WaveFileComponentTestMain() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 用法:
|
||||
* java com.njcn.gather.tool.wave.component.WaveFileComponentTestMain <cfgPath> <datPath> [parseType]
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length < 2) {
|
||||
System.out.println("未传入参数,使用默认测试文件路径");
|
||||
System.out.println("cfgPath: " + DEFAULT_CFG_PATH);
|
||||
System.out.println("datPath: " + DEFAULT_DAT_PATH);
|
||||
}
|
||||
|
||||
Path cfgPath = Paths.get(args.length > 0 ? args[0] : DEFAULT_CFG_PATH);
|
||||
Path datPath = Paths.get(args.length > 1 ? args[1] : DEFAULT_DAT_PATH);
|
||||
int parseType = args.length > 2 ? Integer.parseInt(args[2]) : DEFAULT_PARSE_TYPE;
|
||||
|
||||
WaveFileComponent waveFileComponent = new WaveFileComponent();
|
||||
try (InputStream cfgStream = Files.newInputStream(cfgPath);
|
||||
InputStream datStream = Files.newInputStream(datPath)) {
|
||||
WaveDataDTO waveDataDTO = waveFileComponent.getComtrade(cfgStream, datStream, parseType);
|
||||
printComtradeResult(waveDataDTO);
|
||||
|
||||
WaveDataDTO validWaveDataDTO = waveFileComponent.getValidData(waveDataDTO);
|
||||
printValidDataResult(validWaveDataDTO);
|
||||
|
||||
List<EigenvalueDTO> eigenvalues = waveFileComponent.getEigenvalue(validWaveDataDTO, DEFAULT_DYNAMIC_THRESHOLD);
|
||||
printEigenvalueResult(eigenvalues);
|
||||
}
|
||||
|
||||
runParseComtradeVectorTest(cfgPath, datPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调试 parseComtradeVector 逻辑。
|
||||
*/
|
||||
private static void runParseComtradeVectorTest(Path cfgPath, Path datPath) throws Exception {
|
||||
System.out.println("=== parseComtradeVector 结果 ===");
|
||||
WaveFileComponent waveFileComponent = new WaveFileComponent();
|
||||
WaveVectorComponent waveVectorComponent = new WaveVectorComponent();
|
||||
WaveComtradeParseParam param = new WaveComtradeParseParam();
|
||||
param.setParseType(VECTOR_PARSE_TYPE);
|
||||
param.setPtType(0);
|
||||
param.setPt(1D);
|
||||
param.setCt(1D);
|
||||
param.setMonitorName("main方法调试测点");
|
||||
|
||||
try (InputStream cfgStream = Files.newInputStream(cfgPath);
|
||||
InputStream datStream = Files.newInputStream(datPath)) {
|
||||
WaveDataDTO waveDataDTO = waveFileComponent.getComtrade(cfgStream, datStream, VECTOR_PARSE_TYPE);
|
||||
applyWaveMetadata(waveDataDTO, param);
|
||||
|
||||
List<WaveVectorGroupDTO> vectorGroups = waveVectorComponent.calculateVectors(waveDataDTO);
|
||||
WaveComtradeVectorResultVO result = new WaveComtradeVectorResultVO();
|
||||
result.setMonitorName(waveDataDTO.getMonitorName());
|
||||
result.setTime(waveDataDTO.getTime());
|
||||
result.setSamplePerCycle(waveDataDTO.getComtradeCfgDTO() == null ? null : waveDataDTO.getComtradeCfgDTO().getFinalSampleRate());
|
||||
result.setCycleCount(resolveCycleCount(vectorGroups));
|
||||
result.setVectorGroups(vectorGroups);
|
||||
printParseComtradeVectorResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 给向量调试结果补齐 PT/CT/测点信息。
|
||||
*/
|
||||
private static void applyWaveMetadata(WaveDataDTO waveDataDTO, WaveComtradeParseParam param) {
|
||||
waveDataDTO.setPt(param.getPt() == null || param.getPt() <= 0 ? 1D : param.getPt());
|
||||
waveDataDTO.setCt(param.getCt() == null || param.getCt() <= 0 ? 1D : param.getCt());
|
||||
waveDataDTO.setPtType(param.getPtType() == null ? 0 : param.getPtType());
|
||||
waveDataDTO.setMonitorName(param.getMonitorName() == null || param.getMonitorName().trim().isEmpty()
|
||||
? "未命名测点"
|
||||
: param.getMonitorName().trim());
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印 parseComtradeVector 的关键摘要。
|
||||
*/
|
||||
private static void printParseComtradeVectorResult(WaveComtradeVectorResultVO result) {
|
||||
System.out.println("测点名称: " + result.getMonitorName());
|
||||
System.out.println("事件时间: " + result.getTime());
|
||||
System.out.println("每周波采样点数: " + result.getSamplePerCycle());
|
||||
System.out.println("可计算周波数: " + result.getCycleCount());
|
||||
System.out.println("分组数量: " + sizeOf(result.getVectorGroups()));
|
||||
if (result.getVectorGroups() == null || result.getVectorGroups().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (WaveVectorGroupDTO group : result.getVectorGroups()) {
|
||||
System.out.println("-- 分组: channelName=" + group.getChannelName()
|
||||
+ ", unit=" + group.getUnit()
|
||||
+ ", phaseCount=" + group.getPhaseCount()
|
||||
+ ", phaseNames=" + group.getPhaseNames());
|
||||
if (group.getVectorSeries() == null || group.getVectorSeries().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
WaveCycleVectorDTO firstCycle = group.getVectorSeries().get(0);
|
||||
System.out.println(" 首周波: cycleIndex=" + firstCycle.getCycleIndex() + ", time=" + firstCycle.getTime());
|
||||
printPhaseVectorSummary(firstCycle.getPhaseVectors());
|
||||
if (firstCycle.getPositiveSequence() != null) {
|
||||
System.out.println(" 正序: amplitude=" + firstCycle.getPositiveSequence().getAmplitude()
|
||||
+ ", rms=" + firstCycle.getPositiveSequence().getRms()
|
||||
+ ", phaseAngle=" + firstCycle.getPositiveSequence().getPhaseAngle());
|
||||
}
|
||||
if (firstCycle.getNegativeSequence() != null) {
|
||||
System.out.println(" 负序: amplitude=" + firstCycle.getNegativeSequence().getAmplitude()
|
||||
+ ", rms=" + firstCycle.getNegativeSequence().getRms()
|
||||
+ ", phaseAngle=" + firstCycle.getNegativeSequence().getPhaseAngle());
|
||||
}
|
||||
if (firstCycle.getZeroSequence() != null) {
|
||||
System.out.println(" 零序: amplitude=" + firstCycle.getZeroSequence().getAmplitude()
|
||||
+ ", rms=" + firstCycle.getZeroSequence().getRms()
|
||||
+ ", phaseAngle=" + firstCycle.getZeroSequence().getPhaseAngle());
|
||||
}
|
||||
if (firstCycle.getUnbalance() != null) {
|
||||
System.out.println(" 不平衡度: negative=" + firstCycle.getUnbalance().getNegativeUnbalanceRate()
|
||||
+ ", zero=" + firstCycle.getUnbalance().getZeroUnbalanceRate());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印单相电能质量结果摘要。
|
||||
*/
|
||||
private static void printPhaseVectorSummary(List<WavePhaseVectorDTO> phaseVectors) {
|
||||
if (phaseVectors == null || phaseVectors.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (WavePhaseVectorDTO phaseVector : phaseVectors) {
|
||||
System.out.println(" 相别=" + phaseVector.getPhaseName()
|
||||
+ ", totalRms=" + phaseVector.getTotalRms()
|
||||
+ ", fundamentalAmplitude=" + phaseVector.getFundamentalAmplitude()
|
||||
+ ", fundamentalRms=" + phaseVector.getFundamentalRms()
|
||||
+ ", fundamentalPhaseAngle=" + phaseVector.getFundamentalPhaseAngle()
|
||||
+ ", harmonicDistortionRate=" + phaseVector.getHarmonicDistortionRate());
|
||||
printHarmonicSummary("电压谐波", phaseVector.getHarmonicVoltageContentRates());
|
||||
printHarmonicSummary("电流谐波", phaseVector.getHarmonicCurrentAmplitudes());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印前几个谐波结果,避免控制台过长。
|
||||
*/
|
||||
private static void printHarmonicSummary(String label, List<WaveHarmonicDTO> harmonics) {
|
||||
if (harmonics == null || harmonics.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int limit = Math.min(3, harmonics.size());
|
||||
for (int i = 0; i < limit; i++) {
|
||||
WaveHarmonicDTO harmonic = harmonics.get(i);
|
||||
System.out.println(" " + label + "-第" + harmonic.getHarmonicOrder() + "次: amplitude=" + harmonic.getAmplitude()
|
||||
+ ", rms=" + harmonic.getRms()
|
||||
+ ", rate=" + harmonic.getRate());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析向量结果中的可计算周波数。
|
||||
*/
|
||||
private static Integer resolveCycleCount(List<WaveVectorGroupDTO> vectorGroups) {
|
||||
if (vectorGroups == null || vectorGroups.isEmpty() || vectorGroups.get(0).getVectorSeries() == null) {
|
||||
return 0;
|
||||
}
|
||||
return vectorGroups.get(0).getVectorSeries().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印 getComtrade 的关键摘要,便于快速人工核对。
|
||||
*/
|
||||
private static void printComtradeResult(WaveDataDTO waveDataDTO) {
|
||||
System.out.println("=== getComtrade 结果 ===");
|
||||
System.out.println("事件时间: " + waveDataDTO.getTime());
|
||||
System.out.println("相别数: " + waveDataDTO.getIPhasic());
|
||||
System.out.println("标题数: " + sizeOf(waveDataDTO.getWaveTitle()));
|
||||
System.out.println("通道数: " + sizeOf(waveDataDTO.getChannelNames()));
|
||||
System.out.println("波形点数: " + sizeOf(waveDataDTO.getListWaveData()));
|
||||
if (waveDataDTO.getComtradeCfgDTO() != null) {
|
||||
System.out.println("模拟量通道数: " + waveDataDTO.getComtradeCfgDTO().getNAnalogNum());
|
||||
System.out.println("开关量通道数: " + waveDataDTO.getComtradeCfgDTO().getNDigitalNum());
|
||||
System.out.println("最终采样率: " + waveDataDTO.getComtradeCfgDTO().getFinalSampleRate());
|
||||
}
|
||||
if (waveDataDTO.getWaveTitle() != null && !waveDataDTO.getWaveTitle().isEmpty()) {
|
||||
System.out.println("波形标题: " + waveDataDTO.getWaveTitle());
|
||||
}
|
||||
if (waveDataDTO.getListWaveData() != null && !waveDataDTO.getListWaveData().isEmpty()) {
|
||||
System.out.println("首行数据: " + waveDataDTO.getListWaveData().get(0));
|
||||
System.out.println("末行数据: " + waveDataDTO.getListWaveData().get(waveDataDTO.getListWaveData().size() - 1));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印 getValidData 的关键摘要。
|
||||
*/
|
||||
private static void printValidDataResult(WaveDataDTO waveDataDTO) {
|
||||
System.out.println("=== getValidData 结果 ===");
|
||||
System.out.println("RMS 点数: " + sizeOf(waveDataDTO.getListRmsData()));
|
||||
System.out.println("RMS 最小值点数: " + sizeOf(waveDataDTO.getListRmsMinData()));
|
||||
if (waveDataDTO.getListRmsData() != null && !waveDataDTO.getListRmsData().isEmpty()) {
|
||||
System.out.println("RMS 首行数据: " + waveDataDTO.getListRmsData().get(0));
|
||||
System.out.println("RMS 末行数据: " + waveDataDTO.getListRmsData().get(waveDataDTO.getListRmsData().size() - 1));
|
||||
}
|
||||
if (waveDataDTO.getListRmsMinData() != null && !waveDataDTO.getListRmsMinData().isEmpty()) {
|
||||
System.out.println("RMS 最小值数据: " + waveDataDTO.getListRmsMinData());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印特征值结果摘要。
|
||||
*/
|
||||
private static void printEigenvalueResult(List<EigenvalueDTO> eigenvalues) {
|
||||
System.out.println("=== getEigenvalue 结果 ===");
|
||||
System.out.println("特征值数量: " + sizeOf(eigenvalues));
|
||||
if (eigenvalues == null || eigenvalues.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < eigenvalues.size(); i++) {
|
||||
EigenvalueDTO eigenvalueDTO = eigenvalues.get(i);
|
||||
System.out.println("第" + (i + 1) + "相: amplitude=" + eigenvalueDTO.getAmplitude()
|
||||
+ ", residualVoltage=" + eigenvalueDTO.getResidualVoltage()
|
||||
+ ", ratedVoltage=" + eigenvalueDTO.getRatedVoltage()
|
||||
+ ", durationTime=" + eigenvalueDTO.getDurationTime());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全返回列表大小,避免空指针。
|
||||
*/
|
||||
private static int sizeOf(List<?> list) {
|
||||
return list == null ? 0 : list.size();
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package com.njcn.gather.tool.wave.component;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* 波形文件解析组件测试。
|
||||
*/
|
||||
class WaveFileComponentTest {
|
||||
|
||||
@Test
|
||||
void shouldRoundWaveTimeToThreeDecimals() {
|
||||
Assertions.assertEquals(1.235F, WaveFileComponent.roundWaveTime(1.2345F));
|
||||
Assertions.assertEquals(-99.988F, WaveFileComponent.roundWaveTime(-99.9876F));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRoundWaveAmplitudeToThreeDecimals() {
|
||||
Assertions.assertEquals(220.123F, WaveFileComponent.roundWaveAmplitude(220.1234F));
|
||||
Assertions.assertEquals(-12.988F, WaveFileComponent.roundWaveAmplitude(-12.9876F));
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
package com.njcn.gather.tool.wave.component;
|
||||
|
||||
import com.njcn.gather.tool.wave.pojo.dto.ComtradeCfgDTO;
|
||||
import com.njcn.gather.tool.wave.pojo.dto.WaveDataDTO;
|
||||
import com.njcn.gather.tool.wave.pojo.dto.WaveVectorGroupDTO;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 波形向量计算组件测试。
|
||||
*/
|
||||
class WaveVectorComponentTest {
|
||||
|
||||
@Test
|
||||
void shouldScaleVoltageVectorValuesToKv() {
|
||||
WaveVectorComponent component = new WaveVectorComponent();
|
||||
WaveDataDTO waveDataDTO = buildThreePhaseWaveData("U", 8153.209D, 1D);
|
||||
|
||||
List<WaveVectorGroupDTO> groups = component.calculateVectors(waveDataDTO);
|
||||
|
||||
Assertions.assertEquals("kV", groups.get(0).getUnit());
|
||||
Assertions.assertEquals(5.7652F, groups.get(0).getVectorSeries().get(0).getPhaseVectors().get(0).getTotalRms());
|
||||
Assertions.assertEquals(8.1532F, groups.get(0).getVectorSeries().get(0).getPhaseVectors().get(0).getFundamentalAmplitude());
|
||||
Assertions.assertEquals(5.7652F, groups.get(0).getVectorSeries().get(0).getPhaseVectors().get(0).getFundamentalRms());
|
||||
Assertions.assertEquals(5.7652F, groups.get(0).getVectorSeries().get(0).getPositiveSequence().getRms());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldKeepCurrentVectorValuesInAmpere() {
|
||||
WaveVectorComponent component = new WaveVectorComponent();
|
||||
WaveDataDTO waveDataDTO = buildThreePhaseWaveData("I", 35D, 1D);
|
||||
|
||||
List<WaveVectorGroupDTO> groups = component.calculateVectors(waveDataDTO);
|
||||
|
||||
Assertions.assertEquals("A", groups.get(0).getUnit());
|
||||
Assertions.assertEquals(24.7487F, groups.get(0).getVectorSeries().get(0).getPhaseVectors().get(0).getTotalRms());
|
||||
Assertions.assertEquals(35F, groups.get(0).getVectorSeries().get(0).getPhaseVectors().get(0).getFundamentalAmplitude());
|
||||
Assertions.assertEquals(24.7487F, groups.get(0).getVectorSeries().get(0).getPhaseVectors().get(0).getFundamentalRms());
|
||||
}
|
||||
|
||||
private WaveDataDTO buildThreePhaseWaveData(String titlePrefix, double amplitude, double ratio) {
|
||||
int samplePerCycle = 32;
|
||||
WaveDataDTO waveDataDTO = new WaveDataDTO();
|
||||
ComtradeCfgDTO cfgDTO = new ComtradeCfgDTO();
|
||||
cfgDTO.setFinalSampleRate(samplePerCycle);
|
||||
waveDataDTO.setComtradeCfgDTO(cfgDTO);
|
||||
waveDataDTO.setIPhasic(3);
|
||||
waveDataDTO.setPt(ratio);
|
||||
waveDataDTO.setCt(ratio);
|
||||
waveDataDTO.setWaveTitle(Arrays.asList("x", titlePrefix + "A", titlePrefix + "B", titlePrefix + "C"));
|
||||
waveDataDTO.setChannelNames(Arrays.asList("x", titlePrefix));
|
||||
waveDataDTO.setListWaveData(buildRows(samplePerCycle, amplitude));
|
||||
return waveDataDTO;
|
||||
}
|
||||
|
||||
private List<List<Float>> buildRows(int samplePerCycle, double amplitude) {
|
||||
List<List<Float>> rows = new ArrayList<>();
|
||||
for (int i = 0; i < samplePerCycle; i++) {
|
||||
double angle = 2D * Math.PI * i / samplePerCycle;
|
||||
List<Float> row = new ArrayList<>();
|
||||
row.add((float) i);
|
||||
row.add((float) (amplitude * Math.sin(angle)));
|
||||
row.add((float) (amplitude * Math.sin(angle - 2D * Math.PI / 3D)));
|
||||
row.add((float) (amplitude * Math.sin(angle + 2D * Math.PI / 3D)));
|
||||
rows.add(row);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
package com.njcn.gather.tool.wave.service.impl;
|
||||
|
||||
import com.njcn.gather.tool.wave.component.WaveFileComponent;
|
||||
import com.njcn.gather.tool.wave.component.WaveVectorComponent;
|
||||
import com.njcn.gather.tool.wave.pojo.dto.AnalogDTO;
|
||||
import com.njcn.gather.tool.wave.pojo.dto.ComtradeCfgDTO;
|
||||
import com.njcn.gather.tool.wave.pojo.dto.WaveDataDTO;
|
||||
import com.njcn.gather.tool.wave.pojo.param.WaveComtradeParseParam;
|
||||
import com.njcn.gather.tool.wave.pojo.vo.WaveComtradeResultVO;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 波形服务测试。
|
||||
*/
|
||||
class WaveServiceImplTest {
|
||||
|
||||
@Test
|
||||
void shouldUseCfgRatioWhenCfgContainsValidPtAndCt() throws Exception {
|
||||
WaveServiceImpl service = new WaveServiceImpl(new WaveFileComponent(), new WaveVectorComponent());
|
||||
WaveDataDTO waveDataDTO = new WaveDataDTO();
|
||||
ComtradeCfgDTO cfgDTO = new ComtradeCfgDTO();
|
||||
cfgDTO.setLstAnalogDTO(Arrays.asList(
|
||||
buildAnalog("V", 10000F, 100F),
|
||||
buildAnalog("A", 200F, 1F)
|
||||
));
|
||||
waveDataDTO.setComtradeCfgDTO(cfgDTO);
|
||||
|
||||
WaveComtradeParseParam param = new WaveComtradeParseParam();
|
||||
param.setPt(1D);
|
||||
param.setCt(1D);
|
||||
|
||||
Method method = WaveServiceImpl.class.getDeclaredMethod("applyWaveMetadata", WaveDataDTO.class, WaveComtradeParseParam.class);
|
||||
method.setAccessible(true);
|
||||
method.invoke(service, waveDataDTO, param);
|
||||
|
||||
Assertions.assertEquals(100D, waveDataDTO.getPt());
|
||||
Assertions.assertEquals(200D, waveDataDTO.getCt());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFillComtradeSummaryFields() throws Exception {
|
||||
WaveServiceImpl service = new WaveServiceImpl(new WaveFileComponent(), new WaveVectorComponent());
|
||||
WaveDataDTO waveDataDTO = new WaveDataDTO();
|
||||
ComtradeCfgDTO cfgDTO = new ComtradeCfgDTO();
|
||||
cfgDTO.setNChannelNum(8);
|
||||
cfgDTO.setNPhasic(3);
|
||||
cfgDTO.setLstAnalogDTO(Arrays.asList(
|
||||
buildAnalog("V", 10000F, 100F),
|
||||
buildAnalog("A", 200F, 1F)
|
||||
));
|
||||
waveDataDTO.setComtradeCfgDTO(cfgDTO);
|
||||
waveDataDTO.setIPhasic(3);
|
||||
|
||||
WaveComtradeResultVO result = new WaveComtradeResultVO();
|
||||
Method method = WaveServiceImpl.class.getDeclaredMethod("fillComtradeSummary", WaveComtradeResultVO.class, WaveDataDTO.class);
|
||||
method.setAccessible(true);
|
||||
method.invoke(service, result, waveDataDTO);
|
||||
|
||||
Assertions.assertEquals(8, result.getTotalChannels());
|
||||
Assertions.assertEquals(3, result.getPhaseCount());
|
||||
Assertions.assertEquals("kV/A", result.getUnit());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldMaskValuesInsideBottomPlatformMiddle() throws Exception {
|
||||
WaveServiceImpl service = new WaveServiceImpl(new WaveFileComponent(), new WaveVectorComponent());
|
||||
WaveDataDTO waveDataDTO = new WaveDataDTO();
|
||||
ComtradeCfgDTO cfgDTO = new ComtradeCfgDTO();
|
||||
cfgDTO.setFinalSampleRate(1);
|
||||
waveDataDTO.setComtradeCfgDTO(cfgDTO);
|
||||
waveDataDTO.setListWaveData(buildRows(new float[][]{
|
||||
{0F, 100F, 100F, 100F},
|
||||
{1F, 100F, 100F, 100F},
|
||||
{2F, 100F, 100F, 100F},
|
||||
{3F, 100F, 100F, 100F},
|
||||
{4F, 80F, 100F, 100F},
|
||||
{5F, 60F, 100F, 100F},
|
||||
{6F, 60F, 100F, 100F},
|
||||
{7F, 60F, 100F, 100F},
|
||||
{8F, 95F, 100F, 100F},
|
||||
{9F, 100F, 100F, 100F}
|
||||
}));
|
||||
waveDataDTO.setListRmsData(buildRows(new float[][]{
|
||||
{0F, 100F, 100F, 100F},
|
||||
{1F, 100F, 100F, 100F},
|
||||
{2F, 100F, 100F, 100F},
|
||||
{3F, 100F, 100F, 100F},
|
||||
{4F, 80F, 100F, 100F},
|
||||
{5F, 60F, 100F, 100F},
|
||||
{6F, 60F, 100F, 100F},
|
||||
{7F, 60F, 100F, 100F},
|
||||
{8F, 95F, 100F, 100F},
|
||||
{9F, 100F, 100F, 100F}
|
||||
}));
|
||||
|
||||
Method method = WaveServiceImpl.class.getDeclaredMethod("applySimplifiedDisplay", WaveDataDTO.class);
|
||||
method.setAccessible(true);
|
||||
method.invoke(service, waveDataDTO);
|
||||
|
||||
Assertions.assertEquals(0F, waveDataDTO.getListWaveData().get(0).get(0));
|
||||
Assertions.assertEquals(100F, waveDataDTO.getListWaveData().get(0).get(1));
|
||||
Assertions.assertEquals(100F, waveDataDTO.getListWaveData().get(2).get(1));
|
||||
Assertions.assertEquals(80F, waveDataDTO.getListWaveData().get(4).get(1));
|
||||
Assertions.assertEquals(60F, waveDataDTO.getListWaveData().get(5).get(1));
|
||||
Assertions.assertNull(waveDataDTO.getListWaveData().get(6).get(1));
|
||||
Assertions.assertEquals(60F, waveDataDTO.getListWaveData().get(7).get(1));
|
||||
Assertions.assertEquals(95F, waveDataDTO.getListWaveData().get(8).get(1));
|
||||
Assertions.assertEquals(100F, waveDataDTO.getListWaveData().get(9).get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldKeepDataWhenSimplifiedRangeCannotBeDetected() throws Exception {
|
||||
WaveServiceImpl service = new WaveServiceImpl(new WaveFileComponent(), new WaveVectorComponent());
|
||||
WaveDataDTO waveDataDTO = new WaveDataDTO();
|
||||
ComtradeCfgDTO cfgDTO = new ComtradeCfgDTO();
|
||||
cfgDTO.setFinalSampleRate(1);
|
||||
waveDataDTO.setComtradeCfgDTO(cfgDTO);
|
||||
waveDataDTO.setListWaveData(buildRows(new float[][]{
|
||||
{0F, 100F, 100F, 100F},
|
||||
{1F, 99F, 100F, 100F},
|
||||
{2F, 98F, 100F, 100F}
|
||||
}));
|
||||
waveDataDTO.setListRmsData(buildRows(new float[][]{
|
||||
{0F, 100F, 100F, 100F},
|
||||
{1F, 99F, 100F, 100F},
|
||||
{2F, 98F, 100F, 100F}
|
||||
}));
|
||||
|
||||
Method method = WaveServiceImpl.class.getDeclaredMethod("applySimplifiedDisplay", WaveDataDTO.class);
|
||||
method.setAccessible(true);
|
||||
method.invoke(service, waveDataDTO);
|
||||
|
||||
Assertions.assertEquals(99F, waveDataDTO.getListWaveData().get(1).get(1));
|
||||
Assertions.assertEquals(98F, waveDataDTO.getListRmsData().get(2).get(1));
|
||||
}
|
||||
|
||||
private AnalogDTO buildAnalog(String unit, Float primary, Float secondary) {
|
||||
AnalogDTO analogDTO = new AnalogDTO();
|
||||
analogDTO.setSzUnitName(unit);
|
||||
analogDTO.setFPrimary(primary);
|
||||
analogDTO.setFSecondary(secondary);
|
||||
return analogDTO;
|
||||
}
|
||||
|
||||
private List<List<Float>> buildRows(float[][] values) {
|
||||
List<List<Float>> rows = new ArrayList<>();
|
||||
for (float[] value : values) {
|
||||
List<Float> row = new ArrayList<>();
|
||||
for (float item : value) {
|
||||
row.add(item);
|
||||
}
|
||||
rows.add(row);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user