package com.jiayue.ipfcst.dataexchange.service;

import com.jiayue.ipfcst.common.data.entity.Nwp;
import com.jiayue.ipfcst.common.data.entity.WeatherStationStatusData;
import com.jiayue.ipfcst.common.data.entity.WindTowerStatusData;
import com.jiayue.ipfcst.common.data.repository.NwpRepository;
import com.jiayue.ipfcst.console.service.SysParameterService;
import com.jiayue.ipfcst.dataexchange.service.equipmentstatusdata.WeatherStationStatusDataService;
import com.jiayue.ipfcst.dataexchange.service.equipmentstatusdata.WindTowerStatusDataService;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * 环境数据生成器
 * 用于生成环境数据 包括测风塔和气象站
 * 要求再生成假数据后  假数据能与前一点相互关联呼应，保持曲线平滑过渡。
 *
 * @author xiuwei
 * @date 2021/09/15
 */
@Slf4j
public class EnvironmentDataGenerator {


  final protected WindTowerStatusDataService windTowerStatusDataService;

  final protected WeatherStationStatusDataService weatherStationStatusDataService;

  final protected NwpRepository nwpRepository;

  final protected SysParameterService sysParameterService;


  /**
   * 风塔数据生成器
   */
  private Map<Integer, WindTowerDataGenerator> windTowerDataGenerators = new HashMap<>();


  /**
   * 气象站数据生成器
   */
  private Map<Integer, WeatherStationDataGenerator> weatherStationDataGenerators = new HashMap<>();


  /**
   * 随机数
   */
  final protected Random random = new Random();

  /**
   * 每15分钟一个时间段， 该数据是 下一节点的数据      如现在是13   处于0-15时间段点， 那么该值则为30的数据
   */
  private Nwp nextTimeNwp;

  public EnvironmentDataGenerator(WindTowerStatusDataService windTowerStatusDataService, WeatherStationStatusDataService weatherStationStatusDataService, NwpRepository nwpRepository, SysParameterService sysParameterService) {
    this.windTowerStatusDataService = windTowerStatusDataService;
    this.weatherStationStatusDataService = weatherStationStatusDataService;
    this.nwpRepository = nwpRepository;
    this.sysParameterService = sysParameterService;
  }


  /**
   * 风塔数据生成器
   *
   * @param windTowerId 风塔id
   * @return {@link WindTowerDataGenerator}
   */
  public WindTowerDataGenerator getWindTowerDataGenerator(Integer windTowerId) {
    if (!this.windTowerDataGenerators.containsKey(windTowerId)) {
      this.windTowerDataGenerators.put(windTowerId, new WindTowerDataGenerator(windTowerId));
    }
    return this.windTowerDataGenerators.get(windTowerId);
  }

  /**
   * 气象站数据生成器
   *
   * @param weatherStationId 气象站id
   * @return {@link WeatherStationDataGenerator}
   */
  public WeatherStationDataGenerator getWeatherStationDataGenerator(Integer weatherStationId) {
    if (!this.weatherStationDataGenerators.containsKey(weatherStationId)) {
      this.weatherStationDataGenerators.put(weatherStationId, new WeatherStationDataGenerator(weatherStationId));
    }
    return this.weatherStationDataGenerators.get(weatherStationId);
  }


  /**
   * 获取下一时刻的预测环境数据
   *
   * @return {@link Nwp}
   */
  private Nwp getNextTimeNwp() {
    Long startTime = DateTime.now().getMillis();
    if (this.nextTimeNwp != null) {
      if (this.nextTimeNwp.getPreTime() - startTime > 0)
        return this.nextTimeNwp;
    }
    Long endTime = startTime + 15 * 60 * 1000;
    List<Nwp> nwps = nwpRepository.findByPreTimeBetween(startTime, endTime);
    if (nwps.size() > 0) {
      this.nextTimeNwp = nwps.get(0);
    }
    if (this.nextTimeNwp == null) {
      log.error("数据库中没有该时刻的气象数据");
      throw new RuntimeException("数据库中没有该时刻的气象数据");
    }
    return nextTimeNwp;
  }


  /**
   * 测风塔数据生成器
   *
   * @author xiuwei
   * @date 2021/09/15
   */
  public class WindTowerDataGenerator {

    public WindTowerDataGenerator(Integer windTowerId) {
      this.windTowerId = windTowerId;
    }

