|
@@ -0,0 +1,326 @@
|
|
|
+package com.jiayue.insu.incloud.pushdata;
|
|
|
+
|
|
|
+import cn.hutool.core.convert.Convert;
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import cn.hutool.core.io.file.FileReader;
|
|
|
+import cn.hutool.crypto.digest.HMac;
|
|
|
+import cn.hutool.crypto.digest.HmacAlgorithm;
|
|
|
+import cn.hutool.json.JSONArray;
|
|
|
+import cn.hutool.json.JSONObject;
|
|
|
+import com.jcraft.jsch.SftpException;
|
|
|
+import com.jiayue.insu.incloud.constants.CommonStant;
|
|
|
+import com.jiayue.insu.incloud.constants.CompanyConstant;
|
|
|
+import com.jiayue.insu.incloud.constants.enums.StatusEnum;
|
|
|
+import com.jiayue.insu.incloud.entity.IntegrationCompany;
|
|
|
+import com.jiayue.insu.incloud.entity.Record;
|
|
|
+import com.jiayue.insu.incloud.entity.Station;
|
|
|
+import com.jiayue.insu.incloud.service.IntegrationCompanyService;
|
|
|
+import com.jiayue.insu.incloud.service.RecordService;
|
|
|
+import com.jiayue.insu.incloud.utils.FileUtils;
|
|
|
+import com.jiayue.insu.incloud.utils.HttpUtils;
|
|
|
+import com.jiayue.insu.incloud.utils.SFTPUtil;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.velocity.VelocityContext;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+import java.io.FileNotFoundException;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 北京中央研究院推送数据
|
|
|
+ *
|
|
|
+ * @author yh
|
|
|
+ * @version 1.0
|
|
|
+ * @since 2022/5/22 11:29
|
|
|
+ */
|
|
|
+@Component
|
|
|
+@Slf4j
|
|
|
+public class PushDataForBJZYYJY implements IPushInitForecastData {
|
|
|
+ @Autowired
|
|
|
+ private RecordService recordService;
|
|
|
+ @Autowired
|
|
|
+ private IntegrationCompanyService integrationCompanyService;
|
|
|
+ @Autowired
|
|
|
+ private FileUtils fileUtils;
|
|
|
+ @Autowired
|
|
|
+ private HttpUtils httpUtils;
|
|
|
+ @Autowired
|
|
|
+ private SFTPUtil sftpUtil;
|
|
|
+ @Value("${localFilePath.initFilePath}")
|
|
|
+ String initFilePath;
|
|
|
+ @Value("${localFilePath.bjFilePath}")
|
|
|
+ String bjFilePath;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 推送原始预测数据
|
|
|
+ *
|
|
|
+ * @param station 场站信息
|
|
|
+ * @return 是否成功
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Boolean pushDQAndNWPData(Station station) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将下载好的原始短期文件通过sftp推送
|
|
|
+ *
|
|
|
+ * @param station
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Boolean pushDQData(Station station) {
|
|
|
+ // 获取场站编号
|
|
|
+ String stationCode = station.getStationCode();
|
|
|
+ Record record = new Record(CommonStant.RECORD_TYPE_PUSH_INIT_TO_SFTP, CompanyConstant.COMPANY_BJZYYJY, stationCode, null, LocalDateTime.now(), LocalDateTime.now(), null, null);
|
|
|
+ record.setState(StatusEnum.SUCCESS.getSign());
|
|
|
+ // 如果场站编号为空,则返回
|
|
|
+ if (stationCode == null || "".equals(stationCode)) {
|
|
|
+ record.setState(StatusEnum.STATION_CODE_NULL.getSign());
|
|
|
+ record.setStateContent(StatusEnum.STATION_CODE_NULL.getMsg());
|
|
|
+ recordService.save(record);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ // 获取指定目录下的短期原始数据(/jiayue/insu/file/init/J00269/)
|
|
|
+ String filePath = initFilePath + stationCode + File.separatorChar;
|
|
|
+ File files = new File(filePath);
|
|
|
+ String[] fileNames = files.list();
|
|
|
+ // 如果文件名列表为空
|
|
|
+ if (fileNames == null || fileNames.length == 0) {
|
|
|
+ log.info("指定目录下无文件");
|
|
|
+ record.setState(StatusEnum.FILE_NULL.getSign());
|
|
|
+ record.setStateContent(StatusEnum.FILE_NULL.getMsg());
|
|
|
+ recordService.save(record);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ // 获取当天日期
|
|
|
+ LocalDateTime today = LocalDateTime.now();
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
|
|
|
+ DateTimeFormatter formatterSeparator = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
|
+ String todaySeparatorStr = today.format(formatterSeparator);
|
|
|
+ String todayStr = today.format(formatter);
|
|
|
+ // 转为list并根据日期筛选排序
|
|
|
+ List<String> fileList = Arrays.stream(fileNames).collect(Collectors.toList());
|
|
|
+ List<String> filterFileList = fileList.stream().filter(s -> s.contains(todayStr)).filter(s -> s.contains("DQ")).collect(Collectors.toList());
|
|
|
+ // 如果筛选后无文件
|
|
|
+ if (filterFileList.size() == 0) {
|
|
|
+ log.info("无当日文件");
|
|
|
+ record.setState(StatusEnum.FILE_NULL.getSign());
|
|
|
+ record.setStateContent(StatusEnum.FILE_NULL.getMsg());
|
|
|
+ recordService.save(record);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ filterFileList.sort(Collections.reverseOrder());
|
|
|
+ // 获取原始文件
|
|
|
+ File originalFile = new File(filterFileList.get(0));
|
|
|
+ // 读取文件
|
|
|
+ FileReader fileReader = new FileReader(filePath + originalFile);
|
|
|
+ List<String> originalContents = fileReader.readLines();
|
|
|
+
|
|
|
+ List<Map<String, Object>> vList = new ArrayList<>();
|
|
|
+ String dataTime[];
|
|
|
+ // 循环解析原始短期文件
|
|
|
+ for (String originalContent : originalContents) {
|
|
|
+ // 从有#的数据开始获取 数据示例:#1 帽子山光伏电站 2023-06-22 00:00:00 0.0
|
|
|
+ if (originalContent.contains("#")) {
|
|
|
+ // 刨除当天的数据
|
|
|
+ if(originalContent.contains(todaySeparatorStr)){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 根据分隔符分割,取时间和功率
|
|
|
+ String[] originalContentArr = originalContent.split("\t");
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ // 如果分割后的数组长度小于4,则数据格式不正确
|
|
|
+ if (originalContentArr.length < 4) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 将时间2023-06-22 00:00:00根据分隔分割并组成2023-06-22_00:00:00格式
|
|
|
+ dataTime = originalContentArr[2].split(" ");
|
|
|
+ // 如果分割后的数组长度小于2,则数据格式不正确
|
|
|
+ if (dataTime.length < 2) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 将预测时间和预测功率放入list中
|
|
|
+ map.put("forecastTime", dataTime[0] + "_" + dataTime[1]);
|
|
|
+ map.put("fpValue", originalContentArr[3]);
|
|
|
+ vList.add(map);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 文件存放路径 /jiayue/insu/file/bjInit/J00269/
|
|
|
+ String newFilePath = bjFilePath + stationCode + File.separatorChar;
|
|
|
+ String templateName = File.separatorChar + "vms" + File.separatorChar + "BJZYYJYDQ.vm";
|
|
|
+ String newFileName = "modeloutput-" + stationCode + "J001-" + todayStr + "_SUBSHORT.RB";
|
|
|
+ String fileType = "dq";
|
|
|
+ // 文件数据开始时间
|
|
|
+ String fileDateStr = DateUtil.format(DateUtil.beginOfDay(DateUtil.tomorrow()), "yyyyMMdd_HH:mm:ss");
|
|
|
+ this.pushFileToSftp(record, vList, newFilePath, newFileName, templateName, station, fileType, todayStr, fileDateStr);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Boolean pushNWPData(Station station) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 通过sftp推送实际功率
|
|
|
+ *
|
|
|
+ * @param station
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public Boolean pushRealPowerData(Station station) {
|
|
|
+ Record record = new Record(CommonStant.RECORD_TYPE_PUSH_REAL_POWER_TO_SFTP, CompanyConstant.COMPANY_BJZYYJY, station.getStationCode(), null, LocalDateTime.now(), LocalDateTime.now(), null, null);
|
|
|
+ // 获取公司信息
|
|
|
+ IntegrationCompany integrationCompany = integrationCompanyService.findByCode(CompanyConstant.COMPANY_BJZYYJY);
|
|
|
+ // 获取云上实际功率接口url
|
|
|
+ String url = integrationCompany.getPullUrl();
|
|
|
+ // 获取当天日期
|
|
|
+ LocalDateTime today = LocalDateTime.now();
|
|
|
+ LocalDateTime yesterday = today.plusDays(-1);
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
|
|
|
+
|
|
|
+ String yesterdayStr = yesterday.format(formatter);
|
|
|
+ String todayStr = today.format(formatter);
|
|
|
+ String stationCode = station.getStationCode();
|
|
|
+ // 获取Signature
|
|
|
+ String sign = getSignature("123456&", stationCode, yesterdayStr, todayStr);
|
|
|
+ // post请求参数
|
|
|
+ HashMap<String, String> paramMap = new HashMap<>();
|
|
|
+ paramMap.put("stationCode", station.getStationCode());
|
|
|
+ paramMap.put("startTime", yesterdayStr);
|
|
|
+ paramMap.put("endTime", todayStr);
|
|
|
+ paramMap.put("sign", sign);
|
|
|
+ // 发送post请求并获取结果
|
|
|
+ JSONObject responseJson = httpUtils.httpPost(url, paramMap);
|
|
|
+ JSONArray dataArr = new JSONArray();
|
|
|
+ if (responseJson != null && responseJson.getInt("code") == 0) {
|
|
|
+ dataArr = responseJson.getJSONArray("data");
|
|
|
+ }
|
|
|
+ List<Map<String, Object>> vList = new ArrayList<>();
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss");
|
|
|
+ long time;
|
|
|
+ String realValue;
|
|
|
+ // 循环将请求的数据解析
|
|
|
+ for (int i = 0; i < dataArr.size(); i++) {
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ time = dataArr.getJSONObject(i).getLong("dataTimeStamp");
|
|
|
+ realValue = dataArr.getJSONObject(i).getStr("realPower");
|
|
|
+ map.put("forecastTime", sdf.format(time));
|
|
|
+ map.put("realPower", realValue);
|
|
|
+ vList.add(map);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 文件存放路径 /jiayue/insu/file/bjInit/J00269/
|
|
|
+ String newFilePath = bjFilePath + stationCode + File.separatorChar;
|
|
|
+ DateTimeFormatter formatterTime = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
|
|
|
+ String todayTimeStr = today.format(formatterTime);
|
|
|
+ String newFileName = "realpowerdata-" + stationCode + "J001-" + todayTimeStr + ".RB";
|
|
|
+ String templateName = File.separatorChar + "vms" + File.separatorChar + "BJZYYJYRP.vm";
|
|
|
+ // sftp具体路径
|
|
|
+ String sftpFilePath = "real";
|
|
|
+ // 文件数据开始时间
|
|
|
+ String fileDateStr = DateUtil.format(DateUtil.beginOfDay(new Date()), "yyyyMMdd_HH:mm:ss");
|
|
|
+ this.pushFileToSftp(record, vList, newFilePath, newFileName, templateName, station, sftpFilePath, todayStr, fileDateStr);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param record
|
|
|
+ * @param vList
|
|
|
+ * @param newFilePath
|
|
|
+ * @param newFileName
|
|
|
+ * @param templateName
|
|
|
+ * @param station
|
|
|
+ * @param fileType
|
|
|
+ * @param todayStr
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean pushFileToSftp(Record record, List<Map<String, Object>> vList, String newFilePath, String newFileName, String templateName, Station station, String fileType, String todayStr, String fileDateStr) {
|
|
|
+
|
|
|
+ VelocityContext velocityContext = new VelocityContext();
|
|
|
+ velocityContext.put("vList", vList);
|
|
|
+ velocityContext.put("createTime", DateUtil.format(new Date(), "yyyyMMdd_HH:mm:ss"));
|
|
|
+ velocityContext.put("date", fileDateStr);
|
|
|
+ velocityContext.put("stationCode", station.getStationCode());
|
|
|
+ velocityContext.put("stationName", station.getName());
|
|
|
+
|
|
|
+ File newFile;
|
|
|
+ // 生成新文件
|
|
|
+ try {
|
|
|
+ newFile = fileUtils.createFileByVelocityTemplate(newFilePath, newFileName, templateName, velocityContext);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ record.setState(StatusEnum.CREATE_FILE_FAIL.getSign());
|
|
|
+ record.setStateContent(StatusEnum.CREATE_FILE_FAIL.getMsg());
|
|
|
+ recordService.save(record);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 获取公司信息
|
|
|
+ IntegrationCompany integrationCompany = integrationCompanyService.findByCode(CompanyConstant.COMPANY_BJZYYJY);
|
|
|
+ String sftpInfo = integrationCompany.getPushUrl();
|
|
|
+ String[] sftpInfoArr = sftpInfo.split(":");
|
|
|
+ // 如果sftp的url配置不对,正确为 用户名:米面:ip:端口号:路径
|
|
|
+ if (sftpInfoArr.length < 5) {
|
|
|
+ record.setState(StatusEnum.PUSH_URL_ERROR.getSign());
|
|
|
+ record.setStateContent(StatusEnum.PUSH_URL_ERROR.getMsg());
|
|
|
+ recordService.save(record);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ String userName = sftpInfoArr[0];
|
|
|
+ String passWord = sftpInfoArr[1];
|
|
|
+ String sftpUrl = sftpInfoArr[2];
|
|
|
+ // 如果端口为空
|
|
|
+ if (sftpInfoArr[3] == null || "".equals(sftpInfoArr[3])) {
|
|
|
+ record.setState(StatusEnum.PUSH_URL_ERROR.getSign());
|
|
|
+ record.setStateContent(StatusEnum.PUSH_URL_ERROR.getMsg());
|
|
|
+ recordService.save(record);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ int sftpPort = Integer.valueOf(sftpInfoArr[3]);
|
|
|
+ String sftpFilePath = sftpInfoArr[4];
|
|
|
+ sftpFilePath = sftpFilePath + File.separatorChar + todayStr + File.separatorChar + fileType;
|
|
|
+
|
|
|
+// SFTPUtil sftp = new SFTPUtil(station.getUsername(), station.getPassword(), sftpUrl, sftpPort);
|
|
|
+ log.info("getUsername:" + userName);
|
|
|
+ log.info("getPassword:" + passWord);
|
|
|
+ log.info("sftpUrl:" + sftpUrl);
|
|
|
+ log.info("sftpPort:" + sftpPort);
|
|
|
+ log.info("sftpFilePath:" + sftpFilePath);
|
|
|
+ log.info("newFileName:" + newFile.getName());
|
|
|
+ // 多级目录创建并上传
|
|
|
+ try {
|
|
|
+ sftpUtil.uploadByFileAndPath(userName, passWord, sftpUrl, sftpPort, newFile, sftpFilePath, newFile.getName());
|
|
|
+ } catch (SftpException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (FileNotFoundException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ // 保存日志
|
|
|
+ recordService.save(record);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param keyStr
|
|
|
+ * @param paramsStr
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public String getSignature(String keyStr, String... paramsStr) {
|
|
|
+ byte[] key = keyStr.getBytes();
|
|
|
+ HMac mac = new HMac(HmacAlgorithm.HmacMD5, key);
|
|
|
+ //拼接签名元数据
|
|
|
+ String signOrg = Convert.toStr(paramsStr);
|
|
|
+ String macHexSign = mac.digestHex(signOrg);
|
|
|
+ return macHexSign;
|
|
|
+ }
|
|
|
+}
|