|
@@ -0,0 +1,460 @@
|
|
|
+package com.jiayue.insu.inclientqn.service;
|
|
|
+
|
|
|
+import cn.hutool.core.date.DateTime;
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import cn.hutool.core.date.LocalDateTimeUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import cn.hutool.http.HttpRequest;
|
|
|
+import cn.hutool.json.JSONObject;
|
|
|
+import cn.hutool.json.JSONUtil;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.jiayue.insu.inclientqn.constant.CommonStant;
|
|
|
+import com.jiayue.insu.inclientqn.entity.CorrforeSt;
|
|
|
+import com.jiayue.insu.inclientqn.entity.Record;
|
|
|
+import com.jiayue.insu.inclientqn.entity.Station;
|
|
|
+import com.jiayue.insu.inclientqn.inenum.QNHLEnum;
|
|
|
+import com.jiayue.insu.inclientqn.inenum.StatusEnum;
|
|
|
+import com.jiayue.insu.inclientqn.mapper.CorrforeStMapper;
|
|
|
+import com.jiayue.insu.inclientqn.model.RequestVo;
|
|
|
+import com.jiayue.insu.inclientqn.model.ResponseVo;
|
|
|
+import com.jiayue.insu.inclientqn.permisson.com.ComPermisson;
|
|
|
+import com.jiayue.insu.inclientqn.util.SystermUtils;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.velocity.Template;
|
|
|
+import org.apache.velocity.VelocityContext;
|
|
|
+import org.apache.velocity.app.VelocityEngine;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+import java.io.FileOutputStream;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.StringWriter;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.*;
|
|
|
+import java.util.regex.Matcher;
|
|
|
+import java.util.regex.Pattern;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @description:
|
|
|
+ * @author: yuanhao
|
|
|
+ * @createDate: 2021/9/27
|
|
|
+ * @version: 1.0
|
|
|
+ */
|
|
|
+@Service
|
|
|
+@Slf4j
|
|
|
+@RequiredArgsConstructor
|
|
|
+public class CorrforeService extends ServiceImpl<CorrforeStMapper, CorrforeSt> {
|
|
|
+
|
|
|
+
|
|
|
+ private final RecordService recordService;
|
|
|
+
|
|
|
+ private final StationService stationService;
|
|
|
+
|
|
|
+ private final CorrforeStService corrforeStService;
|
|
|
+
|
|
|
+ private final VelocityEngine velocityEngine;
|
|
|
+
|
|
|
+ private final ComPermisson comPermisson;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 下载修正预测数据
|
|
|
+ *
|
|
|
+ * @param station
|
|
|
+
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean downLoadCorrforeData(Station station) {
|
|
|
+
|
|
|
+ Record record = new Record();
|
|
|
+ record.setType(CommonStant.RECORD_TYPE_PULL_CORRECT);
|
|
|
+ LocalDateTime localDateTime = LocalDateTimeUtil.beginOfDay(LocalDateTime.now());
|
|
|
+ record.setTime(localDateTime);
|
|
|
+ record.setCreateTime(LocalDateTime.now());
|
|
|
+
|
|
|
+
|
|
|
+ String token = station.getComKey();
|
|
|
+ LocalDateTime tokenTime = station.getKeyTime();
|
|
|
+
|
|
|
+ String dataPullUrl = station.getDownloadurl();
|
|
|
+
|
|
|
+
|
|
|
+ boolean result = false;
|
|
|
+ boolean isUpload = false;
|
|
|
+ String response;
|
|
|
+ RequestVo requestVo;
|
|
|
+ List<CorrforeSt> list = new ArrayList<>();
|
|
|
+
|
|
|
+ if (StrUtil.isEmpty(token) || LocalDateTime.now().isAfter(tokenTime)) {
|
|
|
+ if (comPermisson.generateKey(station)) {
|
|
|
+ station = stationService.findThis();
|
|
|
+ token = station.getComKey();
|
|
|
+ tokenTime = station.getKeyTime();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (StrUtil.isNotEmpty(token) && LocalDateTime.now().isBefore(tokenTime)) {
|
|
|
+ try {
|
|
|
+
|
|
|
+ DateTime dateTime = DateUtil.parse(DateUtil.today());
|
|
|
+ requestVo = RequestVo.builder()
|
|
|
+ .transferType(QNHLEnum.TRANSFER_TYPE_CORRECT.getCode())
|
|
|
+ .date(dateTime.toString("yyyyMMdd"))
|
|
|
+ .dataType(QNHLEnum.DATA_CORRFORE_TYPE.getCode())
|
|
|
+ .build();
|
|
|
+
|
|
|
+ JSONObject json = JSONUtil.parseObj(requestVo, true);
|
|
|
+ String body = json.toString();
|
|
|
+
|
|
|
+ HttpRequest httpRequest = HttpRequest.post(dataPullUrl)
|
|
|
+ .header("Content-Type", "application/json")
|
|
|
+ .header("Authorization", token);
|
|
|
+ httpRequest.setGlobalTimeout(20000);
|
|
|
+ response = httpRequest
|
|
|
+ .body(body)
|
|
|
+ .execute().body();
|
|
|
+
|
|
|
+ if (StrUtil.isNotEmpty(response)) {
|
|
|
+ boolean isJson = JSONUtil.isJsonObj(response);
|
|
|
+ if (isJson) {
|
|
|
+ ResponseVo responseVo = JSONUtil.toBean(response, ResponseVo.class);
|
|
|
+ String code = responseVo.getRetCode();
|
|
|
+ if (code.equals(QNHLEnum.REQUEST_SUCCESS.getCode())) {
|
|
|
+
|
|
|
+ log.info(station.getStationCode() + " 请求短期修正数据返回内容:{}", response);
|
|
|
+
|
|
|
+ try {
|
|
|
+
|
|
|
+ if (CommonStant.ET_PHOTOVOLTAIC.equals(station.getType())) {
|
|
|
+ list = correctPhotovoltaicData(responseVo.getData());
|
|
|
+
|
|
|
+ } else {
|
|
|
+ list = correctWindData(responseVo.getData());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**************检测解析数据完整性*******************/
|
|
|
+ BigDecimal one = new BigDecimal("1");
|
|
|
+ BigDecimal checkCount = new BigDecimal(station.getDays().toString()).add(one).multiply(new BigDecimal("96")).add(one);
|
|
|
+
|
|
|
+ if(list.size()>0){
|
|
|
+ if (list.size() < checkCount.intValue()) {
|
|
|
+ log.warn("========== 请求短期修正数据缺数: {}", list.size());
|
|
|
+ }
|
|
|
+ corrforeStService.updateBetweenForecastTime(list.get(0).getTimeFormat(), list.get(list.size() - 1).getTimeFormat(), list);
|
|
|
+
|
|
|
+ genFile(station,list);
|
|
|
+
|
|
|
+ result = true;
|
|
|
+
|
|
|
+
|
|
|
+ }else{
|
|
|
+ record.setState(StatusEnum.CONNECT_RESPONSE_CONTENT_NULL.getCode());
|
|
|
+ record.setStateContent(StatusEnum.CONNECT_RESPONSE_CONTENT_NULL.getMsg());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**************检测解析数据完整性*******************/
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ record.setState(StatusEnum.CONNECT_RESPONSE_FORMAT_ERROR.getSign());
|
|
|
+ record.setStateContent("解析失败");
|
|
|
+ log.error("========== 解析短期或生成文件失败 ");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (result) {
|
|
|
+ log.info("========== 拉取短期修正数据成功! ==========");
|
|
|
+ record.setState(QNHLEnum.REQUEST_SUCCESS.getSign());
|
|
|
+ record.setStateContent(QNHLEnum.REQUEST_SUCCESS.getMsg());
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ record.setState(StatusEnum.CONNECT_RESPONSE_FORMAT_ERROR.getSign());
|
|
|
+ record.setStateContent(StatusEnum.CONNECT_RESPONSE_FORMAT_ERROR.getMsg());
|
|
|
+ log.error("========== 拉取短期修正数据失败 接收响应字符串非json格式 ");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ record.setState(StatusEnum.CONNECT_RESPONSE_CONTENT_NULL.getSign());
|
|
|
+ record.setStateContent(StatusEnum.CONNECT_RESPONSE_CONTENT_NULL.getMsg());
|
|
|
+ log.error("========== 拉取短期修正数据失败 返回响应内容为空 ==========");
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ record.setState(StatusEnum.CONNECT_ERROR.getSign());
|
|
|
+ record.setStateContent(StatusEnum.CONNECT_ERROR.getMsg());
|
|
|
+ log.error("========== 请求短期修正数据失败 连接断开或请求超时 ==========");
|
|
|
+ e.printStackTrace();
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ recordService.save(record);
|
|
|
+ return isUpload;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 光伏数据解析
|
|
|
+ *
|
|
|
+ * @param data 待解析数据
|
|
|
+ * @return
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public List<CorrforeSt> correctPhotovoltaicData(String data) throws Exception {
|
|
|
+ List<CorrforeSt> list = new ArrayList<>();
|
|
|
+
|
|
|
+ try {
|
|
|
+ String[] content = data.split("\n");
|
|
|
+
|
|
|
+ for (int i = 3; i < content.length - 1; i++) {
|
|
|
+
|
|
|
+ CorrforeSt corrforeSt = new CorrforeSt();
|
|
|
+ String column = content[i];
|
|
|
+ String[] datas = column.split(CommonStant.SPACE1_CONSTANT);
|
|
|
+ corrforeSt.setForecastTime(DateUtil.parse(datas[2], "yyyyMMddHHmmss").getTime());
|
|
|
+ corrforeSt.setTimeFormat(DateUtil.parse(datas[2], "yyyyMMddHHmmss").toTimestamp().toLocalDateTime());
|
|
|
+
|
|
|
+ if(column.contains("NULL") || column.contains("null")){
|
|
|
+
|
|
|
+ BigDecimal defaultValue =new BigDecimal("-99");
|
|
|
+
|
|
|
+ corrforeSt.setFpValue(defaultValue);
|
|
|
+
|
|
|
+ corrforeSt.setGlobalR(defaultValue);
|
|
|
+
|
|
|
+ corrforeSt.setDirectR(defaultValue);
|
|
|
+
|
|
|
+ corrforeSt.setDiffuseR(defaultValue);
|
|
|
+
|
|
|
+ corrforeSt.setT(defaultValue);
|
|
|
+
|
|
|
+ corrforeSt.setRh(defaultValue);
|
|
|
+
|
|
|
+ corrforeSt.setP(defaultValue);
|
|
|
+
|
|
|
+ corrforeSt.setWs(defaultValue);
|
|
|
+
|
|
|
+ corrforeSt.setWd(defaultValue);
|
|
|
+
|
|
|
+ corrforeSt.setCorrectTime(LocalDateTime.now());
|
|
|
+
|
|
|
+ }else{
|
|
|
+
|
|
|
+ corrforeSt.setFpValue(isNumber(datas[3]));
|
|
|
+
|
|
|
+ corrforeSt.setGlobalR(isNumber(datas[4]));
|
|
|
+
|
|
|
+ corrforeSt.setDirectR(isNumber(datas[5]));
|
|
|
+
|
|
|
+ corrforeSt.setDiffuseR(isNumber(datas[6]));
|
|
|
+
|
|
|
+ corrforeSt.setT(isNumber(datas[7]));
|
|
|
+
|
|
|
+ corrforeSt.setRh(isNumber(datas[8]));
|
|
|
+
|
|
|
+ corrforeSt.setP(isNumber(datas[9]));
|
|
|
+
|
|
|
+ corrforeSt.setWs(isNumber(datas[10]));
|
|
|
+
|
|
|
+ corrforeSt.setWd(isNumber(datas[11]));
|
|
|
+
|
|
|
+ corrforeSt.setCorrectTime(LocalDateTime.now());
|
|
|
+ }
|
|
|
+
|
|
|
+ Collections.sort(list, Comparator.comparing(CorrforeSt::getForecastTime));
|
|
|
+ list.add(corrforeSt);
|
|
|
+ }
|
|
|
+
|
|
|
+ }catch (Exception e){
|
|
|
+ e.printStackTrace();
|
|
|
+ log.error("解析一体化修正短期内容异常");
|
|
|
+ }
|
|
|
+
|
|
|
+ return list;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 风电数据解析
|
|
|
+ *
|
|
|
+ * @param data 待解析数据
|
|
|
+ * @return 解析数据
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public List<CorrforeSt> correctWindData(String data) throws Exception {
|
|
|
+
|
|
|
+ List<CorrforeSt> list = new ArrayList<>();
|
|
|
+ try {
|
|
|
+ String[] content = data.split("\n");
|
|
|
+
|
|
|
+ if (content[1].contains("CorrectForecast")) {
|
|
|
+
|
|
|
+ for (int i = 3; i < content.length - 1; i++) {
|
|
|
+
|
|
|
+ CorrforeSt corrforeSt = new CorrforeSt();
|
|
|
+ String column = content[i];
|
|
|
+ String[] datas = column.split(CommonStant.SPACE1_CONSTANT);
|
|
|
+ corrforeSt.setForecastTime(DateUtil.parse(datas[2], "yyyyMMddHHmmss").getTime());
|
|
|
+ corrforeSt.setTimeFormat(DateUtil.parse(datas[2], "yyyyMMddHHmmss").toTimestamp().toLocalDateTime());
|
|
|
+
|
|
|
+ if(column.contains("NULL") || column.contains("null")){
|
|
|
+ BigDecimal defaultValue = new BigDecimal("-99");
|
|
|
+
|
|
|
+ corrforeSt.setFpValue(defaultValue);
|
|
|
+
|
|
|
+ corrforeSt.setWs(defaultValue);
|
|
|
+
|
|
|
+ corrforeSt.setWd(defaultValue);
|
|
|
+
|
|
|
+ corrforeSt.setT(defaultValue);
|
|
|
+
|
|
|
+ corrforeSt.setRh(defaultValue);
|
|
|
+
|
|
|
+ corrforeSt.setP(defaultValue);
|
|
|
+
|
|
|
+ corrforeSt.setCorrectTime(LocalDateTime.now());
|
|
|
+ }else{
|
|
|
+
|
|
|
+ corrforeSt.setFpValue(isNumber(datas[3]));
|
|
|
+
|
|
|
+ corrforeSt.setWs(isNumber(datas[4]));
|
|
|
+
|
|
|
+ corrforeSt.setWd(isNumber(datas[5]));
|
|
|
+
|
|
|
+ corrforeSt.setT(isNumber(datas[6]));
|
|
|
+
|
|
|
+ corrforeSt.setRh(isNumber(datas[7]));
|
|
|
+
|
|
|
+ corrforeSt.setP(isNumber(datas[8]));
|
|
|
+
|
|
|
+ corrforeSt.setCorrectTime(LocalDateTime.now());
|
|
|
+ }
|
|
|
+ Collections.sort(list, Comparator.comparing(CorrforeSt::getForecastTime));
|
|
|
+ list.add(corrforeSt);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.error("解析一体化修正短期异常,标识错误不为<CorrectForecast>");
|
|
|
+
|
|
|
+ }
|
|
|
+ }catch (Exception e){
|
|
|
+ e.printStackTrace();
|
|
|
+ log.error("解析一体化修正短期内容异常");
|
|
|
+ }
|
|
|
+
|
|
|
+ return list;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断是否是数值
|
|
|
+ *
|
|
|
+ * @param data
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public BigDecimal isNumber(String data) {
|
|
|
+ BigDecimal bigDecimal = null;
|
|
|
+ Pattern pattern = Pattern.compile("-[0-9]+(.[0-9]+)?|[0-9]+(.[0-9]+)?");
|
|
|
+ Matcher isNum = pattern.matcher(data);
|
|
|
+ try {
|
|
|
+ if (isNum.matches()) {
|
|
|
+ bigDecimal = new BigDecimal(data).setScale(2, BigDecimal.ROUND_DOWN);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ return bigDecimal;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成文件
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public File genFile(Station station,List<CorrforeSt> list) {
|
|
|
+
|
|
|
+ String vmsPath = SystermUtils.getResourceBasePath() + "/vms/DQAMEND.vm";
|
|
|
+ File file = null;
|
|
|
+ Template template = this.velocityEngine.getTemplate(vmsPath);
|
|
|
+ if (template != null) {
|
|
|
+ VelocityContext velocityContext;
|
|
|
+ StringWriter writer;
|
|
|
+
|
|
|
+ list.sort(Comparator.comparing(CorrforeSt::getForecastTime));
|
|
|
+ List<Map<String, Object>> vList = new ArrayList<>();
|
|
|
+
|
|
|
+ for (CorrforeSt a : list) {
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("id", a.getId());
|
|
|
+ map.put("forecastTime", DateUtil.format(a.getTimeFormat(), "yyyyMMddHHmmss"));
|
|
|
+ map.put("fpValue", a.getFpValue() == null ? "-99" : a.getFpValue());
|
|
|
+ map.put("swr", a.getGlobalR() == null ? "-99" : a.getGlobalR());
|
|
|
+ map.put("directRadiation", a.getDirectR() == null ? "-99" : a.getDirectR());
|
|
|
+ map.put("diffuseRadiation", a.getDiffuseR() == null ? "-99" : a.getDiffuseR());
|
|
|
+ map.put("windspeed", a.getWs() == null ? "-99" : a.getWs());
|
|
|
+ map.put("windDir", a.getWd() == null ? "-99" : a.getWd());
|
|
|
+ map.put("temperature", a.getT() == null ? "-99" : a.getT());
|
|
|
+ map.put("humidity", a.getRh() == null ? "-99" : a.getRh());
|
|
|
+ map.put("pressure", a.getP() == null ? "-99" : a.getP());
|
|
|
+ vList.add(map);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ velocityContext = new VelocityContext();
|
|
|
+ velocityContext.put("sign", station.getStationCode());
|
|
|
+
|
|
|
+ velocityContext.put("uploadTime", DateUtil.format(new Date(), "yyyy-MM-dd"));
|
|
|
+ velocityContext.put("vList", vList);
|
|
|
+
|
|
|
+ writer = new StringWriter();
|
|
|
+ template.merge(velocityContext, writer);
|
|
|
+
|
|
|
+
|
|
|
+ File fileUrl = new File(station.getLocalFilePath());
|
|
|
+ if (!fileUrl.exists()) {// 判断目录是否存在
|
|
|
+ fileUrl.mkdirs();
|
|
|
+ }
|
|
|
+
|
|
|
+ String fileName = "AMENDFORECAST_" + DateUtil.format(new Date(), "yyyyMMddHHmm") + ".RB";
|
|
|
+
|
|
|
+ file = new File(station.getLocalFilePath() + File.separatorChar + fileName);
|
|
|
+
|
|
|
+
|
|
|
+ FileOutputStream os = null;
|
|
|
+
|
|
|
+ try {
|
|
|
+ boolean res = file.createNewFile();
|
|
|
+ if (res) {
|
|
|
+ os = new FileOutputStream(file);
|
|
|
+ // 采用UTF-8字符集
|
|
|
+ os.write(writer.toString().getBytes("UTF-8"));
|
|
|
+ os.flush();
|
|
|
+ } else {
|
|
|
+ log.warn(station.getStationCode() + " 生成minlo文件失败");
|
|
|
+ }
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ log.warn(station.getStationCode() + " 创建minlo文件失败");
|
|
|
+ } finally {
|
|
|
+ if (os != null) {
|
|
|
+ try {
|
|
|
+ os.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error("文件生成关闭流失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return file;
|
|
|
+ }
|
|
|
+}
|