    protected Integer windTowerId;
    /**
     * 风切变指数
     */
    protected BigDecimal windShearIndex;


    //上一次所使用的测风塔数据
    protected WindTowerStatusData pWindTowerData = null;

    //下一 刻预测的测风塔数据
    protected WindTowerStatusData fWindTowerData = null;


    /**
     * 得到上一次风塔数据
     * 会自动更新数据
     *
     * @return {@link WindTowerStatusData}
     */
    private WindTowerStatusData getPreWindTowerData() {
      //如果pWindTowerData 为空 或者时间 距离现在超过一分钟  就需要从数据库取出
      if (this.pWindTowerData != null) {
        if (this.pWindTowerData.getTime().after(DateTime.now().minusMinutes(2).toDate())) {
          return this.pWindTowerData;
        }
      }
      List<WindTowerStatusData> l = windTowerStatusDataService.findByEquipmentNoAndTimeBetween(this.windTowerId, DateTime.now().minusMinutes(2).toDate(), DateTime.now().toDate());
      if (l.size() == 0) {
        //没有
        this.pWindTowerData = null;
      } else {
        this.pWindTowerData = l.get(0);
      }
      return this.pWindTowerData;
    }


    /**
     * 计算风切变指数
     * 计算风切变 对20层的风切变有个初步的计算，使其能够粗略平衡每层风速间的关系
     *
     * @return {@link BigDecimal}
     */
    protected BigDecimal getWindShearIndex() {
      if (this.windShearIndex == null) {
        try {
          Nwp nwp = getNextTimeNwp();
          if(nwp.getWd10().compareTo(BigDecimal.ZERO)!=0){
            this.windShearIndex = flushWindShearIndex(nwp);
          }
        } catch (Exception e) {
          this.windShearIndex = BigDecimal.valueOf(0.2);
        }
      }
      return this.windShearIndex;
    }

    protected BigDecimal flushWindShearIndex(Nwp nwp) {
      if(nwp.getWd10().compareTo(BigDecimal.ZERO)==0){
        return BigDecimal.valueOf(0.2);
      }
      double d1 = Math.log10(nwp.getWs30().divide(nwp.getWs10(), 2, BigDecimal.ROUND_HALF_UP).doubleValue());
      double d2 = Math.log10(30 / 10);
      BigDecimal w = BigDecimal.valueOf(d1).divide(BigDecimal.valueOf(d2), 2, BigDecimal.ROUND_HALF_UP);
      d1 = Math.log10(nwp.getWs50().divide(nwp.getWs10(), 2, BigDecimal.ROUND_HALF_UP).doubleValue());
      d2 = Math.log10(50 / 10);
      w = (BigDecimal.valueOf(d1).divide(BigDecimal.valueOf(d2), 2, BigDecimal.ROUND_HALF_UP).add(w)).divide(BigDecimal.valueOf(2));
      d1 = Math.log10(nwp.getWs70().divide(nwp.getWs10(), 2, BigDecimal.ROUND_HALF_UP).doubleValue());
      d2 = Math.log10(70 / 10);
      w = (BigDecimal.valueOf(d1).divide(BigDecimal.valueOf(d2), 2, BigDecimal.ROUND_HALF_UP).add(w)).divide(BigDecimal.valueOf(2));
      d1 = Math.log10(nwp.getWs90().divide(nwp.getWs10(), 2, BigDecimal.ROUND_HALF_UP).doubleValue());
      d2 = Math.log10(90 / 10);
      w = (BigDecimal.valueOf(d1).divide(BigDecimal.valueOf(d2), 2, BigDecimal.ROUND_HALF_UP).add(w)).divide(BigDecimal.valueOf(2));
      d1 = Math.log10(nwp.getWs100().divide(nwp.getWs10(), 2, BigDecimal.ROUND_HALF_UP).doubleValue());
      d2 = Math.log10(100 / 10);
      w = (BigDecimal.valueOf(d1).divide(BigDecimal.valueOf(d2), 2, BigDecimal.ROUND_HALF_UP).add(w)).divide(BigDecimal.valueOf(2));
      return w;
    }


