package com.jiayue.ipfcst.fileupload.service.E42;

import com.jiayue.ipfcst.common.core.exception.BusinessException;
import com.jiayue.ipfcst.common.core.util.DateMomentUtil;
import com.jiayue.ipfcst.common.data.constant.enums.ElectricFieldTypeEnum;
import com.jiayue.ipfcst.common.data.constant.enums.FileTypeEnum;
import com.jiayue.ipfcst.common.data.entity.*;
import com.jiayue.ipfcst.common.data.repository.*;
import com.jiayue.ipfcst.common.data.service.uploadfilerule.E42UploadFileRuleService;
import com.jiayue.ipfcst.console.service.ForecastPowerShortTermService;
import com.jiayue.ipfcst.console.service.ForecastPowerUltraShortTermService;
import com.jiayue.ipfcst.console.service.InverterInfoService;
import com.jiayue.ipfcst.console.service.NwpService;
import com.jiayue.ipfcst.dataexchange.service.EnvironmentDataAnyTimeGenerator;
import com.jiayue.ipfcst.fileupload.service.BaseUploadFileService;
import com.jiayue.ipfcst.fileupload.service.IUploadFileService;
import com.jiayue.ipfcst.fileupload.util.FileUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.hibernate.service.spi.ServiceException;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 湖北上报文件生成
 *
 * @author xsl
 * @version 3.0
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class E42UploadFileService extends BaseUploadFileService implements IUploadFileService {

  private String vmsPath = FileUtil.getResourceBasePath() + "/vms/E42";

  private final VelocityEngine velocityEngine;

  private final ForecastPowerShortTermService forecastPowerShortTermService;

  private final ForecastPowerUltraShortTermService forecastPowerUltraShortTermService;

  private final NwpService nwpService;

  private final WindTowerInfoRepository windTowerInfoRepository;

  private final NwpRepository nwpRepository;

  private final E42UploadFileRuleService e42UploadFileRuleService;

  private final WeatherStationInfoRepository weatherStationInfoRepository;

  private final WindTurbineInfoRepository windTurbineInfoRepository;

  private final InverterInfoService inverterInfoService;


  @Override
  public Map<String, String> getUploadFileType() {
    Map<String, String> uploadFileTypeMap = new HashMap<>();
    uploadFileTypeMap.put(FileTypeEnum.E1.toString(), FileTypeEnum.E1.getMessage());
    uploadFileTypeMap.put(FileTypeEnum.E2.toString(), FileTypeEnum.E2.getMessage());
    uploadFileTypeMap.put(FileTypeEnum.E5.toString(), FileTypeEnum.E5.getMessage());
    uploadFileTypeMap.put(FileTypeEnum.E6.toString(), FileTypeEnum.E6.getMessage());
    uploadFileTypeMap.put(FileTypeEnum.E7.toString(), FileTypeEnum.E7.getMessage());
    uploadFileTypeMap.put(FileTypeEnum.E8.toString(), FileTypeEnum.E8.getMessage());
    uploadFileTypeMap.put(FileTypeEnum.E9.toString(), FileTypeEnum.E9.getMessage());
    return uploadFileTypeMap;
  }

  @Override
  public void generateFile(String fileType, Date date) {
    switch (fileType) {
      case "E1":
        // 可用短期
        this.generateE1File(date);
        break;
      case "E2":
        // 超短期
        this.generateE2File(date);
        break;
      case "E5":
        // 72NWP
        this.generateE5File(date);
        break;
      case "E6":
        // 气象站
        this.generateE6File(date);
        break;
      case "E7":
        // 测风塔
        this.generateE7File(date);
        break;
      case "E8":
        // 逆变器
        this.generateE8File(date);
        break;
      case "E9":
        // 风机
        this.generateE9File(date);
        break;
      default:
        break;
    }
  }

  /**
   * 生成省调D5000短期预测上报文件。
   */
  private void generateE1File(Date date) {
    // 获取短期模板
    Template template = this.velocityEngine.getTemplate(this.vmsPath + "/DQ_SD.vm");
    if (template != null) {
      VelocityContext velocityContext;
      StringWriter writer;
      String fileName;
      File file;
      ElectricField electricFieldInfo = null;
      try {
        electricFieldInfo = super.getElectricField();
      } catch (BusinessException e) {
        log.error("场站获取失败", e);
      }

      if (electricFieldInfo.getElectricFieldTypeEnum().getCode().toString().equals("1")) {
        template = this.velocityEngine.getTemplate(this.vmsPath + "/DQ_SD_G.vm");
      }
      // 获取当前系统时间
      Date systemDate = new Date();
      if (date != null) {
        systemDate = date;
      }
      // 短期默认天数
      int dqDays = super.getTranSysParameter("FILE_FORECAST_DAYS", "3");
      try {
        // 开始时间
        Long startTime = DateMomentUtil.getDayStartTime(DateUtils.addDays(systemDate, 1).getTime());
        // 结束时间（开始加24小时再减去1秒）
        Long endTime = DateMomentUtil.getDayLastTime(DateUtils.addDays(systemDate, dqDays).getTime());
        // 生成上报文件名格式
        fileName = e42UploadFileRuleService.getFileNameRule(electricFieldInfo, "E1", startTime);

        if (getFileName(fileName, "E1")) {
          // 查询短期预测功率
          List<ForecastPowerShortTermHis> forecastPowerShortTermHisList = this.forecastPowerShortTermService.getForecastPowerShortTerm(startTime, endTime);

          // 创建上报文件
          file = super.createTempFile(fileName);
          // 根据模板生成文件内容
          velocityContext = new VelocityContext();
          velocityContext.put("vList", forecastPowerShortTermHisList);
          velocityContext.put("efiLabel", electricFieldInfo.getSign());
          // 场站标识
          velocityContext.put("sign", electricFieldInfo.getSign());
          // 场站标识别名
          velocityContext.put("backupA", electricFieldInfo.getNetSubstationName());
          // 场站装机容量
          velocityContext.put("capacity", electricFieldInfo.getCapacity());
          // 系统当前日期
          velocityContext.put("currentTime", DateFormatUtils.format(systemDate, "yyyy-MM-dd_HH:mm:ss"));
          // 上报数据开始日期
          velocityContext.put("uploadTime", DateFormatUtils.format(startTime, "yyyy-MM-dd") + "_00:00");
          writer = new StringWriter();
          template.merge(velocityContext, writer);
          super.copyUploadFile(writer, file, FileTypeEnum.E1.name(), null, date);
        }
      } catch (Exception e) {
        log.error("省调D5000短期文件生成失败", e);
      }
    } else {
      log.error("省调D5000短期上报模板不存在!");
    }
  }

  /**
   * 生成省调D5000超短期预测上报文件。
   */
  private void generateE2File(Date date) {
    ElectricField electricFieldInfo = null;
    try {
      electricFieldInfo = super.getElectricField();
    } catch (BusinessException e) {
      log.error("场站获取失败", e);
    }
    // 获取超短期模板
    File file1 = null;
    try {
      file1 = ResourceUtils.getFile(this.vmsPath + "/CDQ_SD.vm");
      if (electricFieldInfo.getElectricFieldTypeEnum().getCode().toString().equals("1")) {
        file1 = ResourceUtils.getFile(this.vmsPath + "/CDQ_SD_G.vm");
      }
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    }
    Template template = this.velocityEngine.getTemplate(file1.getPath());
    if (template != null) {
      VelocityContext velocityContext;
      StringWriter writer;
      String fileName;
      File file;
      // 短期默认天数
      int cdqPoint = super.getTranSysParameter("FILE_CDQ_POINT", "16");
      // 获取提前几分钟生成超短期
      int cdqUpMin = super.getTranSysParameter("CDQ_UP_MIN", "0");

      // 获取当前系统时间
      Date systemDate = new Date();
      if (date != null) {
        systemDate = new Date(date.getTime() - cdqUpMin * 1000 * 60);
      }

      try {
        // 开始时间
        Long startTime = DateMomentUtil.getMomentTime(systemDate.getTime() + 15 * 60 * 1000 + cdqUpMin * 1000 * 60, 1, 15 * 60 * 1000L);
        // 结束时间
        Long endTime = startTime + cdqPoint * 15 * 60 * 1000 - 1000;

        // 生成上报文件名格式
        fileName = e42UploadFileRuleService.getFileNameRule(electricFieldInfo, "E2", startTime);

        if (getFileName(fileName, "E2")) {
          // 查询超短期预测功率
          List<ForecastPowerUltraShortTermHis> forecastPowerUltraShortTermList = this.forecastPowerUltraShortTermService.getForecastPowerUltraShortTerm(startTime, endTime);

          // 创建上报文件
          file = super.createTempFile(fileName);
          // 根据模板生成文件内容
          velocityContext = new VelocityContext();
          velocityContext.put("vList", forecastPowerUltraShortTermList);
          velocityContext.put("efiLabel", electricFieldInfo.getSign());
          // 场站标识
          velocityContext.put("sign", electricFieldInfo.getSign());
          // 场站装机容量
          velocityContext.put("capacity", electricFieldInfo.getCapacity());
          // 系统当前日期
          velocityContext.put("currentTime", DateFormatUtils.format(startTime, "yyyy-MM-dd_HH:mm:ss"));
          // 上报数据开始日期
          velocityContext.put("uploadTime", DateFormatUtils.format(startTime, "yyyy-MM-dd_HH:mm"));
          writer = new StringWriter();
          template.merge(velocityContext, writer);

          super.copyUploadFile(writer, file, FileTypeEnum.E2.name(), null, date);
        }
      } catch (Exception e) {
        log.error("省调D5000超短期文件生成失败", e);
      }
    } else {
      log.error("省调D5000超短期上报模板不存在!");
    }
  }

  /**
   * 生成省调D500072NWP预测上报文件。
   */
  private void generateE5File(Date date) {
    // 获取72nwp模板
    Template template = this.velocityEngine.getTemplate(this.vmsPath + "/NWP72_SD.vm");
    if (template != null) {
      VelocityContext velocityContext;
      StringWriter writer;
      String fileName;
      File file;
      ElectricField electricFieldInfo = null;
      try {
        electricFieldInfo = super.getElectricField();
      } catch (BusinessException e) {
        log.error("场站获取失败", e);
      }

      // 获取当前系统时间
      Date systemDate = new Date();
      if (date != null) {
        systemDate = date;
      }
      // 短期默认天数
      int fileNwpDays = super.getTranSysParameter("FILE_NWP_DAYS", "3");

      //获取nwp72轮毂高度
      int turbinH = super.getTranSysParameter("HB_NWP72_TURBINH", "80");

      try {
        Long startTime = DateMomentUtil.getDayStartTime(DateUtils.addDays(systemDate, 1).getTime());
        Long endTime = DateMomentUtil.getDayLastTime(DateUtils.addDays(systemDate, fileNwpDays).getTime()) - 1000;
        // 生成上报文件名格式
        fileName = e42UploadFileRuleService.getFileNameRule(electricFieldInfo, "E5", startTime);
        if (getFileName(fileName, "E5")) {
          List<Map<String, Object>> list = new ArrayList<>();
          DecimalFormat df = new DecimalFormat("0.00");
          // 根据模板生成文件内容
          velocityContext = new VelocityContext();
          // 查询NWP数据
          List<Nwp> nwpDataList = this.nwpService.getNwpData(startTime, endTime);
          // 按照预测时间进行升序
          nwpDataList.sort(Comparator.comparing(Nwp::getPreTime));
          if (ElectricFieldTypeEnum.E1.equals(electricFieldInfo.getElectricFieldTypeEnum())) {
            // 光伏
            for (int i = 0; i < nwpDataList.size(); i++) {
              Map<String, Object> map = new HashMap<>();
              map.put("time", DateFormatUtils.format(nwpDataList.get(i).getPreTime(), "yyyy/MM/dd_HH:mm"));
              map.put("GlobalR", df.format(nwpDataList.get(i).getDirectRadiation().floatValue() + nwpDataList.get(i).getDiffuseRadiation().floatValue()));
              map.put("DirectR", df.format(nwpDataList.get(i).getDirectRadiation()));
              map.put("DiffuseR", df.format(nwpDataList.get(i).getDiffuseRadiation()));
              map.put("t", df.format(nwpDataList.get(i).getT()));
              map.put("rh", df.format(nwpDataList.get(i).getRh()));
              map.put("p", df.format(nwpDataList.get(i).getPressure()));
              map.put("ws", df.format(nwpDataList.get(i).getWs10()));
              map.put("wd", df.format(nwpDataList.get(i).getWd10()));
              list.add(map);
            }
          } else {
            for (int i = 0; i < nwpDataList.size(); i++) {
              Map<String, Object> map = new HashMap<>();
              map.put("time", DateFormatUtils.format(nwpDataList.get(i).getPreTime(), "yyyy/MM/dd_HH:mm"));
              map.put("ws10", df.format(nwpDataList.get(i).getWs10()));
              map.put("wd10", df.format(nwpDataList.get(i).getWd10()));
              map.put("ws30", df.format(nwpDataList.get(i).getWs30()));
              map.put("wd30", df.format(nwpDataList.get(i).getWd30()));
              map.put("ws100", df.format(nwpDataList.get(i).getWs100()));
              map.put("wd100", df.format(nwpDataList.get(i).getWd100()));
              map.put("ws170", df.format(nwpDataList.get(i).getWs170()));
              map.put("wd170", df.format(nwpDataList.get(i).getWd170()));
              map.put("t", df.format(nwpDataList.get(i).getT()));
              map.put("rh", df.format(nwpDataList.get(i).getRh()));
              map.put("ps", df.format(nwpDataList.get(i).getPressure()));
              BigDecimal turbinWS = new BigDecimal(-99);
              BigDecimal turbinWD = new BigDecimal(-99);

              switch (turbinH) {
                case 10:
                  turbinWS = nwpDataList.get(i).getWs10();
                  turbinWD = nwpDataList.get(i).getWd10();
                  break;
                case 30:
                  turbinWS = nwpDataList.get(i).getWs30();
                  turbinWD = nwpDataList.get(i).getWd30();
                  break;
                case 50:
                  turbinWS = nwpDataList.get(i).getWs50();
                  turbinWD = nwpDataList.get(i).getWd50();
                  break;
                case 70:
                  turbinWS = nwpDataList.get(i).getWs70();
                  turbinWD = nwpDataList.get(i).getWd70();
                  break;
                case 80:
                  turbinWS = nwpDataList.get(i).getWs80();
                  turbinWD = nwpDataList.get(i).getWd80();
                  break;
                case 90:
                  turbinWS = nwpDataList.get(i).getWs90();
                  turbinWD = nwpDataList.get(i).getWd90();
                  break;
                case 100:
                  turbinWS = nwpDataList.get(i).getWs100();
                  turbinWD = nwpDataList.get(i).getWd100();
                  break;
                case 170:
                  turbinWS = nwpDataList.get(i).getWs170();
                  turbinWD = nwpDataList.get(i).getWd170();
                  break;
                default:
                  break;
              }
              map.put("turbinWS", df.format(turbinWS));
              map.put("turbinWD", df.format(turbinWD));
              list.add(map);
            }
          }
          // 创建上报文件
          file = super.createTempFile(fileName);
          velocityContext.put("vList", list);
          velocityContext.put("sign", electricFieldInfo.getSign());
          velocityContext.put("electricFieldType", electricFieldInfo.getElectricFieldTypeEnum().toString());
          // 上报数据开始日期
          velocityContext.put("currentTime", DateFormatUtils.format(systemDate, "yyyy-MM-dd_HH:mm:ss"));
          velocityContext.put("uploadTime", DateFormatUtils.format(startTime, "yyyy-MM-dd") + "_00:00");
          writer = new StringWriter();
          template.merge(velocityContext, writer);
          super.copyUploadFile(writer, file, FileTypeEnum.E5.name(), null, date);
        }
      } catch (Exception e) {
        log.error("72NWP省调D5000文件生成失败", e);
      }
    } else {
      log.error("72NWP省调D5000上报模板不存在!");
    }
  }

  /**
   * 生成地调气象站上报文件
   */
  private void generateE6File(Date date) {
    // 获取气象站模板
    Template template = this.velocityEngine.getTemplate(this.vmsPath + "/QXZ_SD.vm");
    if (template != null) {
      VelocityContext velocityContext;
      StringWriter writer;
      String fileName;
      File file;
      ElectricField electricFieldInfo = null;
      try {
        electricFieldInfo = super.getElectricField();
      } catch (BusinessException e) {
        log.error("场站获取失败", e);
      }

      // 获取当前系统时间
      Date systemDate = new Date();
      if (date != null) {
        systemDate = date;
      }

      try {
        Long startTime;
        try {
          startTime = DateMomentUtil.getMomentTime(systemDate.getTime() - 5 * 60 * 1000, 1, 5 * 60 * 1000L);
        } catch (Exception e) {
          log.error("气象站文件生成时刻步长错误", e);
          startTime = DateMomentUtil.getDayStartTime(systemDate.getTime());
        }
        Long endTime = startTime + 5 * 60 * 1000 - 1000;
        // 生成上报文件名格式
        fileName = e42UploadFileRuleService.getFileNameRule(electricFieldInfo, "E6", endTime + 1000);
        if (getFileName(fileName, "E6")) {
          // 获取气象站信息
          List<WeatherStationInfo> weatherStationInfoList = weatherStationInfoRepository.findAll();
          // 将测风塔信息过滤出上报的塔
          List<WeatherStationInfo> weatherStationInfos = weatherStationInfoList.stream().filter(w -> w.getReport() == true).collect(Collectors.toList());
          if (!weatherStationInfos.isEmpty()) {
            Integer uploadWeatherStationId = weatherStationInfos.get(0).getId();
            // 获取测风塔遥测数据
            //            List<WeatherStationStatusData> weatherStationStatusDataList = weatherStationStatusDataRepository.findByTimeBetweenAndEquipmentNo(new Date(startTime), new Date(endTime), uploadWeatherStationId);
            WeatherStationStatusData weatherStationStatusData = super.getWeatherStationStatusData(uploadWeatherStationId);
            // 数据格式化
            DecimalFormat df = new DecimalFormat("0.00");
            BigDecimal globalR;
            BigDecimal directR;
            BigDecimal diffuseR;
            BigDecimal airT;
            BigDecimal p;
            BigDecimal rh;
            BigDecimal cellT;
            BigDecimal ws;
            BigDecimal wd;


            if (weatherStationStatusData == null) {
              // 总辐射产生500-1000随机数
              globalR = new BigDecimal(df.format(Math.random() * 500 + 500));
              // 直辐射产生400-500随机数
              directR = new BigDecimal(df.format(Math.random() * 100 + 400));
              // 散辐射 = 总 - 直
              diffuseR = globalR.subtract(directR);
              airT = new BigDecimal(df.format(Math.random() * 4 + 8));
              p = new BigDecimal(df.format(Math.random() * 200 + 800));
              rh = new BigDecimal(df.format(Math.random() * 10 + 30));
              cellT = new BigDecimal(df.format(Math.random() * 26 + 4));
              ws = new BigDecimal(df.format(Math.random() * 9 + 1));
              wd = new BigDecimal(df.format(Math.random() * 100 + 200));
            } else {
              globalR = weatherStationStatusData.getGlobalR();
              directR = weatherStationStatusData.getDirectR();
              diffuseR = weatherStationStatusData.getDiffuseR();
              airT = weatherStationStatusData.getAirT();
              p = weatherStationStatusData.getP();
              rh = weatherStationStatusData.getRh();
              cellT = weatherStationStatusData.getCellT();
              ws = weatherStationStatusData.getWs();
              wd = weatherStationStatusData.getWd();
            }
            // 创建上报文件
            file = super.createTempFile(fileName);
            // 根据模板生成文件内容
            velocityContext = new VelocityContext();
            velocityContext.put("globalR", globalR);
            velocityContext.put("directR", directR);
            velocityContext.put("diffuseR", diffuseR);
            velocityContext.put("airT", airT);
            velocityContext.put("p", p);
            velocityContext.put("rh", rh);
            velocityContext.put("cellT", cellT);
            velocityContext.put("ws", ws);
            velocityContext.put("wd", wd);
            velocityContext.put("sign", electricFieldInfo.getSign());
            // 系统当前日期
            velocityContext.put("currentTime", DateFormatUtils.format(endTime + 1000, "yyyy-MM-dd_HH:mm") + ":00");
            // 上报数据开始日期
            velocityContext.put("uploadTime", DateFormatUtils.format(endTime + 1000, "yyyy-MM-dd_HH:mm"));
            writer = new StringWriter();
            template.merge(velocityContext, writer);
            super.copyUploadFile(writer, file, FileTypeEnum.E6.name(), null, date);
          } else {
            log.info("没有上报的气象站,不能生成文件！");
          }
        }
      } catch (Exception e) {
        log.error("气象站文件生成失败", e);
      }
    } else {
      log.error("气象站上报模板不存在!");
    }
  }

  /**
   * 生成省调D5000测风塔上报文件
   */
  private void generateE7File(Date date) {
    // 获取测风塔模板
    Template template = this.velocityEngine.getTemplate(this.vmsPath + "/CFT_SD.vm");
    if (template != null) {
      VelocityContext velocityContext;
      StringWriter writer;
      String fileName;
      File file;
      ElectricField electricFieldInfo = null;
      try {
        electricFieldInfo = super.getElectricField();
      } catch (BusinessException e) {
        log.error("场站获取失败", e);
      }

      // 获取当前系统时间
      Date systemDate = new Date();
      if (date != null) {
        systemDate = date;
      }
      try {
        Long startTime;
        try {
          startTime = DateMomentUtil.getMomentTime(systemDate.getTime() - 5 * 60 * 1000, 1, 5 * 60 * 1000L);
        } catch (Exception e) {
          log.error("测风塔文件生成时刻步长错误", e);
          startTime = DateMomentUtil.getDayStartTime(systemDate.getTime());
        }
        Long endTime = startTime + 5 * 60 * 1000 - 1000;
        // 生成上报文件名格式
        fileName = e42UploadFileRuleService.getFileNameRule(electricFieldInfo, "E7", endTime + 1000);
        if (getFileName(fileName, "E7")) {
          // 获取测风塔信息
          List<WindTowerInfo> windTowerInfoList = windTowerInfoRepository.findAll();
          // 将测风塔信息过滤出上报的塔
          List<WindTowerInfo> filterWindTowerInfoList = windTowerInfoList.stream().filter(w -> w.getReport() == true).collect(Collectors.toList());
          if (!filterWindTowerInfoList.isEmpty()) {
            Integer uploadWindTowerId = filterWindTowerInfoList.get(0).getId();
            // 获取测风塔遥测数据
            //            List<WindTowerStatusData> windTowerStatusDataList = windTowerStatusDataRepository.findByEquipmentNoAndTimeBetween(uploadWindTowerId, new Date(startTime), new Date(endTime));
            WindTowerStatusData windTowerStatusData = super.getWindTowerStatusData(uploadWindTowerId);
            // 数据格式化
            DecimalFormat df = new DecimalFormat("0.00");
            BigDecimal ws10 = new BigDecimal(0);
            BigDecimal wd10 = new BigDecimal(0);
            BigDecimal ws30 = new BigDecimal(0);
            BigDecimal wd30 = new BigDecimal(0);
            BigDecimal ws50 = new BigDecimal(0);
            BigDecimal wd50 = new BigDecimal(0);
            BigDecimal ws70 = new BigDecimal(0);
            BigDecimal wd70 = new BigDecimal(0);
            BigDecimal wsHubHeight = new BigDecimal(0);
            BigDecimal wdHubHeight = new BigDecimal(0);
            BigDecimal t8 = new BigDecimal(0);
            BigDecimal p8 = new BigDecimal(0);
            BigDecimal rh8 = new BigDecimal(0);

            if (windTowerStatusData == null) {
              // 没有测风塔数据用nwp数据补
              Long nwpTime;
              try {
                nwpTime = DateMomentUtil.getMomentTime(systemDate.getTime(), 1, 15 * 60 * 1000L);
              } catch (Exception e) {
                log.error("获取nwp时刻步长错误", e);
                nwpTime = DateMomentUtil.getDayStartTime(systemDate.getTime());
              }
              List<Nwp> nwpList = nwpRepository.findByPreTimeBetween(nwpTime, nwpTime);

              if (nwpList.size() > 0) {
                Nwp nwpData = nwpList.get(0);
                ws10 = nwpData.getWs10();
                wd10 = nwpData.getWd10();
                ws30 = nwpData.getWs30();
                wd30 = nwpData.getWd30();
                ws50 = nwpData.getWs50();
                wd50 = nwpData.getWd50();
                ws70 = nwpData.getWs70();
                wd70 = nwpData.getWd70();
                wsHubHeight = nwpData.getWs70();
                wdHubHeight = nwpData.getWd70();
                rh8 = nwpData.getRh();
                t8 = nwpData.getT();
                p8 = nwpData.getPressure();
              }
              // 10米风速产生1-5随机数
              BigDecimal ws10RandomValue = new BigDecimal(df.format(Math.random() * 4 + 1));
              ws10 = ws10.add(ws10RandomValue).setScale(2, BigDecimal.ROUND_HALF_UP);
              // 10米风向产生40-60随机数
              BigDecimal wd10RandomValue = new BigDecimal(df.format(Math.random() * 20 + 40));
              wd10 = wd10.add(wd10RandomValue).setScale(2, BigDecimal.ROUND_HALF_UP);
              // 30米风速产生6-10随机数
              BigDecimal ws30RandomValue = new BigDecimal(df.format(Math.random() * 4 + 6));
              ws30 = ws30.add(ws30RandomValue).setScale(2, BigDecimal.ROUND_HALF_UP);
              // 30米风向产生70-90随机数
              BigDecimal wd30RandomValue = new BigDecimal(df.format(Math.random() * 20 + 70));
              wd30 = wd30.add(wd30RandomValue).setScale(2, BigDecimal.ROUND_HALF_UP);
              // 50米风速产生16-20随机数
              BigDecimal ws50RandomValue = new BigDecimal(df.format(Math.random() * 4 + 16));
              ws50 = ws50.add(ws50RandomValue).setScale(2, BigDecimal.ROUND_HALF_UP);
              // 50米风向产生130-150随机数
              BigDecimal wd50RandomValue = new BigDecimal(df.format(Math.random() * 20 + 130));
              wd50 = wd50.add(wd50RandomValue).setScale(2, BigDecimal.ROUND_HALF_UP);
              // 70米风速产生31-35随机数
              BigDecimal ws70RandomValue = new BigDecimal(df.format(Math.random() * 4 + 31));
              ws70 = ws70.add(ws70RandomValue).setScale(2, BigDecimal.ROUND_HALF_UP);
              // 70米风向产生220-240随机数
              BigDecimal wd70RandomValue = new BigDecimal(df.format(Math.random() * 20 + 220));
              wd70 = wd70.add(wd70RandomValue).setScale(2, BigDecimal.ROUND_HALF_UP);
              BigDecimal wsRandomValue = new BigDecimal(df.format(Math.random() * 4 + 70));
              wsHubHeight = wsHubHeight.add(wsRandomValue).setScale(2, BigDecimal.ROUND_HALF_UP);
              BigDecimal wdRandomValue = new BigDecimal(df.format(Math.random() * 20 + 250));
              wdHubHeight = wdHubHeight.add(wdRandomValue).setScale(2, BigDecimal.ROUND_HALF_UP);
              // 湿度产生50-60随机数
              BigDecimal rhRandomValue = new BigDecimal(df.format(Math.random() * 10 + 50));
              rh8 = rh8.add(rhRandomValue).setScale(2, BigDecimal.ROUND_HALF_UP);
              // 温度产生20-35随机数
              BigDecimal tRandomValue = new BigDecimal(df.format(Math.random() * 15 + 20));
              t8 = t8.add(rhRandomValue).setScale(2, BigDecimal.ROUND_HALF_UP);
              // 气压产生75-90随机数
              BigDecimal paRandomValue = new BigDecimal(df.format(Math.random() * 15 + 75));
              p8 = p8.add(paRandomValue).setScale(2, BigDecimal.ROUND_HALF_UP);
            } else {


              ws10 = windTowerStatusData.getWsInst10();
              wd10 = windTowerStatusData.getWdInst10();
              ws30 = windTowerStatusData.getWsInst30();
              wd30 = windTowerStatusData.getWdInst30();
              ws50 = windTowerStatusData.getWsInst50();
              wd50 = windTowerStatusData.getWdInst50();
              ws70 = windTowerStatusData.getWsInst70();
              wd70 = windTowerStatusData.getWdInst70();
              wsHubHeight = windTowerStatusData.getWsInstHubHeight();
              wdHubHeight = windTowerStatusData.getWdInstHubHeight();
              t8 = windTowerStatusData.getTInst();
              p8 = windTowerStatusData.getPaInst();
              rh8 = windTowerStatusData.getRhInst();


            }
            // 创建上报文件
            file = super.createTempFile(fileName);
            // 根据模板生成文件内容
            velocityContext = new VelocityContext();
            // 上报数据开始日期
            velocityContext.put("efiLabel", electricFieldInfo.getSign());
            // 上报数据开始日期
            velocityContext.put("currentTime", DateFormatUtils.format(endTime + 1000, "yyyy-MM-dd_HH:mm:ss"));
            velocityContext.put("uploadTime", DateFormatUtils.format(endTime + 1000, "yyyy-MM-dd_HH:mm"));
            velocityContext.put("WS_10", ws10);
            velocityContext.put("WD_10", wd10.divideAndRemainder(new BigDecimal(360))[1]);
            velocityContext.put("WS_30", ws30);
            velocityContext.put("WD_30", wd30.divideAndRemainder(new BigDecimal(360))[1]);
            velocityContext.put("WS_50", ws50);
            velocityContext.put("WD_50", wd50.divideAndRemainder(new BigDecimal(360))[1]);
            velocityContext.put("WS_70", ws70);
            velocityContext.put("WD_70", wd70.divideAndRemainder(new BigDecimal(360))[1]);
            velocityContext.put("WS_HubHeight", wsHubHeight);
            velocityContext.put("WD_HubHeight", wdHubHeight.divideAndRemainder(new BigDecimal(360))[1]);
            velocityContext.put("T_8", t8);
            velocityContext.put("P_8", p8);
            velocityContext.put("RH_8", rh8);

            writer = new StringWriter();
            template.merge(velocityContext, writer);
            super.copyUploadFile(writer, file, FileTypeEnum.E7.name(), null, date);
          } else {
            log.info("没有上报的测风塔,不能生成文件！");
          }
        }
      } catch (Exception e) {
        log.error("省调D5000测风塔文件生成失败", e);
      }
    } else {
      log.error("省调D5000测风塔上报模板不存在!");
    }
  }

  /**
   * 生成逆变器省调上报文件。
   * 文件名格式（ZJNCMS_20181204_1050_NBQ.PVD）
   */
  private void generateE8File(Date date) {
    // 获取基本信息模板
    Template template = this.velocityEngine.getTemplate(this.vmsPath + "/NBQ_SD.vm");
    if (template != null) {
      VelocityContext velocityContext;
      StringWriter writer;
      String fileName;
      File file;
      ElectricField electricFieldInfo = null;
      try {
        electricFieldInfo = super.getElectricField();
      } catch (BusinessException e) {
        log.error("场站获取失败", e);
      }
      // 获取当前系统时间
      Date systemDate = new Date();
      if (date != null) {
        systemDate = date;
      }
      try {
        Long startTime;
        try {
          startTime = DateMomentUtil.getMomentTime(systemDate.getTime() - 5 * 60 * 1000, 1, 5 * 60 * 1000L);
        } catch (ServiceException e) {
          log.error("逆变器文件生成时刻步长错误", e);
          startTime = DateMomentUtil.getDayStartTime(systemDate.getTime());
        }
        Long endTime = startTime + 5 * 60 * 1000 - 1000;
        // 生成上报文件名格式
        fileName = e42UploadFileRuleService.getFileNameRule(electricFieldInfo, "E8", endTime + 1000);
        if (getFileName(fileName, "E8")) {
          List<Map<String, String>> vList = new ArrayList<>();
          // 获取逆变器
          List<InverterInfo> inverterInfos = inverterInfoService.getAll();
          //          // 获取逆变器遥测数据
          //          List<InverterStatusData> inverterStatusDataList = inverterStatusDataRepository.findByTimeBetween(new Date(startTime), new Date(endTime));
          // 过滤上报的逆变器
          List<InverterInfo> filterInverterInfoList = inverterInfos.stream().filter(w -> w.getReport() == true).collect(Collectors.toList());
          if (filterInverterInfoList.size() > 0) {
            List<Map<String, String>> dtaInverterList = new ArrayList<>();
            for (InverterInfo inverterInfo : filterInverterInfoList) {
              Map<String, String> map = new HashMap<>();
              // 名称
              map.put("name", inverterInfo.getName());
              map.put("groupSeries", inverterInfo.getGroupSeries() ? "1" : "0");
              // 过滤出逆变器对应的数据
              //              List<InverterStatusData> filterInverterStatusData = inverterStatusDataList.stream().filter(w -> w.getEquipmentNo() == inverterInfo.getId()).collect(Collectors.toList());
              InverterStatusData inverterStatusData = super.getInverterStatusData(inverterInfo.getId());
              DecimalFormat df = new DecimalFormat("0.00");
              //因为现场未接入数据 默认状态为3 数据为0
              if (inverterStatusData != null) {
                //桑 反馈省调d5000和省调老系统的1和0状态相反
                /*if(inverterStatusData.getStatus().toString().equals("1")){
                  map.put("status", "0");
                }else if (inverterStatusData.getStatus().toString().equals("0")){
                  map.put("status", "1");
                }else {
                  map.put("status", inverterStatusData.getStatus().toString());
                }
*/
                /*韩雪融
                 单机信息：
                WPD文件：省调老系统-地调
                0是运行，1是故障，2是待机，3是检修
                PVD文件：
                1是运行，0是故障，2是待机，3是检修

                老系统WPD：
                有功>0  状态为运行：0
                有功<=0  状态为非运行：2
                新系统PVD：
                有功>0  状态为运行：1
                有功<=0  状态为非运行：2*/
                // 有功
                map.put("NbqActivePower", df.format(inverterStatusData.getActivePower().compareTo(new BigDecimal(-99)) == 0 ? 0 : inverterStatusData.getActivePower().divide(new BigDecimal(1000))));
                // 无功
                map.put("NbqReActivePower", df.format(inverterStatusData.getReactivePower().compareTo(new BigDecimal(-99)) == 0 ? 0 : inverterStatusData.getReactivePower().divide(new BigDecimal(1000))));
                // 电压
                map.put("Voltage", df.format(inverterStatusData.getVoltage().compareTo(new BigDecimal(-99)) == 0 ? 0 : inverterStatusData.getVoltage()));
                // 电流
                map.put("GalvanicCurrent", df.format(inverterStatusData.getElectricalCurrent().compareTo(new BigDecimal(-99)) == 0 ? 0 : inverterStatusData.getElectricalCurrent()));
                BigDecimal bd = new BigDecimal(map.get("NbqActivePower"));
                if (bd.compareTo(new BigDecimal(0)) == 1) {
                  //有功大于0 则运行状态为1
                  map.put("status", "1");
                } else {
                  //不大于0则为小于等于0 则运行状态为2
                  map.put("status", "2");
                }
              } else {
                map.put("status", "2");
                map.put("NbqActivePower", "0");
                map.put("NbqReActivePower", "0");
                map.put("Voltage", "0");
                map.put("GalvanicCurrent", "0");
              }
              dtaInverterList.add(map);
            }
            // 创建上报文件
            file = super.createTempFile(fileName);
            // 根据模板生成文件内容
            velocityContext = new VelocityContext();
            velocityContext.put("vList", dtaInverterList);
            // 场站标识
            velocityContext.put("netSubstationName", electricFieldInfo.getNetSubstationName());
            // 场站装机容量
            velocityContext.put("capacity", electricFieldInfo.getCapacity());
            velocityContext.put("sign", electricFieldInfo.getSign());
            // 系统当前日期
            velocityContext.put("currentTime", DateFormatUtils.format(endTime + 1000, "yyyy-MM-dd_HH:mm") + ":00");
            // 上报数据开始日期
            velocityContext.put("uploadTime", DateFormatUtils.format(endTime + 1000, "yyyy-MM-dd_HH:mm"));
            writer = new StringWriter();
            template.merge(velocityContext, writer);
            super.copyUploadFile(writer, file, FileTypeEnum.E8.name(), null, date);
          } else {
            log.info("没有上报的逆变器,不能生成文件！");
          }
        }
      } catch (Exception e) {
        log.error("逆变器文件生成失败", e);
      }
    } else {
      log.error("逆变器上报模板不存在!");
    }
  }

  /**
   * 生成风机基本信息上报文件。
   */
  private void generateE9File(Date date) {
    // 获取基本信息模板
    Template template = this.velocityEngine.getTemplate(this.vmsPath + "/FJ_BASE.vm");
    if (template != null) {
      VelocityContext velocityContext;
      StringWriter writer;
      String fileName;
      File file;
      ElectricField electricFieldInfo = null;
      try {
        electricFieldInfo = super.getElectricField();
      } catch (BusinessException e) {
        log.error("场站获取失败", e);
      }
      // 获取当前系统时间
      Date systemDate = new Date();
      if (date != null) {
        systemDate = date;
      }
      try {
        Long startTime;
        try {
          startTime = DateMomentUtil.getMomentTime(systemDate.getTime() - 5 * 60 * 1000, 1, 5 * 60 * 1000L);
        } catch (ServiceException e) {
          log.error("风机基础信息文件生成时刻步长错误", e);
          startTime = DateMomentUtil.getDayStartTime(systemDate.getTime());
        }
        Long endTime = startTime + 5 * 60 * 1000 - 1000;
        // 生成上报文件名格式
        fileName = e42UploadFileRuleService.getFileNameRule(electricFieldInfo, "E9", endTime + 1000);
        if (getFileName(fileName, "E9")) {
          List<Map<String, String>> vList = new ArrayList<>();
          // 获取风机
          List<WindTurbineInfo> windTurbineInfoList = windTurbineInfoRepository.findAllByOrderByIdAsc();
          // 过滤上报的风机
          List<WindTurbineInfo> filterWindInfoList = windTurbineInfoList.stream().filter(w -> w.getReport() == true).collect(Collectors.toList());
          filterWindInfoList.sort(Comparator.comparing(WindTurbineInfo::getId));
          DecimalFormat df = new DecimalFormat("0.00");
          Double cap = 0.00;
          int index = 0;
          String name = "";
          for (WindTurbineInfo windTurbineInfo : filterWindInfoList) {
            index = index + 1;
            if (index < 10) {
              name = "0" + String.valueOf(index);
            } else {
              name = String.valueOf(index);
            }
            Map<String, String> map = new HashMap<>();
            // 名称
            map.put("name", name);
            // 额定功率
            map.put("maxPower", df.format(windTurbineInfo.getMaxPower() / 1000));
            // 型号
            map.put("modelNumber", windTurbineInfo.getModelNumber());
            // 经度
            map.put("longitude", windTurbineInfo.getLongitude() == null ? "无" : DDtoDMS(windTurbineInfo.getLongitude()));
            // 纬度
            map.put("latitude", windTurbineInfo.getLatitude() == null ? "无" : DDtoDMS(windTurbineInfo.getLatitude()));
            // 是否样板机
            map.put("sample", windTurbineInfo.getSample() ? "1" : "0");
            vList.add(map);
            cap = cap + windTurbineInfo.getMaxPower() / 1000;
          }

          // 创建上报文件
          file = super.createTempFile(fileName);
          // 根据模板生成文件内容
          velocityContext = new VelocityContext();
          velocityContext.put("vList", vList);
          // 场站标识
          velocityContext.put("sign", electricFieldInfo.getSign());
          velocityContext.put("capacity", df.format(cap));
          // 上报数据开始日期
          velocityContext.put("currentTime", DateFormatUtils.format(endTime + 1000, "yyyy-MM-dd_HH:mm:ss"));
          velocityContext.put("uploadTime", DateFormatUtils.format(endTime + 1000, "yyyy-MM-dd_HH:mm"));
          writer = new StringWriter();
          template.merge(velocityContext, writer);
          super.copyUploadFile(writer, file, FileTypeEnum.E9.name(), null, date);
        }
      } catch (Exception e) {
        log.error("省调D5000风机基础信息文件生成失败", e);
      }
    } else {
      log.error("省调D5000风机基础信息上报模板不存在!");
    }
  }


  /**
   * 经纬度转换
   *
   * @param d
   * @return
   */
  private String DDtoDMS(Double d) {

    String[] array = String.valueOf(d).split("[.]");
    String degrees = array[0];//得到度

    Double m = Double.parseDouble("0." + array[1]) * 60;
    String[] array1 = m.toString().split("[.]");
    String minutes = array1[0];//得到分

    Double s = Double.parseDouble("0." + array1[1]) * 60;
    String[] array2 = s.toString().split("[.]");
    String seconds = array2[0];//得到秒
    return degrees + "°" + minutes + "′" + seconds + "″";
  }
}
