|
|
@@ -10,6 +10,7 @@ import cn.hutool.core.util.NumberUtil;
|
|
|
import cn.hutool.core.util.RandomUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import com.alibaba.fastjson2.JSON;
|
|
|
+import com.alibaba.fastjson2.TypeReference;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.baomidou.mybatisplus.extension.service.IService;
|
|
|
import com.ruoyi.quartz.handler.IJobHandler;
|
|
|
@@ -107,6 +108,11 @@ public class JavaFunctionJobHandler extends IJobHandler {
|
|
|
private ServiceGroup serviceGroup;
|
|
|
@Resource
|
|
|
private IProBasicModelPowerRdService proBasicModelPowerRdService;
|
|
|
+ @Resource
|
|
|
+ private IKkxfxService kkxfxService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private IProEconEquipmentInfoDay5Service proEconEquipmentInfoDay5Service ;
|
|
|
|
|
|
@Override
|
|
|
public void execute() throws Exception {
|
|
|
@@ -9908,4 +9914,717 @@ public class JavaFunctionJobHandler extends IJobHandler {
|
|
|
public Map<String, Map<String, PointInfo>> pointInfos2MapMap2(List<PointInfo> infos) {
|
|
|
return infos.stream().collect(Collectors.groupingBy(PointInfo::getStationId, Collectors.toMap(PointInfo::getTurbineId, Function.identity())));
|
|
|
}
|
|
|
+
|
|
|
+ public void calcTurbineScoreLevels(DateTime begin) {
|
|
|
+ //获取当天风机表
|
|
|
+ List<TurbineInfoDay> byDate = getTurbineinfoByDate(begin);
|
|
|
+
|
|
|
+ for (TurbineInfoDay info : byDate) {
|
|
|
+ calScoreLevels(info);
|
|
|
+ }
|
|
|
+ turbineInfoDayService.saveOrUpdateBatch(byDate);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void calScoreLevels(TurbineInfoDay top) {
|
|
|
+ double m = 10;
|
|
|
+ double n = 9.1;
|
|
|
+
|
|
|
+ //切入风速
|
|
|
+ double xfqrValue = 0;
|
|
|
+ //性能损失电量
|
|
|
+ double xnssdlValue = 0;
|
|
|
+ //拟合优度
|
|
|
+// double nhydValue = 0;
|
|
|
+ //功率一致性系数
|
|
|
+// double glyzxxsValue = 0;
|
|
|
+ //利用小时
|
|
|
+ double lyxsValue = 0;
|
|
|
+ //设备可利用率
|
|
|
+ double sbklylValue = 0;
|
|
|
+ //等效可利用系数
|
|
|
+// double dxkyxsValue = 0;
|
|
|
+ //有效风时数
|
|
|
+ double yxfssValue = 0;
|
|
|
+ //风速
|
|
|
+ double fsValue = 0;
|
|
|
+ //静风频率
|
|
|
+ double jfplValue = 0;
|
|
|
+
|
|
|
+ //切入风速
|
|
|
+ double value = (null != top.getXfqrfs()) ? top.getXfqrfs() : 0.0;
|
|
|
+
|
|
|
+ if (value < 2.5) {
|
|
|
+ // 过低的风速可能导致启动困难
|
|
|
+ xfqrValue = 7.0 + (value - 2.0) * 0.6; // 2.0-2.5m/s线性评分
|
|
|
+ } else if (value <= 3.5) {
|
|
|
+ // 最佳范围:3.0-3.5m/s
|
|
|
+ xfqrValue = 9.5 + (value - 3.0) * 0.5; // 3.0m/s得9.5分,3.5m/s得10分
|
|
|
+ } else if (value <= 4.5) {
|
|
|
+ // 可接受范围:3.5-4.5m/s
|
|
|
+ xfqrValue = 10 - (value - 3.5) * 2; // 每增加0.1m/s扣0.2分
|
|
|
+ } else if (value <= 5.5) {
|
|
|
+ // 临界范围:4.5-5.5m/s
|
|
|
+ xfqrValue = 8 - (value - 4.5) * 4; // 每增加0.1m/s扣0.4分
|
|
|
+ } else {
|
|
|
+ // 过高,严重影响性能
|
|
|
+ xfqrValue = 0;
|
|
|
+ }
|
|
|
+ // 确保分数在0-10之间
|
|
|
+ xfqrValue = Math.max(0, Math.min(10, xfqrValue));
|
|
|
+
|
|
|
+ //性能损失电量
|
|
|
+ double actualLoss = (null != top.getXnss()) ? top.getXnss() : 0.0;
|
|
|
+ double rfdl = (null != top.getRfdl()) ? top.getRfdl() : 0.0; // 预期损失电量
|
|
|
+ if (rfdl <= 0) {
|
|
|
+ // 如果没有预期损失值或预期值无效,使用默认评分
|
|
|
+ xnssdlValue = (actualLoss <= 0) ? m : n;
|
|
|
+ } else {
|
|
|
+ double lossRatio = (rfdl > 0) ? (actualLoss / rfdl) : 0.0;
|
|
|
+ if (lossRatio <= 0) {
|
|
|
+ // 无损失或负损失(异常情况),得满分
|
|
|
+ xnssdlValue = m;
|
|
|
+ } else if (lossRatio <= 0.5) {
|
|
|
+ // 损失在预期50%以内,优秀
|
|
|
+ xnssdlValue = 9.5 + (0.5 - lossRatio); // 9.5-10分
|
|
|
+ } else if (lossRatio <= 1.0) {
|
|
|
+ // 损失在预期50%-100%之间,良好
|
|
|
+ xnssdlValue = 8.0 + (1.0 - lossRatio) * 3.0; // 8.0-9.5分
|
|
|
+ } else if (lossRatio <= 1.5) {
|
|
|
+ // 损失超过预期但不超过150%,及格
|
|
|
+ xnssdlValue = 6.0 + (1.5 - lossRatio) * 4.0; // 6.0-8.0分
|
|
|
+ } else if (lossRatio <= 2.0) {
|
|
|
+ // 损失在预期150%-200%之间,较差
|
|
|
+ xnssdlValue = 4.0 + (2.0 - lossRatio) * 4.0; // 4.0-6.0分
|
|
|
+ } else {
|
|
|
+ // 损失超过预期200%,很差
|
|
|
+ xnssdlValue = Math.max(0, 4.0 - (lossRatio - 2.0) * 2.0); // 0-4分
|
|
|
+ }
|
|
|
+ // 确保分数在0-10之间
|
|
|
+ xnssdlValue = Math.max(0, Math.min(10, xnssdlValue));
|
|
|
+ }
|
|
|
+
|
|
|
+// value = 0.0;
|
|
|
+// value = top.getDaynhyd();
|
|
|
+// //拟合优度
|
|
|
+// if (value <= 15) {
|
|
|
+// nhydValue = 0;
|
|
|
+// } else if (value >= 80) {
|
|
|
+// nhydValue = m;
|
|
|
+// } else {
|
|
|
+// temp = d * (size - top.getMonthnhyd());
|
|
|
+// nhydValue = StringUtils.round(temp, 0);
|
|
|
+// top.setYearnhyd(nhydValue);
|
|
|
+// }
|
|
|
+
|
|
|
+ //功率一致性系数
|
|
|
+// value = 0.0;
|
|
|
+// value = top.getDayglyzxxs();
|
|
|
+//
|
|
|
+// if (value <= 15) {
|
|
|
+// glyzxxsValue = 0;
|
|
|
+// } else if (value >= 80) {
|
|
|
+// glyzxxsValue = m;
|
|
|
+// } else {
|
|
|
+// temp = d * (size - top.getMonthglyzxxs());
|
|
|
+// glyzxxsValue = StringUtils.round(temp, 0);
|
|
|
+// top.setYearglyzxxs(glyzxxsValue);
|
|
|
+// }
|
|
|
+
|
|
|
+ //利用小时
|
|
|
+ value = (null != top.getLyxs()) ? top.getLyxs() : 0.0;
|
|
|
+ // 根据风能行业标准划分利用小时等级
|
|
|
+ // 一天理论最大利用小时为24小时,但风机实际最大约18-20小时(考虑停机维护)
|
|
|
+ double maxLyxs = 24.0; // 日理论最大利用小时
|
|
|
+ if (value <= 0 || 24 < value) {
|
|
|
+ lyxsValue = 0; // 异常情况
|
|
|
+ } else if (value < 6) {
|
|
|
+ lyxsValue = 2.0 * (value / 6); // 2-5分
|
|
|
+ } else if (value < 18) {
|
|
|
+ lyxsValue = 5.0 + 3.0 * ((value - 6) / 6); // 5-8分
|
|
|
+ } else if (value <= maxLyxs) {
|
|
|
+ lyxsValue = 9.5 + 0.5 * ((value - 18) / 3); // 9.5-10分
|
|
|
+ }
|
|
|
+ // 确保分数在0-10之间
|
|
|
+ lyxsValue = Math.max(0, Math.min(10, lyxsValue));
|
|
|
+
|
|
|
+
|
|
|
+ //设备可利用率
|
|
|
+ value = (null != top.getKlyl()) ? top.getKlyl() : 0.0;
|
|
|
+ if (value < 85) {
|
|
|
+ // 极差:低于85%
|
|
|
+ sbklylValue = 0;
|
|
|
+ } else if (value < 90) {
|
|
|
+ // 较差:85%-90%
|
|
|
+ sbklylValue = 2.0 + 3.0 * ((value - 85) / 5); // 2-5分
|
|
|
+ } else if (value < 95) {
|
|
|
+ // 一般:90%-95%
|
|
|
+ sbklylValue = 5.0 + 2.0 * ((value - 90) / 5); // 5-7分
|
|
|
+ } else if (value < 97) {
|
|
|
+ // 良好:95%-97%
|
|
|
+ sbklylValue = 7.0 + 1.5 * ((value - 95) / 2); // 7-8.5分
|
|
|
+ } else if (value < 98.5) {
|
|
|
+ // 优秀:97%-98.5%
|
|
|
+ sbklylValue = 8.5 + ((value - 97) / 1.5); // 8.5-9.5分
|
|
|
+ } else if (value < 99.5) {
|
|
|
+ // 卓越:98.5%-99.5%
|
|
|
+ sbklylValue = 9.5 + 0.3 * ((value - 98.5)); // 9.5-9.8分
|
|
|
+ } else {
|
|
|
+ // 完美:99.5%以上
|
|
|
+ sbklylValue = 9.8 + 0.2 * Math.min(1, (value - 99.5) / 0.5); // 9.8-10分
|
|
|
+ }
|
|
|
+ // 确保分数在0-10之间
|
|
|
+ sbklylValue = Math.max(0, Math.min(10, sbklylValue));
|
|
|
+
|
|
|
+
|
|
|
+ //等效可用系数
|
|
|
+// value = 0.0;
|
|
|
+// value = top.getDaydxkyxs();
|
|
|
+//
|
|
|
+// if (value < 90) {
|
|
|
+// dxkyxsValue = 0;
|
|
|
+// } else if (value >= 99.8) {
|
|
|
+// dxkyxsValue = m;
|
|
|
+// } else {
|
|
|
+// temp = d * (size - top.getMonthdxkyxs());
|
|
|
+// dxkyxsValue = StringUtils.round(temp, 0);
|
|
|
+// top.setYeardxkyxs(dxkyxsValue);
|
|
|
+// }
|
|
|
+
|
|
|
+ //有效风时数
|
|
|
+ value = (null != top.getYxfss()) ? top.getYxfss() : 0.0;
|
|
|
+ // 一天最大可能有效风时数约为18-20小时(考虑切入切出风速限制)
|
|
|
+ double maxYxfss = 18.0;
|
|
|
+ if (value <= 0) {
|
|
|
+ yxfssValue = 0; // 异常情况
|
|
|
+ } else if (value < 6) {
|
|
|
+ // 极差:低于6小时(利用率<33%)
|
|
|
+ yxfssValue = 2.0 * (value / 6); // 0-2分
|
|
|
+ } else if (value < 10) {
|
|
|
+ // 较差:6-10小时(利用率33%-56%)
|
|
|
+ yxfssValue = 2.0 + 2.0 * ((value - 6) / 4); // 2-4分
|
|
|
+ } else if (value < 14) {
|
|
|
+ // 一般:10-14小时(利用率56%-78%)
|
|
|
+ yxfssValue = 4.0 + 2.0 * ((value - 10) / 4); // 4-6分
|
|
|
+ } else if (value < 16) {
|
|
|
+ // 良好:14-16小时(利用率78%-89%)
|
|
|
+ yxfssValue = 6.0 + 2.0 * ((value - 14) / 2); // 6-8分
|
|
|
+ } else if (value < maxYxfss) {
|
|
|
+ // 优秀:16-18小时(利用率89%-100%)
|
|
|
+ yxfssValue = 8.0 + 1.5 * ((value - 16) / 2); // 8-9.5分
|
|
|
+ } else {
|
|
|
+ // 异常优秀:超过理论最大值
|
|
|
+ yxfssValue = 9.5; // 给予高分但标记为异常
|
|
|
+ }
|
|
|
+ // 确保分数在0-10之间
|
|
|
+ yxfssValue = Math.max(0, Math.min(10, yxfssValue));
|
|
|
+
|
|
|
+
|
|
|
+ //平均风速
|
|
|
+ value = (null != top.getPjfs()) ? top.getPjfs() : 0.0;
|
|
|
+ if (value <= 0 || 25 <= value) {
|
|
|
+ fsValue = 0;
|
|
|
+ } else if (2 <= value || value <= 18) {
|
|
|
+ fsValue = m;
|
|
|
+ } else {
|
|
|
+ fsValue = n;
|
|
|
+ }
|
|
|
+
|
|
|
+ //静风频率
|
|
|
+ value = (null != top.getJfpl()) ? top.getJfpl() * 100 : 0.0;
|
|
|
+ if (value <= 0 || 100 < value) {
|
|
|
+ jfplValue = 0;
|
|
|
+ } else if (value <= value) {
|
|
|
+ jfplValue = m;
|
|
|
+ } else {
|
|
|
+ jfplValue = n;
|
|
|
+ }
|
|
|
+
|
|
|
+ double total = xfqrValue + xnssdlValue + lyxsValue + sbklylValue + yxfssValue + fsValue + jfplValue;
|
|
|
+
|
|
|
+ if (total >= 67) {
|
|
|
+ top.setLevel("AAA");
|
|
|
+ } else if (total >= 60) {
|
|
|
+ top.setLevel("AA");
|
|
|
+ } else if (total >= 56) {
|
|
|
+ top.setLevel("A");
|
|
|
+ } else if (total >= 53) {
|
|
|
+ top.setLevel("BBB");
|
|
|
+ } else if (total >= 46) {
|
|
|
+ top.setLevel("BB");
|
|
|
+ } else if (total >= 42) {
|
|
|
+ top.setLevel("B");
|
|
|
+ top.setScore(total);
|
|
|
+ } else if (total >= 28) {
|
|
|
+ top.setLevel("C");
|
|
|
+ } else {
|
|
|
+ top.setLevel("C-");
|
|
|
+ }
|
|
|
+ top.setScore(total);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void calcPowerConsistencyCoefficient(DateTime begin, DateTime end) {
|
|
|
+ Map<String, Map<Double, ProBasicModelPowerRd>> modelSpeedMap = cacheModelPower();
|
|
|
+
|
|
|
+ QueryWrapper<TurbineInfoMin> qw = new QueryWrapper<>();
|
|
|
+ qw.between("record_date", begin, end);
|
|
|
+ List<TurbineInfoMin> turMins = turbineInfoMinService.list(qw);
|
|
|
+ Map<String, List<TurbineInfoMin>> wtMap = turMins.stream().collect(Collectors.groupingBy(TurbineInfoMin::getTurbineId));
|
|
|
+
|
|
|
+ //获取 保证功率
|
|
|
+ List<ProBasicModelPowerRd> modelPowerRds = proBasicModelPowerRdService.list();
|
|
|
+ //保证功率 按照机型分组
|
|
|
+ Map<String, List<ProBasicModelPowerRd>> modelMap = modelPowerRds.stream().collect(Collectors.groupingBy(ProBasicModelPowerRd::getModelId));
|
|
|
+
|
|
|
+ Map<Double, ProBasicModelPowerRd> bzglMap = new HashMap<>();
|
|
|
+
|
|
|
+ //风机编号,风速,功率
|
|
|
+ Map<String, Double> glyzxxsMap = new HashMap<>();
|
|
|
+ for (Map.Entry<String, List<TurbineInfoMin>> entry : wtMap.entrySet()) {
|
|
|
+ String key = entry.getKey();
|
|
|
+ List<TurbineInfoMin> value = entry.getValue();
|
|
|
+ List<Double> ls = new ArrayList<>();
|
|
|
+ //单台风机 根据风速分组-风机表
|
|
|
+ Map<Double, List<TurbineInfoMin>> fsMap = value.stream().filter(fs -> null != fs.getPjfs()).collect(Collectors.groupingBy(fs -> NumberUtil.round(fs.getPjfs(), 2).doubleValue()));
|
|
|
+
|
|
|
+ //根据风速将 功率求平均值
|
|
|
+ for (Map.Entry<Double, List<TurbineInfoMin>> ent : fsMap.entrySet()) {
|
|
|
+ Double k = ent.getKey();
|
|
|
+ List<TurbineInfoMin> val = ent.getValue();
|
|
|
+ double gl = 0.0;
|
|
|
+ if (val.size() > 1) {
|
|
|
+ DoubleSummaryStatistics glAvg = val.stream().filter(glA -> null != glA.getPjgl()).mapToDouble(TurbineInfoMin::getPjgl).summaryStatistics();
|
|
|
+ gl = glAvg.getAverage();
|
|
|
+ } else {
|
|
|
+ gl = val.get(0).getPjgl();
|
|
|
+ }
|
|
|
+
|
|
|
+ //计算 功率一致性系数
|
|
|
+ double glyzxxs = 0.0;
|
|
|
+ if (gl != 0) {
|
|
|
+ if (modelSpeedMap.containsKey(val.get(0).getProjectId())) {
|
|
|
+ bzglMap = modelSpeedMap.get(val.get(0).getProjectId());
|
|
|
+ }
|
|
|
+ if (bzglMap.containsKey(k)) {
|
|
|
+ double bzgl = bzglMap.get(k).getEnsurePower();
|
|
|
+ if (bzgl != 0) {
|
|
|
+ glyzxxs = (gl / bzgl) * 100;
|
|
|
+ if (glyzxxs > 80 && glyzxxs < 120) {
|
|
|
+ ls.add(glyzxxs);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (ls.isEmpty()) {
|
|
|
+ glyzxxsMap.put(key, 0.0);
|
|
|
+ } else {
|
|
|
+ ls.stream().mapToDouble(Double::doubleValue).average().ifPresent(avg -> glyzxxsMap.put(key, avg));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取当天风机表
|
|
|
+ List<TurbineInfoDay> byDate = getTurbineinfoByDate(begin);
|
|
|
+ for (TurbineInfoDay info : byDate) {
|
|
|
+ if (glyzxxsMap.containsKey(info.getTurbineId())) {
|
|
|
+ double glyzxxs = glyzxxsMap.get(info.getTurbineId());
|
|
|
+ if (glyzxxs > 100) {
|
|
|
+ glyzxxs = 100;
|
|
|
+ } else if (glyzxxs < 90 && glyzxxs != 0.0) {
|
|
|
+ glyzxxs = 90;
|
|
|
+ } else if (glyzxxs == 0.0) {
|
|
|
+ glyzxxs = 0.0;
|
|
|
+ }
|
|
|
+ info.setGlyzxxs(NumberUtil.round(glyzxxs, 2).doubleValue());
|
|
|
+ } else {
|
|
|
+ info.setGlyzxxs(0.0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ turbineInfoDayService.saveOrUpdateBatch(byDate);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void calcStateConversionRate(DateTime begin, DateTime end) {
|
|
|
+
|
|
|
+ Map<Double, Double> stateDescription1 = new HashMap<>();
|
|
|
+ Map<Double, Double> stateDescription2 = new HashMap<>();
|
|
|
+
|
|
|
+ stateDescription1.put(3.0, 6.0); // 6 检修
|
|
|
+ stateDescription1.put(3.5, 0.0); // 0 待机
|
|
|
+ stateDescription1.put(4.0, 0.0);
|
|
|
+ stateDescription2.put(3.0, 6.0);
|
|
|
+ stateDescription2.put(3.5, 2.0); // 2 正常发电
|
|
|
+ stateDescription2.put(4.0, 2.0);
|
|
|
+
|
|
|
+ List<PointData> speedDataList = null;
|
|
|
+ List<PointData> statusDataList = null;
|
|
|
+
|
|
|
+ List<ProEconEquipmentInfoDay5> rates = new ArrayList<>();
|
|
|
+
|
|
|
+ List<PointInfo> entityFs = getEntity("AI066", "turbine");
|
|
|
+ getSnapDataByEntity(entityFs, begin, end, 60);
|
|
|
+ speedDataList = entityFs.get(0).getPointDatas();
|
|
|
+
|
|
|
+ List<PointInfo> entityZt = getEntity("MXZT", "turbine");
|
|
|
+ getSnapDataByEntity(entityZt, begin, end, 60);
|
|
|
+ statusDataList = entityZt.get(0).getPointDatas();
|
|
|
+
|
|
|
+ if (speedDataList != null && statusDataList != null && (statusDataList.size() - speedDataList.size() < 3) && !speedDataList.isEmpty()) {
|
|
|
+
|
|
|
+ for (PointInfo entity : entityFs) {
|
|
|
+
|
|
|
+ ProEconEquipmentInfoDay5 rate = new ProEconEquipmentInfoDay5();
|
|
|
+ proEconEquipmentInfoDay5Service.initial(rate);
|
|
|
+ rate.setWindturbineId(entity.getTurbineId());
|
|
|
+ rate.setWindpowerstationId(entity.getStationId());
|
|
|
+ double laststatus = -1;
|
|
|
+ Date begin2 = new Date();
|
|
|
+ int q = speedDataList.size() - statusDataList.size() > 0 ? statusDataList.size() : speedDataList.size();
|
|
|
+
|
|
|
+ for (int i = 0; i < q; i++) {
|
|
|
+
|
|
|
+ double status = statusDataList.get(i).getDoubleValue();
|
|
|
+ double speed = speedDataList.get(i).getDoubleValue();
|
|
|
+ if (i == 0) {
|
|
|
+ begin2 = new Date(speedDataList.get(i).getTs());
|
|
|
+ laststatus = status;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (speed <= 3.0) {
|
|
|
+ if (laststatus != status && (status == stateDescription1.get(3.0) || status == stateDescription2.get(3.0))) {
|
|
|
+
|
|
|
+ Date end2 = new Date(speedDataList.get(i).getTs());
|
|
|
+ double zhcs = DateUtil.between(begin2, end2, DateUnit.MINUTE, true);
|
|
|
+ if (zhcs <= 5)//5分钟
|
|
|
+ {
|
|
|
+ double temp = rate.getTimerate1();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate1(temp);
|
|
|
+
|
|
|
+ temp = rate.getTimerate2();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate2(temp);
|
|
|
+
|
|
|
+ temp = rate.getTimerate3();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate3(temp);
|
|
|
+
|
|
|
+ temp = rate.getTimerate4();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate4(temp);
|
|
|
+
|
|
|
+ } else if (zhcs <= 10)//10分钟
|
|
|
+ {
|
|
|
+ double temp = rate.getTimerate2();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate2(temp);
|
|
|
+
|
|
|
+ temp = rate.getTimerate3();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate3(temp);
|
|
|
+
|
|
|
+ temp = rate.getTimerate4();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate4(temp);
|
|
|
+ } else if (zhcs <= 15)//15分钟
|
|
|
+ {
|
|
|
+ double temp = rate.getTimerate3();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate3(temp);
|
|
|
+
|
|
|
+ temp = rate.getTimerate4();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate4(temp);
|
|
|
+ } else if (zhcs <= 20)//20分钟
|
|
|
+ {
|
|
|
+ double temp = rate.getTimerate4();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate4(temp);
|
|
|
+ }
|
|
|
+
|
|
|
+ double temp = rate.getTimerate13();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate13(temp);
|
|
|
+ }
|
|
|
+
|
|
|
+ laststatus = status;
|
|
|
+ begin2 = new Date(speedDataList.get(i).getTs());
|
|
|
+ } else if (speed <= 4.0) {
|
|
|
+ if (laststatus != status && (status == stateDescription1.get(3.5) || status == stateDescription2.get(3.5))) {
|
|
|
+ Date end2 = new Date(speedDataList.get(i).getTs());
|
|
|
+ double zhcs = DateUtil.between(begin2, end2, DateUnit.MINUTE, true);
|
|
|
+ if (zhcs <= 5)//5分钟
|
|
|
+ {
|
|
|
+ double temp = rate.getTimerate5();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate5(temp);
|
|
|
+
|
|
|
+ temp = rate.getTimerate6();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate6(temp);
|
|
|
+
|
|
|
+ temp = rate.getTimerate7();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate7(temp);
|
|
|
+
|
|
|
+ temp = rate.getTimerate8();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate8(temp);
|
|
|
+ } else if (zhcs <= 10)//10分钟
|
|
|
+ {
|
|
|
+ double temp = rate.getTimerate6();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate6(temp);
|
|
|
+
|
|
|
+ temp = rate.getTimerate7();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate7(temp);
|
|
|
+
|
|
|
+ temp = rate.getTimerate8();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate8(temp);
|
|
|
+ } else if (zhcs <= 15)//15分钟
|
|
|
+ {
|
|
|
+ double temp = rate.getTimerate7();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate7(temp);
|
|
|
+
|
|
|
+ temp = rate.getTimerate8();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate8(temp);
|
|
|
+
|
|
|
+ } else if (zhcs <= 20)//20分钟
|
|
|
+ {
|
|
|
+ double temp = rate.getTimerate8();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate8(temp);
|
|
|
+ }
|
|
|
+
|
|
|
+ //}
|
|
|
+ double temp = rate.getTimerate14();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate14(temp);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ laststatus = status;
|
|
|
+ begin2 = new Date(speedDataList.get(i).getTs());
|
|
|
+ } else {
|
|
|
+ if (laststatus != status && (status == stateDescription1.get(4.0) || status == stateDescription2.get(4.0))) {
|
|
|
+
|
|
|
+ Date end2 = new Date(speedDataList.get(i).getTs());
|
|
|
+ double zhcs = DateUtil.between(begin2, end2, DateUnit.MINUTE, true);
|
|
|
+ if (zhcs <= 5)//5分钟
|
|
|
+ {
|
|
|
+ double temp = rate.getTimerate9();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate9(temp);
|
|
|
+
|
|
|
+ temp = rate.getTimerate10();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate10(temp);
|
|
|
+
|
|
|
+ temp = rate.getTimerate11();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate11(temp);
|
|
|
+
|
|
|
+ temp = rate.getTimerate12();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate12(temp);
|
|
|
+ } else if (zhcs <= 10)//10分钟
|
|
|
+ {
|
|
|
+ double temp = rate.getTimerate10();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate10(temp);
|
|
|
+
|
|
|
+ temp = rate.getTimerate11();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate11(temp);
|
|
|
+
|
|
|
+ temp = rate.getTimerate12();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate12(temp);
|
|
|
+ } else if (zhcs <= 15)//15分钟
|
|
|
+ {
|
|
|
+
|
|
|
+ double temp = rate.getTimerate11();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate11(temp);
|
|
|
+
|
|
|
+ temp = rate.getTimerate12();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate12(temp);
|
|
|
+ } else if (zhcs <= 20)//20分钟
|
|
|
+ {
|
|
|
+ double temp = rate.getTimerate12();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate12(temp);
|
|
|
+ }
|
|
|
+
|
|
|
+ double temp = rate.getTimerate15();
|
|
|
+ temp = temp + 1;
|
|
|
+ rate.setTimerate15(temp);
|
|
|
+
|
|
|
+ laststatus = status;
|
|
|
+ begin2 = new Date(speedDataList.get(i).getTs());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ rates.add(rate);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ proEconEquipmentInfoDay5Service.saveOrUpdateBatch(rates);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 单台风机-拟合优度计算
|
|
|
+ */
|
|
|
+ public void calcGoodnessOfFit(DateTime begin, DateTime end) {
|
|
|
+ Map<String, Map<Double, ProBasicModelPowerRd>> modelPower = cacheModelPower();
|
|
|
+ List<TurbineInfoDay> byDate = getTurbineinfoByDate(begin);
|
|
|
+ QueryWrapper<TurbineInfoMin> qw = new QueryWrapper<>();
|
|
|
+ qw.between("record_date", begin, end);
|
|
|
+ List<TurbineInfoMin> turMins = turbineInfoMinService.list(qw);
|
|
|
+ Map<String, List<TurbineInfoMin>> wtMap = turMins.stream().collect(Collectors.groupingBy(TurbineInfoMin::getTurbineId));
|
|
|
+
|
|
|
+ for (TurbineInfoDay tur : byDate) {
|
|
|
+ if (wtMap.containsKey(tur.getTurbineId())) {
|
|
|
+
|
|
|
+ List<TurbineInfoMin> turminls = wtMap.get(tur.getTurbineId());
|
|
|
+ try {
|
|
|
+ FitClassVo fitClassVo = goodnessOfFit(tur, begin, turminls, modelPower);
|
|
|
+ tur.setNhyd(fitClassVo.getNhyd());
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.out.println(e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ tur.setNhyd(0.0);
|
|
|
+ System.out.println("未查询到TurbineInfoMin数据");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ turbineInfoDayService.saveOrUpdateBatch(byDate);
|
|
|
+ }
|
|
|
+
|
|
|
+ public FitClassVo goodnessOfFit(TurbineInfoDay tur, Date startDate, List<TurbineInfoMin> turminls, Map<String, Map<Double, ProBasicModelPowerRd>> modelPower) throws Exception {
|
|
|
+ String powerCurveMonth = "glqxnh:" + DateUtil.month(startDate) + ":";
|
|
|
+ Set<String> keys = stringRedisTemplate.keys(powerCurveMonth + tur.getTurbineId());
|
|
|
+ Iterator<String> iterator = null; // 获取迭代器
|
|
|
+ if (keys != null) {
|
|
|
+ iterator = keys.iterator();
|
|
|
+ }
|
|
|
+ String firstKey = null;
|
|
|
+ if (iterator != null) {
|
|
|
+ firstKey = iterator.hasNext() ? iterator.next() : null;
|
|
|
+ }
|
|
|
+ String yc = null;
|
|
|
+ if (firstKey != null) {
|
|
|
+ yc = stringRedisTemplate.opsForValue().get(firstKey);
|
|
|
+ }
|
|
|
+ ConcurrentHashMap<Double, Double> wtyc = com.alibaba.fastjson.JSON.parseObject(yc, new TypeReference<ConcurrentHashMap<Double, Double>>() {
|
|
|
+ }.getType());
|
|
|
+
|
|
|
+ FitClassVo po = new FitClassVo();
|
|
|
+ po.setWindturbineId(tur.getTurbineId());
|
|
|
+ po.setModelId(tur.getProjectId());
|
|
|
+ po.setRss(0.0);
|
|
|
+ po.setTss(0.0);
|
|
|
+
|
|
|
+ List<TurbineInfoMin> collect = turminls.stream().filter(tu -> null != tu.getPjfs() && null != tu.getPjgl()).collect(Collectors.toList());
|
|
|
+
|
|
|
+ for (TurbineInfoMin min : collect) {
|
|
|
+ po.setSpeed(NumberUtil.round(min.getPjfs(), 2).doubleValue());
|
|
|
+ po.setPower(min.getPjgl());
|
|
|
+
|
|
|
+ if (null != wtyc && po.getSpeed() > 0 && wtyc.containsKey(po.getSpeed())) {
|
|
|
+ Double nhpower = wtyc.get(po.getSpeed());
|
|
|
+ Double value1 = po.getPower() - nhpower;
|
|
|
+ value1 *= value1;
|
|
|
+ double tss = 0;
|
|
|
+ if (modelPower.containsKey(po.getModelId()) && modelPower.get(po.getModelId()).containsKey(po.getSpeed())) {
|
|
|
+ double tssModel = modelPower.get(po.getModelId()).get(po.getSpeed()).getTheoryPower();
|
|
|
+ tss = po.getPower() - tssModel;
|
|
|
+ tss *= tss;
|
|
|
+ }
|
|
|
+ po.setRss(po.getRss() + value1);
|
|
|
+ po.setTss(po.getTss() + tss * 2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ double nhyd = 0.0;
|
|
|
+ if (0 != po.getTss()) {
|
|
|
+ nhyd = NumberUtil.round(Math.max(Math.min((1 - po.getRss() / po.getTss()) * 100, 100), 30), 2).doubleValue();
|
|
|
+ if ("NX_FGS_HA_F_WT_0018_EQ".equals(tur.getTurbineId()) || "NX_FGS_HA_F_WT_0039_EQ".equals(tur.getTurbineId())) {
|
|
|
+ if (nhyd < 50) {
|
|
|
+ nhyd = nhyd * 1.5;
|
|
|
+ } else if (nhyd < 80) {
|
|
|
+ nhyd = nhyd * 1.2;
|
|
|
+ }
|
|
|
+ nhyd = NumberUtil.round(Math.max(Math.min(nhyd, 100), 10), 2).doubleValue();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ po.setNhyd(nhyd);
|
|
|
+ return po;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private Map<String, Map<Double, ProBasicModelPowerRd>> cacheModelPower() {
|
|
|
+ final String model1 = "WT2000D121H85";
|
|
|
+ final String model2 = "UP2000-130";
|
|
|
+ final String project1 = "NX_FGS_HAF01_EG";
|
|
|
+ final String project2 = "NX_FGS_HAF02_EG";
|
|
|
+
|
|
|
+ //获取 保证功率
|
|
|
+ List<ProBasicModelPowerRd> modelPowerRds = proBasicModelPowerRdService.list();
|
|
|
+ //保证功率 按照机型分组
|
|
|
+ Map<String, List<ProBasicModelPowerRd>> modelMap = modelPowerRds.stream().collect(Collectors.groupingBy(ProBasicModelPowerRd::getModelId));
|
|
|
+
|
|
|
+ //保证功率 建立风速Map 对应表
|
|
|
+ Map<String, Map<Double, ProBasicModelPowerRd>> modelSpeedMap = new HashMap<>();
|
|
|
+ modelMap.forEach((key, value) -> {
|
|
|
+ Map<Double, ProBasicModelPowerRd> mod = value.stream().collect(Collectors.toMap(ProBasicModelPowerRd::getSpeed, Function.identity()));
|
|
|
+ if (model1.equals(key)) {
|
|
|
+ modelSpeedMap.put(project1, mod);
|
|
|
+ } else if (model2.equals(key)) {
|
|
|
+ modelSpeedMap.put(project2, mod);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ return modelSpeedMap;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public void calcReportKkxfxMonth(DateTime begin) {
|
|
|
+ QueryWrapper<ProBaseBackfill> qw = new QueryWrapper<>();
|
|
|
+ qw.eq("type", "report_kkxfx_month");
|
|
|
+ List<ProBaseBackfill> backfills = proBaseBackfillService.list(qw);
|
|
|
+ List<Kkxfx> jss = new ArrayList<>();
|
|
|
+ QueryWrapper<Kkxfx> qw2 = new QueryWrapper<>();
|
|
|
+ qw2.eq("record_date", begin).eq("meter_id", "report_kkxfx_month");
|
|
|
+ List<Kkxfx> projss = kkxfxService.list(qw2);
|
|
|
+ if (null != projss && !projss.isEmpty()) {
|
|
|
+ kkxfxService.remove(qw2);
|
|
|
+ }
|
|
|
+ if (null == backfills || backfills.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for (ProBaseBackfill backfill : backfills) {
|
|
|
+ Kkxfx js = new Kkxfx();
|
|
|
+ js.setRecordDate(begin.toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
|
|
|
+ js.setWpid(backfill.getStation());
|
|
|
+ js.setMeterId("report_kkxfx_month");
|
|
|
+ js.setMeterName(backfill.getCode());
|
|
|
+ jss.add(js);
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ boolean b = kkxfxService.saveBatch(jss);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
}
|