    /**
     * 获取趋势点 未来某点最近的预测点的风速值 并根据一个点的预测风速生成各层的预测风速 共20层
     *
     * @return {@link WindTowerStatusData}
     */
    private WindTowerStatusData getForecastWindData() {
      if (this.fWindTowerData == null || this.fWindTowerData.getTime() == null || this.fWindTowerData.getTime().before(DateTime.now().plusMinutes(15).toDate())) {
        this.fWindTowerData = new WindTowerStatusData();
        Nwp nwp = getNextTimeNwp();
        if (nwp != null) {
          flushWindShearIndex(nwp);
        }
        this.fWindTowerData = nwpToWindTowerStatusData(nwp);
      }
      return this.fWindTowerData;
    }

    /**
     * 将天气预报
     *
     * @param nwp 数值天气预报
     * @return {@link WindTowerStatusData}
     */
    protected WindTowerStatusData nwpToWindTowerStatusData(Nwp nwp) {
      WindTowerStatusData windTowerStatusData = new WindTowerStatusData();
      if (nwp == null) {
        return windTowerStatusData;
      }
      windTowerStatusData.setTime(new Date(nwp.getPreTime()));
      windTowerStatusData.setWsInst10(nwp.getWs10());
      windTowerStatusData.setWsInst30(nwp.getWs30());
      windTowerStatusData.setWsInst50(nwp.getWs50());
      BigDecimal fakeWs;
      fakeWs = windTowerStatusData.getWsInst10().multiply(BigDecimal.valueOf(Math.pow(6, getWindShearIndex().doubleValue())));
      windTowerStatusData.setWsInst60(fakeWs);
      windTowerStatusData.setWsInst70(nwp.getWs70());
      windTowerStatusData.setWsInst80(nwp.getWs80());
      windTowerStatusData.setWsInst90(nwp.getWs90());
      windTowerStatusData.setWsInst100(nwp.getWs100());
      fakeWs = windTowerStatusData.getWsInst10().multiply(BigDecimal.valueOf(Math.pow(11, getWindShearIndex().doubleValue())));
      windTowerStatusData.setWsInst110(fakeWs);
      fakeWs = windTowerStatusData.getWsInst10().multiply(BigDecimal.valueOf(Math.pow(12, getWindShearIndex().doubleValue())));
      windTowerStatusData.setWsInst120(fakeWs);

      windTowerStatusData.setWdInst10(nwp.getWd10());
      windTowerStatusData.setWdInst30(nwp.getWd30());
      windTowerStatusData.setWdInst50(nwp.getWd50());
      windTowerStatusData.setWdInst60(getNextValOfWd(nwp.getWd50()));
      windTowerStatusData.setWdInst70(nwp.getWd70());
      windTowerStatusData.setWdInst80(nwp.getWd80());
      windTowerStatusData.setWdInst90(nwp.getWd90());
      windTowerStatusData.setWdInst100(nwp.getWd100());
      windTowerStatusData.setWdInst110(getNextValOfWd(nwp.getWd100()));
      windTowerStatusData.setWdInst120(getNextValOfWd(nwp.getWd100()));
      windTowerStatusData.setTInst(nwp.getT());
      windTowerStatusData.setRhInst(nwp.getRh());
      windTowerStatusData.setPaInst(nwp.getPressure());
      return windTowerStatusData;
    }


    /**
     * 通过趋势点的时间以及风速 推算出现在的数据
     *
     * @return {@link WindTowerStatusData}
     */
    public WindTowerStatusData generateWindTowerData() {
      //生成所用的测风塔数据用于 后期填补数据
      WindTowerStatusData gWindTowerData = new WindTowerStatusData();
      gWindTowerData.setEquipmentNo(windTowerId);
      try {
        //预测的下一刻的测风塔数据
        WindTowerStatusData fWindTowerData = getForecastWindData();
        //上一时刻所使用的测风塔数据
        WindTowerStatusData pWindTowerData = getPreWindTowerData();
        //上一时刻数据
        if (pWindTowerData == null) {
          this.pWindTowerData = fWindTowerData;
          pWindTowerData = getPreWindTowerData();
        } else {
          if (this.pWindTowerData.getTime().after(DateTime.now().minusMinutes(1).toDate())) {
            return pWindTowerData;
          }
        }
        //1.判断时间差值  分钟差
        int min = (int) (fWindTowerData.getTime().getTime() - DateTime.now().getMillis()) / (60 * 1000);
        if (min == 0) {
          min = 15;
        }
        generateWindTowerDataByPreAndForecast(gWindTowerData, pWindTowerData, fWindTowerData, min);
        gWindTowerData.setTime(DateTime.now().withMillisOfSecond(0).withSecondOfMinute(0).toDate());
        this.pWindTowerData = gWindTowerData;
      } catch (Exception e) {
        log.warn("测风塔{}生成假数据时发生异常,返回前一时刻数据。", windTowerId, e);
       if(this.pWindTowerData!=null) {
         this.pWindTowerData.setTime(DateTime.now().withMillisOfSecond(0).withSecondOfMinute(0).toDate());
         return this.pWindTowerData;
       }else{
         log.warn("测风塔{}生成假数据时发生异常,没有预测数据，返回空数据。", windTowerId, e);
         return gWindTowerData;
       }
      }
      return gWindTowerData;
    }
  }

