完成责任量化功能

This commit is contained in:
2023-07-26 20:26:40 +08:00
parent 7cc21af253
commit 1d6ae663ab
8 changed files with 47 additions and 277 deletions

View File

@@ -0,0 +1,47 @@
package com.njcn.advance.model.responsibility;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
/**
* 当根据动态责任数据获取用户责任量化结果时,将需要的一些参数进行缓存
* 比如 harmNum,pNode,HKData,FKData,HarmData,监测点的测量间隔,win窗口最小公倍数
* 以及FKData每个时间点的p对应的用户List<name>
*
* @author hongawen
* @Date: 2019/4/29 16:06
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CacheQvvrData implements Serializable {
private int pNode;
private int harmNum;
private float[] harmData;
private PDataStruct[] FKdata;
private HKDataStruct[] HKdata;
private List<String> names;
private int lineInterval;
private int win;
//最小公倍数
private int minMultiple;
//横轴时间
private List<Long> times;
}

View File

@@ -0,0 +1,36 @@
package com.njcn.advance.model.responsibility;
import com.sun.jna.Structure;
import java.io.Serializable;
import java.util.List;
public class HKDataStruct extends Structure implements Serializable {
public float hk[] = new float[QvvrStruct.MAX_P_NODE + 1];
public HKDataStruct() {
}
@Override
protected List getFieldOrder() {
return null;
}
public HKDataStruct(double[] hk) {
for (int i = 0; i < hk.length; i++) {
this.hk[i] = (float) hk[i];
}
}
public static class ByReference extends HKDataStruct implements Structure.ByReference {
public ByReference(double[] p) {
super(p);
}
}
public static class ByValue extends HKDataStruct implements Structure.ByValue {
public ByValue(double[] p) {
super(p);
}
}
}

View File

@@ -0,0 +1,53 @@
package com.njcn.advance.model.responsibility;
import com.sun.jna.Structure;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
public class PDataStruct extends Structure implements Serializable {
public float p[] = new float[QvvrStruct.MAX_P_NODE];
public PDataStruct() {
}
@Override
protected List getFieldOrder() {
return null;
}
public PDataStruct(double[] p) {
for (int i = 0; i < p.length; i++) {
this.p[i] = (float) p[i];
}
}
public static class ByReference extends PDataStruct implements Structure.ByReference {
public ByReference(double[] p) {
super(p);
}
}
public static class ByValue extends PDataStruct implements Structure.ByValue {
public ByValue(double[] p) {
super(p);
}
}
public float[] getP() {
return p;
}
public void setP(float[] p) {
this.p = p;
}
@Override
public String toString() {
return "PDataStruct{" +
"p=" + Arrays.toString(p) +
'}';
}
}

View File

@@ -0,0 +1,200 @@
package com.njcn.advance.model.responsibility;
import com.sun.jna.Structure;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
public class QvvrStruct extends Structure implements Serializable {
public static final int MAX_P_NODE= 200; //功率节点个数限制按200个限制
public static final int MAX_P_NUM= 96 * 100; //功率数据按15分钟间隔100天处理
public static final int MAX_HARM_NUM= 1440 * 100; //谐波数据按一分钟间隔100天处理
public static final int MAX_WIN_LEN=96 * 10; //按15分钟算10天
public static final int MIN_WIN_LEN = 4; //按15分钟算1小时
//输入参数
public int cal_flag; //计算标志0默认用电压和功率数据计算相关系数和责任1用代入的动态相关系数计算责任
public int harm_num; //谐波数据个数
public int p_num; //功率数据个数
public int p_node; //功率负荷节点数
public int win; //数据窗大小
public int res_num; //代入的责任数据个数
public float harm_mk; //谐波电压门槛
public float harm_data[]; //谐波数据序列
public PDataStruct p_data[]; //功率数据序列
public PDataStruct sim_data[]; //动态相关系数数据序列,可作为输入或者输出
public PDataStruct FKdata[]; //不包含背景动态谐波责任数据序列,可作为输入或者输出
public HKDataStruct HKdata[]; //包含背景动态谐波责任数据序列,可作为输入或者输出
public float Core[]; //典则相关系数
public float BjCore[]; //包含背景典则相关系数
//输出结果
public int cal_ok; //是否计算正确标志置位0表示未计算置位1表示计算完成
public float sumFKdata[];//不包含背景谐波责任
public float sumHKdata[];//包含背景谐波责任
public QvvrStruct() {
cal_flag = 0;
harm_data = new float[MAX_HARM_NUM];
p_data = new PDataStruct[MAX_P_NUM];
sim_data = new PDataStruct[MAX_P_NUM];
FKdata = new PDataStruct[MAX_P_NUM];
HKdata = new HKDataStruct[MAX_P_NUM];
Core = new float[MAX_P_NUM];
BjCore = new float[MAX_P_NUM];
sumFKdata = new float[MAX_P_NODE];
sumHKdata = new float[MAX_P_NODE + 1];
}
public static class ByReference extends QvvrStruct implements Structure.ByReference {
}
public static class ByValue extends QvvrStruct implements Structure.ByValue {
}
public PDataStruct[] getFKdata() {
return FKdata;
}
public void setFKdata(PDataStruct[] FKdata) {
this.FKdata = FKdata;
}
public HKDataStruct[] getHKdata() {
return HKdata;
}
public void setHKdata(HKDataStruct[] HKdata) {
this.HKdata = HKdata;
}
public float[] getSumFKdata() {
return sumFKdata;
}
public void setSumFKdata(float[] sumFKdata) {
this.sumFKdata = sumFKdata;
}
public float[] getSumHKdata() {
return sumHKdata;
}
public void setSumHKdata(float[] sumHKdata) {
this.sumHKdata = sumHKdata;
}
public int getCal_flag() {
return cal_flag;
}
public void setCal_flag(int cal_flag) {
this.cal_flag = cal_flag;
}
public int getHarm_num() {
return harm_num;
}
public void setHarm_num(int harm_num) {
this.harm_num = harm_num;
}
public float getHarm_mk() {
return harm_mk;
}
public void setHarm_mk(float harm_mk) {
this.harm_mk = harm_mk;
}
public float[] getHarm_data() {
return harm_data;
}
public void setHarm_data(float[] harm_data) {
this.harm_data = harm_data;
}
public float[] getCore() {
return Core;
}
public void setCore(float[] core) {
Core = core;
}
public float[] getBjCore() {
return BjCore;
}
public void setBjCore(float[] bjCore) {
BjCore = bjCore;
}
public int getCal_ok() {
return cal_ok;
}
public void setCal_ok(int cal_ok) {
this.cal_ok = cal_ok;
}
public int getP_num() {
return p_num;
}
public void setP_num(int p_num) {
this.p_num = p_num;
}
public int getP_node() {
return p_node;
}
public void setP_node(int p_node) {
this.p_node = p_node;
}
public int getWin() {
return win;
}
public void setWin(int win) {
this.win = win;
}
public int getRes_num() {
return res_num;
}
public void setRes_num(int res_num) {
this.res_num = res_num;
}
public PDataStruct[] getP_data() {
return p_data;
}
public void setP_data(PDataStruct[] p_data) {
this.p_data = p_data;
}
public PDataStruct[] getSim_data() {
return sim_data;
}
public void setSim_data(PDataStruct[] sim_data) {
this.sim_data = sim_data;
}
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[]{"sumFKdata", "sumHKdata"});
}
}

View File

@@ -1,21 +0,0 @@
package com.njcn.advance.service.responsibility.impl;
import com.njcn.advance.pojo.bo.responsibility.QvvrStruct;
import com.sun.jna.Library;
import com.sun.jna.Native;
/**
* @author hongawen
* @version 1.0.0
* @date 2021年07月14日 16:17
*/
public interface JnaLibrary extends Library {
JnaLibrary INSTANCE = (JnaLibrary)
Native.loadLibrary(JnaLibrary.class.getResource("/harm_response.dll")
.getPath()
.substring(1),// substring(1)的原因是在Windows下获取到的路径前面会多一个斜杠但在Linux下不会,
JnaLibrary.class);
void harm_response(QvvrStruct outData);
}

