/*
package com.ruoyi;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.quartz.handler.IJobHandler;
import com.ruoyi.ucp.entity.*;
import com.ruoyi.ucp.feign.AdapterApi;
import com.ruoyi.ucp.service.*;
import com.ruoyi.ucp.util.CalcCache;
import org.apache.commons.math3.fitting.PolynomialCurveFitter;
import org.apache.commons.math3.fitting.WeightedObservedPoints;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.net.URI;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.stream.Collectors;

//@Service
public class JavaFunctionJobHandler extends IJobHandler {

    @Resource
    private AdapterApi adapter;
    @Resource
    private IPointInfoService pointService;
    @Resource
    private IStationInfoHourService stationInfoHourService;
    @Resource
    private IStationInfoDayService stationInfoDayService;
    @Resource
    private ILineInfoDayService lineInfoDayService;
    @Resource
    private IStateAiService stateAiService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private IEquipmentModelService equipmentModelService;
    @Resource
    private ITurbineInfoDayService turbineInfoDayService;
    @Resource
    private IProEconReportIndicatorPoolService reportIndicatorPoolService;
    @Resource
    private ITurbineInfoMinService turbineInfoMinService;
    @Resource
    private IStationInfoMinService stationInfoMinService;
    @Resource
    private IProBasicProjectPlanService proBasicProjectPlanService;

    @Override
    public void execute() throws Exception {

    }

    @Override
    public IJobHandler getFunctionHandler() {
        return null;
    }

    @Override
    public void setFunctionHandler(IJobHandler jobHandler) {

    }

    public URI taosGoldenUriTest() {
        return URI.create("http://127.0.0.1:8011/ts");
    }

    public String pointInfos2Keys(List<PointInfo> entity) {
        return entity.stream().map(PointInfo::getPointKey).collect(Collectors.joining(","));
    }

    public List<StationInfoHour> getStationinfoByHour(Date hour) {
        QueryWrapper<StationInfoHour> wrapper = new QueryWrapper<>();
        wrapper.eq("record_date", hour);
        return stationInfoHourService.list(wrapper);
    }

    public List<StationInfoHour> getStationinfoByHour(Date hour, List<PointInfo> entity) {
        List<StationInfoHour> byDate = getStationinfoByHour(hour);
        if (CollUtil.isEmpty(byDate)) {
            entity.forEach(pi -> {
                StationInfoHour day = new StationInfoHour();
                day.setStationId(pi.getStationId());
                day.setRecordDate(hour);
                byDate.add(day);
            });
        }
        return byDate;
    }

    public List<StationInfoDay> getStationinfoByDate(Date date) {
        QueryWrapper<StationInfoDay> wrapper = new QueryWrapper<>();
        wrapper.eq("record_date", date);
        return stationInfoDayService.list(wrapper);
    }

    public List<StationInfoMin> getStationinfoByMin(Date date) {
        QueryWrapper<StationInfoMin> wrapper = new QueryWrapper<>();
        wrapper.eq("record_date", date);
        return stationInfoMinService.list(wrapper);
    }

    public List<StationInfoMin> getStationinfoByMin(Date date, List<PointInfo> entity) {
        List<StationInfoMin> byDate = getStationinfoByMin(date);
        if (CollUtil.isEmpty(byDate)) {
            entity.forEach(pi -> {
                StationInfoMin day = new StationInfoMin();
                day.setStationId(pi.getStationId());
                day.setRecordDate(date);
                byDate.add(day);
            });
        }
        return byDate;
    }


    public StationInfoDay getStationinfoByDate(Date date, String stId) {
        QueryWrapper<StationInfoDay> wrapper = new QueryWrapper<>();
        wrapper.eq("record_date", date).eq("station_id", stId);
        List<StationInfoDay> list = stationInfoDayService.list(wrapper);
        StationInfoDay day;
        if (CollUtil.isEmpty(list)) {
            day = new StationInfoDay();
            day.setStationId(stId);
            day.setRecordDate(date);
        } else {
            day = list.get(0);
        }
        return day;
    }

    public List<StationInfoDay> getStationinfoByDate(Date date, List<PointInfo> entity) {
        QueryWrapper<StationInfoDay> wrapper = new QueryWrapper<>();
        wrapper.eq("record_date", date);
        List<StationInfoDay> list = stationInfoDayService.list(wrapper);
        if (CollUtil.isEmpty(list)) {
            entity.forEach(pi -> {
                StationInfoDay day = new StationInfoDay();
                day.setStationId(pi.getStationId());
                day.setRecordDate(date);
                list.add(day);
            });
        }
        return list;
    }

    public List<StationInfoDay> getStationinfoByDate2(Date date, List<PointInfo> entity) {
        QueryWrapper<StationInfoDay> wrapper = new QueryWrapper<>();
        List<String> sts = entity.stream().map(PointInfo::getStationId).collect(Collectors.toList());
        wrapper.eq("record_date", date).in("station_id", sts);
        List<StationInfoDay> list = stationInfoDayService.list(wrapper);
        if (CollUtil.isEmpty(list)) {
            entity.forEach(pi -> {
                StationInfoDay day = new StationInfoDay();
                day.setStationId(pi.getStationId());
                day.setRecordDate(date);
                list.add(day);
            });
        }
        return list;
    }

    public List<LineInfoDay> getLineinfoByDate(Date date) {
        QueryWrapper<LineInfoDay> wrapper = new QueryWrapper<>();
        wrapper.eq("record_date", date);
        return lineInfoDayService.list(wrapper);
    }

    public List<LineInfoDay> getLineinfoByDate(Date date, String stId) {
        QueryWrapper<LineInfoDay> wrapper = new QueryWrapper<>();
        wrapper.eq("record_date", date).eq("station_id", stId);
        return lineInfoDayService.list(wrapper);
    }

    public List<LineInfoDay> getLineinfoByDate(Date date, List<PointInfo> entity) {
        QueryWrapper<LineInfoDay> wrapper = new QueryWrapper<>();
        wrapper.eq("record_date", date);
        List<LineInfoDay> list = lineInfoDayService.list(wrapper);
        if (CollUtil.isEmpty(list)) {
            entity.forEach(pi -> {
                LineInfoDay day = new LineInfoDay();
                day.setStationId(pi.getStationId());
                day.setProjectId(pi.getProjectId());
                day.setLineId(pi.getLineId());
                day.setRecordDate(date);
                list.add(day);
            });
        }
        return list;
    }

    public List<LineInfoDay> getLineinfoByDate2(Date date, List<PointInfo> entity) {
        QueryWrapper<LineInfoDay> wrapper = new QueryWrapper<>();
        List<String> lines = entity.stream().map(PointInfo::getLineId).collect(Collectors.toList());
        wrapper.eq("record_date", date).in("line_id", lines);
        List<LineInfoDay> list = lineInfoDayService.list(wrapper);
        if (CollUtil.isEmpty(list)) {
            entity.forEach(pi -> {
                LineInfoDay day = new LineInfoDay();
                day.setStationId(pi.getStationId());
                day.setProjectId(pi.getProjectId());
                day.setLineId(pi.getLineId());
                day.setRecordDate(date);
                list.add(day);
            });
        }
        return list;
    }

    public URI taosUri() {
        return URI.create("http://172.16.12.101:8012/ts");
    }

    public URI goldenUri() {
        return URI.create("http://172.16.12.103:8011/ts");
    }

    public Map<String, String> getEntityMap(String uniformCode, String institutionType) {
        PointInfo pi = new PointInfo();
        pi.setUniformCode(uniformCode);
        pi.setInstitutionType(institutionType);
        List<PointInfo> entity = pointService.getByEntity(pi);
        switch (institutionType) {
            case "turbine":
            case "state":
                return entity.stream().collect(Collectors.toMap(PointInfo::getTurbineId, PointInfo::getPointKey));
            case "station":
                return entity.stream().collect(Collectors.toMap(PointInfo::getStationId, PointInfo::getPointKey));
        }
        return new HashMap<>();
    }

    public Map<String, TurbineInfoDay> getTurbineinfoMap(Date date, List<PointInfo> entity) {
        QueryWrapper<TurbineInfoDay> wrapper = new QueryWrapper<>();
        wrapper.eq("record_date", date);
        List<TurbineInfoDay> list = turbineInfoDayService.list(wrapper);
        if (list.isEmpty()) {
            entity.forEach(pi -> {
                TurbineInfoDay day = new TurbineInfoDay();
                day.setStationId(pi.getStationId());
                day.setProjectId(pi.getProjectId());
                day.setLineId(pi.getLineId());
                day.setTurbineId(pi.getTurbineId());
                day.setRecordDate(date);
                list.add(day);
            });
        }
        return list.stream().collect(Collectors.toMap(TurbineInfoDay::getTurbineId, Function.identity()));
    }

    public List<PointInfo> getEntity(String uniformCode, String institutionType) {
        PointInfo pi = new PointInfo();
        pi.setUniformCode(uniformCode);
        pi.setInstitutionType(institutionType);
        return pointService.getByEntity(pi);
    }

    public List<PointInfo> getEntityByUis(String uniformCode, String institutionType, String stId) {
        PointInfo pi = new PointInfo();
        pi.setUniformCode(uniformCode);
        pi.setInstitutionType(institutionType);
        pi.setStationId(stId);
        return pointService.getByEntity(pi);
    }

    public Map<String, Double> getTurbinePowerLoss(Double rfdl, PointInfo piZt, List<PointData> fsList, List<PointData> glList) {
        if (rfdl == null) rfdl = 0.0;
        String tbId = piZt.getTurbineId();
        //        Map<Double, Long> collect = piZt.getPointDatas().stream().collect(Collectors.groupingBy(PointData::getValue, Collectors.counting()));
        double sumfs = fsList.stream().mapToDouble(PointData::getValue).sum();
//        double xs = 1;
//        if (rfdl > 0 && sum1 > 0) {
//            xs = rfdl / (sum1 / 240);
//        }
        //        double sum2 = fsList.stream().mapToDouble(pd -> {
        //            Double v = CalcCache.fitcoef.get(tbId).get(pd.getValue());
        //            if (v == null) v = 0.0;
        //            return v;
        //        }).sum();
        //        sum2=sum2/240;

        List<PointData> collectZt = piZt.getPointDatas();
        double jxss = 0, sdtj = 0, gzss = 0, djss = 0, xnss = 0, fdjcl = 0, xdjcl = 0, xdtj = 0;
        Map<String, Double> map = new HashMap<>();
        if (Math.abs(collectZt.size() - fsList.size()) < 9 && Math.abs(fsList.size() - glList.size()) < 9) {
            int min = Math.min(collectZt.size(), Math.min(fsList.size(), glList.size()));
            for (int i = 0; i < min; i++) {
                Double v = CalcCache.fitcoef.get(tbId).get(fsList.get(i).getValue());
                if (v == null) v = 0.0;
                v = v - glList.get(i).getValue();
                switch ((int) collectZt.get(i).getValue()) {
                    //计划检修损失：
                    case 6:
                        //检修
                        jxss += v;
                        break;
                    case 1:
                        //手动停机
                        sdtj += v;
                        break;
                    //非计划检修损失：
                    case 4:
                        //故障
                        gzss += v;
                        break;
                    case 0:
                        //待机
                        djss += v;
                        break;
                    //性能损失：
                    case 2:
                        //性能
                        xnss += v;
                        break;
                    case 3:
                        //发电降出力
                        fdjcl += v;
                        break;
                    //限电损失：
                    case 8:
                        //限电降出力
                        xdjcl += v;
                        break;
                    case 9:
                        //限电停机
                        xdtj += v;
                        break;
                }
            }
        }
        if (jxss > 30000) jxss = 0;
        if (sdtj > 30000) sdtj = 0;
        if (gzss > 30000) gzss = 0;
        if (djss > 30000) djss = 0;
        if (xnss > 30000) xnss = 0;
        if (fdjcl > 30000) fdjcl = 0;
        if (xdjcl > 30000) xdjcl = 0;
        if (xdtj > 30000) xdtj = 0;
        //15秒*60分钟
        map.put("jxss", jxss > 0 ? jxss / 240 : 0);
        map.put("sdtj", sdtj > 0 ? sdtj / 240 : 0);
        map.put("gzss", gzss > 0 ? gzss / 240 : 0);
        map.put("djss", djss > 0 ? djss / 240 : 0);
        map.put("xnss", xnss > 0 ? xnss / 240 : 0);
        map.put("fdjcl", fdjcl > 0 ? fdjcl / 240 : 0);
        map.put("xdjcl", xdjcl > 0 ? xdjcl / 240 : 0);
        map.put("xdtj", xdtj > 0 ? xdtj / 240 : 0);

        double v = map.get("jxss") + map.get("sdtj") + map.get("gzss") + map.get("djss") + map.get("xnss") + map.get("fdjcl") + map.get("xdjcl") + map.get("xdtj");
        System.out.println(piZt.getTurbineId() + "，日发" + rfdl + "，损失" + v + ",风速和" + sumfs / 240);
        return map;
    }

    public void calcAQTS(Date date) {
        QueryWrapper<StationInfoDay> wrapper = new QueryWrapper<>();
        wrapper.select("min(record_date) record_date");
        StationInfoDay one = stationInfoDayService.getOne(wrapper);
        wrapper = new QueryWrapper<>();
        wrapper.eq("record_date", one.getRecordDate());
        //最早时间的列表
        List<StationInfoDay> list = stationInfoDayService.list(wrapper);
        List<StationInfoDay> today = getStationinfoByDate(date);
        if (today.isEmpty()) {
            for (StationInfoDay infoDay : list) {
                StationInfoDay day = new StationInfoDay();
                day.setStationId(infoDay.getStationId());
                day.setRecordDate(date);
                day.setAqts(infoDay.getAqts() + (int) DateUtil.betweenDay(infoDay.getRecordDate(), date, true));
                today.add(day);
            }
        } else {
            Map<String, StationInfoDay> collect = list.stream().collect(Collectors.toMap(StationInfoDay::getStationId, Function.identity()));
            for (StationInfoDay day : today) {
                StationInfoDay day1 = collect.get(day.getStationId());
                day.setAqts(day1.getAqts() + (int) DateUtil.betweenDay(day1.getRecordDate(), date, true));
            }
        }
        stationInfoDayService.saveOrUpdateBatch(today);
    }

    public void calcLineSwGWCyDl(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);

        List<StationInfoDay> stationInfos = getStationinfoByDate(time0);
        Map<String, StationInfoDay> stationMap = stationInfos.stream().collect(Collectors.toMap(StationInfoDay::getStationId, Function.identity()));
        List<LineInfoDay> lineInfos = getLineinfoByDate(time0);
        StationInfoDay stationInfo;
        for (LineInfoDay lineInfo : lineInfos) {
            stationInfo = stationMap.get(lineInfo.getStationId());
            double xs = (double) lineInfo.getRfdl() / stationInfo.getRfdl();
            lineInfo.setSwdl(xs * stationInfo.getSwdl());
            lineInfo.setGwdl(xs * stationInfo.getGwdl());
            lineInfo.setCydl(xs * stationInfo.getCydl());
            lineInfo.setZyb(xs * stationInfo.getZyb());
        }
        lineInfoDayService.saveOrUpdateBatch(lineInfos);
    }

    public void calcLineSwGWCyDlSameDay() {
        //date当天零点
        DateTime time0 = DateUtil.beginOfDay(DateUtil.date());

        List<StationInfoDay> stationInfos = getStationinfoByDate(time0);
        Map<String, StationInfoDay> stationMap = stationInfos.stream().collect(Collectors.toMap(StationInfoDay::getStationId, Function.identity()));
        List<LineInfoDay> lineInfos = getLineinfoByDate(time0);
        StationInfoDay stationInfo;
        for (LineInfoDay lineInfo : lineInfos) {
            stationInfo = stationMap.get(lineInfo.getStationId());
            double xs = (double) lineInfo.getRfdl() / stationInfo.getRfdl();
            lineInfo.setSwdl(xs * stationInfo.getSwdl());
            lineInfo.setGwdl(xs * stationInfo.getGwdl());
            lineInfo.setCydl(xs * stationInfo.getCydl());
            lineInfo.setZyb(xs * stationInfo.getZyb());
        }
        lineInfoDayService.saveOrUpdateBatch(lineInfos);
    }

    public void calcLineSwGWCyDl(Date date, String stId) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);

        StationInfoDay sti = getStationinfoByDate(time0, stId);
        List<LineInfoDay> lineInfos = getLineinfoByDate(time0, stId);
        for (LineInfoDay lineInfo : lineInfos) {
            double xs = (double) lineInfo.getRfdl() / sti.getRfdl();
            lineInfo.setSwdl(xs * sti.getSwdl());
            lineInfo.setGwdl(xs * sti.getGwdl());
            lineInfo.setCydl(xs * sti.getCydl());
            lineInfo.setZyb(xs * sti.getZyb());
        }
        lineInfoDayService.saveOrUpdateBatch(lineInfos);
    }

    public void calcStationZhcyRfDl(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);

        QueryWrapper<LineInfoDay> wrapper = new QueryWrapper<>();
        wrapper.select("sum(rfdl) rfdl,station_id").eq("record_date", time0).groupBy("station_id");
        List<LineInfoDay> list = lineInfoDayService.list(wrapper);
        Map<String, Integer> rfdlMap = list.stream().collect(Collectors.toMap(LineInfoDay::getStationId, LineInfoDay::getRfdl));
        List<StationInfoDay> byDate = getStationinfoByDate(time0);

        for (StationInfoDay day : byDate) {
            day.setRfdl(rfdlMap.get(day.getStationId()));
            day.setZhcydl(day.getRfdl() + day.getGwdl() - day.getSwdl());
            day.setCydl(day.getZhcydl() - day.getZyb());
        }
        stationInfoDayService.saveOrUpdateBatch(byDate);
    }

    public void calcStationRjhfdl(Date month) {
        DateTime begin = DateUtil.beginOfMonth(month);
        DateTime end = DateUtil.endOfMonth(month);
        DateTime beginTq = DateUtil.offset(begin, DateField.YEAR, -1);
        DateTime endTq = DateUtil.offset(end, DateField.YEAR, -1);

        QueryWrapper<StationInfoDay> wrapper = new QueryWrapper<>();
        wrapper.lambda().between(StationInfoDay::getRecordDate, begin, end);
        List<StationInfoDay> days = stationInfoDayService.list(wrapper);
        Map<String, Map<String, StationInfoDay>> dayMap = new HashMap<>();
        if (CollUtil.isNotEmpty(days)) {
            dayMap = days.stream().collect(Collectors.groupingBy(StationInfoDay::getStationId,
                    Collectors.toMap(sid -> DateUtil.date(sid.getRecordDate()).toString(), Function.identity())));
        }
        wrapper.clear();
        wrapper.lambda().between(StationInfoDay::getRecordDate, beginTq, endTq);
        List<StationInfoDay> sids = stationInfoDayService.list(wrapper);
        Map<String, List<StationInfoDay>> sidMap;
        if (CollUtil.isNotEmpty(sids)) {
            sidMap = sids.stream().collect(Collectors.groupingBy(StationInfoDay::getStationId));
        } else {
            sidMap = null;
        }
        QueryWrapper<ProBasicProjectPlan> wrapperPlan = new QueryWrapper<>();
        wrapperPlan.lambda().eq(ProBasicProjectPlan::getYear, String.valueOf(begin.year()))
                .eq(ProBasicProjectPlan::getMonth, String.valueOf(begin.month() + 1));
        List<ProBasicProjectPlan> plantList = proBasicProjectPlanService.list(wrapperPlan);

        for (ProBasicProjectPlan plan : plantList) {
            String stId = plan.getWindpowerstationId();
            Map<String, StationInfoDay> daym = dayMap.get(stId);
            if (daym == null) daym = new HashMap<>();
            if (sidMap == null) {
                for (StationInfoDay day : daym.values()) {
                    day.setJhfdl(plan.getGeneratingCapacity() / daym.size());
                }
            } else {
                //去年月发电量
                List<StationInfoDay> sidList = sidMap.get(stId);
                double rfdlSum = sidList.stream().mapToDouble(StationInfoDay::getRfdl).sum();
                double v = plan.getGeneratingCapacity() / rfdlSum;
                for (StationInfoDay sid : sidList) {
                    DateTime time = DateUtil.offset(sid.getRecordDate(), DateField.YEAR, 1);
                    StationInfoDay day = daym.get(time.toString());
                    if (day == null) {
                        day = new StationInfoDay();
                        day.setStationId(stId);
                        day.setRecordDate(time);
                        days.add(day);
                    }
                    day.setJhfdl(v * sid.getRfdl());
                }
            }

        }
        stationInfoDayService.saveOrUpdateBatch(days);
    }

    public void calcStationZhcyRfDlSameDay() {
        //date当天零点
        DateTime time0 = DateUtil.beginOfDay(DateUtil.date());

        QueryWrapper<LineInfoDay> wrapper = new QueryWrapper<>();
        wrapper.select("sum(rfdl) rfdl,station_id").eq("record_date", time0).groupBy("station_id");
        List<LineInfoDay> list = lineInfoDayService.list(wrapper);
        Map<String, Integer> rfdlMap = list.stream().collect(Collectors.toMap(LineInfoDay::getStationId, LineInfoDay::getRfdl));
        List<StationInfoDay> byDate = getStationinfoByDate(time0);

        for (StationInfoDay day : byDate) {
            day.setRfdl(rfdlMap.get(day.getStationId()));
            day.setZhcydl(day.getRfdl() + day.getGwdl() - day.getSwdl());
            day.setCydl(day.getZhcydl() - day.getZyb());
        }
        stationInfoDayService.saveOrUpdateBatch(byDate);
    }

    public void calcStationZhcyRfDl(Date date, String stId) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);

        QueryWrapper<LineInfoDay> wrapper = new QueryWrapper<>();
        wrapper.select("sum(rfdl) rfdl,station_id").eq("record_date", time0)
                .eq("station_id", stId).groupBy("station_id");
        List<LineInfoDay> list = lineInfoDayService.list(wrapper);
        Map<String, Integer> rfdlMap = list.stream().collect(Collectors.toMap(LineInfoDay::getStationId, LineInfoDay::getRfdl));
        StationInfoDay day = getStationinfoByDate(time0, stId);

        day.setRfdl(rfdlMap.get(day.getStationId()));
        day.setZhcydl(day.getRfdl() + day.getGwdl() - day.getSwdl());
        day.setCydl(day.getZhcydl() - day.getZyb());
        stationInfoDayService.saveOrUpdateBatch(Collections.singleton(day));
    }

    public void calcStationSwGwCyRdl(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);

        List<PointInfo> swdlEt = getEntity("Z-ZXYG-CX", "meter");
        List<PointInfo> gwdlEt = getEntity("Z-FXYG-CX", "meter");
        List<PointInfo> cydlEt = getEntity("Z-ZXYG-ZYB", "meter");
        getZeroNextData(swdlEt, time0, time);
        getZeroNextData(gwdlEt, time0, time);
        getZeroNextData(cydlEt, time0, time);

        Map<String, PointInfo> swdlMap = swdlEt.stream().collect(Collectors.toMap(PointInfo::getStationId, Function.identity()));
        Map<String, PointInfo> gwdlMap = gwdlEt.stream().collect(Collectors.toMap(PointInfo::getStationId, Function.identity()));
        Map<String, PointInfo> cydlMap = cydlEt.stream().collect(Collectors.toMap(PointInfo::getStationId, Function.identity()));

        List<StationInfoDay> byDate = getStationinfoByDate(time0, swdlEt);
        String stId;
        PointInfo swdlPi, gwdlPi, cydlPi;
        for (StationInfoDay info : byDate) {
            stId = info.getStationId();
            swdlPi = swdlMap.get(stId);
            gwdlPi = gwdlMap.get(stId);
            cydlPi = cydlMap.get(stId);
            int swdl = (int) ((swdlPi.getPointDatas().get(1).getValue() - swdlPi.getPointDatas().get(0).getValue()) * swdlPi.getCoef());
            int gwdl = (int) ((gwdlPi.getPointDatas().get(1).getValue() - gwdlPi.getPointDatas().get(0).getValue()) * gwdlPi.getCoef());
            int cydl = (int) ((cydlPi.getPointDatas().get(1).getValue() - cydlPi.getPointDatas().get(0).getValue()) * cydlPi.getCoef());
            if (swdl < 0 || swdl > 6000000) swdl = 0;
            if (gwdl < 0 || gwdl > 6000000) gwdl = 0;
            if (cydl < 0 || cydl > 6000000) cydl = 0;
            info.setSwdl(swdl);
            info.setGwdl(gwdl);
            info.setZyb(cydl);
        }
        stationInfoDayService.saveOrUpdateBatch(byDate);
    }

    public void calcStationSwGwCyDlSameDay() {
        //date当天零点
        DateTime time0 = DateUtil.beginOfDay(DateUtil.date());

        List<PointInfo> swdlEt = getEntity("Z-ZXYG-CX", "meter");
        List<PointInfo> gwdlEt = getEntity("Z-FXYG-CX", "meter");
        List<PointInfo> cydlEt = getEntity("Z-ZXYG-ZYB", "meter");
        getZeroNextData(swdlEt, time0);
        getZeroNextData(gwdlEt, time0);
        getZeroNextData(cydlEt, time0);

        Map<String, PointInfo> swdlMap = swdlEt.stream().collect(Collectors.toMap(PointInfo::getStationId, Function.identity()));
        Map<String, PointInfo> gwdlMap = gwdlEt.stream().collect(Collectors.toMap(PointInfo::getStationId, Function.identity()));
        Map<String, PointInfo> cydlMap = cydlEt.stream().collect(Collectors.toMap(PointInfo::getStationId, Function.identity()));

        List<StationInfoDay> byDate = getStationinfoByDate(time0, swdlEt);
        String stId;
        PointInfo swdlPi, gwdlPi, cydlPi;
        for (StationInfoDay info : byDate) {
            stId = info.getStationId();
            swdlPi = swdlMap.get(stId);
            gwdlPi = gwdlMap.get(stId);
            cydlPi = cydlMap.get(stId);
            int swdl = (int) ((swdlPi.getPointDatas().get(1).getValue() - swdlPi.getPointDatas().get(0).getValue()) * swdlPi.getCoef());
            int gwdl = (int) ((gwdlPi.getPointDatas().get(1).getValue() - gwdlPi.getPointDatas().get(0).getValue()) * gwdlPi.getCoef());
            int cydl = (int) ((cydlPi.getPointDatas().get(1).getValue() - cydlPi.getPointDatas().get(0).getValue()) * cydlPi.getCoef());
            if (swdl < 0 || swdl > 6000000) swdl = 0;
            if (gwdl < 0 || gwdl > 6000000) gwdl = 0;
            if (cydl < 0 || cydl > 6000000) cydl = 0;
            info.setSwdl(swdl);
            info.setGwdl(gwdl);
            info.setZyb(cydl);
        }
        stationInfoDayService.saveOrUpdateBatch(byDate);
    }

    public void calcStationSwGwCyRdl(Date date, String stId) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);

        List<PointInfo> swdlEt = getEntityByUis("Z-ZXYG-CX", "meter", stId);
        List<PointInfo> gwdlEt = getEntityByUis("Z-FXYG-CX", "meter", stId);
        List<PointInfo> cydlEt = getEntityByUis("Z-ZXYG-ZYB", "meter", stId);
        getZeroNextData(swdlEt, time0, time);
        getZeroNextData(gwdlEt, time0, time);
        getZeroNextData(cydlEt, time0, time);

        List<StationInfoDay> byDate = getStationinfoByDate2(time0, swdlEt);
        StationInfoDay info = byDate.get(0);
        PointInfo swdlPi = swdlEt.get(0);
        PointInfo gwdlPi = gwdlEt.get(0);
        PointInfo cydlPi = cydlEt.get(0);
        int swdl = (int) ((swdlPi.getPointDatas().get(1).getValue() - swdlPi.getPointDatas().get(0).getValue()) * swdlPi.getCoef());
        int gwdl = (int) ((gwdlPi.getPointDatas().get(1).getValue() - gwdlPi.getPointDatas().get(0).getValue()) * gwdlPi.getCoef());
        int cydl = (int) ((cydlPi.getPointDatas().get(1).getValue() - cydlPi.getPointDatas().get(0).getValue()) * cydlPi.getCoef());
        if (stId.equals("GJNY_SXGS_JSL_FDC_STA") && time0.before(DateUtil.parse("2024-07-08"))) {
            swdl = swdl * 100;
            gwdl = gwdl * 100;
        }
        if (swdl < 0 || swdl > 6000000) swdl = 0;
        if (gwdl < 0 || gwdl > 6000000) gwdl = 0;
        if (cydl < 0 || cydl > 6000000) cydl = 0;
        info.setSwdl(swdl);
        info.setGwdl(gwdl);
        info.setZyb(cydl);
        stationInfoDayService.saveOrUpdateBatch(byDate);
    }

    public void SwdlRepair(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);
        List<PointInfo> swdlEt = getEntity("Z-ZXYG-CX", "meter");
        Map<String, PointInfo> map = swdlEt.stream().collect(Collectors.toMap(PointInfo::getStationId, Function.identity()));
        List<StationInfoDay> list = getStationinfoByDate(time0);
        Map<String, StationInfoDay> dayMap = list.stream().collect(Collectors.toMap(StationInfoDay::getStationId, Function.identity()));
        CalcCache.swdlTime.forEach((key, ts) -> {
            int swdl = 0;
            PointData data1, data0;
            double ll = (double) (time.getTime() - ts) / 23 * 60 * 60 * 1000;
            if (ts > 0 && (ll > 23 && ll < 25)) {
                StationInfoDay day = dayMap.get(key);
                PointInfo info = map.get(key);
                List<PointData> raw1 = adapter.getHistoryRaw(goldenUri(), key, time.getTime(), DateUtil.offsetMinute(time, 6).getTime());
                if (CollUtil.isEmpty(raw1)) {
                    Map<String, PointData> section = adapter.getHistorySection(goldenUri(), key, time.getTime() + 1000);
                    data1 = section.get(key);
                } else {
                    data1 = raw1.get(0);
                }
                Map<String, PointData> section = adapter.getHistorySection(goldenUri(), key, ts + 1000);
                data0 = section.get(key);
                swdl = (int) ((data1.getValue() - data0.getValue()) * info.getCoef());
                if (swdl > day.getRfdl()) {
                    List<PointData> rawl1 = adapter.getHistoryRaw(goldenUri(), key, DateUtil.offsetMinute(time, -60).getTime(), time.getTime());
                    for (int i = rawl1.size() - 1; i >= 0; i--) {
                        swdl = (int) ((rawl1.get(i).getValue() - data0.getValue()) * info.getCoef());
                        if (swdl <= day.getRfdl()) {
                            day.setSwdl(swdl);
                            day.setZhcydl(day.getRfdl() + day.getGwdl() - day.getSwdl());
                            day.setCydl(day.getZhcydl() - day.getZyb());
                            CalcCache.swdlTime.put(info.getPointKey(), rawl1.get(i).getTs());
                            break;
                        }
                    }
                } else {
                    day.setSwdl(swdl);
                    day.setZhcydl(day.getRfdl() + day.getGwdl() - day.getSwdl());
                    day.setCydl(day.getZhcydl() - day.getZyb());
                }
            }
        });
        for (StationInfoDay day : list) {
            int swdl = 0;
            if (day.getSwdl() > day.getRfdl()) {
                PointInfo info = map.get(day.getStationId());
                Long l = CalcCache.swdlTime.get(info.getPointKey());
                PointData data0;
                if (l == null || l == 0) {
                    List<PointData> raw0 = adapter.getHistoryRaw(goldenUri(), info.getPointKey(), time0.getTime(), DateUtil.offsetMinute(time0, 6).getTime());
                    if (CollUtil.isEmpty(raw0)) {
                        Map<String, PointData> section = adapter.getHistorySection(goldenUri(), info.getPointKey(), time0.getTime() + 1000);
                        data0 = section.get(info.getPointKey());
                    } else {
                        data0 = raw0.get(0);
                    }
                } else {
                    double ll = (double) (time.getTime() - l) / 23 * 60 * 60 * 1000;
                    if (ll > 23 && ll < 25) {
                        Map<String, PointData> section = adapter.getHistorySection(goldenUri(), info.getPointKey(), l + 1000);
                        data0 = section.get(info.getPointKey());
                    } else {
                        continue;
                    }
                }
                List<PointData> raw1 = adapter.getHistoryRaw(goldenUri(), info.getPointKey(), DateUtil.offsetMinute(time, -60).getTime(), time.getTime());
                for (int i = raw1.size() - 1; i >= 0; i--) {
                    swdl = (int) ((raw1.get(i).getValue() - data0.getValue()) * info.getCoef());
                    if (swdl <= day.getRfdl()) {
                        day.setSwdl(swdl);
                        day.setZhcydl(day.getRfdl() + day.getGwdl() - day.getSwdl());
                        day.setCydl(day.getZhcydl() - day.getZyb());
                        CalcCache.swdlTime.put(info.getPointKey(), raw1.get(i).getTs());
                        break;
                    }
                }
            }
        }
        stationInfoDayService.saveOrUpdateBatch(list);
        stringRedisTemplate.opsForValue().set("swdlTime", JSON.toJSONString(CalcCache.swdlTime));
    }

    public void getZeroNextData(List<PointInfo> entity, Date start0, Date start) {
        List<PointData> snap0, snap;
        for (PointInfo info : entity) {
            PointData data0, data;
            List<PointData> datas = new ArrayList<>();
            snap0 = adapter.getHistoryRaw(goldenUri(), info.getPointKey(), start0.getTime(), DateUtil.offsetMinute(start0, 6).getTime());
            if (CollUtil.isEmpty(snap0)) {
                Map<String, PointData> section = adapter.getHistorySection(goldenUri(), info.getPointKey(), start0.getTime());
                snap0 = new ArrayList<>(section.values());
            }
            snap = adapter.getHistoryRaw(goldenUri(), info.getPointKey(), start.getTime(), DateUtil.offsetMinute(start, 6).getTime());
            if (CollUtil.isEmpty(snap)) {
                Map<String, PointData> section = adapter.getHistorySection(goldenUri(), info.getPointKey(), start.getTime());
                snap = new ArrayList<>(section.values());
            }
            if (CollUtil.isEmpty(snap0) || CollUtil.isEmpty(snap)) {
                data0 = new PointData();
                data = new PointData();
            } else {
                data0 = snap0.get(0);
                data = snap.get(0);
            }
            datas.add(data0);
            datas.add(data);
            info.setPointDatas(datas);
        }
    }

    public void getZeroNextData(List<PointInfo> entity, Date start0) {
        String keys = entity.stream().map(PointInfo::getPointKey).collect(Collectors.joining(","));
        Map<String, PointData> latest = adapter.getLatest(goldenUri(), keys);
        List<PointData> snap0;
        for (PointInfo info : entity) {
            PointData data0, data;
            List<PointData> datas = new ArrayList<>();
            snap0 = adapter.getHistoryRaw(goldenUri(), info.getPointKey(), start0.getTime(), DateUtil.offsetMinute(start0, 90).getTime());
            if (CollUtil.isEmpty(snap0)) {
                Map<String, PointData> section = adapter.getHistorySection(goldenUri(), info.getPointKey(), start0.getTime());
                snap0 = new ArrayList<>(section.values());
            }
            data = latest.get(info.getPointKey());
            if (CollUtil.isEmpty(snap0) || data == null) {
                data0 = new PointData();
                data = new PointData();
            } else {
                data0 = snap0.get(0);
            }
            datas.add(data0);
            datas.add(data);
            info.setPointDatas(datas);
        }
    }

    public void calcStationHourRFDL(Date hour) {
        PointInfo pointInfo = new PointInfo();
        pointInfo.setInstitutionType("station");
        pointInfo.setUniformCode("RFDLSYZ");
        List<PointInfo> entity = pointService.getByEntity(pointInfo);
        Map<String, PointData> section = adapter.getHistorySection(taosUri(), pointInfos2Keys(entity), hour.getTime());
        List<StationInfoHour> byHours = getStationinfoByHour(hour);
        if (byHours.isEmpty()) {
            for (PointInfo point : entity) {
                StationInfoHour info = new StationInfoHour();
                info.setStationId(point.getStationId());
                info.setRecordDate(DateUtil.beginOfHour(hour));
                info.setRfdl(section.get(point.getPointKey()).getValue());
                byHours.add(info);
            }
        } else {
            Map<String, String> collect = entity.stream().collect(Collectors.toMap(PointInfo::getStationId, PointInfo::getPointKey));
            for (StationInfoHour byHour : byHours) {
                byHour.setRfdl(section.get(collect.get(byHour.getStationId())).getValue());
            }
        }
        stationInfoHourService.saveOrUpdateBatch(byHours);
    }

    public void calcLineRfdl(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);

        List<PointInfo> entity = getEntity("Z-ZXYG-JX", "meter");
        entity = entity.stream().filter(e -> !"".equals(e.getProjectId())).collect(Collectors.toList());
        getZeroNextData(entity, time0, time);
        Map<String, PointInfo> swdlMap = entity.stream().collect(Collectors.toMap(PointInfo::getLineId, Function.identity()));
        List<LineInfoDay> byDate = getLineinfoByDate(time0, entity);
        String lineId;
        PointInfo swdlPi;
        int v = 0;
        for (LineInfoDay day : byDate) {
            lineId = day.getLineId();
            swdlPi = swdlMap.get(lineId);
            v = (int) ((swdlPi.getPointDatas().get(1).getValue() - swdlPi.getPointDatas().get(0).getValue()) * swdlPi.getCoef());
            if (v < 0 || v > 30000000) v = 0;
            day.setRfdl(v);
        }
        lineInfoDayService.saveOrUpdateBatch(byDate);
    }

    public void calcTurbineRFDLSameDay() {
        DateTime time = DateUtil.date();
        //date当天零点
        DateTime time0 = DateUtil.beginOfDay(time);

        List<PointInfo> entity = getEntity("AI121", "turbine");
        getZeroNextData(entity, time0, time);
        Map<String, PointInfo> turMap = entity.stream().collect(Collectors.toMap(PointInfo::getTurbineId, Function.identity()));
        Map<String, String> fsMap = getEntityMap("AI066", "turbine");

        Map<String, TurbineInfoDay> byDate = getTurbineinfoMap(time0, entity);

        TurbineInfoDay infoDay;
        PointInfo rfdlPi;
        String turbineId;
        List<TurbineInfoDay> infoDays = new ArrayList<>();
        DoubleStatData stat;
        for (PointInfo info : entity) {
            turbineId = info.getTurbineId();
            infoDay = byDate.get(turbineId);

            rfdlPi = turMap.get(turbineId);
            double v = (rfdlPi.getPointDatas().get(1).getValue() - rfdlPi.getPointDatas().get(0).getValue()) * rfdlPi.getCoef();
            if (v < 0 || v > 1000000) {
                v = 0;
            } else if (v > 30000) {
                v = v / (v % 30000 + 3);
            }
            infoDay.setRfdl(v);
            stat = adapter.getHistoryStat(goldenUri(), fsMap.get(turbineId), time0.getTime(), time.getTime());
            if (stat == null) {
                infoDay.setPjfs(0.0);
            } else {
                infoDay.setPjfs(stat.getAvg().getValue());
            }

            infoDays.add(infoDay);
        }
        turbineInfoDayService.saveOrUpdateBatch(infoDays);
    }

    public void calcTurbine5s2SameDay() {
        DateTime time = DateUtil.date();
        //date当天零点
        DateTime time0 = DateUtil.beginOfDay(time);
        //风速
        List<PointInfo> entityFs = getEntity("AI066", "turbine");
        //功率
        List<PointInfo> entityGl = getEntity("AI114", "turbine");
        //状态
        List<PointInfo> entityZT = getEntity("MXZT", "turbine");
        Map<String, Map<String, PointInfo>> ztMapMapInfos = entityZT.stream().collect(Collectors.groupingBy(PointInfo::getStationId, Collectors.toMap(PointInfo::getTurbineId, Function.identity())));
        Map<String, TurbineInfoDay> dayMap = getTurbineinfoMap(time0, entityFs);
        List<TurbineInfoDay> infoDays = new ArrayList<>();
        Map<String, Map<String, PointInfo>> fsMapMap = entityFs.stream().collect(Collectors.groupingBy(PointInfo::getStationId, Collectors.toMap(PointInfo::getTurbineId, Function.identity())));
        Map<String, Map<String, PointInfo>> glMapMap = entityGl.stream().collect(Collectors.groupingBy(PointInfo::getStationId, Collectors.toMap(PointInfo::getTurbineId, Function.identity())));

        ztMapMapInfos.forEach((stId, ztMapInfo) -> ztMapInfo.forEach((wtId, ztInfo) -> {
            //0 待机，1 手动停机，2 正常发电，3 发电降出力，4 故障，5 故障受累，6 检修，7 检修受累，8 限电降出力，
            // 9 限电停机，10 电网受累，11 环境受累，12 通讯中断，13 设备离线
            TurbineInfoDay infoDay = dayMap.get(wtId);
            PointInfo fspi = fsMapMap.get(stId).get(wtId);
            PointInfo glpi = glMapMap.get(stId).get(wtId);
            getSnapDataByEntity(fspi, time0, time, 15);
            getSnapDataByEntity(glpi, time0, time, 15);
            getSnapDataByEntity(ztInfo, taosUri(), time0, time, 15);
            List<PointData> fsData = fspi.getPointDatas();
            fsData = fsData.stream().peek(pd -> pd.setDoubleValue(NumberUtil.round(pd.getValue() > 25 ? 25.0 : pd.getValue(), 2).doubleValue())).collect(Collectors.toList());
            Map<String, Double> loss = getTurbinePowerLoss(infoDay.getRfdl(), ztInfo, fsData, glpi.getPointDatas());
            infoDay.setJhjxss(loss.get("jxss") + loss.get("sdtj"));
            infoDay.setFjhjxss(loss.get("gzss") + loss.get("djss") + loss.get("fdjcl"));
            infoDay.setXdss(loss.get("xdjcl") + loss.get("xdtj"));
            infoDay.setSlss(0.0);
            infoDay.setDjss(loss.get("djss"));
            infoDay.setGzss(loss.get("gzss"));
            if (infoDay.getRfdl() == 0) {
                infoDay.setXnss(0.0);
            } else {
                infoDay.setXnss(loss.get("xnss"));
            }
            infoDay.setLlfdl(infoDay.getRfdl() + infoDay.getJhjxss() + infoDay.getFjhjxss() + infoDay.getXdss() + infoDay.getSlss() + infoDay.getXnss());
            infoDays.add(infoDay);
        }));
        turbineInfoDayService.saveOrUpdateBatch(infoDays);
    }

    public void calcLineRfdlSameDay() {
        //date当天零点
        DateTime time0 = DateUtil.beginOfDay(DateUtil.date());

        List<PointInfo> entity = getEntity("Z-ZXYG-JX", "meter");
        entity = entity.stream().filter(e -> !"".equals(e.getProjectId())).collect(Collectors.toList());
        getZeroNextData(entity, time0);
        Map<String, PointInfo> rfdlMap = entity.stream().collect(Collectors.toMap(PointInfo::getLineId, Function.identity()));
        List<LineInfoDay> byDate = getLineinfoByDate(time0, entity);

        PointInfo rfdlPi;
        int v;
        for (LineInfoDay day : byDate) {
            rfdlPi = rfdlMap.get(day.getLineId());
            v = (int) ((rfdlPi.getPointDatas().get(1).getValue() - rfdlPi.getPointDatas().get(0).getValue()) * rfdlPi.getCoef());
            if (v < 0 || v > 30000000) v = 0;
            day.setRfdl(v);
        }
        lineInfoDayService.saveOrUpdateBatch(byDate);
    }

    public void calcLineRfdl(Date date, String stId) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);

        List<PointInfo> entity = getEntity("Z-ZXYG-JX", "meter");
        entity = entity.stream().filter(e -> StrUtil.isNotEmpty(e.getProjectId()) && Objects.equals(stId, e.getStationId())).collect(Collectors.toList());
        getZeroNextData(entity, time0, time);
        Map<String, PointInfo> swdlMap = entity.stream().collect(Collectors.toMap(PointInfo::getLineId, Function.identity()));
        List<LineInfoDay> byDate = getLineinfoByDate2(time0, entity);
        String lineId;
        PointInfo swdlPi;
        int v = 0;
        for (LineInfoDay day : byDate) {
            lineId = day.getLineId();
            swdlPi = swdlMap.get(lineId);
            v = (int) ((swdlPi.getPointDatas().get(1).getValue() - swdlPi.getPointDatas().get(0).getValue()) * swdlPi.getCoef());
            if (v < 0 || v > 30000000) v = 0;
            day.setRfdl(v);
        }
        lineInfoDayService.saveOrUpdateBatch(byDate);
    }

    public void calcLineDjlRfdl(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);
        //date当天零点加三分钟
        DateTime time2 = DateUtil.offsetMinute(time, 3);
        //date昨天零点加三分钟
        DateTime time1 = DateUtil.offsetMinute(time0, 3);

        PointInfo pi = new PointInfo();
        pi.setUniformCode("Z-ZXYG-JX");
        pi.setLineId("all");
        List<PointInfo> entity = pointService.getByEntity(pi);
        //        entity = entity.stream().filter(e -> e.getStationId().equals("GJNY_SXGS_ZZ_FDC_STA")).collect(Collectors.toList());
        String keys = pointInfos2Keys(entity);
        Map<String, PointData> latest2 = adapter.getHistorySection(goldenUri(), keys, time2.getTime());
        Map<String, PointData> latest1 = adapter.getHistorySection(goldenUri(), keys, time1.getTime());

        List<LineInfoDay> byDate = getLineinfoByDate(time0);
        Map<String, LineInfoDay> collect = new HashMap<>();
        if (!byDate.isEmpty()) {
            collect = byDate.stream().collect(Collectors.toMap(LineInfoDay::getLineId, Function.identity()));
        }

        List<LineInfoDay> list = new ArrayList<>();
        for (PointInfo info : entity) {
            LineInfoDay day;
            if (byDate.isEmpty()) {
                day = new LineInfoDay();
                day.setStationId(info.getStationId());
                day.setProjectId(info.getProjectId());
                day.setLineId(info.getLineId());
                day.setRecordDate(time0);
            } else {
                day = collect.get(info.getLineId());
            }
            day.setRfdl((int) ((latest2.get(info.getPointKey()).getValue() - latest1.get(info.getPointKey()).getValue()) * info.getCoef()));
            if (day.getRfdl() <= 0 || day.getRfdl() > 30000000) {
                day.setRfdl(0);
            }
            list.add(day);
        }
        lineInfoDayService.saveOrUpdateBatch(list);
    }

    public int test(Date date, String key, int coef) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);
        PointInfo info = new PointInfo();
        info.setPointKey(key);
        getZeroNextData(Collections.singletonList(info), time0, time);
        int swdl = (int) ((info.getPointDatas().get(1).getValue() - info.getPointDatas().get(0).getValue()) * coef);
        return swdl;
    }

    public void calcStationZhcydl(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);

        QueryWrapper<LineInfoDay> wrapper = new QueryWrapper<>();
        wrapper.select("sum(rfdl) rfdl,station_id").eq("record_date", time0).groupBy("station_id");
        List<LineInfoDay> list = lineInfoDayService.list(wrapper);
        List<StationInfoDay> byDate = getStationinfoByDate(time0);
        //        list = list.stream().filter(b -> b.getStationId().equals("GJNY_SXGS_ZZ_FDC_STA")).collect(Collectors.toList());

        Map<String, StationInfoDay> collect = new HashMap<>();
        if (!byDate.isEmpty()) {
            collect = byDate.stream().collect(Collectors.toMap(StationInfoDay::getStationId, Function.identity()));
        }

        StationInfoDay infoDay;
        List<StationInfoDay> infoDays = new ArrayList<>();
        for (LineInfoDay day : list) {
            if (byDate.isEmpty()) {
                infoDay = new StationInfoDay();
                infoDay.setStationId(day.getStationId());
                infoDay.setRecordDate(time0);
            } else {
                infoDay = collect.get(day.getStationId());
            }
            infoDay.setRfdl(day.getRfdl());
            infoDay.setZhcydl(infoDay.getRfdl() + infoDay.getGwdl() - infoDay.getSwdl());
            infoDays.add(infoDay);
        }
        stationInfoDayService.saveOrUpdateBatch(infoDays);
    }

    public void calcStationHourPjglRfdl(Date hour) {
        //hour整点
        DateTime time = DateUtil.beginOfHour(hour);
        //1小时前
        DateTime time0 = DateUtil.offsetHour(time, -1);
        //当天零点
        DateTime rft = DateUtil.beginOfDay(time);

        List<PointInfo> entity = getEntity("Z-ZXYG-JX", "meter");
        //出线
        List<PointInfo> entityCx = getEntity("AGC001", "booster");
        Map<String, PointInfo> statMapCx = getStatDataByEntity(entityCx, goldenUri(), time0, time, PointInfo::getStationId);
        List<StationInfoHour> byHours = getStationinfoByHour(time, entityCx);

        entity = entity.stream().filter(e -> !"".equals(e.getProjectId())).collect(Collectors.toList());
        if (time.getHours() == 0) {
            getSectionDataByEntity(entity, goldenUri(), DateUtil.offsetDay(rft, -1), time);
        } else {
            getSectionDataByEntity(entity, goldenUri(), rft, time);
        }
        Map<String, List<PointInfo>> stMap = entity.stream().collect(Collectors.groupingBy(PointInfo::getStationId));
        for (StationInfoHour byHour : byHours) {
            List<PointInfo> pis = stMap.get(byHour.getStationId());
            double dl = 0, v = 0;
            List<PointData> pds;
            for (PointInfo pi : pis) {
                pds = pi.getPointDatas();
                if (pds.size() > 1) v = (pds.get(1).getValue() - pds.get(0).getValue()) * pi.getCoef();
                dl += (v < 0 || v > 30000000) ? 0 : v;
            }
            byHour.setRfdl(dl);

            PointInfo info = statMapCx.get(byHour.getStationId());
            double v1 = info.getPointDatas().get(0).getValue();
            byHour.setPjgl(v1 <= 0 ? 0 : v1 * info.getCoef());
        }

        stationInfoHourService.saveOrUpdateBatch(byHours);
    }

    public void calcStationMinRfdl(Date hour) {
        //hour整分钟
        DateTime time = DateUtil.beginOfMinute(hour);
        //当天零点
        DateTime rft = DateUtil.beginOfDay(time);
        List<PointInfo> entity = getEntity("Z-ZXYG-JX", "meter");
        entity = entity.stream().filter(e -> !"".equals(e.getProjectId())).collect(Collectors.toList());
        List<StationInfoMin> byHours = getStationinfoByMin(time, entity);
        getSectionDataByEntity(entity, goldenUri(), rft, time);
        Map<String, List<PointInfo>> stMap = entity.stream().collect(Collectors.groupingBy(PointInfo::getStationId));
        for (StationInfoMin byHour : byHours) {
            List<PointInfo> pis = stMap.get(byHour.getStationId());
            double dl = 0, v = 0;
            List<PointData> pds;
            for (PointInfo pi : pis) {
                pds = pi.getPointDatas();
                if (pds.size() > 1) v = (pds.get(1).getValue() - pds.get(0).getValue()) * pi.getCoef();
                dl += (v < 0 || v > 30000000) ? 0 : v;
            }
            byHour.setRfdl(dl);
        }
        stationInfoMinService.saveOrUpdateBatch(byHours);
    }

    public void calcStationHourPJGL(Date hour) {
        hour = DateUtil.beginOfHour(hour);
        DateTime start = DateUtil.offsetHour(hour, -1);
        //出线
        List<PointInfo> entityCx = getEntity("AGC001", "booster");
        Map<String, PointInfo> statMapCx = getStatDataByEntity(entityCx, goldenUri(), start, hour, PointInfo::getStationId);

        List<StationInfoHour> byHours = getStationinfoByHour(hour, entityCx);
        for (StationInfoHour byHour : byHours) {
            PointInfo info = statMapCx.get(byHour.getStationId());
            double v = info.getPointDatas().get(0).getValue();
            if (v < 0) {
                v = 0;
            } else {
                v = v * info.getCoef();
            }
            byHour.setPjgl(v);
        }
        stationInfoHourService.saveOrUpdateBatch(byHours);
    }

    public void calcStationRfdlFj(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);

        QueryWrapper<TurbineInfoDay> wrapper = new QueryWrapper<>();
        wrapper.select("sum(rfdl) rfdl,station_id").eq("record_date", time0).groupBy("station_id");
        List<TurbineInfoDay> list = turbineInfoDayService.list(wrapper);
        Map<String, TurbineInfoDay> dayMap = list.stream().collect(Collectors.toMap(TurbineInfoDay::getStationId, Function.identity()));
        List<StationInfoDay> byDate = getStationinfoByDate(time0);

        TurbineInfoDay tDay;
        for (StationInfoDay day : byDate) {
            tDay = dayMap.get(day.getStationId());
            day.setRfdlFj(tDay.getRfdl());
        }
        stationInfoDayService.saveOrUpdateBatch(byDate);
    }

    public void calcTurbineRFDL(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);

        List<PointInfo> entity = getEntity("AI121", "turbine");
        getZeroNextData(entity, time0, time);
        Map<String, PointInfo> turMap = entity.stream().collect(Collectors.toMap(PointInfo::getTurbineId, Function.identity()));
        Map<String, String> fsMap = getEntityMap("AI066", "turbine");

        Map<String, TurbineInfoDay> byDate = getTurbineinfoMap(time0, entity);

        TurbineInfoDay infoDay;
        PointInfo rfdlPi;
        String turbineId;
        List<TurbineInfoDay> infoDays = new ArrayList<>();
        DoubleStatData stat;
        for (PointInfo info : entity) {
            turbineId = info.getTurbineId();
            infoDay = byDate.get(turbineId);

            rfdlPi = turMap.get(turbineId);
            double v = (rfdlPi.getPointDatas().get(1).getValue() - rfdlPi.getPointDatas().get(0).getValue()) * rfdlPi.getCoef();
            if (v < 0 || v > 1000000) {
                v = 0;
            } else if (v > 30000) {
                v = v / (v % 30000 + 3);
            }
            infoDay.setRfdl(v);
            stat = adapter.getHistoryStat(goldenUri(), fsMap.get(turbineId), time0.getTime(), time.getTime());
            if (stat == null) {
                infoDay.setPjfs(0.0);
            } else {
                infoDay.setPjfs(stat.getAvg().getValue());
            }

            infoDays.add(infoDay);
        }
        turbineInfoDayService.saveOrUpdateBatch(infoDays);
    }

    */