  protected WindTowerStatusData generateWindTowerDataByPreAndForecast(WindTowerStatusData generate, WindTowerStatusData pre, WindTowerStatusData forecast, int spaceByMin) {
    //设置风速  假
    generate.setWsInst10(getNextValOfWs(pre.getWsInst10(), forecast.getWsInst10(), spaceByMin));
    generate.setWsAve10(generate.getWsInst10());
    generate.setWsInst30(getNextValOfWs(pre.getWsInst30(), forecast.getWsInst30(), spaceByMin));
    generate.setWsAve30(generate.getWsInst30());
    generate.setWsInst50(getNextValOfWs(pre.getWsInst50(), forecast.getWsInst50(), spaceByMin));
    generate.setWsAve50(generate.getWsInst50());
    generate.setWsInst60(getNextValOfWs(pre.getWsInst60(), forecast.getWsInst60(), spaceByMin));
    generate.setWsAve60(generate.getWsInst60());
    generate.setWsInst70(getNextValOfWs(pre.getWsInst70(), forecast.getWsInst70(), spaceByMin));
    generate.setWsAve70(generate.getWsInst70());
    generate.setWsInst80(getNextValOfWs(pre.getWsInst80(), forecast.getWsInst80(), spaceByMin));
    generate.setWsAve80(generate.getWsInst80());
    generate.setWsInst90(getNextValOfWs(pre.getWsInst90(), forecast.getWsInst90(), spaceByMin));
    generate.setWsAve90(generate.getWsInst90());
    generate.setWsInst100(getNextValOfWs(pre.getWsInst100(), forecast.getWsInst100(), spaceByMin));
    generate.setWsAve100(generate.getWsInst100());
    generate.setWsInst110(getNextValOfWs(pre.getWsInst110(), forecast.getWsInst110(), spaceByMin));
    generate.setWsAve110(generate.getWsInst110());
    generate.setWsInst120(getNextValOfWs(pre.getWsInst120(), forecast.getWsInst120(), spaceByMin));
    generate.setWsAve120(generate.getWsInst120());

    generate.setWdInst10(getNextValOfWd(pre.getWdInst10()));
    generate.setWdAve10(generate.getWdInst10());
    generate.setWdInst30(getNextValOfWd(pre.getWdInst30()));
    generate.setWdAve30(generate.getWdInst30());
    generate.setWdInst50(getNextValOfWd(pre.getWdInst50()));
    generate.setWdAve50(generate.getWdInst50());
    generate.setWdInst60(getNextValOfWd(pre.getWdInst60()));
    generate.setWdAve60(generate.getWdInst60());
    generate.setWdInst70(getNextValOfWd(pre.getWdInst70()));
    generate.setWdAve70(generate.getWdInst70());
    generate.setWdInst80(getNextValOfWd(pre.getWdInst80()));
    generate.setWdAve80(generate.getWdInst80());
    generate.setWdInst90(getNextValOfWd(pre.getWdInst90()));
    generate.setWdAve90(generate.getWdInst90());
    generate.setWdInst100(getNextValOfWd(pre.getWdInst100()));
    generate.setWdAve100(generate.getWdInst100());
    generate.setWdInst110(getNextValOfWd(pre.getWdInst110()));
    generate.setWdAve110(generate.getWdInst110());
    generate.setWdInst120(getNextValOfWd(pre.getWdInst120()));
    generate.setWdAve120(generate.getWdInst120());

    generate.setTInst(getNextValOfWsq(pre.getTInst(), forecast.getTInst(), spaceByMin));
    generate.setTAve(generate.getTInst());
    generate.setRhInst(getNextValOfWsq(pre.getRhInst(), forecast.getRhInst(), spaceByMin));
    generate.setRhAve(generate.getRhInst());
    generate.setPaInst(getNextValOfWsq(pre.getPaInst(), forecast.getPaInst(), spaceByMin));
    generate.setPaAve(generate.getPaInst());
    try {
      int h = Integer.parseInt(sysParameterService.getSysParameter("hubHeight", "70"));
      generate.setHubData(h);
    } catch (Exception e) {
      log.error("设置测风塔假数据轮毂风速时发生异常", e);
    }
    BigDecimal den = BigDecimal.valueOf(1.293).multiply(BigDecimal.valueOf(273).divide(BigDecimal.valueOf(273).add(generate.getTInst()), 2).multiply((generate.getPaInst().compareTo(BigDecimal.valueOf(500)) > 0 ? generate.getPaInst() : generate.getPaInst().multiply(BigDecimal.TEN)).divide(BigDecimal.valueOf(1013), 2))).setScale(2, RoundingMode.HALF_UP);
    generate.setAirDensity(den);
    generate.setIsGenerated(true);
    return generate;
  }


