动态库名称调整
This commit is contained in:
@@ -0,0 +1,132 @@
|
|||||||
|
package com.njcn.advance.event.cause.jna;
|
||||||
|
|
||||||
|
import com.sun.jna.Library;
|
||||||
|
import com.sun.jna.Native;
|
||||||
|
import com.sun.jna.Structure;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JNA接口调用qvvr_dll.dll
|
||||||
|
*/
|
||||||
|
public interface QvvrCauseDLL extends Library {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载DLL - 从resource目录或classpath
|
||||||
|
*/
|
||||||
|
QvvrCauseDLL INSTANCE = loadLibrary();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支持jar打包的库加载方法 - 从jar内resources提取到临时目录后加载
|
||||||
|
*/
|
||||||
|
static QvvrCauseDLL loadLibrary() {
|
||||||
|
String osName = System.getProperty("os.name").toLowerCase();
|
||||||
|
String libFileName;
|
||||||
|
String resourcePath;
|
||||||
|
|
||||||
|
// 根据操作系统确定库文件名
|
||||||
|
if (osName.contains("windows")) {
|
||||||
|
libFileName = "qvvr_cause_dll.dll";
|
||||||
|
resourcePath = "/qvvr_cause_dll.dll";
|
||||||
|
} else if (osName.contains("linux")) {
|
||||||
|
libFileName = "libqvvr_cause_dll.so";
|
||||||
|
resourcePath = "/libqvvr_cause_dll.so";
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedOperationException("不支持的操作系统: " + osName);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 从jar中提取库文件到临时目录
|
||||||
|
File tempLibFile = extractLibraryFromJar(resourcePath, libFileName);
|
||||||
|
|
||||||
|
// 加载提取的库文件
|
||||||
|
System.out.println("加载库文件: " + tempLibFile.getAbsolutePath());
|
||||||
|
return Native.load(tempLibFile.getAbsolutePath(), QvvrCauseDLL.class);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"无法加载QVVR库文件。\n" +
|
||||||
|
"请确保文件 " + libFileName + " 存在于 src/main/resources/ 目录下。\n" +
|
||||||
|
"当前操作系统: " + osName,
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从jar中提取库文件到临时目录
|
||||||
|
*/
|
||||||
|
static File extractLibraryFromJar(String resourcePath, String libFileName) throws IOException {
|
||||||
|
// 获取资源输入流
|
||||||
|
InputStream libStream = QvvrCauseDLL.class.getResourceAsStream(resourcePath);
|
||||||
|
if (libStream == null) {
|
||||||
|
throw new FileNotFoundException("在jar中找不到库文件: " + resourcePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建临时文件
|
||||||
|
String tempDir = System.getProperty("java.io.tmpdir");
|
||||||
|
File tempLibFile = new File(tempDir, "qvvr_" + System.currentTimeMillis() + "_" + libFileName);
|
||||||
|
|
||||||
|
// 提取库文件到临时目录
|
||||||
|
try (FileOutputStream out = new FileOutputStream(tempLibFile)) {
|
||||||
|
byte[] buffer = new byte[8192];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = libStream.read(buffer)) != -1) {
|
||||||
|
out.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
libStream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置为可执行
|
||||||
|
tempLibFile.setExecutable(true);
|
||||||
|
tempLibFile.setReadable(true);
|
||||||
|
|
||||||
|
// JVM退出时删除临时文件
|
||||||
|
tempLibFile.deleteOnExit();
|
||||||
|
|
||||||
|
System.out.println("已提取库文件到: " + tempLibFile.getAbsolutePath());
|
||||||
|
return tempLibFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直接调用C DLL的qvvr_fun_cause函数
|
||||||
|
* void __stdcall qvvr_fun_cause(void *data)
|
||||||
|
*/
|
||||||
|
void qvvr_fun_cause(QvvrDataStruct data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对应C语言的qvvr_data_struct结构体
|
||||||
|
* 完全按照qvvr_dll.h中的定义映射
|
||||||
|
*/
|
||||||
|
public static class QvvrDataStruct extends Structure {
|
||||||
|
|
||||||
|
// 输入参数定义
|
||||||
|
public float[] smp_va = new float[128 * 50 * 120]; // A相电压采样数据
|
||||||
|
public float[] smp_vb = new float[128 * 50 * 120]; // B相电压采样数据
|
||||||
|
public float[] smp_vc = new float[128 * 50 * 120]; // C相电压采样数据
|
||||||
|
public int smp_rate; // 采样率参数
|
||||||
|
public int smp_len; // 每个通道的采样数据个数
|
||||||
|
|
||||||
|
// 输入阈值参数
|
||||||
|
public float[] threshold = new float[50]; // 预设阈值时间参数
|
||||||
|
|
||||||
|
// 输出结果参数定义
|
||||||
|
public int cause; // 电压暂降判断出暂降原因 0-未知,1-短路,2-电压调节器,3-感动电机
|
||||||
|
public int no_cal; // 未计算判断标志,该位1表示输入数据有问题(数据缺失或异常等)未进行电压暂降判断暂降原因
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<String> getFieldOrder() {
|
||||||
|
return Arrays.asList("smp_va", "smp_vb", "smp_vc", "smp_rate", "smp_len", "threshold", "cause", "no_cal");
|
||||||
|
}
|
||||||
|
|
||||||
|
public QvvrDataStruct() {
|
||||||
|
super();
|
||||||
|
// 初始化输出参数
|
||||||
|
this.cause = 0;
|
||||||
|
this.no_cal = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.njcn.advance.event.service;
|
package com.njcn.advance.event.service;
|
||||||
|
|
||||||
import com.njcn.advance.event.cause.core.VoltageSagAnalyzer;
|
import com.njcn.advance.event.cause.core.VoltageSagAnalyzer;
|
||||||
|
import com.njcn.advance.event.cause.jna.QvvrCauseDLL;
|
||||||
import com.njcn.advance.event.cause.model.AnalysisResult;
|
import com.njcn.advance.event.cause.model.AnalysisResult;
|
||||||
import com.njcn.advance.event.cause.model.DataFeature;
|
import com.njcn.advance.event.cause.model.DataFeature;
|
||||||
import com.njcn.advance.event.cause.model.QvvrDataStruct;
|
import com.njcn.advance.event.cause.model.QvvrDataStruct;
|
||||||
@@ -30,7 +31,7 @@ public class Test {
|
|||||||
WaveFileComponent waveFileComponent = new WaveFileComponent();
|
WaveFileComponent waveFileComponent = new WaveFileComponent();
|
||||||
EventAnalysisDTO eventAnalysis = new EventAnalysisDTO();
|
EventAnalysisDTO eventAnalysis = new EventAnalysisDTO();
|
||||||
WaveDataDTO waveDataDTO;
|
WaveDataDTO waveDataDTO;
|
||||||
String waveName = "5";
|
String waveName = "11";
|
||||||
String cfgPath, datPath;
|
String cfgPath, datPath;
|
||||||
cfgPath = "D:\\comtrade\\00-B7-8D-00-FA-44" + File.separator + waveName + GeneralConstant.CFG;
|
cfgPath = "D:\\comtrade\\00-B7-8D-00-FA-44" + File.separator + waveName + GeneralConstant.CFG;
|
||||||
datPath = "D:\\comtrade\\00-B7-8D-00-FA-44" + File.separator + waveName + GeneralConstant.DAT;
|
datPath = "D:\\comtrade\\00-B7-8D-00-FA-44" + File.separator + waveName + GeneralConstant.DAT;
|
||||||
@@ -41,34 +42,64 @@ public class Test {
|
|||||||
throw new BusinessException(WaveFileResponseEnum.ANALYSE_WAVE_NOT_FOUND);
|
throw new BusinessException(WaveFileResponseEnum.ANALYSE_WAVE_NOT_FOUND);
|
||||||
}
|
}
|
||||||
waveDataDTO = waveFileComponent.getComtrade(cfgStream, datStream, 0);
|
waveDataDTO = waveFileComponent.getComtrade(cfgStream, datStream, 0);
|
||||||
|
// // java针对暂降原因分析的调用
|
||||||
|
// QvvrDataStruct qvvrDataStruct = new QvvrDataStruct();
|
||||||
|
// // 采样率
|
||||||
|
// qvvrDataStruct.setSmpRate(waveDataDTO.getComtradeCfgDTO().getFinalSampleRate());
|
||||||
|
// // 瞬时值
|
||||||
|
// List<List<Float>> listWaveData = waveDataDTO.getListWaveData();
|
||||||
|
// // 通道采样个数
|
||||||
|
// qvvrDataStruct.setSmpLen(listWaveData.size());
|
||||||
|
// // 获取ABC三相的瞬时数据
|
||||||
|
// // A相电压采样数据
|
||||||
|
// float[] smpVa = new float[listWaveData.size()];
|
||||||
|
// // B相电压采样数据
|
||||||
|
// float[] smpVb = new float[listWaveData.size()];
|
||||||
|
// // C相电压采样数据
|
||||||
|
// float[] smpVc = new float[listWaveData.size()];
|
||||||
|
// for (int i = 0; i < listWaveData.size(); i++) {
|
||||||
|
// smpVa[i] = listWaveData.get(i).get(1);
|
||||||
|
// smpVb[i] = listWaveData.get(i).get(2);
|
||||||
|
// smpVc[i] = listWaveData.get(i).get(3);
|
||||||
|
// }
|
||||||
|
// qvvrDataStruct.setSmpVa(smpVa);
|
||||||
|
// qvvrDataStruct.setSmpVb(smpVb);
|
||||||
|
// qvvrDataStruct.setSmpVc(smpVc);
|
||||||
|
//
|
||||||
|
// // 暂降原因
|
||||||
|
// VoltageSagAnalyzer voltageSagAnalyzer = new VoltageSagAnalyzer();
|
||||||
|
// try{
|
||||||
|
// AnalysisResult cause = voltageSagAnalyzer.analyzeVoltageSagWithDetails(qvvrDataStruct);
|
||||||
|
// eventAnalysis.setCause(cause.getCause());
|
||||||
|
// }catch (Exception e){
|
||||||
|
// log.error("DAT文件分析异常", e);
|
||||||
|
// eventAnalysis.setCause(DataFeature.CAUSE_TYPE0);
|
||||||
|
// eventAnalysis.setCauseFlag(0);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
QvvrDataStruct qvvrDataStruct = new QvvrDataStruct();
|
|
||||||
// 采样率
|
|
||||||
qvvrDataStruct.setSmpRate(waveDataDTO.getComtradeCfgDTO().getFinalSampleRate());
|
|
||||||
// 瞬时值
|
|
||||||
List<List<Float>> listWaveData = waveDataDTO.getListWaveData();
|
List<List<Float>> listWaveData = waveDataDTO.getListWaveData();
|
||||||
// 通道采样个数
|
|
||||||
qvvrDataStruct.setSmpLen(listWaveData.size());
|
|
||||||
// 获取ABC三相的瞬时数据
|
|
||||||
// A相电压采样数据
|
|
||||||
float[] smpVa = new float[listWaveData.size()];
|
|
||||||
// B相电压采样数据
|
|
||||||
float[] smpVb = new float[listWaveData.size()];
|
|
||||||
// C相电压采样数据
|
|
||||||
float[] smpVc = new float[listWaveData.size()];
|
|
||||||
for (int i = 0; i < listWaveData.size(); i++) {
|
|
||||||
smpVa[i] = listWaveData.get(i).get(1);
|
|
||||||
smpVb[i] = listWaveData.get(i).get(2);
|
|
||||||
smpVc[i] = listWaveData.get(i).get(3);
|
|
||||||
}
|
|
||||||
qvvrDataStruct.setSmpVa(smpVa);
|
|
||||||
qvvrDataStruct.setSmpVb(smpVb);
|
|
||||||
qvvrDataStruct.setSmpVc(smpVc);
|
|
||||||
VoltageSagAnalyzer voltageSagAnalyzer = new VoltageSagAnalyzer();
|
|
||||||
AnalysisResult cause = voltageSagAnalyzer.analyzeVoltageSagWithDetails(qvvrDataStruct);
|
|
||||||
log.info("DAT文件分析结果: 原因={} ({})", cause.getCause(), getCauseDescription(cause.getCause()));
|
|
||||||
|
|
||||||
|
// 暂降原因JNA的方式
|
||||||
|
com.njcn.advance.event.cause.jna.QvvrCauseDLL.QvvrDataStruct causeDataStruct = new com.njcn.advance.event.cause.jna.QvvrCauseDLL.QvvrDataStruct();
|
||||||
|
causeDataStruct.smp_rate = waveDataDTO.getComtradeCfgDTO().getFinalSampleRate();
|
||||||
|
causeDataStruct.smp_len = listWaveData.size();
|
||||||
|
// 获取ABC三相的瞬时数据
|
||||||
|
for (int i = 0; i < listWaveData.size(); i++) {
|
||||||
|
causeDataStruct.smp_va[i] = listWaveData.get(i).get(1);
|
||||||
|
causeDataStruct.smp_vb[i] = listWaveData.get(i).get(2);
|
||||||
|
causeDataStruct.smp_vc[i] = listWaveData.get(i).get(3);
|
||||||
|
}
|
||||||
|
// 执行算法分析 - 直接调用C DLL
|
||||||
|
try {
|
||||||
|
QvvrCauseDLL.INSTANCE.qvvr_fun_cause(causeDataStruct);
|
||||||
|
System.out.println("暂降原因: " + getCauseDescription(causeDataStruct.cause));
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("调用DLL失败: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 暂降类型JNA的方式
|
||||||
// 创建数据结构
|
// 创建数据结构
|
||||||
com.njcn.advance.event.type.jna.QvvrDLL.QvvrDataStruct typeDataStruct = new com.njcn.advance.event.type.jna.QvvrDLL.QvvrDataStruct();
|
com.njcn.advance.event.type.jna.QvvrDLL.QvvrDataStruct typeDataStruct = new com.njcn.advance.event.type.jna.QvvrDLL.QvvrDataStruct();
|
||||||
typeDataStruct.smp_rate = waveDataDTO.getComtradeCfgDTO().getFinalSampleRate();
|
typeDataStruct.smp_rate = waveDataDTO.getComtradeCfgDTO().getFinalSampleRate();
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.njcn.advance.event.service.impl;
|
|||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.njcn.advance.event.cause.core.VoltageSagAnalyzer;
|
import com.njcn.advance.event.cause.core.VoltageSagAnalyzer;
|
||||||
|
import com.njcn.advance.event.cause.jna.QvvrCauseDLL;
|
||||||
import com.njcn.advance.event.cause.model.AnalysisResult;
|
import com.njcn.advance.event.cause.model.AnalysisResult;
|
||||||
import com.njcn.advance.event.cause.model.DataFeature;
|
import com.njcn.advance.event.cause.model.DataFeature;
|
||||||
import com.njcn.advance.event.cause.model.QvvrDataStruct;
|
import com.njcn.advance.event.cause.model.QvvrDataStruct;
|
||||||
@@ -88,36 +89,26 @@ public class EventAdvanceServiceImpl implements IEventAdvanceService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QvvrDataStruct qvvrDataStruct = new QvvrDataStruct();
|
|
||||||
// 采样率
|
|
||||||
qvvrDataStruct.setSmpRate(waveDataDTO.getComtradeCfgDTO().getFinalSampleRate());
|
|
||||||
// 瞬时值
|
|
||||||
List<List<Float>> listWaveData = waveDataDTO.getListWaveData();
|
List<List<Float>> listWaveData = waveDataDTO.getListWaveData();
|
||||||
// 通道采样个数
|
|
||||||
qvvrDataStruct.setSmpLen(listWaveData.size());
|
|
||||||
// 获取ABC三相的瞬时数据
|
|
||||||
// A相电压采样数据
|
|
||||||
float[] smpVa = new float[listWaveData.size()];
|
|
||||||
// B相电压采样数据
|
|
||||||
float[] smpVb = new float[listWaveData.size()];
|
|
||||||
// C相电压采样数据
|
|
||||||
float[] smpVc = new float[listWaveData.size()];
|
|
||||||
for (int i = 0; i < listWaveData.size(); i++) {
|
|
||||||
smpVa[i] = listWaveData.get(i).get(1);
|
|
||||||
smpVb[i] = listWaveData.get(i).get(2);
|
|
||||||
smpVc[i] = listWaveData.get(i).get(3);
|
|
||||||
}
|
|
||||||
qvvrDataStruct.setSmpVa(smpVa);
|
|
||||||
qvvrDataStruct.setSmpVb(smpVb);
|
|
||||||
qvvrDataStruct.setSmpVc(smpVc);
|
|
||||||
|
|
||||||
// 暂降原因
|
// 暂降原因JNA的方式
|
||||||
VoltageSagAnalyzer voltageSagAnalyzer = new VoltageSagAnalyzer();
|
com.njcn.advance.event.cause.jna.QvvrCauseDLL.QvvrDataStruct causeDataStruct = new com.njcn.advance.event.cause.jna.QvvrCauseDLL.QvvrDataStruct();
|
||||||
try{
|
causeDataStruct.smp_rate = waveDataDTO.getComtradeCfgDTO().getFinalSampleRate();
|
||||||
AnalysisResult cause = voltageSagAnalyzer.analyzeVoltageSagWithDetails(qvvrDataStruct);
|
causeDataStruct.smp_len = listWaveData.size();
|
||||||
eventAnalysis.setCause(cause.getCause());
|
// 获取ABC三相的瞬时数据
|
||||||
}catch (Exception e){
|
for (int i = 0; i < listWaveData.size(); i++) {
|
||||||
log.error("DAT文件分析异常", e);
|
causeDataStruct.smp_va[i] = listWaveData.get(i).get(1);
|
||||||
|
causeDataStruct.smp_vb[i] = listWaveData.get(i).get(2);
|
||||||
|
causeDataStruct.smp_vc[i] = listWaveData.get(i).get(3);
|
||||||
|
}
|
||||||
|
// 执行算法分析 - 直接调用C DLL
|
||||||
|
try {
|
||||||
|
QvvrCauseDLL.INSTANCE.qvvr_fun_cause(causeDataStruct);
|
||||||
|
eventAnalysis.setCause(causeDataStruct.cause);
|
||||||
|
if (causeDataStruct.no_cal != 0) {
|
||||||
|
eventAnalysis.setCauseFlag(0);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
eventAnalysis.setCause(DataFeature.CAUSE_TYPE0);
|
eventAnalysis.setCause(DataFeature.CAUSE_TYPE0);
|
||||||
eventAnalysis.setCauseFlag(0);
|
eventAnalysis.setCauseFlag(0);
|
||||||
}
|
}
|
||||||
@@ -157,7 +148,6 @@ public class EventAdvanceServiceImpl implements IEventAdvanceService {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
eventAnalysis.setType(DataFeature.TYPE10);
|
eventAnalysis.setType(DataFeature.TYPE10);
|
||||||
eventAnalysis.setTypeFlag(0);
|
eventAnalysis.setTypeFlag(0);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
return eventAnalysis;
|
return eventAnalysis;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,11 +31,8 @@ public interface QvvrDLL extends Library {
|
|||||||
libFileName = "qvvr_dll.dll";
|
libFileName = "qvvr_dll.dll";
|
||||||
resourcePath = "/qvvr_dll.dll";
|
resourcePath = "/qvvr_dll.dll";
|
||||||
} else if (osName.contains("linux")) {
|
} else if (osName.contains("linux")) {
|
||||||
libFileName = "libqvvr.so";
|
libFileName = "libqvvr_dll.so";
|
||||||
resourcePath = "/libqvvr.so";
|
resourcePath = "/libqvvr_dll.so";
|
||||||
} else if (osName.contains("mac")) {
|
|
||||||
libFileName = "libqvvr.dylib";
|
|
||||||
resourcePath = "/libqvvr.dylib";
|
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedOperationException("不支持的操作系统: " + osName);
|
throw new UnsupportedOperationException("不支持的操作系统: " + osName);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user