/*public void calcTurbine5s(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);

        //状态
        List<PointInfo> entityZt = getEntity("MXZT", "turbine");
        //功率
        Map<String, String> collectGl = getEntityMap("AI114", "turbine");
        //风速
        Map<String, String> collectFs = getEntityMap("AI066", "turbine");

        Map<String, TurbineInfoDay> dayMap = getTurbineinfoMap(time0, entityZt);

        String tbId;
        TurbineInfoDay infoDay;
        List<TurbineInfoDay> infoDays = new ArrayList<>();
        for (PointInfo info : entityZt) {
            tbId = info.getTurbineId();
            List<PointData> snapZt = adapter.getHistorySnap(taosUri(), info.getPointKey(), time0.getTime(), time.getTime(), 60);
            //0 待机，1 手动停机，2 正常发电，3 发电降出力，4 故障，5 故障受累，6 检修，7 检修受累，8 限电降出力，
            // 9 限电停机，10 电网受累，11 环境受累，12 通讯中断，13 设备离线

            List<DoubleStatData> statGl = adapter.getHistoryStat2(goldenUri(), collectGl.get(tbId), time0.getTime(), time.getTime(), 60);
            List<DoubleStatData> statFs = adapter.getHistoryStat2(goldenUri(), collectFs.get(tbId), time0.getTime(), time.getTime(), 60);
            List<PointData> glList = statGl.stream().map(DoubleStatData::getAvg).collect(Collectors.toList());
            List<PointData> fsList = statFs.stream().map(DoubleStatData::getAvg)
                    .peek(fs -> {
                        if (fs.getValue() < 25) {
                            fs.setDoubleValue(NumberUtil.round(fs.getValue(), 2).doubleValue());
                        } else {
                            fs.setDoubleValue(25.0);
                        }
                    }).collect(Collectors.toList());

//            Map<String, Double> loss = getTurbinePowerLoss(snapZt, fsList, tbId, glList);
            Map<String, Double> loss = new HashMap<>();

            infoDay = dayMap.get(tbId);
            infoDay.setJhjxss(loss.get("jxss") + loss.get("sdtj"));
            infoDay.setFjhjxss(loss.get("gzss") + loss.get("djss") + loss.get("fdjcl"));
            infoDay.setXdss(loss.get("xdjcl") + loss.get("xdtj"));
            infoDay.setSlss(0.0);
            if (infoDay.getRfdl() == 0) {
                infoDay.setXnss(0.0);
            } else {
                infoDay.setXnss(loss.get("xnss") * 0.1);
            }
            infoDay.setLlfdl(infoDay.getRfdl() + infoDay.getJhjxss() + infoDay.getFjhjxss() +
                    infoDay.getXdss() + infoDay.getSlss() + infoDay.getXnss());
            infoDays.add(infoDay);
        }
        turbineInfoDayService.saveOrUpdateBatch(infoDays);
    }*//*


    //此处加公式
    public void calcStationSspjfs() {
        List<PointInfo> fsEntity = getEntity("AI066", "turbine");
        String keys = pointInfos2Keys(fsEntity);
        Map<String, PointData> latest = adapter.getLatest(goldenUri(), keys);
        Map<String, List<String>> listMap = fsEntity.stream().collect(Collectors.groupingBy(PointInfo::getStationId, Collectors.mapping(PointInfo::getPointKey, Collectors.toList())));

        Map<String, String> entityMap = getEntityMap("SSPJFS", "station");

        List<PointData> tsData = new ArrayList<>();
        listMap.forEach((stId, keyList) -> {
            double v = keyList.stream().mapToDouble(key -> latest.get(key).getValue()).average().orElse(0.0);
            PointData data = new PointData();
            data.setTs(System.currentTimeMillis());
            data.setTagName(entityMap.get(stId));
            data.setDoubleValue(v);
            tsData.add(data);
        });
        adapter.writeHistoryBatch(taosUri(), tsData);
    }

    public void calcTurbine5s2(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);
        //风速
        List<PointInfo> entityFs = getEntity("AI066", "turbine");
        //功率
        List<PointInfo> entityGl = getEntity("AI114", "turbine");
        getSnapDataByEntity(entityFs, time0, time, 15);
        getSnapDataByEntity(entityGl, time0, time, 15);

        List<PointInfo> ztMapMap = calcTurbineZt(time0, time, entityFs, entityGl);
        Map<String, Map<String, PointInfo>> ztMapMapInfos = ztMapMap.stream().collect(
                Collectors.groupingBy(PointInfo::getStationId, Collectors.toMap(PointInfo::getTurbineId, Function.identity())));
        Map<String, TurbineInfoDay> dayMap = getTurbineinfoMap(time0, entityFs);

        List<TurbineInfoDay> infoDays = new ArrayList<>();
        Map<String, Map<String, List<PointData>>> fsMapMap = entityFs.stream().collect(Collectors.groupingBy(PointInfo::getStationId,
                Collectors.toMap(PointInfo::getTurbineId, PointInfo::getPointDatas)));
        Map<String, Map<String, List<PointData>>> glMapMap = entityGl.stream().collect(Collectors.groupingBy(PointInfo::getStationId,
                Collectors.toMap(PointInfo::getTurbineId, PointInfo::getPointDatas)));

        ztMapMapInfos.forEach((stId, ztMapInfo) -> ztMapInfo.forEach((wtId, ztInfo) -> {
            //0 待机，1 手动停机，2 正常发电，3 发电降出力，4 故障，5 故障受累，6 检修，7 检修受累，8 限电降出力，
            // 9 限电停机，10 电网受累，11 环境受累，12 通讯中断，13 设备离线
            TurbineInfoDay infoDay = dayMap.get(wtId);
            Map<String, Double> loss = getTurbinePowerLoss(infoDay.getRfdl(), ztMapMapInfos.get(stId).get(wtId), fsMapMap.get(stId).get(wtId), glMapMap.get(stId).get(wtId));
            infoDay.setJhjxss(loss.get("jxss") + loss.get("sdtj"));
            infoDay.setFjhjxss(loss.get("gzss") + loss.get("djss") + loss.get("fdjcl"));
            infoDay.setXdss(loss.get("xdjcl") + loss.get("xdtj"));
            infoDay.setSlss(0.0);
            infoDay.setDjss(loss.get("djss"));
            infoDay.setGzss(loss.get("gzss"));
            if (infoDay.getRfdl() == 0) {
                infoDay.setXnss(0.0);
            } else {
                infoDay.setXnss(loss.get("xnss"));
            }
            infoDay.setLlfdl(infoDay.getRfdl() + infoDay.getJhjxss() + infoDay.getFjhjxss() +
                    infoDay.getXdss() + infoDay.getSlss() + infoDay.getXnss());
            infoDays.add(infoDay);
        }));
        turbineInfoDayService.saveOrUpdateBatch(infoDays);
    }

    public List<PointInfo> calcTurbineZt(Date start, Date end, List<PointInfo> fsInfos, List<PointInfo> glInfos) {

        List<PointInfo> turbineZt = calcTurbineDizt(start, end, 15);
        List<PointInfo> turbineAizt = calcTurbineAizt(start, end, 15);
        turbineZt.addAll(turbineAizt);
        Map<String, Map<String, PointInfo>> ztMapMap = turbineZt.stream().collect(Collectors.groupingBy(PointInfo::getStationId,
                Collectors.toMap(PointInfo::getTurbineId, Function.identity())));

        //AGC
        List<PointInfo> entityAgc = getEntity("AGC002", "booster");
        getSnapDataByEntity(entityAgc, start, end, 15);
        //出线
        List<PointInfo> entityCx = getEntity("AGC001", "booster");
        getSnapDataByEntity(entityCx, start, end, 15);
        //叶轮转速给定
        List<PointInfo> entityYlzsgd = getEntity("AI110", "turbine");
        getSnapDataByEntity(entityYlzsgd, start, end, 15);

        Map<String, PointInfo> collectAgc = entityAgc.stream().collect(Collectors.toMap(PointInfo::getStationId, Function.identity()));
        Map<String, PointInfo> collectCx = entityCx.stream().collect(Collectors.toMap(PointInfo::getStationId, Function.identity()));
        Map<String, Map<String, List<PointData>>> collectYlzsgd = entityYlzsgd.stream().collect(Collectors.groupingBy(PointInfo::getStationId,
                Collectors.toMap(PointInfo::getTurbineId, PointInfo::getPointDatas)));
        Map<String, Map<String, PointInfo>> fsMapMap = fsInfos.stream().collect(Collectors.groupingBy(PointInfo::getStationId,
                Collectors.toMap(PointInfo::getTurbineId, Function.identity())));
        Map<String, Map<String, List<PointData>>> glMapMap = glInfos.stream().collect(Collectors.groupingBy(PointInfo::getStationId,
                Collectors.toMap(PointInfo::getTurbineId, PointInfo::getPointDatas)));

        ztMapMap.forEach((stId, ztMap) -> {
            PointInfo agcInfo = collectAgc.get(stId);
            PointInfo cxInfo = collectCx.get(stId);
            Map<String, PointInfo> fsMap = fsMapMap.get(stId);

            Map<String, List<PointData>> pdsZsglMap = new HashMap<>();
            ztMap.forEach((wtId, zt) -> {
                List<PointData> peek = fsMap.get(wtId).getPointDatas().stream().peek(pd -> pd.setDoubleValue(NumberUtil.round(pd.getValue() > 25 ? 25.0
                        : pd.getValue(), 2).doubleValue())).collect(Collectors.toList());
                fsMap.get(wtId).setPointDatas(peek);
                List<PointData> zsglSnap = fsMap.get(wtId).getPointDatas().stream().map(pd -> {
                    Double v = CalcCache.fitcoef.get(wtId).get(pd.getValue());
                    return new PointData(pd.getTs(), v == null ? 0 : v);
                }).collect(Collectors.toList());
                pdsZsglMap.put(wtId, zsglSnap);
            });
            List<PointData> agcc = agcInfo.getPointDatas().stream().peek(agc -> {
                agc.setDoubleValue(agc.getValue() * agcInfo.getCoef());
                agc.setLongValue(0L);
            }).collect(Collectors.toList());
            agcInfo.setPointDatas(agcc);
            List<PointData> cxc = cxInfo.getPointDatas().stream().peek(cx -> {
                cx.setDoubleValue(cx.getValue() * cxInfo.getCoef());
                cx.setLongValue(0L);
            }).collect(Collectors.toList());
            cxInfo.setPointDatas(cxc);

            //风机风速、功率->场站风速、功率
//            List<PointData> firstFs = new ArrayList<>();
//            List<PointData> firstGl = new ArrayList<>();
            List<PointData> firstZsgl = new ArrayList<>();
            double v1, v2, v3;
            for (int i = 0; i < agcInfo.getPointDatas().size(); i++) {
                int finalI = i;
                long ts = start.getTime() + i * 15000L;
//                v1 = fsMap.values().stream().mapToDouble(pds -> pds.getPointDatas().get(finalI).getValue()).average().orElse(0.0);
//                v2 = glMap.values().stream().mapToDouble(pds -> pds.getPointDatas().get(finalI).getValue()).sum();
                v3 = pdsZsglMap.values().stream().mapToDouble(pds -> pds.get(finalI).getValue()).sum();
//                firstFs.add(new PointData(ts, v1));
//                firstGl.add(new PointData(ts, v2));
                firstZsgl.add(new PointData(ts, v3));
            }

            List<PointData> czxd = calcStationXd2(agcInfo, cxInfo.getPointDatas(), firstZsgl);
            String ybj = "GJNY_SXGS_XZ_F_WT_0013_EQ,GJNY_SXGS_XZ_F_WT_0023_EQ,GJNY_SXGS_XZ_F_WT_0027_EQ,GJNY_SXGS_XZ_F_WT_0034_EQ,GJNY_SXGS_XZ_F_WT_0044_EQ,GJNY_SXGS_XZ_F_WT_0060_EQ,GJNY_SXGS_XZ_F_WT_0062_EQ,GJNY_SXGS_FSG_F_WT_0005_EQ,GJNY_SXGS_FSG_F_WT_0006_EQ,GJNY_SXGS_FSG_F_WT_0038_EQ,GJNY_SXGS_FSG_F_WT_0039_EQ,GJNY_SXGS_ZZ_F_WT_0008_EQ,GJNY_SXGS_ZZ_F_WT_0015_EQ,GJNY_SXGS_ZZ_F_WT_0022_EQ,GJNY_SXGS_ZZ_F_WT_0046_EQ,GJNY_SXGS_ZZ_F_WT_0049_EQ,GJNY_SXGS_CSL_F_WT_0003_EQ,GJNY_SXGS_CSL_F_WT_0012_EQ,GJNY_SXGS_CSL_F_WT_0023_EQ,GJNY_SXGS_JSL_F_WT_0002_EQ,GJNY_SXGS_JSL_F_WT_0003_EQ,GJNY_SXGS_JSL_F_WT_0028_EQ,GJNY_SXGS_JSL_F_WT_0047_EQ,GJNY_SXGS_JSL_F_WT_0070_EQ,GJNY_SXGS_JSL_F_WT_0094_EQ,GJNY_SXGS_LJS_F_WT_0002_EQ,GJNY_SXGS_LJS_F_WT_0011_EQ,GJNY_SXGS_LJS_F_WT_0030_EQ,GJNY_SXGS_LJS_F_WT_0033_EQ";
            ztMap.forEach((wtId, ztInfo) -> {
                if (ybj.contains(wtId)) return;
                List<PointData> fss = fsMap.get(wtId).getPointDatas();
                List<PointData> gls = glMapMap.get(stId).get(wtId);
                //叶轮转速给定
                List<PointData> ylzsgds = collectYlzsgd.get(stId).get(wtId);
                calcTurbineXd(ztInfo, gls, fss, ylzsgds, czxd);
            });
        });
        return turbineZt;
    }

    public List<PointData> calcTurbineSimpleZt(Date start, Date end, Integer interval, String tbId) {
        List<PointInfo> turbineZt = calcTurbineDizt(start, end, interval, tbId);
        List<PointInfo> turbineAizt = calcTurbineAizt(start, end, interval, tbId);
        turbineZt.addAll(turbineAizt);
        Map<String, List<PointData>> collect = turbineZt.stream().collect(Collectors.toMap(PointInfo::getTurbineId, PointInfo::getPointDatas));
        return collect.get(tbId);//.stream().map(PointData::getValue).collect(Collectors.toList());
    }

    public void calcTurbineXd(PointInfo ztInfo, List<PointData> gls, List<PointData> fss, List<PointData> ylzsgds, List<PointData> czxd) {
        Map<String, EquipmentModel> map = equipmentModelService.map();
        Double capacity = map.get(ztInfo.getSpare()).getPowerProduction();
        List<PointData> zts = ztInfo.getPointDatas();
        for (int i = 0; i < fss.size(); i++) {
            double ssgl = gls.get(i).getValue();
            double ssfs = fss.get(i).getValue();
            double ylzsgd = ylzsgds.get(i).getValue();

            if (czxd.get(i).isBooleanValue() && ssgl < capacity * 0.9) {
                if (ssfs >= 12) {
                    zts.get(i).setDoubleValue(8.0);
                }
                if (ylzsgd != 0 && ylzsgd < 17.3) {//降出力
                    zts.get(i).setDoubleValue(8.0);
                }
            }
        }
    }

    //此处加公式
    public List<PointData> calcStationXd2(PointInfo agcInfo, List<PointData> cxSnap, List<PointData> zsglSnap) {
        String stId = agcInfo.getStationId();

        List<PointData> agcSnap = agcInfo.getPointDatas();
        List<PointData> zsgl5s = get5Avg(zsglSnap);
        List<PointData> agc5s = get5Avg(agcSnap);
        List<PointData> cx5s = get5Avg(cxSnap);
        //场站限电
        List<PointData> czxd = zsglSnap.stream().map(s -> new PointData(s.getTs(), 0.0)).collect(Collectors.toList());
        //之前是否限电
        boolean iszqxd = false;
        for (int i = 0; i < zsglSnap.size(); i++) {
            boolean isxd = false;
            double zsgl = zsglSnap.get(i).getValue();
            double zsgl5 = zsgl5s.get(i).getValue();
            double agc = agcSnap.get(i).getValue();
            double agc5 = agc5s.get(i).getValue();
            double cxgl = cxSnap.get(i).getValue();
            double cxgl5 = cx5s.get(i).getValue();

            boolean k;   //agc一直不变
            //第一次初始化复制实时数据到缓存
            if (CalcCache.powerCache.get(stId) == null || CalcCache.powerCache.get(stId) != agc) {
                CalcCache.powerCache.put(stId, agc);
                k = false;
            } else {
                k = true;
            }
            if (agc != 0) {
                //如果场站限电状态为不限电
                if (zsgl5 >= agcInfo.getSpare2() * 40) {
                    if (agc5 <= cxgl5) {
                        isxd = true;
                    } else if (iszqxd) {
                        if (zsgl / agc > 1.15) {
                            isxd = true;
                        } else if (zsgl > agc && agc5 - cxgl5 < 400) {
                            isxd = true;
                        }
                    } else if (zsgl / agc >= 1.2 && agc - cxgl <= 200) {
                        isxd = true;
                    }
                } else if (k) {
                    if (zsgl / agc >= 1.1 && agc5 - cxgl5 <= 200) {
                        isxd = true;
                    }
                }
            }
            czxd.get(i).setBooleanValue(isxd);
            iszqxd = isxd;
        }
        return czxd;
    }

    private List<PointData> get5Avg(List<PointData> pointData) {
        List<PointData> result = new ArrayList<>();
        for (int i = 0; i < pointData.size(); i++) {
            PointData data = new PointData();
            data.setTs(pointData.get(i).getTs());
            double v;
            if (i > 4) {
                v = (pointData.get(i).getValue() + pointData.get(i - 1).getValue() + pointData.get(i - 2).getValue() + pointData.get(i - 3).getValue() + pointData.get(i - 4).getValue()) / 5;
            } else {
                v = pointData.get(i).getValue();
            }
            data.setDoubleValue(v);
            result.add(data);
        }
        return result;
    }


    public List<PointInfo> calcTurbineAizt(Date start, Date end, int interval) {
        List<PointInfo> entityAiZt = getEntity("AI422", "state");
        List<StateAi> list = stateAiService.list();
        Map<String, Map<Integer, Integer>> collectAi = list.stream().collect(Collectors.groupingBy(StateAi::getModel, Collectors.toMap(StateAi::getOriginalState, StateAi::getMappingState)));
        getSnapDataByEntity(entityAiZt, start, end, interval);
        for (PointInfo info : entityAiZt) {
            List<PointData> peek = info.getPointDatas().stream().peek(pd -> {
                Integer m = collectAi.get(info.getSpare()).get((int) pd.getValue());
                if (m == null) m = 2;
                pd.setDoubleValue(m);
            }).collect(Collectors.toList());
            info.setPointDatas(peek);
        }
        return entityAiZt;
    }

    public List<PointInfo> calcTurbineAizt(Date start, Date end, int interval, String tbId) {
        List<PointInfo> entityAiZt = getEntity("AI422", "state");
        entityAiZt = entityAiZt.stream().filter(e -> tbId.equals(e.getTurbineId())).collect(Collectors.toList());
        List<StateAi> list = stateAiService.list();
        Map<String, Map<Integer, Integer>> collectAi = list.stream().collect(Collectors.groupingBy(StateAi::getModel, Collectors.toMap(StateAi::getOriginalState, StateAi::getMappingState)));
        getSnapDataByEntity(entityAiZt, start, end, interval);
        for (PointInfo info : entityAiZt) {
            List<PointData> peek = info.getPointDatas().stream().peek(pd -> {
                Integer m = collectAi.get(info.getSpare()).get((int) pd.getValue());
                if (m == null) m = 2;
                pd.setDoubleValue(m);
            }).collect(Collectors.toList());
            info.setPointDatas(peek);
        }
        return entityAiZt;
    }

    public List<PointInfo> calcTurbineDizt(Date start, Date end, int interval) {
        List<PointInfo> entity = new ArrayList<>();
        List<PointInfo> entity0 = getEntity("MX000", "state");
        List<PointInfo> entity1 = getEntity("MX001", "state");
        List<PointInfo> entity2 = getEntity("MX002", "state");
        List<PointInfo> entity4 = getEntity("MX004", "state");
        List<PointInfo> entity6 = getEntity("MX006", "state");
        entity.addAll(entity0);
        entity.addAll(entity1);
        entity.addAll(entity2);
        entity.addAll(entity4);
        entity.addAll(entity6);
        List<String> keys = entity.stream().map(PointInfo::getPointKey).collect(Collectors.toList());
        Map<String, PointData> latest = adapter.getHistorySection(goldenUri(), String.join(",", keys), start.getTime());

        Map<String, Map<String, PointInfo>> wtUcPis = entity.stream().collect(Collectors.groupingBy(PointInfo::getTurbineId, Collectors.toMap(PointInfo::getUniformCode, Function.identity())));
        wtUcPis.forEach((wtId, map) -> {
            map.forEach((uc, pi) -> {
                List<PointData> raw = adapter.getHistoryRaw(goldenUri(), pi.getPointKey(), start.getTime(), end.getTime());
                List<PointData> ds = boolPointDatasFull(latest.get(pi.getPointKey()).isBooleanValue(), raw, start.getTime(), end.getTime(), interval);
                pi.setPointDatas(ds);
                ThreadUtil.sleep(5);
            });
            List<PointData> mx000 = map.get("MX000").getPointDatas();
            PointData data0;
            for (int i = 0; i < mx000.size(); i++) {
                data0 = mx000.get(i);
                if (data0.getValue() == 1.0) {
                    data0.setDoubleValue(0.0);
                    data0.setBooleanValue(false);
                } else if (map.get("MX001").getPointDatas().get(i).getValue() == 1.0) {
                    data0.setDoubleValue(1.0);
                } else if (map.get("MX002").getPointDatas().get(i).getValue() == 1.0) {
                    data0.setDoubleValue(2.0);
                } else if (map.get("MX004").getPointDatas().get(i).getValue() == 1.0) {
                    data0.setDoubleValue(4.0);
                } else if (map.get("MX006").getPointDatas().get(i).getValue() == 1.0) {
                    data0.setDoubleValue(6.0);
                } else {
                    //                    System.out.println(wtId + data0.getTs() + "：di无对应状态！");
                    data0.setDoubleValue(2.0);
                }
            }
            map.get("MX001").setPointDatas(null);
            map.get("MX002").setPointDatas(null);
            map.get("MX004").setPointDatas(null);
            map.get("MX006").setPointDatas(null);
        });
        return entity0;
    }

    public List<PointInfo> calcTurbineDizt(Date start, Date end, int interval, String tbId) {
        List<PointInfo> entity = new ArrayList<>();
        List<PointInfo> entity0 = getEntity("MX000", "state");
        List<PointInfo> entity1 = getEntity("MX001", "state");
        List<PointInfo> entity2 = getEntity("MX002", "state");
        List<PointInfo> entity4 = getEntity("MX004", "state");
        List<PointInfo> entity6 = getEntity("MX006", "state");
        entity0 = entity0.stream().filter(e -> tbId.equals(e.getTurbineId())).collect(Collectors.toList());
        entity1 = entity1.stream().filter(e -> tbId.equals(e.getTurbineId())).collect(Collectors.toList());
        entity2 = entity2.stream().filter(e -> tbId.equals(e.getTurbineId())).collect(Collectors.toList());
        entity4 = entity4.stream().filter(e -> tbId.equals(e.getTurbineId())).collect(Collectors.toList());
        entity6 = entity6.stream().filter(e -> tbId.equals(e.getTurbineId())).collect(Collectors.toList());
        entity.addAll(entity0);
        entity.addAll(entity1);
        entity.addAll(entity2);
        entity.addAll(entity4);
        entity.addAll(entity6);
        List<String> keys = entity.stream().map(PointInfo::getPointKey).collect(Collectors.toList());
        Map<String, PointData> latest = adapter.getHistorySection(goldenUri(), String.join(",", keys), start.getTime());

        Map<String, Map<String, PointInfo>> wtUcPis = entity.stream().collect(Collectors.groupingBy(PointInfo::getTurbineId, Collectors.toMap(PointInfo::getUniformCode, Function.identity())));
        wtUcPis.forEach((wtId, map) -> {
            map.forEach((uc, pi) -> {
                List<PointData> raw = adapter.getHistoryRaw(goldenUri(), pi.getPointKey(), start.getTime(), end.getTime());
                List<PointData> ds = boolPointDatasFull(latest.get(pi.getPointKey()).isBooleanValue(), raw, start.getTime(), end.getTime(), interval);
                pi.setPointDatas(ds);
                ThreadUtil.sleep(5);
            });
            List<PointData> mx000 = map.get("MX000").getPointDatas();
            PointData data0;
            for (int i = 0; i < mx000.size(); i++) {
                data0 = mx000.get(i);
                if (data0.getValue() == 1.0) {
                    data0.setDoubleValue(0.0);
                    data0.setBooleanValue(false);
                } else if (map.get("MX001").getPointDatas().get(i).getValue() == 1.0) {
                    data0.setDoubleValue(1.0);
                } else if (map.get("MX002").getPointDatas().get(i).getValue() == 1.0) {
                    data0.setDoubleValue(2.0);
                } else if (map.get("MX004").getPointDatas().get(i).getValue() == 1.0) {
                    data0.setDoubleValue(4.0);
                } else if (map.get("MX006").getPointDatas().get(i).getValue() == 1.0) {
                    data0.setDoubleValue(6.0);
                } else {
                    //                    System.out.println(wtId + data0.getTs() + "：di无对应状态！");
                    data0.setDoubleValue(2.0);
                }
            }
            map.get("MX001").setPointDatas(null);
            map.get("MX002").setPointDatas(null);
            map.get("MX004").setPointDatas(null);
            map.get("MX006").setPointDatas(null);
        });
        return entity0;
    }

    public PointInfo calcTurbineAizt2(PointInfo entityAiZt, Map<String, Map<Integer, Integer>> collectAi, Date start, Date end, int interval) {
        if (entityAiZt == null) return null;
        getSnapDataByEntity(entityAiZt, start, end, interval);
        Map<Integer, Integer> integerMap = collectAi.get(entityAiZt.getSpare());
        List<PointData> data = entityAiZt.getPointDatas().stream().peek(pd -> {
            Integer m = integerMap.get((int) pd.getValue());
            if (m == null) m = 2;
            pd.setDoubleValue(m);
        }).collect(Collectors.toList());
        entityAiZt.setPointDatas(data);
        return entityAiZt;
    }

    public PointInfo calcTurbineDizt2(Map<String, PointInfo> wtucpi, Map<String, PointData> latest, Date start, Date end, int interval) {
        if (wtucpi == null) return null;
        wtucpi.forEach((uc, pi) -> {
            List<PointData> raw = adapter.getHistoryRaw(goldenUri(), pi.getPointKey(), start.getTime(), end.getTime());
            List<PointData> ds = boolPointDatasFull(latest.get(pi.getPointKey()).isBooleanValue(), raw, start.getTime(), end.getTime(), interval);
            pi.setPointDatas(ds);
            ThreadUtil.sleep(5);
        });
        PointInfo mx000 = wtucpi.get("MX000");
        PointData data0;
        for (int i = 0; i < mx000.getPointDatas().size(); i++) {
            data0 = mx000.getPointDatas().get(i);
            if (data0.getValue() == 1.0) {
                data0.setDoubleValue(0.0);
                data0.setBooleanValue(false);
            } else if (wtucpi.get("MX001").getPointDatas().get(i).getValue() == 1.0) {
                data0.setDoubleValue(1.0);
            } else if (wtucpi.get("MX002").getPointDatas().get(i).getValue() == 1.0) {
                data0.setDoubleValue(2.0);
            } else if (wtucpi.get("MX004").getPointDatas().get(i).getValue() == 1.0) {
                data0.setDoubleValue(4.0);
            } else if (wtucpi.get("MX006").getPointDatas().get(i).getValue() == 1.0) {
                data0.setDoubleValue(6.0);
            } else {
                System.out.println(mx000.getTurbineId() + data0.getTs() + "：di无对应状态！");
                data0.setDoubleValue(2.0);
            }
        }
        wtucpi.get("MX001").setPointDatas(null);
        wtucpi.get("MX002").setPointDatas(null);
        wtucpi.get("MX004").setPointDatas(null);
        wtucpi.get("MX006").setPointDatas(null);
        return mx000;
    }

    public List<PointData> boolPointDatasFull(boolean v, List<PointData> data, long startTime, long endTime, int interval) {
        int j = 0, m = 0;
        List<PointData> data2 = new ArrayList<>();
        for (long i = startTime; i <= endTime; i += interval * 1000L) {
            PointData dt = new PointData();
            dt.setTs(i);
            data2.add(dt);
            //超出范围
            if (j >= data.size() - 1) continue;
            if (i < data.get(j).getTs()) {
                if (m == 0) {
                    dt.setBooleanValue(v);
                } else {
                    dt.setBooleanValue(data.get(j - 1).isBooleanValue());
                }
            } else {
                dt.setBooleanValue(data.get(j).isBooleanValue());
                j++;
                m++;
            }
        }
        return data2;
    }

    public List<PointData> doublePointDatasFull(double v, List<PointData> data, long startTime, long endTime, int interval) {
        int j = 0, m = 0;
        List<PointData> data2 = new ArrayList<>();
        for (long i = startTime; i <= endTime; i += interval * 1000L) {
            PointData dt = new PointData();
            dt.setTs(i);
            data2.add(dt);
            //超出范围
            if (j >= data.size() - 1) continue;
            if (i < data.get(j).getTs()) {
                if (m == 0) {
                    dt.setDoubleValue(v);
                } else {
                    dt.setDoubleValue(data.get(j - 1).getValue());
                }
            } else {
                dt.setDoubleValue(data.get(j).getValue());
                j++;
                m++;
            }
        }
        return data2;
    }

    public void calcGlqxnh(Date start, Date end) {
        //风速
        List<PointInfo> entityFs = getEntity("AI066", "turbine");
        //功率
        List<PointInfo> entityGl = getEntity("AI114", "turbine");
        Map<String, PointInfo> glMap = entityGl.stream().collect(Collectors.toMap(PointInfo::getTurbineId, Function.identity()));

        Map<String, EquipmentModel> map = equipmentModelService.map();

        List<PointInfo> entity = new ArrayList<>();
        List<PointInfo> entity0 = getEntity("MX000", "state");
        List<PointInfo> entity1 = getEntity("MX001", "state");
        List<PointInfo> entity2 = getEntity("MX002", "state");
        List<PointInfo> entity4 = getEntity("MX004", "state");
        List<PointInfo> entity6 = getEntity("MX006", "state");
        entity.addAll(entity0);
        entity.addAll(entity1);
        entity.addAll(entity2);
        entity.addAll(entity4);
        entity.addAll(entity6);
        List<String> keys = entity.stream().map(PointInfo::getPointKey).collect(Collectors.toList());
        Map<String, PointData> latest = adapter.getHistorySection(goldenUri(), String.join(",", keys), start.getTime());
        Map<String, Map<String, PointInfo>> wtUcPis = entity.stream().collect(Collectors.groupingBy(PointInfo::getTurbineId, Collectors.toMap(PointInfo::getUniformCode, Function.identity())));

        List<PointInfo> entityAiZt = getEntity("AI422", "state");
        Map<String, PointInfo> aiztMap = entityAiZt.stream().collect(Collectors.toMap(PointInfo::getTurbineId, Function.identity()));
        List<StateAi> list = stateAiService.list();
        Map<String, Map<Integer, Integer>> collectAi = list.stream().collect(Collectors.groupingBy(StateAi::getModel, Collectors.toMap(StateAi::getOriginalState, StateAi::getMappingState)));

        //        Map<String, Map<Double,Double>> fitMap = new HashMap<>();
//        entityFs = entityFs.stream().filter(ef -> !CalcCache.keys.contains(ef.getTurbineId())).collect(Collectors.toList());
        for (PointInfo ef : entityFs) {
            String wtId = ef.getTurbineId();
            PointInfo glInfo = glMap.get(wtId);
            getSnapDataByEntity(ef, start, end, 60);
            getSnapDataByEntity(glInfo, start, end, 60);
            List<PointData> peek = ef.getPointDatas().stream().peek(pd -> pd.setDoubleValue(NumberUtil.round(pd.getValue(), 2).doubleValue())).collect(Collectors.toList());
            ef.setPointDatas(peek);

            PointInfo turbineZt = calcTurbineDizt2(wtUcPis.get(wtId), latest, start, end, 60);
            PointInfo turbineAizt = calcTurbineAizt2(aiztMap.get(wtId), collectAi, start, end, 60);
            Map<Double, Double> fit = new TreeMap<>();
            if (turbineZt != null) {
                double capacity = map.get(turbineZt.getSpare()).getPowerProduction();
                fit = dataProcessAndFit(ef, glInfo, turbineZt, CalcCache.bzgl.get(turbineZt.getSpare()), capacity);
                //                fitMap.put(wtId, fit);
                turbineZt.setPointDatas(null);
            }
            if (turbineAizt != null) {
                double capacity = map.get(turbineAizt.getSpare()).getPowerProduction();
                fit = dataProcessAndFit(ef, glInfo, turbineAizt, CalcCache.bzgl.get(turbineAizt.getSpare()), capacity);
                //                fitMap.put(wtId, fit);
                turbineAizt.setPointDatas(null);
            }
            ef.setPointDatas(null);
            glInfo.setPointDatas(null);
            String key = "glqxnh:" + (end.getMonth() + 1) + ":" + wtId;
            stringRedisTemplate.opsForValue().set(key, JSON.toJSONString(fit));
            CalcCache.fitcoef.put(key, new ConcurrentHashMap<>(fit));
        }
        System.out.println("苹果天涯");
        //        stringRedisTemplate.opsForValue().set("glqxnh", JSON.toJSONString(fitMap));
    }

    public void calcGlqxnhSurplus(Date start, Date end) {
        //风速
        List<PointInfo> entityFs = getEntity("AI066", "turbine");
        //功率
        List<PointInfo> entityGl = getEntity("AI114", "turbine");
        Map<String, PointInfo> glMap = entityGl.stream().collect(Collectors.toMap(PointInfo::getTurbineId, Function.identity()));

        Map<String, EquipmentModel> map = equipmentModelService.map();

        List<PointInfo> entity = new ArrayList<>();
        List<PointInfo> entity0 = getEntity("MX000", "state");
        List<PointInfo> entity1 = getEntity("MX001", "state");
        List<PointInfo> entity2 = getEntity("MX002", "state");
        List<PointInfo> entity4 = getEntity("MX004", "state");
        List<PointInfo> entity6 = getEntity("MX006", "state");
        entity.addAll(entity0);
        entity.addAll(entity1);
        entity.addAll(entity2);
        entity.addAll(entity4);
        entity.addAll(entity6);
        List<String> keys = entity.stream().map(PointInfo::getPointKey).collect(Collectors.toList());
        Map<String, PointData> latest = adapter.getHistorySection(goldenUri(), String.join(",", keys), start.getTime());
        Map<String, Map<String, PointInfo>> wtUcPis = entity.stream().collect(Collectors.groupingBy(PointInfo::getTurbineId, Collectors.toMap(PointInfo::getUniformCode, Function.identity())));

        List<PointInfo> entityAiZt = getEntity("AI422", "state");
        Map<String, PointInfo> aiztMap = entityAiZt.stream().collect(Collectors.toMap(PointInfo::getTurbineId, Function.identity()));
        List<StateAi> list = stateAiService.list();
        Map<String, Map<Integer, Integer>> collectAi = list.stream().collect(Collectors.groupingBy(StateAi::getModel, Collectors.toMap(StateAi::getOriginalState, StateAi::getMappingState)));

        //        Map<String, Map<Double,Double>> fitMap = new HashMap<>();
        entityFs = entityFs.stream().filter(ef -> !CalcCache.already.contains(ef.getTurbineId())).collect(Collectors.toList());
        for (PointInfo ef : entityFs) {
            String wtId = ef.getTurbineId();
            PointInfo glInfo = glMap.get(wtId);
            getSnapDataByEntity(ef, start, end, 60);
            getSnapDataByEntity(glInfo, start, end, 60);
            List<PointData> peek = ef.getPointDatas().stream().peek(pd -> pd.setDoubleValue(NumberUtil.round(pd.getValue(), 2).doubleValue())).collect(Collectors.toList());
            ef.setPointDatas(peek);

            PointInfo turbineZt = calcTurbineDizt2(wtUcPis.get(wtId), latest, start, end, 60);
            PointInfo turbineAizt = calcTurbineAizt2(aiztMap.get(wtId), collectAi, start, end, 60);
            Map<Double, Double> fit = new TreeMap<>();
            if (turbineZt != null) {
                double capacity = map.get(turbineZt.getSpare()).getPowerProduction();
                fit = dataProcessAndFit(ef, glInfo, turbineZt, CalcCache.bzgl.get(turbineZt.getSpare()), capacity);
                //                fitMap.put(wtId, fit);
                turbineZt.setPointDatas(null);
            }
            if (turbineAizt != null) {
                double capacity = map.get(turbineAizt.getSpare()).getPowerProduction();
                fit = dataProcessAndFit(ef, glInfo, turbineAizt, CalcCache.bzgl.get(turbineAizt.getSpare()), capacity);
                //                fitMap.put(wtId, fit);
                turbineAizt.setPointDatas(null);
            }
            ef.setPointDatas(null);
            glInfo.setPointDatas(null);
            String key = "glqxnh:" + (end.getMonth() + 1) + ":" + wtId;
            stringRedisTemplate.opsForValue().set(key, JSON.toJSONString(fit));
            CalcCache.fitcoef.put(key, new ConcurrentHashMap<>(fit));
        }
        System.out.println("苹果天涯");
        //        stringRedisTemplate.opsForValue().set("glqxnh", JSON.toJSONString(fitMap));
    }

    public Map<Double, Double> dataProcessAndFit(PointInfo fsPI, PointInfo glPI, PointInfo ztPI, Map<Double, Double> modelPowerMap, double capacity) {
        System.out.println("开始拟合");
        List<PointData> fsPds = fsPI.getPointDatas();
        List<PointData> glPds = glPI.getPointDatas();
        List<PointData> ztPds = ztPI.getPointDatas();
        WeightedObservedPoints points = new WeightedObservedPoints();
        if (ztPds.size() - glPds.size() == 1) ztPds.remove(glPds.size());
        //数据过滤 0正常，1过滤掉
        if (fsPds.size() != glPds.size() || glPds.size() != ztPds.size()) return new HashMap<>();

        Double bzv;
        for (int i = 0; i < ztPds.size(); i++) {
            double fs = fsPds.get(i).getValue();
            double gl = glPds.get(i).getValue();
            // 过滤非并网值  风机状态不等于2
            if (ztPds.get(i).getValue() != 2.0) {
                //
            } else if (fs < 0 || fs > 25 || gl < 0 || gl > capacity * 1.05) {// 按给定风速功率过滤
                //
            } else {
                bzv = modelPowerMap.get(fs);
                if (bzv == null || bzv == 0.0) {
                    points.add(fs, gl);
                    continue;
                }
                double k = gl / bzv;  //功率曲线偏差: 保证功率/实际功率   k:偏差百分比
                if (k < 0.61 || k > 1.25) {
                    //
                } else {
                    points.add(fs, gl);
                }
            }
        }
        Map<Double, Double> glyc = new TreeMap<>();
        PolynomialCurveFitter fitter = PolynomialCurveFitter.create(4);
        try {
            double[] result = fitter.fit(points.toList());


            double min = calcMin(result);
            System.out.println(ztPI.getTurbineId());
            System.out.println(ztPI.getSpare());
            System.out.println(min);
            double[] max = calcMax(result);
            if (min == 0 || max[0] == 0 || max[1] == 0) {
                System.out.println();
            }
            System.out.println(max[0] + "," + max[1]);
            double ru;
            for (double i = 0; i < 25; i += 0.01) {
                i = NumberUtil.round(i, 2).doubleValue();
                if (i < 3) {
                    ru = 0.0;
                } else if (i < min) {
                    ru = modelPowerMap.get(i);
                } else if (i < max[0]) {
                    ru = calcPoly(i, result);
                } else {
                    ru = max[1];
                }
                glyc.put(i, NumberUtil.round(ru, 2).doubleValue());
            }

        } catch (Exception e) {
            System.out.println(ztPI.getTurbineId());
            System.out.println(ztPI.getSpare());
            System.out.println(e.getMessage());
        }
        System.out.println("拟合完成" + glyc);
        return glyc;
    }

    public double calcMin(double[] coef) {
        double minX = 0, minY = 9000;
        for (double x = 0; x < 8; x += 0.01) {
            double y = calcPoly(x, coef);
            if (y < minY) {
                minY = y;
                minX = x;
            }
        }
        return minX;
    }

    public double[] calcMax(double[] coef) {
        double[] a = new double[2];
        for (double x = 8; x < 16; x += 0.01) {
            double y = calcPoly(x, coef);
            if (y > a[1]) {
                a[0] = x;
                a[1] = y;
            }
        }
        return a;
    }

    public void printResult(double[] r, double accuracy) {

        for (double index = 0; index < 25; index += accuracy) {
            System.out.println("[" + index + "," + calcPoly(index, r) + "],");
        }
    }

    public void getSectionDataByEntity(List<PointInfo> entitys, URI uri, Date start, Date end) {
        String collect = entitys.stream().map(PointInfo::getPointKey).collect(Collectors.joining(","));
        Map<String, PointData> section0 = adapter.getHistorySection(uri, collect, start.getTime());
        Map<String, PointData> section1 = adapter.getHistorySection(uri, collect, end.getTime());
        for (PointInfo entity : entitys) {
            entity.setPointDatas(new ArrayList<>());
            entity.getPointDatas().add(section0.get(entity.getPointKey()));
            entity.getPointDatas().add(section1.get(entity.getPointKey()));
        }
    }

    public void getSnapDataByEntity(List<PointInfo> entity, URI uri, Date start, Date end, int interval) {
        for (PointInfo info : entity) {
            getSnapDataByEntity(info, uri, start, end, interval);
            ThreadUtil.sleep(5);
        }
    }

    public void getSnapDataByEntity(PointInfo entity, URI uri, Date start, Date end, int interval) {
        List<PointData> snap = adapter.getHistorySnap(uri, entity.getPointKey(), start.getTime(), end.getTime(), interval);
        entity.setPointDatas(snap);
    }

    public void getSnapDataByEntity(List<PointInfo> entity, Date start, Date end, int interval) {
        getSnapDataByEntity(entity, goldenUri(), start, end, interval);
    }

    public void getSnapDataByEntity(PointInfo entity, Date start, Date end, int interval) {
        getSnapDataByEntity(entity, goldenUri(), start, end, interval);
    }


    public double calcPoly(String wtId, double value) {
        return CalcCache.fitcoef.get(wtId).get(value);
    }

    public double calcPoly(double x, double[] factor) {
        double y = 0;
        for (int deg = 0; deg < factor.length; deg++) {
            y += Math.pow(x, deg) * factor[deg];
        }
        return y;
    }


    //切入切出风速

    public void cutInWindSpeed() {
        //date当天零点
        DateTime timeNow00 = DateUtil.beginOfDay(new Date());
        //date昨天零点
        DateTime timeBegin00 = DateUtil.offsetDay(timeNow00, -1);
        //上个月
        DateTime timeBegin2 = DateUtil.offsetMonth(timeBegin00, -1);
        //上个月第一天
        DateTime timeBegin1 = DateUtil.beginOfMonth(timeBegin2);
        //上个月最后一天
        DateTime timeEnd2 = DateUtil.endOfMonth(timeBegin2);
        //上个月天数
        int days = (int) DateUtil.betweenDay(timeBegin1, timeEnd2, false);
        //遍历天数
        for (int i = 1; i <= days; i++) {
            DateTime timeNow = DateUtil.offsetDay(timeBegin1, i);
            DateTime timeBegin = DateUtil.offsetDay(timeBegin1, i - 1);


            List<PointInfo> turbineZt = calcTurbineAizt(timeBegin, timeNow, 60);
            List<PointInfo> turbineZtDI = calcTurbineDizt(timeBegin, timeNow, 60);
            turbineZt.addAll(turbineZtDI);

            //所有风机的风速测点
            QueryWrapper<PointInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("uniform_code", "AI066");

            List<PointInfo> pointInfos = getEntity("AI066", "turbine");
            //        List<PointInfo> pointInfos = pointInfo.selectList(queryWrapper);

            //定义切入风速map集合
            ConcurrentHashMap<String, ConcurrentHashMap<String, Double>> mapIn = new ConcurrentHashMap<>();

            //定义切出风速集合
            ConcurrentHashMap<String, ConcurrentHashMap<String, Double>> mapOut = new ConcurrentHashMap<>();


            //插入集合
            List<TurbineInfoDay> interest = new ArrayList<>();
            //更新集合
            List<TurbineInfoDay> update = new ArrayList<>();
            //遍历每台风机，取出每台风机的pointDatas
            for (PointInfo turbine : turbineZt) {

                mapIn.put(turbine.getTurbineId(), new ConcurrentHashMap<>());
                mapOut.put(turbine.getTurbineId(), new ConcurrentHashMap<>());

                List<PointData> pointDatas = turbine.getPointDatas();

                //风速测点key
                String windSpeedKey = null;


                //遍历pointInfos，找出pointData1的id和pointInfos中相等的，取出pointInfo的pointKey
                for (PointInfo info : pointInfos) {
                    if (Objects.equals(turbine.getTurbineId(), info.getTurbineId())) {
                        windSpeedKey = info.getPointKey();
                    }
                }


                //遍历pointDatas,取出当前状态和后一个状态
                for (int k = 1; k < pointDatas.size(); k++) {
                    PointData pointData1 = pointDatas.get(k - 1);
                    PointData pointData2 = pointDatas.get(k);
                    double value1 = pointData1.getValue();
                    double value2 = pointData2.getValue();
                    //切入时间
                    long ts1;
                    //切出时间
                    long ts2;

                    //如果1的值为0,2的值为2，则为切入状态
                    if (value1 == 0 && value2 == 2) {
                        ts1 = pointData2.getTs();
                        //                    String stringDate = DateUtil.date(ts1).toString("yyyy-MM-dd HH:mm:ss");
                        //                    System.out.println(turbine.getTurbineId() + "切入" + stringDate);
                        //切入时间前5分钟
                        long ts11 = ts1 - 300000;
                        //根据风速key,从适配器取切入前5分钟的所有风速
                        List<PointData> pointDatas1 = adapter.getHistorySnap(goldenUri(), windSpeedKey, ts11, ts1, 10);
                        //平均所有风速即为平均切入风速
                        double avgCutInWindSpeed = pointDatas1.stream().mapToDouble(PointData::getValue).average().orElse(0);
                        //                    System.out.println(turbine.getTurbineId() + "切入风速" + avgCutInWindSpeed);

                        //存入map集合，外层key为turbineId，内层key为ts1，value为平均切入风速

                        mapIn.get(turbine.getTurbineId()).put(String.valueOf(ts1), avgCutInWindSpeed);

                    }

                    //切出
                    if (value1 == 2 && value2 != 2) {
                        ts2 = pointData2.getTs();
                        String stringDate = DateUtil.date(ts2).toString("yyyy-MM-dd HH:mm:ss");
                        //                    System.out.println(turbine.getTurbineId() + "切出" + stringDate);
                        //切出时间前5分钟
                        long ts22 = ts2 - 300000;
                        List<PointData> pointDatas2 = adapter.getHistorySnap(goldenUri(), windSpeedKey, ts22, ts2, 10);
                        double avgCutOutWindSpeed = pointDatas2.stream().mapToDouble(PointData::getValue).average().orElse(0);
                        //                    System.out.println(turbine.getTurbineId() + "切出风速" + avgCutOutWindSpeed);

                        //存入map集合，外层key为turbineId，内层key为ts2，value为平均切出风速

                        mapOut.get(turbine.getTurbineId()).put(String.valueOf(ts2), avgCutOutWindSpeed);
                    }

                }
                //遍历map集合，取出每个风机的所有切入风速，算一个平均值
                ConcurrentHashMap<String, Double> mapTurbineValues = mapIn.get(turbine.getTurbineId());
                //平均切入风速
                double avgCutInWindSpeed = 0;
                if (mapTurbineValues != null) {
                    AtomicReference<Double> sum = new AtomicReference<>(0.0);
                    //遍历mapTurbineValues，V大于5的舍弃，剩余算平均值
                    for (String key : mapTurbineValues.keySet()) {
                        if (mapTurbineValues.get(key) > 5) {
                            mapTurbineValues.remove(key);
                        }
                    }
                    mapTurbineValues.forEach((k1, v) -> {
                        sum.updateAndGet(v1 -> v1 + v);
                    });

                    //如果值为空则置0
                    if (sum.get() == 0) {
                        avgCutInWindSpeed = 0;
                    } else {
                        avgCutInWindSpeed = sum.get() / mapTurbineValues.size();
                    }
                    System.out.println(turbine.getTurbineId() + "切入平均风速" + avgCutInWindSpeed + "时间" + timeBegin);
                }

                //遍历map集合，取出每个风机的所有切出风速，算一个平均值
                ConcurrentHashMap<String, Double> mapTurbineValues2 = mapOut.get(turbine.getTurbineId());

                double avgCutOutWindSpeed;
                if (mapTurbineValues2 != null) {
                    AtomicReference<Double> sum = new AtomicReference<>(0.0);

                    for (String key : mapTurbineValues2.keySet()) {
                        if (mapTurbineValues2.get(key) > 5) {
                            mapTurbineValues2.remove(key);
                        }
                    }
                    mapTurbineValues2.forEach((k2, v) -> {
                        sum.updateAndGet(v1 -> v1 + v);
                    });

                    if (sum.get() == 0) {
                        avgCutOutWindSpeed = 0;
                    } else {
                        avgCutOutWindSpeed = sum.get() / mapTurbineValues2.size();
                    }
                    System.out.println(turbine.getTurbineId() + "切出平均风速" + avgCutOutWindSpeed + "时间" + timeBegin);
                }

                //存入数据库
                String turbineId = turbine.getTurbineId();
                Date jdkDate = timeBegin;
                System.out.println(turbineId + " " + jdkDate);
                QueryWrapper<TurbineInfoDay> turbineInfoDayQueryWrapper = new QueryWrapper<>();
                turbineInfoDayQueryWrapper.eq("turbine_id", turbine.getTurbineId());
                turbineInfoDayQueryWrapper.eq("record_date", timeBegin);
                TurbineInfoDay one = turbineInfoDayService.getOne(turbineInfoDayQueryWrapper);
                System.out.println(one);
                if (one == null) {
                    TurbineInfoDay turbineInfoDay = new TurbineInfoDay();
                    turbineInfoDay.setTurbineId(turbine.getTurbineId());
                    turbineInfoDay.setRecordDate(timeBegin);
                    turbineInfoDay.setXfqrfs(avgCutInWindSpeed);
                    System.out.println(turbineInfoDay);

                    interest.add(turbineInfoDay);
                    //                turbineInfoDayService.save(turbineInfoDay);
                } else {
                    one.setXfqrfs(avgCutInWindSpeed);
                    System.out.println(one);
                    //                turbineInfoDayService.updateById(one);
                    update.add(one);
                }

            }

            //        //批量插入
            //        turbineInfoDayService.saveBatch(interest);
            //        //批量更新
            //        turbineInfoDayService.updateBatchById(update);
            //        //批量插入或更新
            turbineInfoDayService.saveOrUpdateBatch(interest);
            turbineInfoDayService.saveOrUpdateBatch(update);
        }
    }

    //算额定风速
    public void calcGlqxnh_edfs() {
        //date当天零点
        DateTime timeNow00 = DateUtil.beginOfDay(new Date());
        //date昨天零点
        DateTime timeBegin00 = DateUtil.offsetDay(timeNow00, -1);
        //上个月
        DateTime timeBegin2 = DateUtil.offsetMonth(timeBegin00, -1);
        //上个月第一天
        DateTime timeBegin1 = DateUtil.beginOfMonth(timeBegin2);
        //上个月最后一天
        DateTime timeEnd2 = DateUtil.endOfMonth(timeBegin2);
        //上个月天数
        int days = (int) DateUtil.betweenDay(timeBegin1, timeEnd2, false);
        //遍历天数
        for (int i = 1; i <= days; i++) {
            DateTime end = DateUtil.offsetDay(timeBegin1, i);
            DateTime start = DateUtil.offsetDay(timeBegin1, i - 1);

            //风速
            List<PointInfo> entityFs = getEntity("AI066", "turbine");
            //功率
            List<PointInfo> entityGl = getEntity("AI114", "turbine");
            Map<String, PointInfo> glMap = entityGl.stream().collect(Collectors.toMap(PointInfo::getTurbineId, Function.identity()));

            Map<String, EquipmentModel> map = equipmentModelService.map();

            List<PointInfo> entity = new ArrayList<>();
            List<PointInfo> entity0 = getEntity("MX000", "state");
            List<PointInfo> entity1 = getEntity("MX001", "state");
            List<PointInfo> entity2 = getEntity("MX002", "state");
            List<PointInfo> entity4 = getEntity("MX004", "state");
            List<PointInfo> entity6 = getEntity("MX006", "state");
            entity.addAll(entity0);
            entity.addAll(entity1);
            entity.addAll(entity2);
            entity.addAll(entity4);
            entity.addAll(entity6);
            List<String> keys = entity.stream().map(PointInfo::getPointKey).collect(Collectors.toList());
            Map<String, PointData> latest = adapter.getHistorySection(goldenUri(), String.join(",", keys), start.getTime());
            Map<String, Map<String, PointInfo>> wtUcPis = entity.stream().collect(Collectors.groupingBy(PointInfo::getTurbineId, Collectors.toMap(PointInfo::getUniformCode, Function.identity())));

            List<PointInfo> entityAiZt = getEntity("AI422", "state");
            Map<String, PointInfo> aiztMap = entityAiZt.stream().collect(Collectors.toMap(PointInfo::getTurbineId, Function.identity()));
            List<StateAi> list = stateAiService.list();
            Map<String, Map<Integer, Integer>> collectAi = list.stream().collect(Collectors.groupingBy(StateAi::getModel, Collectors.toMap(StateAi::getOriginalState, StateAi::getMappingState)));

            //        Map<String, Map<Double,Double>> fitMap = new HashMap<>();

            //插入集合
            List<TurbineInfoDay> interest = new ArrayList<>();
            //更新集合
            List<TurbineInfoDay> update = new ArrayList<>();


            for (PointInfo ef : entityFs) {
                String wtId = ef.getTurbineId();
                PointInfo glInfo = glMap.get(wtId);
                getSnapDataByEntity(ef, start, end, 60);
                getSnapDataByEntity(glInfo, start, end, 60);
                List<PointData> peek = ef.getPointDatas().stream().peek(pd -> pd.setDoubleValue(NumberUtil.round(pd.getValue(), 2).doubleValue())).collect(Collectors.toList());
                ef.setPointDatas(peek);

                try {
                    PointInfo turbineZt = calcTurbineDizt2(wtUcPis.get(wtId), latest, start, end, 60);
                    PointInfo turbineAizt = calcTurbineAizt2(aiztMap.get(wtId), collectAi, start, end, 60);


                    Map<Double, Double> fit = new TreeMap<>();
                    double capacity = 2000;
                    if (turbineZt != null) {
                        System.out.println("数据处理拟合");
                        capacity = map.get(turbineZt.getSpare()).getPowerProduction();
                        fit = dataProcessAndFit(ef, glInfo, turbineZt, CalcCache.bzgl.get(turbineZt.getSpare()), capacity);
                        //                fitMap.put(wtId, fit);
                        turbineZt.setPointDatas(null);
                    }
                    if (turbineAizt != null) {
                        System.out.println("数据处理拟合");
                        capacity = map.get(turbineAizt.getSpare()).getPowerProduction();
                        fit = dataProcessAndFit(ef, glInfo, turbineAizt, CalcCache.bzgl.get(turbineAizt.getSpare()), capacity);
                        //                fitMap.put(wtId, fit);
                        turbineAizt.setPointDatas(null);
                    }
                    ef.setPointDatas(null);
                    glInfo.setPointDatas(null);

                    //存redis
                    //            stringRedisTemplate.opsForValue().set("glqxnh:" + end.getMonth() + ":" + wtId, JSON.toJSONString(fit));

                    System.out.println("拟合曲线的大小" + fit.size() + ":" + wtId);

                    //符合条件的风速和
                    List<Double> listDouble = new ArrayList<>();
                    //遍历fit集合，取出值与capacity相等的key
                    if (!fit.isEmpty()) {
                        for (double key : fit.keySet()) {
                            Double v = fit.get(key);
                            //如果v-capacity的值小于10大于-10，则把key加入listDouble
                            if ((Math.abs(v - capacity) <= 10) && Math.abs(v - capacity) >= -10) {
                                listDouble.add(key);
                            }
                        }
                    }
                    //取出listDouble的值求平均值
                    double agValue = 0;
                    if (!listDouble.isEmpty()) {
                        for (Double aDouble : listDouble) {
                            agValue += aDouble;
                        }
                        agValue = agValue / listDouble.size();
                    }
                    System.out.println("wtId:" + wtId + "agValue平均额定风速:" + agValue);


                    //存入数据库
                    System.out.println(wtId + " " + start);
                    QueryWrapper<TurbineInfoDay> turbineInfoDayQueryWrapper = new QueryWrapper<>();
                    turbineInfoDayQueryWrapper.eq("turbine_id", wtId);
                    turbineInfoDayQueryWrapper.eq("record_date", start);
                    TurbineInfoDay one = turbineInfoDayService.getOne(turbineInfoDayQueryWrapper);
                    System.out.println(one);
                    if (one == null) {
                        TurbineInfoDay turbineInfoDay = new TurbineInfoDay();
                        turbineInfoDay.setTurbineId(wtId);
                        turbineInfoDay.setRecordDate(start);
                        turbineInfoDay.setEdfs(agValue);
                        System.out.println(turbineInfoDay);
                        //                    turbineInfoDayService.save(turbineInfoDay);
                        interest.add(turbineInfoDay);
                    } else {
                        one.setEdfs(agValue);
                        System.out.println(one);
                        //                    turbineInfoDayService.updateById(one);
                        update.add(one);
                    }

                } catch (Exception e) {
                    System.out.println(wtId + " " + start);
                }


            }


            //        //批量插入
            //        turbineInfoDayService.saveBatch(interest);
            //        //批量更新
            //        turbineInfoDayService.updateBatchById(update);
            //        //批量插入或更新
            turbineInfoDayService.saveOrUpdateBatch(interest);
            turbineInfoDayService.saveOrUpdateBatch(update);
        }


        //        stringRedisTemplate.opsForValue().set("glqxnh", JSON.toJSONString(fitMap));
    }

    //环境温度
    public void ambientTemperature() {
        //date当天零点
        DateTime timeNow = DateUtil.beginOfDay(new Date());
        //date昨天零点
        DateTime timeBegin = DateUtil.offsetDay(timeNow, -1);


        //所有风机的温度
        QueryWrapper<PointInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uniform_code", "AI072");

        List<PointInfo> pointInfos = getEntity("AI072", "turbine");

        //插入集合
        List<TurbineInfoDay> interest = new ArrayList<>();
        //更新集合
        List<TurbineInfoDay> update = new ArrayList<>();


        //遍历pointInfos
        for (PointInfo turbine : pointInfos) {
            List<PointData> pointDatas = adapter.getHistorySnap(goldenUri(), turbine.getPointKey(), timeBegin.getTime(), timeNow.getTime(), 10);
            //遍历pointDatas,取出数据算平均值
            double avgCutInWindSpeed = 0;
            for (PointData pointData : pointDatas) {
                avgCutInWindSpeed += pointData.getValue();
            }
            avgCutInWindSpeed /= pointDatas.size();

            //存入数据库
            String turbineId = turbine.getTurbineId();
            Date jdkDate = timeBegin;
            System.out.println(turbineId + " " + jdkDate);
            QueryWrapper<TurbineInfoDay> turbineInfoDayQueryWrapper = new QueryWrapper<>();
            turbineInfoDayQueryWrapper.eq("turbine_id", turbine.getTurbineId());
            turbineInfoDayQueryWrapper.eq("record_date", timeBegin);
            TurbineInfoDay one = turbineInfoDayService.getOne(turbineInfoDayQueryWrapper);
            System.out.println(one);
            if (one == null) {
                TurbineInfoDay turbineInfoDay = new TurbineInfoDay();
                turbineInfoDay.setTurbineId(turbine.getTurbineId());
                turbineInfoDay.setRecordDate(timeBegin);
                turbineInfoDay.setHjwd(avgCutInWindSpeed);
                System.out.println(turbineInfoDay);
                interest.add(turbineInfoDay);
                //                turbineInfoDayService.save(turbineInfoDay);
            } else {
                one.setHjwd(avgCutInWindSpeed);
                System.out.println(one);
                update.add(one);
                //                turbineInfoDayService.updateById(one);
            }

        }
        //        //批量插入
        //        turbineInfoDayService.saveBatch(interest);
        //        //批量更新
        //        turbineInfoDayService.updateBatchById(update);
        //        //批量插入或更新
        turbineInfoDayService.saveOrUpdateBatch(interest);
        turbineInfoDayService.saveOrUpdateBatch(update);


    }

    public void writeReportPool(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);
        DateTime beginOfMonth = DateUtil.beginOfMonth(time0);
        DateTime beginOfYear = DateUtil.beginOfYear(time0);

        QueryWrapper<StationInfoDay> wrapper = new QueryWrapper<>();
        wrapper.eq("record_date", time0);
        List<StationInfoDay> days = stationInfoDayService.list(wrapper);
        Map<String, StationInfoDay> dayMap = days.stream().collect(Collectors.toMap(StationInfoDay::getStationId, Function.identity()));
        wrapper = new QueryWrapper<>();
        wrapper.select("sum(rfdl) rfdl,sum(swdl) swdl,sum(gwdl) gwdl,sum(cydl) cydl,sum(zhcydl) zhcydl,station_id").between("record_date", beginOfMonth, time0).groupBy("station_id");
        List<StationInfoDay> monthDays = stationInfoDayService.list(wrapper);
        Map<String, StationInfoDay> monthMap = monthDays.stream().collect(Collectors.toMap(StationInfoDay::getStationId, Function.identity()));
        wrapper = new QueryWrapper<>();
        wrapper.select("sum(rfdl) rfdl,sum(swdl) swdl,sum(gwdl) gwdl,sum(cydl) cydl,sum(zhcydl) zhcydl,station_id").between("record_date", beginOfYear, time0).groupBy("station_id");
        List<StationInfoDay> yearDays = stationInfoDayService.list(wrapper);
        Map<String, StationInfoDay> yearMap = yearDays.stream().collect(Collectors.toMap(StationInfoDay::getStationId, Function.identity()));

        //        QueryWrapper<ProEconReportIndicatorPool> wrapperrp = new QueryWrapper<>();
        //        wrapperrp.eq("record_date", time0).last("and foreign_key_id = windpowerstation_id");
        //        List<ProEconReportIndicatorPool> pools = reportIndicatorPoolService.list(wrapperrp);

        QueryWrapper<ProEconReportIndicatorPool> wrapperrp = new QueryWrapper<>();
        wrapperrp.eq("record_date", time0).in("foreign_key_id", days.stream().map(StationInfoDay::getStationId).collect(Collectors.toList()));
        List<ProEconReportIndicatorPool> pools = reportIndicatorPoolService.list(wrapperrp);

        if (!pools.isEmpty()) {
            StationInfoDay day, month, year;
            List<ProEconReportIndicatorPool> poolList = new ArrayList<>();
            for (ProEconReportIndicatorPool pool : pools) {
                String stationId = pool.getForeignKeyId();
                day = dayMap.get(stationId);
                pool.setRfdldb(day.getRfdl().doubleValue());
                pool.setRswdldb(day.getSwdl().doubleValue());
                pool.setRgwgwdldb(day.getGwdl().doubleValue());
                pool.setRfdcydldb(day.getCydl().doubleValue());
                pool.setRzhcydldb(day.getZhcydl().doubleValue());
                month = monthMap.get(stationId);
                pool.setYfdldb(month.getRfdl().doubleValue());
                pool.setYswdldb(month.getSwdl().doubleValue());
                pool.setYgwgwdldb(month.getGwdl().doubleValue());
                pool.setYfdcydldb(month.getCydl().doubleValue());
                pool.setYzhcydldb(month.getZhcydl().doubleValue());
                year = yearMap.get(stationId);
                pool.setNfdldb(year.getRfdl().doubleValue());
                pool.setNswdldb(year.getSwdl().doubleValue());
                pool.setNgwgwdldb(year.getGwdl().doubleValue());
                pool.setNfdcydldb(year.getCydl().doubleValue());
                pool.setNzhcydldb(year.getZhcydl().doubleValue());
                poolList.add(pool);
            }
            reportIndicatorPoolService.saveOrUpdateBatch(poolList);
        } else {

            List<ProEconReportIndicatorPool> poolList = new ArrayList<>();
            for (StationInfoDay day : days) {
                ProEconReportIndicatorPool pool = new ProEconReportIndicatorPool();
                pool.setRecordDate(time0);
                pool.setForeignKeyId(day.getStationId());
                poolList.add(pool);
            }
            reportIndicatorPoolService.saveOrUpdateBatch(poolList);

        }


    }

    public void writeReportPoolSameDay() {
        //date当天零点
        DateTime time0 = DateUtil.beginOfDay(DateUtil.date());
        DateTime beginOfMonth = DateUtil.beginOfMonth(time0);
        DateTime beginOfYear = DateUtil.beginOfYear(time0);

        QueryWrapper<StationInfoDay> wrapper = new QueryWrapper<>();
        wrapper.eq("record_date", time0);
        List<StationInfoDay> days = stationInfoDayService.list(wrapper);
        Map<String, StationInfoDay> dayMap = days.stream().collect(Collectors.toMap(StationInfoDay::getStationId, Function.identity()));
        wrapper = new QueryWrapper<>();
        wrapper.select("sum(rfdl) rfdl,sum(swdl) swdl,sum(gwdl) gwdl,sum(cydl) cydl,sum(zhcydl) zhcydl,station_id").between("record_date", beginOfMonth, time0).groupBy("station_id");
        List<StationInfoDay> monthDays = stationInfoDayService.list(wrapper);
        Map<String, StationInfoDay> monthMap = monthDays.stream().collect(Collectors.toMap(StationInfoDay::getStationId, Function.identity()));
        wrapper = new QueryWrapper<>();
        wrapper.select("sum(rfdl) rfdl,sum(swdl) swdl,sum(gwdl) gwdl,sum(cydl) cydl,sum(zhcydl) zhcydl,station_id").between("record_date", beginOfYear, time0).groupBy("station_id");
        List<StationInfoDay> yearDays = stationInfoDayService.list(wrapper);
        Map<String, StationInfoDay> yearMap = yearDays.stream().collect(Collectors.toMap(StationInfoDay::getStationId, Function.identity()));

        QueryWrapper<ProEconReportIndicatorPool> wrapperRp = new QueryWrapper<>();
        wrapperRp.eq("record_date", time0).last("and foreign_key_id = windpowerstation_id");
        List<ProEconReportIndicatorPool> pools = reportIndicatorPoolService.list(wrapperRp);
        wrapperRp = new QueryWrapper<>();
        wrapperRp.eq("record_date", time0).eq("foreign_key_id", "GJNY_SXGS_DBXNY_ZGS0");
        ProEconReportIndicatorPool poolsCompany = reportIndicatorPoolService.getOne(wrapperRp);

        StationInfoDay day, month, year;
        if (pools.isEmpty()) {
            pools = new ArrayList<>();
            for (StationInfoDay infoDay : days) {
                String stationId = infoDay.getStationId();
                ProEconReportIndicatorPool pool = new ProEconReportIndicatorPool();
                pool.setRecordDate(time0);
                pool.setForeignKeyId(stationId);
                pool.setWindpowerstationId(stationId);
                month = monthMap.get(stationId);
                year = yearMap.get(stationId);
                poolSetValueDl1(pool, infoDay, month, year);
                pools.add(pool);
            }
        } else {
            for (ProEconReportIndicatorPool pool : pools) {
                String stationId = pool.getWindpowerstationId();
                day = dayMap.get(stationId);
                month = monthMap.get(stationId);
                year = yearMap.get(stationId);
                poolSetValueDl1(pool, day, month, year);
            }
        }
        reportIndicatorPoolService.saveOrUpdateBatch(pools);
        if (poolsCompany == null) {
            poolsCompany = new ProEconReportIndicatorPool();
            poolsCompany.setRecordDate(time0);
            poolsCompany.setForeignKeyId("GJNY_SXGS_DBXNY_ZGS0");
            poolsCompany.setCompanyId("GJNY_SXGS_DBXNY_ZGS");
            poolSetValueDl(poolsCompany, pools);
        } else {
            poolSetValueDl(poolsCompany, pools);
        }
        reportIndicatorPoolService.saveOrUpdate(poolsCompany);
    }

    public void poolSetValueDl1(ProEconReportIndicatorPool pool, StationInfoDay day, StationInfoDay month, StationInfoDay year) {
        pool.setRfdldb(day.getRfdl().doubleValue());
        pool.setRswdldb(day.getSwdl().doubleValue());
        pool.setRgwgwdldb(day.getGwdl().doubleValue());
        pool.setRfdcydldb(day.getCydl().doubleValue());
        pool.setRzhcydldb(day.getZhcydl().doubleValue());
        pool.setYfdldb(month.getRfdl().doubleValue());
        pool.setYswdldb(month.getSwdl().doubleValue());
        pool.setYgwgwdldb(month.getGwdl().doubleValue());
        pool.setYfdcydldb(month.getCydl().doubleValue());
        pool.setYzhcydldb(month.getZhcydl().doubleValue());
        pool.setNfdldb(year.getRfdl().doubleValue());
        pool.setNswdldb(year.getSwdl().doubleValue());
        pool.setNgwgwdldb(year.getGwdl().doubleValue());
        pool.setNfdcydldb(year.getCydl().doubleValue());
        pool.setNzhcydldb(year.getZhcydl().doubleValue());
    }

    public void poolSetValueDl(ProEconReportIndicatorPool pool, LineInfoDay day, LineInfoDay month, LineInfoDay year) {
        pool.setRfdldb(day.getRfdl().doubleValue());
        pool.setRswdldb(day.getSwdl());
        pool.setRgwgwdldb(day.getGwdl());
        pool.setRfdcydldb(day.getCydl());
        pool.setRzhcydldb(day.getRfdl().doubleValue() + day.getGwdl() - day.getSwdl());
        pool.setYfdldb(month.getRfdl().doubleValue());
        pool.setYswdldb(month.getSwdl());
        pool.setYgwgwdldb(month.getGwdl());
        pool.setYfdcydldb(month.getCydl());
        pool.setYzhcydldb(month.getRfdl().doubleValue() + month.getGwdl() - month.getSwdl());
        pool.setNfdldb(year.getRfdl().doubleValue());
        pool.setNswdldb(year.getSwdl());
        pool.setNgwgwdldb(year.getGwdl());
        pool.setNfdcydldb(year.getCydl());
        pool.setNzhcydldb(year.getRfdl().doubleValue() + year.getGwdl() - year.getSwdl());
    }

    public void poolSetValueDl(ProEconReportIndicatorPool pool, List<ProEconReportIndicatorPool> pools) {
        ProEconReportIndicatorPool p = sumProperties(pools, ProEconReportIndicatorPool.class);
        pool.setRfdldb(p.getRfdldb());
        pool.setRswdldb(p.getRswdldb());
        pool.setRgwgwdldb(p.getRgwgwdldb());
        pool.setRfdcydldb(p.getRfdcydldb());
        pool.setRzhcydldb(p.getRzhcydldb());
        pool.setYfdldb(p.getYfdldb());
        pool.setYswdldb(p.getYswdldb());
        pool.setYgwgwdldb(p.getYgwgwdldb());
        pool.setYfdcydldb(p.getYfdcydldb());
        pool.setYzhcydldb(p.getYzhcydldb());
        pool.setNfdldb(p.getNfdldb());
        pool.setNswdldb(p.getNswdldb());
        pool.setNgwgwdldb(p.getNgwgwdldb());
        pool.setNfdcydldb(p.getNfdcydldb());
        pool.setNzhcydldb(p.getNzhcydldb());
    }

    public void writeReportPoolProject(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);
        DateTime beginOfMonth = DateUtil.beginOfMonth(time0);
        DateTime beginOfYear = DateUtil.beginOfYear(time0);

        QueryWrapper<LineInfoDay> wrapper = new QueryWrapper<>();
        wrapper.select("sum(rfdl) rfdl,sum(swdl) swdl,sum(gwdl) gwdl,sum(cydl) cydl,project_id").eq("record_date", time0).groupBy("project_id");
        List<LineInfoDay> days = lineInfoDayService.list(wrapper);
        Map<String, LineInfoDay> dayMap = days.stream().collect(Collectors.toMap(LineInfoDay::getProjectId, Function.identity()));
        wrapper = new QueryWrapper<>();
        wrapper.select("sum(rfdl) rfdl,sum(swdl) swdl,sum(gwdl) gwdl,sum(cydl) cydl,project_id").between("record_date", beginOfMonth, time0).groupBy("project_id");
        List<LineInfoDay> monthDays = lineInfoDayService.list(wrapper);
        Map<String, LineInfoDay> monthMap = monthDays.stream().collect(Collectors.toMap(LineInfoDay::getProjectId, Function.identity()));
        wrapper = new QueryWrapper<>();
        wrapper.select("sum(rfdl) rfdl,sum(swdl) swdl,sum(gwdl) gwdl,sum(cydl) cydl,project_id").between("record_date", beginOfYear, time0).groupBy("project_id");
        List<LineInfoDay> yearDays = lineInfoDayService.list(wrapper);
        Map<String, LineInfoDay> yearMap = yearDays.stream().collect(Collectors.toMap(LineInfoDay::getProjectId, Function.identity()));

        //        QueryWrapper<ProEconReportIndicatorPool> wrapperrp = new QueryWrapper<>();
        //        wrapperrp.eq("record_date", time0).last("and foreign_key_id = project_id");
        //        List<ProEconReportIndicatorPool> pools = reportIndicatorPoolService.list(wrapperrp);


        QueryWrapper<ProEconReportIndicatorPool> wrapperrp2 = new QueryWrapper<>();
        wrapperrp2.eq("record_date", time0).in("foreign_key_id", days.stream().map(LineInfoDay::getProjectId).collect(Collectors.toList()));
        List<ProEconReportIndicatorPool> pools2 = reportIndicatorPoolService.list(wrapperrp2);

        if (!pools2.isEmpty()) {
            LineInfoDay day, month, year;
            List<ProEconReportIndicatorPool> poolList = new ArrayList<>();
            String projectId;
            for (ProEconReportIndicatorPool pool : pools2) {
                projectId = pool.getForeignKeyId();
                day = dayMap.get(projectId);
                pool.setRfdldb(day.getRfdl().doubleValue());
                pool.setRswdldb(day.getSwdl());
                pool.setRgwgwdldb(day.getGwdl());
                pool.setRfdcydldb(day.getCydl());
                pool.setRzhcydldb(day.getRfdl().doubleValue() + day.getGwdl() - day.getSwdl());
                month = monthMap.get(projectId);
                pool.setYfdldb(month.getRfdl().doubleValue());
                pool.setYswdldb(month.getSwdl());
                pool.setYgwgwdldb(month.getGwdl());
                pool.setYfdcydldb(month.getCydl());
                pool.setRzhcydldb(month.getRfdl().doubleValue() + month.getGwdl() - month.getSwdl());
                year = yearMap.get(projectId);
                pool.setNfdldb(year.getRfdl().doubleValue());
                pool.setNswdldb(year.getSwdl());
                pool.setNgwgwdldb(year.getGwdl());
                pool.setNfdcydldb(year.getCydl());
                pool.setRzhcydldb(year.getRfdl().doubleValue() + year.getGwdl() - year.getSwdl());
                poolList.add(pool);
            }
            reportIndicatorPoolService.saveOrUpdateBatch(poolList);
        } else {

            List<ProEconReportIndicatorPool> poolList = new ArrayList<>();
            for (LineInfoDay day : days) {
                ProEconReportIndicatorPool pool = new ProEconReportIndicatorPool();
                pool.setRecordDate(time0);
                pool.setForeignKeyId(day.getProjectId());
                poolList.add(pool);
            }
            reportIndicatorPoolService.saveOrUpdateBatch(poolList);

        }
    }

    public void writeReportPoolProjectSameDay() {
        //date当天零点
        DateTime time0 = DateUtil.beginOfDay(DateUtil.date());
        DateTime beginOfMonth = DateUtil.beginOfMonth(time0);
        DateTime beginOfYear = DateUtil.beginOfYear(time0);

        QueryWrapper<LineInfoDay> wrapper = new QueryWrapper<>();
        wrapper.select("sum(rfdl) rfdl,sum(swdl) swdl,sum(gwdl) gwdl,sum(cydl) cydl,project_id,station_id").eq("record_date", time0).groupBy("project_id,station_id");
        List<LineInfoDay> days = lineInfoDayService.list(wrapper);
        Map<String, LineInfoDay> dayMap = days.stream().collect(Collectors.toMap(LineInfoDay::getProjectId, Function.identity()));
        wrapper = new QueryWrapper<>();
        wrapper.select("sum(rfdl) rfdl,sum(swdl) swdl,sum(gwdl) gwdl,sum(cydl) cydl,project_id,station_id").between("record_date", beginOfMonth, time0).groupBy("project_id,station_id");
        List<LineInfoDay> monthDays = lineInfoDayService.list(wrapper);
        Map<String, LineInfoDay> monthMap = monthDays.stream().collect(Collectors.toMap(LineInfoDay::getProjectId, Function.identity()));
        wrapper = new QueryWrapper<>();
        wrapper.select("sum(rfdl) rfdl,sum(swdl) swdl,sum(gwdl) gwdl,sum(cydl) cydl,project_id,station_id").between("record_date", beginOfYear, time0).groupBy("project_id,station_id");
        List<LineInfoDay> yearDays = lineInfoDayService.list(wrapper);
        Map<String, LineInfoDay> yearMap = yearDays.stream().collect(Collectors.toMap(LineInfoDay::getProjectId, Function.identity()));

        QueryWrapper<ProEconReportIndicatorPool> wrapperRp = new QueryWrapper<>();
        wrapperRp.eq("record_date", time0).last("and foreign_key_id = project_id");
        List<ProEconReportIndicatorPool> pools = reportIndicatorPoolService.list(wrapperRp);

        LineInfoDay day, month, year;
        if (pools.isEmpty()) {
            pools = new ArrayList<>();
            for (LineInfoDay infoDay : days) {
                String projectId = infoDay.getProjectId();
                ProEconReportIndicatorPool pool = new ProEconReportIndicatorPool();
                pool.setRecordDate(time0);
                pool.setForeignKeyId(projectId);
                pool.setWindpowerstationId(infoDay.getStationId());
                pool.setProjectId(projectId);
                month = monthMap.get(projectId);
                year = yearMap.get(projectId);
                poolSetValueDl(pool, infoDay, month, year);
                pools.add(pool);
            }
        } else {
            for (ProEconReportIndicatorPool pool : pools) {
                String projectId = pool.getProjectId();
                day = dayMap.get(projectId);
                month = monthMap.get(projectId);
                year = yearMap.get(projectId);
                poolSetValueDl(pool, day, month, year);
            }
        }
        reportIndicatorPoolService.saveOrUpdateBatch(pools);
    }

    public void writeReportPoolPjfs(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);
        DateTime beginOfMonth = DateUtil.beginOfMonth(time0);
        DateTime beginOfYear = DateUtil.beginOfYear(time0);

        QueryWrapper<TurbineInfoDay> wrapper = new QueryWrapper<>();
        wrapper.select("avg(pjfs) pjfs,project_id").eq("record_date", time0).groupBy("project_id");
        List<TurbineInfoDay> days = turbineInfoDayService.list(wrapper);
        Map<String, TurbineInfoDay> dayMap = days.stream().collect(Collectors.toMap(TurbineInfoDay::getProjectId, Function.identity()));
        wrapper = new QueryWrapper<>();
        wrapper.select("avg(pjfs) pjfs,project_id").between("record_date", beginOfMonth, time0).groupBy("project_id");
        List<TurbineInfoDay> monthDays = turbineInfoDayService.list(wrapper);
        Map<String, TurbineInfoDay> monthMap = monthDays.stream().collect(Collectors.toMap(TurbineInfoDay::getProjectId, Function.identity()));
        wrapper = new QueryWrapper<>();
        wrapper.select("avg(pjfs) pjfs,project_id").between("record_date", beginOfYear, time0).groupBy("project_id");
        List<TurbineInfoDay> yearDays = turbineInfoDayService.list(wrapper);
        Map<String, TurbineInfoDay> yearMap = yearDays.stream().collect(Collectors.toMap(TurbineInfoDay::getProjectId, Function.identity()));

        //        QueryWrapper<ProEconReportIndicatorPool> wrapperrp = new QueryWrapper<>();
        //        wrapperrp.eq("record_date", time0).last("and foreign_key_id = project_id");

        QueryWrapper<ProEconReportIndicatorPool> wrapperrp = new QueryWrapper<>();
        wrapperrp.eq("record_date", time0).in("foreign_key_id", days.stream().map(TurbineInfoDay::getProjectId).collect(Collectors.toList()));
        List<ProEconReportIndicatorPool> pools = reportIndicatorPoolService.list(wrapperrp);


        QueryWrapper<ProEconReportIndicatorPool> wrapperrp2 = new QueryWrapper<>();
        wrapperrp2.eq("record_date", time0).eq("foreign_key_id", "GJNY_SXGS_DBXNY_ZGS0");
        ProEconReportIndicatorPool pools2 = reportIndicatorPoolService.getOne(wrapperrp2);

        if (pools2 == null) {
            ProEconReportIndicatorPool GSPJFS = new ProEconReportIndicatorPool();
            GSPJFS.setRecordDate(time0);
            GSPJFS.setForeignKeyId("GJNY_SXGS_DBXNY_ZGS0");
            GSPJFS.setCompanyId("GJNY_SXGS_DBXNY_ZGS");
            reportIndicatorPoolService.saveOrUpdate(GSPJFS);
        }


        TurbineInfoDay day, month, year;
        String projectId;

        if (!pools.isEmpty()) {
            for (ProEconReportIndicatorPool pool : pools) {
                projectId = pool.getForeignKeyId();
                day = dayMap.get(projectId);
                pool.setRpjfs(day.getPjfs());
                month = monthMap.get(projectId);
                pool.setYpjfs(month.getPjfs());
                year = yearMap.get(projectId);
                pool.setNpjfs(year.getPjfs());
            }
            double v1 = pools.stream().mapToDouble(ProEconReportIndicatorPool::getRpjfs).average().orElse(0);
            double v2 = pools.stream().mapToDouble(ProEconReportIndicatorPool::getYpjfs).average().orElse(0);
            double v3 = pools.stream().mapToDouble(ProEconReportIndicatorPool::getNpjfs).average().orElse(0);
            if (!(pools2 == null)) {
                pools2.setRpjfs(v1);
                pools2.setYpjfs(v2);
                pools2.setNpjfs(v3);
                reportIndicatorPoolService.saveOrUpdate(pools2);
            }
            reportIndicatorPoolService.saveOrUpdateBatch(pools);
        } else {
            List<ProEconReportIndicatorPool> poolList = new ArrayList<>();
            for (TurbineInfoDay day2 : days) {
                ProEconReportIndicatorPool pool = new ProEconReportIndicatorPool();
                pool.setRecordDate(time0);
                pool.setForeignKeyId(day2.getProjectId());
                poolList.add(pool);
            }
            reportIndicatorPoolService.saveOrUpdateBatch(poolList);

        }

    }

    public void gongsizhibiao(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);
        DateTime beginOfMonth = DateUtil.beginOfMonth(time0);
        DateTime beginOfYear = DateUtil.beginOfYear(time0);

        QueryWrapper<ProEconReportIndicatorPool> wrapper = new QueryWrapper<>();
        wrapper.eq("record_date", time0)
                //包含"STA"
                .like("foreign_key_id", "_STA");
        List<ProEconReportIndicatorPool> list = reportIndicatorPoolService.list(wrapper);
        //遍历list,累加指标RFDL

        //公司指标,日发电量
        double rfdl = 0;
        //公司指标,日上网电量
        double swdl = 0;
        //公司指标,日购网电量
        double gwdl = 0;
        //公司指标,日综合厂用电量
        double zhcydl = 0;

        //公司指标,月发电量
        double yfdl = 0;
        //公司指标,月上网电量
        double yswdl = 0;
        //公司指标,月购网电量
        double ygwdl = 0;
        //公司指标,月综合厂用电量
        double yzhcydl = 0;

        //公司指标,年发电量
        double nfdl = 0;
        //公司指标,年上网电量
        double nswdl = 0;
        //公司指标,年购网电量
        double ngwdl = 0;
        //公司指标,年综合厂用电量
        double nzhcydl = 0;


        for (ProEconReportIndicatorPool pool : list) {
            rfdl += pool.getRfdldb();
            swdl += pool.getRswdldb();
            gwdl += pool.getRgwgwdldb();
            zhcydl += pool.getRzhcydldb();
            yfdl += pool.getYfdldb();
            yswdl += pool.getYswdldb();
            ygwdl += pool.getYgwgwdldb();
            yzhcydl += pool.getYzhcydldb();
            nfdl += pool.getNfdldb();
            nswdl += pool.getNswdldb();
            ngwdl += pool.getNgwgwdldb();
            nzhcydl += pool.getNzhcydldb();
        }

        QueryWrapper<ProEconReportIndicatorPool> wrapperrp2 = new QueryWrapper<>();
        wrapperrp2.eq("record_date", time0).eq("foreign_key_id", "GJNY_SXGS_DBXNY_ZGS0");
        ProEconReportIndicatorPool GSZB = reportIndicatorPoolService.getOne(wrapperrp2);
        //公司指标集合
        GSZB.setRfdldb(rfdl);
        GSZB.setRswdldb(swdl);
        GSZB.setRgwgwdldb(gwdl);
        GSZB.setRzhcydldb(zhcydl);
        GSZB.setYfdldb(yfdl);
        GSZB.setYswdldb(yswdl);
        GSZB.setYgwgwdldb(ygwdl);
        GSZB.setYzhcydldb(yzhcydl);
        GSZB.setNfdldb(nfdl);
        GSZB.setNswdldb(nswdl);
        GSZB.setNgwgwdldb(ngwdl);
        GSZB.setNzhcydldb(nzhcydl);

        reportIndicatorPoolService.saveOrUpdate(GSZB);


    }

    //公司指标，累加风机理论发电量
    public void writeReportPoolLLFDL(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);
        DateTime beginOfMonth = DateUtil.beginOfMonth(time0);
        DateTime beginOfYear = DateUtil.beginOfYear(time0);

        QueryWrapper<TurbineInfoDay> wrapper = new QueryWrapper<>();
        wrapper.select("avg(llfdl) llfdl,project_id").eq("record_date", time0).groupBy("project_id");
        List<TurbineInfoDay> days = turbineInfoDayService.list(wrapper);
        Map<String, TurbineInfoDay> dayMap = days.stream().collect(Collectors.toMap(TurbineInfoDay::getProjectId, Function.identity()));
        wrapper = new QueryWrapper<>();
        wrapper.select("avg(llfdl) llfdl,project_id").between("record_date", beginOfMonth, time0).groupBy("project_id");
        List<TurbineInfoDay> monthDays = turbineInfoDayService.list(wrapper);
        Map<String, TurbineInfoDay> monthMap = monthDays.stream().collect(Collectors.toMap(TurbineInfoDay::getProjectId, Function.identity()));
        wrapper = new QueryWrapper<>();
        wrapper.select("avg(llfdl) llfdl,project_id").between("record_date", beginOfYear, time0).groupBy("project_id");
        List<TurbineInfoDay> yearDays = turbineInfoDayService.list(wrapper);
        Map<String, TurbineInfoDay> yearMap = yearDays.stream().collect(Collectors.toMap(TurbineInfoDay::getProjectId, Function.identity()));


        QueryWrapper<ProEconReportIndicatorPool> wrapperrp = new QueryWrapper<>();
        wrapperrp.eq("record_date", time0).in("foreign_key_id", days.stream().map(TurbineInfoDay::getProjectId).collect(Collectors.toList()));
        List<ProEconReportIndicatorPool> pools = reportIndicatorPoolService.list(wrapperrp);


        QueryWrapper<ProEconReportIndicatorPool> wrapperrp2 = new QueryWrapper<>();
        wrapperrp2.eq("record_date", time0).eq("foreign_key_id", "GJNY_SXGS_DBXNY_ZGS0");
        ProEconReportIndicatorPool pools2 = reportIndicatorPoolService.getOne(wrapperrp2);

        if (pools2 == null) {
            ProEconReportIndicatorPool GSPJFS = new ProEconReportIndicatorPool();
            GSPJFS.setRecordDate(time0);
            GSPJFS.setForeignKeyId("GJNY_SXGS_DBXNY_ZGS0");
            GSPJFS.setCompanyId("GJNY_SXGS_DBXNY_ZGS");
            reportIndicatorPoolService.saveOrUpdate(GSPJFS);
        }


        TurbineInfoDay day, month, year;
        String projectId;

        if (!pools.isEmpty()) {
            for (ProEconReportIndicatorPool pool : pools) {
                projectId = pool.getForeignKeyId();
                day = dayMap.get(projectId);
                pool.setRllfdl(day.getLlfdl());
                month = monthMap.get(projectId);
                pool.setYllfdl(month.getLlfdl());
                year = yearMap.get(projectId);
                pool.setNllfdl(year.getLlfdl());
            }
            double v1 = pools.stream().mapToDouble(ProEconReportIndicatorPool::getRllfdl).sum();
            double v2 = pools.stream().mapToDouble(ProEconReportIndicatorPool::getYllfdl).sum();
            double v3 = pools.stream().mapToDouble(ProEconReportIndicatorPool::getNllfdl).sum();
            //pools.stream().mapToDouble(ProEconReportIndicatorPool::getRllfdl)，求和


            if (pools2 != null) {
                pools2.setRllfdl(v1);
                pools2.setYllfdl(v2);
                pools2.setNllfdl(v3);
                reportIndicatorPoolService.saveOrUpdate(pools2);
            }
            reportIndicatorPoolService.saveOrUpdateBatch(pools);
        } else {
            List<ProEconReportIndicatorPool> poolList = new ArrayList<>();
            for (TurbineInfoDay day2 : days) {
                ProEconReportIndicatorPool pool = new ProEconReportIndicatorPool();
                pool.setRecordDate(time0);
                pool.setForeignKeyId(day2.getProjectId());
                poolList.add(pool);
            }
            reportIndicatorPoolService.saveOrUpdateBatch(poolList);

        }

    }

    public void calcRealtimeTurbineZt() {
        DateTime date0 = DateUtil.date();
        boolean isOnMin = false;
        //分钟变化
        if (CalcCache.minuteNow.minute() != date0.minute()) {
            date0 = DateUtil.beginOfMinute(date0);
            CalcCache.minuteNow = date0;
            isOnMin = true;
        }
        DateTime date = date0;

        List<PointInfo> turbineZt = calcRealtimeTurbineDizt();
        List<PointInfo> turbineAizt = calcRealtimeTurbineAizt();
        turbineZt.addAll(turbineAizt);
        turbineZt = turbineZt.stream().peek(t -> {
            if (t.getPointDatas().get(0).getTs() + 35 * 60 * 1000 <= date.getTime()) {
                t.getPointDatas().get(0).setDoubleValue(12.0);
            }
        }).collect(Collectors.toList());
        Map<String, Map<String, PointInfo>> ztMapMap = turbineZt.stream().collect(Collectors.groupingBy(PointInfo::getStationId, Collectors.toMap(PointInfo::getTurbineId, Function.identity())));
        //AGC
        List<PointInfo> entityAgc = getEntity("AGC002", "booster");
        getSnapDataByEntity(entityAgc, DateUtil.offsetMinute(date, -5), date, 15);
        //出线
        List<PointInfo> entityCx = getEntity("AGC001", "booster");
        getSnapDataByEntity(entityCx, DateUtil.offsetMinute(date, -5), date, 15);
        //风速
        List<PointInfo> entityFs = getEntity("AI066", "turbine");
        getSnapDataByEntity(entityFs, DateUtil.offsetMinute(date, -5), date, 15);

        Map<String, PointInfo> collectAgc = entityAgc.stream().collect(Collectors.toMap(PointInfo::getStationId, Function.identity()));
        Map<String, PointInfo> collectCx = entityCx.stream().collect(Collectors.toMap(PointInfo::getStationId, Function.identity()));
        Map<String, Map<String, PointInfo>> fsMapMap = entityFs.stream().collect(Collectors.groupingBy(PointInfo::getStationId, Collectors.toMap(PointInfo::getTurbineId, Function.identity())));
        //功率
        List<PointInfo> entityGl = getEntity("AI114", "turbine");
        getLatestByEntity(entityGl);
        Map<String, List<PointData>> glMap = entityGl.stream().collect(Collectors.toMap(PointInfo::getTurbineId, PointInfo::getPointDatas));

        ztMapMap.forEach((stId, ztMap) -> {
            PointInfo agcInfo = collectAgc.get(stId);
            PointInfo cxInfo = collectCx.get(stId);
            Map<String, PointInfo> fsMap = fsMapMap.get(stId);

            Map<String, List<PointData>> pdsZsglMap = new HashMap<>();
            ztMap.forEach((wtId, zt) -> {
                List<PointData> peek = fsMap.get(wtId).getPointDatas().stream().peek(pd -> pd.setDoubleValue(NumberUtil.round(pd.getValue() > 25 ? 25.0 : pd.getValue(), 2).doubleValue())).collect(Collectors.toList());
                fsMap.get(wtId).setPointDatas(peek);
                List<PointData> zsglSnap = fsMap.get(wtId).getPointDatas().stream().map(pd -> {
                    Double v = CalcCache.fitcoef.get(wtId).get(pd.getValue());
                    return new PointData(pd.getTs(), v == null ? 0 : v);
                }).collect(Collectors.toList());
                pdsZsglMap.put(wtId, zsglSnap);
            });
            List<PointData> agcc = agcInfo.getPointDatas().stream().peek(agc -> {
                agc.setDoubleValue(agc.getValue() * agcInfo.getCoef());
                agc.setLongValue(0L);
            }).collect(Collectors.toList());
            agcInfo.setPointDatas(agcc);
            List<PointData> cxc = cxInfo.getPointDatas().stream().peek(cx -> {
                cx.setDoubleValue(cx.getValue() * cxInfo.getCoef());
                cx.setLongValue(0L);
            }).collect(Collectors.toList());
            cxInfo.setPointDatas(cxc);

            //风机风速、功率->场站风速、功率
            List<PointData> firstZsgl = new ArrayList<>();
            double v3;
            for (int i = 0; i < 20; i++) {
                int finalI = i;
                long ts = date.getTime() + i * 15000;
                v3 = pdsZsglMap.values().stream().mapToDouble(pds -> pds.get(finalI).getValue()).sum();
                firstZsgl.add(new PointData(ts, v3));
            }

            boolean czxd = calcRealtimeStationXd(agcInfo, cxInfo.getPointDatas(), firstZsgl);
            if (czxd) {
                //叶轮转速给定
                List<PointInfo> entityYlzsgd = getEntity("AI110", "turbine");
                getLatestByEntity(entityYlzsgd);

                Map<String, List<PointData>> collectYlzsgd = entityYlzsgd.stream().collect(Collectors.toMap(PointInfo::getTurbineId, PointInfo::getPointDatas));

                ztMap.forEach((wtId, ztInfo) -> {
                    List<PointData> fss = fsMap.get(wtId).getPointDatas();
                    List<PointData> gls = glMap.get(wtId);
                    //叶轮转速给定
                    List<PointData> ylzsgds = collectYlzsgd.get(wtId);
                    calcRealtimeTurbineXd(ztInfo, gls.get(0), fss.get(fss.size() - 1), ylzsgds.get(0));
                });
            }
        });

        Map<String, String> entityMxzt = getEntityMap("MXZT", "turbine");
        Map<String, String> entityQfzt = getEntityMap("SSQFZT", "turbine");
        //Map<String, String> entityKygl = getEntityMap("KYGL", "turbine");

        List<PointInfo> fsEntity = entityFs.stream().peek(fs -> {
            PointData data = fs.getPointDatas().get(fs.getPointDatas().size() - 1);
            if (data != null) {
                fs.setPointDatas(Collections.singletonList(data));
            } else {
                fs.setPointDatas(Collections.singletonList(new PointData()));
            }
        }).collect(Collectors.toList());
        List<PointData> qfztDataList = fsEntity.stream().map(fs -> {
            String wtId = fs.getTurbineId();
            PointData data = fs.getPointDatas().get(0);
            data.setTs(date.getTime());
            data.setTagName(entityQfzt.get(wtId));
            data.setDoubleValue(calcQfzt(glMap.get(wtId).get(0).getValue(), CalcCache.fitcoef.get(wtId).get(data.getValue())));
            return data;
        }).collect(Collectors.toList());

        //风机状态转换为写适配器的测点与值
        List<PointData> dataList = turbineZt.stream().map(zt -> {
            PointData data = zt.getPointDatas().get(0);
            data.setTs(date.getTime());
            data.setTagName(entityMxzt.get(zt.getTurbineId()));
            return data;
        }).collect(Collectors.toList());
        if (isOnMin) {
            adapter.writeHistoryBatch(taosUri(), dataList);
            adapter.writeHistoryBatch(taosUri(), qfztDataList);
        } else {
            List<PointData> collect = dataList.stream().filter(d -> {
                if (Objects.equals(CalcCache.statusCache.get(d.getTagName()), d.getValue())) {
                    return false;
                } else {
                    CalcCache.statusCache.put(d.getTagName(), d.getValue());
                    return true;
                }
            }).collect(Collectors.toList());
            List<PointData> qfztDatas = qfztDataList.stream().filter(d -> {
                if (Objects.equals(CalcCache.qfztCache.get(d.getTagName()), d.getValue())) {
                    return false;
                } else {
                    CalcCache.qfztCache.put(d.getTagName(), d.getValue());
                    return true;
                }
            }).collect(Collectors.toList());
            adapter.writeHistoryBatch(taosUri(), collect);
            adapter.writeHistoryBatch(taosUri(), qfztDatas);
        }
    }
    //此处加公式

    public Map<String, Double> calcRealtimeTurbineZt(String stId) {

        List<PointInfo> turbineZt = calcRealtimeTurbineDizt();
        List<PointInfo> turbineAizt = calcRealtimeTurbineAizt();
        turbineZt.addAll(turbineAizt);
        Map<String, Double> collect = turbineZt.stream().filter(zt -> zt.getStationId().equals(stId)).peek(t -> {
            if (t.getPointDatas().get(0).getTs() + 35 * 60 * 1000 <= DateUtil.date().getTime()) {
                t.getPointDatas().get(0).setDoubleValue(12.0);
            }
        }).collect(Collectors.toMap(PointInfo::getTurbineId, pi -> pi.getPointDatas().get(0).getValue()));
        return collect;
    }
    // 计算每种状态的总持续时间
    public void calcTurbineStateMin(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);

        List<PointInfo> entityMxzt = getEntity("MXZT", "turbine");
        getRawDataByEntity(entityMxzt, taosUri(), time0, time);

        Map<String, TurbineInfoDay> byDate = getTurbineinfoMap(time0, entityMxzt);

        for (PointInfo info : entityMxzt) {
            TurbineInfoDay infoDay = byDate.get(info.getTurbineId());
            Map<Double, Long> durations = calculateStateDurations(info.getPointDatas());
            infoDay.setDjMin(durations.getOrDefault(0.0, 0L) / 60000.0);
            infoDay.setTjMin(durations.getOrDefault(1.0, 0L) / 60000.0);
            infoDay.setYxMin(durations.getOrDefault(2.0, 0L) / 60000.0);
            infoDay.setGzMin(durations.getOrDefault(4.0, 0L) / 60000.0);
            infoDay.setJxMin(durations.getOrDefault(6.0, 0L) / 60000.0);
            infoDay.setXdMin(durations.getOrDefault(8.0, 0L) / 60000.0);
            infoDay.setLxMin(durations.getOrDefault(12.0, 0L) / 60000.0);
        }
        turbineInfoDayService.saveOrUpdateBatch(byDate.values());
    }

    public Map<Double, Long> calculateStateDurations(List<PointData> datas) {
        if (CollUtil.isEmpty(datas)) return Collections.emptyMap();

        Map<Double, Long> durations = new HashMap<>();
        double prevState = datas.get(0).getValue(); // 初始状态
        long prevTs = datas.get(0).getTs(); // 初始时间戳

        PointData current;
        double currentState;
        long currentTs;
        for (int i = 1; i < datas.size(); i++) {
            current = datas.get(i);
            currentState = current.getValue();
            currentTs = current.getTs();

            if (currentState != prevState) {
                // 当状态变化时，计算前一个状态的持续时间并更新map
                durations.put(prevState, durations.getOrDefault(prevState, 0L) + (currentTs - prevTs));
                prevState = currentState;
                prevTs = currentTs;
            }
        }
        // 不要忘记计算列表中最后一个状态的持续时间（如果列表没有以状态变化结束）
        durations.put(prevState, durations.getOrDefault(prevState, 0L) + (datas.get(datas.size() - 1).getTs() - prevTs));
        return durations;
    }

    public void getRawDataByEntity(List<PointInfo> entity, URI uri, Date start, Date end) {
        for (PointInfo info : entity) {
            List<PointData> snap = adapter.getHistoryRaw(uri, info.getPointKey(), start.getTime(), end.getTime());
            ThreadUtil.sleep(5);
            info.setPointDatas(snap);
        }
    }

    public void getStatDataByEntity(List<PointInfo> entity, URI uri, Date start, Date end) {
        for (PointInfo info : entity) {
            DoubleStatData stat = adapter.getHistoryStat(uri, info.getPointKey(), start.getTime(), end.getTime());
            ThreadUtil.sleep(5);
            info.setPointDatas(new ArrayList<>(3));
            if (stat != null) {
                info.getPointDatas().add(stat.getAvg());
                info.getPointDatas().add(stat.getMax());
                info.getPointDatas().add(stat.getMin());
            } else {
                info.getPointDatas().add(new PointData());
                info.getPointDatas().add(new PointData());
                info.getPointDatas().add(new PointData());
            }
        }
    }

    public Map<String, PointInfo> getStatDataByEntity(List<PointInfo> entity, URI uri, Date start, Date end, Function<PointInfo, String> function) {
        getStatDataByEntity(entity, uri, start, end);
        return entity.stream().collect(Collectors.toMap(function, Function.identity()));
    }

    // 主函数或测试方法（如果需要）
    public static void main(String[] args) {

        Double b = 2.0;
        double c = 2.0;
        System.out.println(b == c);
        Double d = Double.valueOf(c);
        System.out.println(Objects.equals(b, c));
        System.out.println(Objects.equals(d, b));
        System.out.println(Objects.equals(null, null));


        List<PointData> points = new ArrayList<>();
        points.add(new PointData(1000, 1));
        points.add(new PointData(1500, 2));
        points.add(new PointData(2000, 1));
        points.add(new PointData(2500, 3));

        //        Map<Integer, Long> durations = calculateStateDurations(points);
        //        for (Map.Entry<Integer, Long> entry : durations.entrySet()) {
        //            System.out.println("State " + entry.getKey() + ": " + entry.getValue() + "ms");
        //        }
    }

    public List<PointInfo> getLatest(String uniformCode, String institutionType) {
        List<PointInfo> entity = getEntity(uniformCode, institutionType);
        String collect = entity.stream().map(PointInfo::getPointKey).collect(Collectors.joining(","));
        Map<String, PointData> latest = adapter.getLatest(goldenUri(), collect);
        entity.forEach(e -> {
            e.setPointDatas(Collections.singletonList(latest.get(e.getPointKey())));
        });
        return entity;
    }

    public void getLatestByEntity(List<PointInfo> entity) {
        String collect = entity.stream().map(PointInfo::getPointKey).collect(Collectors.joining(","));
        Map<String, PointData> latest = adapter.getLatest(goldenUri(), collect);
        entity.forEach(e -> {
            e.setPointDatas(Collections.singletonList(latest.get(e.getPointKey())));
        });
    }

    public List<PointInfo> calcRealtimeTurbineDizt() {
        List<PointInfo> entity = new ArrayList<>();
        List<PointInfo> result = new ArrayList<>();
        List<PointInfo> entity0 = getEntity("MX000", "state");
        List<PointInfo> entity1 = getEntity("MX001", "state");
        List<PointInfo> entity2 = getEntity("MX002", "state");
        List<PointInfo> entity4 = getEntity("MX004", "state");
        List<PointInfo> entity6 = getEntity("MX006", "state");
        entity.addAll(entity0);
        entity.addAll(entity1);
        entity.addAll(entity2);
        entity.addAll(entity4);
        entity.addAll(entity6);
        String keys = entity.stream().map(PointInfo::getPointKey).collect(Collectors.joining(","));
        Map<String, PointData> latest = adapter.getLatest(goldenUri(), keys);

        Map<String, Map<String, PointInfo>> wtUcPis = entity.stream().collect(Collectors.groupingBy(PointInfo::getTurbineId, Collectors.toMap(PointInfo::getUniformCode, Function.identity())));
        wtUcPis.forEach((wtId, map) -> {
            String collect = map.values().stream().map(PointInfo::getPointKey).collect(Collectors.joining(","));
            PointInfo info2 = map.get("MX002");
            PointData data2 = latest.get(info2.getPointKey());
            if (data2.getValue() == 1.0) {
                data2.setDoubleValue(2.0);
                data2.setBooleanValue(false);
                info2.setPointDatas(Collections.singletonList(data2));
                result.add(info2);
            } else {
                PointInfo info0 = map.get("MX000");
                PointData data0 = latest.get(info0.getPointKey());
                if (data0.getValue() == 1.0) {
                    data0.setDoubleValue(0.0);
                    data0.setBooleanValue(false);
                    info0.setPointDatas(Collections.singletonList(data0));
                    result.add(info0);
                } else {
                    PointInfo info6 = map.get("MX006");
                    PointData data6 = latest.get(info6.getPointKey());
                    if (data6.getValue() == 1.0) {
                        data6.setDoubleValue(6.0);
                        data6.setBooleanValue(false);
                        info6.setPointDatas(Collections.singletonList(data6));
                        result.add(info6);
                    } else {
                        PointInfo info4 = map.get("MX004");
                        PointData data4 = latest.get(info4.getPointKey());
                        if (data4.getValue() == 1.0) {
                            data4.setDoubleValue(4.0);
                            data4.setBooleanValue(false);
                            info4.setPointDatas(Collections.singletonList(data4));
                            result.add(info4);
                        } else {
                            PointInfo info1 = map.get("MX001");
                            PointData data1 = latest.get(info1.getPointKey());
                            if (data1.getValue() == 1.0) {
                                data1.setDoubleValue(1.0);
                                data1.setBooleanValue(false);
                                info1.setPointDatas(Collections.singletonList(data1));
                                result.add(info1);
                            } else {
                                Map<String, PointData> latest2 = adapter.getLatest(goldenUri(), collect);
                                data1.setDoubleValue(2.0);
                                System.out.println("wtId: " + wtId + ",状态值无批配: " + data1.getValue());
                                info1.setPointDatas(Collections.singletonList(data1));
                                result.add(info1);
                            }
                        }
                    }
                }
            }
        });
        return result;
    }

    public List<PointInfo> calcRealtimeTurbineAizt() {
        List<PointInfo> entityAiZt = getEntity("AI422", "state");
        List<StateAi> list = stateAiService.list();
        //机型，源状态，目标状态
        Map<String, Map<Integer, Integer>> collectAi = list.stream().collect(Collectors.groupingBy(StateAi::getModel, Collectors.toMap(StateAi::getOriginalState, StateAi::getMappingState)));
        String collect = entityAiZt.stream().map(PointInfo::getPointKey).collect(Collectors.joining(","));
        Map<String, PointData> latest = adapter.getLatest(goldenUri(), collect);

        for (PointInfo info : entityAiZt) {
            PointData data = latest.get(info.getPointKey());
            Integer m = collectAi.get(info.getSpare()).get((int) data.getValue());
            if (m == null) m = 2;
            data.setDoubleValue(m);
            info.setPointDatas(Collections.singletonList(data));
        }
        return entityAiZt;
    }

    public void getAgoAvg(List<PointInfo> entity, Date start, Date end) {
        for (PointInfo info : entity) {
            DoubleStatData snap = adapter.getHistoryStat(goldenUri(), info.getPointKey(), start.getTime(), end.getTime());
            ThreadUtil.sleep(5);
            info.setPointDatas(Collections.singletonList(snap.getAvg()));
        }
    }

    public void calcRealtimeTurbineXd(PointInfo ztInfo, PointData gl, PointData fs, PointData ylzsgd) {
        Map<String, EquipmentModel> map = equipmentModelService.map();
        Double capacity = map.get(ztInfo.getSpare()).getPowerProduction();
        PointData zt = ztInfo.getPointDatas().get(0);

        if (gl.getValue() < capacity * 0.9) {
            if (fs.getValue() >= 12) {
                zt.setDoubleValue(8.0);
            }
            if (ylzsgd.getValue() != 0 && ylzsgd.getValue() < 17.3) {//降出力
                zt.setDoubleValue(8.0);
            }
        }
    }

    //此处加公式
    public boolean calcRealtimeStationXd(PointInfo agcInfo, List<PointData> cxSnap, List<PointData> zsglSnap) {
        String stId = agcInfo.getStationId();

        List<PointData> agcSnap = agcInfo.getPointDatas();
        List<PointData> zsgl5s = get5Avg(zsglSnap);
        List<PointData> agc5s = get5Avg(agcSnap);
        List<PointData> cx5s = get5Avg(cxSnap);
        //之前是否限电
        boolean iszqxd = false;
        for (int i = 0; i < zsglSnap.size(); i++) {
            boolean isxd = false;
            double zsgl = zsglSnap.get(i).getValue();
            double zsgl5 = zsgl5s.get(i).getValue();
            double agc = agcSnap.get(i).getValue();
            double agc5 = agc5s.get(i).getValue();
            double cxgl = cxSnap.get(i).getValue();
            double cxgl5 = cx5s.get(i).getValue();

            boolean k;   //agc一直不变
            //第一次初始化复制实时数据到缓存
            if (CalcCache.powerCacheRt.get(stId) == null || CalcCache.powerCacheRt.get(stId) != agc) {
                CalcCache.powerCacheRt.put(stId, agc);
                k = false;
            } else {
                k = true;
            }
            if (agc != 0) {
                //如果场站限电状态为不限电
                if (zsgl5 >= agcInfo.getSpare2() * 40) {
                    if (agc5 <= cxgl5) {
                        isxd = true;
                    } else if (iszqxd) {
                        if (zsgl / agc > 1.15) {
                            isxd = true;
                        } else if (zsgl > agc && agc5 - cxgl5 < 400) {
                            isxd = true;
                        }
                    } else if (zsgl / agc >= 1.2 && agc - cxgl <= 200) {
                        isxd = true;
                    }
                } else if (k) {
                    if (zsgl / agc >= 1.1 && agc5 - cxgl5 <= 200) {
                        isxd = true;
                    }
                }
            }
            iszqxd = isxd;
        }
        return iszqxd;
    }

    */