  /**
   * 气象站数据生成器
   *
   * @author xiuwei
   * @date 2021/10/19
   */
  public class WeatherStationDataGenerator {

    public WeatherStationDataGenerator(Integer weatherStationId) {
      this.weatherStationId = weatherStationId;
    }

    /**
     * 气象站id
     */
    protected Integer weatherStationId;


    //上一次所使用的气象站数据
    protected WeatherStationStatusData pWeatherStationStatusData = null;

    //下一 刻预测的气象站数据
    protected WeatherStationStatusData fWeatherStationStatusData = null;

    /**
     * 得到上一次气象站数据
     * 会自动更新数据
     *
     * @return {@link WindTowerStatusData}
     */
    public WeatherStationStatusData getPreWeatherStationStatusData() {
      //如果pre 为空 或者时间 距离现在超过一分钟  就需要从数据库取出
      if (this.pWeatherStationStatusData != null) {
        if (this.pWeatherStationStatusData.getTime().after(DateTime.now().minusMinutes(1).toDate())) {
          return this.pWeatherStationStatusData;
        }
      }
      List<WeatherStationStatusData> l = weatherStationStatusDataService.findByEquipmentNoAndTimeBetween(this.weatherStationId, DateTime.now().minusMinutes(1).toDate(), DateTime.now().toDate());
      if (l.size() == 0) {
        //没有
        this.pWeatherStationStatusData = null;
      } else {
        this.pWeatherStationStatusData = l.get(0);
      }
      return this.pWeatherStationStatusData;
    }

    /**
     * 获取趋势点 未来某点最近的预测点的风速值 并根据一个点的预测风速生成各层的预测风速 共20层
     *
     * @return {@link WindTowerStatusData}
     */
    public WeatherStationStatusData getForecastWeatherStationStatusData() {
      if (this.fWeatherStationStatusData == null || this.fWeatherStationStatusData.getTime().before(DateTime.now().plusMillis(15).toDate())) {
        this.fWeatherStationStatusData = new WeatherStationStatusData();
        Nwp nwp = getNextTimeNwp();
        this.fWeatherStationStatusData.setTime(new Date(nwp.getPreTime()));
        //风速
        this.fWeatherStationStatusData.setWs(nwp.getWs10());
        //风向
        this.fWeatherStationStatusData.setWd(nwp.getWd10());
        //总辐射
        this.fWeatherStationStatusData.setGlobalR(nwp.getSwr());
        //散射辐射
        this.fWeatherStationStatusData.setDiffuseR(nwp.getDiffuseRadiation());
        //直辐射
        this.fWeatherStationStatusData.setDirectR(nwp.getDirectRadiation());
        //温度
        this.fWeatherStationStatusData.setAirT(nwp.getT());
        //湿度
        this.fWeatherStationStatusData.setRh(nwp.getRh());
        //气压
        this.fWeatherStationStatusData.setP(nwp.getPressure());
      }
      return this.fWeatherStationStatusData;
    }


