波形解析代码移植

This commit is contained in:
2025-09-01 10:23:04 +08:00
parent 59aad2c89c
commit 0043a21455
3 changed files with 215 additions and 86 deletions

View File

@@ -75,7 +75,7 @@ public class WaveFileComponent {
waveDataDTO.setListWaveData(listWaveData);
//add by hongawen,将暂态触发起始时间记录下来
waveDataDTO.setTime(DateUtil.format(comtradeCfgDTO.getTimeTrige(),DatePattern.NORM_DATETIME_MS_PATTERN));
waveDataDTO.setTime(DateUtil.format(comtradeCfgDTO.getTimeTrige(), DatePattern.NORM_DATETIME_MS_PATTERN));
/*****根据通道号计算相别** add by yexb -----end****/
return waveDataDTO;
@@ -513,37 +513,48 @@ public class WaveFileComponent {
//抽点后新的的采样率
List<RateDTO> newLstRate = new ArrayList<>();
for (int iRate = 0; iRate < comtradeCfgDTO.getNRates(); iRate++) {
// if (comtradeCfgDTO.getLstRate().get(iRate).getNOneSample() >= 32) {
// 计算本段录波总共有多少波形
nWaveNum = comtradeCfgDTO.getLstRate().get(iRate).getNSampleNum() / comtradeCfgDTO.getLstRate().get(iRate).getNOneSample();
//设置总波形大小
comtradeCfgDTO.setNAllWaveNum(comtradeCfgDTO.getNAllWaveNum() + nWaveNum);
// 将最低采样率替换到本段录波内
RateDTO tmpRateDTO = new RateDTO();
// 有效值标志,如果是有效值,那么就需要反向补点,而不是抽点
if (comtradeCfgDTO.getLstRate().get(iRate).getNOneSample() >= 32) {
// 计算本段录波总共有多少波形
nWaveNum = comtradeCfgDTO.getLstRate().get(iRate).getNSampleNum() / comtradeCfgDTO.getLstRate().get(iRate).getNOneSample();
//设置总波形大小
comtradeCfgDTO.setNAllWaveNum(comtradeCfgDTO.getNAllWaveNum() + nWaveNum);
// 将最低采样率替换到本段录波内
RateDTO tmpRateDTO = new RateDTO();
newLstRate.add(tmpRateDTO);
//iFlag =3 一定不进行抽点算法
if (iType != 3) {
//true 抽点算法(当前采样率跟统一采样率不一样则是抽点,否则是未抽点)
if (!Objects.equals(comtradeCfgDTO.getLstRate().get(iRate).getNOneSample(), comtradeCfgDTO.getFinalSampleRate())) {
newLstRate.get(nnInd).setNOneSample(comtradeCfgDTO.getFinalSampleRate());
// 计算本段录波按照最低采样点应该有多少录波
newLstRate.get(nnInd).setNSampleNum(comtradeCfgDTO.getFinalSampleRate() * nWaveNum);
} else {
newLstRate.get(nnInd).setNOneSample(comtradeCfgDTO.getLstRate().get(iRate).getNOneSample());
// 计算本段录波按照最低采样点应该有多少录波
newLstRate.get(nnInd).setNSampleNum(comtradeCfgDTO.getLstRate().get(iRate).getNOneSample() * nWaveNum);
}
//YXB 2025-08-27
tmpRateDTO.bRMSFlag = false;
}
//如果采样是全波有效值或者半波有效值,需要去补足周波点数 YXB 2025-08-27
else if (comtradeCfgDTO.getLstRate().get(iRate).getNOneSample() <= 2) {
//YXB 2025-08-27
tmpRateDTO.bRMSFlag = true;
}
newLstRate.add(tmpRateDTO);
//iFlag =3 一定不进行抽点算法
if (iType != 3) {
//true 抽点算法(当前采样率跟统一采样率不一样则是抽点,否则是未抽点)
if (!Objects.equals(comtradeCfgDTO.getLstRate().get(iRate).getNOneSample(), comtradeCfgDTO.getFinalSampleRate())) {
newLstRate.get(nnInd).setNOneSample(comtradeCfgDTO.getFinalSampleRate());
// 计算本段录波按照最低采样点应该有多少录波
newLstRate.get(nnInd).setNSampleNum(comtradeCfgDTO.getFinalSampleRate() * nWaveNum);
} else {
newLstRate.get(nnInd).setNOneSample(comtradeCfgDTO.getLstRate().get(iRate).getNOneSample());
// 计算本段录波按照最低采样点应该有多少录波
newLstRate.get(nnInd).setNSampleNum(comtradeCfgDTO.getLstRate().get(iRate).getNOneSample() * nWaveNum);
}
// 正常的配置中采样率
comtradeCfgDTO.getLstRate().get(nnInd).setNOneSample(comtradeCfgDTO.getLstRate().get(iRate).getNOneSample());
comtradeCfgDTO.getLstRate().get(nnInd).setNSampleNum(comtradeCfgDTO.getLstRate().get(iRate).getNSampleNum());
nnInd++;
} else {
newLstRate.get(nnInd).setNOneSample(comtradeCfgDTO.getLstRate().get(iRate).getNOneSample());
// 计算本段录波按照最低采样点应该有多少录波
newLstRate.get(nnInd).setNSampleNum(comtradeCfgDTO.getLstRate().get(iRate).getNOneSample() * nWaveNum);
}
// 正常的配置中采样率
/* comtradeCfgDTO.getLstRate().get(nnInd).setNOneSample(comtradeCfgDTO.getLstRate().get(iRate).getNOneSample());
comtradeCfgDTO.getLstRate().get(nnInd).setNSampleNum(comtradeCfgDTO.getLstRate().get(iRate).getNSampleNum());*/
nnInd++;
// }
}
// 偏移量,采样间隔
long nOffSet = 0, nWaveSpan;
@@ -557,8 +568,6 @@ public class WaveFileComponent {
// nBlockNum 总循环次数
for (int i = 0; i < nBlockNum; i++) {
tmpRateDTO = comtradeCfgDTO.getLstRate().get(nIndex);
// 计算本段抽点采样间隔
nWaveSpan = tmpRateDTO.getNOneSample() / newLstRate.get(nIndex).getNOneSample();
// 判断是否进入下一段
if (i == tmpRateDTO.getNSampleNum() + nOffSet) {
nOffSet += tmpRateDTO.getNSampleNum();
@@ -567,74 +576,193 @@ public class WaveFileComponent {
break;
}
}
//YXB 2025-08-27 如果是有效值,那么需要去补点,而不是抽点
if (newLstRate.get(nIndex).bRMSFlag == true) {
//计算本段补点采样间隔
nWaveSpan = newLstRate.get(nIndex).getNOneSample() / tmpRateDTO.getNOneSample();
} else {
// 计算本段抽点采样间隔
nWaveSpan = tmpRateDTO.getNOneSample() / newLstRate.get(nIndex).getNOneSample();
}
dfValue = (float) 20 / tmpRateDTO.getNOneSample();
// 判断是否到了需要抽的采样点
if (i % nWaveSpan == 0) {
// 计算每个通道的值
//存储局部数据集合包含了时间ABC三相
List<Float> tmpWaveData = new ArrayList<>();
AnalogDTO tmpAnalogDTO;
for (int j = 0; j < comtradeCfgDTO.getNAnalogNum(); j++) {
tmpAnalogDTO = comtradeCfgDTO.getLstAnalogDTO().get(j);
//数据只有电压ABC三相数据不展示U0、I0等数据 YXB2020-10-09 去除相别为N相的数据
if ("N".equalsIgnoreCase(tmpAnalogDTO.getSzPhasicName())) {
break;
}
float fCoef = tmpAnalogDTO.getFCoefficent();
fValue = BitConverter.byte2ToUnsignedShort(datArray, i * nBlockSize + 2 * 4 + j * 2) * fCoef;
//WW 2019-11-14//P是一次值 S是二次值
if ("S".equalsIgnoreCase(tmpAnalogDTO.getSzValueType())) {
//判断单位是V还是kV
if ("KV".equalsIgnoreCase(tmpAnalogDTO.getSzUnitName())) {
fValue = fValue * 1000.0f;
}
}
//P是一次值 S是二次值
else if ("P".equalsIgnoreCase(tmpAnalogDTO.getSzValueType())) {
//判断单位是V还是kV
if ("V".equalsIgnoreCase(tmpAnalogDTO.getSzUnitName())) {
//根据cfg内的变比将一次值转换成二次值
if (tmpAnalogDTO.getFPrimary() != 0.0f) {
fValue = fValue * tmpAnalogDTO.getFSecondary() / tmpAnalogDTO.getFPrimary();
//YXB 2025-08-27 如果是有效值,那么需要去补点,而不是抽点
if (newLstRate.get(nIndex).bRMSFlag == true) {
// 计算有多少个周波
long allWaveTemp = newLstRate.get(nIndex).getNSampleNum() / newLstRate.get(nIndex).getNOneSample();
// 本段需要补多少点
long allempSample = newLstRate.get(nIndex).getNOneSample();
//int iStartWaveTemp = i ;// 开始补点的起点
for (int iWaveTemp = 0; iWaveTemp < allWaveTemp; iWaveTemp++) {
for (int mTempSample = 0; mTempSample < allempSample; mTempSample++) {
//最多只有半波有效值也就是每周波是1个或者2个点然后去补最少16个点
if (mTempSample / nWaveSpan == 1 && mTempSample % nWaveSpan == 0) {
i++;
}
//存储局部数据集合包含了时间ABC三相
tmpWaveData = new ArrayList<>();
for (int j = 0; j < comtradeCfgDTO.getNAnalogNum(); j++) {
//数据只有电压ABC三相数据不展示U0、I0等数据 YXB2020-10-09 去除相别为N相的数据
if (comtradeCfgDTO.getLstAnalogDTO().get(j).getSzPhasicName().equalsIgnoreCase("N")) {
break;
}
float fCoef = comtradeCfgDTO.getLstAnalogDTO().get(j).getFCoefficent();
fValue = BitConverter.byte2ToUnsignedShort(datArray, i * nBlockSize + 2 * 4 + j * 2) * fCoef;
//WW 2019-11-14
/*************************
* 1、接口返回的默认是二次值
* 2、P是一次值 S是二次值
* 3、S(二次值)情况下:
* ①、单位为"V"时候则直接等于;
* ②、单位为"kV"时候需要乘以1000
* 4、P(一次值)情况下:
* ①、单位为"V"时候则直接等于;
* ②、单位为"kV"时候需要乘以1000
*************************/
//P是一次值 S是二次值
if (comtradeCfgDTO.getLstAnalogDTO().get(j).getSzValueType().equalsIgnoreCase("S")) {
//判断单位是V还是kV
if (comtradeCfgDTO.getLstAnalogDTO().get(j).getSzUnitName().equalsIgnoreCase("KV")) {
fValue = fValue * 1000.0f;
} else {
fValue = fValue;
}
}
//P是一次值 S是二次值
else if (comtradeCfgDTO.getLstAnalogDTO().get(j).getSzValueType().equalsIgnoreCase("P")) {
//判断单位是V还是kV
if (comtradeCfgDTO.getLstAnalogDTO().get(j).getSzUnitName().equalsIgnoreCase("V")) {
//根据cfg内的变比将一次值转换成二次值
if (comtradeCfgDTO.getLstAnalogDTO().get(j).getFPrimary() != 0.0f) {
fValue = fValue * comtradeCfgDTO.getLstAnalogDTO().get(j).getFSecondary() / comtradeCfgDTO.getLstAnalogDTO().get(j).getFPrimary();
} else {
fValue = fValue;
}
}
//判断单位是V还是kV
else if (comtradeCfgDTO.getLstAnalogDTO().get(j).getSzUnitName().equalsIgnoreCase("KV")) {
//根据cfg内的变比将一次值转换成二次值
if (comtradeCfgDTO.getLstAnalogDTO().get(j).getFPrimary() != 0.0f) {
fValue = fValue * 1000.0f * comtradeCfgDTO.getLstAnalogDTO().get(j).getFSecondary() / comtradeCfgDTO.getLstAnalogDTO().get(j).getFPrimary();
} else {
fValue = fValue;
}
} else //还有可能是 电流单位是A
{
//根据cfg内的变比将一次值转换成二次值
if (comtradeCfgDTO.getLstAnalogDTO().get(j).getFPrimary() != 0.0f) {
fValue = comtradeCfgDTO.getLstAnalogDTO().get(j).getFSecondary() / comtradeCfgDTO.getLstAnalogDTO().get(j).getFPrimary();
} else {
fValue = fValue;
}
}
}
//xValue前移量假如是第一次时候则需要前移
if (!blxValue && j == 0) {
xValueAll = (float) (i * 20) / tmpRateDTO.getNOneSample() - comtradeCfgDTO.getNPush();
blxValue = true;
//只增加一个xValue的值 //增加时间值
tmpWaveData.add((float) (Math.round(xValueAll * 100)) / 100);
} else if (j == 0) {
xValueAll += (float) dfValue / nWaveSpan;
//只增加一个xValue的值 //增加时间值
tmpWaveData.add((float) (Math.round(xValueAll * 100)) / 100);
}
//不同通道yValue的值都需要增加最终成ABC三相 //每个通道的值
tmpWaveData.add((float) (Math.round(fValue * 100)) / 100);
}
//把每个单独的值赋予到整体里面去
listWaveData.add(tmpWaveData);
}
//判断单位是V还是kV
else if ("KV".equalsIgnoreCase(tmpAnalogDTO.getSzUnitName())) {
//根据cfg内的变比将一次值转换成二次值
if (tmpAnalogDTO.getFPrimary() != 0.0f) {
fValue = fValue * 1000.0f * tmpAnalogDTO.getFSecondary() / tmpAnalogDTO.getFPrimary();
// 把每个单独的值赋予到整体里面去
if (iWaveTemp < (allWaveTemp - 1)) {
i++;
}
}
} else {
for (int j = 0; j < comtradeCfgDTO.getNAnalogNum(); j++) {
//数据只有电压ABC三相数据不展示U0、I0等数据 YXB2020-10-09 去除相别为N相的数据
if (comtradeCfgDTO.getLstAnalogDTO().get(j).getSzPhasicName().equalsIgnoreCase("N")) {
break;
}
float fCoef = comtradeCfgDTO.getLstAnalogDTO().get(j).getFCoefficent();
fValue = BitConverter.byte2ToUnsignedShort(datArray, i * nBlockSize + 2 * 4 + j * 2) * fCoef;
//WW 2019-11-14
/**************************
* 1、接口返回的默认是二次值
* 2、P是一次值 S是二次值
* 3、S(二次值)情况下:
* ①、单位为"V"时候则直接等于;
* ②、单位为"kV"时候需要乘以1000
* 4、P(一次值)情况下:
* ①、单位为"V"时候则直接等于;
* ②、单位为"kV"时候需要乘以1000
**************************/
//P是一次值 S是二次值
if (comtradeCfgDTO.getLstAnalogDTO().get(j).getSzValueType().equalsIgnoreCase("S")) {
//判断单位是V还是kV
if (comtradeCfgDTO.getLstAnalogDTO().get(j).getSzUnitName().equalsIgnoreCase("KV")) {
fValue = fValue * 1000.0f;
} else {
fValue = fValue;
}
}
//还有可能是电流单位是A
else {
//根据cfg内的变比将一次值转换成二次值
if (tmpAnalogDTO.getFPrimary() != 0.0f) {
fValue = tmpAnalogDTO.getFSecondary() / tmpAnalogDTO.getFPrimary();
//P是一次值 S是二次值
else if (comtradeCfgDTO.getLstAnalogDTO().get(j).getSzValueType().equalsIgnoreCase("P")) {
//判断单位是V还是kV
if (comtradeCfgDTO.getLstAnalogDTO().get(j).getSzUnitName().equalsIgnoreCase("V")) {
//根据cfg内的变比将一次值转换成二次值
if (comtradeCfgDTO.getLstAnalogDTO().get(j).getFPrimary() != 0.0f) {
fValue = fValue * comtradeCfgDTO.getLstAnalogDTO().get(j).getFSecondary() / comtradeCfgDTO.getLstAnalogDTO().get(j).getFPrimary();
} else {
fValue = fValue;
}
}
//判断单位是V还是kV
else if (comtradeCfgDTO.getLstAnalogDTO().get(j).getSzUnitName().equalsIgnoreCase("KV")) {
//根据cfg内的变比将一次值转换成二次值
if (comtradeCfgDTO.getLstAnalogDTO().get(j).getFPrimary() != 0.0f) {
fValue = fValue * 1000.0f * comtradeCfgDTO.getLstAnalogDTO().get(j).getFSecondary() / comtradeCfgDTO.getLstAnalogDTO().get(j).getFPrimary();
} else {
fValue = fValue;
}
} else //还有可能是 电流单位是A
{
//根据cfg内的变比将一次值转换成二次值
if (comtradeCfgDTO.getLstAnalogDTO().get(j).getFPrimary() != 0.0f) {
fValue = comtradeCfgDTO.getLstAnalogDTO().get(j).getFSecondary() / comtradeCfgDTO.getLstAnalogDTO().get(j).getFPrimary();
} else {
fValue = fValue;
}
}
}
//xValue前移量假如是第一次时候则需要前移
if (!blxValue && j == 0) {
xValueAll = (float) (i * 20) / tmpRateDTO.getNOneSample() - comtradeCfgDTO.getNPush();
blxValue = true;
//只增加一个xValue的值 //增加时间值
tmpWaveData.add((float) (Math.round(xValueAll * 100)) / 100);
} else if (j == 0) {
xValueAll += (float) nWaveSpan * dfValue;
//只增加一个xValue的值 //增加时间值
tmpWaveData.add((float) (Math.round(xValueAll * 100)) / 100);
}
//不同通道yValue的值都需要增加最终成ABC三相 //每个通道的值
tmpWaveData.add((float) (Math.round(fValue * 100)) / 100);
}
//ComtradeCfg.OneChannleCfg.get(j)
//xValue前移量假如是第一次时候则需要前移
if (!blxValue && j == 0) {
xValueAll = (float) (i * 20) / tmpRateDTO.getNOneSample() - comtradeCfgDTO.getNPush();
blxValue = true;
//只增加一个xValue的值 //增加时间值
tmpWaveData.add((float) (Math.round(xValueAll * 100)) / 100);
} else if (j == 0) {
xValueAll += (float) nWaveSpan * dfValue;
//只增加一个xValue的值 //增加时间值
tmpWaveData.add((float) (Math.round(xValueAll * 100)) / 100);
}
//不同通道yValue的值都需要增加最终成ABC三相 //每个通道的值
tmpWaveData.add((float) (Math.round(fValue * 100)) / 100);
//把每个单独的值赋予到整体里面去
listWaveData.add(tmpWaveData);
}
//把每个单独的值赋予到整体里面去
listWaveData.add(tmpWaveData);
}
}
}
@@ -656,12 +784,13 @@ public class WaveFileComponent {
int nFinalOneSample = -1;
// 最小采样率
int nMinOneSample = -1;
if (lstRate.size() > 0) {
if (!lstRate.isEmpty()) {
nMinOneSample = lstRate.get(0).getNOneSample();
int tmpOneSample;
for (RateDTO rateDTO : lstRate) {
tmpOneSample = rateDTO.getNOneSample();
if (tmpOneSample >= 32) {
//YXB 2025-08-27 32->16
if (tmpOneSample >= 16) {
if (nMinOneSample > tmpOneSample) {
nMinOneSample = tmpOneSample;
}
@@ -680,7 +809,7 @@ public class WaveFileComponent {
nFinalOneSample = 32;
} else if (nMinOneSample > 128) {
nFinalOneSample = 128;
}else {
} else {
nFinalOneSample = nMinOneSample;
}
break;

View File

@@ -1,8 +1,5 @@
package com.njcn.event.file.pojo.dto;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

View File

@@ -21,4 +21,7 @@ public class RateDTO implements Serializable {
private Integer nOneSample;
// 总采样点数
private Integer nSampleNum;
//有效值标志,如果是有效值,那么就需要反向补点,而不是抽点
public Boolean bRMSFlag;//YXB 2025-08-27
}