/*public void calcStationSwGwCyRdl(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);

        List<PointInfo> swdlEt = getEntity("Z-ZXYG-CX", "meter");
        List<PointInfo> gwdlEt = getEntity("Z-FXYG-CX", "meter");
        List<PointInfo> cydlEt = getEntity("Z-ZXYG-ZYB", "meter");
        getZeroNextData(swdlEt, time0, time);
        getZeroNextData(gwdlEt, time0, time);
        getZeroNextData(cydlEt, time0, time);

        Map<String, PointInfo> swdlMap = swdlEt.stream().collect(Collectors.toMap(PointInfo::getStationId, Function.identity()));
        Map<String, PointInfo> gwdlMap = gwdlEt.stream().collect(Collectors.toMap(PointInfo::getStationId, Function.identity()));
        Map<String, PointInfo> cydlMap = cydlEt.stream().collect(Collectors.toMap(PointInfo::getStationId, Function.identity()));

        List<StationInfoDay> byDate = getStationinfoByDate(time0, swdlEt);
        String stId;
        PointInfo swdlPi, gwdlPi, cydlPi;
        for (StationInfoDay info : byDate) {
            stId = info.getStationId();
            swdlPi = swdlMap.get(stId);
            gwdlPi = gwdlMap.get(stId);
            cydlPi = cydlMap.get(stId);
            int swdl = (int) ((swdlPi.getPointDatas().get(1).getValue() - swdlPi.getPointDatas().get(0).getValue()) * swdlPi.getCoef());
            int gwdl = (int) ((gwdlPi.getPointDatas().get(1).getValue() - gwdlPi.getPointDatas().get(0).getValue()) * gwdlPi.getCoef());
            int cydl = (int) ((cydlPi.getPointDatas().get(1).getValue() - cydlPi.getPointDatas().get(0).getValue()) * cydlPi.getCoef());
            if (swdl < 0 || swdl > 1000000) swdl = 0;
            if (gwdl < 0 || gwdl > 1000000) gwdl = 0;
            if (cydl < 0 || cydl > 1000000) cydl = 0;
            info.setSwdl(swdl);
            info.setGwdl(gwdl);
            info.setCydl(cydl);
        }
        stationInfoDayService.saveOrUpdateBatch(byDate);
    }*//*


    public void writeReportPool5SPjfsLlfdlZtsj(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);
        DateTime beginOfMonth = DateUtil.beginOfMonth(time0);
        DateTime beginOfYear = DateUtil.beginOfYear(time0);

        QueryWrapper<TurbineInfoDay> wrapper = new QueryWrapper<>();
        wrapper.select("sum(llfdl) llfdl,sum(jhjxss) jhjxss,sum(fjhjxss) fjhjxss,sum(xdss) xdss,sum(slss) slss,sum(xnss) xnss," +
                        "sum(gzss) gzss,sum(djss) djss,avg(pjfs) pjfs,sum(dj_min) dj_min,sum(tj_min) tj_min,sum(yx_min) yx_min,sum(gz_min) gz_min," +
                        "sum(jx_min) jx_min,sum(xd_min) xd_min,sum(lx_min) lx_min,project_id,station_id")
                .eq("record_date", time0).groupBy("project_id,station_id");
        List<TurbineInfoDay> days = turbineInfoDayService.list(wrapper);
        Map<String, TurbineInfoDay> dayMap = days.stream().collect(Collectors.toMap(TurbineInfoDay::getProjectId, Function.identity()));
        wrapper = new QueryWrapper<>();
        wrapper.select("sum(llfdl) llfdl,sum(jhjxss) jhjxss,sum(fjhjxss) fjhjxss,sum(xdss) xdss,sum(slss) slss,sum(xnss) xnss," +
                        "sum(gzss) gzss,sum(djss) djss,avg(pjfs) pjfs,sum(dj_min) dj_min,sum(tj_min) tj_min,sum(yx_min) yx_min,sum(gz_min) gz_min," +
                        "sum(jx_min) jx_min,sum(xd_min) xd_min,sum(lx_min) lx_min,project_id,station_id")
                .between("record_date", beginOfMonth, time0).groupBy("project_id,station_id");
        List<TurbineInfoDay> monthDays = turbineInfoDayService.list(wrapper);
        Map<String, TurbineInfoDay> monthMap = monthDays.stream().collect(Collectors.toMap(TurbineInfoDay::getProjectId, Function.identity()));
        wrapper = new QueryWrapper<>();
        wrapper.select("sum(llfdl) llfdl,sum(jhjxss) jhjxss,sum(fjhjxss) fjhjxss,sum(xdss) xdss,sum(slss) slss,sum(xnss) xnss," +
                        "sum(gzss) gzss,sum(djss) djss,avg(pjfs) pjfs,sum(dj_min) dj_min,sum(tj_min) tj_min,sum(yx_min) yx_min,sum(gz_min) gz_min," +
                        "sum(jx_min) jx_min,sum(xd_min) xd_min,sum(lx_min) lx_min,project_id,station_id")
                .between("record_date", beginOfYear, time0).groupBy("project_id,station_id");
        List<TurbineInfoDay> yearDays = turbineInfoDayService.list(wrapper);
        Map<String, TurbineInfoDay> yearMap = yearDays.stream().collect(Collectors.toMap(TurbineInfoDay::getProjectId, Function.identity()));

        QueryWrapper<ProEconReportIndicatorPool> wrapperRp = new QueryWrapper<>();
        wrapperRp.eq("record_date", time0).last("and foreign_key_id = project_id");
        List<ProEconReportIndicatorPool> poolsProject = reportIndicatorPoolService.list(wrapperRp);
        wrapperRp = new QueryWrapper<>();
        wrapperRp.eq("record_date", time0).last("and foreign_key_id = windpowerstation_id");
        List<ProEconReportIndicatorPool> poolsStation = reportIndicatorPoolService.list(wrapperRp);
        wrapperRp = new QueryWrapper<>();
        wrapperRp.eq("record_date", time0).eq("foreign_key_id", "GJNY_SXGS_DBXNY_ZGS0");
        ProEconReportIndicatorPool poolsCompany = reportIndicatorPoolService.getOne(wrapperRp);

        TurbineInfoDay day, month, year;
        String projectId;
        if (poolsProject.isEmpty()) {
            for (TurbineInfoDay infoDay : days) {
                projectId = infoDay.getProjectId();
                ProEconReportIndicatorPool pool = new ProEconReportIndicatorPool();
                pool.setRecordDate(time0);
                pool.setForeignKeyId(projectId);
                pool.setWindpowerstationId(infoDay.getStationId());
                pool.setProjectId(projectId);
                month = monthMap.get(projectId);
                year = yearMap.get(projectId);
                poolSetValue1(pool, infoDay, month, year);
                poolsProject.add(pool);
            }
        } else {
            for (ProEconReportIndicatorPool pool : poolsProject) {
                projectId = pool.getProjectId();
                day = dayMap.get(projectId);
                month = monthMap.get(projectId);
                year = yearMap.get(projectId);
                poolSetValue1(pool, day, month, year);
            }
        }
        reportIndicatorPoolService.saveOrUpdateBatch(poolsProject);
        Map<String, List<ProEconReportIndicatorPool>> projectMap = poolsProject.stream().collect(Collectors.groupingBy(ProEconReportIndicatorPool::getWindpowerstationId));
        if (poolsStation.isEmpty()) {
            projectMap.forEach((StId, pis) -> {
                ProEconReportIndicatorPool pool = new ProEconReportIndicatorPool();
                pool.setRecordDate(time0);
                pool.setForeignKeyId(StId);
                pool.setWindpowerstationId(StId);
                poolSetValue(pool, pis);
                poolsStation.add(pool);
            });
        } else {
            for (ProEconReportIndicatorPool pool : poolsStation) {
                List<ProEconReportIndicatorPool> pools = projectMap.get(pool.getWindpowerstationId());
                poolSetValue(pool, pools);
            }
        }
        reportIndicatorPoolService.saveOrUpdateBatch(poolsStation);
        if (poolsCompany == null) {
            poolsCompany = new ProEconReportIndicatorPool();
            poolsCompany.setRecordDate(time0);
            poolsCompany.setForeignKeyId("GJNY_SXGS_DBXNY_ZGS0");
            poolsCompany.setCompanyId("GJNY_SXGS_DBXNY_ZGS");
            poolSetValue(poolsCompany, poolsStation);
        } else {
            poolSetValue(poolsCompany, poolsStation);
        }
        reportIndicatorPoolService.saveOrUpdate(poolsCompany);
    }


    public void writeReportPoolPjfs2(Date date) {
        //date当天零点
        DateTime time = DateUtil.beginOfDay(date);
        //date昨天零点
        DateTime time0 = DateUtil.offsetDay(time, -1);
        DateTime beginOfMonth = DateUtil.beginOfMonth(time0);
        DateTime beginOfYear = DateUtil.beginOfYear(time0);

        QueryWrapper<TurbineInfoDay> wrapper = new QueryWrapper<>();
        wrapper.select("avg(pjfs) pjfs,project_id,station_id")
                .eq("record_date", time0).groupBy("project_id,station_id");
        List<TurbineInfoDay> days = turbineInfoDayService.list(wrapper);
        Map<String, TurbineInfoDay> dayMap = days.stream().collect(Collectors.toMap(TurbineInfoDay::getProjectId, Function.identity()));
        wrapper = new QueryWrapper<>();
        wrapper.select("avg(pjfs) pjfs,project_id,station_id")
                .between("record_date", beginOfMonth, time0).groupBy("project_id,station_id");
        List<TurbineInfoDay> monthDays = turbineInfoDayService.list(wrapper);
        Map<String, TurbineInfoDay> monthMap = monthDays.stream().collect(Collectors.toMap(TurbineInfoDay::getProjectId, Function.identity()));
        wrapper = new QueryWrapper<>();
        wrapper.select("avg(pjfs) pjfs,project_id,station_id")
                .between("record_date", beginOfYear, time0).groupBy("project_id,station_id");
        List<TurbineInfoDay> yearDays = turbineInfoDayService.list(wrapper);
        Map<String, TurbineInfoDay> yearMap = yearDays.stream().collect(Collectors.toMap(TurbineInfoDay::getProjectId, Function.identity()));

        QueryWrapper<ProEconReportIndicatorPool> wrapperRp = new QueryWrapper<>();
        wrapperRp.eq("record_date", time0).last("and foreign_key_id = project_id");
        List<ProEconReportIndicatorPool> poolsProject = reportIndicatorPoolService.list(wrapperRp);
        wrapperRp = new QueryWrapper<>();
        wrapperRp.eq("record_date", time0).last("and foreign_key_id = windpowerstation_id");
        List<ProEconReportIndicatorPool> poolsStation = reportIndicatorPoolService.list(wrapperRp);
        wrapperRp = new QueryWrapper<>();
        wrapperRp.eq("record_date", time0).eq("foreign_key_id", "GJNY_SXGS_DBXNY_ZGS0");
        ProEconReportIndicatorPool poolsCompany = reportIndicatorPoolService.getOne(wrapperRp);

        TurbineInfoDay day, month, year;
        String projectId;
        if (poolsProject.isEmpty()) {
            for (TurbineInfoDay infoDay : days) {
                projectId = infoDay.getProjectId();
                ProEconReportIndicatorPool pool = new ProEconReportIndicatorPool();
                pool.setRecordDate(time0);
                pool.setForeignKeyId(projectId);
                pool.setWindpowerstationId(infoDay.getStationId());
                pool.setProjectId(projectId);
                month = monthMap.get(projectId);
                year = yearMap.get(projectId);

                pool.setRpjfs(infoDay.getPjfs());
                pool.setYpjfs(month.getPjfs());
                pool.setNpjfs(year.getPjfs());

                poolsProject.add(pool);
            }
        } else {
            for (ProEconReportIndicatorPool pool : poolsProject) {
                projectId = pool.getProjectId();
                day = dayMap.get(projectId);
                month = monthMap.get(projectId);
                year = yearMap.get(projectId);

                pool.setRpjfs(day.getPjfs());
                pool.setYpjfs(month.getPjfs());
                pool.setNpjfs(year.getPjfs());
            }
        }
        reportIndicatorPoolService.saveOrUpdateBatch(poolsProject);
        Map<String, List<ProEconReportIndicatorPool>> projectMap = poolsProject.stream().collect(Collectors.groupingBy(ProEconReportIndicatorPool::getWindpowerstationId));
        if (poolsStation.isEmpty()) {
            projectMap.forEach((StId, pis) -> {
                ProEconReportIndicatorPool pool = new ProEconReportIndicatorPool();
                pool.setRecordDate(time0);
                pool.setForeignKeyId(StId);
                pool.setWindpowerstationId(StId);

                ProEconReportIndicatorPool p = sumProperties(pis, ProEconReportIndicatorPool.class);
                pool.setRpjfs(p.getRpjfs() / pis.size());
                pool.setYpjfs(p.getYpjfs() / pis.size());
                pool.setNpjfs(p.getNpjfs() / pis.size());
                poolsStation.add(pool);
            });
        } else {
            for (ProEconReportIndicatorPool pool : poolsStation) {
                List<ProEconReportIndicatorPool> pools = projectMap.get(pool.getWindpowerstationId());

                ProEconReportIndicatorPool p = sumProperties(pools, ProEconReportIndicatorPool.class);
                pool.setRpjfs(p.getRpjfs() / pools.size());
                pool.setYpjfs(p.getYpjfs() / pools.size());
                pool.setNpjfs(p.getNpjfs() / pools.size());
            }
        }
        reportIndicatorPoolService.saveOrUpdateBatch(poolsStation);
        if (poolsCompany == null) {
            poolsCompany = new ProEconReportIndicatorPool();
            poolsCompany.setRecordDate(time0);
            poolsCompany.setForeignKeyId("GJNY_SXGS_DBXNY_ZGS0");
            poolsCompany.setCompanyId("GJNY_SXGS_DBXNY_ZGS");

            ProEconReportIndicatorPool p = sumProperties(poolsStation, ProEconReportIndicatorPool.class);
            poolsCompany.setRpjfs(p.getRpjfs() / poolsStation.size());
            poolsCompany.setYpjfs(p.getYpjfs() / poolsStation.size());
            poolsCompany.setNpjfs(p.getNpjfs() / poolsStation.size());
        } else {
            ProEconReportIndicatorPool p = sumProperties(poolsStation, ProEconReportIndicatorPool.class);
            poolsCompany.setRpjfs(p.getRpjfs() / poolsStation.size());
            poolsCompany.setYpjfs(p.getYpjfs() / poolsStation.size());
            poolsCompany.setNpjfs(p.getNpjfs() / poolsStation.size());
        }
        reportIndicatorPoolService.saveOrUpdate(poolsCompany);
    }

    public void poolSetValue1(ProEconReportIndicatorPool pool, TurbineInfoDay day, TurbineInfoDay month, TurbineInfoDay year) {
        pool.setRpjfs(day.getPjfs());
        pool.setRgzssdl(day.getGzss() == null ? day.getFjhjxss() * 0.11 : day.getGzss());
        pool.setRjxssdl(day.getJhjxss());
        pool.setRdjssdl(day.getDjss() == null ? day.getFjhjxss() * 0.89 : day.getDjss());
        pool.setRxnssdl(day.getXnss());
        pool.setRxdjclssdl(day.getXdss());
        pool.setRllfdl(day.getLlfdl());
        pool.setRhjdjxs(day.getDjMin() / 60);
        pool.setRhjgztjxs(day.getGzMin() / 60);
        pool.setRhjtxzdxs(day.getLxMin() / 60);
        pool.setRhjjxtjxs(day.getJxMin() / 60);
        pool.setRhjxdxs(day.getXdMin() / 60);
        pool.setRhjyxxs(day.getYxMin() / 60);
        pool.setRhjslxs(0.0);

        pool.setYpjfs(month.getPjfs());
        pool.setYgzssdl(month.getGzss() == null ? month.getFjhjxss() * 0.11 : month.getGzss());
        pool.setYjxssdl(month.getJhjxss());
        pool.setYdjssdl(month.getDjss() == null ? month.getFjhjxss() * 0.89 : month.getDjss());
        pool.setYxnssdl(month.getXnss());
        pool.setYxdjclssdl(month.getXdss());
        pool.setYllfdl(month.getLlfdl());
        pool.setYhjdjxs(month.getDjMin() / 60);
        pool.setYhjgztjxs(month.getGzMin() / 60);
        pool.setYhjtxzdxs(month.getLxMin() / 60);
        pool.setYhjjxtjxs(month.getJxMin() / 60);
        pool.setYhjxdxs(month.getXdMin() / 60);
        pool.setYhjyxxs(month.getYxMin() / 60);
        pool.setYhjslxs(0.0);

        pool.setNpjfs(year.getPjfs());
        pool.setNgzssdl(year.getGzss() == null ? year.getFjhjxss() * 0.11 : year.getGzss());
        pool.setNjxssdl(year.getJhjxss());
        pool.setNdjssdl(year.getDjss() == null ? year.getFjhjxss() * 0.89 : year.getDjss());
        pool.setNxnssdl(year.getXnss());
        pool.setNxdjclssdl(year.getXdss());
        pool.setNllfdl(year.getLlfdl());
        pool.setNhjdjxs(year.getDjMin() / 60);
        pool.setNhjgztjxs(year.getGzMin() / 60);
        pool.setNhjtxzdxs(year.getLxMin() / 60);
        pool.setNhjjxtjxs(year.getJxMin() / 60);
        pool.setNhjxdxs(year.getXdMin() / 60);
        pool.setNhjyxxs(year.getYxMin() / 60);
        pool.setNhjslxs(0.0);
    }

    public void poolSetValue(ProEconReportIndicatorPool pool, List<ProEconReportIndicatorPool> pools) {
        ProEconReportIndicatorPool p = sumProperties(pools, ProEconReportIndicatorPool.class);
        pool.setRpjfs(p.getRpjfs() / pools.size());
        pool.setRgzssdl(p.getRgzssdl());
        pool.setRjxssdl(p.getRjxssdl());
        pool.setRdjssdl(p.getRdjssdl());
        pool.setRxnssdl(p.getRxnssdl());
        pool.setRxdjclssdl(p.getRxdjclssdl());
        pool.setRllfdl(p.getRllfdl());
        pool.setRhjdjxs(p.getRhjdjxs());
        pool.setRhjgztjxs(p.getRhjgztjxs());
        pool.setRhjtxzdxs(p.getRhjtxzdxs());
        pool.setRhjjxtjxs(p.getRhjjxtjxs());
        pool.setRhjxdxs(p.getRhjxdxs());
        pool.setRhjyxxs(p.getRhjyxxs());
        pool.setRhjslxs(0.0);

        pool.setYpjfs(p.getYpjfs() / pools.size());
        pool.setYgzssdl(p.getYgzssdl());
        pool.setYjxssdl(p.getYjxssdl());
        pool.setYdjssdl(p.getYdjssdl());
        pool.setYxnssdl(p.getYxnssdl());
        pool.setYxdjclssdl(p.getYxdjclssdl());
        pool.setYllfdl(p.getYllfdl());
        pool.setYhjdjxs(p.getYhjdjxs());
        pool.setYhjgztjxs(p.getYhjgztjxs());
        pool.setYhjtxzdxs(p.getYhjtxzdxs());
        pool.setYhjjxtjxs(p.getYhjjxtjxs());
        pool.setYhjxdxs(p.getYhjxdxs());
        pool.setYhjyxxs(p.getYhjyxxs());
        pool.setYhjslxs(0.0);

        pool.setNpjfs(p.getNpjfs() / pools.size());
        pool.setNgzssdl(p.getNgzssdl());
        pool.setNjxssdl(p.getNjxssdl());
        pool.setNdjssdl(p.getNdjssdl());
        pool.setNxnssdl(p.getNxnssdl());
        pool.setNxdjclssdl(p.getNxdjclssdl());
        pool.setNllfdl(p.getNllfdl());
        pool.setNhjdjxs(p.getNhjdjxs());
        pool.setNhjgztjxs(p.getNhjgztjxs());
        pool.setNhjtxzdxs(p.getNhjtxzdxs());
        pool.setNhjjxtjxs(p.getNhjjxtjxs());
        pool.setNhjxdxs(p.getNhjxdxs());
        pool.setNhjyxxs(p.getNhjyxxs());
        pool.setNhjslxs(0.0);
    }

    public <T> T sumProperties(List<T> list, Class<T> clazz) {
        T result;
        try {
            result = clazz.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        if (list == null || list.isEmpty()) return result;

        // 获取所有字段
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true); // 确保私有字段也可以被访问
            // 检查字段类型是否为Double
            Class<?> type = field.getType();
            if (type.equals(Double.class) || type.equals(Integer.class) || type.equals(Long.class) || type.equals(Float.class)) {
                double sum = 0.0;
                // 遍历列表中的每个对象并累加数值字段
                try {
                    for (T item : list) {
                        Field itemField = clazz.getDeclaredField(field.getName());
                        itemField.setAccessible(true);
                        // 尝试获取当前对象的字段值
                        Double value = (Double) itemField.get(item); // 注意类型转换
                        if (value != null) sum += value;
                    }
                    // 设置累加后的值到结果对象中
                    if (type.equals(Double.class)) {
                        field.set(result, sum);
                    } else if (type.equals(Integer.class)) {
                        field.set(result, (int) sum);
                    } else if (type.equals(Long.class)) {
                        field.set(result, (long) sum);
                    } else {
                        field.set(result, (float) sum);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    return result;
                }
            }
        }
        return result;
    }

    private ProEconReportIndicatorPool getPoolSum(List<ProEconReportIndicatorPool> pools) {
        ProEconReportIndicatorPool pool0 = new ProEconReportIndicatorPool();
        for (ProEconReportIndicatorPool pool : pools) {
            pool0.setRfdldb(nullSum(pool0.getRfdldb(), pool.getRfdldb()));
            pool0.setRswdldb(nullSum(pool0.getRswdldb(), pool.getRswdldb()));
            pool0.setRgwgwdldb(nullSum(pool0.getRgwgwdldb(), pool.getRgwgwdldb()));
            pool0.setRnwgwdldb(nullSum(pool0.getRnwgwdldb(), pool.getRnwgwdldb()));

        }
        return pool0;
    }

    public double nullSum(Double a, Double b) {
        if (a == null) a = 0.0;
        if (b == null) b = 0.0;
        return a + b;
    }

    public double calcQfzt(Double ssgl, Double zsgl) {
        if (ssgl == null || ssgl < 0) ssgl = 0.0;
        double qfzt, ratioll;
        ratioll = (zsgl == null || zsgl <= 0) ? 0 : (zsgl - ssgl) / zsgl;
        if (ratioll < 0.05) {
            qfzt = 0;
        } else if (ratioll < 0.1) {
            qfzt = 1;
        } else if (ratioll < 0.2) {
            qfzt = 2;
        } else if (ratioll < 0.4) {
            qfzt = 3;
        } else {
            qfzt = 4;
        }
        return qfzt;
    }

    public List<TurbineInfoMin> getTurbineinfoByMin(Date date) {
        QueryWrapper<TurbineInfoMin> wrapper = new QueryWrapper<>();
        wrapper.eq("record_date", date);
        return turbineInfoMinService.list(wrapper);
    }

    public List<TurbineInfoMin> getTurbineinfoByMin(Date date, List<PointInfo> entity) {
        List<TurbineInfoMin> list = getTurbineinfoByMin(date);
        if (list.isEmpty()) {
            entity.forEach(pi -> {
                TurbineInfoMin day = new TurbineInfoMin();
                day.setStationId(pi.getStationId());
                day.setProjectId(pi.getProjectId());
                day.setLineId(pi.getLineId());
                day.setTurbineId(pi.getTurbineId());
                day.setRecordDate(date);
                list.add(day);
            });
        }
        return list;
    }

    public Map<String, TurbineInfoMin> getTurbineinfoByMinMap(Date date) {
        List<TurbineInfoMin> tims = getTurbineinfoByMin(date);
        return tims.stream().collect(Collectors.toMap(TurbineInfoMin::getTurbineId, Function.identity()));
    }

    public Map<String, TurbineInfoMin> getTurbineinfoByMinMap(Date date, List<PointInfo> entity) {
        List<TurbineInfoMin> tims = getTurbineinfoByMin(date, entity);
        return tims.stream().collect(Collectors.toMap(TurbineInfoMin::getTurbineId, Function.identity()));
    }

    public Map<String, PointInfo> getRawDataByEntity(List<PointInfo> entity, URI uri, Date start, Date end, Function<PointInfo, String> function) {
        getRawDataByEntity(entity, uri, start, end);
        return entity.stream().collect(Collectors.toMap(function, Function.identity()));
    }

    public void calcTurbinePjfsPjglKyglLlglMin(Date date, int granularity) {
        date = DateUtil.beginOfMinute(date);
        DateTime start = DateUtil.offsetMinute(date, -granularity);
        //风速
        List<PointInfo> entityFs = getEntity("AI066", "turbine");
        Map<String, PointInfo> rawMapFs = getRawDataByEntity(entityFs, goldenUri(), start, date, PointInfo::getTurbineId);
        //功率
        List<PointInfo> entityGl = getEntity("AI114", "turbine");
        Map<String, PointInfo> rawMapGl = getRawDataByEntity(entityGl, goldenUri(), start, date, PointInfo::getTurbineId);
        List<PointInfo> entityZt = getEntity("MXZT", "turbine");
        Map<String, PointInfo> rawMapZt = getRawDataByEntity(entityZt, goldenUri(), start, date, PointInfo::getTurbineId);

        List<TurbineInfoMin> mins = getTurbineinfoByMin(date, entityFs);
        for (TurbineInfoMin min : mins) {
            String tbId = min.getTurbineId();
            List<PointData> fsDatas = rawMapFs.get(tbId).getPointDatas();
            List<PointData> ztDatas = rawMapZt.get(tbId).getPointDatas();
            ztDatas = doublePointDatasFull(2, ztDatas, start.getTime(), date.getTime(), 1);
            Map<Long, Double> ztMap = ztDatas.stream().collect(Collectors.toMap(PointData::getTs, PointData::getValue));
            double pjfs = fsDatas.stream().mapToDouble(PointData::getValue).average().orElse(0.0);
            fsDatas.stream().peek(pd -> pd.setDoubleValue(pd.getValue() > 25 ? 25 : pd.getValue() < 0 ? 0 : NumberUtil.round(pd.getValue(), 2).doubleValue())).collect(Collectors.toList());
            double llgl = fsDatas.stream().mapToDouble(pd -> pd.getValue() < 3 ? 0d : CalcCache.llgl.get(tbId).get(pd.getValue())).average().orElse(0.0);
            double kygl = fsDatas.stream().filter(pd -> ztMap.get(pd.getTs()) != 4 || ztMap.get(pd.getTs()) != 6)
                    .mapToDouble(pd -> CalcCache.fitcoef.get(tbId).get(pd.getValue())).average().orElse(0.0);
            double sjgl = rawMapGl.get(tbId).getPointDatas().stream().mapToDouble(PointData::getValue).average().orElse(0.0);

            double v = llgl * 0.9;
            if (kygl > v) kygl = v;
            if (kygl < sjgl) kygl = sjgl;
            min.setPjfs(pjfs);
            min.setPjgl(sjgl);
            min.setLlgl(llgl);
            min.setKygl(kygl);
        }
        turbineInfoMinService.saveOrUpdateBatch(mins);
    }

    public void calcTurbineSsfsQx(Date date) {
        DateTime date0 = DateUtil.beginOfDay(date);
        DateTime date1 = DateUtil.endOfDay(date);
        //风速
        List<PointInfo> entityFs = getEntity("AI066", "turbine");
        List<String> fjs = Arrays.asList("GJNY_SXGS_FSG_F_WT_0040_EQ", "GJNY_SXGS_FSG_F_WT_0047_EQ");
        entityFs = entityFs.stream().filter(e -> fjs.contains(e.getTurbineId())).collect(Collectors.toList());
        getSnapDataByEntity(entityFs, date0, date1, 60);
        int i = 0;
        for (PointInfo et : entityFs) {
            StrBuilder sb = new StrBuilder();
            StrBuilder sb1 = new StrBuilder();
            for (PointData v : et.getPointDatas()) {
                sb.append(v.getValue()).append(",");
                sb1.append(i).append(",");
                i++;
            }
            System.out.println(sb1);
            System.out.println(sb);
        }
    }

    public void calcStationLlglKyglSjglAgcMin(Date date, int granularity) {
        date = DateUtil.beginOfMinute(date);
        DateTime start = DateUtil.offsetMinute(date, -granularity);

        //AGC
        List<PointInfo> entityAgc = getEntity("AGC002", "booster");
        Map<String, PointInfo> statMapAgc = getStatDataByEntity(entityAgc, goldenUri(), start, date, PointInfo::getStationId);
        //出线
        List<PointInfo> entityCx = getEntity("AGC001", "booster");
        Map<String, PointInfo> statMapCx = getStatDataByEntity(entityCx, goldenUri(), start, date, PointInfo::getStationId);

        QueryWrapper<TurbineInfoMin> wrapper = new QueryWrapper<>();
        wrapper.select("sum(llgl) llgl,sum(kygl) kygl,avg(pjfs) pjfs,station_id").eq("record_date", date).groupBy("station_id");
        List<TurbineInfoMin> list = turbineInfoMinService.list(wrapper);
        Map<String, TurbineInfoMin> minMap = list.stream().collect(Collectors.toMap(TurbineInfoMin::getStationId, Function.identity()));
        List<StationInfoMin> byDate = getStationinfoByMin(date, entityAgc);

        for (StationInfoMin day : byDate) {
            String stId = day.getStationId();
            TurbineInfoMin min = minMap.get(stId);
            PointInfo agcInfo = statMapAgc.get(stId);
            PointInfo cxInfo = statMapCx.get(stId);
            day.setLlgl(min.getLlgl());
            day.setKygl(min.getKygl());
            day.setAgc(agcInfo.getPointDatas().get(0).getValue() * agcInfo.getCoef());
            day.setPjgl(cxInfo.getPointDatas().get(0).getValue() * cxInfo.getCoef());
            day.setPjfs(min.getPjfs());
        }
        stationInfoMinService.saveOrUpdateBatch(byDate);
    }
}






*/