View File

@@ -18,6 +18,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.advance.enums.AdvanceResponseEnum;
import com.njcn.advance.mapper.responsibility.RespDataMapper;
import com.njcn.advance.model.responsibility.CacheQvvrData;
import com.njcn.advance.model.responsibility.HKDataStruct;
import com.njcn.advance.model.responsibility.PDataStruct;
import com.njcn.advance.model.responsibility.QvvrStruct;
import com.njcn.advance.pojo.bo.responsibility.*;
import com.njcn.advance.pojo.dto.responsibility.CustomerData;
import com.njcn.advance.pojo.dto.responsibility.CustomerResponsibility;
@@ -31,12 +35,9 @@ import com.njcn.advance.pojo.po.responsibility.RespUserData;
import com.njcn.advance.service.responsibility.IRespDataResultService;
import com.njcn.advance.service.responsibility.IRespDataService;
import com.njcn.advance.service.responsibility.IRespUserDataService;
import com.njcn.advance.utils.JnaCallBalance;
import com.njcn.advance.utils.JnaCallDllOrSo;
import com.njcn.advance.utils.ResponsibilityCallDllOrSo;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.FileUtil;
import com.njcn.common.utils.PubUtils;
import com.njcn.db.constant.DbConstant;
@@ -49,13 +50,10 @@ import com.njcn.harmonic.pojo.param.HistoryHarmParam;
import com.njcn.influx.pojo.dto.HarmData;
import com.njcn.influx.pojo.dto.HarmHistoryDataDTO;
import com.njcn.oss.constant.OssPath;
import com.njcn.oss.enums.OssResponseEnum;
import com.njcn.oss.utils.FileStorageUtil;
import com.njcn.system.pojo.vo.DictDataVO;
import com.njcn.web.factory.PageFactory;
import com.njcn.web.pojo.param.BaseParam;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@@ -86,8 +84,6 @@ public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> i
private final HarmDataFeignClient harmDataFeignClient;
private final GetQvvrData getQvvrData;
private final IRespDataResultService respDataResultService;
@Override
@@ -106,16 +102,16 @@ public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> i
//没有排序参数默认根据sort字段排序没有排序字段的根据updateTime更新时间排序
queryWrapper.orderBy(true, false, "pqs_resp_data.create_time");
}
queryWrapper.between("pqs_resp_data.create_time",queryParam.getSearchBeginTime(),queryParam.getSearchEndTime());
queryWrapper.between("pqs_resp_data.create_time", queryParam.getSearchBeginTime(), queryParam.getSearchEndTime());
}
queryWrapper.eq("pqs_resp_data.state", DataStateEnum.ENABLE.getCode());
Page<RespDataDTO> page = this.baseMapper.page(new Page<>(PageFactory.getPageNum(queryParam), PageFactory.getPageSize(queryParam)), queryWrapper);
List<RespDataDTO> records = page.getRecords();
if(CollectionUtil.isNotEmpty(records)){
if (CollectionUtil.isNotEmpty(records)) {
//获取该监测点的详细信息
for (RespDataDTO respDataDTO : records) {
LineDetailVO lineSubGdDetail = lineFeignClient.getLineSubGdDetail(respDataDTO.getLineId()).getData();
BeanUtil.copyProperties(lineSubGdDetail,respDataDTO);
BeanUtil.copyProperties(lineSubGdDetail, respDataDTO);
}
}
return page.setRecords(records);
@@ -133,7 +129,6 @@ public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> i
}
@Override
public ResponsibilityResult getDynamicData(ResponsibilityCalculateParam responsibilityCalculateParam) {
ResponsibilityResult result = new ResponsibilityResult();
@@ -153,7 +148,6 @@ public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> i
if (CollectionUtils.isEmpty(userDataExcels)) {
throw new BusinessException(AdvanceResponseEnum.USER_DATA_NOT_FOUND);
}
//开始处理,根据接口参数需求,需要节点数(用户数,用户名+监测点号为一个用户),时间范围内功率数据
DealDataResult dealDataResult = RespUserDataServiceImpl.getStanderData(userDataExcels, 1);
Map<String/*户号@监测点号@户名*/, Map<String/*yyyy-MM-dd天日期*/, List<UserDataExcel>>> totalData = dealDataResult.getTotalListData();
@@ -263,8 +257,7 @@ public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> i
qvvrStruct.harm_mk = harmMk;
qvvrStruct.p_data = pData;
qvvrStruct.harm_data = harmData;
ResponsibilityCallDllOrSo responsibilityCallDllOrSo = new ResponsibilityCallDllOrSo("harm_response.dll");
ResponsibilityCallDllOrSo responsibilityCallDllOrSo = new ResponsibilityCallDllOrSo("harm_response");
responsibilityCallDllOrSo.setPath();
ResponsibilityCallDllOrSo.ResponsibilityLibrary responsibilityLibrary = ResponsibilityCallDllOrSo.ResponsibilityLibrary.INSTANTCE;
responsibilityLibrary.harm_response(qvvrStruct);
@@ -402,16 +395,16 @@ public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> i
LambdaQueryWrapper<RespDataResult> respDataResultLambdaQueryWrapper = new LambdaQueryWrapper<>();
respDataResultLambdaQueryWrapper.eq(RespDataResult::getResDataId, responsibilityData.getId())
.eq(RespDataResult::getTime, responsibilityCalculateParam.getTime())
.eq(RespDataResult::getStartTime, DateUtil.parse(responsibilityCalculateParam.getSearchBeginTime()+" 00:00:00",DatePattern.NORM_DATETIME_PATTERN))
.eq(RespDataResult::getEndTime, DateUtil.parse(responsibilityCalculateParam.getSearchEndTime()+" 23:59:59",DatePattern.NORM_DATETIME_PATTERN))
.eq(RespDataResult::getStartTime, DateUtil.parse(responsibilityCalculateParam.getSearchBeginTime() + " 00:00:00", DatePattern.NORM_DATETIME_PATTERN))
.eq(RespDataResult::getEndTime, DateUtil.parse(responsibilityCalculateParam.getSearchEndTime() + " 23:59:59", DatePattern.NORM_DATETIME_PATTERN))
.eq(RespDataResult::getLimitValue, data.getOverLimit());
RespDataResult respDataResult = respDataResultService.getOne(respDataResultLambdaQueryWrapper);
if (Objects.isNull(respDataResult)) {
respDataResult = new RespDataResult();
respDataResult.setResDataId(responsibilityData.getId());
respDataResult.setTime(responsibilityCalculateParam.getTime());
respDataResult.setStartTime(DateUtil.parse(responsibilityCalculateParam.getSearchBeginTime()+" 00:00:00",DatePattern.NORM_DATETIME_PATTERN));
respDataResult.setEndTime(DateUtil.parse(responsibilityCalculateParam.getSearchEndTime()+" 23:59:59",DatePattern.NORM_DATETIME_PATTERN));
respDataResult.setStartTime(DateUtil.parse(responsibilityCalculateParam.getSearchBeginTime() + " 00:00:00", DatePattern.NORM_DATETIME_PATTERN));
respDataResult.setEndTime(DateUtil.parse(responsibilityCalculateParam.getSearchEndTime() + " 23:59:59", DatePattern.NORM_DATETIME_PATTERN));
respDataResult.setLimitValue(data.getOverLimit());
//时间横轴数据 timeDatas
JSONArray timeDataJson = JSONArray.parseArray(JSON.toJSONString(timeDatas));
@@ -480,8 +473,8 @@ public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> i
//谐波横轴所有的时间
List<Long> times = cacheQvvrData.getTimes();
//首先根据窗口判断限值时间范围是否满足最小窗口
Long limitSL = DateUtil.parse(responsibilitySecondCalParam.getLimitStartTime(),DatePattern.NORM_DATETIME_PATTERN).getTime();
Long limitEL = DateUtil.parse(responsibilitySecondCalParam.getLimitEndTime(),DatePattern.NORM_DATETIME_PATTERN).getTime();
Long limitSL = DateUtil.parse(responsibilitySecondCalParam.getLimitStartTime(), DatePattern.NORM_DATETIME_PATTERN).getTime();
Long limitEL = DateUtil.parse(responsibilitySecondCalParam.getLimitEndTime(), DatePattern.NORM_DATETIME_PATTERN).getTime();
List<Integer> temp = getTimes(times, limitSL, limitEL);
//在动态责任数据中,时间的起始索引位置和截止索引位置
Integer timeStartIndex = temp.get(0);
@@ -559,7 +552,10 @@ public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> i
qvvrStruct.setFKdata(FKdata);
qvvrStruct.setHKdata(HKdata);
}
qvvrStruct = getQvvrData.getResponsibilityResult(qvvrStruct);
ResponsibilityCallDllOrSo responsibilityCallDllOrSo = new ResponsibilityCallDllOrSo("harm_response");
responsibilityCallDllOrSo.setPath();
ResponsibilityCallDllOrSo.ResponsibilityLibrary responsibilityLibrary = ResponsibilityCallDllOrSo.ResponsibilityLibrary.INSTANTCE;
responsibilityLibrary.harm_response(qvvrStruct);
if (qvvrStruct.cal_ok == 0) {
throw new BusinessException(AdvanceResponseEnum.RESPONSIBILITY_PARAMETER_ERROR);
}
@@ -651,16 +647,16 @@ public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> i
LambdaQueryWrapper<RespDataResult> respDataResultLambdaQueryWrapper1 = new LambdaQueryWrapper<>();
respDataResultLambdaQueryWrapper1.eq(RespDataResult::getResDataId, responsibilityData.getId())
.eq(RespDataResult::getTime, responsibilitySecondCalParam.getTime())
.eq(RespDataResult::getStartTime, DateUtil.parse(responsibilitySecondCalParam.getLimitStartTime(),DatePattern.NORM_DATETIME_PATTERN))
.eq(RespDataResult::getEndTime, DateUtil.parse(responsibilitySecondCalParam.getLimitEndTime(),DatePattern.NORM_DATETIME_PATTERN))
.eq(RespDataResult::getStartTime, DateUtil.parse(responsibilitySecondCalParam.getLimitStartTime(), DatePattern.NORM_DATETIME_PATTERN))
.eq(RespDataResult::getEndTime, DateUtil.parse(responsibilitySecondCalParam.getLimitEndTime(), DatePattern.NORM_DATETIME_PATTERN))
.eq(RespDataResult::getLimitValue, responsibilitySecondCalParam.getLimitValue());
RespDataResult respDataResult = respDataResultService.getOne(respDataResultLambdaQueryWrapper1);
if (Objects.isNull(respDataResult)) {
respDataResult = new RespDataResult();
respDataResult.setResDataId(responsibilityData.getId());
respDataResult.setTime(responsibilitySecondCalParam.getTime());
respDataResult.setStartTime(DateUtil.parse(responsibilitySecondCalParam.getLimitStartTime(),DatePattern.NORM_DATETIME_PATTERN));
respDataResult.setEndTime(DateUtil.parse(responsibilitySecondCalParam.getLimitEndTime(),DatePattern.NORM_DATETIME_PATTERN));
respDataResult.setStartTime(DateUtil.parse(responsibilitySecondCalParam.getLimitStartTime(), DatePattern.NORM_DATETIME_PATTERN));
respDataResult.setEndTime(DateUtil.parse(responsibilitySecondCalParam.getLimitEndTime(), DatePattern.NORM_DATETIME_PATTERN));
respDataResult.setLimitValue(responsibilitySecondCalParam.getLimitValue());
//时间横轴数据 timeDatas
JSONArray timeDataJson = JSONArray.parseArray(JSON.toJSONString(timeDatas));
@@ -686,7 +682,6 @@ public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> i
}
/**
* 监测点测量间隔获取最后用于计算的功率数据
*

View File

@@ -1,6 +1,6 @@
package com.njcn.advance.utils;
import com.njcn.advance.pojo.bo.responsibility.QvvrStruct;
import com.njcn.advance.model.responsibility.QvvrStruct;
import com.sun.jna.Library;
import com.sun.jna.Native;