feat(mms-mapping): 添加ICD转XML映射功能
- 新增DefaultCfgToXml.txt模板文件,定义报告列表、逻辑节点分类、相别、倍数器、单位等配置项 - 添加IcdToXmlGenerateCommand类,封装ICD文件转换命令参数,包括文件名、字节流、版本号等属性 - 创建IcdToXmlGenerateRequest类,定义ICD转XML生成请求参数,包含版本号、作者、保存选项等字段 - 实现IcdToXmlGenerateResult类,封装转换结果,包含状态、消息、IED名称、LD实例等信息 - 开发IcdToXmlMappingService组件,提供索引映射配置和统计数据分析功能 - 添加IcdToXmlRequestConverter组件,实现请求参数到命令对象的转换逻辑 - 创建IcdToXmlResponse类,定义ICD转XML响应结构,包含状态、消息、映射文档等属性 - 实现IcdToXmlResponseConverter组件,将结果对象转换为响应对象 - 添加IcdToXmlTaskAppService服务,协调各个组件完成ICD到XML的完整转换流程 - 集成ICD解析、模板加载、索引分析、验证、映射生成等核心功能模块
This commit is contained in:
@@ -0,0 +1,231 @@
|
||||
package com.njcn.gather.icd.mapping.component;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import com.njcn.gather.icd.mapping.pojo.dto.*;
|
||||
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;
|
||||
@Setter
|
||||
@Getter
|
||||
@Component
|
||||
public class IcdToXmlMappingService {
|
||||
|
||||
private IndexMappingConfig indexMapping;
|
||||
|
||||
@Data
|
||||
public static class IndexMappingConfig {
|
||||
private StatIndex mmxu;
|
||||
private StatIndex mhai;
|
||||
private StatIndex interHarmonic;
|
||||
private StatIndex msqi;
|
||||
private Integer mflkShort;
|
||||
private Integer mflkLong;
|
||||
private Integer qvvr;
|
||||
|
||||
@Data
|
||||
public static class StatIndex {
|
||||
private Integer average;
|
||||
private Integer maximum;
|
||||
private Integer minimum;
|
||||
private Integer percentile95;
|
||||
}
|
||||
}
|
||||
|
||||
public IndexMappingConfig toIndexMapping(){
|
||||
IndexMappingConfig indexMapping = new IndexMappingConfig();
|
||||
return indexMapping;
|
||||
}
|
||||
|
||||
public void setIndexMapping(IndexMappingConfig config) {
|
||||
this.indexMapping = config;
|
||||
}
|
||||
|
||||
public IndexMappingConfig buildIndexMappingFromSelection(List<IndexSelectionGroupCommand> indexSelectionGroups) {
|
||||
IndexMappingConfig config = new IndexMappingConfig();
|
||||
|
||||
if (indexSelectionGroups == null || indexSelectionGroups.isEmpty()) {
|
||||
return config;
|
||||
}
|
||||
|
||||
for (IndexSelectionGroupCommand group : indexSelectionGroups) {
|
||||
String groupKey = group.getGroupKey();
|
||||
List<IndexBindingCommand> bindings = group.getBindings();
|
||||
|
||||
if (bindings == null || bindings.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ("统计数据__DSSTATISTICDATA".equals(groupKey)) {
|
||||
processStatisticDataGroup(config, bindings);
|
||||
} else if ("波动闪变__DSFLICKERDATA".equals(groupKey)) {
|
||||
processFlickerDataGroup(config, bindings);
|
||||
} else if ("暂态事件__DSEVEQVVR".equals(groupKey)) {
|
||||
processQvvrGroup(config, bindings);
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
private void processStatisticDataGroup(IndexMappingConfig config, List<IndexBindingCommand> bindings) {
|
||||
for (IndexBindingCommand binding : bindings) {
|
||||
String dataSetName = binding.getDataSetName();
|
||||
String label = binding.getLabel();
|
||||
Integer lnInst = parseLnInst(binding.getLnInst());
|
||||
|
||||
if (lnInst == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ("dsStHarm".equals(dataSetName) ) {
|
||||
if (config.getMhai() == null) {
|
||||
config.setMhai(new IndexMappingConfig.StatIndex());
|
||||
}
|
||||
mapStatIndex(config.getMhai(), label, lnInst);
|
||||
} else if ("dsStIHarm".equals(dataSetName)) {
|
||||
if (config.getInterHarmonic() == null) {
|
||||
config.setInterHarmonic(new IndexMappingConfig.StatIndex());
|
||||
}
|
||||
mapStatIndex(config.getInterHarmonic(), label, lnInst);
|
||||
} else if ("dsStMMXU".equals(dataSetName)) {
|
||||
if (config.getMmxu() == null) {
|
||||
config.setMmxu(new IndexMappingConfig.StatIndex());
|
||||
}
|
||||
mapStatIndex(config.getMmxu(), label, lnInst);
|
||||
}else if ("dsStMSQI".equals(dataSetName)) {
|
||||
if (config.getMsqi() == null) {
|
||||
config.setMsqi(new IndexMappingConfig.StatIndex());
|
||||
}
|
||||
mapStatIndex(config.getMsqi(), label, lnInst);
|
||||
} else if ("dsStatisticData".equals(dataSetName)) {
|
||||
if (label != null && label.contains("间谐波")) {
|
||||
if (config.getInterHarmonic() == null) {
|
||||
config.setInterHarmonic(new IndexMappingConfig.StatIndex());
|
||||
}
|
||||
mapStatIndex(config.getInterHarmonic(), label, lnInst);
|
||||
} else {
|
||||
if (config.getMmxu() == null) {
|
||||
config.setMmxu(new IndexMappingConfig.StatIndex());
|
||||
}
|
||||
mapStatIndex(config.getMmxu(), label, lnInst);
|
||||
if (config.getMhai() == null) {
|
||||
config.setMhai(new IndexMappingConfig.StatIndex());
|
||||
}
|
||||
mapStatIndex(config.getMhai(), label, lnInst);
|
||||
if (config.getMsqi() == null) {
|
||||
config.setMsqi(new IndexMappingConfig.StatIndex());
|
||||
}
|
||||
mapStatIndex(config.getMsqi(), label, lnInst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processFlickerDataGroup(IndexMappingConfig config, List<IndexBindingCommand> bindings) {
|
||||
for (IndexBindingCommand binding : bindings) {
|
||||
String dataSetName = binding.getDataSetName();
|
||||
String label = binding.getLabel();
|
||||
Integer lnInst = parseLnInst(binding.getLnInst());
|
||||
|
||||
if (lnInst == null) {
|
||||
continue;
|
||||
}
|
||||
if ("dsPST".equals(dataSetName)) {
|
||||
if (config.getMflkShort() == null) {
|
||||
config.setMflkShort(0);
|
||||
}
|
||||
config.setMflkShort(lnInst);
|
||||
}
|
||||
else if ("dsPLT".equals(dataSetName)) {
|
||||
if (config.getMflkLong() == null) {
|
||||
config.setMflkLong(0);
|
||||
}
|
||||
config.setMflkLong(lnInst);
|
||||
}else {
|
||||
if (config.getMflkShort() == null) {
|
||||
config.setMflkShort(0);
|
||||
}
|
||||
config.setMflkShort(lnInst);
|
||||
if (config.getMflkLong() == null) {
|
||||
config.setMflkLong(0);
|
||||
}
|
||||
config.setMflkLong(lnInst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processQvvrGroup(IndexMappingConfig config, List<IndexBindingCommand> bindings) {
|
||||
for (IndexBindingCommand binding : bindings) {
|
||||
String label = binding.getLabel();
|
||||
Integer lnInst = parseLnInst(binding.getLnInst());
|
||||
|
||||
if (lnInst == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (label != null && label.startsWith("电压变动")) {
|
||||
config.setQvvr(lnInst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void mapStatIndex(IndexMappingConfig.StatIndex statIndex, String label, Integer lnInst) {
|
||||
if (label == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (label) {
|
||||
case "最大值":
|
||||
statIndex.setMaximum(lnInst);
|
||||
break;
|
||||
case "最小值":
|
||||
statIndex.setMinimum(lnInst);
|
||||
break;
|
||||
case "平均值":
|
||||
statIndex.setAverage(lnInst);
|
||||
break;
|
||||
case "95值":
|
||||
statIndex.setPercentile95(lnInst);
|
||||
break;
|
||||
case "间谐波最大值":
|
||||
statIndex.setMaximum(lnInst);
|
||||
break;
|
||||
case "间谐波最小值":
|
||||
statIndex.setMinimum(lnInst);
|
||||
break;
|
||||
case "间谐波平均值":
|
||||
statIndex.setAverage(lnInst);
|
||||
break;
|
||||
case "间谐波95值":
|
||||
statIndex.setPercentile95(lnInst);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private Integer parseLnInst(String lnInstStr) {
|
||||
if (lnInstStr == null || lnInstStr.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(lnInstStr.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.njcn.gather.icd.mapping.component;
|
||||
|
||||
import com.njcn.gather.icd.mapping.pojo.dto.IcdToXmlGenerateCommand;
|
||||
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.param.IcdToXmlGenerateRequest;
|
||||
import com.njcn.gather.icd.mapping.pojo.param.IndexBindingRequest;
|
||||
import com.njcn.gather.icd.mapping.pojo.param.IndexSelectionGroupRequest;
|
||||
import com.njcn.gather.icd.mapping.pojo.param.JsonToXmlRequest;import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class IcdToXmlRequestConverter {
|
||||
|
||||
public IcdToXmlGenerateCommand toCommand(MultipartFile icdFile, IcdToXmlGenerateRequest request) {
|
||||
IcdToXmlGenerateCommand command = new IcdToXmlGenerateCommand();
|
||||
try {
|
||||
command.setFileBytes(icdFile.getBytes());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("读取 ICD 文件失败", e);
|
||||
}
|
||||
command.setFileName(icdFile.getOriginalFilename());
|
||||
command.setVersion(request.getVersion());
|
||||
command.setAuthor(request.getAuthor());
|
||||
command.setSaveToDisk(request.isSaveToDisk());
|
||||
command.setOutputDir(request.getOutputDir());
|
||||
command.setIndexSelection(toIndexSelectionGroupCommands(request.getIndexSelection()));
|
||||
return command;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 JsonToXmlRequest 转换为 IcdToXmlGenerateCommand。
|
||||
* 注意:此方法不处理文件,仅转换索引选择结果。
|
||||
*/
|
||||
public IcdToXmlGenerateCommand toCommand(JsonToXmlRequest request) {
|
||||
IcdToXmlGenerateCommand command = new IcdToXmlGenerateCommand();
|
||||
command.setVersion("1.0");
|
||||
command.setAuthor("");
|
||||
command.setSaveToDisk(false);
|
||||
command.setOutputDir(null);
|
||||
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
private List<IndexSelectionGroupCommand> toIndexSelectionGroupCommands(List<IndexSelectionGroupRequest> indexSelection) {
|
||||
List<IndexSelectionGroupCommand> indexSelectionGroupCommands = new ArrayList<>();
|
||||
if (indexSelection != null) {
|
||||
for (IndexSelectionGroupRequest groupRequest : indexSelection) {
|
||||
IndexSelectionGroupCommand groupCommand = new IndexSelectionGroupCommand();
|
||||
groupCommand.setGroupKey(groupRequest.getGroupKey());
|
||||
groupCommand.setGroupDesc(groupRequest.getGroupDesc());
|
||||
groupCommand.setBindings(toIndexBindingCommands(groupRequest.getBindings()));
|
||||
indexSelectionGroupCommands.add(groupCommand);
|
||||
}
|
||||
}
|
||||
return indexSelectionGroupCommands;
|
||||
}
|
||||
|
||||
private List<IndexBindingCommand> toIndexBindingCommands(List<IndexBindingRequest> bindings) {
|
||||
List<IndexBindingCommand> indexBindingCommands = new ArrayList<>();
|
||||
if (bindings != null) {
|
||||
for (IndexBindingRequest bindingRequest : bindings) {
|
||||
IndexBindingCommand bindingCommand = new IndexBindingCommand();
|
||||
bindingCommand.setReportName(bindingRequest.getReportName());
|
||||
bindingCommand.setDataSetName(bindingRequest.getDataSetName());
|
||||
bindingCommand.setLabel(bindingRequest.getLabel());
|
||||
bindingCommand.setLnInst(bindingRequest.getLnInst());
|
||||
indexBindingCommands.add(bindingCommand);
|
||||
}
|
||||
}
|
||||
return indexBindingCommands;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.njcn.gather.icd.mapping.component;
|
||||
|
||||
import com.njcn.gather.icd.mapping.pojo.bo.IcdToXmlGenerateResult;
|
||||
import com.njcn.gather.icd.mapping.pojo.bo.analysis.IndexCandidate;
|
||||
import com.njcn.gather.icd.mapping.pojo.bo.analysis.IndexCandidateReportItem;
|
||||
import com.njcn.gather.icd.mapping.pojo.vo.IcdToXmlResponse;
|
||||
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 org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class IcdToXmlResponseConverter {
|
||||
|
||||
public IcdToXmlResponse fromResult(IcdToXmlGenerateResult result) {
|
||||
IcdToXmlResponse response = new IcdToXmlResponse();
|
||||
response.setStatus(result.getStatus());
|
||||
response.setMessage(result.getMessage());
|
||||
response.setIedName(result.getIedName());
|
||||
response.setLdInst(result.getLdInst());
|
||||
response.setSavedPath(result.getSavedPath());
|
||||
response.getProblems().addAll(result.getProblems());
|
||||
|
||||
if (result.getIndexAnalysis() != null && result.getIndexAnalysis().getCandidates() != null) {
|
||||
for (IndexCandidate candidate : result.getIndexAnalysis().getCandidates()) {
|
||||
IndexCandidateResponse candidateResponse = new IndexCandidateResponse();
|
||||
candidateResponse.setGroupKey(candidate.getGroupKey());
|
||||
candidateResponse.setGroupDesc(candidate.getGroupDesc());
|
||||
candidateResponse.setReportCount(candidate.getReportCount());
|
||||
candidateResponse.getTemplateLabels().addAll(candidate.getTemplateLabels());
|
||||
|
||||
if (candidate.getReports() != null) {
|
||||
for (IndexCandidateReportItem item : candidate.getReports()) {
|
||||
IndexCandidateReportItemResponse itemResponse = new IndexCandidateReportItemResponse();
|
||||
itemResponse.setReportName(item.getReportName());
|
||||
itemResponse.setDataSetName(item.getDataSetName());
|
||||
itemResponse.setReportDesc(item.getReportDesc());
|
||||
itemResponse.getAvailableLnInstValues().addAll(item.getAvailableLnInstValues());
|
||||
candidateResponse.getReports().add(itemResponse);
|
||||
}
|
||||
}
|
||||
|
||||
response.getIndexCandidates().add(candidateResponse);
|
||||
}
|
||||
}
|
||||
|
||||
if (result.getMappingDocument() != null) {
|
||||
MappingDocumentResponse doc = new MappingDocumentResponse();
|
||||
doc.setVersion(result.getMappingDocument().getVersion());
|
||||
doc.setAuthor(result.getMappingDocument().getAuthor());
|
||||
doc.setIed(result.getMappingDocument().getIed());
|
||||
doc.setLd(result.getMappingDocument().getLd());
|
||||
doc.setReportCount(result.getMappingDocument().getReportMap() == null
|
||||
? 0 : result.getMappingDocument().getReportMap().size());
|
||||
doc.setDataSetCount(result.getMappingDocument().getDataSetList() == null
|
||||
? 0 : result.getMappingDocument().getDataSetList().size());
|
||||
response.setMappingDocument(doc);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,852 @@
|
||||
package com.njcn.gather.icd.mapping.component;
|
||||
|
||||
|
||||
import com.njcn.gather.icd.mapping.pojo.bo.icd.*;
|
||||
import com.njcn.gather.icd.mapping.utils.XmlTemplateParser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import com.njcn.gather.icd.mapping.pojo.dto.*;
|
||||
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;
|
||||
@Component
|
||||
public class RuleBasedXmlMappingService {
|
||||
|
||||
@Autowired
|
||||
private IcdParserService icdParserService;
|
||||
|
||||
private static final Pattern VALUE_RULE_PATTERN = Pattern.compile(
|
||||
"<Value\\s+" +
|
||||
"name=\"([^\"]+)\"\\s+" +
|
||||
"desc=\"([^\"]+)\"\\s+" +
|
||||
"type=\"([^\"]+)\"\\s+" +
|
||||
"(?:DO=\"([^\"]*)\")?\\s*" +
|
||||
"(?:DA=\"([^\"]*)\")?\\s*" +
|
||||
"(?:BaseFlag=\"([^\"]*)\")?\\s*" +
|
||||
"(?:LimitUp=\"([^\"]*)\")?\\s*" +
|
||||
"(?:LimitDown=\"([^\"]*)\")?\\s*" +
|
||||
"(?:Coefficient=\"([^\"]*)\")?\\s*" +
|
||||
"/>", Pattern.CASE_INSENSITIVE
|
||||
);
|
||||
|
||||
private static final Pattern XML_VALUE_PATTERN = Pattern.compile(
|
||||
"<Value\\s+" +
|
||||
"name=\"([^\"]+)\"\\s+" +
|
||||
"desc=\"([^\"]+)\"\\s+" +
|
||||
"type=\"([^\"]+)\"\\s+" +
|
||||
"(?:DO=\"([^\"]*)\")?\\s*" +
|
||||
"(?:DA=\"([^\"]*)\")?\\s*" +
|
||||
"(?:BaseFlag=\"([^\"]*)\")?\\s*" +
|
||||
"(?:LimitUp=\"([^\"]*)\")?\\s*" +
|
||||
"(?:LimitDown=\"([^\"]*)\")?\\s*" +
|
||||
"(?:Coefficient=\"([^\"]*)\")?\\s*" +
|
||||
"/>", Pattern.CASE_INSENSITIVE
|
||||
);
|
||||
|
||||
private static final Pattern DO_INDEX_PATTERN = Pattern.compile("(MMXU|MHAI|MSQI|MFLK|QVVR)(\\d+)");
|
||||
private static final Pattern DO_NO_INDEX_PATTERN = Pattern.compile("(MMXU|MHAI|MSQI|MFLK|QVVR)\\$");
|
||||
|
||||
public InputStream loadDefaultXmlFile( ) throws Exception {
|
||||
ClassPathResource templateResource = new ClassPathResource("template/JiangSu_Config2.xml");
|
||||
|
||||
if (!templateResource.exists()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return templateResource.getInputStream();
|
||||
}
|
||||
|
||||
public List<InputStream> loadDefaultRuleFile( ) throws Exception {
|
||||
|
||||
ClassPathResource ruleResource = new ClassPathResource("template/默认规则.txt");
|
||||
if ( !ruleResource.exists()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
InputStream ruleStream = ruleResource.getInputStream();
|
||||
List<InputStream> ruleStreams = new ArrayList<>();
|
||||
ruleStreams.add(ruleStream);
|
||||
return ruleStreams;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public String generateWithRuleFiles(IcdDocument icdDocument,
|
||||
InputStream templateStream,
|
||||
List<InputStream> ruleStreams,
|
||||
IcdToXmlMappingService.IndexMappingConfig indexMapping) throws Exception {
|
||||
|
||||
Map<String, List<ValueRule>> mergedRules = mergeAllRules(ruleStreams, indexMapping);
|
||||
|
||||
Map<String, IcdMetricInfo> icdMetrics = extractIcdMetrics(icdDocument);
|
||||
|
||||
Map<String, ValueRule> applicableRules = findApplicableRules(mergedRules, icdMetrics);
|
||||
|
||||
XmlTemplateParser.ParseResult parseResult = new XmlTemplateParser().parse(templateStream);
|
||||
String xmlContent = parseResult.getTemplateContent();
|
||||
|
||||
xmlContent = fillIedInfo(xmlContent, icdDocument);
|
||||
|
||||
xmlContent = fillReportControls(xmlContent, icdDocument);
|
||||
|
||||
xmlContent = applyRulesToXml(xmlContent, applicableRules);
|
||||
|
||||
Path tempPath = Files.createTempFile("rule_mapped_", ".xml");
|
||||
Files.write(tempPath, xmlContent.getBytes(StandardCharsets.UTF_8));
|
||||
return tempPath.toString();
|
||||
}
|
||||
|
||||
|
||||
private Map<String, List<ValueRule>> mergeAllRules(List<InputStream> ruleStreams,
|
||||
IcdToXmlMappingService.IndexMappingConfig indexMapping) throws Exception {
|
||||
Map<String, List<ValueRule>> mergedRules = new LinkedHashMap<>();
|
||||
|
||||
for (InputStream ruleStream : ruleStreams) {
|
||||
Map<String, List<ValueRule>> rules = parseRuleFile(ruleStream, indexMapping);
|
||||
for (Map.Entry<String, List<ValueRule>> entry : rules.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
List<ValueRule> ruleList = entry.getValue();
|
||||
mergedRules.computeIfAbsent(key, k -> new ArrayList<>()).addAll(ruleList);
|
||||
}
|
||||
}
|
||||
|
||||
return mergedRules;
|
||||
}
|
||||
|
||||
|
||||
private Map<String, List<ValueRule>> parseRuleFile(InputStream ruleStream,
|
||||
IcdToXmlMappingService.IndexMappingConfig indexMapping) throws Exception {
|
||||
Map<String, List<ValueRule>> rules = new HashMap<>();
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(ruleStream, StandardCharsets.UTF_8));
|
||||
String line;
|
||||
String currentGroup = "";
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
line = line.trim();
|
||||
|
||||
if (line.startsWith("<!--")) {
|
||||
if (line.contains("MMXU") || line.contains("基本数据")) {
|
||||
currentGroup = "MMXU";
|
||||
} else if (line.contains("间谐波")) {
|
||||
currentGroup = "INTER_HARMONIC";
|
||||
} else if (line.contains("MHAI") && line.contains("谐波数据")) {
|
||||
currentGroup = "MHAI";
|
||||
} else if (line.contains("MSQI") || line.contains("序分量")) {
|
||||
currentGroup = "MSQI";
|
||||
} else if (line.contains("短闪") || line.contains("短时闪变")) {
|
||||
currentGroup = "MFLK_SHORT";
|
||||
} else if (line.contains("长闪") || line.contains("长时闪变")) {
|
||||
currentGroup = "MFLK_LONG";
|
||||
} else if (line.contains("QVVR") || line.contains("电压变动")) {
|
||||
currentGroup = "QVVR";
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line.isEmpty() || !line.startsWith("<Value")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Matcher matcher = VALUE_RULE_PATTERN.matcher(line);
|
||||
if (matcher.find()) {
|
||||
ValueRule rule = new ValueRule();
|
||||
rule.setName(matcher.group(1));
|
||||
rule.setDesc(matcher.group(2));
|
||||
rule.setType(matcher.group(3));
|
||||
String doPath = matcher.group(4) != null ? matcher.group(4) : "";
|
||||
String daPath = matcher.group(5) != null ? matcher.group(5) : "";
|
||||
|
||||
if (indexMapping != null && !doPath.isEmpty()) {
|
||||
doPath = applyIndexMapping(doPath, currentGroup, indexMapping, rule.getName(), rule.getDesc());
|
||||
}
|
||||
|
||||
rule.setDoPath(doPath);
|
||||
rule.setDaPath(daPath);
|
||||
rule.setBaseFlag(matcher.group(6));
|
||||
rule.setLimitUp(matcher.group(7));
|
||||
rule.setLimitDown(matcher.group(8));
|
||||
rule.setCoefficient(matcher.group(9));
|
||||
|
||||
String key = buildRuleKey(rule.getName(), rule.getDesc());
|
||||
if (!key.isEmpty() && hasValidDoOrDa(rule)) {
|
||||
rules.computeIfAbsent(key.toLowerCase(), k -> new ArrayList<>()).add(rule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reader.close();
|
||||
return rules;
|
||||
}
|
||||
|
||||
private String applyIndexMapping(String doPath, String currentGroup,
|
||||
IcdToXmlMappingService.IndexMappingConfig indexMapping,
|
||||
String name, String desc) {
|
||||
if (indexMapping == null) {
|
||||
return doPath;
|
||||
}
|
||||
|
||||
Matcher matcherWithIndex = DO_INDEX_PATTERN.matcher(doPath);
|
||||
if (matcherWithIndex.find()) {
|
||||
String lnClass = matcherWithIndex.group(1);
|
||||
int originalIndex = Integer.parseInt(matcherWithIndex.group(2));
|
||||
|
||||
int newIndex = determineNewIndex(currentGroup, lnClass, originalIndex, indexMapping, name, desc);
|
||||
if(name.contains("fluc")){
|
||||
System.out.println("fluc");
|
||||
}
|
||||
if (newIndex >= 0) {
|
||||
return matcherWithIndex.replaceAll(lnClass + newIndex);
|
||||
}
|
||||
|
||||
return doPath;
|
||||
}
|
||||
|
||||
Matcher matcherNoIndex = DO_NO_INDEX_PATTERN.matcher(doPath);
|
||||
if (matcherNoIndex.find()) {
|
||||
String lnClass = matcherNoIndex.group(1);
|
||||
|
||||
int newIndex = determineNewIndex(currentGroup, lnClass,0, indexMapping, name, desc);
|
||||
|
||||
if (newIndex >= 0) {
|
||||
return matcherNoIndex.replaceAll(lnClass + newIndex + "\\$");
|
||||
}
|
||||
}
|
||||
|
||||
return doPath;
|
||||
}
|
||||
|
||||
private int determineNewIndexByName(String currentGroup, String lnClass,
|
||||
IcdToXmlMappingService.IndexMappingConfig indexMapping,
|
||||
String name, String desc) {
|
||||
if (indexMapping == null || name == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
String upperName = name.toUpperCase();
|
||||
String lowerDesc = (desc != null ? desc : "").toLowerCase();
|
||||
|
||||
boolean isMaximum = upperName.startsWith("MAX_");
|
||||
boolean isMinimum = upperName.startsWith("MIN_");
|
||||
boolean is95Percentile = upperName.startsWith("G_");
|
||||
boolean isAverage = !isMaximum && !isMinimum && !is95Percentile;
|
||||
|
||||
// 判断是否为间谐波指标:通过desc是否包含"间谐波"
|
||||
boolean isInterHarmonic = lowerDesc.contains("间谐波");
|
||||
|
||||
if ("MMXU".equals(currentGroup) || "MMXU".equals(lnClass)) {
|
||||
IcdToXmlMappingService.IndexMappingConfig.StatIndex mmxu = indexMapping.getMmxu();
|
||||
if (mmxu != null) {
|
||||
if (isAverage && mmxu.getAverage() != null) return mmxu.getAverage();
|
||||
if (isMaximum && mmxu.getMaximum() != null) return mmxu.getMaximum();
|
||||
if (isMinimum && mmxu.getMinimum() != null) return mmxu.getMinimum();
|
||||
if (is95Percentile && mmxu.getPercentile95() != null) return mmxu.getPercentile95();
|
||||
}
|
||||
}
|
||||
|
||||
if ("INTER_HARMONIC".equals(currentGroup) || isInterHarmonic) {
|
||||
IcdToXmlMappingService.IndexMappingConfig.StatIndex interHarmonic = indexMapping.getInterHarmonic();
|
||||
if (interHarmonic != null) {
|
||||
if (isAverage && interHarmonic.getAverage() != null) return interHarmonic.getAverage();
|
||||
if (isMaximum && interHarmonic.getMaximum() != null) return interHarmonic.getMaximum();
|
||||
if (isMinimum && interHarmonic.getMinimum() != null) return interHarmonic.getMinimum();
|
||||
if (is95Percentile && interHarmonic.getPercentile95() != null) return interHarmonic.getPercentile95();
|
||||
}
|
||||
}
|
||||
|
||||
if ("MHAI".equals(currentGroup) && !isInterHarmonic) {
|
||||
IcdToXmlMappingService.IndexMappingConfig.StatIndex mhai = indexMapping.getMhai();
|
||||
if (mhai != null) {
|
||||
if (isAverage && mhai.getAverage() != null) return mhai.getAverage();
|
||||
if (isMaximum && mhai.getMaximum() != null) return mhai.getMaximum();
|
||||
if (isMinimum && mhai.getMinimum() != null) return mhai.getMinimum();
|
||||
if (is95Percentile && mhai.getPercentile95() != null) return mhai.getPercentile95();
|
||||
}
|
||||
}
|
||||
|
||||
if ("MSQI".equals(currentGroup) || "MSQI".equals(lnClass)) {
|
||||
IcdToXmlMappingService.IndexMappingConfig.StatIndex msqi = indexMapping.getMsqi();
|
||||
if (msqi != null) {
|
||||
if (isAverage && msqi.getAverage() != null) return msqi.getAverage();
|
||||
if (isMaximum && msqi.getMaximum() != null) return msqi.getMaximum();
|
||||
if (isMinimum && msqi.getMinimum() != null) return msqi.getMinimum();
|
||||
if (is95Percentile && msqi.getPercentile95() != null) return msqi.getPercentile95();
|
||||
}
|
||||
}
|
||||
|
||||
if ("MFLK_SHORT".equals(currentGroup) || "MFLK".equals(lnClass)) {
|
||||
if (indexMapping.getMflkShort() != null) {
|
||||
return indexMapping.getMflkShort();
|
||||
}
|
||||
}
|
||||
|
||||
if ("MFLK_LONG".equals(currentGroup)) {
|
||||
if (indexMapping.getMflkLong() != null) {
|
||||
return indexMapping.getMflkLong();
|
||||
}
|
||||
}
|
||||
|
||||
if ("QVVR".equals(currentGroup) || "QVVR".equals(lnClass)) {
|
||||
if (indexMapping.getQvvr() != null) {
|
||||
return indexMapping.getQvvr();
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private int determineNewIndex(String currentGroup, String lnClass, int originalIndex,
|
||||
IcdToXmlMappingService.IndexMappingConfig indexMapping,
|
||||
String name, String desc) {
|
||||
if (indexMapping == null) {
|
||||
return originalIndex;
|
||||
}
|
||||
|
||||
String lowerName = (name != null ? name : "").toLowerCase();
|
||||
String lowerDesc = (desc != null ? desc : "").toLowerCase();
|
||||
|
||||
boolean isAverage = lowerName.contains("avg") || lowerDesc.contains("平均值");
|
||||
boolean isMaximum = lowerName.startsWith("max_") || lowerDesc.contains("最大值");
|
||||
boolean isMinimum = lowerName.startsWith("min_") || lowerDesc.contains("最小值");
|
||||
boolean is95Percentile = lowerName.startsWith("g_") || lowerDesc.contains("95值");
|
||||
|
||||
// 判断是否为间谐波指标
|
||||
boolean isInterHarmonic = lowerDesc.contains("间谐波");
|
||||
|
||||
if ("MMXU".equals(currentGroup) || "MMXU".equals(lnClass)) {
|
||||
IcdToXmlMappingService.IndexMappingConfig.StatIndex mmxu = indexMapping.getMmxu();
|
||||
if (mmxu != null) {
|
||||
if (isAverage && mmxu.getAverage() != null) return mmxu.getAverage();
|
||||
if (isMaximum && mmxu.getMaximum() != null) return mmxu.getMaximum();
|
||||
if (isMinimum && mmxu.getMinimum() != null) return mmxu.getMinimum();
|
||||
if (is95Percentile && mmxu.getPercentile95() != null) return mmxu.getPercentile95();
|
||||
}
|
||||
}
|
||||
|
||||
if ("INTER_HARMONIC".equals(currentGroup) || isInterHarmonic) {
|
||||
IcdToXmlMappingService.IndexMappingConfig.StatIndex interHarmonic = indexMapping.getInterHarmonic();
|
||||
if (interHarmonic != null) {
|
||||
if (isAverage && interHarmonic.getAverage() != null) return interHarmonic.getAverage();
|
||||
if (isMaximum && interHarmonic.getMaximum() != null) return interHarmonic.getMaximum();
|
||||
if (isMinimum && interHarmonic.getMinimum() != null) return interHarmonic.getMinimum();
|
||||
if (is95Percentile && interHarmonic.getPercentile95() != null) return interHarmonic.getPercentile95();
|
||||
}
|
||||
}
|
||||
|
||||
if ("MHAI".equals(currentGroup) && !isInterHarmonic) {
|
||||
IcdToXmlMappingService.IndexMappingConfig.StatIndex mhai = indexMapping.getMhai();
|
||||
if (mhai != null) {
|
||||
if (isAverage && mhai.getAverage() != null) return mhai.getAverage();
|
||||
if (isMaximum && mhai.getMaximum() != null) return mhai.getMaximum();
|
||||
if (isMinimum && mhai.getMinimum() != null) return mhai.getMinimum();
|
||||
if (is95Percentile && mhai.getPercentile95() != null) return mhai.getPercentile95();
|
||||
}
|
||||
}
|
||||
|
||||
if ("MSQI".equals(currentGroup) || "MSQI".equals(lnClass)) {
|
||||
IcdToXmlMappingService.IndexMappingConfig.StatIndex msqi = indexMapping.getMsqi();
|
||||
if (msqi != null) {
|
||||
if (isAverage && msqi.getAverage() != null) return msqi.getAverage();
|
||||
if (isMaximum && msqi.getMaximum() != null) return msqi.getMaximum();
|
||||
if (isMinimum && msqi.getMinimum() != null) return msqi.getMinimum();
|
||||
if (is95Percentile && msqi.getPercentile95() != null) return msqi.getPercentile95();
|
||||
}
|
||||
}
|
||||
|
||||
if ("MFLK_SHORT".equals(currentGroup)) {
|
||||
if (indexMapping.getMflkShort() != null) {
|
||||
return indexMapping.getMflkShort();
|
||||
}
|
||||
}
|
||||
|
||||
if ("MFLK_LONG".equals(currentGroup)) {
|
||||
if (indexMapping.getMflkLong() != null) {
|
||||
return indexMapping.getMflkLong();
|
||||
}
|
||||
}
|
||||
|
||||
if ("QVVR".equals(currentGroup) || "QVVR".equals(lnClass)) {
|
||||
if (indexMapping.getQvvr() != null) {
|
||||
return indexMapping.getQvvr();
|
||||
}
|
||||
}
|
||||
|
||||
return originalIndex;
|
||||
}
|
||||
|
||||
private Map<String, IcdMetricInfo> extractIcdMetrics(IcdDocument icdDocument) {
|
||||
Map<String, IcdMetricInfo> metrics = new HashMap<>();
|
||||
|
||||
if (icdDocument == null || icdDocument.getLogicalNodes() == null) {
|
||||
return metrics;
|
||||
}
|
||||
|
||||
for (LnNode lnNode : icdDocument.getLogicalNodes()) {
|
||||
if (lnNode.getDoiList() == null) continue;
|
||||
|
||||
for (DoiNode doiNode : lnNode.getDoiList()) {
|
||||
String doPath = buildDoPath(lnNode, doiNode);
|
||||
|
||||
List<String> daPaths = collectAllDaPaths(doiNode.getChildren(), new ArrayList<>());
|
||||
for (String daPath : daPaths) {
|
||||
String fullKey = buildMetricKey(doPath, daPath);
|
||||
|
||||
IcdMetricInfo info = new IcdMetricInfo();
|
||||
info.setLnClass(lnNode.getLnClass());
|
||||
info.setLnInst(lnNode.getLnInst());
|
||||
info.setDoName(doiNode.getName());
|
||||
info.setDoPath(doPath);
|
||||
info.setDaPath(daPath);
|
||||
info.setPhase(extractPhase(daPath));
|
||||
info.setType(extractType(daPath));
|
||||
|
||||
metrics.put(fullKey.toLowerCase(), info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return metrics;
|
||||
}
|
||||
|
||||
private List<String> collectAllDaPaths(List<DoiElementNode> nodes, List<String> currentPath) {
|
||||
List<String> results = new ArrayList<>();
|
||||
if (nodes == null) return results;
|
||||
|
||||
for (DoiElementNode node : nodes) {
|
||||
List<String> newPath = new ArrayList<>(currentPath);
|
||||
|
||||
if ("SDI".equalsIgnoreCase(node.getKind())) {
|
||||
if (node.getName() != null && !node.getName().isEmpty()) {
|
||||
String name = node.getName();
|
||||
if (name.startsWith("phs")) {
|
||||
if (name.endsWith("Har")) {
|
||||
newPath.add("phs*Har");
|
||||
} else {
|
||||
newPath.add("phs*");
|
||||
}
|
||||
}
|
||||
else {
|
||||
newPath.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (node.getChildren() != null && !node.getChildren().isEmpty()) {
|
||||
results.addAll(collectAllDaPaths(node.getChildren(), newPath));
|
||||
}
|
||||
} else if ("DAI".equalsIgnoreCase(node.getKind())) {
|
||||
if (node.getName() != null && !node.getName().isEmpty()) {
|
||||
newPath.add(node.getName());
|
||||
}
|
||||
|
||||
if (node.getValues() != null && !node.getValues().isEmpty()) {
|
||||
for (String val : node.getValues()) {
|
||||
if (val != null && !val.isEmpty()) {
|
||||
newPath.add(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
results.add(String.join("$", newPath));
|
||||
|
||||
if (node.getChildren() != null && !node.getChildren().isEmpty()) {
|
||||
results.addAll(collectAllDaPaths(node.getChildren(), newPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private String buildDoPath(LnNode lnNode, DoiNode doiNode) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (lnNode.getLnClass() != null) {
|
||||
sb.append(lnNode.getLnClass());
|
||||
}
|
||||
if (lnNode.getLnInst() != null) {
|
||||
sb.append(lnNode.getLnInst());
|
||||
}
|
||||
if (doiNode.getName() != null) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append("$");
|
||||
sb.append("MX");
|
||||
sb.append("$");
|
||||
}
|
||||
sb.append(doiNode.getName());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String buildMetricKey(String doPath, String daPath) {
|
||||
return doPath + "|" + daPath;
|
||||
}
|
||||
|
||||
private Map<String, ValueRule> findApplicableRules(Map<String, List<ValueRule>> allRules,
|
||||
Map<String, IcdMetricInfo> icdMetrics) {
|
||||
Map<String, ValueRule> applicable = new HashMap<>();
|
||||
|
||||
System.out.println("========== 开始匹配规则 ==========");
|
||||
System.out.println("规则总数: " + allRules.size());
|
||||
System.out.println("ICD指标总数: " + icdMetrics.size());
|
||||
|
||||
int matchedCount = 0;
|
||||
int unmatchedCount = 0;
|
||||
|
||||
for (Map.Entry<String, List<ValueRule>> entry : allRules.entrySet()) {
|
||||
String ruleKey = entry.getKey();
|
||||
List<ValueRule> ruleVariants = entry.getValue();
|
||||
|
||||
boolean foundInIcd = false;
|
||||
ValueRule matchedRule = null;
|
||||
|
||||
System.out.println("\n正在匹配规则: " + ruleKey + " (共" + ruleVariants.size() + "个候选)");
|
||||
|
||||
for (int i = 0; i < ruleVariants.size(); i++) {
|
||||
ValueRule rule = ruleVariants.get(i);
|
||||
if (rule.getDoPath() == null || rule.getDoPath().isEmpty()) {
|
||||
System.out.println(" 候选[" + (i+1) + "] 跳过: DO为空");
|
||||
continue;
|
||||
}
|
||||
|
||||
String ruleDo = normalizePath(rule.getDoPath());
|
||||
String ruleDa = normalizePath(rule.getDaPath());
|
||||
|
||||
System.out.println(" 尝试候选[" + (i+1) + "]: DO=" + rule.getDoPath() + " DA=" + rule.getDaPath());
|
||||
|
||||
for (Map.Entry<String, IcdMetricInfo> icdEntry : icdMetrics.entrySet()) {
|
||||
String icdKey = icdEntry.getKey();
|
||||
IcdMetricInfo icdMetric = icdEntry.getValue();
|
||||
|
||||
String icdDo = normalizePath(icdMetric.getDoPath());
|
||||
String icdDa = normalizePath(icdMetric.getDaPath());
|
||||
|
||||
boolean doMatch = matchesPattern(ruleDo, icdDo);
|
||||
boolean daMatch = matchesPattern(ruleDa, icdDa);
|
||||
|
||||
if (doMatch && daMatch) {
|
||||
System.out.println(" ✓ 匹配成功! ICD Key: " + icdKey);
|
||||
System.out.println(" ICD DO=" + icdMetric.getDoPath() + " DA=" + icdMetric.getDaPath());
|
||||
foundInIcd = true;
|
||||
matchedRule = rule;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundInIcd) {
|
||||
System.out.println(" >> 规则 " + ruleKey + " 匹配成功,使用候选[" + (i+1) + "]");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundInIcd && matchedRule != null) {
|
||||
applicable.put(ruleKey, matchedRule);
|
||||
matchedCount++;
|
||||
} else {
|
||||
unmatchedCount++;
|
||||
if (unmatchedCount <= 15) {
|
||||
System.out.println("✗ 未匹配: " + ruleKey + " (共" + ruleVariants.size() + "个候选)");
|
||||
for (ValueRule rule : ruleVariants) {
|
||||
System.out.println(" 候选: DO=" + rule.getDoPath() + " DA=" + rule.getDaPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("\n========== 规则匹配结束 ==========");
|
||||
System.out.println("匹配成功: " + matchedCount + " 条规则");
|
||||
System.out.println("未匹配: " + unmatchedCount + " 条规则");
|
||||
|
||||
return applicable;
|
||||
}
|
||||
|
||||
private String normalizePath(String path) {
|
||||
if (path == null) return "";
|
||||
return path.trim().toLowerCase();
|
||||
}
|
||||
|
||||
private String fillIedInfo(String xmlContent, IcdDocument icdDocument) {
|
||||
if (icdDocument == null) {
|
||||
return xmlContent;
|
||||
}
|
||||
|
||||
String iedName = icdDocument.getIedName();
|
||||
String ldPrefix = icdDocument.getLdPrefix();
|
||||
|
||||
if (iedName != null && !iedName.isEmpty()) {
|
||||
// 替换 <IED name="..." .../>
|
||||
xmlContent = xmlContent.replaceAll(
|
||||
"<IED\\s+name=\"[^\"]*\"",
|
||||
"<IED name=\"" + escapeXml(iedName) + "\""
|
||||
);
|
||||
}
|
||||
|
||||
if (ldPrefix != null && !ldPrefix.isEmpty()) {
|
||||
// 替换 <LDevice Prefix="..." .../>
|
||||
xmlContent = xmlContent.replaceAll(
|
||||
"<LDevice\\s+Prefix=\"[^\"]*\"",
|
||||
"<LDevice Prefix=\"" + escapeXml(ldPrefix) + "\""
|
||||
);
|
||||
}
|
||||
|
||||
return xmlContent;
|
||||
}
|
||||
|
||||
private String fillReportControls(String xmlContent, IcdDocument icdDocument) {
|
||||
if (icdDocument == null || icdDocument.getReportControls() == null || icdDocument.getReportControls().isEmpty()) {
|
||||
return xmlContent;
|
||||
}
|
||||
|
||||
// 构建 ReportStat 内容
|
||||
StringBuilder reportStatBuilder = new StringBuilder();
|
||||
reportStatBuilder.append("\t\t<ReportStat>\n");
|
||||
|
||||
for (ReportControlNode rc : icdDocument.getReportControls()) {
|
||||
if (rc.getName() != null && !rc.getName().isEmpty()) {
|
||||
String name = rc.getName();
|
||||
// 只处理特定的 ReportControl 名称
|
||||
if (name.contains("brcbFluc") ||
|
||||
name.contains("brcbStHarm") ||
|
||||
name.contains("brcbStIHarm") ||
|
||||
name.contains("brcbStMMXU") ||
|
||||
name.contains("brcbStMSQI") ||
|
||||
name.contains("brcbPLT")||
|
||||
name.contains("brcbPST")||
|
||||
name.contains("brcbFlicker")||
|
||||
name.contains("brcbStatistic") ){
|
||||
// 构建 ReportControl 字符串格式:
|
||||
// LLN0$BR$brcbFlickerData,600,0,0,1,0,0,yes,1,1,1,1,1,0,1,1,1,3,1
|
||||
String reportControlStr = buildReportControlString(rc);
|
||||
reportStatBuilder.append("\t\t\t<Report ReportControl=\"")
|
||||
.append(escapeXml(reportControlStr))
|
||||
.append("\" />\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
reportStatBuilder.append("\t\t</ReportStat>");
|
||||
|
||||
// 替换原有的 <ReportStat>...</ReportStat> 部分
|
||||
xmlContent = xmlContent.replaceAll(
|
||||
"<ReportStat>[\\s\\S]*?</ReportStat>",
|
||||
reportStatBuilder.toString().replace("$", "\\$").replace("[", "\\[").replace("]", "\\]")
|
||||
);
|
||||
|
||||
return xmlContent;
|
||||
}
|
||||
|
||||
private String buildReportControlString(ReportControlNode rc) {
|
||||
// 格式:LLN0$BR$brcbName,intgPd,dchg,qchg,dupd,period,gi,issuffixed,seqNum,timeStamp,reasonCode,dataSet,dataRef,bufOvfl,entryID,configRef,segmentation,FlickerFlag
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
// ReportControl 名称(需要根据实际情况调整前缀)
|
||||
sb.append("LLN0$").append(rc.getBuffered() != null && rc.getBuffered() ? "BR$" : "RP$").append(rc.getName());
|
||||
// 这里需要根据实际 ICD 中的配置来填充其他字段
|
||||
// 目前使用默认值,后续可以根据 ReportControlNode 的字段扩展
|
||||
if(rc.getName().contains("PLT") || rc.getName().contains("Flicker") || rc.getName().contains("PST") || rc.getName().contains("Fluc")){
|
||||
sb.append(",600"); // intgPd - 上送周期
|
||||
}else{
|
||||
sb.append(",60"); // intgPd - 上送周期
|
||||
}
|
||||
sb.append(",1"); // dchg - 数据变化触发
|
||||
sb.append(",0"); // qchg - 品质变化触发
|
||||
sb.append(",0"); // dupd - 数据更新触发
|
||||
sb.append(",0"); // period - 周期触发
|
||||
sb.append(",0"); // gi - 总召唤
|
||||
sb.append(",yes"); // issuffixed
|
||||
sb.append(",1"); // seqNum
|
||||
sb.append(",1"); // timeStamp
|
||||
sb.append(",1"); // reasonCode
|
||||
sb.append(",1"); // dataSet
|
||||
sb.append(",1"); // dataRef
|
||||
sb.append(",0"); // bufOvfl
|
||||
sb.append(",1"); // entryID
|
||||
sb.append(",1"); // configRef
|
||||
sb.append(",1"); // segmentation
|
||||
sb.append(",3"); // 保留字段
|
||||
if(rc.getName().contains("PLT") || rc.getName().contains("Flicker")){
|
||||
sb.append(",1"); // FlickerFlag
|
||||
}else if(rc.getName().contains("PST") || rc.getName().contains("Fluc")){
|
||||
sb.append(",2"); // FlickerFlag
|
||||
} else {
|
||||
sb.append(",0"); // FlickerFlag
|
||||
}
|
||||
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private boolean matchesPattern(String pattern, String actual) {
|
||||
if (pattern == null || actual == null) {
|
||||
return pattern == null && actual == null;
|
||||
}
|
||||
|
||||
String normalizedPattern = pattern.replaceAll("\\[[^\\]]*\\]", "");
|
||||
|
||||
|
||||
if (normalizedPattern.isEmpty() || actual.isEmpty()) {
|
||||
return normalizedPattern.isEmpty() && actual.isEmpty();
|
||||
}
|
||||
|
||||
return actual.equals(normalizedPattern);
|
||||
}
|
||||
|
||||
private String applyRulesToXml(String xmlContent, Map<String, ValueRule> applicableRules) {
|
||||
Matcher matcher = XML_VALUE_PATTERN.matcher(xmlContent);
|
||||
StringBuffer result = new StringBuffer();
|
||||
|
||||
while (matcher.find()) {
|
||||
String name = matcher.group(1);
|
||||
String desc = matcher.group(2);
|
||||
String type = matcher.group(3);
|
||||
|
||||
String key = buildRuleKey(name, desc);
|
||||
ValueRule matchedRule = applicableRules.get(key.toLowerCase());
|
||||
|
||||
if (matchedRule != null) {
|
||||
StringBuilder valueNode = new StringBuilder("<Value ");
|
||||
valueNode.append("name=\"").append(escapeXml(name)).append("\" ");
|
||||
valueNode.append("desc=\"").append(escapeXml(desc)).append("\" ");
|
||||
valueNode.append("type=\"").append(type).append("\" ");
|
||||
|
||||
if ((matchedRule.getDoPath() != null) && !matchedRule.getDoPath().isEmpty()) {
|
||||
valueNode.append("DO=\"").append(escapeXml(matchedRule.getDoPath())).append("\" ");
|
||||
}
|
||||
if (matchedRule.getDaPath() != null && !matchedRule.getDaPath().isEmpty()) {
|
||||
valueNode.append("DA=\"").append(escapeXml(matchedRule.getDaPath())).append("\" ");
|
||||
}
|
||||
if (matchedRule.getBaseFlag() != null && !matchedRule.getBaseFlag().isEmpty()) {
|
||||
valueNode.append("BaseFlag=\"").append(escapeXml(matchedRule.getBaseFlag())).append("\" ");
|
||||
}
|
||||
if (matchedRule.getLimitUp() != null && !matchedRule.getLimitUp().isEmpty()) {
|
||||
valueNode.append("LimitUp=\"").append(escapeXml(matchedRule.getLimitUp())).append("\" ");
|
||||
}
|
||||
if (matchedRule.getLimitDown() != null && !matchedRule.getLimitDown().isEmpty()) {
|
||||
valueNode.append("LimitDown=\"").append(escapeXml(matchedRule.getLimitDown())).append("\" ");
|
||||
}
|
||||
if (matchedRule.getCoefficient() != null && !matchedRule.getCoefficient().isEmpty()) {
|
||||
valueNode.append("Coefficient=\"").append(escapeXml(matchedRule.getCoefficient())).append("\" ");
|
||||
}
|
||||
|
||||
valueNode.append("/>");
|
||||
matcher.appendReplacement(result, Matcher.quoteReplacement(valueNode.toString()));
|
||||
}
|
||||
}
|
||||
matcher.appendTail(result);
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private String buildRuleKey(String name, String desc) {
|
||||
if (name != null && !name.isEmpty()) {
|
||||
return name;
|
||||
}
|
||||
return desc != null ? desc : "";
|
||||
}
|
||||
|
||||
private boolean hasValidDoOrDa(ValueRule rule) {
|
||||
return (rule.getDoPath() != null && !rule.getDoPath().isEmpty()) ||
|
||||
(rule.getDaPath() != null && !rule.getDaPath().isEmpty());
|
||||
}
|
||||
|
||||
private String extractPhase(String daPath) {
|
||||
if (daPath == null) return "";
|
||||
if (daPath.contains("phsA")) return "A";
|
||||
if (daPath.contains("phsB")) return "B";
|
||||
if (daPath.contains("phsC")) return "C";
|
||||
if (daPath.contains("c1")) return "正序";
|
||||
if (daPath.contains("c2")) return "负序";
|
||||
if (daPath.contains("c3")) return "零序";
|
||||
return "无相别";
|
||||
}
|
||||
|
||||
private String extractType(String daPath) {
|
||||
if (daPath == null) return "";
|
||||
if (daPath.contains("mag")) return "mag";
|
||||
if (daPath.contains("ang")) return "ang";
|
||||
return "";
|
||||
}
|
||||
|
||||
private String escapeXml(String text) {
|
||||
if (text == null) return "";
|
||||
return text.replace("&", "&")
|
||||
.replace("<", "<")
|
||||
.replace(">", ">")
|
||||
.replace("\"", """)
|
||||
.replace("'", "'");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static class ValueRule {
|
||||
private String name;
|
||||
private String desc;
|
||||
private String type;
|
||||
private String doPath;
|
||||
private String daPath;
|
||||
private String baseFlag;
|
||||
private String limitUp;
|
||||
private String limitDown;
|
||||
private String coefficient;
|
||||
|
||||
public String getName() { return name; }
|
||||
public void setName(String name) { this.name = name; }
|
||||
public String getDesc() { return desc; }
|
||||
public void setDesc(String desc) { this.desc = desc; }
|
||||
public String getType() { return type; }
|
||||
public void setType(String type) { this.type = type; }
|
||||
public String getDoPath() { return doPath; }
|
||||
public void setDoPath(String doPath) { this.doPath = doPath; }
|
||||
public String getDaPath() { return daPath; }
|
||||
public void setDaPath(String daPath) { this.daPath = daPath; }
|
||||
public String getBaseFlag() { return baseFlag; }
|
||||
public void setBaseFlag(String baseFlag) { this.baseFlag = baseFlag; }
|
||||
public String getLimitUp() { return limitUp; }
|
||||
public void setLimitUp(String limitUp) { this.limitUp = limitUp; }
|
||||
public String getLimitDown() { return limitDown; }
|
||||
public void setLimitDown(String limitDown) { this.limitDown = limitDown; }
|
||||
public String getCoefficient() { return coefficient; }
|
||||
public void setCoefficient(String coefficient) { this.coefficient = coefficient; }
|
||||
}
|
||||
|
||||
static class IcdMetricInfo {
|
||||
private String lnClass;
|
||||
private String lnInst;
|
||||
private String doName;
|
||||
private String doPath;
|
||||
private String daPath;
|
||||
private String phase;
|
||||
private String type;
|
||||
|
||||
public String getLnClass() { return lnClass; }
|
||||
public void setLnClass(String lnClass) { this.lnClass = lnClass; }
|
||||
public String getLnInst() { return lnInst; }
|
||||
public void setLnInst(String lnInst) { this.lnInst = lnInst; }
|
||||
public String getDoName() { return doName; }
|
||||
public void setDoName(String doName) { this.doName = doName; }
|
||||
public String getDoPath() { return doPath; }
|
||||
public void setDoPath(String doPath) { this.doPath = doPath; }
|
||||
public String getDaPath() { return daPath; }
|
||||
public void setDaPath(String daPath) { this.daPath = daPath; }
|
||||
public String getPhase() { return phase; }
|
||||
public void setPhase(String phase) { this.phase = phase; }
|
||||
public String getType() { return type; }
|
||||
public void setType(String type) { this.type = type; }
|
||||
}
|
||||
}
|
||||
@@ -3,14 +3,22 @@ package com.njcn.gather.icd.mapping.controller;
|
||||
import com.njcn.common.pojo.annotation.OperateInfo;
|
||||
import com.njcn.common.pojo.enums.common.LogEnum;
|
||||
import com.njcn.common.utils.LogUtil;
|
||||
import com.njcn.gather.icd.mapping.component.IcdToXmlRequestConverter;
|
||||
import com.njcn.gather.icd.mapping.component.IcdToXmlResponseConverter;
|
||||
import com.njcn.gather.icd.mapping.component.MappingRequestConverter;
|
||||
import com.njcn.gather.icd.mapping.component.MappingResponseConverter;
|
||||
import com.njcn.gather.icd.mapping.pojo.bo.GenerateMappingResult;
|
||||
import com.njcn.gather.icd.mapping.pojo.bo.IcdToXmlGenerateResult;
|
||||
import com.njcn.gather.icd.mapping.pojo.dto.GenerateFromIcdCommand;
|
||||
import com.njcn.gather.icd.mapping.pojo.dto.IcdToXmlGenerateCommand;
|
||||
import com.njcn.gather.icd.mapping.pojo.param.GenerateMappingFromIcdRequest;
|
||||
import com.njcn.gather.icd.mapping.pojo.param.IcdToXmlGenerateRequest;
|
||||
import com.njcn.gather.icd.mapping.pojo.param.JsonToXmlRequest;
|
||||
import com.njcn.gather.icd.mapping.pojo.param.SubmitIndexSelectionRequest;
|
||||
import com.njcn.gather.icd.mapping.pojo.vo.IcdToXmlResponse;
|
||||
import com.njcn.gather.icd.mapping.pojo.vo.MappingTaskResponse;
|
||||
import com.njcn.gather.icd.mapping.service.MappingTaskService;
|
||||
import com.njcn.gather.icd.mapping.service.impl.IcdToXmlTaskAppService;
|
||||
import com.njcn.gather.icd.mapping.utils.DateUtils;
|
||||
import com.njcn.web.controller.BaseController;
|
||||
import io.swagger.annotations.Api;
|
||||
@@ -44,6 +52,15 @@ public class MappingController extends BaseController {
|
||||
/** 响应转换器,按接口阶段裁剪最小返回字段。 */
|
||||
private final MappingResponseConverter responseConverter;
|
||||
|
||||
/** 请求参数转换器,将接口入参转换为应用层命令。 */
|
||||
private final IcdToXmlResponseConverter icdResponseConverter;
|
||||
|
||||
/** 响应转换器,按接口阶段裁剪最小返回字段。 */
|
||||
private final IcdToXmlRequestConverter icdRequestConverter;
|
||||
|
||||
/** 响应转换器,按接口阶段裁剪最小返回字段。 */
|
||||
private final IcdToXmlTaskAppService icdToXmlTaskAppService;
|
||||
|
||||
/**
|
||||
* 上传 ICD 文件,返回候选结果和可编辑的 ICD 解析结果。
|
||||
*/
|
||||
@@ -89,4 +106,27 @@ public class MappingController extends BaseController {
|
||||
GenerateMappingResult result = mappingTaskService.getIcdMmsJson(command);
|
||||
return responseConverter.fromSubmitResult(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接将 MMS JSON 转换为 XML 文件。
|
||||
* 适用于已经通过 getIcdMmsJson 获得 JSON 后,单独进行 XML 转换的场景。
|
||||
*/
|
||||
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
||||
@ApiOperation("MMS JSON 转 XML")
|
||||
@PostMapping("/get-xml-from-json")
|
||||
public IcdToXmlResponse getXmlFromJson(@Validated @RequestPart("request") JsonToXmlRequest request) {
|
||||
String methodDescribe = getMethodDescribe("getXmlFromJson");
|
||||
LogUtil.njcnDebug(log, "{},开始将 MMS JSON 转换为 XML", methodDescribe);
|
||||
|
||||
// // 将请求参数转换为 Command
|
||||
// IcdToXmlGenerateCommand command =
|
||||
// icdRequestConverter.toCommand(request);
|
||||
//
|
||||
// 调用服务生成 XML
|
||||
IcdToXmlGenerateResult result =
|
||||
icdToXmlTaskAppService.generateXmlFromJson(request.getMappingJson());
|
||||
|
||||
return icdResponseConverter.fromResult(result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.njcn.gather.icd.mapping.pojo.bo;
|
||||
|
||||
import com.njcn.gather.icd.mapping.pojo.bo.analysis.IndexAnalysis;
|
||||
import com.njcn.gather.icd.mapping.pojo.bo.mapping.MappingDocument;
|
||||
import com.njcn.gather.icd.mapping.pojo.enums.GenerateStatus;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class IcdToXmlGenerateResult {
|
||||
private GenerateStatus status;
|
||||
private String message;
|
||||
private String iedName;
|
||||
private String ldInst;
|
||||
private IndexAnalysis indexAnalysis;
|
||||
private MappingDocument mappingDocument;
|
||||
private String savedPath;
|
||||
private List<String> problems = new ArrayList<String>();
|
||||
|
||||
public GenerateStatus getStatus() { return status; }
|
||||
public void setStatus(GenerateStatus status) { this.status = status; }
|
||||
public String getMessage() { return message; }
|
||||
public void setMessage(String message) { this.message = message; }
|
||||
public String getIedName() { return iedName; }
|
||||
public void setIedName(String iedName) { this.iedName = iedName; }
|
||||
public String getLdInst() { return ldInst; }
|
||||
public void setLdInst(String ldInst) { this.ldInst = ldInst; }
|
||||
public IndexAnalysis getIndexAnalysis() { return indexAnalysis; }
|
||||
public void setIndexAnalysis(IndexAnalysis indexAnalysis) { this.indexAnalysis = indexAnalysis; }
|
||||
public MappingDocument getMappingDocument() { return mappingDocument; }
|
||||
public void setMappingDocument(MappingDocument mappingDocument) { this.mappingDocument = mappingDocument; }
|
||||
public String getSavedPath() { return savedPath; }
|
||||
public void setSavedPath(String savedPath) { this.savedPath = savedPath; }
|
||||
public List<String> getProblems() { return problems; }
|
||||
public void setProblems(List<String> problems) { this.problems = problems; }
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.njcn.gather.icd.mapping.pojo.dto;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class IcdToXmlGenerateCommand {
|
||||
/** 原始文件名。 */
|
||||
private String fileName;
|
||||
|
||||
/** ICD 文件字节数组。 */
|
||||
private byte[] fileBytes;
|
||||
|
||||
/** 输出版本号。 */
|
||||
private String version;
|
||||
|
||||
/** 作者。 */
|
||||
private String author;
|
||||
|
||||
/** 是否保存到磁盘。 */
|
||||
private boolean saveToDisk;
|
||||
|
||||
|
||||
|
||||
/** 输出目录。 */
|
||||
private String outputDir;
|
||||
|
||||
/** 用户上送的索引选择结果。 */
|
||||
private List<IndexSelectionGroupCommand> indexSelection = new ArrayList<IndexSelectionGroupCommand>();
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
public byte[] getFileBytes() {
|
||||
return fileBytes;
|
||||
}
|
||||
|
||||
public void setFileBytes(byte[] fileBytes) {
|
||||
this.fileBytes = fileBytes;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
public boolean isSaveToDisk() {
|
||||
return saveToDisk;
|
||||
}
|
||||
|
||||
public void setSaveToDisk(boolean saveToDisk) {
|
||||
this.saveToDisk = saveToDisk;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getOutputDir() {
|
||||
return outputDir;
|
||||
}
|
||||
|
||||
public void setOutputDir(String outputDir) {
|
||||
this.outputDir = outputDir;
|
||||
}
|
||||
|
||||
public List<IndexSelectionGroupCommand> getIndexSelection() {
|
||||
return indexSelection;
|
||||
}
|
||||
|
||||
public void setIndexSelection(List<IndexSelectionGroupCommand> indexSelection) {
|
||||
this.indexSelection = indexSelection;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.njcn.gather.icd.mapping.pojo.param;
|
||||
|
||||
import lombok.Data;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class IcdToXmlGenerateRequest {
|
||||
/** 输出版本号。为空时后端默认补 1.0。 */
|
||||
private String version;
|
||||
|
||||
/** 作者。为空时默认空字符串。 */
|
||||
private String author;
|
||||
|
||||
/** 是否保存到磁盘。 */
|
||||
private boolean saveToDisk;
|
||||
|
||||
/** 输出目录。saveToDisk=true 时才会用到。 */
|
||||
private String outputDir;
|
||||
|
||||
|
||||
/**
|
||||
* 索引选择结果。
|
||||
*
|
||||
* 说明:
|
||||
* 1. 每一个元素代表一个“业务分组”,例如:实时数据、统计数据、波动闪变。
|
||||
* 2. 每个业务分组下面又包含多条绑定关系。
|
||||
* 3. 允许为空;为空时后端返回 NEED_INDEX_SELECTION,给前端候选参考项。
|
||||
*/
|
||||
private List<IndexSelectionGroupRequest> indexSelection = new ArrayList<IndexSelectionGroupRequest>();
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
public boolean isSaveToDisk() {
|
||||
return saveToDisk;
|
||||
}
|
||||
|
||||
public void setSaveToDisk(boolean saveToDisk) {
|
||||
this.saveToDisk = saveToDisk;
|
||||
}
|
||||
|
||||
public String getOutputDir() {
|
||||
return outputDir;
|
||||
}
|
||||
|
||||
public void setOutputDir(String outputDir) {
|
||||
this.outputDir = outputDir;
|
||||
}
|
||||
|
||||
public List<IndexSelectionGroupRequest> getIndexSelection() {
|
||||
return indexSelection;
|
||||
}
|
||||
|
||||
public void setIndexSelection(List<IndexSelectionGroupRequest> indexSelection) {
|
||||
this.indexSelection = indexSelection;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.njcn.gather.icd.mapping.pojo.param;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* JSON 转 XML 请求参数。
|
||||
*/
|
||||
public class JsonToXmlRequest {
|
||||
|
||||
/**
|
||||
* MMS 映射 JSON 字符串。
|
||||
* 由 getIcdMmsJson 接口返回的 mappingJson 字段提供。
|
||||
*/
|
||||
private String mappingJson;
|
||||
|
||||
/**
|
||||
* 索引选择结果(用于重建索引映射配置)。
|
||||
* 如果提供了 indexSelection,则会重新构建索引映射;
|
||||
* 如果为空,则使用默认的索引映射配置。
|
||||
*/
|
||||
|
||||
|
||||
public String getMappingJson() {
|
||||
return mappingJson;
|
||||
}
|
||||
|
||||
public void setMappingJson(String mappingJson) {
|
||||
this.mappingJson = mappingJson;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.njcn.gather.icd.mapping.pojo.vo;
|
||||
|
||||
|
||||
import com.njcn.gather.icd.mapping.pojo.enums.GenerateStatus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
// 手动写getter/setter,避免Lombok依赖问题
|
||||
public class IcdToXmlResponse {
|
||||
private GenerateStatus status;
|
||||
private String message;
|
||||
private String iedName;
|
||||
private String ldInst;
|
||||
private String savedPath;
|
||||
private MappingDocumentResponse mappingDocument;
|
||||
private List<IndexCandidateResponse> indexCandidates = new ArrayList<IndexCandidateResponse>();
|
||||
private List<String> problems = new ArrayList<String>();
|
||||
public GenerateStatus getStatus() { return status; }
|
||||
public void setStatus(GenerateStatus status) { this.status = status; }
|
||||
public String getMessage() { return message; }
|
||||
public void setMessage(String message) { this.message = message; }
|
||||
public String getIedName() { return iedName; }
|
||||
public void setIedName(String iedName) { this.iedName = iedName; }
|
||||
public String getLdInst() { return ldInst; }
|
||||
public void setLdInst(String ldInst) { this.ldInst = ldInst; }
|
||||
|
||||
public String getSavedPath() { return savedPath; }
|
||||
public void setSavedPath(String savedPath) { this.savedPath = savedPath; }
|
||||
public MappingDocumentResponse getMappingDocument() { return mappingDocument; }
|
||||
public void setMappingDocument(MappingDocumentResponse mappingDocument) { this.mappingDocument = mappingDocument; }
|
||||
public List<IndexCandidateResponse> getIndexCandidates() { return indexCandidates; }
|
||||
public void setIndexCandidates(List<IndexCandidateResponse> indexCandidates) { this.indexCandidates = indexCandidates; }
|
||||
public List<String> getProblems() { return problems; }
|
||||
public void setProblems(List<String> problems) { this.problems = problems; }
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
package com.njcn.gather.icd.mapping.service.impl;
|
||||
|
||||
|
||||
import com.njcn.gather.icd.mapping.component.*;
|
||||
import com.njcn.gather.icd.mapping.pojo.bo.IcdToXmlGenerateResult;
|
||||
import com.njcn.gather.icd.mapping.pojo.bo.analysis.IndexAnalysis;
|
||||
import com.njcn.gather.icd.mapping.pojo.bo.analysis.ValidationResult;
|
||||
import com.njcn.gather.icd.mapping.pojo.bo.icd.IcdDocument;
|
||||
import com.njcn.gather.icd.mapping.pojo.bo.mapping.MappingDocument;
|
||||
import com.njcn.gather.icd.mapping.pojo.bo.template.DefaultTemplate;
|
||||
import com.njcn.gather.icd.mapping.pojo.dto.IcdToXmlGenerateCommand;
|
||||
import com.njcn.gather.icd.mapping.pojo.enums.GenerateStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class IcdToXmlTaskAppService {
|
||||
private final IcdParserService icdParserService;
|
||||
private final DefaultTemplateLoader defaultTemplateLoader;
|
||||
private final IndexAnalysisService indexAnalysisService;
|
||||
private final IndexValidationService indexValidationService;
|
||||
private final MappingGenerationService mappingGenerationService;
|
||||
private final RuleBasedXmlMappingService ruleBasedXmlMappingService;
|
||||
private final MappingDocumentSerializer mappingDocumentSerializer;
|
||||
private final FileStorageService fileStorageService;
|
||||
private final IcdToXmlMappingService icdToXmlMappingService;
|
||||
private final JsonToXmlConversionService jsonToXmlConversionService;
|
||||
|
||||
public IcdToXmlTaskAppService(IcdParserService icdParserService,
|
||||
DefaultTemplateLoader defaultTemplateLoader,
|
||||
IndexAnalysisService indexAnalysisService,
|
||||
IndexValidationService indexValidationService,
|
||||
MappingGenerationService mappingGenerationService,
|
||||
RuleBasedXmlMappingService ruleBasedXmlMappingService,
|
||||
MappingDocumentSerializer mappingDocumentSerializer,
|
||||
FileStorageService fileStorageService,
|
||||
IcdToXmlMappingService icdToXmlMappingService,
|
||||
JsonToXmlConversionService jsonToXmlConversionService) {
|
||||
this.icdParserService = icdParserService;
|
||||
this.defaultTemplateLoader = defaultTemplateLoader;
|
||||
this.indexAnalysisService = indexAnalysisService;
|
||||
this.indexValidationService = indexValidationService;
|
||||
this.mappingGenerationService = mappingGenerationService;
|
||||
this.ruleBasedXmlMappingService = ruleBasedXmlMappingService;
|
||||
this.mappingDocumentSerializer = mappingDocumentSerializer;
|
||||
this.fileStorageService = fileStorageService;
|
||||
this.icdToXmlMappingService = icdToXmlMappingService;
|
||||
this.jsonToXmlConversionService = jsonToXmlConversionService;
|
||||
}
|
||||
|
||||
public IcdToXmlGenerateResult generateFromIcd(IcdToXmlGenerateCommand command) {
|
||||
IcdToXmlGenerateResult result = new IcdToXmlGenerateResult();
|
||||
try {
|
||||
// ========== 第一步:ICD → JSON ==========
|
||||
|
||||
// 1. 解析 ICD
|
||||
IcdDocument icdDocument = icdParserService.parse(command.getFileBytes(), command.getFileName());
|
||||
result.setIedName(icdDocument.getIedName());
|
||||
result.setLdInst(icdDocument.getLdInst());
|
||||
|
||||
// 2. 加载 DefaultCfg.txt和默认配置
|
||||
//DefaultTemplate template = defaultTemplateLoader.loadDefaultTemplateToXml();
|
||||
DefaultTemplate template = defaultTemplateLoader.load();
|
||||
result.getProblems().addAll(template.verify());
|
||||
|
||||
InputStream templateStream = ruleBasedXmlMappingService.loadDefaultXmlFile();
|
||||
if(templateStream==null){result.getProblems().add("缺少默认xml配置文件");}
|
||||
List<InputStream> ruleStreams = ruleBasedXmlMappingService.loadDefaultRuleFile();
|
||||
if(ruleStreams==null){result.getProblems().add("缺少默认规则配置文件");}
|
||||
|
||||
|
||||
// 3. 分析索引候选
|
||||
IndexAnalysis indexAnalysis = indexAnalysisService.analyze(icdDocument, template);
|
||||
result.setIndexAnalysis(indexAnalysis);
|
||||
result.getProblems().addAll(indexAnalysis.getProblems());
|
||||
|
||||
// 4. 如果没有提交任何绑定关系,则直接返回待匹配项
|
||||
if (command.getIndexSelection() == null || command.getIndexSelection().isEmpty()) {
|
||||
result.setStatus(GenerateStatus.NEED_INDEX_SELECTION);
|
||||
result.setMessage("索引配置缺失或不合法,请根据候选信息完成标签与数字索引的绑定后重新提交");
|
||||
return result;
|
||||
}
|
||||
|
||||
// 5. 校验用户提交的绑定关系
|
||||
ValidationResult validationResult = indexValidationService.validate(indexAnalysis, command.getIndexSelection());
|
||||
if (!validationResult.isValid()) {
|
||||
result.setStatus(GenerateStatus.NEED_INDEX_SELECTION);
|
||||
result.setMessage("索引配置缺失或不合法,请根据候选信息完成标签与数字索引的绑定后重新提交");
|
||||
result.getProblems().addAll(validationResult.getProblems());
|
||||
return result;
|
||||
}
|
||||
|
||||
// 6. 生成正式映射结构(JSON中间态)
|
||||
MappingDocument mappingDocument = mappingGenerationService.generate(
|
||||
icdDocument,
|
||||
template,
|
||||
indexAnalysis,
|
||||
command.getIndexSelection(),
|
||||
command.getVersion(),
|
||||
command.getAuthor()
|
||||
);
|
||||
result.setMappingDocument(mappingDocument);
|
||||
|
||||
// 7. 序列化为JSON字符串(中间产物)
|
||||
String mappingJson = mappingDocumentSerializer.toPrettyJson(mappingDocument);
|
||||
|
||||
// ========== 第二步:JSON → XML ==========
|
||||
|
||||
// 8. 重新绑定正确索引
|
||||
IcdToXmlMappingService.IndexMappingConfig mappingConfig = icdToXmlMappingService.buildIndexMappingFromSelection(command.getIndexSelection());
|
||||
icdToXmlMappingService.setIndexMapping(mappingConfig);
|
||||
|
||||
// 9. 从JSON转换为XML
|
||||
String xmlPath = jsonToXmlConversionService.convertFromJson(
|
||||
mappingJson,
|
||||
templateStream,
|
||||
ruleStreams,
|
||||
icdToXmlMappingService.getIndexMapping()
|
||||
);
|
||||
result.setSavedPath(xmlPath);
|
||||
|
||||
result.setStatus(GenerateStatus.SUCCESS);
|
||||
result.setMessage("映射生成成功");
|
||||
return result;
|
||||
} catch (Exception ex) {
|
||||
result.setStatus(GenerateStatus.FAILED);
|
||||
result.setMessage("映射生成失败:" + ex.getMessage());
|
||||
result.getProblems().add(ex.getMessage());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接从 JSON 字符串生成 XML 文件。
|
||||
*
|
||||
* @param mappingJson MMS 映射 JSON 字符串(由 getIcdMmsJson 接口返回)
|
||||
* @return XML 生成结果
|
||||
*/
|
||||
public IcdToXmlGenerateResult generateXmlFromJson(String mappingJson){
|
||||
IcdToXmlGenerateResult result = new IcdToXmlGenerateResult();
|
||||
try {
|
||||
// 1. 加载模板和规则文件
|
||||
InputStream templateStream = ruleBasedXmlMappingService.loadDefaultXmlFile();
|
||||
if (templateStream == null) {
|
||||
result.setStatus(GenerateStatus.FAILED);
|
||||
result.getProblems().add("缺少默认xml配置文件");
|
||||
result.setMessage("XML 生成失败:缺少默认xml配置文件");
|
||||
return result;
|
||||
}
|
||||
|
||||
List<InputStream> ruleStreams = ruleBasedXmlMappingService.loadDefaultRuleFile();
|
||||
if (ruleStreams == null) {
|
||||
result.setStatus(GenerateStatus.FAILED);
|
||||
result.getProblems().add("缺少默认规则配置文件");
|
||||
result.setMessage("XML 生成失败:缺少默认规则配置文件");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// 3. 从 JSON 转换为 XML
|
||||
String xmlPath = jsonToXmlConversionService.convertFromJson(
|
||||
mappingJson,
|
||||
templateStream,
|
||||
ruleStreams,
|
||||
icdToXmlMappingService.getIndexMapping()
|
||||
);
|
||||
|
||||
result.setSavedPath(xmlPath);
|
||||
result.setStatus(GenerateStatus.SUCCESS);
|
||||
result.setMessage("XML 生成成功");
|
||||
return result;
|
||||
} catch (Exception ex) {
|
||||
result.setStatus(GenerateStatus.FAILED);
|
||||
result.setMessage("XML 生成失败:" + ex.getMessage());
|
||||
result.getProblems().add(ex.getMessage());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.njcn.gather.icd.mapping.utils;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class XmlTemplateParser {
|
||||
|
||||
/**
|
||||
* 读取XML模板为原始字符串(100%保留所有换行、空格、注释、空属性)
|
||||
*/
|
||||
public ParseResult parse(InputStream inputStream) throws Exception {
|
||||
StringBuilder template = new StringBuilder();
|
||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
template.append(line).append("\n"); // 保留原始换行
|
||||
}
|
||||
}
|
||||
Map<String, String> baseParams = new HashMap<>();
|
||||
return new ParseResult(template.toString(), baseParams);
|
||||
}
|
||||
|
||||
public static class ParseResult {
|
||||
private final String templateContent;
|
||||
private final Map<String, String> baseParams;
|
||||
|
||||
public ParseResult(String templateContent, Map<String, String> baseParams) {
|
||||
this.templateContent = templateContent;
|
||||
this.baseParams = baseParams;
|
||||
}
|
||||
|
||||
public String getTemplateContent() { return templateContent; }
|
||||
public Map<String, String> getBaseParams() { return baseParams; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,723 @@
|
||||
{
|
||||
"ReportList": [
|
||||
{
|
||||
"desc": "统计数据",
|
||||
"inst": "01",
|
||||
"TrgOps": "96",
|
||||
"Select": "DataStatFileMap",
|
||||
"DataSetList": [
|
||||
"dsStatisticData",
|
||||
"dsStHarm",
|
||||
"dsStIHarm",
|
||||
"dsStMMXU",
|
||||
"dsStMSQI",
|
||||
],
|
||||
"LnInstList": [
|
||||
"最大值",
|
||||
"最小值",
|
||||
"平均值",
|
||||
"95值",
|
||||
"间谐波最大值",
|
||||
"间谐波最小值",
|
||||
"间谐波平均值",
|
||||
"间谐波95值",
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "波动闪变",
|
||||
"inst": "01",
|
||||
"TrgOps": "96",
|
||||
"Select": "FlickerFileMap",
|
||||
"DataSetList": [
|
||||
"dsFlickerData",
|
||||
"dsPST"
|
||||
],
|
||||
"LnInstList": [
|
||||
"波动闪变值"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "暂态事件",
|
||||
"inst": "01",
|
||||
"TrgOps": "96",
|
||||
"Select": "QVVR",
|
||||
"DataSetList": [
|
||||
"dsEveQVVR"
|
||||
],
|
||||
"LnInstList": [
|
||||
"电压变动A",
|
||||
"电压变动B",
|
||||
"电压变动C"
|
||||
]
|
||||
}
|
||||
],
|
||||
"LnClassList": [
|
||||
{
|
||||
"desc": "基本数据",
|
||||
"nameList": [
|
||||
"MMXU"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "序分量值",
|
||||
"nameList": [
|
||||
"MSQI"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "谐波/间谐波数据",
|
||||
"nameList": [
|
||||
"MHAI"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "波动闪变",
|
||||
"nameList": [
|
||||
"MFLK"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "电压变动",
|
||||
"nameList": [
|
||||
"QVVR"
|
||||
]
|
||||
}
|
||||
],
|
||||
"PhaseList": [
|
||||
{
|
||||
"desc": "无相别",
|
||||
"nameList": [
|
||||
"null"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "正序",
|
||||
"nameList": [
|
||||
"c1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "负序",
|
||||
"nameList": [
|
||||
"c2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "零序",
|
||||
"nameList": [
|
||||
"c3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "A相",
|
||||
"nameList": [
|
||||
"phsA",
|
||||
"phsAHar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "B相",
|
||||
"nameList": [
|
||||
"phsB",
|
||||
"phsBHar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "C相",
|
||||
"nameList": [
|
||||
"phsC",
|
||||
"phsCHar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "AB线",
|
||||
"nameList": [
|
||||
"phsAB",
|
||||
"phsABHar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "BC线",
|
||||
"nameList": [
|
||||
"phsBC",
|
||||
"phsBCHar"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "CA线",
|
||||
"nameList": [
|
||||
"phsCA",
|
||||
"phsCAHar"
|
||||
]
|
||||
}
|
||||
],
|
||||
"MultiplierList": [
|
||||
{
|
||||
"multiplier": 1,
|
||||
"nameList": [
|
||||
"null"
|
||||
]
|
||||
},
|
||||
{
|
||||
"multiplier": 1000,
|
||||
"nameList": [
|
||||
"k"
|
||||
]
|
||||
}
|
||||
],
|
||||
"UnitList": [
|
||||
{
|
||||
"desc": "other",
|
||||
"nameList": [
|
||||
"null"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "v",
|
||||
"nameList": [
|
||||
"V"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "a",
|
||||
"nameList": [
|
||||
"A"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "w",
|
||||
"nameList": [
|
||||
"W",
|
||||
"VAr",
|
||||
"VA"
|
||||
]
|
||||
}
|
||||
],
|
||||
"TypeList": [
|
||||
{
|
||||
"desc": "值",
|
||||
"nameList": [
|
||||
"mag"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "角度",
|
||||
"nameList": [
|
||||
"ang"
|
||||
]
|
||||
}
|
||||
],
|
||||
"DataObjectsList": [
|
||||
{
|
||||
"desc": "非间谐波数据",
|
||||
"LnInstList": [
|
||||
"最大值",
|
||||
"最小值",
|
||||
"平均值",
|
||||
"95值"
|
||||
],
|
||||
"ObjectList": [
|
||||
{
|
||||
"desc": "频率",
|
||||
"nameList": [
|
||||
"Hz"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "线电压总有效值",
|
||||
"nameList": [
|
||||
"PPV"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "相电压总有效值",
|
||||
"nameList": [
|
||||
"PhV"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "电流总有效值",
|
||||
"nameList": [
|
||||
"A"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "有功功率",
|
||||
"nameList": [
|
||||
"W"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "无功功率",
|
||||
"nameList": [
|
||||
"VAr"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "视在功率",
|
||||
"nameList": [
|
||||
"VA"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "功率因数",
|
||||
"nameList": [
|
||||
"PF"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "位移功率因数",
|
||||
"nameList": [
|
||||
"DF"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "三相总有功功率",
|
||||
"nameList": [
|
||||
"TotW"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "三相总无功功率",
|
||||
"nameList": [
|
||||
"TotVAr"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "三相总视在功率",
|
||||
"nameList": [
|
||||
"TotVA"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "三相功率因数",
|
||||
"nameList": [
|
||||
"TotPF"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "三相位移功率因数",
|
||||
"nameList": [
|
||||
"TotDF"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "频率偏差",
|
||||
"nameList": [
|
||||
"HzDev"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "相电压偏差",
|
||||
"nameList": [
|
||||
"PhVDev"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "线电压偏差",
|
||||
"nameList": [
|
||||
"PPVDev"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "正序负序和零序电压",
|
||||
"nameList": [
|
||||
"SeqV"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "正序负序和零序电流",
|
||||
"nameList": [
|
||||
"SeqA"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "电压负序不平衡度",
|
||||
"nameList": [
|
||||
"ImbNgV"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "电流负序不平衡度",
|
||||
"nameList": [
|
||||
"ImbNgA"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "电压零序不平衡度",
|
||||
"nameList": [
|
||||
"ImbZroV"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "电流零序不平衡度",
|
||||
"nameList": [
|
||||
"ImbZroA"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "相电压谐波总畸变率",
|
||||
"nameList": [
|
||||
"ThdPhV"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "相电压总偶次谐波畸变率",
|
||||
"nameList": [
|
||||
"ThdEvnPhV"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "相电压总奇次谐波畸变率",
|
||||
"nameList": [
|
||||
"ThdOddPhV"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "线电压谐波总畸变率",
|
||||
"nameList": [
|
||||
"ThdPPV"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "线电压总偶次谐波畸变率",
|
||||
"nameList": [
|
||||
"ThdEvnPPV"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "线电压总奇次谐波畸变率",
|
||||
"nameList": [
|
||||
"ThdOddPPV"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "相电压谐波含有率序列",
|
||||
"baseflag": 1,
|
||||
"basecount": 49,
|
||||
"nameList": [
|
||||
"HRPhV",
|
||||
"HPhVMag"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "线电压谐波含有率序列",
|
||||
"baseflag": 1,
|
||||
"basecount": 49,
|
||||
"nameList": [
|
||||
"HRPPV"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "电流总谐波畸变率",
|
||||
"nameList": [
|
||||
"ThdA"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "电流总偶次谐波畸变率",
|
||||
"nameList": [
|
||||
"ThdEvnA"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "电流总奇次谐波畸变率",
|
||||
"nameList": [
|
||||
"ThdOddA"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "谐波电流有效值序列",
|
||||
"baseflag": 1,
|
||||
"basecount": 49,
|
||||
"nameList": [
|
||||
"HA",
|
||||
"HAMag"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "谐波电压有效值序列",
|
||||
"baseflag": 1,
|
||||
"basecount": 49,
|
||||
"nameList": [
|
||||
"HPhV"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "2~50次谐波有功功率序列",
|
||||
"baseflag": 1,
|
||||
"basecount": 49,
|
||||
"nameList": [
|
||||
"HW"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "2~50次谐波无功功率序列",
|
||||
"baseflag": 1,
|
||||
"basecount": 49,
|
||||
"nameList": [
|
||||
"HVAr"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "2~50次谐波视在功率序列",
|
||||
"baseflag": 1,
|
||||
"basecount": 49,
|
||||
"nameList": [
|
||||
"HVA"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "三相总谐波视在功率",
|
||||
"nameList": [
|
||||
"TotHVA"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "三相总谐波无功功率",
|
||||
"nameList": [
|
||||
"TotHVAr"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "三相总谐波有功功率",
|
||||
"nameList": [
|
||||
"TotHW"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "相电压基波有效值",
|
||||
"baseflag": 2,
|
||||
"queuecount": 49,
|
||||
"nameList": [
|
||||
"HFundPhV",
|
||||
"FundPhV"
|
||||
],
|
||||
"queueList":[
|
||||
"HPhV"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "线电压基波有效值",
|
||||
"baseflag": 2,
|
||||
"queuecount": 49,
|
||||
"nameList": [
|
||||
"HFundPPV"
|
||||
],
|
||||
"queueList":[
|
||||
"HPPV"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "电流基波有效值",
|
||||
"baseflag": 2,
|
||||
"queuecount": 49,
|
||||
"nameList": [
|
||||
|
||||
],
|
||||
"queueList":[
|
||||
"HA"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "基波有功功率",
|
||||
"baseflag": 2,
|
||||
"queuecount": 49,
|
||||
"nameList": [
|
||||
|
||||
],
|
||||
"queueList":[
|
||||
"HW"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "基波无功功率",
|
||||
"baseflag": 2,
|
||||
"queuecount": 49,
|
||||
"nameList": [
|
||||
|
||||
],
|
||||
"queueList":[
|
||||
"HVAr"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "基波视在功率",
|
||||
"baseflag": 2,
|
||||
"queuecount": 49,
|
||||
"nameList": [
|
||||
|
||||
],
|
||||
"queueList":[
|
||||
"HVA"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "间谐波数据",
|
||||
"LnInstList": [
|
||||
"间谐波最大值",
|
||||
"间谐波最小值",
|
||||
"间谐波平均值",
|
||||
"间谐波95值",
|
||||
"间谐波实时数据"
|
||||
],
|
||||
"ObjectList": [
|
||||
{
|
||||
"desc": "相电压间谐波含有率序列",
|
||||
"baseflag": 1,
|
||||
"basecount": 50,
|
||||
"nameList": [
|
||||
"HPhV"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "线电压间谐波含有率序列",
|
||||
"baseflag": 1,
|
||||
"basecount": 50,
|
||||
"nameList": [
|
||||
"HRPPV"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "间谐波电流有效值序列",
|
||||
"baseflag": 1,
|
||||
"basecount": 50,
|
||||
"nameList": [
|
||||
"HA"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "间谐波电压有效值序列",
|
||||
"baseflag": 1,
|
||||
"basecount": 50,
|
||||
"nameList": [
|
||||
"HRPhV"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "电压变动",
|
||||
"LnInstList": [
|
||||
"电压变动A",
|
||||
"电压变动B",
|
||||
"电压变动C",
|
||||
],
|
||||
"ObjectList": [
|
||||
{
|
||||
"desc": "电压扰动事件启动",
|
||||
"nameList": [
|
||||
"VarStr"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "电压暂降事件启动",
|
||||
"nameList": [
|
||||
"DipStr"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "电压暂升事件启动",
|
||||
"nameList": [
|
||||
"SwlStr"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "电压中断事件启动",
|
||||
"nameList": [
|
||||
"IntrStr"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "电压扰动事件特征幅值",
|
||||
"nameList": [
|
||||
"VVa"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "电压扰动事件持续时间",
|
||||
"nameList": [
|
||||
"VVaTm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "电压暂降启动定值",
|
||||
"nameList": [
|
||||
"DipStrVal"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "电压暂升启动定值",
|
||||
"nameList": [
|
||||
"SwlStrVal"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "电压中断启动定值",
|
||||
"nameList": [
|
||||
"IntrStrVal"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "其余数据",
|
||||
"LnInstList": [
|
||||
"波动闪变值",
|
||||
"录波文件"
|
||||
],
|
||||
"ObjectList": [
|
||||
{
|
||||
"desc": "线电压短时闪变值",
|
||||
"nameList": [
|
||||
"PPPst"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "相电压短时闪变值",
|
||||
"nameList": [
|
||||
"PhPst"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "线电压长时闪变值",
|
||||
"nameList": [
|
||||
"PPPlt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "相电压长时闪变值",
|
||||
"nameList": [
|
||||
"PhPlt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "线电压电压变动幅值",
|
||||
"nameList": [
|
||||
"PPFluc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "相电压电压变动幅值",
|
||||
"nameList": [
|
||||
"PhFluc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "线电压电压变动频度",
|
||||
"nameList": [
|
||||
"PPFlucf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"desc": "相电压电压变动频度",
|
||||
"nameList": [
|
||||
"PhFlucf"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--注:#7#代表通配符,用于通配数据类型 采用8421码,8-CP95 4-最小值 2-最大值 1-平均值-->
|
||||
<!-- %2,50%代表通配符,用于通配谐波数据,采用范围编码,第一个数字表示谐波起始号,第二个数字谐波结束号-->
|
||||
<!-- SEQ=后面的值采用8421码 8-T 4-C 2-B 1-A-->
|
||||
<!--注:type类型:0-DataType 1-监测点 2-剔除标记 3-发生时刻,毫秒 4-数据链表 5-相位 6-值索引 9-实时SOE事件-->
|
||||
<JSConfigTemplate version="2023-10-31" author="ww" SelectStat="JiangSu" SelectReal="Kafka Producer" desc="默认">
|
||||
<!--注:暂态事件解析规则配置 Flag:0-不分相 1-分相 如果Flag=0 A,B,C配置成一样,如果Flag=1,A,B,C根据实际配置-->
|
||||
<WavePhasic Flag="1" A="QVVR0" B="QVVR1" C="QVVR2" />
|
||||
<!--注:暂态事件持续事件单位:0-毫秒 1-秒-->
|
||||
<UnitOfTime Unit="0" />
|
||||
<!--注:上送值的时间:UTC-UTC时间 beijing-北京时间-->
|
||||
<ValueOfTime Unit="UTC" />
|
||||
<!--注:录波文件的时间:UTC-UTC时间 beijing-北京时间-->
|
||||
<ComtradeFile WaveTimeFlag="beijing" />
|
||||
<IED name="PQMonitor" desc="电能质量监测装置" />
|
||||
<LDevice Prefix="PQM" desc="监测点" />
|
||||
<ReportMap>
|
||||
<!--用于映射需要触发那些报告-->
|
||||
<!--ReportControl:ID,RCBName,intgPd,dchg,qchg,dupd,period,gi,issuffixed,seqNum,timeStamp,reasonCode,dataSet,dataRef,bufOvfl,entryID,configRef,segmentation,FlickerFlag-->
|
||||
<!--600/60秒,即10分钟/1分钟-->
|
||||
<!--0,0,0,1,0为周期触发报告-->
|
||||
<!--1,0,0,0,0为变位触发报告-->
|
||||
<!--0,0,1,0,0为更新触发报告-->
|
||||
<ReportStat>
|
||||
<Report ReportControl="LLN0$BR$brcbFlickerData,600,0,0,1,0,0,yes,1,1,1,1,1,0,1,1,1,3,1" />
|
||||
<Report ReportControl="LLN0$BR$brcbStatisticData,60,0,0,1,0,0,yes,1,1,1,1,1,0,1,1,1,3,0" />
|
||||
</ReportStat>
|
||||
<ReportReal>
|
||||
<Report ReportControl="LLN0$RP$brcbFlickerData,600,0,0,0,1,0,yes,1,1,1,1,1,0,1,1,1,3,1" />
|
||||
<Report ReportControl="LLN0$RP$urcbRealData,3,0,0,0,1,0,yes,1,1,1,1,1,0,1,1,1,3,0" />
|
||||
</ReportReal>
|
||||
<ReportEvent>
|
||||
<Report ReportControl="LLN0$BR$brcbQVVR,60,1,0,0,0,0,yes,1,1,1,1,1,0,1,1,1,8,1,0"/>
|
||||
<Report ReportControl="LLN0$BR$brcbRDRE,60,1,0,0,0,0,yes,1,1,1,1,1,0,1,1,1,8,1,0"/>
|
||||
<Report ReportControl="LLN0$BR$brcbGGIO,60,1,0,0,0,0,yes,1,1,1,1,1,0,1,1,1,8,1,0"/>
|
||||
</ReportEvent>
|
||||
</ReportMap>
|
||||
<Topic name="HISDATA" desc="历史稳态数据">
|
||||
<DataType name="DATA_TYPE" value="02" desc="历史短时闪变数据" type="0">
|
||||
<Monitor name="MONITOR" desc="监测点" type="1">
|
||||
<Item name="TIME" desc="发生时刻" type="3" />
|
||||
<Item name="F_S" desc="短时闪变和波动" type="4" >
|
||||
<Sequence name="SEQ" value="7" desc="相别" type="5" >
|
||||
<Value name="PST" desc="短时闪变" type="6" DO="" DA="" />
|
||||
<Value name="FLUC" desc="电压波动幅度" type="6" DO="" DA="" />
|
||||
<Value name="FLUCF" desc="电压波动频度" type="6" DO="" DA="" />
|
||||
</Sequence>
|
||||
</Item>
|
||||
</Monitor>
|
||||
</DataType>
|
||||
<DataType name="DATA_TYPE" value="04" desc="历史长时闪变数据" type="0">
|
||||
<Monitor name="MONITOR" desc="监测点" type="1">
|
||||
<Item name="TIME" desc="发生时刻" type="3" />
|
||||
<Item name="F_L" desc="闪变" type="4" >
|
||||
<Sequence name="SEQ" value="7" desc="相别" type="5" >
|
||||
<Value name="PLT" desc="长时闪变" type="6" DO="" DA="" />
|
||||
</Sequence>
|
||||
</Item>
|
||||
</Monitor>
|
||||
</DataType>
|
||||
<DataType name="DATA_TYPE" value="03" desc="历史暂态数据" type="0" >
|
||||
<Monitor name="MONITOR" desc="监测点" type="1" >
|
||||
<Item name="VOLTAGE" desc="暂态指标" type="4" >
|
||||
<Sequence name="SEQ" value="7" desc="相别" type="5">
|
||||
<Value name="MAG" desc="残余电压" type="6" DO="" DA="" />
|
||||
<Value name="DUR" desc="持续时间" type="6" DO="" DA="" />
|
||||
<Value name="SEQ" desc="相别" type="6" DO="" DA="" />
|
||||
<Value name="STARTTIME" desc="开始时间" type="6" DO="" DA="" />
|
||||
<Value name="ENDTIME" desc="结束时间" type="6" DO="" DA="" />
|
||||
<Value name="DISKIND" desc="暂降类型" type="6" DO="" DA="" />
|
||||
<Value name="WAVEFILE" desc="波形文件名称" type="6" DO="" DA="" />
|
||||
</Sequence>
|
||||
</Item>
|
||||
</Monitor>
|
||||
</DataType>
|
||||
<DataType name="DATA_TYPE" value="01" desc="历史稳态数据" type="0">
|
||||
<Monitor name="MONITOR" desc="监测点" type="1">
|
||||
<Item name="FLAG" value="0" desc="剔除标记" type="2" />
|
||||
<Item name="TIME" desc="发生时刻" type="3" />
|
||||
<Item name="V" desc="电压" type="4" >
|
||||
<!--电压V部分(A-C相)-->
|
||||
<Sequence name="SEQ" value="7" desc="相别(A-C相)" type="5">
|
||||
<!--注:Coefficient 值系数,转成kafka的时候乘以系数;BaseFlag 基础数据标志 0或没有-非基础数据 1-基础数据;LimitUp 数据合理上限,如果包含*%UN字符表示需要乘以电压等级电压,如果包含*%U字符表示需要乘以电压等级/1.732电压例如:220kV则相电压上限为1.5*220;LimitDown 数据合理下限 如果包含*%U字符表示需要乘以电压等级电压-->
|
||||
<Value name="G_DELTA_V" desc="电压偏差95值" type="6" DO="" DA="" BaseFlag="1" LimitUp="20" LimitDown="-20" Coefficient="1"/>
|
||||
<Value name="DELTA_V" desc="电压偏差平均值" type="6" DO="" DA="" BaseFlag="1" LimitUp="20" LimitDown="-20" Coefficient="1"/>
|
||||
<Value name="MAX_DELTA_V" desc="电压偏差最大值" type="6" DO="" DA="" BaseFlag="1" LimitUp="20" LimitDown="-20" Coefficient="1"/>
|
||||
<Value name="MIN_DELTA_V" desc="电压偏差最小值" type="6" DO="" DA="" BaseFlag="1" LimitUp="20" LimitDown="-20" Coefficient="1"/>
|
||||
<Value name="G_VRMS" desc="电压有效值95值" type="6" DO="" DA="" BaseFlag="1" LimitUp="0*%U" LimitDown="150*%U" />
|
||||
<Value name="VRMS" desc="电压有效值平均值" type="6" DO="" DA="" BaseFlag="1" LimitUp="0*%U" LimitDown="150*%U" />
|
||||
<Value name="MAX_VRMS" desc="电压有效值最大值" type="6" DO="" DA="" BaseFlag="1" LimitUp="0*%U" LimitDown="150*%U" />
|
||||
<Value name="MIN_VRMS" desc="电压有效值最小值" type="6" DO="" DA="" BaseFlag="1" LimitUp="0*%U" LimitDown="150*%U" />
|
||||
<Value name="VTHD" desc="电压总谐波畸变率平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_VTHD" desc="电压总谐波畸变率最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_VTHD" desc="电压总谐波畸变率最小值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_VFUND_ANGLE" desc="基波电压相角最小值" type="6" DO="" DA="" />
|
||||
<Value name="V1" desc="基波电压有效值平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_V1" desc="基波电压有效值最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_V1" desc="基波电压有效值最小值" type="6" DO="" DA="" />
|
||||
<Value name="SV_%0,49%" desc="间谐波电压含有率(f25-2475)平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_SV_%0,49%" desc="间谐波电压含有率(f25-2475)最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_SV_%0,49%" desc="间谐波电压含有率(f25-2475)最小值" type="6" DO="" DA="" />
|
||||
<Value name="V%2,50%" desc="谐波电压含有率(2-50)平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_V%2,50%" desc="谐波电压含有率(2-50)最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_V%2,50%" desc="谐波电压含有率(2-50)最小值" type="6" DO="" DA="" />
|
||||
<Value name="VA%2,50%" desc="谐波电压相角(2-50)平均值" type="6" DO="" DA="" />
|
||||
</Sequence>
|
||||
<Sequence name="SEQ" value="8" desc="相别(T相)" type="5">
|
||||
<!--电压V部分(T相)-->
|
||||
<Value name="VNSEQ" desc="负序电压平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_VNSEQ" desc="负序电压最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_VNSEQ" desc="负序电压最小值" type="6" DO="" DA="" />
|
||||
<Value name="V_UNBAN" desc="负序电压不平衡平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_V_UNBAN" desc="负序电压不平衡最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_V_UNBAN" desc="负序电压不平衡最小值" type="6" DO="" DA="" />
|
||||
<Value name="VZSEQ" desc="零序电压平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_VZSEQ" desc="零序电压最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_VZSEQ" desc="零序电压最小值" type="6" DO="" DA="" />
|
||||
<Value name="VZSEQ_UNBAN" desc="零序电压不平衡平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_VZSEQ_UNBAN" desc="零序电压不平衡最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_VZSEQ_UNBAN" desc="零序电压不平衡最小值" type="6" DO="" DA="" />
|
||||
<Value name="G_FREQ" desc="频率95值" type="6" DO="" DA="" />
|
||||
<Value name="FREQ" desc="频率平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_FREQ" desc="频率最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_FREQ" desc="频率最小值" type="6" DO="" DA="" />
|
||||
<Value name="G_DELTA_FREQ" desc="频率偏差95值" type="6" DO="" DA="" />
|
||||
<Value name="DELTA_FREQ" desc="频率偏差平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_DELTA_FREQ" desc="频率偏差最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_DELTA_FREQ" desc="频率偏差最小值" type="6" DO="" DA="" />
|
||||
<Value name="VPSEQ" desc="正序电压平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_VPSEQ" desc="正序电压最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_VPSEQ" desc="正序电压最小值" type="6" DO="" DA="" />
|
||||
</Sequence>
|
||||
</Item>
|
||||
<Item name="I" desc="电流" type="4" >
|
||||
<!--电流I部分(A-C相)-->
|
||||
<Sequence name="SEQ" value="7" desc="相别(A-C相)" type="5">
|
||||
<Value name="G_IRMS" desc="电流有效值95值" type="6" DO="" DA="" />
|
||||
<Value name="IRMS" desc="电流有效值平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_IRMS" desc="电流有效值最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_IRMS" desc="电流有效值最小值" type="6" DO="" DA="" />
|
||||
<Value name="I1" desc="基波电流有效值平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_I1" desc="基波电流有效值最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_I1" desc="基波电流有效值最小值" type="6" DO="" DA="" />
|
||||
<Value name="SI_%0,49%" desc="间谐波电流幅值(f25-2475)平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_SI_%0,49%" desc="间谐波电流幅值(f25-2475)最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_SI_%0,49%" desc="间谐波电流幅值(f25-2475)最小值" type="6" DO="" DA="" />
|
||||
<Value name="I%2,50%" desc="谐波电流幅值(2-50)平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_I%2,50%" desc="谐波电流幅值(2-50)最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_I%2,50%" desc="谐波电流幅值(2-50)最小值" type="6" DO="" DA="" />
|
||||
</Sequence>
|
||||
<!--电流I部分(T相)-->
|
||||
<Sequence name="SEQ" value="8" desc="相别(T相)" type="5">
|
||||
<Value name="INSEQ" desc="负序电流平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_INSEQ" desc="负序电流最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_INSEQ" desc="负序电流最小值" type="6" DO="" DA="" />
|
||||
<Value name="I_UNBAN" desc="负序电流不平衡平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_I_UNBAN" desc="负序电流不平衡最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_I_UNBAN" desc="负序电流不平衡最小值" type="6" DO="" DA="" />
|
||||
<Value name="IZSEQ" desc="零序电流平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_IZSEQ" desc="零序电流最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_IZSEQ" desc="零序电流最小值" type="6" DO="" DA="" />
|
||||
<Value name="IZSEQ_UNBAN" desc="零序电流不平衡平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_IZSEQ_UNBAN" desc="零序电流不平衡最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_IZSEQ_UNBAN" desc="零序电流不平衡最小值" type="6" DO="" DA="" />
|
||||
<Value name="IPSEQ" desc="正序电流平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_IPSEQ" desc="正序电流最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_IPSEQ" desc="正序电流最小值" type="6" DO="" DA="" />
|
||||
</Sequence>
|
||||
</Item>
|
||||
<Item name="PQ" desc="功率" type="4" >
|
||||
<!--功率PQ部分(A-C相)-->
|
||||
<Sequence name="SEQ" value="7" desc="相别(A-C相)" type="5">
|
||||
<Value name="PF" desc="功率因数平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_PF" desc="功率因数最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_PF" desc="功率因数最小值" type="6" DO="" DA="" />
|
||||
<Value name="DF" desc="基波功率因数平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_DF" desc="基波功率因数最大值" type="6" DO="" DA="" />
|
||||
<Value name="P_FUND" desc="基波有功功率平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_P_FUND" desc="基波有功功率最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_P_FUND" desc="基波有功功率最小值" type="6" DO="" DA="" />
|
||||
<Value name="G_S" desc="视在功率95值" type="6" DO="" DA="" />
|
||||
<Value name="S" desc="视在功率平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_S" desc="视在功率最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_S" desc="视在功率最小值" type="6" DO="" DA="" />
|
||||
<Value name="G_Q" desc="无功功率95值" type="6" DO="" DA="" />
|
||||
<Value name="Q" desc="无功功率平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_Q" desc="无功功率最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_Q" desc="无功功率最小值" type="6" DO="" DA="" />
|
||||
<Value name="P%2,50%" desc="谐波有功功率(2-50)平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_P%2,50%" desc="谐波有功功率(2-50)最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_P%2,50%" desc="谐波有功功率(2-50)最小值" type="6" DO="" DA="" />
|
||||
<Value name="G_P" desc="有功功率95值" type="6" DO="" DA="" />
|
||||
<Value name="P" desc="有功功率平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_P" desc="有功功率最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_P" desc="有功功率最小值" type="6" DO="" DA="" />
|
||||
</Sequence>
|
||||
<!--功率PQ部分(T相)-->
|
||||
<Sequence name="SEQ" value="8" desc="相别(T相)" type="5">
|
||||
<Value name="PF" desc="总功率因数平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_PF" desc="总功率因数最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_PF" desc="总功率因数最小值" type="6" DO="" DA="" />
|
||||
<Value name="DF" desc="总基波功率因数平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_DF" desc="总基波功率因数最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_DF" desc="总基波功率因数最小值" type="6" DO="" DA="" />
|
||||
<Value name="S" desc="总视在功率平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_S" desc="总视在功率最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_S" desc="总视在功率最小值" type="6" DO="" DA="" />
|
||||
<Value name="Q" desc="总无功功率平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_Q" desc="总无功功率最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_Q" desc="总无功功率最小值" type="6" DO="" DA="" />
|
||||
<Value name="P" desc="总有功功率平均值" type="6" DO="" DA="" />
|
||||
<Value name="MAX_P" desc="总有功功率最大值" type="6" DO="" DA="" />
|
||||
<Value name="MIN_P" desc="总有功功率最小值" type="6" DO="" DA="" />
|
||||
</Sequence>
|
||||
</Item>
|
||||
</Monitor>
|
||||
</DataType>
|
||||
</Topic>
|
||||
<Topic name="SOEDATA" desc="告警SOE">
|
||||
<SOE name="ThdVVal" desc="电压总畸变率越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="ThdAVal" desc="电流总畸变率越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="HToddVVal" desc="奇次谐波电压含有率越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="HTeddVVal" desc="偶次谐波电压含有率越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="H2AVal" desc="2次谐波电流越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="H3AVal" desc="3次谐波电流越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="H4AVal" desc="4次谐波电流越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="H5AVal" desc="5次谐波电流越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="H7AVal" desc="7次谐波电流越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="H9AVal" desc="9次谐波电流越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="H11AVal" desc="11次谐波电流越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="H13AVal" desc="13次谐波电流越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="ImbNgVFVal" desc="电压负序不平衡度越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="ImbNgAFVal" desc="电流负序不平衡度越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="OvHzStrVal" desc="频率高越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="UnHzStrVal" desc="频率低越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="LRVInterrup" desc="长期电压中断告警" type="9" DO="" DA="" />
|
||||
<SOE name="LRVSwell" desc="电压上偏差越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="LRVSag" desc="电压下偏差越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="PhPstVal" desc="短时闪变越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="PhPltVal" desc="长时闪变越限告警" type="9" DO="" DA="" />
|
||||
<SOE name="PhyStateFault" desc="终端运行状态:故障" type="9" DO="" DA="" />
|
||||
<SOE name="PhyStateRun" desc="终端运行状态:运行" type="9" DO="" DA="" />
|
||||
<SOE name="PwrUp" desc="终端上电" type="9" DO="" DA="" />
|
||||
<SOE name="PwrDn" desc="终端掉电" type="9" DO="" DA="" />
|
||||
<SOE name="CommInterrupt" desc="终端通信中断" type="9" DO="" DA="" />
|
||||
<SOE name="CommResume" desc="终端通信恢复" type="9" DO="" DA="" />
|
||||
</Topic>
|
||||
</JSConfigTemplate>
|
||||
127
tools/mms-mapping/src/main/resources/template/默认规则.txt
Normal file
127
tools/mms-mapping/src/main/resources/template/默认规则.txt
Normal file
@@ -0,0 +1,127 @@
|
||||
<Value name="相电压短时闪变值波动闪变值值" desc="短时闪变" type="6" DO="MFLK1$MX$PhPst" DA="phs*$cVal$mag$f" />
|
||||
<Value name="相电压电压变动幅值波动闪变值值" desc="电压波动幅值" type="6" DO="MMXU2$MX$FLUC" DA="phs*$cVal$mag$f" />
|
||||
<Value name="相电压电压变动频度波动闪变值值" desc="电压波动频度" type="6" DO="MMXU2$MX$FLUCCF" DA="phs*$cVal$mag$f" />
|
||||
<Value name="相电压长时闪变值波动闪变值值" desc="长时闪变" type="6" DO="MFLK2$MX$PhPlt" DA="phs*$cVal$mag$f" />
|
||||
<Value name="电压扰动事件特征幅值值" desc="残余电压" type="6" DO="QVVR0$MX$VVa" DA="mag$f" />
|
||||
<Value name="电压扰动事件持续时间" desc="持续时间" type="6" DO="QVVR0$MX$VVaTm" DA="mag$f" />
|
||||
<Value name="SEQ" desc="相别" type="6" DO="" DA="" />
|
||||
<Value name="STARTTIME" desc="开始时间" type="6" DO="" DA="" />
|
||||
<Value name="ENDTIME" desc="结束时间" type="6" DO="" DA="" />
|
||||
<Value name="DISKIND" desc="暂降类型" type="6" DO="" DA="" />
|
||||
<Value name="WAVEFILE" desc="波形文件名称" type="6" DO="" DA="" />
|
||||
<Value name="相电压偏差95值值" desc="电压偏差95值" type="6" DO="MMXU5$MX$VolDev" DA="phs*$cVal$mag$f" BaseFlag="1" LimitUp="20" LimitDown="-20" Coefficient="1"/>
|
||||
<Value name="相电压偏差平均值值" desc="电压偏差平均值" type="6" DO="MMXU2$MX$VolDev" DA="phs*$cVal$mag$f" BaseFlag="1" LimitUp="20" LimitDown="-20" Coefficient="1"/>
|
||||
<Value name="相电压偏差最大值值" desc="电压偏差最大值" type="6" DO="MMXU3$MX$VolDev" DA="phs*$cVal$mag$f" BaseFlag="1" LimitUp="20" LimitDown="-20" Coefficient="1"/>
|
||||
<Value name="相电压偏差最小值值" desc="电压偏差最小值" type="6" DO="MMXU4$MX$VolDev" DA="phs*$cVal$mag$f" BaseFlag="1" LimitUp="20" LimitDown="-20" Coefficient="1"/>
|
||||
<Value name="相电压总有效值95值值" desc="电压有效值95值" type="6" DO="MMXU5$MX$PhV" DA="phs*$cVal$mag$f" BaseFlag="1" LimitUp="0*%U" LimitDown="150*%U" />
|
||||
<Value name="相电压总有效值平均值值" desc="电压有效值平均值" type="6" DO="MMXU2$MX$PhV" DA="phs*$cVal$mag$f" BaseFlag="1" LimitUp="0*%U" LimitDown="150*%U" />
|
||||
<Value name="相电压总有效值最大值值" desc="电压有效值最大值" type="6" DO="MMXU3$MX$PhV" DA="phs*$cVal$mag$f" BaseFlag="1" LimitUp="0*%U" LimitDown="150*%U" />
|
||||
<Value name="相电压总有效值最小值值" desc="电压有效值最小值" type="6" DO="MMXU4$MX$PhV" DA="phs*$cVal$mag$f" BaseFlag="1" LimitUp="0*%U" LimitDown="150*%U" />
|
||||
<Value name="相电压谐波总畸变率平均值值" desc="电压总谐波畸变率平均值" type="6" DO="MHAI2$MX$ThdPhV" DA="phs*$cVal$mag$f" />
|
||||
<Value name="相电压谐波总畸变率最大值值" desc="电压总谐波畸变率最大值" type="6" DO="MHAI3$MX$ThdPhV" DA="phs*$cVal$mag$f" />
|
||||
<Value name="相电压谐波总畸变率最小值值" desc="电压总谐波畸变率最小值" type="6" DO="MHAI4$MX$ThdPhV" DA="phs*$cVal$mag$f" />
|
||||
<Value name="MIN_VFUND_ANGLE" desc="基波电压相角最小值" type="6" DO="MHAI4$MX$FundPhVAng" DA="phs*$cVal$ang$f" />
|
||||
<Value name="相电压基波有效值平均值值" desc="基波电压有效值平均值" type="6" DO="MHAI2$MX$FundPhV" DA="phs*$cVal$mag$f" />
|
||||
<Value name="相电压基波有效值最大值值" desc="基波电压有效值最大值" type="6" DO="MHAI3$MX$FundPhV" DA="phs*$cVal$mag$f" />
|
||||
<Value name="相电压基波有效值最小值值" desc="基波电压有效值最小值" type="6" DO="MHAI4$MX$FundPhV" DA="phs*$cVal$mag$f" />
|
||||
<Value name="相电压间谐波含有率序列间谐波平均值值" desc="间谐波电压含有率(f25-2475)平均值" type="6" DO="MHAI8$MX$HPhV" DA="phs*Har[%-0]$mag$f" />
|
||||
<Value name="相电压间谐波含有率序列间谐波最大值值" desc="间谐波电压含有率(f25-2475)最大值" type="6" DO="MHAI9$MX$HPhV" DA="phs*Har[%-0]$mag$f" />
|
||||
<Value name="相电压间谐波含有率序列间谐波最小值值" desc="间谐波电压含有率(f25-2475)最小值" type="6" DO="MHAI10$MX$HPhV" DA="phs*Har[%-0]$mag$f" />
|
||||
|
||||
<Value name="间谐波电压有效值序列间谐波平均值值" desc="间谐波电压含有率(f25-2475)平均值" type="6" DO="MHAI8$MX$HPhV" DA="phs*Har[%-0]$mag$f" />
|
||||
<Value name="间谐波电压有效值序列间谐波最大值值" desc="间谐波电压含有率(f25-2475)最大值" type="6" DO="MHAI9$MX$HPhV" DA="phs*Har[%-0]$mag$f" />
|
||||
<Value name="间谐波电压有效值序列间谐波最小值值" desc="间谐波电压含有率(f25-2475)最小值" type="6" DO="MHAI10$MX$HPhV" DA="phs*Har[%-0]$mag$f" />
|
||||
|
||||
<Value name="相电压谐波含有率序列平均值值" desc="谐波电压含有率(2-50)平均值" type="6" DO="MHAI2$MX$HPhV" DA="phs*Har[%-2]$mag$f" />
|
||||
<Value name="相电压谐波含有率序列最大值值" desc="谐波电压含有率(2-50)最大值" type="6" DO="MHAI3$MX$HPhV" DA="phs*Har[%-2]$mag$f" />
|
||||
<Value name="相电压谐波含有率序列最小值值" desc="谐波电压含有率(2-50)最小值" type="6" DO="MHAI4$MX$HPhV" DA="phs*Har[%-2]$mag$f" />
|
||||
<Value name="谐波电压有效值序列平均值角度" desc="谐波电压相角(2-50)平均值" type="6" DO="MHAI2$MX$HPhV" DA="phs*Har[%-2]$ang$f" />
|
||||
<Value name="正序负序和零序电压平均值负序值" desc="负序电压平均值" type="6" DO="MSQI2$MX$SeqV" DA="c2$cVal$mag$f" />
|
||||
<Value name="正序负序和零序电压最大值负序值" desc="负序电压最大值" type="6" DO="MSQI3$MX$SeqV" DA="c2$cVal$mag$f" />
|
||||
<Value name="正序负序和零序电压最小值负序值" desc="负序电压最小值" type="6" DO="MSQI4$MX$SeqV" DA="c2$cVal$mag$f" />
|
||||
<Value name="电压负序不平衡度平均值值" desc="负序电压不平衡平均值" type="6" DO="MSQI2$MX$ImbNgV" DA="mag$f" />
|
||||
<Value name="电压负序不平衡度最大值值" desc="负序电压不平衡最大值" type="6" DO="MSQI3$MX$ImbNgV" DA="mag$f" />
|
||||
<Value name="电压负序不平衡度最小值值" desc="负序电压不平衡最小值" type="6" DO="MSQI4$MX$ImbNgV" DA="mag$f" />
|
||||
<Value name="正序负序和零序电压平均值零序值" desc="零序电压平均值" type="6" DO="MSQI2$MX$SeqV" DA="c3$cVal$mag$f" />
|
||||
<Value name="正序负序和零序电压最大值零序值" desc="零序电压最大值" type="6" DO="MSQI3$MX$SeqV" DA="c3$cVal$mag$f" />
|
||||
<Value name="正序负序和零序电压最小值零序值" desc="零序电压最小值" type="6" DO="MSQI4$MX$SeqV" DA="c3$cVal$mag$f" />
|
||||
<Value name="电压零序不平衡度平均值值" desc="零序电压不平衡平均值" type="6" DO="MSQI2$MX$ImbZroV" DA="mag$f" />
|
||||
<Value name="电压零序不平衡度最大值值" desc="零序电压不平衡最大值" type="6" DO="MSQI3$MX$ImbZroV" DA="mag$f" />
|
||||
<Value name="电压零序不平衡度最小值值" desc="零序电压不平衡最小值" type="6" DO="MSQI4$MX$ImbZroV" DA="mag$f" />
|
||||
<Value name="频率95值值" desc="频率95值" type="6" DO="MMXU5$MX$Hz" DA="mag$f" />
|
||||
<Value name="频率平均值值" desc="频率平均值" type="6" DO="MMXU2$MX$Hz" DA="mag$f" />
|
||||
<Value name="频率最大值值" desc="频率最大值" type="6" DO="MMXU3$MX$Hz" DA="mag$f" />
|
||||
<Value name="频率最小值值" desc="频率最小值" type="6" DO="MMXU4$MX$Hz" DA="mag$f" />
|
||||
<Value name="频率偏差95值值" desc="频率偏差95值" type="6" DO="MMXU5$MX$FreqDev" DA="mag$f" />
|
||||
<Value name="频率偏差平均值值" desc="频率偏差平均值" type="6" DO="MMXU2$MX$FreqDev" DA="mag$f" />
|
||||
<Value name="频率偏差最大值值" desc="频率偏差最大值" type="6" DO="MMXU3$MX$FreqDev" DA="mag$f" />
|
||||
<Value name="频率偏差最小值值" desc="频率偏差最小值" type="6" DO="MMXU4$MX$FreqDev" DA="mag$f" />
|
||||
<Value name="正序负序和零序电压平均值正序值" desc="正序电压平均值" type="6" DO="MSQI2$MX$SeqV" DA="c1$cVal$mag$f" />
|
||||
<Value name="正序负序和零序电压最大值正序值" desc="正序电压最大值" type="6" DO="MSQI3$MX$SeqV" DA="c1$cVal$mag$f" />
|
||||
<Value name="正序负序和零序电压最小值正序值" desc="正序电压最小值" type="6" DO="MSQI4$MX$SeqV" DA="c1$cVal$mag$f" />
|
||||
<Value name="电流总有效值95值值" desc="电流有效值95值" type="6" DO="MMXU5$MX$A" DA="phs*$cVal$mag$f" />
|
||||
<Value name="电流总有效值平均值值" desc="电流有效值平均值" type="6" DO="MMXU2$MX$A" DA="phs*$cVal$mag$f" />
|
||||
<Value name="电流总有效值最大值值" desc="电流有效值最大值" type="6" DO="MMXU3$MX$A" DA="phs*$cVal$mag$f" />
|
||||
<Value name="电流总有效值最小值值" desc="电流有效值最小值" type="6" DO="MMXU4$MX$A" DA="phs*$cVal$mag$f" />
|
||||
<Value name="电流基波有效值平均值值" desc="基波电流有效值平均值" type="6" DO="MHAI2$MX$HA" DA="phs*Har[1]$mag$f" />
|
||||
<Value name="电流基波有效值最大值值" desc="基波电流有效值最大值" type="6" DO="MHAI3$MX$HA" DA="phs*Har[1]$mag$f" />
|
||||
<Value name="电流基波有效值最小值值" desc="基波电流有效值最小值" type="6" DO="MHAI4$MX$HA" DA="phs*Har[1]$mag$f" />
|
||||
<Value name="间谐波电流有效值序列间谐波平均值值" desc="间谐波电流幅值(f25-2475)平均值" type="6" DO="MHAI8$MX$HA" DA="phs*Har[%-0]$mag$f" />
|
||||
<Value name="间谐波电流有效值序列间谐波最大值值" desc="间谐波电流幅值(f25-2475)最大值" type="6" DO="MHAI9$MX$HA" DA="phs*Har[%-0]$mag$f" />
|
||||
<Value name="间谐波电流有效值序列间谐波最小值值" desc="间谐波电流幅值(f25-2475)最小值" type="6" DO="MHAI10$MX$HA" DA="phs*Har[%-0]$mag$f" />
|
||||
<Value name="谐波电流有效值序列平均值值" desc="谐波电流幅值(2-50)平均值" type="6" DO="MHAI2$MX$HA" DA="phs*Har[%-0]$mag$f" />
|
||||
<Value name="谐波电流有效值序列最大值值" desc="谐波电流幅值(2-50)最大值" type="6" DO="MHAI3$MX$HA" DA="phs*Har[%-0]$mag$f" />
|
||||
<Value name="谐波电流有效值序列最小值值" desc="谐波电流幅值(2-50)最小值" type="6" DO="MHAI4$MX$HA" DA="phs*Har[%-0]$mag$f" />
|
||||
<Value name="正序负序和零序电流平均值负序值" desc="负序电流平均值" type="6" DO="MSQI2$MX$SeqA" DA="c2$cVal$mag$f" />
|
||||
<Value name="正序负序和零序电流最大值负序值" desc="负序电流最大值" type="6" DO="MSQI3$MX$SeqA" DA="c2$cVal$mag$f" />
|
||||
<Value name="正序负序和零序电流最小值负序值" desc="负序电流最小值" type="6" DO="MSQI4$MX$SeqA" DA="c2$cVal$mag$f" />
|
||||
<Value name="电流负序不平衡度平均值值" desc="负序电流不平衡平均值" type="6" DO="MSQI2$MX$ImbNgA" DA="mag$f" />
|
||||
<Value name="电流负序不平衡度最大值值" desc="负序电流不平衡最大值" type="6" DO="MSQI3$MX$ImbNgA" DA="mag$f" />
|
||||
<Value name="电流负序不平衡度最小值值" desc="负序电流不平衡最小值" type="6" DO="MSQI4$MX$ImbNgA" DA="mag$f" />
|
||||
<Value name="正序负序和零序电流平均值零序值" desc="零序电流平均值" type="6" DO="MSQI2$MX$SeqA" DA="c3$cVal$mag$f" />
|
||||
<Value name="正序负序和零序电流最大值零序值" desc="零序电流最大值" type="6" DO="MSQI3$MX$SeqA" DA="c3$cVal$mag$f" />
|
||||
<Value name="正序负序和零序电流最小值零序值" desc="零序电流最小值" type="6" DO="MSQI4$MX$SeqA" DA="c3$cVal$mag$f" />
|
||||
<Value name="电流零序不平衡度平均值值" desc="零序电流不平衡平均值" type="6" DO="MSQI2$MX$ImbZroA" DA="mag$f" />
|
||||
<Value name="电流零序不平衡度最大值值" desc="零序电流不平衡最大值" type="6" DO="MSQI3$MX$ImbZroA" DA="mag$f" />
|
||||
<Value name="电流零序不平衡度最小值值" desc="零序电流不平衡最小值" type="6" DO="MSQI4$MX$ImbZroA" DA="mag$f" />
|
||||
<Value name="正序负序和零序电流平均值正序值" desc="正序电流平均值" type="6" DO="MSQI2$MX$SeqA" DA="c1$cVal$mag$f" />
|
||||
<Value name="正序负序和零序电流最大值正序值" desc="正序电流最大值" type="6" DO="MSQI3$MX$SeqA" DA="c1$cVal$mag$f" />
|
||||
<Value name="正序负序和零序电流最小值正序值" desc="正序电流最小值" type="6" DO="MSQI4$MX$SeqA" DA="c1$cVal$mag$f" />
|
||||
<Value name="功率因数平均值值" desc="功率因数平均值" type="6" DO="MMXU2$MX$PF" DA="phs*$cVal$mag$f" />
|
||||
<Value name="功率因数最大值值" desc="功率因数最大值" type="6" DO="MMXU3$MX$PF" DA="phs*$cVal$mag$f" />
|
||||
<Value name="功率因数最小值值" desc="功率因数最小值" type="6" DO="MMXU4$MX$PF" DA="phs*$cVal$mag$f" />
|
||||
<Value name="位移功率因数平均值值" desc="基波功率因数平均值" type="6" DO="MHAI2$MX$HSigPF" DA="phs*Har[1]$mag$f" />
|
||||
<Value name="位移功率因数最大值值" desc="基波功率因数最大值" type="6" DO="MHAI3$MX$HSigPF" DA="phs*Har[1]$mag$f" />
|
||||
<Value name="基波有功功率平均值值" desc="基波有功功率平均值" type="6" DO="MHAI2$MX$HW" DA="phs*Har[1]$mag$f" />
|
||||
<Value name="基波有功功率最大值值" desc="基波有功功率最大值" type="6" DO="MHAI3$MX$HW" DA="phs*Har[1]$mag$f" />
|
||||
<Value name="基波有功功率最小值值" desc="基波有功功率最小值" type="6" DO="MHAI4$MX$HW" DA="phs*Har[1]$mag$f" />
|
||||
<Value name="视在功率95值值" desc="视在功率95值" type="6" DO="MMXU5$MX$VA" DA="phs*$cVal$mag$f" />
|
||||
<Value name="视在功率平均值值" desc="视在功率平均值" type="6" DO="MMXU2$MX$VA" DA="phs*$cVal$mag$f" />
|
||||
<Value name="视在功率最大值值" desc="视在功率最大值" type="6" DO="MMXU3$MX$VA" DA="phs*$cVal$mag$f" />
|
||||
<Value name="视在功率最小值值" desc="视在功率最小值" type="6" DO="MMXU4$MX$VA" DA="phs*$cVal$mag$f" />
|
||||
<Value name="无功功率95值值" desc="无功功率95值" type="6" DO="MMXU5$MX$VAr" DA="phs*$cVal$mag$f" />
|
||||
<Value name="无功功率平均值值" desc="无功功率平均值" type="6" DO="MMXU2$MX$VAr" DA="phs*$cVal$mag$f" />
|
||||
<Value name="无功功率最大值值" desc="无功功率最大值" type="6" DO="MMXU3$MX$VAr" DA="phs*$cVal$mag$f" />
|
||||
<Value name="无功功率最小值值" desc="无功功率最小值" type="6" DO="MMXU4$MX$VAr" DA="phs*$cVal$mag$f" />
|
||||
<Value name="2~50次谐波有功功率序列平均值值" desc="谐波有功功率(2-50)平均值" type="6" DO="MHAI2$MX$HW" DA="phs*Har[%-0]$mag$f" />
|
||||
<Value name="2~50次谐波有功功率序列最大值值" desc="谐波有功功率(2-50)最大值" type="6" DO="MHAI3$MX$HW" DA="phs*Har[%-0]$mag$f" />
|
||||
<Value name="2~50次谐波有功功率序列最小值值" desc="谐波有功功率(2-50)最小值" type="6" DO="MHAI4$MX$HW" DA="phs*Har[%-0]$mag$f" />
|
||||
<Value name="有功功率95值值" desc="有功功率95值" type="6" DO="MMXU5$MX$W" DA="phs*$cVal$mag$f" />
|
||||
<Value name="有功功率平均值值" desc="有功功率平均值" type="6" DO="MMXU2$MX$W" DA="phs*$cVal$mag$f" />
|
||||
<Value name="有功功率最大值值" desc="有功功率最大值" type="6" DO="MMXU3$MX$W" DA="phs*$cVal$mag$f" />
|
||||
<Value name="有功功率最小值值" desc="有功功率最小值" type="6" DO="MMXU4$MX$W" DA="phs*$cVal$mag$f" />
|
||||
<Value name="三相功率因数平均值值" desc="总功率因数平均值" type="6" DO="MMXU2$MX$TotPF" DA="mag$f" />
|
||||
<Value name="三相功率因数最大值值" desc="总功率因数最大值" type="6" DO="MMXU3$MX$TotPF" DA="mag$f" />
|
||||
<Value name="三相功率因数最小值值" desc="总功率因数最小值" type="6" DO="MMXU4$MX$TotPF" DA="mag$f" />
|
||||
<Value name="三相位移功率因数平均值值" desc="总基波功率因数平均值" type="6" DO="MHAI2$MX$HTotPF" DA="har[1]$mag$f" />
|
||||
<Value name="三相位移功率因数最大值值" desc="总基波功率因数最大值" type="6" DO="MHAI3$MX$HTotPF" DA="har[1]$mag$f" />
|
||||
<Value name="三相位移功率因数最小值值" desc="总基波功率因数最小值" type="6" DO="MHAI4$MX$HTotPF" DA="har[1]$mag$f" />
|
||||
<Value name="三相总视在功率平均值值" desc="总视在功率平均值" type="6" DO="MMXU2$MX$TotVA" DA="mag$f" />
|
||||
<Value name="三相总视在功率最大值值" desc="总视在功率最大值" type="6" DO="MMXU3$MX$TotVA" DA="mag$f" />
|
||||
<Value name="三相总视在功率最小值值" desc="总视在功率最小值" type="6" DO="MMXU4$MX$TotVA" DA="mag$f" />
|
||||
<Value name="三相总无功功率平均值值" desc="总无功功率平均值" type="6" DO="MMXU2$MX$TotVAr" DA="mag$f" />
|
||||
<Value name="三相总无功功率最大值值" desc="总无功功率最大值" type="6" DO="MMXU3$MX$TotVAr" DA="mag$f" />
|
||||
<Value name="三相总无功功率最小值值" desc="总无功功率最小值" type="6" DO="MMXU4$MX$TotVAr" DA="mag$f" />
|
||||
<Value name="三相总有功功率平均值值" desc="总有功功率平均值" type="6" DO="MMXU2$MX$TotW" DA="mag$f" />
|
||||
<Value name="三相总有功功率最大值值" desc="总有功功率最大值" type="6" DO="MMXU3$MX$TotW" DA="mag$f" />
|
||||
<Value name="三相总有功功率最小值值" desc="总有功功率最小值" type="6" DO="MMXU4$MX$TotW" DA="mag$f" />
|
||||
Reference in New Issue
Block a user