波形解析代码移植

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); waveDataDTO.setListWaveData(listWaveData);
//add by hongawen,将暂态触发起始时间记录下来 //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****/ /*****根据通道号计算相别** add by yexb -----end****/
return waveDataDTO; return waveDataDTO;
@@ -513,13 +513,23 @@ public class WaveFileComponent {
//抽点后新的的采样率 //抽点后新的的采样率
List<RateDTO> newLstRate = new ArrayList<>(); List<RateDTO> newLstRate = new ArrayList<>();
for (int iRate = 0; iRate < comtradeCfgDTO.getNRates(); iRate++) { for (int iRate = 0; iRate < comtradeCfgDTO.getNRates(); iRate++) {
if (comtradeCfgDTO.getLstRate().get(iRate).getNOneSample() >= 32) { // if (comtradeCfgDTO.getLstRate().get(iRate).getNOneSample() >= 32) {
// 计算本段录波总共有多少波形 // 计算本段录波总共有多少波形
nWaveNum = comtradeCfgDTO.getLstRate().get(iRate).getNSampleNum() / comtradeCfgDTO.getLstRate().get(iRate).getNOneSample(); nWaveNum = comtradeCfgDTO.getLstRate().get(iRate).getNSampleNum() / comtradeCfgDTO.getLstRate().get(iRate).getNOneSample();
//设置总波形大小 //设置总波形大小
comtradeCfgDTO.setNAllWaveNum(comtradeCfgDTO.getNAllWaveNum() + nWaveNum); comtradeCfgDTO.setNAllWaveNum(comtradeCfgDTO.getNAllWaveNum() + nWaveNum);
// 将最低采样率替换到本段录波内 // 将最低采样率替换到本段录波内
RateDTO tmpRateDTO = new RateDTO(); RateDTO tmpRateDTO = new RateDTO();
// 有效值标志,如果是有效值,那么就需要反向补点,而不是抽点
if (comtradeCfgDTO.getLstRate().get(iRate).getNOneSample() >= 32) {
//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); newLstRate.add(tmpRateDTO);
//iFlag =3 一定不进行抽点算法 //iFlag =3 一定不进行抽点算法
if (iType != 3) { if (iType != 3) {
@@ -540,10 +550,11 @@ public class WaveFileComponent {
} }
// 正常的配置中采样率 // 正常的配置中采样率
comtradeCfgDTO.getLstRate().get(nnInd).setNOneSample(comtradeCfgDTO.getLstRate().get(iRate).getNOneSample()); /* comtradeCfgDTO.getLstRate().get(nnInd).setNOneSample(comtradeCfgDTO.getLstRate().get(iRate).getNOneSample());
comtradeCfgDTO.getLstRate().get(nnInd).setNSampleNum(comtradeCfgDTO.getLstRate().get(iRate).getNSampleNum()); comtradeCfgDTO.getLstRate().get(nnInd).setNSampleNum(comtradeCfgDTO.getLstRate().get(iRate).getNSampleNum());*/
nnInd++; nnInd++;
} // }
} }
// 偏移量,采样间隔 // 偏移量,采样间隔
long nOffSet = 0, nWaveSpan; long nOffSet = 0, nWaveSpan;
@@ -557,8 +568,6 @@ public class WaveFileComponent {
// nBlockNum 总循环次数 // nBlockNum 总循环次数
for (int i = 0; i < nBlockNum; i++) { for (int i = 0; i < nBlockNum; i++) {
tmpRateDTO = comtradeCfgDTO.getLstRate().get(nIndex); tmpRateDTO = comtradeCfgDTO.getLstRate().get(nIndex);
// 计算本段抽点采样间隔
nWaveSpan = tmpRateDTO.getNOneSample() / newLstRate.get(nIndex).getNOneSample();
// 判断是否进入下一段 // 判断是否进入下一段
if (i == tmpRateDTO.getNSampleNum() + nOffSet) { if (i == tmpRateDTO.getNSampleNum() + nOffSet) {
nOffSet += tmpRateDTO.getNSampleNum(); nOffSet += tmpRateDTO.getNSampleNum();
@@ -567,57 +576,175 @@ public class WaveFileComponent {
break; 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(); dfValue = (float) 20 / tmpRateDTO.getNOneSample();
// 判断是否到了需要抽的采样点 // 判断是否到了需要抽的采样点
if (i % nWaveSpan == 0) { if (i % nWaveSpan == 0) {
// 计算每个通道的值 // 计算每个通道的值
//存储局部数据集合包含了时间ABC三相 //存储局部数据集合包含了时间ABC三相
List<Float> tmpWaveData = new ArrayList<>(); List<Float> tmpWaveData = new ArrayList<>();
AnalogDTO tmpAnalogDTO; //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++) { for (int j = 0; j < comtradeCfgDTO.getNAnalogNum(); j++) {
tmpAnalogDTO = comtradeCfgDTO.getLstAnalogDTO().get(j);
//数据只有电压ABC三相数据不展示U0、I0等数据 YXB2020-10-09 去除相别为N相的数据 //数据只有电压ABC三相数据不展示U0、I0等数据 YXB2020-10-09 去除相别为N相的数据
if ("N".equalsIgnoreCase(tmpAnalogDTO.getSzPhasicName())) { if (comtradeCfgDTO.getLstAnalogDTO().get(j).getSzPhasicName().equalsIgnoreCase("N")) {
break; break;
} }
float fCoef = tmpAnalogDTO.getFCoefficent(); float fCoef = comtradeCfgDTO.getLstAnalogDTO().get(j).getFCoefficent();
fValue = BitConverter.byte2ToUnsignedShort(datArray, i * nBlockSize + 2 * 4 + j * 2) * fCoef; fValue = BitConverter.byte2ToUnsignedShort(datArray, i * nBlockSize + 2 * 4 + j * 2) * fCoef;
//WW 2019-11-14
//WW 2019-11-14//P是一次值 S是二次值 /*************************
if ("S".equalsIgnoreCase(tmpAnalogDTO.getSzValueType())) { * 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 //判断单位是V还是kV
if ("KV".equalsIgnoreCase(tmpAnalogDTO.getSzUnitName())) { if (comtradeCfgDTO.getLstAnalogDTO().get(j).getSzUnitName().equalsIgnoreCase("KV")) {
fValue = fValue * 1000.0f; fValue = fValue * 1000.0f;
} else {
fValue = fValue;
} }
} }
//P是一次值 S是二次值 //P是一次值 S是二次值
else if ("P".equalsIgnoreCase(tmpAnalogDTO.getSzValueType())) { else if (comtradeCfgDTO.getLstAnalogDTO().get(j).getSzValueType().equalsIgnoreCase("P")) {
//判断单位是V还是kV //判断单位是V还是kV
if ("V".equalsIgnoreCase(tmpAnalogDTO.getSzUnitName())) { if (comtradeCfgDTO.getLstAnalogDTO().get(j).getSzUnitName().equalsIgnoreCase("V")) {
//根据cfg内的变比将一次值转换成二次值 //根据cfg内的变比将一次值转换成二次值
if (tmpAnalogDTO.getFPrimary() != 0.0f) { if (comtradeCfgDTO.getLstAnalogDTO().get(j).getFPrimary() != 0.0f) {
fValue = fValue * tmpAnalogDTO.getFSecondary() / tmpAnalogDTO.getFPrimary(); fValue = fValue * comtradeCfgDTO.getLstAnalogDTO().get(j).getFSecondary() / comtradeCfgDTO.getLstAnalogDTO().get(j).getFPrimary();
} else {
fValue = fValue;
} }
} }
//判断单位是V还是kV //判断单位是V还是kV
else if ("KV".equalsIgnoreCase(tmpAnalogDTO.getSzUnitName())) { else if (comtradeCfgDTO.getLstAnalogDTO().get(j).getSzUnitName().equalsIgnoreCase("KV")) {
//根据cfg内的变比将一次值转换成二次值 //根据cfg内的变比将一次值转换成二次值
if (tmpAnalogDTO.getFPrimary() != 0.0f) { if (comtradeCfgDTO.getLstAnalogDTO().get(j).getFPrimary() != 0.0f) {
fValue = fValue * 1000.0f * tmpAnalogDTO.getFSecondary() / tmpAnalogDTO.getFPrimary(); fValue = fValue * 1000.0f * comtradeCfgDTO.getLstAnalogDTO().get(j).getFSecondary() / comtradeCfgDTO.getLstAnalogDTO().get(j).getFPrimary();
} else {
fValue = fValue;
} }
} } else //还有可能是 电流单位是A
//还有可能是电流单位是A {
else {
//根据cfg内的变比将一次值转换成二次值 //根据cfg内的变比将一次值转换成二次值
if (tmpAnalogDTO.getFPrimary() != 0.0f) { if (comtradeCfgDTO.getLstAnalogDTO().get(j).getFPrimary() != 0.0f) {
fValue = tmpAnalogDTO.getFSecondary() / tmpAnalogDTO.getFPrimary(); fValue = comtradeCfgDTO.getLstAnalogDTO().get(j).getFSecondary() / comtradeCfgDTO.getLstAnalogDTO().get(j).getFPrimary();
} else {
fValue = fValue;
} }
} }
} }
//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) dfValue / nWaveSpan;
//只增加一个xValue的值 //增加时间值
tmpWaveData.add((float) (Math.round(xValueAll * 100)) / 100);
}
//不同通道yValue的值都需要增加最终成ABC三相 //每个通道的值
tmpWaveData.add((float) (Math.round(fValue * 100)) / 100);
}
//把每个单独的值赋予到整体里面去
listWaveData.add(tmpWaveData);
}
// 把每个单独的值赋予到整体里面去
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;
}
}
//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前移量假如是第一次时候则需要前移 //xValue前移量假如是第一次时候则需要前移
if (!blxValue && j == 0) { if (!blxValue && j == 0) {
xValueAll = (float) (i * 20) / tmpRateDTO.getNOneSample() - comtradeCfgDTO.getNPush(); xValueAll = (float) (i * 20) / tmpRateDTO.getNOneSample() - comtradeCfgDTO.getNPush();
@@ -638,6 +765,7 @@ public class WaveFileComponent {
} }
} }
} }
}
} catch (Exception e) { } catch (Exception e) {
throw new BusinessException(WaveFileResponseEnum.DAT_DATA_ERROR); throw new BusinessException(WaveFileResponseEnum.DAT_DATA_ERROR);
} }
@@ -656,12 +784,13 @@ public class WaveFileComponent {
int nFinalOneSample = -1; int nFinalOneSample = -1;
// 最小采样率 // 最小采样率
int nMinOneSample = -1; int nMinOneSample = -1;
if (lstRate.size() > 0) { if (!lstRate.isEmpty()) {
nMinOneSample = lstRate.get(0).getNOneSample(); nMinOneSample = lstRate.get(0).getNOneSample();
int tmpOneSample; int tmpOneSample;
for (RateDTO rateDTO : lstRate) { for (RateDTO rateDTO : lstRate) {
tmpOneSample = rateDTO.getNOneSample(); tmpOneSample = rateDTO.getNOneSample();
if (tmpOneSample >= 32) { //YXB 2025-08-27 32->16
if (tmpOneSample >= 16) {
if (nMinOneSample > tmpOneSample) { if (nMinOneSample > tmpOneSample) {
nMinOneSample = tmpOneSample; nMinOneSample = tmpOneSample;
} }
@@ -680,7 +809,7 @@ public class WaveFileComponent {
nFinalOneSample = 32; nFinalOneSample = 32;
} else if (nMinOneSample > 128) { } else if (nMinOneSample > 128) {
nFinalOneSample = 128; nFinalOneSample = 128;
}else { } else {
nFinalOneSample = nMinOneSample; nFinalOneSample = nMinOneSample;
} }
break; break;

View File

@@ -1,8 +1,5 @@
package com.njcn.event.file.pojo.dto; 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.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;

View File

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