    public WeatherStationStatusData generateWeatherStationData() {
      //预测的下一刻的气象站数据
      WeatherStationStatusData fWeatherStationStatusData = getForecastWeatherStationStatusData();
      //生成所用的气象站数据用于 后期填补数据
      WeatherStationStatusData gWeatherStationStatusData = new WeatherStationStatusData();
      gWeatherStationStatusData.setEquipmentNo(this.weatherStationId);
      //上一时刻所使用的气象站数据
      WeatherStationStatusData pWeatherStationStatusData = getPreWeatherStationStatusData();
      //TODO  上一时刻数据
      if (pWeatherStationStatusData == null) {
        this.pWeatherStationStatusData = fWeatherStationStatusData;
        pWeatherStationStatusData = getPreWeatherStationStatusData();
      } else {
        if (this.pWeatherStationStatusData.getTime().after(DateTime.now().minusMinutes(1).toDate())) {
          return pWeatherStationStatusData;
        }
      }
      //1.判断时间差值  分钟差
      int min = (int) (fWeatherStationStatusData.getTime().getTime() - DateTime.now().getMillis()) / (60 * 1000);
      if (min == 0) {
        min = 15;
      }
      gWeatherStationStatusData.setGlobalR(getNextValOfWsq(pWeatherStationStatusData.getGlobalR(), fWeatherStationStatusData.getGlobalR(), min));
      gWeatherStationStatusData.setDirectR(getNextValOfWsq(pWeatherStationStatusData.getDirectR(), fWeatherStationStatusData.getDirectR(), min));
      gWeatherStationStatusData.setDiffuseR(getNextValOfWsq(pWeatherStationStatusData.getDiffuseR(), fWeatherStationStatusData.getDiffuseR(), min));
      gWeatherStationStatusData.setAirT(getNextValOfWsq(pWeatherStationStatusData.getAirT(), fWeatherStationStatusData.getAirT(), min));
      gWeatherStationStatusData.setP(getNextValOfWsq(pWeatherStationStatusData.getP(), fWeatherStationStatusData.getP(), min));
      gWeatherStationStatusData.setRh(getNextValOfWsq(pWeatherStationStatusData.getRh(), fWeatherStationStatusData.getRh(), min));
      gWeatherStationStatusData.setWs(getNextValOfWs(pWeatherStationStatusData.getWs(), fWeatherStationStatusData.getWs(), min));
      gWeatherStationStatusData.setWd(getNextValOfWd(fWeatherStationStatusData.getWd()));
      //日照时长累积
      if (pWeatherStationStatusData.getHourDA() == null || pWeatherStationStatusData.getHourDA().compareTo(BigDecimal.valueOf(-99)) == 0) {
        pWeatherStationStatusData.setHourDA(BigDecimal.ZERO);
      }
      gWeatherStationStatusData.setHourDA(gWeatherStationStatusData.getGlobalR().compareTo(BigDecimal.ZERO) > 0 ? pWeatherStationStatusData.getHourDA().add(BigDecimal.valueOf(0.017)) : pWeatherStationStatusData.getHourDA());
      //总累
      if (pWeatherStationStatusData.getGlobalRDA() == null || pWeatherStationStatusData.getGlobalRDA().compareTo(BigDecimal.valueOf(-99)) == 0) {
        pWeatherStationStatusData.setGlobalRDA(BigDecimal.ZERO);
      }
      gWeatherStationStatusData.setGlobalRDA(pWeatherStationStatusData.getGlobalR().add(BigDecimal.valueOf(0.017).multiply(gWeatherStationStatusData.getGlobalR())));

      //散累
      if (pWeatherStationStatusData.getDiffuseRDA() == null || pWeatherStationStatusData.getDiffuseRDA().compareTo(BigDecimal.valueOf(-99)) == 0) {
        pWeatherStationStatusData.setDiffuseRDA(BigDecimal.ZERO);
      }
      gWeatherStationStatusData.setDiffuseRDA(pWeatherStationStatusData.getDiffuseRDA().add(BigDecimal.valueOf(0.017).multiply(gWeatherStationStatusData.getDiffuseR())));

      //直累
      if (pWeatherStationStatusData.getDirectRDA() == null || pWeatherStationStatusData.getDirectRDA().compareTo(BigDecimal.valueOf(-99)) == 0) {
        pWeatherStationStatusData.setDirectRDA(BigDecimal.ZERO);
      }
      gWeatherStationStatusData.setDirectRDA(pWeatherStationStatusData.getDirectRDA().add(BigDecimal.valueOf(0.017).multiply(gWeatherStationStatusData.getDirectR())));

      gWeatherStationStatusData.setTime(DateTime.now().withMillisOfSecond(0).withSecondOfMinute(0).toDate());
      gWeatherStationStatusData.setIsGenerated(true);

      return gWeatherStationStatusData;
    }

  }


