Commit 1d703e7a authored by ZWT's avatar ZWT

feat(吉林演示): 松原

1.天气数据接收定时任务,解决代码扫描问题,修改文件读取相关代码,解决资源未关流问题;
2.修改登录验证码生成工具类,解决代码扫描问题,修复随机数不安全问题;
3.删除除主程序启动类外其他启动类模块,解决代码扫描问题;
4.删除自定义httputlis类,解决代码扫描问题,替换部分代码远程调用方法;
5.重构光伏预测模块下载电站实际发电数据导入模板接口,解决代码扫描问题;
6.重构光伏预测模块导入电站实际发电数据接口,解决代码扫描问题;
7.删除公用excel导入导出工具类及poi相关pom依赖,解决代码扫描问题;
8.光伏功率预测模块,增加查询线路列表接口,解决页面接口报错问题;
9.增加测试用历史数据导入接口;

BREAKING CHANGE: 无

Closes 无

[skip ci]
parent 77e79ae5
package pps.cloud.base.service;
import xstartup.annotation.XService;
import xstartup.annotation.XText;
import xstartup.base.XContext;
import xstartup.data.XServiceResult;
/**
* 天气数据接收Cloud模块
*
* @author ZWT
* @date 2023/11/13 17:49
*/
@XService
@XText("天气数据接收Cloud模块")
public interface IBaseWeatherCloudService {
/**
* 天气数据接收Cloud模块--天气数据处理
*
* @param context 上下文
* @param oilFieldName 油田名称
* @return {@link XServiceResult }
*/
@XText("天气数据接收Cloud模块--天气数据处理")
XServiceResult weatherDataProcess(XContext context, String oilFieldName);
/**
* 天气数据接收Cloud模块--天气Api数据处理
*
* @param context 上下文
* @return {@link XServiceResult}
*/
@XText("天气数据接收Cloud模块--天气Api数据处理")
XServiceResult weatherApiDataProcess(XContext context);
}
package pps.cloud.base.service;
import xstartup.annotation.XService;
import xstartup.annotation.XText;
import xstartup.base.XContext;
import xstartup.data.XServiceResult;
/**
* 第三方风力发电数据
*
* @author ZWT
* @date 2024/09/03 16:30
*/
@XService
@XText("第三方风力发电数据Cloud模块")
public interface IThirdWindPowerGenerationCloudService {
/**
* 第三方风力发电数据Cloud模块--第三方风力发电数据定时任务
*
* @param context 上下文
* @return {@link XServiceResult }
*/
@XText("第三方风力发电数据Cloud模块--第三方风力发电数据定时任务")
XServiceResult thirdWindPowerGenerationJob(XContext context);
}
package pps.cloud.base.service;
import xstartup.annotation.XService;
import xstartup.annotation.XText;
import xstartup.base.XContext;
import xstartup.data.XServiceResult;
/**
* 风资源训练集数据Cloud模块
*
* @author ZWT
* @date 2024/08/30 14:03
*/
@XService
@XText("风资源训练集数据Cloud模块")
public interface IWindPredictionHistoryCloudService {
/**
* 风资源训练集数据Cloud模块--风资源训练集定时任务
*
* @param context 上下文
* @return {@link XServiceResult }
*/
@XText("风资源训练集数据Cloud模块--风资源训练集定时任务")
XServiceResult windPredictionHistoryJob(XContext context);
}
package pps.core.base.service;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import pps.core.base.entity.BaseDataEnt;
import pps.core.base.entity.BaseDataImportLogEnt;
import pps.core.base.entity.BaseModelValEnt;
import pps.core.base.enums.ImportFieldDic;
import pps.core.base.mapper.BaseDataImportLogMapper;
import pps.core.base.mapper.BaseDataMapper;
import pps.core.base.mapper.BaseModelValMapper;
import pps.core.base.service.data.base_data.*;
import pps.core.common.constant.BusinessConstant;
import xstartup.annotation.XService;
import xstartup.annotation.XText;
import xstartup.base.XContext;
import xstartup.base.data.CustomQueryInput;
import xstartup.base.util.XCopyUtils;
import xstartup.base.util.XHttpUtils;
import xstartup.base.util.XJsonUtils;
import xstartup.data.XListResult;
import xstartup.data.XPageResult;
import xstartup.data.XServiceResult;
import xstartup.data.XSingleResult;
import xstartup.error.XError;
import xstartup.feature.api.annotation.XApiGet;
import xstartup.feature.api.annotation.XApiPost;
import xstartup.feature.mybatis.helper.XMapperHelper;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
@XService
public class BaseDataService {
@XApiPost
public XServiceResult createBaseData(XContext context, CreateBaseDataInput input) {
BaseDataMapper mapper = context.getBean(BaseDataMapper.class);
BaseDataEnt entity = new BaseDataEnt();
XCopyUtils.copyObject(input, entity);
mapper.insert(entity);
return XServiceResult.OK;
}
@XApiPost
public XServiceResult updateBaseData(XContext context, UpdateBaseDataInput input) {
BaseDataMapper mapper = context.getBean(BaseDataMapper.class);
BaseDataEnt entity = mapper.selectOne(new LambdaQueryWrapper<BaseDataEnt>()
.eq(BaseDataEnt::getId, input.getId()));
if (ObjectUtil.isNull(entity)) {
return XServiceResult.error(context, XError.NotFound);
}
XCopyUtils.copyObject(input, entity);
mapper.updateById(entity);
return XServiceResult.OK;
}
@XApiPost
public XServiceResult deleteBaseData(XContext context, DeleteBaseDataInput input) {
BaseDataMapper mapper = context.getBean(BaseDataMapper.class);
BaseDataEnt entity = mapper.selectOne(new LambdaQueryWrapper<BaseDataEnt>()
.eq(BaseDataEnt::getId, input.getId()));
if (ObjectUtil.isNull(entity)) {
return XServiceResult.error(context, XError.NotFound);
}
mapper.deleteById(entity);
return XServiceResult.OK;
}
@XApiGet
public XSingleResult<GetBaseDataOutput> getBaseData(XContext context, GetBaseDataInput input) {
BaseDataMapper mapper = context.getBean(BaseDataMapper.class);
BaseDataEnt entity = mapper.selectOne(new LambdaQueryWrapper<BaseDataEnt>()
.eq(BaseDataEnt::getId, input.getId()));
if (ObjectUtil.isNull(entity)) {
return XSingleResult.error(context, XError.NotFound);
}
GetBaseDataOutput output = new GetBaseDataOutput();
XCopyUtils.copyObject(entity, output);
return XSingleResult.success(output);
}
@XApiGet
public XListResult<QueryBaseDataOutput> queryBaseDataCopy(XContext context, GetBaseDataInput input) {
BaseDataMapper mapper = context.getBean(BaseDataMapper.class);
LambdaQueryWrapper<BaseDataEnt> queryWrapper = new LambdaQueryWrapper<BaseDataEnt>()
.eq(BaseDataEnt::getLineId, input.getLineId())
.orderByAsc(BaseDataEnt::getDataDate);
Date beginTime;
Date endTime;
if (CharSequenceUtil.isBlank(input.getDataDate())) {
DateTime date = DateUtil.date();
beginTime = DateUtil.beginOfDay(date);
endTime = DateUtil.endOfDay(date);
queryWrapper.ge(BaseDataEnt::getDataDate, beginTime)
.le(BaseDataEnt::getDataDate, endTime);
} else {
if (CharSequenceUtil.contains(input.getDataDate(), '@')) {
String[] dataDates = CharSequenceUtil.splitToArray(input.getDataDate(), '@');
beginTime = DateUtil.beginOfDay(DateUtil.parseDateTime(dataDates[0]));
endTime = DateUtil.endOfDay(DateUtil.parseDateTime(dataDates[1]));
queryWrapper.ge(BaseDataEnt::getDataDate, beginTime)
.le(BaseDataEnt::getDataDate, endTime);
} else {
beginTime = DateUtil.beginOfDay(DateUtil.parseDateTime(input.getDataDate()));
endTime = DateUtil.endOfDay(DateUtil.parseDateTime(input.getDataDate()));
queryWrapper.ge(BaseDataEnt::getDataDate, beginTime)
.le(BaseDataEnt::getDataDate, endTime);
}
}
List<BaseDataEnt> list = mapper.selectList(queryWrapper);
CalcBaseDataInput calcBaseDataInput = new CalcBaseDataInput("", input.getKeyName(), input.getLineId(), "train_pre", DateUtil.formatDateTime(beginTime), DateUtil.formatDateTime(endTime));
Map<String, Object> map = getCalcData(context, calcBaseDataInput);
list.forEach(item -> {
String dataDate = DateUtil.formatDateTime(item.getDataDate());
if (map.containsKey(dataDate)) {
item.setPredictedPower(new BigDecimal(map.get(dataDate).toString()));
}
});
return XListResult.success(XCopyUtils.copyNewList(list, QueryBaseDataOutput.class));
}
@XApiGet
public XListResult<QueryBaseDataOutput> queryBaseData(XContext context, GetBaseDataInput input) {
BaseDataImportLogMapper logMapper = context.getBean(BaseDataImportLogMapper.class);
BaseDataImportLogEnt ent = logMapper.selectOne(new LambdaQueryWrapper<BaseDataImportLogEnt>()
.eq(BaseDataImportLogEnt::getLineId, input.getLineId())
.orderByDesc(BaseDataImportLogEnt::getCreateTime)
.last(BusinessConstant.LAST_LIMIT));
List<QueryBaseDataOutput> outputs = new ArrayList<>();
if (ObjectUtil.isNotNull(ent)) {
BaseDataMapper mapper = context.getBean(BaseDataMapper.class);
List<BaseDataEnt> list = mapper.selectList(new LambdaQueryWrapper<BaseDataEnt>()
.ge(BaseDataEnt::getDataDate, ent.getBeginDate())
.le(BaseDataEnt::getDataDate, ent.getEndDate())
.eq(BaseDataEnt::getLineId, input.getLineId())
.orderByAsc(BaseDataEnt::getDataDate));
outputs = XCopyUtils.copyNewList(list, QueryBaseDataOutput.class);
}
return XListResult.success(outputs);
}
@XApiGet
@XText("获取预测数据")
public XListResult<GetBaseDataOutput> queryPreBaseData(XContext context, GetBaseDataInput input) {
BaseDataImportLogMapper logMapper = context.getBean(BaseDataImportLogMapper.class);
BaseDataImportLogEnt ent = logMapper.selectOne(new LambdaQueryWrapper<BaseDataImportLogEnt>()
.eq(BaseDataImportLogEnt::getLineId, input.getLineId())
.orderByDesc(BaseDataImportLogEnt::getCreateTime)
.last(BusinessConstant.LAST_LIMIT));
List<GetBaseDataOutput> outputs = new ArrayList<>();
if (ObjectUtil.isNotNull(ent)) {
BaseDataMapper mapper = context.getBean(BaseDataMapper.class);
List<BaseDataEnt> list = mapper.selectList(new LambdaQueryWrapper<BaseDataEnt>()
.ge(BaseDataEnt::getDataDate, ent.getBeginDate())
.le(BaseDataEnt::getDataDate, ent.getEndDate())
.eq(BaseDataEnt::getLineId, input.getLineId())
.orderByAsc(BaseDataEnt::getDataDate));
Map<String, Object> map = getCalcData(context, new CalcBaseDataInput("", input.getKeyName(), input.getLineId(), "train_pre", DateUtil.formatDateTime(ent.getBeginDate()), DateUtil.formatDateTime(ent.getEndDate())));
list.forEach(item -> {
String dataDate = DateUtil.formatDateTime(item.getDataDate());
if (map.containsKey(dataDate)) {
item.setPredictedPower(new BigDecimal(map.get(dataDate).toString()));
}
});
outputs = XCopyUtils.copyNewList(list, GetBaseDataOutput.class);
}
return XListResult.success(outputs);
}
@XApiGet
public XPageResult<QueryBaseDataOutput> queryBaseDataList(XContext context, QueryBaseDataInput input) {
BaseDataMapper mapper = context.getBean(BaseDataMapper.class);
QueryWrapper<BaseDataEnt> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda()
.eq(BaseDataEnt::getLineId, input.getLineId())
.eq(BaseDataEnt::getDataDate, input.getDataDate());
return XMapperHelper.query(mapper, input, queryWrapper, QueryBaseDataOutput.class);
}
@XApiGet
public XPageResult<QueryBaseDataOutput> dynamicQueryBaseData(XContext context, CustomQueryInput input) {
BaseDataMapper mapper = context.getBean(BaseDataMapper.class);
return XMapperHelper.query(mapper, input, BaseDataEnt.class, QueryBaseDataOutput.class);
}
// @XText("下载导入模板")
// @XApiGet
// public XFileResult downloadImportTemplate(XContext context) {
// String fileSavePath = XStorageTool.getAbsolutePath("/temp/excel/导入模板_" + DateUtil.formatDate(new Date()) + ".xlsx");
// String templateFilePath = "template/import_template.xlsx";
// InputStream templateInputStream = this.getClass().getClassLoader().getResourceAsStream(templateFilePath);
// byte[] excelContent = ExportExcelUtils.genSingleExcelFileData(templateInputStream, null);
// try {
// ExportExcelUtils.outputFileData(excelContent, fileSavePath);
// } catch (Exception e) {
// context.getLogger().error(e);
// }
// return XFileResult.success(XFileType.APPLICATION_XLSX, fileSavePath);
// }
//
// @XText("新增导入")
// @XApiUpload
// public XServiceResult importFile(XContext context, ImportFileInput input) {
// List<String> headerList = getExcelHeaderList();
// List<Map<String, Object>> mapList = ExcelUtils.readExcel(input.getFile().getInputStream(), input.getFile().getFileName(), headerList, 0);
// try {
// List<BaseDataView> dataList = new ArrayList<>(mapList.size());
// Date minDate = null;
// Date maxDate = null;
// for (Map<String, Object> objectMap : mapList) {
// BaseDataView dataView = BeanUtil.toBean(objectMap, BaseDataView.class);
// dataView.setOuId(input.getWellOuId());
// dataView.setLineId(input.getLineId());
// if (ObjectUtil.isNotNull(dataView.getDataDate())) {
// if (ObjectUtil.isNull(minDate)) {
// minDate = dataView.getDataDate();
// maxDate = dataView.getDataDate();
// }
// if (DateUtil.compare(minDate, dataView.getDataDate()) > 0) {
// minDate = dataView.getDataDate();
// } else if (DateUtil.compare(maxDate, dataView.getDataDate()) < 0) {
// maxDate = dataView.getDataDate();
// }
// }
// dataList.add(dataView);
// }
// if (ObjectUtil.isNull(minDate)) {
// return XServiceResult.error(1000, "日期错误");
// }
// BaseDataMapper mapper = context.getBean(BaseDataMapper.class);
// mapper.delete(new LambdaQueryWrapper<BaseDataEnt>()
// .eq(BaseDataEnt::getLineId, input.getLineId())
// .ge(BaseDataEnt::getDataDate, minDate)
// .le(BaseDataEnt::getDataDate, maxDate));
// BaseDataViewMapper viewMapper = context.getBean(BaseDataViewMapper.class);
// viewMapper.batchInsert(dataList);
// BaseDataImportLogMapper logMapper = context.getBean(BaseDataImportLogMapper.class);
// BaseDataImportLogEnt ent = new BaseDataImportLogEnt();
// ent.setOuId(input.getWellOuId());
// ent.setLineId(input.getLineId());
// ent.setBeginDate(minDate);
// ent.setEndDate(maxDate);
// ent.setCreateTime(new Date());
// logMapper.insert(ent);
// } catch (Exception e) {
// return XServiceResult.error(-1, e.getMessage());
// }
// return XServiceResult.OK;
// }
private List<String> getExcelHeaderList() {
List<Map<String, Object>> fieldList = new ArrayList<>();
for (ImportFieldDic value : ImportFieldDic.values()) {
Map<String, Object> map = new HashMap<>();
map.put("col", value.getCol());
map.put("sort", value.getSort());
fieldList.add(map);
}
fieldList.sort(Comparator.comparing(o -> ((Integer) o.get("sort"))));
return fieldList.stream().map(x -> ((String) x.get("col"))).collect(Collectors.toList());
}
@XText("获取预算")
@XApiGet
public XServiceResult calcBaseData(XContext context, CalcBaseDataInput calcBaseDataInput) {
getCalcData(context, calcBaseDataInput);
return XServiceResult.OK;
}
public Map<String, Object> getCalcData(XContext context, CalcBaseDataInput calcBaseDataInput) {
Map<String, Object> returnMap = new HashMap<>();
try {
String jsonString = XJsonUtils.toJson(calcBaseDataInput);
context.getLogger().info(jsonString);
String result = XHttpUtils.postAsJson("http://121.36.43.217:8098/model/predict", jsonString, 10000);
returnMap = XJsonUtils.toMap(result);
return returnMap;
} catch (Exception e) {
return returnMap;
}
}
public void doTrainData(CalcBaseDataInput calcBaseDataInput) {
try {
String jsonString = XJsonUtils.toJson(calcBaseDataInput);
XHttpUtils.postAsJson("http://121.36.43.217:8098/model/train", jsonString, 10000);
} catch (Exception e) {
throw new RuntimeException("调用预测接口失败");
}
}
@XApiPost
@XText("预测算法训练")
public XServiceResult trainBaseData(XContext context, TrainBaseModelValInput input) {
BaseDataImportLogMapper logMapper = context.getBean(BaseDataImportLogMapper.class);
BaseDataImportLogEnt ent = logMapper.selectOne(new LambdaQueryWrapper<BaseDataImportLogEnt>()
.eq(BaseDataImportLogEnt::getLineId, input.getLineId())
.orderByDesc(BaseDataImportLogEnt::getCreateTime)
.last(BusinessConstant.LAST_LIMIT));
if (ObjectUtil.isNull(ent))
return XServiceResult.OK;
if (CollUtil.isNotEmpty(input.getKeyNames())) {
for (String keyName : input.getKeyNames()) {
CalcBaseDataInput calcBaseDataInput = new CalcBaseDataInput("", keyName, input.getLineId(), "train_val", DateUtil.formatDateTime(ent.getBeginDate()), DateUtil.formatDateTime(ent.getEndDate()));
doTrainData(calcBaseDataInput);
}
} else {
CalcBaseDataInput calcBaseDataInput = new CalcBaseDataInput("", input.getKeyName(), input.getLineId(), "train_val", DateUtil.formatDateTime(ent.getBeginDate()), DateUtil.formatDateTime(ent.getEndDate()));
doTrainData(calcBaseDataInput);
}
return XServiceResult.OK;
}
@XApiGet
@XText("获取最新算法训练数据")
public XSingleResult<TrainBaseModelValOutput> getTrainBaseData(XContext context, GetTrainBaseModelValInput input) {
BaseModelValMapper baseModelValMapper = context.getBean(BaseModelValMapper.class);
if (ObjectUtil.isNull(input.getLineId())) {
return XSingleResult.error(500, "请选择线路");
}
if (CharSequenceUtil.isBlank(input.getKeyNames())) {
return XSingleResult.error(500, "请选择模型");
}
BaseModelValEnt baseModelValEnt = baseModelValMapper.selectOne(new LambdaQueryWrapper<BaseModelValEnt>()
.eq(BaseModelValEnt::getLineId, input.getLineId())
.eq(BaseModelValEnt::getKeyname, input.getKeyNames())
.orderByDesc(BaseModelValEnt::getCreatetime).last(BusinessConstant.LAST_LIMIT));
TrainBaseModelValOutput output = XCopyUtils.copyNewObject(baseModelValEnt, TrainBaseModelValOutput.class);
if (ObjectUtil.isNotNull(baseModelValEnt) && CharSequenceUtil.isAllNotBlank(output.getYtrue(), output.getYpred())) {
Map<String, Object> ytrueMap = XJsonUtils.toMap(output.getYtrue().replace("\\", ""));
Map<String, Object> yPreMap = XJsonUtils.toMap(output.getYpred().replace("\\", ""));
List<TrainBaseModelValDetailOutput> list = new ArrayList<>();
for (String key : ytrueMap.keySet()) {
TrainBaseModelValDetailOutput detailOutput = new TrainBaseModelValDetailOutput();
Date date = new Date(Long.parseLong(key));
detailOutput.setKey(DateUtil.formatDateTime(date));
detailOutput.setPower(ytrueMap.get(key).toString());
if (yPreMap.containsKey(key)) {
detailOutput.setPredictedPower(yPreMap.get(key).toString());
}
list.add(detailOutput);
}
output.setList(list);
} else {
output = new TrainBaseModelValOutput();
}
return XSingleResult.success(output);
}
}
\ No newline at end of file
package pps.core.base.service;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.NioUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang3.StringUtils;
import pps.cloud.base.service.IBaseWeatherCloudService;
import pps.core.base.entity.*;
import pps.core.base.enums.WindDirection;
import pps.core.base.mapper.*;
import pps.core.base.service.data.third_weather_data.DailyData;
import pps.core.base.service.data.third_weather_data.ThirdApiWeatherData;
import pps.core.base.service.data.third_weather_data.Weather15mData;
import pps.core.base.service.data.third_weather_data.WeatherDeleteCondition;
import pps.core.base.utils.ReceivedIMAPMail;
import pps.core.common.constant.BusinessConstant;
import pps.core.common.utils.BaseUtils;
import xstartup.annotation.XService;
import xstartup.base.XContext;
import xstartup.base.XStartup;
import xstartup.base.tool.XLoggerTool;
import xstartup.base.util.XCopyUtils;
import xstartup.core.base.helper.XThreadHelper;
import xstartup.data.XServiceResult;
import javax.mail.*;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;
/**
* 天气数据接收Cloud模块
*
* @author ZWT
* @date 2023/11/13 17:54
*/
@XService
public class BaseWeatherCloudServiceImpl implements IBaseWeatherCloudService {
private static final String host = XStartup.getCurrent().getProperty("weather.mail.host");
private static final String username = XStartup.getCurrent().getProperty("weather.mail.username");
private static final String password = XStartup.getCurrent().getProperty("weather.mail.password");
private static final String protocol = XStartup.getCurrent().getProperty("weather.mail.protocol");
private static final String storeDir = XStartup.getCurrent().getProperty("weather.file.temp.path");
/**
* 天气数据接收Cloud模块--天气数据处理
*
* @param context 上下文
* @param oilFieldCode 油田编码
* @return {@link XServiceResult }
*/
@Override
public XServiceResult weatherDataProcess(XContext context, String oilFieldCode) {
XLoggerTool logger = context.getLogger();
//取未读邮件
Store store = null;
Folder folder = null;
List<JSONObject> jsonObjectList = new ArrayList<>(48);
try {
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
store = session.getStore(protocol);
store.connect(host, username, password);
folder = store.getFolder("INBOX");
folder.open(Folder.READ_WRITE);
logger.info("------ weatherDataProcess connect mail ------");
List<Message> messageList = ReceivedIMAPMail.filterMessage(folder.getMessages(), null, null);
if (CollUtil.isNotEmpty(messageList)) {
for (Message message : messageList) {
ReceivedIMAPMail re = new ReceivedIMAPMail((MimeMessage) message);
String subject = re.getSubject();
if (!CharSequenceUtil.endWith(subject, "天气预测数据" + oilFieldCode)) {
continue;
}
logger.info("------ weatherDataProcess subject: {}", subject);
//读取附件
re.getMailContent(message);
String tempFilePath = this.saveAttachment(message);
logger.info("------ weatherDataProcess load file: {}", tempFilePath);
JSONObject jsonObject = JSON.parseObject(FileUtil.readUtf8String(tempFilePath));
jsonObjectList.add(jsonObject);
logger.info("------ weatherDataProcess del temp file path: {}", tempFilePath);
FileUtil.del(tempFilePath);
message.setFlag(Flags.Flag.DELETED, true);
}
}
} catch (MessagingException | IOException | ParseException e) {
logger.error("------ weatherDataProcess Exception", e);
} finally {
logger.info("------ weatherDataProcess mail finally close");
NioUtil.close(folder);
NioUtil.close(store);
}
logger.info("------ weatherDataProcess jsonObjectList size: {}", jsonObjectList.size());
if (CollUtil.isNotEmpty(jsonObjectList)) {
//气象局数据处理
XThreadHelper.async(() -> {
this.weatherBureauDataProcess(context, jsonObjectList);
});
//风机预测数据处理
XThreadHelper.async(() -> {
this.windTurbineDataProcess(context, jsonObjectList);
});
//光伏预测数据处理
XThreadHelper.async(() -> {
this.photovoltaicDataProcess(context, jsonObjectList);
});
}
return XServiceResult.OK;
}
/**
* 天气数据接收Cloud模块--天气Api数据处理
*
* @param context 上下文
* @return {@link XServiceResult}
*/
@Override
public XServiceResult weatherApiDataProcess(XContext context) {
XLoggerTool logger = context.getLogger();
DateTime date = DateUtil.date();
//查第二采油厂所有电站
BasePhotovoltaicPlantViewMapper viewMapper = context.getBean(BasePhotovoltaicPlantViewMapper.class);
//todo 暂时就一个点,第二采油厂全用API这一个点的数据
List<BasePhotovoltaicPlantView> plantList = viewMapper.selectPlantList(BasePhotovoltaicPlantView.builder()
.ouId("2c4c9d1c-ad55-4c14-b889-4dc33e3461e2")
.build());
if (CollUtil.isEmpty(plantList)) {
logger.info("------ weatherDataProcess plantList is empty ------");
return XServiceResult.OK;
}
//新数据删除接收
List<WeatherDeleteCondition> deleteList = new ArrayList<>(32);
List<ThirdWeatherDataView> weatherDataViewList = new ArrayList<>(2048);
//todo 老表逻辑(后期删除):后续可能替换
List<String> oldDeleteList = new ArrayList<>(32);
List<PlantPredictedPowerDataEnt> oldBatchList = new ArrayList<>(BusinessConstant.LIST_MAX_SIZE);
//取未读邮件
Store store = null;
Folder folder = null;
DateTime startTime = date;
try {
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
store = session.getStore(protocol);
store.connect(host, username, password);
folder = store.getFolder("INBOX");
folder.open(Folder.READ_WRITE);
logger.info("------ weatherApiDataProcess connect mail ------");
List<Message> messageList = ReceivedIMAPMail.filterMessage(folder.getMessages(), null, null);
if (CollUtil.isNotEmpty(messageList)) {
ReceivedIMAPMail re;
for (Message message : messageList) {
re = new ReceivedIMAPMail((MimeMessage) message);
String subject = re.getSubject();
if (!CharSequenceUtil.endWith(subject, "天气预报接口数据")) {
continue;
}
//读取附件
re.getMailContent(message);
String tempFilePath = this.saveAttachment(message);
logger.info("------ weatherApiDataProcess load file: {}", tempFilePath);
//处理读取流部分数据丢失精度问题
String jsonString = FileUtil.readUtf8String(tempFilePath);
jsonString = CharSequenceUtil.replace(jsonString, "%", ".");
List<Weather15mData> weather15mDataList = JSON.parseArray(jsonString, Weather15mData.class);
if (CollUtil.isEmpty(weather15mDataList)) {
logger.info("------ weatherApiDataProcess weather15mDataList isEmpty ------");
return XServiceResult.OK;
}
int count = 0;
for (Weather15mData weather15mData : weather15mDataList) {
//取天气坐标
List<String> split = CharSequenceUtil.split(weather15mData.getLocation().getQuery(), ':');
BigDecimal latitude = new BigDecimal(split.get(0));
BigDecimal longitude = new BigDecimal(split.get(1));
//取天气更新时间
Date timeUpdated = weather15mData.getTimeUpdated();
//获取15天明细数据
List<ThirdApiWeatherData> data = weather15mData.getData();
//获取开始结束时间,添加删除条件
DateTime beginTime = DateUtil.offsetMinute(data.get(0).getForecastTime(), -5);
Date endTime = DateUtil.offsetMinute(data.get(data.size() - 1).getForecastTime(), 15);
if (count == 0) {
startTime = beginTime;
}
count++;
deleteList.add(
WeatherDeleteCondition.builder()
.longitude(longitude)
.latitude(latitude)
.beginTime(beginTime)
.endTime(endTime)
.build()
);
//todo 老表逻辑(后期删除):删除数据逻辑
for (BasePhotovoltaicPlantView plantView : plantList) {
oldDeleteList.add(plantView.getId());
}
//天气数据处理
List<ThirdWeatherDataView> weatherDataList = XCopyUtils.copyNewList(data, ThirdWeatherDataView.class);
for (ThirdWeatherDataView thirdWeatherDataView : weatherDataList) {
thirdWeatherDataView.setLongitude(longitude);
thirdWeatherDataView.setLatitude(latitude);
thirdWeatherDataView.setUpdateTime(timeUpdated);
thirdWeatherDataView.setCreateTime(date);
weatherDataViewList.add(thirdWeatherDataView);
//todo 老表逻辑(后期删除):封装预测数据
for (BasePhotovoltaicPlantView plantView : plantList) {
this.addPlantPredictedPower(oldBatchList, plantView.getId(), thirdWeatherDataView);
}
}
}
logger.info("------ weatherApiDataProcess del temp file path: {}", tempFilePath);
FileUtil.del(tempFilePath);
message.setFlag(Flags.Flag.DELETED, true);
}
}
} catch (MessagingException e) {
logger.error("------ weatherApiDataProcess MessagingException", e);
} catch (ParseException e) {
logger.error("------ weatherApiDataProcess ParseException", e);
} catch (UnsupportedEncodingException e) {
logger.error("------ weatherApiDataProcess UnsupportedEncodingException", e);
} catch (IOException e) {
logger.error("------ weatherApiDataProcess IOException", e);
} finally {
logger.info("------ weatherApiDataProcess finally close");
NioUtil.close(folder);
NioUtil.close(store);
}
//todo 老表逻辑(后期删除):删除/新增预测数据
this.deletePlantPredictedPowerList(context, oldDeleteList, startTime, DateUtil.offsetDay(startTime, 16));
this.insertBatchPlantPredictedPowerList(context, oldBatchList);
int size;
if (CollUtil.isNotEmpty(deleteList)) {
ThirdWeatherDataMapper dataMapper = context.getBean(ThirdWeatherDataMapper.class);
size = deleteList.size();
logger.info("------ weatherApiDataProcess batchDelete delete size: {}", size);
if (size > BaseUtils.BATCH_SIZE) {
List<List<WeatherDeleteCondition>> subList = BaseUtils.getSubList(deleteList);
for (List<WeatherDeleteCondition> list : subList) {
LambdaQueryWrapper<ThirdWeatherDataEnt> wrapper = new LambdaQueryWrapper<>();
for (WeatherDeleteCondition dataEnt : list) {
wrapper.or(w -> w.eq(ThirdWeatherDataEnt::getLatitude, dataEnt.getLatitude())
.eq(ThirdWeatherDataEnt::getLongitude, dataEnt.getLongitude())
.between(ThirdWeatherDataEnt::getForecastTime, dataEnt.getBeginTime(), dataEnt.getEndTime())
);
}
dataMapper.delete(wrapper);
}
} else {
LambdaQueryWrapper<ThirdWeatherDataEnt> wrapper = new LambdaQueryWrapper<>();
for (WeatherDeleteCondition dataEnt : deleteList) {
wrapper.or(w -> w.eq(ThirdWeatherDataEnt::getLatitude, dataEnt.getLatitude())
.eq(ThirdWeatherDataEnt::getLongitude, dataEnt.getLongitude())
.between(ThirdWeatherDataEnt::getForecastTime, dataEnt.getBeginTime(), dataEnt.getEndTime())
);
}
dataMapper.delete(wrapper);
}
}
if (CollUtil.isNotEmpty(weatherDataViewList)) {
ThirdWeatherDataViewMapper dataViewMapper = context.getBean(ThirdWeatherDataViewMapper.class);
size = weatherDataViewList.size();
logger.info("------ weatherApiDataProcess batchList insert size: {}", size);
if (size > BaseUtils.BATCH_SIZE) {
List<List<ThirdWeatherDataView>> subList = BaseUtils.getSubList(weatherDataViewList);
subList.forEach(dataViewMapper::insertBatch);
} else {
dataViewMapper.insertBatch(weatherDataViewList);
}
}
return XServiceResult.OK;
}
/*------------------------- private -------------------------*/
/**
* 添加电厂预测功率
*
* @param batchList 批处理列表
* @param plantId 植物id
* @param thirdWeatherDataView 第三天气数据视图
*/
private void addPlantPredictedPower(List<PlantPredictedPowerDataEnt> batchList, String plantId, ThirdWeatherDataView thirdWeatherDataView) {
DateTime date = DateUtil.date(thirdWeatherDataView.getForecastTime());
batchList.add(PlantPredictedPowerDataEnt.builder()
.plantId(plantId)
.createTime(thirdWeatherDataView.getCreateTime())
.yearTime(String.valueOf(date.year()))
.monthTime(this.zeroFill(date.monthBaseOne()))
.dayTime(this.zeroFill(date.dayOfMonth()))
.hourTime(this.zeroFill(date.hour(true)))
.minTime(this.zeroFill(date.minute()))
.dataDate(date.toString(BusinessConstant.DATE_FORMAT_ALL))
.temperature(thirdWeatherDataView.getTem())
.windSpeed(thirdWeatherDataView.getWns100m())
.windDirection(new BigDecimal(thirdWeatherDataView.getWnd()))
.pressure(thirdWeatherDataView.getPrsQfe())
.humidity(thirdWeatherDataView.getRhu())
.planeIrradiance(thirdWeatherDataView.getDni())
.horizontalIrradiance(thirdWeatherDataView.getGhi())
.power(BigDecimal.ZERO)
.build());
}
/**
* 计算
*
* @param a 一
* @param b b
* @param c c
* @return {@link BigDecimal}
*/
private BigDecimal compute(BigDecimal a, BigDecimal b, BigDecimal c) {
return a.add(b.subtract(a).multiply(c));
}
/**
* int转String
*
* @param num 数字
* @return {@link String}
*/
private String int2Str(int num) {
return num < 10 ? "0" + num : String.valueOf(num);
}
/**
* 保存附件
*
* @param part 部分
* @return {@link String}
* @throws MessagingException 消息传递异常
* @throws IOException IOException
*/
private String saveAttachment(Part part) throws MessagingException, IOException {
String fileName;
String filePath = null;
if (part.isMimeType("multipart/*")) {
Multipart mp = (Multipart) part.getContent();
BodyPart mPart;
for (int i = 0; i < mp.getCount(); i++) {
mPart = mp.getBodyPart(i);
String disposition = mPart.getDisposition();
if (Part.ATTACHMENT.equals(disposition) || Part.INLINE.equals(disposition)) {
fileName = mPart.getFileName();
if (CharSequenceUtil.isNotEmpty(fileName) && StringUtils.lowerCase(fileName).contains("GB2312")) {
fileName = MimeUtility.decodeText(fileName);
}
filePath = this.saveTempFile(mPart, CharSequenceUtil.replace(fileName, "\\?|=", ""));
} else if (mPart.isMimeType("multipart/*")) {
this.saveAttachment(mPart);
} else {
fileName = mPart.getFileName();
if (CharSequenceUtil.isNotEmpty(fileName) && StringUtils.lowerCase(fileName).contains("GB2312")) {
filePath = this.saveTempFile(mPart, MimeUtility.decodeText(fileName));
}
}
}
} else if (part.isMimeType("message/rfc822")) {
this.saveAttachment((Part) part.getContent());
}
return filePath;
}
/**
* 保存临时文件
*
* @param mPart m部分
* @param fileName 文件名
* @return {@link String }
*/
private String saveTempFile(BodyPart mPart, String fileName) {
String filePath;
try (InputStream inputStream = mPart.getInputStream()) {
StringBuilder stringBuilder = new StringBuilder(storeDir)
.append(File.separator)
.append(DateTime.now().toString("yyyyMMdd"));
filePath = stringBuilder.append(File.separator).append(fileName).toString();
FileUtil.touch(filePath);
FileUtil.writeFromStream(inputStream, filePath);
} catch (IOException | MessagingException e) {
throw new RuntimeException(e);
}
return filePath;
}
/**
* 零填充
*
* @param number 数字
* @return {@link String}
*/
private String zeroFill(int number) {
if (number < 10) {
return "0" + number;
}
return String.valueOf(number);
}
/**
* 气象局数据处理
*
* @param context 上下文
* @param jsonObjectList json对象列表
*/
private void weatherBureauDataProcess(XContext context, List<JSONObject> jsonObjectList) {
context.getLogger().info("------ weatherDataProcess weatherBureauDataProcess begin ------");
List<String> deleteList = new ArrayList<>(32);
List<WeatherBureauDataView> batchList = new ArrayList<>(BusinessConstant.LIST_MAX_SIZE);
DateTime create = DateUtil.date();
DateTime end = DateUtil.offsetDay(create, 16);
int count = 0;
for (JSONObject jsonObject : jsonObjectList) {
this.dataFractionation(jsonObject, deleteList, batchList);
if (count == 0) {
batchList.sort(Comparator.comparing(WeatherBureauDataView::getDataTime));
create = DateUtil.offsetMinute(batchList.get(0).getDataTime(), -5);
}
count++;
if (BusinessConstant.TEN.equals(count)) {
this.deleteWeatherBureauList(context, deleteList, create, end);
this.insertWeatherBureauList(context, batchList);
context.getLogger().info("------ weatherDataProcess clear size d {} b {}", deleteList.size(), batchList.size());
CollUtil.clear(deleteList, batchList);
count = 0;
}
}
context.getLogger().info("------ weatherDataProcess delete and insertBatch");
if (CollUtil.isNotEmpty(deleteList)) {
this.deleteWeatherBureauList(context, deleteList, create, end);
}
if (CollUtil.isNotEmpty(batchList)) {
this.insertWeatherBureauList(context, batchList);
}
CollUtil.clear(deleteList, batchList);
context.getLogger().info("------ weatherDataProcess weatherBureauDataProcess end ------");
}
/**
* 数据处理
*
* @param jsonObject json对象
* @param deleteList 删除列表
* @param batchList 批次列表
*/
private void dataFractionation(JSONObject jsonObject, List<String> deleteList, List<WeatherBureauDataView> batchList) {
Map<String, List<DailyData>> cityDataMap = new HashMap<>(16);
for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof JSONArray) {
cityDataMap.put(key, ((JSONArray) value).toJavaList(DailyData.class));
}
}
for (String cityCode : cityDataMap.keySet()) {
List<DailyData> dailyDataList = cityDataMap.get(cityCode);
//删除数据
deleteList.add(cityCode);
//遍历预测数据列表
int flag = 0;
DateTime dateTime;
for (DailyData dailyData : dailyDataList) {
dateTime = DateUtil.date(dailyData.getDateTime());
for (int i = 0; i < 8; i++) {
int hour = LocalTime.parse(dailyData.getHourTimeArray().get(i)).getHour();
DateTime parse = DateUtil.parse(DateUtil.formatDate(dateTime) + ' ' + this.int2Str(hour) + ':' + BusinessConstant.START_OF_DAY_TIME);
if (DateUtil.compare(parse, dateTime) < 0 && flag == 0) {
parse = DateUtil.offsetDay(parse, 1);
dateTime = DateUtil.offsetDay(dateTime, 1);
flag++;
}
WeatherBureauDataView view = WeatherBureauDataView.builder()
.dataTime(parse)
.weatherIcon(this.getStringByIndex(dailyData.getWeatherArray(), i))
.airTemperature(this.stringToBigDecimal(dailyData.getTemperatureArray(), i, "℃"))
.precipitation(this.getStringByIndex(dailyData.getPrecipitationArray(), i))
.windSpeed(this.stringToBigDecimal(dailyData.getWindSpeedArray(), i, "m/s"))
.windDirection(this.getWindDirection(dailyData.getWindDirectionArray(), i))
.pressure(this.stringToBigDecimal(dailyData.getPressureArray(), i, "hPa"))
.humidity(this.stringToBigDecimal(dailyData.getHumidityArray(), i, "%"))
.cloudCover(this.stringToBigDecimal(dailyData.getCloudCoverArray(), i, "%"))
.areaCode(cityCode)
.build();
//去重
if (batchList.stream()
.noneMatch(item -> DateUtil.compare(item.getDataTime(), view.getDataTime()) == 0 && CharSequenceUtil.equals(item.getAreaCode(), view.getAreaCode()))) {
batchList.add(view);
}
}
}
}
}
/**
* 条件删除预测数据
*
* @param context 上下文
* @param deleteList 删除列表
* @param create 创造
* @param end 结束
*/
private void deleteWeatherBureauList(XContext context, List<String> deleteList, DateTime create, DateTime end) {
if (CollUtil.isNotEmpty(deleteList)) {
WeatherBureauDataViewMapper mapper = context.getBean(WeatherBureauDataViewMapper.class);
int size = deleteList.size();
context.getLogger().info("------ deleteWeatherBureauList batchDelete delete size: {}", size);
if (size > BaseUtils.BATCH_SIZE) {
List<List<String>> subList = BaseUtils.getSubList(deleteList);
for (List<String> list : subList) {
mapper.deleteBatch(list, create, end);
}
} else {
mapper.deleteBatch(deleteList, create, end);
}
}
}
/**
* 插入间歇装置预测功率列表
*
* @param context 上下文
* @param batchList 批处理列表
*/
private void insertWeatherBureauList(XContext context, List<WeatherBureauDataView> batchList) {
if (CollUtil.isNotEmpty(batchList)) {
WeatherBureauDataViewMapper dataViewMapper = context.getBean(WeatherBureauDataViewMapper.class);
int size = batchList.size();
context.getLogger().info("------ insertWindTurbineList batchList insert size: {}", size);
if (size > BaseUtils.BATCH_SIZE) {
List<List<WeatherBureauDataView>> subList = BaseUtils.getSubList(batchList);
subList.forEach(dataViewMapper::insertBatch);
} else {
dataViewMapper.insertBatch(batchList);
}
}
}
/**
* 风机预测数据处理
*
* @param context 上下文
* @param jsonObjectList json对象列表
*/
private void windTurbineDataProcess(XContext context, List<JSONObject> jsonObjectList) {
context.getLogger().info("------ weatherDataProcess windTurbineDataProcess begin ------");
BaseWindTurbineViewMapper mapper = context.getBean(BaseWindTurbineViewMapper.class);
List<BaseWindTurbineView> turbineList = mapper.selectWindTurbineList(new BaseWindTurbineView());
if (CollUtil.isEmpty(turbineList)) {
context.getLogger().info("------ weatherDataProcess turbineList is empty ------");
return;
}
context.getLogger().info("------ weatherDataProcess dataFractionation");
List<String> deleteList = new ArrayList<>(32);
List<WindPredictionFutureView> batchList = new ArrayList<>(BusinessConstant.LIST_MAX_SIZE);
DateTime create = DateUtil.date();
DateTime end = DateUtil.offsetDay(create, 16);
//按照cityCode分组
Map<String, List<BaseWindTurbineView>> turbineMap = turbineList.stream()
.collect(Collectors.groupingBy(BaseWindTurbineView::getCityCode));
int count = 0;
for (JSONObject jsonObject : jsonObjectList) {
this.windDataFractionation(jsonObject, turbineMap, deleteList, batchList);
if (count == 0) {
batchList.sort(Comparator.comparing(WindPredictionFutureView::getDataTime));
create = DateUtil.offsetMinute(batchList.get(0).getDataTime(), -5);
}
count++;
if (BusinessConstant.FIVE.equals(count)) {
this.deleteWindTurbineList(context, deleteList, create, end);
this.insertWindTurbineList(context, batchList);
context.getLogger().info("------ weatherDataProcess clear size d {} b {}", deleteList.size(), batchList.size());
CollUtil.clear(deleteList, batchList);
count = 0;
}
}
context.getLogger().info("------ weatherDataProcess delete and insertBatch");
if (CollUtil.isNotEmpty(deleteList)) {
this.deleteWindTurbineList(context, deleteList, create, end);
}
if (CollUtil.isNotEmpty(batchList)) {
this.insertWindTurbineList(context, batchList);
}
CollUtil.clear(deleteList, batchList);
context.getLogger().info("------ weatherDataProcess windTurbineDataProcess end ------");
}
/**
* 插入间歇装置预测功率列表
*
* @param context 上下文
* @param batchList 批处理列表
*/
private void insertWindTurbineList(XContext context, List<WindPredictionFutureView> batchList) {
if (CollUtil.isNotEmpty(batchList)) {
WindPredictionFutureViewMapper dataViewMapper = context.getBean(WindPredictionFutureViewMapper.class);
int size = batchList.size();
context.getLogger().info("------ insertWindTurbineList batchList insert size: {}", size);
if (size > BaseUtils.BATCH_SIZE) {
List<List<WindPredictionFutureView>> subList = BaseUtils.getSubList(batchList);
subList.forEach(dataViewMapper::insertBatch);
} else {
dataViewMapper.insertBatch(batchList);
}
}
}
/**
* 条件删除预测数据
*
* @param context 上下文
* @param deleteList 删除列表
* @param create 创造
* @param end 结束
*/
private void deleteWindTurbineList(XContext context, List<String> deleteList, DateTime create, DateTime end) {
if (CollUtil.isNotEmpty(deleteList)) {
WindPredictionFutureViewMapper mapper = context.getBean(WindPredictionFutureViewMapper.class);
int size = deleteList.size();
context.getLogger().info("------ deleteWindTurbineList batchDelete delete size: {}", size);
if (size > BaseUtils.BATCH_SIZE) {
List<List<String>> subList = BaseUtils.getSubList(deleteList);
for (List<String> list : subList) {
mapper.deleteBatch(list, create, end);
}
} else {
mapper.deleteBatch(deleteList, create, end);
}
}
}
/**
* 风机电站数据处理
*
* @param jsonObject json对象
* @param turbineMap 涡轮机图
* @param deleteList 删除列表
* @param batchList 批次列表
*/
private void windDataFractionation(JSONObject jsonObject, Map<String, List<BaseWindTurbineView>> turbineMap, List<String> deleteList,
List<WindPredictionFutureView> batchList) {
Map<String, List<DailyData>> cityDataMap = new HashMap<>(16);
for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof JSONArray) {
cityDataMap.put(key, ((JSONArray) value).toJavaList(DailyData.class));
}
}
for (String cityCode : cityDataMap.keySet()) {
if (!turbineMap.containsKey(cityCode)) {
continue;
}
List<DailyData> dailyDataList = cityDataMap.get(cityCode);
List<BaseWindTurbineView> plantViewList = turbineMap.get(cityCode);
//删除数据
for (BaseWindTurbineView plantView : plantViewList) {
deleteList.add(plantView.getId());
}
//遍历预测数据列表
for (DailyData dailyData : dailyDataList) {
for (BaseWindTurbineView plant : plantViewList) {
DateTime dateTime = DateUtil.date(dailyData.getDateTime());
List<WindPredictionFutureView> allList = new ArrayList<>(32);
List<WindPredictionFutureView> objList = new ArrayList<>(16);
String plantId = plant.getId();
DateTime date;
int flag = 0;
for (int i = 0; i < 8; i++) {
//判断小时数与查到的小时数,如果查到的小时数小,判断为第二天
int hour = LocalTime.parse(dailyData.getHourTimeArray().get(i)).getHour();
DateTime parse = DateUtil.parse(DateUtil.formatDate(dateTime) + ' ' + this.int2Str(hour) + ':' + BusinessConstant.START_OF_DAY_TIME);
if (DateUtil.compare(parse, dateTime) < 0 && flag == 0) {
parse = DateUtil.offsetDay(parse, 1);
dateTime = DateUtil.offsetDay(dateTime, 1);
flag++;
}
WindPredictionFutureView dao = WindPredictionFutureView.builder()
.stationId(plantId)
.dataTime(parse)
.windDirection(this.getWindDirection(dailyData.getWindDirectionArray(), i))
.windSpeed(this.stringToBigDecimal(dailyData.getWindSpeedArray(), i, "m/s"))
.airTemperature(this.stringToBigDecimal(dailyData.getTemperatureArray(), i, "℃"))
.humidity(this.stringToBigDecimal(dailyData.getHumidityArray(), i, "%"))
.pressure(this.stringToBigDecimal(dailyData.getPressureArray(), i, "hPa"))
.build();
// 5.执行SQL
allList.add(dao);
WindPredictionFutureView isExit = objList.stream()
.filter(item -> DateUtil.compare(item.getDataTime(), dao.getDataTime()) == 0)
.findFirst()
.orElse(null);
if (Objects.isNull(isExit)) {
objList.add(dao);
}
}
// 原站点时间结构为:08:00 11:00 14:00 17:00 20:00 23:00 02:00 05:00
// 两条数据中间差了两个小时,使用上下两条数据推算出中间差掉的两个小时
for (int i = 0; i < objList.size() - 1; i++) {
for (int y = 1; y < 3; y++) {
WindPredictionFutureView dataEnt = objList.get(i);
date = DateUtil.date(dataEnt.getDataTime());
String hourString;
Integer hourTime = date.hour(true);
if (hourTime.equals(23)) {
date = DateUtil.offsetDay(date, 1);
hourString = "0" + (y - 1);
} else {
if ((hourTime + y) < 10) {
hourString = "0" + (hourTime + y);
} else {
hourString = String.valueOf(hourTime + y);
}
}
WindPredictionFutureView nextData = objList.get(i + 1);
BigDecimal valueOf = BigDecimal.valueOf(0.3 * y);
WindPredictionFutureView dao = WindPredictionFutureView.builder()
.stationId(plantId)
.dataTime(DateUtil.parse(String.valueOf(date.year()) + '-' + this.int2Str(date.month() + 1) + '-' + this.int2Str(date.dayOfMonth()) + ' ' + hourString + ':' + BusinessConstant.START_OF_DAY_TIME))
.windDirection(dataEnt.getWindDirection())
.windSpeed(this.compute(dataEnt.getWindSpeed(), nextData.getWindSpeed(), valueOf))
.airTemperature(this.compute(dataEnt.getAirTemperature(), nextData.getAirTemperature(), valueOf))
.humidity(this.compute(dataEnt.getHumidity(), nextData.getHumidity(), valueOf))
.pressure(this.compute(dataEnt.getPressure(), nextData.getPressure(), valueOf))
.build();
// 5.执行SQL
allList.add(dao);
}
}
//入库
List<WindPredictionFutureView> sortList = allList.stream()
.sorted(Comparator.comparing(WindPredictionFutureView::getDataTime))
.collect(Collectors.toList());
for (int i = 0; i < sortList.size(); i++) {
WindPredictionFutureView item = sortList.get(i);
batchList.add(item);
if (i < sortList.size() - 1) {
for (int y = 0; y < BusinessConstant.TIME_LIST.size(); y++) {
WindPredictionFutureView dao = XCopyUtils.copyNewObject(item);
dao.setDataTime(DateUtil.parse(DateUtil.format(dao.getDataTime(), BusinessConstant.DATE_FORMAT_HOUR2) + ':' + BusinessConstant.TIME_LIST.get(y)));
WindPredictionFutureView nextData = sortList.get(i + 1);
BigDecimal valueOf = BigDecimal.valueOf(0.3 * (y + 1));
dao.setAirTemperature(this.compute(Objects.isNull(item.getAirTemperature()) ? BigDecimal.ZERO : item.getAirTemperature(),
Objects.isNull(nextData.getAirTemperature()) ? BigDecimal.ZERO : nextData.getAirTemperature(),
valueOf));
dao.setHumidity(this.compute(Objects.isNull(item.getHumidity()) ? BigDecimal.ZERO : item.getHumidity(),
Objects.isNull(nextData.getHumidity()) ? BigDecimal.ZERO : nextData.getHumidity(),
valueOf));
dao.setWindSpeed(this.compute(Objects.isNull(item.getWindSpeed()) ? BigDecimal.ZERO : item.getWindSpeed(),
Objects.isNull(nextData.getWindSpeed()) ? BigDecimal.ZERO : nextData.getWindSpeed(),
valueOf));
dao.setPressure(this.compute(Objects.isNull(item.getPressure()) ? BigDecimal.ZERO : item.getPressure(),
Objects.isNull(nextData.getPressure()) ? BigDecimal.ZERO : nextData.getPressure(),
valueOf));
batchList.add(dao);
}
}
}
}
}
}
}
/**
* 光伏数据处理
*
* @param context 上下文
* @param jsonObjectList json对象列表
*/
private void photovoltaicDataProcess(XContext context, List<JSONObject> jsonObjectList) {
context.getLogger().info("------ weatherDataProcess photovoltaicDataProcess begin ------");
//取电站(排除第二采油厂)
BasePhotovoltaicPlantViewMapper viewMapper = context.getBean(BasePhotovoltaicPlantViewMapper.class);
List<BasePhotovoltaicPlantView> plantList = viewMapper.selectPlantList(new BasePhotovoltaicPlantView());
if (CollUtil.isEmpty(plantList)) {
context.getLogger().info("------ weatherDataProcess plantList is empty ------");
return;
}
context.getLogger().info("------ weatherDataProcess dataFractionation");
List<String> deleteList = new ArrayList<>(32);
List<PlantPredictedPowerDataEnt> batchList = new ArrayList<>(BusinessConstant.LIST_MAX_SIZE);
DateTime create = DateUtil.date();
DateTime end = DateUtil.offsetDay(create, 16);
//按照cityCode分组
Map<String, List<BasePhotovoltaicPlantView>> plantMap = plantList.stream()
.collect(Collectors.groupingBy(BasePhotovoltaicPlantView::getCityCode));
int count = 0;
for (JSONObject jsonObject : jsonObjectList) {
this.dataFractionation(jsonObject, plantMap, deleteList, batchList);
if (count == 0) {
batchList.sort(Comparator.comparing(PlantPredictedPowerDataEnt::getDataDate));
create = DateUtil.offsetMinute(DateUtil.parse(batchList.get(0).getDataDate()), -5);
}
count++;
if (BusinessConstant.FIVE.equals(count)) {
this.deletePlantPredictedPowerList(context, deleteList, create, end);
this.insertBatchPlantPredictedPowerList(context, batchList);
context.getLogger().info("------ weatherDataProcess clear size d {} b {}", deleteList.size(), batchList.size());
CollUtil.clear(deleteList, batchList);
count = 0;
}
}
context.getLogger().info("------ weatherDataProcess delete and insertBatch");
if (CollUtil.isNotEmpty(deleteList)) {
this.deletePlantPredictedPowerList(context, deleteList, create, end);
}
if (CollUtil.isNotEmpty(batchList)) {
this.insertBatchPlantPredictedPowerList(context, batchList);
}
CollUtil.clear(deleteList, batchList);
context.getLogger().info("------ weatherDataProcess photovoltaicDataProcess end ------");
}
/**
* 数据拆分
*
* @param jsonObject json对象
* @param plantMap 植物地图
* @param deleteList 删除列表
* @param batchList 批次列表
*/
private void dataFractionation(JSONObject jsonObject, Map<String, List<BasePhotovoltaicPlantView>> plantMap, List<String> deleteList, List<PlantPredictedPowerDataEnt> batchList) {
Map<String, List<DailyData>> cityDataMap = new HashMap<>(16);
for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof JSONArray) {
cityDataMap.put(key, ((JSONArray) value).toJavaList(DailyData.class));
}
}
for (String cityCode : cityDataMap.keySet()) {
if (!plantMap.containsKey(cityCode)) {
continue;
}
List<DailyData> dailyDataList = cityDataMap.get(cityCode);
List<BasePhotovoltaicPlantView> plantViewList = plantMap.get(cityCode);
//删除数据
for (BasePhotovoltaicPlantView plantView : plantViewList) {
deleteList.add(plantView.getId());
}
//遍历预测数据列表
for (DailyData dailyData : dailyDataList) {
for (BasePhotovoltaicPlantView plant : plantViewList) {
DateTime dateTime = DateUtil.date(dailyData.getDateTime());
List<PlantPredictedPowerDataEnt> allList = new ArrayList<>(32);
List<PlantPredictedPowerDataEnt> objList = new ArrayList<>(16);
String plantId = plant.getId();
DateTime date;
int flag = 0;
for (int i = 0; i < 8; i++) {
//判断小时数与查到的小时数,如果查到的小时数小,判断为第二天
int hour = LocalTime.parse(dailyData.getHourTimeArray().get(i)).getHour();
DateTime parse = DateUtil.parse(DateUtil.formatDate(dateTime) + ' ' + this.int2Str(hour) + ':' + BusinessConstant.START_OF_DAY_TIME);
if (DateUtil.compare(parse, dateTime) < 0 && flag == 0) {
parse = DateUtil.offsetDay(parse, 1);
dateTime = DateUtil.offsetDay(dateTime, 1);
flag++;
}
PlantPredictedPowerDataEnt dao = this.getPlantPredictedPowerEnt(plantId,
this.int2Str(hour),
this.stringToBigDecimal(dailyData.getTemperatureArray(), i, "℃"),
this.stringToBigDecimal(dailyData.getWindSpeedArray(), i, "m/s"),
new BigDecimal(this.getWindDirection(dailyData.getWindDirectionArray(), i)),
this.stringToBigDecimal(dailyData.getPressureArray(), i, "hPa"),
this.stringToBigDecimal(dailyData.getHumidityArray(), i, "%"),
String.valueOf(parse.year()),
this.int2Str(parse.monthBaseOne()),
this.int2Str(parse.dayOfMonth())
);
// 5.执行SQL
allList.add(dao);
PlantPredictedPowerDataEnt isExit = objList.stream()
.filter(item ->
CharSequenceUtil.equals(item.getYearTime(), dao.getYearTime()) &&
CharSequenceUtil.equals(item.getMonthTime(), dao.getMonthTime()) &&
CharSequenceUtil.equals(item.getDayTime(), dao.getDayTime()) &&
CharSequenceUtil.equals(item.getHourTime(), dao.getHourTime()))
.findFirst()
.orElse(null);
if (Objects.isNull(isExit)) {
objList.add(dao);
}
}
// 原站点时间结构为:08:00 11:00 14:00 17:00 20:00 23:00 02:00 05:00
// 两条数据中间差了两个小时,使用上下两条数据推算出中间差掉的两个小时
for (int i = 0; i < objList.size() - 1; i++) {
for (int y = 1; y < 3; y++) {
PlantPredictedPowerDataEnt dataEnt = objList.get(i);
date = DateTime.of(dataEnt.getDataDate(), "yyyy-MM-dd HH:mm");
String hourString;
Integer hourTime = Integer.valueOf(dataEnt.getHourTime());
if (hourTime.equals(23)) {
date = DateUtil.offsetDay(date, 1);
hourString = "0" + (y - 1);
} else {
if ((hourTime + y) < 10) {
hourString = "0" + (hourTime + y);
} else {
hourString = String.valueOf(hourTime + y);
}
}
PlantPredictedPowerDataEnt nextData = objList.get(i + 1);
BigDecimal valueOf = BigDecimal.valueOf(0.3 * y);
PlantPredictedPowerDataEnt dao = this.getPlantPredictedPowerEnt(plantId,
hourString,
this.compute(dataEnt.getTemperature(), nextData.getTemperature(), valueOf),
this.compute(dataEnt.getWindSpeed(), nextData.getWindSpeed(), valueOf),
dataEnt.getWindDirection(),
this.compute(dataEnt.getPressure(), nextData.getPressure(), valueOf),
this.compute(dataEnt.getHumidity(), nextData.getHumidity(), valueOf),
String.valueOf(date.year()),
this.int2Str(date.month() + 1),
this.int2Str(date.dayOfMonth())
);
// 5.执行SQL
allList.add(dao);
}
}
//入库
List<PlantPredictedPowerDataEnt> sortList = allList.stream()
.sorted(Comparator.comparing(PlantPredictedPowerDataEnt::getDataDate))
.collect(Collectors.toList());
for (int i = 0; i < sortList.size(); i++) {
PlantPredictedPowerDataEnt item = sortList.get(i);
batchList.add(item);
if (i < sortList.size() - 1) {
for (int y = 0; y < BusinessConstant.TIME_LIST.size(); y++) {
PlantPredictedPowerDataEnt dao = XCopyUtils.copyNewObject(item);
dao.setMinTime(BusinessConstant.TIME_LIST.get(y));
dao.setDataDate(dao.getYearTime() + '-' + dao.getMonthTime() + '-' + dao.getDayTime() + ' ' + dao.getHourTime() + ':' + dao.getMinTime());
PlantPredictedPowerDataEnt nextData = sortList.get(i + 1);
BigDecimal valueOf = BigDecimal.valueOf(0.3 * (y + 1));
dao.setTemperature(this.compute(Objects.isNull(item.getTemperature()) ? BigDecimal.ZERO : item.getTemperature(),
Objects.isNull(nextData.getTemperature()) ? BigDecimal.ZERO : nextData.getTemperature(),
valueOf));
dao.setHumidity(this.compute(Objects.isNull(item.getHumidity()) ? BigDecimal.ZERO : item.getHumidity(),
Objects.isNull(nextData.getHumidity()) ? BigDecimal.ZERO : nextData.getHumidity(),
valueOf));
dao.setWindSpeed(this.compute(Objects.isNull(item.getWindSpeed()) ? BigDecimal.ZERO : item.getWindSpeed(),
Objects.isNull(nextData.getWindSpeed()) ? BigDecimal.ZERO : nextData.getWindSpeed(),
valueOf));
dao.setPressure(this.compute(Objects.isNull(item.getPressure()) ? BigDecimal.ZERO : item.getPressure(),
Objects.isNull(nextData.getPressure()) ? BigDecimal.ZERO : nextData.getPressure(),
valueOf));
dao.setPlaneIrradiance(this.compute(Objects.isNull(item.getPlaneIrradiance()) ? BigDecimal.ZERO : item.getPlaneIrradiance(),
Objects.isNull(nextData.getPlaneIrradiance()) ? BigDecimal.ZERO : nextData.getPlaneIrradiance(),
valueOf));
dao.setHorizontalIrradiance(this.compute(Objects.isNull(item.getHorizontalIrradiance()) ? BigDecimal.ZERO : item.getHorizontalIrradiance(),
Objects.isNull(nextData.getHorizontalIrradiance()) ? BigDecimal.ZERO : nextData.getHorizontalIrradiance(),
valueOf));
dao.setPower(this.compute(Objects.isNull(item.getPower()) ? BigDecimal.ZERO : item.getPower(),
Objects.isNull(nextData.getPower()) ? BigDecimal.ZERO : nextData.getPower(),
valueOf));
batchList.add(dao);
}
}
}
}
}
}
}
/**
* 获取电厂预测功率ent
*
* @param plantId 电站ID
* @param hourTime 小时
* @param temperature 温度
* @param windSpeed 风速
* @param windDirection 风向
* @param pressure 压力
* @param humidity 湿度
* @param yearTime 年时间
* @param monthTime 月份时间
* @param dayTime 白天
* @return {@link PlantPredictedPowerDataEnt}
*/
private PlantPredictedPowerDataEnt getPlantPredictedPowerEnt(String plantId, String hourTime, BigDecimal temperature, BigDecimal windSpeed, BigDecimal windDirection,
BigDecimal pressure, BigDecimal humidity, String yearTime, String monthTime, String dayTime) {
PlantPredictedPowerDataEnt dao = new PlantPredictedPowerDataEnt();
dao.setCreateTime(DateUtil.date());
dao.setPlantId(plantId);
dao.setHourTime(hourTime);
dao.setTemperature(temperature);
dao.setWindSpeed(windSpeed);
dao.setWindDirection(windDirection);
dao.setPressure(pressure);
dao.setHumidity(humidity);
dao.setYearTime(yearTime);
dao.setMonthTime(monthTime);
dao.setDayTime(dayTime);
dao.setMinTime(BusinessConstant.START_OF_DAY_TIME);
dao.setDataDate(dao.getYearTime() + '-' + dao.getMonthTime() + '-' + dao.getDayTime() + ' ' + dao.getHourTime() + ':' + dao.getMinTime());
return dao;
}
/**
* 条件删除预测数据
*
* @param context 上下文
* @param deleteList 删除列表
* @param create 创造
* @param end 结束
*/
private void deletePlantPredictedPowerList(XContext context, List<String> deleteList, DateTime create, DateTime end) {
if (CollUtil.isNotEmpty(deleteList)) {
PlantPredictedPowerDataMapper mapper = context.getBean(PlantPredictedPowerDataMapper.class);
int size = deleteList.size();
context.getLogger().info("------ deletePlantPredictedPowerList batchDelete delete size: {}", size);
if (size > BaseUtils.BATCH_SIZE) {
List<List<String>> subList = BaseUtils.getSubList(deleteList);
for (List<String> list : subList) {
mapper.delete(new LambdaQueryWrapper<PlantPredictedPowerDataEnt>()
.in(PlantPredictedPowerDataEnt::getPlantId, list)
.between(PlantPredictedPowerDataEnt::getDataDate, create, end));
}
} else {
mapper.delete(new LambdaQueryWrapper<PlantPredictedPowerDataEnt>()
.in(PlantPredictedPowerDataEnt::getPlantId, deleteList)
.between(PlantPredictedPowerDataEnt::getDataDate, create, end));
}
}
}
/**
* 插入间歇装置预测功率列表
*
* @param context 上下文
* @param batchList 批处理列表
*/
private void insertBatchPlantPredictedPowerList(XContext context, List<PlantPredictedPowerDataEnt> batchList) {
if (CollUtil.isNotEmpty(batchList)) {
PlantPredictedPowerDataViewMapper dataViewMapper = context.getBean(PlantPredictedPowerDataViewMapper.class);
int size = batchList.size();
context.getLogger().info("------ insertBatchPlantPredictedPowerList batchList insert size: {}", size);
if (size > BaseUtils.BATCH_SIZE) {
List<List<PlantPredictedPowerDataEnt>> subList = BaseUtils.getSubList(batchList);
subList.forEach(dataViewMapper::insertBatch);
} else {
dataViewMapper.insertBatch(batchList);
}
}
}
/**
* 获取风向
*
* @param windDirectionArray 风向阵列
* @param i 我
* @return int
*/
private int getWindDirection(List<String> windDirectionArray, int i) {
int wind = 0;
if (CollUtil.isNotEmpty(windDirectionArray)) {
if (i < windDirectionArray.size()) {
WindDirection windDirection = WindDirection.findByValue(windDirectionArray.get(i));
if (ObjectUtil.isNotNull(windDirection)) {
wind = windDirection.getValue();
}
}
}
return wind;
}
/**
* 字符串转换为BigDecimal
*
* @param stringList 字符串列表
* @param i 我
* @param replaceStr 替换str
* @return {@link BigDecimal }
*/
private BigDecimal stringToBigDecimal(List<String> stringList, int i, String replaceStr) {
BigDecimal result;
if (CollUtil.isNotEmpty(stringList) && i < stringList.size() && CharSequenceUtil.isNotBlank(stringList.get(i))) {
result = new BigDecimal(CharSequenceUtil.replace(stringList.get(i), replaceStr, ""));
} else {
result = BigDecimal.ZERO;
}
return result;
}
/**
* 按索引位置取字符串
*
* @param stringList 字符串列表
* @param i 我
* @return {@link String }
*/
private String getStringByIndex(List<String> stringList, int i) {
String result;
if (CollUtil.isNotEmpty(stringList) && i < stringList.size() && CharSequenceUtil.isNotBlank(stringList.get(i))) {
result = stringList.get(i);
} else {
result = BusinessConstant.DEFAULT_VALUE;
}
return result;
}
}
\ No newline at end of file
package pps.core.base.service;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import pps.cloud.base.service.IThirdWindPowerGenerationCloudService;
import pps.core.base.entity.ThirdWindPowerGenerationUpdateView;
import pps.core.base.entity.ThirdWindPowerGenerationView;
import pps.core.base.mapper.ThirdWindPowerGenerationUpdateViewMapper;
import pps.core.base.mapper.ThirdWindPowerGenerationViewMapper;
import pps.core.base.utils.ServiceUtil;
import pps.core.common.utils.BaseUtils;
import xstartup.annotation.XService;
import xstartup.base.XContext;
import xstartup.base.util.XCopyUtils;
import xstartup.data.XServiceResult;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 第三方风力发电数据
*
* @author ZWT
* @date 2024/09/03 16:34
*/
@XService
public class ThirdWindPowerGenerationCloudServiceImpl implements IThirdWindPowerGenerationCloudService {
/**
* 第三方风力发电数据定时任务
* todo 模拟数据生成
*
* @param context 上下文
* @return {@link XServiceResult }
*/
@Override
public XServiceResult thirdWindPowerGenerationJob(XContext context) {
DateTime endTime = DateUtil.date();
DateTime startTime = DateUtil.offsetMinute(endTime, -30);
ThirdWindPowerGenerationViewMapper viewMapper = context.getBean(ThirdWindPowerGenerationViewMapper.class);
List<ThirdWindPowerGenerationView> list = viewMapper.generateSimulatedData(ThirdWindPowerGenerationView.builder()
.startTime(startTime)
.endTime(endTime)
.build());
if (CollUtil.isNotEmpty(list)) {
List<ThirdWindPowerGenerationView> batchList = new ArrayList<>(list.size() * 2);
List<ThirdWindPowerGenerationUpdateView> batchUpdateList = new ArrayList<>(list.size());
//查当前环境
String systemSource = ServiceUtil.getOilFieldCode(context);
ThirdWindPowerGenerationView copy;
for (ThirdWindPowerGenerationView view : list) {
view.setSystemSource(systemSource);
view.setInputTime(endTime);
copy = this.newThirdWindPowerGenerationView(view);
batchList.add(copy);
batchList.add(view);
//每日最新数据
batchUpdateList.add(XCopyUtils.copyNewObject(view, ThirdWindPowerGenerationUpdateView.class));
}
//批量新增
if (batchList.size() > BaseUtils.BATCH_SIZE) {
List<List<ThirdWindPowerGenerationView>> subList = BaseUtils.getSubList(batchList);
subList.forEach(viewMapper::batchInsert);
} else {
viewMapper.batchInsert(batchList);
}
//生成每日最新数据
ThirdWindPowerGenerationUpdateViewMapper mapper = context.getBean(ThirdWindPowerGenerationUpdateViewMapper.class);
mapper.deleteBatch(list.stream()
.map(ThirdWindPowerGenerationView::getStationId)
.collect(Collectors.toList()),
DateUtil.beginOfDay(endTime), DateUtil.endOfDay(endTime));
//批量新增
if (batchUpdateList.size() > BaseUtils.BATCH_SIZE) {
List<List<ThirdWindPowerGenerationUpdateView>> subList = BaseUtils.getSubList(batchUpdateList);
subList.forEach(mapper::batchInsert);
} else {
mapper.batchInsert(batchUpdateList);
}
}
return XServiceResult.OK;
}
/*--------------------------------- private ---------------------------------*/
/**
* 第三代风力发电新观点
*
* @param view 看法
* @return {@link ThirdWindPowerGenerationView }
*/
private ThirdWindPowerGenerationView newThirdWindPowerGenerationView(ThirdWindPowerGenerationView view) {
return ThirdWindPowerGenerationView.builder()
.stationName(view.getStationName())
.stationId(view.getStationId())
.collectTime(DateUtil.offsetMinute(view.getCollectTime(), -15))
.actualWindSpeed(view.getActualWindSpeed())
.actualPower(view.getActualPower())
.actualGeneration(view.getActualGeneration())
.actualWindDirection(view.getActualWindDirection())
.inputTime(view.getInputTime())
.systemSource(view.getSystemSource())
.build();
}
}
\ No newline at end of file
package pps.core.base.service;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import pps.cloud.base.service.IWindPredictionHistoryCloudService;
import pps.core.base.entity.ThirdWindPowerGenerationEnt;
import pps.core.base.entity.WindPredictionFutureEnt;
import pps.core.base.entity.WindPredictionHistoryView;
import pps.core.base.mapper.ThirdWindPowerGenerationMapper;
import pps.core.base.mapper.WindPredictionFutureMapper;
import pps.core.base.mapper.WindPredictionHistoryViewMapper;
import pps.core.base.utils.ServiceUtil;
import pps.core.common.utils.BaseUtils;
import xstartup.annotation.XService;
import xstartup.base.XContext;
import xstartup.data.XServiceResult;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 风资源训练集数据Cloud模块
*
* @author ZWT
* @date 2024/08/30 14:07
*/
@XService
public class WindPredictionHistoryCloudServiceImpl implements IWindPredictionHistoryCloudService {
/**
* 风资源训练集定时任务
* wind_prediction_history的 actual_power存实际功率
* wind_prediction_future的 actual_power为预测功率
*
* @param context 上下文
* @return {@link XServiceResult }
*/
@Override
public XServiceResult windPredictionHistoryJob(XContext context) {
DateTime startTime = DateUtil.beginOfDay(DateUtil.yesterday());
DateTime endTime = DateUtil.endOfDay(startTime);
//取日期范围内已预测数据
WindPredictionFutureMapper mapper = context.getBean(WindPredictionFutureMapper.class);
List<WindPredictionFutureEnt> list = mapper.selectList(new QueryWrapper<WindPredictionFutureEnt>()
.select("station_id",
"data_time",
"wind_direction",
"wind_speed",
"air_temperature",
"humidity",
"pressure",
"actual_wind_speed",
"actual_power AS predicted_power")
.lambda()
.between(WindPredictionFutureEnt::getDataTime, startTime, endTime)
);
if (CollUtil.isNotEmpty(list)) {
//查实际发电数据
ThirdWindPowerGenerationMapper generationMapper = context.getBean(ThirdWindPowerGenerationMapper.class);
List<ThirdWindPowerGenerationEnt> generationList = generationMapper.selectList(new QueryWrapper<ThirdWindPowerGenerationEnt>()
.select("station_id", "collect_time", "MAX( actual_power ) AS actual_power",
"MAX( actual_generation ) AS actual_generation", "MAX( actual_wind_speed ) AS actual_wind_speed",
"MAX( actual_wind_direction ) AS actual_wind_direction")
.lambda()
.between(ThirdWindPowerGenerationEnt::getCollectTime, startTime, endTime)
.eq(ThirdWindPowerGenerationEnt::getSystemSource, ServiceUtil.getOilFieldCode(context))
.groupBy(ThirdWindPowerGenerationEnt::getStationId, ThirdWindPowerGenerationEnt::getCollectTime)
);
Map<String, Map<Date, ThirdWindPowerGenerationEnt>> collect;
if (CollUtil.isEmpty(generationList)) {
collect = Collections.emptyMap();
} else {
collect = generationList.stream()
.collect(Collectors.groupingBy(ThirdWindPowerGenerationEnt::getStationId, Collectors.toMap(ThirdWindPowerGenerationEnt::getCollectTime, Function.identity())));
}
//数据处理
List<WindPredictionHistoryView> historyList = this.dataProcess(list, collect);
//按时间范围删除数据
WindPredictionHistoryViewMapper viewMapper = context.getBean(WindPredictionHistoryViewMapper.class);
viewMapper.deleteByTimeRange(startTime, endTime);
if (historyList.size() > BaseUtils.BATCH_SIZE) {
List<List<WindPredictionHistoryView>> subList = BaseUtils.getSubList(historyList);
subList.forEach(viewMapper::batchInsert);
} else {
viewMapper.batchInsert(historyList);
}
}
return XServiceResult.OK;
}
/*------------------------- private -------------------------*/
/**
* 数据处理
* todo 模拟数据
*
* @param list 列表
* @param collect 收集
* @return {@link List }<{@link WindPredictionHistoryView }>
*/
private List<WindPredictionHistoryView> dataProcess(List<WindPredictionFutureEnt> list, Map<String, Map<Date, ThirdWindPowerGenerationEnt>> collect) {
List<WindPredictionHistoryView> historyList = new ArrayList<>(list.size());
Map<Date, ThirdWindPowerGenerationEnt> map;
ThirdWindPowerGenerationEnt ent;
for (WindPredictionFutureEnt future : list) {
WindPredictionHistoryView view = new WindPredictionHistoryView();
view.setStationId(future.getStationId());
view.setDataTime(future.getDataTime());
view.setWindDirection(future.getWindDirection());
view.setWindSpeed(future.getWindSpeed());
view.setAirTemperature(future.getAirTemperature());
view.setHumidity(future.getHumidity());
view.setPressure(future.getPressure());
view.setPredictedPower(future.getPredictedPower());
//匹配真实数据
boolean flag = true;
if (collect.containsKey(future.getStationId())) {
map = collect.get(future.getStationId());
if (map.containsKey(future.getDataTime())) {
flag = false;
ent = map.get(future.getDataTime());
view.setActualPower(ent.getActualPower());
view.setActualWindSpeed(ent.getActualWindSpeed());
view.setActualWindDirection(ent.getAccurateWindDirection());
}
}
if (flag) {
view.setActualPower(BigDecimal.ZERO);
view.setActualWindSpeed(BigDecimal.ZERO);
view.setActualWindDirection(BigDecimal.ZERO);
}
historyList.add(view);
}
return historyList;
}
}
\ No newline at end of file
package pps.core.base.service.data.base_data;
public class CalcBaseDataInput {
private String ou_id;// 组织机构
private String keyName;// 模型名称 model_xgb
private Integer line_id; // 线路名称
private String stape; // train_val训练/train_pre预测
private String startime; // 开始时间
private String endtime; // 结束时间
public CalcBaseDataInput() {
}
public CalcBaseDataInput(String ou_id, String keyName, Integer line_id, String stape, String startime, String endtime) {
this.ou_id = ou_id;
this.keyName = keyName;
this.line_id = line_id;
this.stape = stape;
this.startime = startime;
this.endtime = endtime;
}
public String getOu_id() {
return ou_id;
}
public void setOu_id(String ou_id) {
this.ou_id = ou_id;
}
public String getKeyName() {
return keyName;
}
public void setKeyName(String keyName) {
this.keyName = keyName;
}
public Integer getLine_id() {
return line_id;
}
public void setLine_id(Integer line_id) {
this.line_id = line_id;
}
public String getStape() {
return stape;
}
public void setStape(String stape) {
this.stape = stape;
}
public String getStartime() {
return startime;
}
public void setStartime(String startime) {
this.startime = startime;
}
public String getEndtime() {
return endtime;
}
public void setEndtime(String endtime) {
this.endtime = endtime;
}
}
package pps.core.base.service.data.base_data;
import xstartup.annotation.XText;
import java.math.BigDecimal;
import java.util.Date;
public class CreateBaseDataInput {
private Integer id;
@XText("组织id")
private String ouId;
@XText("线路id")
private Integer lineId;
@XText("日期")
private Date dataDate;
@XText("风速")
private BigDecimal windSpeed;
@XText("风向")
private BigDecimal windDirection;
@XText("温度")
private BigDecimal temperature;
@XText("压强")
private BigDecimal pressure;
@XText("湿度")
private BigDecimal humidity;
@XText("组件平面辐照度")
private BigDecimal planeIrradiance;
@XText("全水平辐照度")
private BigDecimal horizontalIrradiance;
@XText("实际功率")
private BigDecimal power;
@XText("预测功率")
private BigDecimal predictedPower;
@XText("天气")
private BigDecimal weather;
public BigDecimal getWeather() {
return weather;
}
public void setWeather(BigDecimal weather) {
this.weather = weather;
}
public Integer getId() {
return this.id;
}
public void setId(Integer value) {
this.id = value;
}
public String getOuId() {
return this.ouId;
}
public void setOuId(String value) {
this.ouId = value;
}
public Integer getLineId() {
return this.lineId;
}
public void setLineId(Integer value) {
this.lineId = value;
}
public Date getDataDate() {
return this.dataDate;
}
public void setDataDate(Date value) {
this.dataDate = value;
}
public BigDecimal getWindSpeed() {
return this.windSpeed;
}
public void setWindSpeed(BigDecimal value) {
this.windSpeed = value;
}
public BigDecimal getWindDirection() {
return this.windDirection;
}
public void setWindDirection(BigDecimal value) {
this.windDirection = value;
}
public BigDecimal getTemperature() {
return this.temperature;
}
public void setTemperature(BigDecimal value) {
this.temperature = value;
}
public BigDecimal getPressure() {
return this.pressure;
}
public void setPressure(BigDecimal value) {
this.pressure = value;
}
public BigDecimal getHumidity() {
return this.humidity;
}
public void setHumidity(BigDecimal value) {
this.humidity = value;
}
public BigDecimal getPlaneIrradiance() {
return this.planeIrradiance;
}
public void setPlaneIrradiance(BigDecimal value) {
this.planeIrradiance = value;
}
public BigDecimal getHorizontalIrradiance() {
return this.horizontalIrradiance;
}
public void setHorizontalIrradiance(BigDecimal value) {
this.horizontalIrradiance = value;
}
public BigDecimal getPower() {
return this.power;
}
public void setPower(BigDecimal value) {
this.power = value;
}
public BigDecimal getPredictedPower() {
return this.predictedPower;
}
public void setPredictedPower(BigDecimal value) {
this.predictedPower = value;
}
}
package pps.core.base.service.data.base_data;
public class DeleteBaseDataInput {
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
package pps.core.base.service.data.base_data;
import xstartup.annotation.XText;
public class GetBaseDataInput {
private Integer id;
@XText("组织id")
private String ouId;
@XText("线路id")
private Integer lineId;
@XText("日期")
private String dataDate;
private String keyName;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getOuId() {
return ouId;
}
public void setOuId(String ouId) {
this.ouId = ouId;
}
public Integer getLineId() {
return lineId;
}
public void setLineId(Integer lineId) {
this.lineId = lineId;
}
public String getDataDate() {
return dataDate;
}
public void setDataDate(String dataDate) {
this.dataDate = dataDate;
}
public String getKeyName() {
return keyName;
}
public void setKeyName(String keyName) {
this.keyName = keyName;
}
}
package pps.core.base.service.data.base_data;
import xstartup.annotation.XText;
import java.math.BigDecimal;
import java.util.Date;
public class GetBaseDataOutput {
private Integer id;
@XText("组织id")
private String ouId;
@XText("线路id")
private Integer lineId;
@XText("日期")
private Date dataDate;
@XText("风速")
private BigDecimal windSpeed;
@XText("风向")
private BigDecimal windDirection;
@XText("温度")
private BigDecimal temperature;
@XText("压强")
private BigDecimal pressure;
@XText("湿度")
private BigDecimal humidity;
@XText("组件平面辐照度")
private BigDecimal planeIrradiance;
@XText("全水平辐照度")
private BigDecimal horizontalIrradiance;
@XText("实际功率")
private BigDecimal power;
@XText("预测功率")
private BigDecimal predictedPower;
@XText("天气")
private BigDecimal weather;
public BigDecimal getWeather() {
return weather;
}
public void setWeather(BigDecimal weather) {
this.weather = weather;
}
public Integer getId() {
return this.id;
}
public void setId(Integer value) {
this.id = value;
}
public String getOuId() {
return this.ouId;
}
public void setOuId(String value) {
this.ouId = value;
}
public Integer getLineId() {
return this.lineId;
}
public void setLineId(Integer value) {
this.lineId = value;
}
public Date getDataDate() {
return this.dataDate;
}
public void setDataDate(Date value) {
this.dataDate = value;
}
public BigDecimal getWindSpeed() {
return this.windSpeed;
}
public void setWindSpeed(BigDecimal value) {
this.windSpeed = value;
}
public BigDecimal getWindDirection() {
return this.windDirection;
}
public void setWindDirection(BigDecimal value) {
this.windDirection = value;
}
public BigDecimal getTemperature() {
return this.temperature;
}
public void setTemperature(BigDecimal value) {
this.temperature = value;
}
public BigDecimal getPressure() {
return this.pressure;
}
public void setPressure(BigDecimal value) {
this.pressure = value;
}
public BigDecimal getHumidity() {
return this.humidity;
}
public void setHumidity(BigDecimal value) {
this.humidity = value;
}
public BigDecimal getPlaneIrradiance() {
return this.planeIrradiance;
}
public void setPlaneIrradiance(BigDecimal value) {
this.planeIrradiance = value;
}
public BigDecimal getHorizontalIrradiance() {
return this.horizontalIrradiance;
}
public void setHorizontalIrradiance(BigDecimal value) {
this.horizontalIrradiance = value;
}
public BigDecimal getPower() {
return this.power;
}
public void setPower(BigDecimal value) {
this.power = value;
}
public BigDecimal getPredictedPower() {
return this.predictedPower;
}
public void setPredictedPower(BigDecimal value) {
this.predictedPower = value;
}
}
package pps.core.base.service.data.base_data;
import xstartup.annotation.XText;
public class GetTrainBaseModelValInput {
private Integer id;
private String keyNames;
@XText("组织id")
private String ouId;
@XText("线路id")
private Integer lineId;
@XText("日期")
private String dataDate;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getOuId() {
return ouId;
}
public void setOuId(String ouId) {
this.ouId = ouId;
}
public Integer getLineId() {
return lineId;
}
public void setLineId(Integer lineId) {
this.lineId = lineId;
}
public String getDataDate() {
return dataDate;
}
public void setDataDate(String dataDate) {
this.dataDate = dataDate;
}
public String getKeyNames() {
return keyNames;
}
public void setKeyNames(String keyNames) {
this.keyNames = keyNames;
}
}
package pps.core.base.service.data.base_data;
import xstartup.annotation.XText;
import xstartup.base.data.XPageInput;
import java.util.Date;
public class QueryBaseDataInput extends XPageInput {
@XText("组织id")
private String ouId;
@XText("线路id")
private Integer lineId;
@XText("日期")
private Date dataDate;
public String getOuId() {
return ouId;
}
public void setOuId(String ouId) {
this.ouId = ouId;
}
public Integer getLineId() {
return lineId;
}
public void setLineId(Integer lineId) {
this.lineId = lineId;
}
public Date getDataDate() {
return dataDate;
}
public void setDataDate(Date dataDate) {
this.dataDate = dataDate;
}
}
package pps.core.base.service.data.base_data;
import xstartup.annotation.XText;
import xstartup.base.data.XPageInput;
import java.math.BigDecimal;
import java.util.Date;
public class QueryBaseDataOutput extends XPageInput {
private Integer id;
@XText("组织id")
private String ouId;
@XText("线路id")
private Integer lineId;
@XText("日期")
private Date dataDate;
@XText("风速")
private BigDecimal windSpeed;
@XText("风向")
private BigDecimal windDirection;
@XText("温度")
private BigDecimal temperature;
@XText("压强")
private BigDecimal pressure;
@XText("湿度")
private BigDecimal humidity;
@XText("组件平面辐照度")
private BigDecimal planeIrradiance;
@XText("全水平辐照度")
private BigDecimal horizontalIrradiance;
@XText("实际功率")
private BigDecimal power;
@XText("预测功率")
private BigDecimal predictedPower;
@XText("天气")
private BigDecimal weather;
public BigDecimal getWeather() {
return weather;
}
public void setWeather(BigDecimal weather) {
this.weather = weather;
}
public Integer getId() {
return this.id;
}
public void setId(Integer value) {
this.id = value;
}
public String getOuId() {
return this.ouId;
}
public void setOuId(String value) {
this.ouId = value;
}
public Integer getLineId() {
return this.lineId;
}
public void setLineId(Integer value) {
this.lineId = value;
}
public Date getDataDate() {
return this.dataDate;
}
public void setDataDate(Date value) {
this.dataDate = value;
}
public BigDecimal getWindSpeed() {
return this.windSpeed;
}
public void setWindSpeed(BigDecimal value) {
this.windSpeed = value;
}
public BigDecimal getWindDirection() {
return this.windDirection;
}
public void setWindDirection(BigDecimal value) {
this.windDirection = value;
}
public BigDecimal getTemperature() {
return this.temperature;
}
public void setTemperature(BigDecimal value) {
this.temperature = value;
}
public BigDecimal getPressure() {
return this.pressure;
}
public void setPressure(BigDecimal value) {
this.pressure = value;
}
public BigDecimal getHumidity() {
return this.humidity;
}
public void setHumidity(BigDecimal value) {
this.humidity = value;
}
public BigDecimal getPlaneIrradiance() {
return this.planeIrradiance;
}
public void setPlaneIrradiance(BigDecimal value) {
this.planeIrradiance = value;
}
public BigDecimal getHorizontalIrradiance() {
return this.horizontalIrradiance;
}
public void setHorizontalIrradiance(BigDecimal value) {
this.horizontalIrradiance = value;
}
public BigDecimal getPower() {
return this.power;
}
public void setPower(BigDecimal value) {
this.power = value;
}
public BigDecimal getPredictedPower() {
return this.predictedPower;
}
public void setPredictedPower(BigDecimal value) {
this.predictedPower = value;
}
}
package pps.core.base.service.data.base_data;
public class TrainBaseModelValDetailOutput {
private String key;
private String predictedPower;
private String power;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getPredictedPower() {
return predictedPower;
}
public void setPredictedPower(String predictedPower) {
this.predictedPower = predictedPower;
}
public String getPower() {
return power;
}
public void setPower(String power) {
this.power = power;
}
}
package pps.core.base.service.data.base_data;
import xstartup.annotation.XText;
import java.util.List;
public class TrainBaseModelValInput {
private Integer id;
private String keyName;
private List<String> keyNames;
@XText("组织id")
private String ouId;
@XText("线路id")
private Integer lineId;
@XText("日期")
private String dataDate;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getOuId() {
return ouId;
}
public void setOuId(String ouId) {
this.ouId = ouId;
}
public Integer getLineId() {
return lineId;
}
public void setLineId(Integer lineId) {
this.lineId = lineId;
}
public String getDataDate() {
return dataDate;
}
public void setDataDate(String dataDate) {
this.dataDate = dataDate;
}
public List<String> getKeyNames() {
return keyNames;
}
public void setKeyNames(List<String> keyNames) {
this.keyNames = keyNames;
}
public String getKeyName() {
return keyName;
}
public void setKeyName(String keyName) {
this.keyName = keyName;
}
}
package pps.core.base.service.data.base_data;
import com.baomidou.mybatisplus.annotation.TableField;
import xstartup.annotation.XText;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
public class TrainBaseModelValOutput {
@XText("实际数据")
private String ytrue;
@XText("预测数据")
private String ypred;
@TableField
private String mae;
@TableField
private String rmse;
@TableField
private String r2;
@XText("训练模式")
private String keyname;
@XText("线路")
private Integer lineId;
private String stape;
@XText("开始时间")
private String startime;
@XText("结束时间")
private String endtime;
private String taget;
private String timecol;
private String features;
private String modelpath;
private String paramKeys;
@XText("id")
private BigDecimal id;
@XText("创建时间")
private Date createTime;
private List<TrainBaseModelValDetailOutput> list;
public String getYtrue() {
return ytrue;
}
public void setYtrue(String ytrue) {
this.ytrue = ytrue;
}
public String getYpred() {
return ypred;
}
public void setYpred(String ypred) {
this.ypred = ypred;
}
public String getMae() {
return mae;
}
public void setMae(String mae) {
this.mae = mae;
}
public String getRmse() {
return rmse;
}
public void setRmse(String rmse) {
this.rmse = rmse;
}
public String getR2() {
return r2;
}
public void setR2(String r2) {
this.r2 = r2;
}
public String getKeyname() {
return keyname;
}
public void setKeyname(String keyname) {
this.keyname = keyname;
}
public Integer getLineId() {
return lineId;
}
public void setLineId(Integer lineId) {
this.lineId = lineId;
}
public String getStape() {
return stape;
}
public void setStape(String stape) {
this.stape = stape;
}
public String getStartime() {
return startime;
}
public void setStartime(String startime) {
this.startime = startime;
}
public String getEndtime() {
return endtime;
}
public void setEndtime(String endtime) {
this.endtime = endtime;
}
public String getTaget() {
return taget;
}
public void setTaget(String taget) {
this.taget = taget;
}
public String getTimecol() {
return timecol;
}
public void setTimecol(String timecol) {
this.timecol = timecol;
}
public String getFeatures() {
return features;
}
public void setFeatures(String features) {
this.features = features;
}
public String getModelpath() {
return modelpath;
}
public void setModelpath(String modelpath) {
this.modelpath = modelpath;
}
public String getParamKeys() {
return paramKeys;
}
public void setParamKeys(String paramKeys) {
this.paramKeys = paramKeys;
}
public BigDecimal getId() {
return id;
}
public void setId(BigDecimal id) {
this.id = id;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public List<TrainBaseModelValDetailOutput> getList() {
return list;
}
public void setList(List<TrainBaseModelValDetailOutput> list) {
this.list = list;
}
}
package pps.core.base.service.data.base_data;
import xstartup.annotation.XText;
import java.math.BigDecimal;
import java.util.Date;
public class UpdateBaseDataInput {
private Integer id;
@XText("组织id")
private String ouId;
@XText("线路id")
private Integer lineId;
@XText("日期")
private Date dataDate;
@XText("风速")
private BigDecimal windSpeed;
@XText("风向")
private BigDecimal windDirection;
@XText("温度")
private BigDecimal temperature;
@XText("压强")
private BigDecimal pressure;
@XText("湿度")
private BigDecimal humidity;
@XText("组件平面辐照度")
private BigDecimal planeIrradiance;
@XText("全水平辐照度")
private BigDecimal horizontalIrradiance;
@XText("实际功率")
private BigDecimal power;
@XText("预测功率")
private BigDecimal predictedPower;
@XText("天气")
private BigDecimal weather;
public BigDecimal getWeather() {
return weather;
}
public void setWeather(BigDecimal weather) {
this.weather = weather;
}
public Integer getId() {
return this.id;
}
public void setId(Integer value) {
this.id = value;
}
public String getOuId() {
return this.ouId;
}
public void setOuId(String value) {
this.ouId = value;
}
public Integer getLineId() {
return this.lineId;
}
public void setLineId(Integer value) {
this.lineId = value;
}
public Date getDataDate() {
return this.dataDate;
}
public void setDataDate(Date value) {
this.dataDate = value;
}
public BigDecimal getWindSpeed() {
return this.windSpeed;
}
public void setWindSpeed(BigDecimal value) {
this.windSpeed = value;
}
public BigDecimal getWindDirection() {
return this.windDirection;
}
public void setWindDirection(BigDecimal value) {
this.windDirection = value;
}
public BigDecimal getTemperature() {
return this.temperature;
}
public void setTemperature(BigDecimal value) {
this.temperature = value;
}
public BigDecimal getPressure() {
return this.pressure;
}
public void setPressure(BigDecimal value) {
this.pressure = value;
}
public BigDecimal getHumidity() {
return this.humidity;
}
public void setHumidity(BigDecimal value) {
this.humidity = value;
}
public BigDecimal getPlaneIrradiance() {
return this.planeIrradiance;
}
public void setPlaneIrradiance(BigDecimal value) {
this.planeIrradiance = value;
}
public BigDecimal getHorizontalIrradiance() {
return this.horizontalIrradiance;
}
public void setHorizontalIrradiance(BigDecimal value) {
this.horizontalIrradiance = value;
}
public BigDecimal getPower() {
return this.power;
}
public void setPower(BigDecimal value) {
this.power = value;
}
public BigDecimal getPredictedPower() {
return this.predictedPower;
}
public void setPredictedPower(BigDecimal value) {
this.predictedPower = value;
}
}
package pps.core.task.job;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import pps.cloud.base.service.IThirdWindPowerGenerationCloudService;
import pps.core.common.cache.TaskLockCache;
import pps.core.task.constant.TaskConstant;
import pps.core.task.utils.ServiceUtil;
import xstartup.annotation.XService;
import xstartup.annotation.XText;
import xstartup.base.XContext;
import xstartup.data.XServiceResult;
import xstartup.service.job.XJob;
import xstartup.service.job.annotation.XCronTrigger;
/**
* 第三方风力发电数据定时任务
* todo 测试用
*
* @author ZWT
* @date 2024/09/03 16:22
*/
@XText("第三方风力发电数据定时任务")
@XService
public class ThirdWindPowerGenerationJob implements XJob {
/**
* 每半小时执行
*
* @param xContext x上下文
* @return {@link XServiceResult }
*/
@XCronTrigger(value = TaskConstant.HALF_HOUR_31)
@Override
public XServiceResult execute(XContext xContext) {
xContext.getLogger().info("------ ThirdWindPowerGenerationJob start:{}", DateUtil.date());
String key = TaskConstant.TASK_LOCK_KEY + "ThirdWindPowerGenerationJob";
TaskLockCache exist = TaskLockCache.exist(xContext, key);
if (ObjectUtil.isNull(exist)) {
ServiceUtil.setCache(xContext, key);
try {
IThirdWindPowerGenerationCloudService service = xContext.getBean(IThirdWindPowerGenerationCloudService.class);
XServiceResult result = service.thirdWindPowerGenerationJob(xContext);
result.throwIfFail();
} catch (Exception e) {
xContext.getLogger().error("------ ThirdWindPowerGenerationJob Exception: ", e);
} finally {
xContext.getLogger().info("------ ThirdWindPowerGenerationJob end:{}", DateUtil.date());
TaskLockCache.delete(xContext, key);
}
}
return XServiceResult.OK;
}
}
\ No newline at end of file
package pps.core.task.job;
import cn.hutool.core.util.ObjectUtil;
import pps.cloud.base.service.IBaseWeatherCloudService;
import pps.core.common.cache.TaskLockCache;
import pps.core.task.constant.TaskConstant;
import pps.core.task.utils.ServiceUtil;
import xstartup.annotation.XText;
import xstartup.base.XContext;
import xstartup.data.XServiceResult;
/**
* 天气API数据邮件接收定时任务
*
* @author ZWT
* @date 2024/04/22 17:24
*/
@XText("天气API数据邮件接收定时任务")
public class WeatherApiReceiveJob {
/**
* 早/晚九点十五分执行
*
* @param xContext x上下文
* @return {@link XServiceResult}
*/
public XServiceResult execute(XContext xContext) {
xContext.getLogger().info("------ WeatherApiReceiveJob start:{}", System.currentTimeMillis());
String key = TaskConstant.TASK_LOCK_KEY + "WeatherApiReceiveJob";
TaskLockCache exist = TaskLockCache.exist(xContext, key);
if (ObjectUtil.isNull(exist)) {
ServiceUtil.setCache(xContext, key);
try {
IBaseWeatherCloudService service = xContext.getBean(IBaseWeatherCloudService.class);
XServiceResult result = service.weatherApiDataProcess(xContext);
result.throwIfFail();
} catch (Exception e) {
xContext.getLogger().error("------ WeatherApiReceiveJob Exception: ", e);
} finally {
xContext.getLogger().info("------ WeatherApiReceiveJob end:{}", System.currentTimeMillis());
TaskLockCache.delete(xContext, key);
}
}
return XServiceResult.OK;
}
}
\ No newline at end of file
package pps.core.task.job;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import pps.cloud.base.service.IBaseWeatherCloudService;
import pps.core.common.cache.TaskLockCache;
import pps.core.task.constant.TaskConstant;
import pps.core.task.utils.ServiceUtil;
import xstartup.annotation.XText;
import xstartup.base.XContext;
import xstartup.data.XServiceResult;
/**
* 天气数据邮件接收定时任务
*
* @author ZWT
* @date 2023/11/13 17:15
*/
@XText("天气数据邮件接收定时任务")
public class WeatherReceiveJob {
/**
* 半小时隔5分钟执行一次
*
* @param xContext x上下文
* @param oilFieldCode 油田代码
* @return {@link XServiceResult }
*/
public XServiceResult execute(XContext xContext, String oilFieldCode) {
xContext.getLogger().info("------ WeatherReceiveJob start:{}", DateUtil.date());
String key = TaskConstant.TASK_LOCK_KEY + "WeatherReceiveJob";
TaskLockCache exist = TaskLockCache.exist(xContext, key);
if (ObjectUtil.isNull(exist)) {
ServiceUtil.setCache(xContext, key);
try {
IBaseWeatherCloudService service = xContext.getBean(IBaseWeatherCloudService.class);
XServiceResult result = service.weatherDataProcess(xContext, oilFieldCode);
result.throwIfFail();
} catch (Exception e) {
xContext.getLogger().error("------ WeatherReceiveJob Exception: ", e);
} finally {
xContext.getLogger().info("------ WeatherReceiveJob end:{}", DateUtil.date());
TaskLockCache.delete(xContext, key);
}
}
return XServiceResult.OK;
}
}
\ No newline at end of file
package pps.core.task.job;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import pps.cloud.base.service.IWindPredictionHistoryCloudService;
import pps.core.common.cache.TaskLockCache;
import pps.core.task.constant.TaskConstant;
import pps.core.task.utils.ServiceUtil;
import xstartup.annotation.XService;
import xstartup.annotation.XText;
import xstartup.base.XContext;
import xstartup.data.XServiceResult;
import xstartup.service.job.XJob;
import xstartup.service.job.annotation.XCronTrigger;
/**
* 风资源训练集数据定时任务
*
* @author ZWT
* @date 2024/08/30 13:50
*/
@XText("风资源训练集数据定时任务")
@XService
public class WindPredictionHistoryJob implements XJob {
/**
* 每天00:12执行
*
* @param xContext x上下文
* @return {@link XServiceResult }
*/
@XCronTrigger(value = TaskConstant.EVERY_DAY_12)
@Override
public XServiceResult execute(XContext xContext) {
xContext.getLogger().info("------ WindPredictionHistoryJob start:{}", DateUtil.date());
String key = TaskConstant.TASK_LOCK_KEY + "WindPredictionHistoryJob";
TaskLockCache exist = TaskLockCache.exist(xContext, key);
if (ObjectUtil.isNull(exist)) {
ServiceUtil.setCache(xContext, key);
try {
IWindPredictionHistoryCloudService service = xContext.getBean(IWindPredictionHistoryCloudService.class);
XServiceResult result = service.windPredictionHistoryJob(xContext);
result.throwIfFail();
} catch (Exception e) {
xContext.getLogger().error("------ WindPredictionHistoryJob Exception: ", e);
} finally {
xContext.getLogger().info("------ WindPredictionHistoryJob end:{}", DateUtil.date());
TaskLockCache.delete(xContext, key);
}
}
return XServiceResult.OK;
}
}
......@@ -46,8 +46,6 @@ public class DeployPpsAllApplication {
startup.enable(XJobFeature.class).config(new XJobServiceConf(SpaceOptimizeUltraJob.class));
startup.enable(XJobFeature.class).config(new XJobServiceConf(SpaceOptimizeShortJob.class));
startup.enable(XJobFeature.class).config(new XJobServiceConf(PlantPredictedPowerLongTermDataJob.class));
startup.enable(XJobFeature.class).config(new XJobServiceConf(WindPredictionHistoryJob.class));
startup.enable(XJobFeature.class).config(new XJobServiceConf(ThirdWindPowerGenerationJob.class));
startup.run(args);
}
}
......@@ -17,8 +17,6 @@ x.job.service=pps.core.task.job.SpaceOptimizeLongJob,\
pps.core.task.job.SpaceCalibrationJob,\
pps.core.task.job.SpaceOptimizeShortJob,\
pps.core.task.job.SpaceOptimizeUltraJob,\
pps.core.task.job.WindPredictionHistoryJob,\
pps.core.task.job.ThirdWindPowerGenerationJob,\
pps.core.task.job.PlantPredictedPowerLongTermDataJob
# redis
x.cache.type=@x.cache.type@
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment