package com.gyee.runeconomy.service.fiveloss; import cn.hutool.core.date.DateUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.gyee.common.vo.benchmark.FjjxbVo; import com.gyee.runeconomy.dto.FiveLoss.AnnotationTool; import com.gyee.runeconomy.dto.FiveLoss.FixedVo; import com.gyee.runeconomy.dto.FiveLoss.TableTitle; import com.gyee.runeconomy.dto.FiveLoss.exception.CustomException; import com.gyee.runeconomy.dto.result.PowerPointData; import com.gyee.runeconomy.dto.result.ResultCode; import com.gyee.runeconomy.model.auto.ProEconEquipmentInfoDay1; import com.gyee.runeconomy.service.auto.IProEconEquipmentInfoDay1Service; import lombok.extern.slf4j.Slf4j; import lombok.val; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; import java.util.stream.Collectors; @Slf4j @Service public class FiveLossService { @Resource private ProEconPowerFittingAnalySisService analysisService; @Resource private IProEconEquipmentInfoDay1Service equipmentInfoDay1Service; @Resource private ITurbineInfoDayService turbineInfoDayService; /** * 损失电量计算 eg: 1.5MW 一小时发电:1500kWh 一分钟发电:1500/60 == 25kW * * @param ztmxData 状态明细 * @param zsglData 设备的理论功率 * @param interval 原始数据的间隔 * @param status 风机当前状态 * @return */ private double generalLoss(List ztmxData, Map zsglData, int interval, double status) { double ssdl = 0.0; List pointData = ztmxData.stream().filter(zt -> zt.getMxzt() == status).collect(Collectors.toList()); if (status == 0.0 || status == 2.0 || status == 3.0 || status == 4.0 || status == 9.0 || status == 10.0 || status == 11.0) { for (PowerPointData obj : pointData) { double speed = new BigDecimal(obj.getSpeed()).setScale(2, RoundingMode.FLOOR).doubleValue(); double zsgl = null == zsglData.get(speed) ? 0:zsglData.get(speed); double power = obj.getPower(); double temp = (zsgl - power) > 0 ? zsgl - power : 0; ssdl = ssdl + (temp / 60) * (interval / 60); } } else { for (PowerPointData obj : pointData) { if (obj.getSpeed() < 3.0) continue; double speed = new BigDecimal(obj.getSpeed()).setScale(2, RoundingMode.FLOOR).doubleValue(); double zsgl = null == zsglData.get(speed) ? 0:zsglData.get(speed); ssdl = ssdl + (zsgl / 60) * (interval / 60); } } //理论发电量 status < 0 if (status < 0){ for (PowerPointData obj : ztmxData) { if (obj.getSpeed() < 3.0) continue; double speed = new BigDecimal(obj.getSpeed()).setScale(2, RoundingMode.FLOOR).doubleValue(); double zsgl = null == zsglData.get(speed) ? 0:zsglData.get(speed); ssdl = ssdl + (zsgl / 60) * (interval / 60); } } return ssdl > 0 ? ssdl : 0; } //新的五损计算方法 //1.思路整理 实际电量、计划检修损失电量、非计划检修损失电量、限电损失电量、受累损失电量、性能损失电量、理论发电量 //计算思路 实际电量 当前功率 * 时间 = 电量 //计划检修损失电量 /** * 使用文件,通过自诉案功率计算五损数据 * @param ids 准备的数据ID */ public Map fiveLossCalByZSGL(String ids) { Map promise = null; try { log.info("======风机绩效榜计算开始............."); promise = new HashMap<>(); List result = new ArrayList<>(); Map> zsglmap = InitialRunner.zsllglNewMap; List analyses = analysisService.selectListByIds(ids); if (analyses.isEmpty()){ log.info("======风机榜效帮计算结束,数据为空............."); throw new CustomException(ResultCode.ERROR); } for (ProEconPowerFittingAnalySis p : analyses) { List content = FileUtil.readFile(p.getPath(), true); if (content.isEmpty() || zsglmap.isEmpty() || zsglmap.get(p.getWindturbineId()) == null){ log.info("======风机榜效帮计算结束," + p.getWindturbineId() + "文件内容或当前风机的自算功率为空............."); continue; } log.info("======风机绩效榜计算:" + p.getWindturbineId()); double llfdl = 0.0; //理论发电量 double rfdl = 0.0; //日发电量 double jhjxssdl = 0.0;//计划检修损失电量 double fjhjxssdl =0.0;//非计划检修电量 double xdssdl = 0.0;//限电损失电量 double slssdl = 0.0;//受累损失电量 double xnssdl = 0.0;//性能损失电量 double speed = 0.0;//风速 content.remove(0); //去掉标题栏 int count = 86400 / p.getInterp(); //一天86400s 一天的条数 List> coll = CollectUtil.groupListByQty(content, count); for (List ls : coll) { List pdl = ls.stream().map(mp -> new PowerPointData(mp.split(","), false)).collect(Collectors.toList()); double lldl = generalLoss(pdl, zsglmap.get(p.getWindturbineId()), p.getInterp(), -1); //理论发电量 double dj = generalLoss(pdl, zsglmap.get(p.getWindturbineId()), p.getInterp(), 0); //待机 double sdtj = generalLoss(pdl, zsglmap.get(p.getWindturbineId()), p.getInterp(), 1); //手动停机 double zcfd = generalLoss(pdl, zsglmap.get(p.getWindturbineId()), p.getInterp(), 2); //正常发电 double xdss = generalLoss(pdl, zsglmap.get(p.getWindturbineId()), p.getInterp(), 5); //限电损失电量 double qxjcl = generalLoss(pdl, zsglmap.get(p.getWindturbineId()), p.getInterp(), 3); //缺陷降出力损失电量 double xdjcl = generalLoss(pdl, zsglmap.get(p.getWindturbineId()), p.getInterp(), 4); //限电降出力损失电量 double cnsltj = generalLoss(pdl, zsglmap.get(p.getWindturbineId()), p.getInterp(), 7); //场内受累停机损失电量 double cnsljx = generalLoss(pdl, zsglmap.get(p.getWindturbineId()), p.getInterp(), 9); //场内受累检修损失电量 double dwsl = generalLoss(pdl, zsglmap.get(p.getWindturbineId()), p.getInterp(), 10); //电网受累损失电量 double hjsl = generalLoss(pdl, zsglmap.get(p.getWindturbineId()), p.getInterp(), 11); //环境受累损失电量 double gzss = generalLoss(pdl, zsglmap.get(p.getWindturbineId()), p.getInterp(), 6); //故障损失电量 double tjjx = generalLoss(pdl, zsglmap.get(p.getWindturbineId()), p.getInterp(), 8); //停机检修 llfdl += lldl; jhjxssdl += (tjjx + cnsljx); fjhjxssdl += (gzss + cnsltj); xdssdl += (xdjcl + xdss); slssdl += (dwsl + hjsl); xnssdl += (dj + sdtj + zcfd + qxjcl); rfdl += pdl.get(pdl.size() - 1).getDl(); speed += pdl.stream().mapToDouble(PowerPointData::getSpeed).sum(); } FjjxbVo vo = new FjjxbVo(); vo.setId(p.getWindturbineId()); vo.setName(p.getCode()); vo.setLlfdl(new BigDecimal(llfdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setSjfdl(new BigDecimal(rfdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setJhjx(new BigDecimal(jhjxssdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setFjhjx(new BigDecimal(fjhjxssdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setXd(new BigDecimal(xdssdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setXn(new BigDecimal(xnssdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setSl(new BigDecimal(slssdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setSpeed(new BigDecimal(speed/content.size()).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setFnlly(llfdl > 0 ? new BigDecimal(rfdl / llfdl).setScale(2, RoundingMode.FLOOR).doubleValue() : 0); result.add(vo); } log.info("======风机榜效帮计算结束............."); result.stream().sorted(Comparator.comparing(FjjxbVo::getId)); /** 添加标题 **/ val fxList = AnnotationTool.getFixedVoList(FjjxbVo.class); List lt = fxList.stream().map(d -> new TableTitle(d.getName(), d.getDes())).collect(Collectors.toList()); promise.put("title", lt); promise.put("data", result); } catch (Exception e) { e.printStackTrace(); } return promise; } public Map fiveLossCalByZSGL2(String ids) { Map promise = null; try { log.info("======风机绩效榜计算开始............."); promise = new HashMap<>(); List result = new ArrayList<>(); Map> zsglmap = InitialRunner.zsllglNewMap; List analyses = analysisService.selectListByIds(ids); if (analyses.isEmpty()){ log.info("======风机榜效帮计算结束,数据为空............."); throw new CustomException(ResultCode.ERROR); } QueryWrapper wrapper = new QueryWrapper<>(); String[] split = analyses.get(0).getTime().split("-"); Date start = DateUtil.parse(split[0]).toJdkDate(); Date end = DateUtil.parse(split[1]).toJdkDate(); wrapper.lambda().between(ProEconEquipmentInfoDay1::getRecordDate, start, end); List list = equipmentInfoDay1Service.list(wrapper); Map> collect = list.stream().collect(Collectors.groupingBy(ProEconEquipmentInfoDay1::getWindturbineId)); List day1s; for (ProEconPowerFittingAnalySis p : analyses) { day1s = collect.get(p.getWindturbineId()); double llfdl = day1s.stream().mapToDouble(ProEconEquipmentInfoDay1::getRllfdl).sum(); //理论发电量 double rfdl = day1s.stream().mapToDouble(ProEconEquipmentInfoDay1::getRfdl).sum(); //日发电量 double jhjxssdl = day1s.stream().mapToDouble(ProEconEquipmentInfoDay1::getRjxssdl).sum();//计划检修损失电量 double fjhjxssdl = day1s.stream().mapToDouble(ProEconEquipmentInfoDay1::getRgzssdl).sum();//非计划检修电量 double xdssdl = day1s.stream().mapToDouble(ProEconEquipmentInfoDay1::getRxdtjssdl).sum()+ day1s.stream().mapToDouble(ProEconEquipmentInfoDay1::getRxdjclssdl).sum();//限电损失电量 double slssdl = 0.0;//受累损失电量 double xnssdl = day1s.stream().mapToDouble(ProEconEquipmentInfoDay1::getRxnssdl).sum();//性能损失电量 double speed = day1s.stream().mapToDouble(ProEconEquipmentInfoDay1::getRpjfs).average().orElse(0.0);//风速 FjjxbVo vo = new FjjxbVo(); vo.setId(p.getWindturbineId()); vo.setName(p.getCode()); vo.setLlfdl(new BigDecimal(llfdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setSjfdl(new BigDecimal(rfdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setJhjx(new BigDecimal(jhjxssdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setFjhjx(new BigDecimal(fjhjxssdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setXd(new BigDecimal(xdssdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setXn(new BigDecimal(xnssdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setSl(new BigDecimal(slssdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setSpeed(new BigDecimal(speed).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setFnlly(llfdl > 0 ? new BigDecimal(rfdl / llfdl).setScale(2, RoundingMode.FLOOR).doubleValue() : 0); result.add(vo); } log.info("======风机榜效帮计算结束............."); result.stream().sorted(Comparator.comparing(FjjxbVo::getId)); /** 添加标题 **/ List fxList = AnnotationTool.getFixedVoList(FjjxbVo.class); List lt = fxList.stream().map(d -> new TableTitle(d.getName(), d.getDes())).collect(Collectors.toList()); promise.put("title", lt); promise.put("data", result); } catch (Exception e) { e.printStackTrace(); } return promise; } public Map fiveLossCalByZSGL3(String ids) { Map promise = null; try { log.info("======风机绩效榜计算开始............."); promise = new HashMap<>(); List result = new ArrayList<>(); // Map> zsglmap = InitialRunner.zsllglNewMap; List analyses = analysisService.selectListByIds(ids); if (analyses.isEmpty()){ log.info("======风机榜效帮计算结束,数据为空............."); throw new CustomException(ResultCode.ERROR); } QueryWrapper wrapper = new QueryWrapper<>(); String[] split = analyses.get(0).getTime().split("-"); Date start = DateUtil.parse(split[0]).toJdkDate(); Date end = DateUtil.parse(split[1]).toJdkDate(); wrapper.lambda().between(TurbineInfoDay::getRecordDate, start, end); List list = turbineInfoDayService.list(wrapper); Map> collect = list.stream().collect(Collectors.groupingBy(TurbineInfoDay::getTurbineId)); Map> collectcz = list.stream().collect(Collectors.groupingBy(TurbineInfoDay::getStationId)); List day1s; for (ProEconPowerFittingAnalySis p : analyses) { FjjxbVo vo = new FjjxbVo(); if("A".equals(p.getWindturbineId())){ day1s = collectcz.get(p.getStation()); vo.setId(p.getStation()); vo.setName(p.getStationcn().replaceFirst("风电场","")); }else { day1s = collect.get(p.getWindturbineId()); vo.setId(p.getWindturbineId()); vo.setName(p.getCode()); } double llfdl = day1s.stream().mapToDouble(TurbineInfoDay::getLlfdl).sum(); //理论发电量 double rfdl = day1s.stream().mapToDouble(TurbineInfoDay::getRfdl).sum(); //日发电量 double jhjxssdl = day1s.stream().mapToDouble(TurbineInfoDay::getJhjxss).sum();//计划检修损失电量 double fjhjxssdl = day1s.stream().mapToDouble(TurbineInfoDay::getFjhjxss).sum();//非计划检修电量 double xdssdl = day1s.stream().mapToDouble(TurbineInfoDay::getXdss).sum();//限电损失电量 double slssdl = 0.0;//受累损失电量 double xnssdl = day1s.stream().mapToDouble(TurbineInfoDay::getXnss).sum();//性能损失电量 double speed = day1s.stream().mapToDouble(TurbineInfoDay::getPjfs).average().orElse(0.0);//风速 llfdl = llfdl/1000; rfdl = rfdl/1000; jhjxssdl = jhjxssdl/1000; fjhjxssdl = fjhjxssdl/1000; xdssdl = xdssdl/1000; xnssdl = xnssdl/1000; vo.setLlfdl(new BigDecimal(llfdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setSjfdl(new BigDecimal(rfdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setJhjx(new BigDecimal(jhjxssdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setFjhjx(new BigDecimal(fjhjxssdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setXd(new BigDecimal(xdssdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setXn(new BigDecimal(xnssdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setSl(new BigDecimal(slssdl).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setSpeed(new BigDecimal(speed).setScale(2, RoundingMode.FLOOR).doubleValue()); vo.setFnlly(llfdl > 0 ? new BigDecimal(rfdl / llfdl).setScale(2, RoundingMode.FLOOR).doubleValue() : 0); result.add(vo); } log.info("======风机榜效帮计算结束............."); result.stream().sorted(Comparator.comparing(FjjxbVo::getId)); /** 添加标题 **/ List fxList = AnnotationTool.getFixedVoList(FjjxbVo.class); List lt = fxList.stream().map(d -> new TableTitle(d.getName(), d.getDes())).collect(Collectors.toList()); promise.put("title", lt); promise.put("data", result); } catch (Exception e) { e.printStackTrace(); } return promise; } }