  /**
   * 获取随机的增长斜率  用于获取风速斜率
   *
   * @param pv  上一值
   * @param fv  预测值
   * @param min 分钟数
   * @return {@link BigDecimal}
   */
  public BigDecimal getNextValOfWs(BigDecimal pv, BigDecimal fv, int min) {
    if (min == 0) {
      //如果时间差为0  直接返回预测风速
      return fv.setScale(2, RoundingMode.HALF_UP);
    }
    if (fv.compareTo(BigDecimal.valueOf(-99)) == 0) {
      return BigDecimal.ZERO;
    }
    if (pv.compareTo(BigDecimal.valueOf(-99)) == 0) {
      return fv.setScale(2, RoundingMode.HALF_UP);
    }
    //1.计算风速差
    BigDecimal fs = fv.subtract(pv);
    if (fs.compareTo(BigDecimal.ZERO) == 0) {
      //如果风速差为0  直接返回预测风速
      return fv.multiply(BigDecimal.valueOf(0.95)).setScale(2, RoundingMode.HALF_UP);
    }
    //计算基础斜率
    BigDecimal jx;
    if (pv.compareTo(BigDecimal.ZERO) == 0) {
      //如果上一个值为0 斜率便是风速差除以时间差
      jx = fs.divide(BigDecimal.valueOf(min), 4, RoundingMode.HALF_UP);
    } else {
      //增斜率为 差值除以上一值 即提升比例   提升比例处理时间 便是 提升比例斜率
      jx = fs.divide(pv, 4, RoundingMode.HALF_UP).divide(BigDecimal.valueOf(min), 4, RoundingMode.HALF_UP);
    }
    //基础斜率（增） 减去 上下波动随机数 +0.02~-0.02 即正负1%波动
    jx = jx.subtract(BigDecimal.valueOf(0.5).subtract(getRandomVal()).multiply(BigDecimal.valueOf(0.04))).setScale(2, RoundingMode.HALF_UP);
    // 上一值乘增斜率
    return pv.multiply(BigDecimal.ONE.add(jx)).setScale(2, RoundingMode.HALF_UP);
  }


  /**
   * 温度 湿度 气压 等数据变化不大的数据 选择平滑曲线过渡
   *
   * @param pv  上一值
   * @param fv  预测值
   * @param min 分钟数
   * @return {@link BigDecimal}
   */
  public BigDecimal getNextValOfWsq(BigDecimal pv, BigDecimal fv, int min) {
    if (min == 0) {
      //如果时间差为0  直接返回预测值
      return fv.setScale(2, RoundingMode.HALF_UP);
    }
    if (fv.compareTo(BigDecimal.valueOf(-99)) == 0) {
      return BigDecimal.ZERO;
    }
    if (pv.compareTo(BigDecimal.valueOf(-99)) == 0) {
      return fv;
    }

    //1.计算数据差
    BigDecimal fs = fv.subtract(pv);
    if (fs.compareTo(BigDecimal.ZERO) == 0) {
      //如果差为0  以 -1~1 随机数  为变化数据差
      fs = BigDecimal.valueOf(0.5).subtract(getRandomVal()).multiply(BigDecimal.valueOf(2));
    }
    //计算基础斜率
    BigDecimal jx = fs.divide(pv, 2, RoundingMode.HALF_UP).divide(BigDecimal.valueOf(min), 2, RoundingMode.HALF_UP);
    return pv.multiply(BigDecimal.ONE.add(jx)).setScale(2, RoundingMode.HALF_UP);
  }


  /**
   * 风向   风向要求值不高
   *
   * @param fv 预测风向
   * @return {@link BigDecimal}
   */
  public BigDecimal getNextValOfWd(BigDecimal fv) {
    //预测数据 ±随机数（0-10）
    fv = fv.add(BigDecimal.valueOf(0.5).subtract(getRandomVal()).multiply(BigDecimal.valueOf(20))).setScale(2, RoundingMode.HALF_UP);
    if (fv.compareTo(BigDecimal.valueOf(360)) > 0) {
      fv = fv.subtract(BigDecimal.valueOf(360));
    }
    if (fv.compareTo(BigDecimal.ZERO) < 0) {
      fv = BigDecimal.valueOf(360).add(fv);
    }
    return fv;
  }


  /**
   * 得到浮点随机数 0-1
   *
   * @return {@link BigDecimal}
   */
  private synchronized BigDecimal getRandomVal() {
    return BigDecimal.valueOf(random.nextDouble());
  }

}
