package com.yeejoin.amos.boot.module.jxiop.biz.service.impl;

import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.PostConstruct;

import com.yeejoin.amos.boot.module.jxiop.biz.Enum.WarningPeriodEnum;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.typroject.tyboot.component.emq.EmqKeeper;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.jxiop.api.dto.BizMessage;
import com.yeejoin.amos.boot.module.jxiop.api.dto.RiskBizInfoVo;
import com.yeejoin.amos.boot.module.jxiop.api.dto.RiskDynamicDetailsVo;
import com.yeejoin.amos.boot.module.jxiop.api.dto.TableContentVo;
import com.yeejoin.amos.boot.module.jxiop.api.entity.StationBasic;
import com.yeejoin.amos.boot.module.jxiop.api.mapper.StationBasicMapper;
import com.yeejoin.amos.boot.module.jxiop.biz.Enum.WarningNameEnum;
import com.yeejoin.amos.boot.module.jxiop.biz.constants.CommonConstans;
import com.yeejoin.amos.boot.module.jxiop.biz.entity.IdxBizFanWarningRecord;
import com.yeejoin.amos.boot.module.jxiop.biz.entity.IdxBizFanWarningRuleSet;
import com.yeejoin.amos.boot.module.jxiop.biz.entity.IdxBizPvWarningRecord;
import com.yeejoin.amos.boot.module.jxiop.biz.entity.IdxBizPvWarningRuleSet;
import com.yeejoin.amos.boot.module.jxiop.biz.entity5.JumpConfig;
import com.yeejoin.amos.boot.module.jxiop.biz.mapper2.IdxBizFanHealthIndexMapper;
import com.yeejoin.amos.boot.module.jxiop.biz.mapper2.IdxBizFanWarningRecordMapper;
import com.yeejoin.amos.boot.module.jxiop.biz.mapper2.IdxBizFanWarningRuleSetMapper;
import com.yeejoin.amos.boot.module.jxiop.biz.mapper2.IdxBizPvHealthIndexMapper;
import com.yeejoin.amos.boot.module.jxiop.biz.mapper2.IdxBizPvWarningRecordMapper;
import com.yeejoin.amos.boot.module.jxiop.biz.mapper2.IdxBizPvWarningRuleSetMapper;
import com.yeejoin.amos.boot.module.jxiop.biz.mapper5.JumpConfigMapper;
import com.yeejoin.amos.boot.module.jxiop.biz.tdMapper2.FanHealthIndexDayMapper;
import com.yeejoin.amos.boot.module.jxiop.biz.tdMapper2.FanHealthIndexHourMapper;
import com.yeejoin.amos.boot.module.jxiop.biz.tdMapper2.FanHealthIndexMomentMapper;
import com.yeejoin.amos.boot.module.jxiop.biz.tdMapper2.FanWaringRecordMapper;
import com.yeejoin.amos.boot.module.jxiop.biz.tdMapper2.PvHealthIndexDayMapper;
import com.yeejoin.amos.boot.module.jxiop.biz.tdMapper2.PvHealthIndexHourMapper;
import com.yeejoin.amos.boot.module.jxiop.biz.tdMapper2.PvHealthIndexMomentMapper;
import com.yeejoin.amos.boot.module.jxiop.biz.tdMapper2.PvWaringRecordMapper;
import com.yeejoin.amos.boot.module.jxiop.biz.tdengine.FanHealthIndexDay;
import com.yeejoin.amos.boot.module.jxiop.biz.tdengine.FanHealthIndexHour;
import com.yeejoin.amos.boot.module.jxiop.biz.tdengine.FanHealthIndexMoment;
import com.yeejoin.amos.boot.module.jxiop.biz.tdengine.FanWarningRecord;
import com.yeejoin.amos.boot.module.jxiop.biz.tdengine.PvHealthIndexDay;
import com.yeejoin.amos.boot.module.jxiop.biz.tdengine.PvHealthIndexHour;
import com.yeejoin.amos.boot.module.jxiop.biz.tdengine.PvHealthIndexMoment;
import com.yeejoin.amos.boot.module.jxiop.biz.tdengine.PvWarningRecord;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

@EnableScheduling
@Service
@Slf4j
public class HealthStatusIndicatorServiceImpl {

	// @Value("${healthValue_Warn}")
	// Double healthValueWarn;
	// @Value("${healthValue_Risk}")
	// Double healthValueRisk;
	// @Value("${healthValue_Notice}")
	// Double healthValueNotice;

	// @Value("${healthValue_DayCount}")
	// long healthValueDayCount;
	// @Value("${healthValue_HourCount}")
	// long healthValueHourCount;
	// @Value("${healthValue_MinCount}")
	// long healthValueMinCount;

	/**
	 * 夏造风电分析index_key
	 */
	public static final String INDEX_KEY_FAN = "XZFX#ZNFX";
	/**
	 * 泰和光伏分析 index_key
	 */
	public static final String INDEX_KEY_PV = "THFX#ZNFX";
	/**
	 * 智能分析触发预警系统标识 - 光伏
	 */
	public static final String SMART_ANALYSE_PV = "smartAnalysePv";
	/**
	 * 智能分析触发预警系统标识 - 风电
	 */
	public static final String SMART_ANALYSE_FAN = "smartAnalyseFan";
	@Autowired
	IdxBizFanHealthIndexMapper idxBizFanHealthIndexMapper;
	@Autowired
	IdxBizFanWarningRecordMapper idxBizFanWarningRecordMapper;
	@Autowired
	IdxBizPvWarningRecordServiceImpl idxBizPvWarningRecordService;
	@Autowired
	IdxBizFanWarningRecordServiceImpl idxBizFanWarningRecordService;
	/***
	 * 每一小时获取一次最大粒度内的指数异常数据 判断一小时内数据是否符合预警规则 符合则报警并在redis中缓存 同一级别的预警记录下次不生成
	 *
	 */

	@Autowired
	IdxBizPvHealthIndexMapper idxBizPvHealthIndexMapper;
	@Autowired
	PvHealthIndexHourMapper pvHealthIndexHourMapper;
	@Autowired
	PvHealthIndexDayMapper pvHealthIndexDayMapper;
	@Autowired
	PvHealthIndexMomentMapper pvHealthIndexMomentMapper;
	@Autowired
	FanHealthIndexHourMapper fanHealthIndexHourMapper;
	@Autowired
	FanHealthIndexDayMapper fanHealthIndexDayMapper;
	@Autowired
	FanHealthIndexMomentMapper fanHealthIndexMomentMapper;
	@Autowired
	IdxBizPvWarningRuleSetMapper idxBizPvWarningRuleSetMapper;
	@Autowired
	IdxBizFanWarningRuleSetMapper idxBizFanWarningRuleSetMapper;
	@Autowired
	IdxBizPvWarningRecordMapper idxBizPvWarningRecordMapper;
	@Autowired
	StationBasicMapper stationBasicMapper;
	@Autowired
	EmqKeeper emqKeeper;
	@Value("${openHealth:true}")
	boolean openHealth;
	@Autowired
	private RedisUtils redisUtils;
	@Autowired
	private FanWaringRecordMapper fanWaringRecordMapper;

	@Autowired
	private FanWarningRecordServiceImpl fanWarningRecordService;

	@Autowired
	private PvWaringRecordMapper pvWaringRecordMapper;

	@Value("${analyse.cycle.offset:1}")
	private Integer AnalyseOffset;
	@Autowired
	private JumpConfigMapper jumpConfigMapper;

	/***
	 * 每一小时获取一次最大粒度内的指数异常数据 判断一小时内数据是否符合预警规则 符合则报警并在redis中缓存 同一级别的预警记录下次不生成
	 *
	 */

	// @Scheduled(cron = "0 0 */1 * * ?")
	public void healthWarningMinuteGF(Date time) {
		String format = DateUtil.format(time, "yyyy-MM-dd HH:mm:00");
//        Date date = DateUtils.dateAddHours(time, -8);
		log.info("光伏---------------------预警时间----" + time);
		// Calendar calendar = Calendar.getInstance();
//        calendar.set(Calendar.HOUR_OF_DAY,calendar.get(Calendar.HOUR_OF_DAY)-1);
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");

		Integer maxWaringCycle = idxBizPvWarningRuleSetMapper.getMaxWaringCycleOfMinutes() + AnalyseOffset;
		Date date = DateUtil.offsetHour(time, -8);
		date = DateUtil.offsetMinute(date, 0 - (maxWaringCycle * 10));
		LambdaQueryWrapper<PvHealthIndexMoment> wrapper = new LambdaQueryWrapper<>();
		// wrapper.ne(PvHealthIndexMoment::getHealthLevel,"安全");
		wrapper.ge(PvHealthIndexMoment::getTs, date);
		wrapper.eq(PvHealthIndexMoment::getAnalysisObjType, "测点");
		Date dateMax = DateUtil.offsetHour(time, -8);
		wrapper.le(PvHealthIndexMoment::getTs, dateMax);
		wrapper.orderByAsc(PvHealthIndexMoment::getTs);
		List<PvHealthIndexMoment> healthIndices = pvHealthIndexMomentMapper.selectList(wrapper);
		List<String> collect = healthIndices.stream().map(PvHealthIndexMoment::getAnalysisObjSeq)
				.collect(Collectors.toList());
		if (null == healthIndices || collect.isEmpty()) {
			return;
		}
		LambdaQueryWrapper<IdxBizPvWarningRuleSet> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(IdxBizPvWarningRuleSet::getAnalysisType, WarningPeriodEnum.MINUTES.getName());
		queryWrapper.in(IdxBizPvWarningRuleSet::getAnalysisPointId, collect);
		List<IdxBizPvWarningRuleSet> idxBizPvWarningRules = idxBizPvWarningRuleSetMapper.selectList(queryWrapper);

		Map<String, Map<String, List<PvHealthIndexMoment>>> gateWayMaps = healthIndices.stream()
				.collect(Collectors.groupingBy(PvHealthIndexMoment::getGatewayId,
						Collectors.groupingBy(PvHealthIndexMoment::getIndexAddress)));
		List<IdxBizPvWarningRecord> idxBizPvWarningRecordList = new ArrayList<>();
		List<PvWarningRecord> tdPvWarningRecordList = new ArrayList<>();
		HashMap<String, StationBasic> stationMap = new HashMap<>();
		for (String gateWayId : gateWayMaps.keySet()) {

			LambdaQueryWrapper<StationBasic> basicLambdaQueryWrapper = new LambdaQueryWrapper<>();
			basicLambdaQueryWrapper.eq(StationBasic::getFanGatewayId, gateWayId).or().eq(StationBasic::getBoosterGatewayId, gateWayId);
			basicLambdaQueryWrapper.last("limit 1");
			StationBasic stationBasic = stationBasicMapper.selectOne(basicLambdaQueryWrapper);
			stationMap.put(gateWayId, stationBasic);

			Map<String, List<PvHealthIndexMoment>> healthDataMaps = gateWayMaps.get(gateWayId);
			for (String address : healthDataMaps.keySet()) {
				List<PvHealthIndexMoment> idxBizPvHealthIndices = healthDataMaps.get(address);
				List<IdxBizPvWarningRuleSet> idxBizPvWarningRuleSets = idxBizPvWarningRules.stream()
						.filter(t -> t.getAnalysisPointId().equals(idxBizPvHealthIndices.get(0).getAnalysisObjSeq()))
						.collect(Collectors.toList());
				if (ObjectUtils.isEmpty(idxBizPvWarningRuleSets)) {
					continue;
				}
				Double healthValueWarn = 0.0;
				Double healthValueRisk = 0.0;
				Double healthValueNotice = 0.0;

				int healthValueWarnCount = 0;
				int healthValueRiskCount = 0;
				int healthValueNoticeCount = 0;
				int healthValueMinCount = 0;
				int riskNum = 0;
				int warnNum = 0;
				int noticeNum = 0;

				for (IdxBizPvWarningRuleSet e : idxBizPvWarningRuleSets) {
					switch (e.getWarningName()) {
					case "警告":
						healthValueWarn = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueWarnCount = Integer.parseInt(e.getWarningCycle());
						break;
					case "危险":
						healthValueRisk = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueRiskCount = Integer.parseInt(e.getWarningCycle());
						break;
					case "注意":
						healthValueNotice = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueNoticeCount = Integer.parseInt(e.getWarningCycle());
						break;
					}

				}

				List<Double> healthIndex = idxBizPvHealthIndices.stream().map(PvHealthIndexMoment::getHealthIndex)
						.collect(Collectors.toList());
				Double finalHealthValueRisk = healthValueRisk;
				if (healthIndex.size() >= healthValueRiskCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueRiskCount,
							healthIndex.size());
					riskNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueRisk).count();
				}
				Double finalHealthValueWarn = healthValueWarn;
				if (healthIndex.size() >= healthValueWarnCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueWarnCount,
							healthIndex.size());
					warnNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueWarn).count();
				}
				Double finalHealthValueNotice = healthValueNotice;
				if (healthIndex.size() >= healthValueNoticeCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueNoticeCount,
							healthIndex.size());
					noticeNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueNotice).count();
				}
				String level = "";
				String content = "";
				String num = "";
				if (noticeNum == healthValueNoticeCount) {
					// redisUtils.set(gateWayId+"_"+address+"_health_notice_minute","notice");
					level = "注意";
					num = "" + healthValueNotice;
					content = healthValueNoticeCount * 10 + "分钟";
				}
				if (warnNum == healthValueWarnCount) {
					// redisUtils.set(gateWayId+"_"+address+"_health_warn_minute","warn");
					level = "警告";
					num = "" + healthValueWarn;
					content = healthValueWarnCount * 10 + "分钟";
				}
				if (riskNum == healthValueRiskCount) {
					// redisUtils.set(gateWayId+"_"+address+"_health_risk_minute","risk");
					level = "危险";
					num = "" + healthValueRisk;
					content = healthValueRiskCount * 10 + "分钟";

				}
				// 库里若已存在该测点预警 不生成重复的 若新生预警等级高于历史 则生成
				LambdaQueryWrapper<PvWarningRecord> query = new LambdaQueryWrapper<>();
				query.eq(PvWarningRecord::getAnalysisPointId, idxBizPvHealthIndices.get(0).getAnalysisObjSeq());
				query.eq(PvWarningRecord::getStatus, "0");
				query.isNull(PvWarningRecord::getDisposotionDate);
				query.orderByDesc(PvWarningRecord::getTs);
				List<PvWarningRecord> idxBizPvWarningRecords = pvWaringRecordMapper.selectList(query);

				int flag = ObjectUtils.isEmpty(idxBizPvWarningRecords) || WarningNameEnum
						.getCode(level) > WarningNameEnum.getCode(idxBizPvWarningRecords.get(0).getWarningName()) ? 0
								: 1;
				Boolean timeFlag = format
						.equals(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getRecDate());
				if (!level.equals("") && flag == 0 && timeFlag) {
					IdxBizPvWarningRecord idxBizPvWarningRecord = new IdxBizPvWarningRecord();
					idxBizPvWarningRecord.setKks(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getKks());
					idxBizPvWarningRecord
							.setArae(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getArea());
					idxBizPvWarningRecord
							.setStation(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getStation());
					idxBizPvWarningRecord
							.setSubarray(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getSubarray());
					idxBizPvWarningRecord.setGatewayId(gateWayId);
					idxBizPvWarningRecord.setIndexAddress(address);
					idxBizPvWarningRecord.setEquipmentName(
							idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getEquipmentName());
					idxBizPvWarningRecord.setAnalysisPointId(
							idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getAnalysisObjSeq());
					idxBizPvWarningRecord.setDisposotionState("待确认");
					idxBizPvWarningRecord.setStatus("0");
					idxBizPvWarningRecord.setWarningName(level);
					idxBizPvWarningRecord
							.setCONTENT(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getPointName()
									+ "连续" + content + "健康指数≤" + num);
					idxBizPvWarningRecord.setRecDate(time);
					idxBizPvWarningRecord.setWarningPeriod(WarningPeriodEnum.MINUTES.getName());
					idxBizPvWarningRecord.setManufacturer(
							idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getManufacturer());
					idxBizPvWarningRecord
							.setPointName(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getPointName());
					idxBizPvWarningRecord.setHealthIndexSeq(
							idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getHealthIndex().toString());
					idxBizPvWarningRecord.setHealthLevel(
							idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getHealthLevel());
					idxBizPvWarningRecordList.add(idxBizPvWarningRecord);
					long currentTimeMillis = System.currentTimeMillis();
					long nanoTime = System.nanoTime();
					long timestamp = currentTimeMillis * 1000000 + nanoTime % 1000000;
					PvWarningRecord pvWarningRecord = new PvWarningRecord();
					BeanUtils.copyProperties(idxBizPvWarningRecord, pvWarningRecord, "disposotionDate", "recDate",
							"CONTENT");
					pvWarningRecord.setContent(idxBizPvWarningRecord.getCONTENT());
					pvWarningRecord.setRecDate(format);
					pvWarningRecord.setTs(timestamp);
					pvWarningRecord.setHealthIndex(String.format(CommonConstans.Onedecimalplaces,
							idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getHealthIndex()));
					pvWarningRecord.setOrgCode(idxBizPvHealthIndices.get(0).getOrgCode());
					tdPvWarningRecordList.add(pvWarningRecord);
					// idxBizPvWarningRecordMapper.insert(idxBizPvWarningRecord);
				}
			}
		}
//        idxBizPvWarningRecordService.saveBatch(idxBizPvWarningRecordList);

		if (CollUtil.isNotEmpty(tdPvWarningRecordList)) {
			log.info("==================光伏按时刻产生预警数据成功", JSON.toJSONString(tdPvWarningRecordList));
			// tdengine插入
			pvWaringRecordMapper.saveBatchWarningRecords(tdPvWarningRecordList);
		}
		// 触发风险模型生成预警处置模块的预警记录
		fetchDataPv(tdPvWarningRecordList, stationMap);

	}

//     @Scheduled(cron = "0 0/5 * * * ?")
//    @Async("async")
//    public void healthWarningMinuteNoArg( ) {
//        Date time = new Date();
////        if (!openHealth){
////            return;
////        }
//        String format = DateUtil.format(time, "yyyy-MM-dd HH:mm:00");
////        Date date = DateUtils.dateAddHours(time, -8);
//        log.info("光伏---------------------预警时间----"+time);
//        // Calendar calendar = Calendar.getInstance();
////        calendar.set(Calendar.HOUR_OF_DAY,calendar.get(Calendar.HOUR_OF_DAY)-1);
//        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
//
//        Integer maxWaringCycle = idxBizPvWarningRuleSetMapper.getMaxWaringCycleOfMinutes();
//        Date date =DateUtil.offsetHour(time,-8);
//        date =DateUtil.offsetMinute(date,0-(maxWaringCycle*10));
//        LambdaQueryWrapper<PvHealthIndexMoment> wrapper = new LambdaQueryWrapper<>();
//        wrapper.ne(PvHealthIndexMoment::getHealthLevel,"安全");
//        wrapper.ge(PvHealthIndexMoment::getTs,date);
//        wrapper.eq(PvHealthIndexMoment::getAnalysisObjType, "测点");
//        wrapper.orderByDesc(PvHealthIndexMoment::getTs);
//        List<PvHealthIndexMoment> healthIndices = pvHealthIndexMomentMapper.selectList(wrapper);
//        List<String> collect = healthIndices.stream().map(PvHealthIndexMoment::getAnalysisObjSeq).collect(Collectors.toList());
//        if (null == healthIndices ){
//            return;
//        }
//        LambdaQueryWrapper<IdxBizPvWarningRuleSet> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(IdxBizPvWarningRuleSet::getAnalysisType,"按时刻");
//        queryWrapper.in(IdxBizPvWarningRuleSet::getAnalysisPointId, collect);
//        List<IdxBizPvWarningRuleSet> idxBizPvWarningRules = idxBizPvWarningRuleSetMapper.selectList(queryWrapper);
//
//
//        Map<String, Map<String, List<PvHealthIndexMoment>>> gateWayMaps = healthIndices.stream().collect(Collectors.groupingBy(PvHealthIndexMoment::getGatewayId, Collectors.groupingBy(PvHealthIndexMoment::getIndexAddress)));
//        List<IdxBizPvWarningRecord> idxBizPvWarningRecordList = new ArrayList<>();
//        List<PvWarningRecord> tdPvWarningRecordList = new ArrayList<>();
//        HashMap<String, StationBasic> stationMap = new HashMap<>();
//        for (String gateWayId : gateWayMaps.keySet()) {
//
//            LambdaQueryWrapper<StationBasic> basicLambdaQueryWrapper = new LambdaQueryWrapper<>();
//            basicLambdaQueryWrapper.eq(StationBasic::getFanGatewayId, gateWayId);
//            basicLambdaQueryWrapper.last("limit 1");
//            StationBasic stationBasic = stationBasicMapper.selectOne(basicLambdaQueryWrapper);
//            stationMap.put(gateWayId, stationBasic);
//
//            Map<String, List<PvHealthIndexMoment>> healthDataMaps = gateWayMaps.get(gateWayId);
//            for (String address : healthDataMaps.keySet()) {
//                List<PvHealthIndexMoment> idxBizPvHealthIndices = healthDataMaps.get(address);
//                List<IdxBizPvWarningRuleSet> idxBizPvWarningRuleSets = idxBizPvWarningRules.stream().filter(t -> t.getAnalysisPointId().equals(idxBizPvHealthIndices.get(0).getAnalysisObjSeq())).collect(Collectors.toList());
//                if (ObjectUtils.isEmpty(idxBizPvWarningRuleSets) ){
//                    continue;
//                }
//                Double healthValueWarn = 0.0;
//                Double healthValueRisk = 0.0;
//                Double healthValueNotice = 0.0;
//
//                int healthValueWarnCount = 0;
//                int healthValueRiskCount = 0;
//                int healthValueNoticeCount = 0;
//                int healthValueMinCount = 0;
//                int riskNum=0;
//                int warnNum=0;
//                int noticeNum=0;
//
//
//
//                for (IdxBizPvWarningRuleSet e : idxBizPvWarningRuleSets) {
//                    switch (e.getWarningName()){
//                        case "警告":
//                            healthValueWarn = Double.parseDouble(e.getWarningIf().substring(2));
//                            healthValueWarnCount =Integer.parseInt(e.getWarningCycle());
//                            break;
//                        case "危险":
//                            healthValueRisk = Double.parseDouble(e.getWarningIf().substring(2));
//                            healthValueRiskCount =Integer.parseInt(e.getWarningCycle());
//                            break;
//                        case "注意":
//                            healthValueNotice = Double.parseDouble(e.getWarningIf().substring(2));
//                            healthValueNoticeCount =Integer.parseInt(e.getWarningCycle());
//                            break;
//                    }
//
//                }
//
//                List<Double> healthIndex = idxBizPvHealthIndices.stream().map(PvHealthIndexMoment::getHealthIndex).collect(Collectors.toList());
//                Double finalHealthValueRisk = healthValueRisk;
//                if(healthIndex.size()>=healthValueRiskCount){
//                    List<Double> healthIndexList = healthIndex.subList(healthIndex.size()-healthValueRiskCount,healthIndex.size());
//                    riskNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueRisk).count();
//                }
//                Double finalHealthValueWarn = healthValueWarn;
//                if(healthIndex.size()>=healthValueWarnCount){
//                    List<Double> healthIndexList = healthIndex.subList(healthIndex.size()-healthValueWarnCount,healthIndex.size());
//                    warnNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueWarn).count();
//                }
//                Double finalHealthValueNotice = healthValueNotice;
//                if(healthIndex.size()>=healthValueNoticeCount){
//                    List<Double> healthIndexList = healthIndex.subList(healthIndex.size()-healthValueWarnCount,healthIndex.size());
//                    noticeNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueNotice).count();
//                }
//                String level = "";
//                String content = "";
//                String num = "";
//                if (noticeNum == healthValueNoticeCount ){
//                    //     redisUtils.set(gateWayId+"_"+address+"_health_notice_minute","notice");
//                    level ="注意";
//                    num = ""+healthValueNotice;
//                    content = healthValueNoticeCount*10 + "分钟";
//                }
//                if (warnNum == healthValueWarnCount ){
//                    //    redisUtils.set(gateWayId+"_"+address+"_health_warn_minute","warn");
//                    level ="警告";
//                    num = ""+healthValueWarn;
//                    content = healthValueWarnCount*10 + "分钟";
//                }
//                if (riskNum == healthValueRiskCount ){
//                    //   redisUtils.set(gateWayId+"_"+address+"_health_risk_minute","risk");
//                    level ="危险";
//                    num = ""+healthValueRisk;
//                    content = healthValueRiskCount*10 + "分钟";
//
//                }
//                //库里若已存在该测点预警 不生成重复的 若新生预警等级高于历史 则生成
//                LambdaQueryWrapper<PvWarningRecord> query = new LambdaQueryWrapper<>();
//                query.eq(PvWarningRecord::getAnalysisPointId,idxBizPvHealthIndices.get(0).getAnalysisObjSeq());
//                query.isNotNull(PvWarningRecord::getDisposotionDate);
//                query.orderByDesc(PvWarningRecord::getTs);
//                List<PvWarningRecord> idxBizPvWarningRecords = pvWaringRecordMapper.selectList(query);
//
//                int flag = ObjectUtils.isEmpty(idxBizPvWarningRecords)  || WarningNameEnum.getCode(level) > WarningNameEnum.getCode(idxBizPvWarningRecords.get(0).getWarningName()) ? 0 :1;
//
//                if (!level.equals("") && flag == 0){
//                    IdxBizPvWarningRecord idxBizPvWarningRecord = new IdxBizPvWarningRecord();
//                    idxBizPvWarningRecord.setKks(idxBizPvHealthIndices.get(0).getKks());
//                    idxBizPvWarningRecord.setArae(idxBizPvHealthIndices.get(0).getArea());
//                    idxBizPvWarningRecord.setStation(idxBizPvHealthIndices.get(0).getStation());
//                    idxBizPvWarningRecord.setSubarray(idxBizPvHealthIndices.get(0).getSubarray());
//                    idxBizPvWarningRecord.setGatewayId(gateWayId);
//                    idxBizPvWarningRecord.setIndexAddress(address);
//                    idxBizPvWarningRecord.setEquipmentName(idxBizPvHealthIndices.get(0).getEquipmentName());
//                    idxBizPvWarningRecord.setAnalysisPointId(idxBizPvHealthIndices.get(0).getAnalysisObjSeq());
//                    idxBizPvWarningRecord.setDisposotionState("待确认");
//                    idxBizPvWarningRecord.setStatus("0");
//                    idxBizPvWarningRecord.setWarningName(level);
//                    idxBizPvWarningRecord.setCONTENT(idxBizPvHealthIndices.get(0).getPointName() + "连续"+content+"健康指数≤"+num );
//                    idxBizPvWarningRecord.setRecDate(time);
//                    idxBizPvWarningRecord.setWarningPeriod("按时刻");
//                    idxBizPvWarningRecord.setManufacturer(idxBizPvHealthIndices.get(0).getManufacturer());
//                    idxBizPvWarningRecord.setPointName(idxBizPvHealthIndices.get(0).getPointName());
//                    idxBizPvWarningRecord.setHealthIndexSeq(idxBizPvHealthIndices.get(0).getHealthIndex().toString());
//                    idxBizPvWarningRecord.setHealthLevel(idxBizPvHealthIndices.get(0).getHealthLevel());
//                    idxBizPvWarningRecordList.add(idxBizPvWarningRecord);
//                    long currentTimeMillis = System.currentTimeMillis();
//                    long nanoTime = System.nanoTime();
//                    long timestamp = currentTimeMillis * 1000000 + nanoTime % 1000000;
//                    PvWarningRecord pvWarningRecord = new PvWarningRecord();
//                    BeanUtils.copyProperties(idxBizPvWarningRecord, pvWarningRecord, "disposotionDate", "recDate", "CONTENT");
//                    pvWarningRecord.setContent(idxBizPvWarningRecord.getCONTENT());
//                    pvWarningRecord.setRecDate(format);
//                    pvWarningRecord.setTs(timestamp);
//                    pvWarningRecord.setHealthIndex(String.format(CommonConstans.Onedecimalplaces,idxBizPvHealthIndices.get(0).getHealthIndex()));
//                    pvWarningRecord.setOrgCode(idxBizPvHealthIndices.get(0).getOrgCode());
//                    tdPvWarningRecordList.add(pvWarningRecord);
//                    // idxBizPvWarningRecordMapper.insert(idxBizPvWarningRecord);
//                }
//            }
//        }
////        idxBizPvWarningRecordService.saveBatch(idxBizPvWarningRecordList);
//
//        if (CollUtil.isNotEmpty(tdPvWarningRecordList)) {
//            log.info("==================光伏按时刻产生预警数据成功",JSON.toJSONString(tdPvWarningRecordList));
//            // tdengine插入
////            pvWaringRecordMapper.saveBatchWarningRecords(tdPvWarningRecordList);
//        }
//        // 触发风险模型生成预警处置模块的预警记录
//        fetchDataPv(tdPvWarningRecordList, stationMap);
//
//    }

	public void healthWarningMinuteGF(Date time, String gatewayId) {
		if (!openHealth) {
			return;
		}
		String format = DateUtil.format(time, "yyyy-MM-dd HH:mm:00");
//        Date date = DateUtils.dateAddHours(time, -8);
		log.info("光伏---------------------预警时间----" + time);
		// Calendar calendar = Calendar.getInstance();
//        calendar.set(Calendar.HOUR_OF_DAY,calendar.get(Calendar.HOUR_OF_DAY)-1);
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");

		Integer maxWaringCycle = idxBizPvWarningRuleSetMapper.getMaxWaringCycleOfMinutesByGatewayId(gatewayId)
				+ AnalyseOffset;
		Date date = DateUtil.offsetHour(time, -8);
		date = DateUtil.offsetMinute(date, 0 - (maxWaringCycle * 10));
		LambdaQueryWrapper<PvHealthIndexMoment> wrapper = new LambdaQueryWrapper<>();
		// wrapper.ne(PvHealthIndexMoment::getHealthLevel,"安全");
		wrapper.ge(PvHealthIndexMoment::getTs, date);
		wrapper.eq(PvHealthIndexMoment::getAnalysisObjType, "测点");
		wrapper.eq(PvHealthIndexMoment::getGatewayId, gatewayId);
		Date dateMax = DateUtil.offsetHour(time, -8);
		wrapper.le(PvHealthIndexMoment::getTs, dateMax);
		wrapper.orderByAsc(PvHealthIndexMoment::getTs);
		List<PvHealthIndexMoment> healthIndices = pvHealthIndexMomentMapper.selectList(wrapper);
		List<String> collect = healthIndices.stream().map(PvHealthIndexMoment::getAnalysisObjSeq)
				.collect(Collectors.toList());
		if (null == healthIndices) {
			return;
		}
		LambdaQueryWrapper<IdxBizPvWarningRuleSet> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(IdxBizPvWarningRuleSet::getAnalysisType, WarningPeriodEnum.MINUTES.getName());
		queryWrapper.in(IdxBizPvWarningRuleSet::getAnalysisPointId, collect);
		queryWrapper.eq(IdxBizPvWarningRuleSet::getGatewayId, gatewayId);
		List<IdxBizPvWarningRuleSet> idxBizPvWarningRules = idxBizPvWarningRuleSetMapper.selectList(queryWrapper);

		Map<String, Map<String, List<PvHealthIndexMoment>>> gateWayMaps = healthIndices.stream()
				.collect(Collectors.groupingBy(PvHealthIndexMoment::getGatewayId,
						Collectors.groupingBy(PvHealthIndexMoment::getIndexAddress)));
		List<IdxBizPvWarningRecord> idxBizPvWarningRecordList = new ArrayList<>();
		List<PvWarningRecord> tdPvWarningRecordList = new ArrayList<>();
		HashMap<String, StationBasic> stationMap = new HashMap<>();
//        for (String gateWayId : gateWayMaps.keySet()) {

		LambdaQueryWrapper<StationBasic> basicLambdaQueryWrapper = new LambdaQueryWrapper<>();
		basicLambdaQueryWrapper.eq(StationBasic::getFanGatewayId, gatewayId).or().eq(StationBasic::getBoosterGatewayId, gatewayId);
		basicLambdaQueryWrapper.last("limit 1");
		StationBasic stationBasic = stationBasicMapper.selectOne(basicLambdaQueryWrapper);
		stationMap.put(gatewayId, stationBasic);

		Map<String, List<PvHealthIndexMoment>> healthDataMaps = gateWayMaps.get(gatewayId);
		for (String address : healthDataMaps.keySet()) {
			List<PvHealthIndexMoment> idxBizPvHealthIndices = healthDataMaps.get(address);
			List<IdxBizPvWarningRuleSet> idxBizPvWarningRuleSets = idxBizPvWarningRules.stream()
					.filter(t -> t.getAnalysisPointId().equals(idxBizPvHealthIndices.get(0).getAnalysisObjSeq()))
					.collect(Collectors.toList());
			if (ObjectUtils.isEmpty(idxBizPvWarningRuleSets)) {
				continue;
			}
			Double healthValueWarn = 0.0;
			Double healthValueRisk = 0.0;
			Double healthValueNotice = 0.0;

			int healthValueWarnCount = 0;
			int healthValueRiskCount = 0;
			int healthValueNoticeCount = 0;
			int healthValueMinCount = 0;
			int riskNum = 0;
			int warnNum = 0;
			int noticeNum = 0;

			for (IdxBizPvWarningRuleSet e : idxBizPvWarningRuleSets) {
				switch (e.getWarningName()) {
				case "警告":
					healthValueWarn = Double.parseDouble(e.getWarningIf().substring(2));
					healthValueWarnCount = Integer.parseInt(e.getWarningCycle());
					break;
				case "危险":
					healthValueRisk = Double.parseDouble(e.getWarningIf().substring(2));
					healthValueRiskCount = Integer.parseInt(e.getWarningCycle());
					break;
				case "注意":
					healthValueNotice = Double.parseDouble(e.getWarningIf().substring(2));
					healthValueNoticeCount = Integer.parseInt(e.getWarningCycle());
					break;
				}

			}

			List<Double> healthIndex = idxBizPvHealthIndices.stream().map(PvHealthIndexMoment::getHealthIndex)
					.collect(Collectors.toList());
			Double finalHealthValueRisk = healthValueRisk;
			if (healthIndex.size() >= healthValueRiskCount) {
				List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueRiskCount,
						healthIndex.size());
				riskNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueRisk).count();
			}
			Double finalHealthValueWarn = healthValueWarn;
			if (healthIndex.size() >= healthValueWarnCount) {
				List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueWarnCount,
						healthIndex.size());
				warnNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueWarn).count();
			}
			Double finalHealthValueNotice = healthValueNotice;
			if (healthIndex.size() >= healthValueNoticeCount) {
				List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueNoticeCount,
						healthIndex.size());
				noticeNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueNotice).count();
			}
			String level = "";
			String content = "";
			String num = "";
			if (noticeNum == healthValueNoticeCount) {
				// redisUtils.set(gateWayId+"_"+address+"_health_notice_minute","notice");
				level = "注意";
				num = "" + healthValueNotice;
				content = healthValueNoticeCount * 10 + "分钟";
			}
			if (warnNum == healthValueWarnCount) {
				// redisUtils.set(gateWayId+"_"+address+"_health_warn_minute","warn");
				level = "警告";
				num = "" + healthValueWarn;
				content = healthValueWarnCount * 10 + "分钟";
			}
			if (riskNum == healthValueRiskCount) {
				// redisUtils.set(gateWayId+"_"+address+"_health_risk_minute","risk");
				level = "危险";
				num = "" + healthValueRisk;
				content = healthValueRiskCount * 10 + "分钟";

			}
			// 库里若已存在该测点预警 不生成重复的 若新生预警等级高于历史 则生成
			LambdaQueryWrapper<PvWarningRecord> query = new LambdaQueryWrapper<>();
			query.eq(PvWarningRecord::getAnalysisPointId, idxBizPvHealthIndices.get(0).getAnalysisObjSeq());
			query.eq(PvWarningRecord::getStatus, "0");
			query.isNull(PvWarningRecord::getDisposotionDate);
			query.orderByDesc(PvWarningRecord::getTs);
			List<PvWarningRecord> idxBizPvWarningRecords = pvWaringRecordMapper.selectList(query);

			int flag = ObjectUtils.isEmpty(idxBizPvWarningRecords) || WarningNameEnum.getCode(level) > WarningNameEnum
					.getCode(idxBizPvWarningRecords.get(0).getWarningName()) ? 0 : 1;
			Boolean timeFlag = format.equals(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getRecDate());
			if (!level.equals("") && flag == 0 && timeFlag) {
				IdxBizPvWarningRecord idxBizPvWarningRecord = new IdxBizPvWarningRecord();
				idxBizPvWarningRecord.setKks(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getKks());
				idxBizPvWarningRecord.setArae(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getArea());
				idxBizPvWarningRecord
						.setStation(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getStation());
				idxBizPvWarningRecord
						.setSubarray(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getSubarray());
				idxBizPvWarningRecord.setGatewayId(gatewayId);
				idxBizPvWarningRecord.setIndexAddress(address);
				idxBizPvWarningRecord.setEquipmentName(
						idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getEquipmentName());
				idxBizPvWarningRecord.setAnalysisPointId(
						idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getAnalysisObjSeq());
				idxBizPvWarningRecord.setDisposotionState("待确认");
				idxBizPvWarningRecord.setStatus("0");
				idxBizPvWarningRecord.setWarningName(level);
				idxBizPvWarningRecord
						.setCONTENT(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getPointName() + "连续"
								+ content + "健康指数≤" + num);
				idxBizPvWarningRecord.setRecDate(time);
				idxBizPvWarningRecord.setWarningPeriod(WarningPeriodEnum.MINUTES.getName());
				idxBizPvWarningRecord
						.setManufacturer(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getManufacturer());
				idxBizPvWarningRecord
						.setPointName(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getPointName());
				idxBizPvWarningRecord.setHealthIndexSeq(
						idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getHealthIndex().toString());
				idxBizPvWarningRecord
						.setHealthLevel(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getHealthLevel());
				idxBizPvWarningRecordList.add(idxBizPvWarningRecord);
				long currentTimeMillis = System.currentTimeMillis();
				long nanoTime = System.nanoTime();
				long timestamp = currentTimeMillis * 1000000 + nanoTime % 1000000;
				PvWarningRecord pvWarningRecord = new PvWarningRecord();
				BeanUtils.copyProperties(idxBizPvWarningRecord, pvWarningRecord, "disposotionDate", "recDate",
						"CONTENT");
				pvWarningRecord.setContent(idxBizPvWarningRecord.getCONTENT());
				pvWarningRecord.setRecDate(format);
				pvWarningRecord.setTs(timestamp);
				pvWarningRecord.setHealthIndex(String.format(CommonConstans.Onedecimalplaces,
						idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getHealthIndex()));
				pvWarningRecord.setOrgCode(idxBizPvHealthIndices.get(0).getOrgCode());
				tdPvWarningRecordList.add(pvWarningRecord);
				// idxBizPvWarningRecordMapper.insert(idxBizPvWarningRecord);
			}
		}
//        }
//        idxBizPvWarningRecordService.saveBatch(idxBizPvWarningRecordList);

		if (CollUtil.isNotEmpty(tdPvWarningRecordList)) {
			log.info("==================光伏按时刻产生预警数据成功", JSON.toJSONString(tdPvWarningRecordList));
			// tdengine插入
			pvWaringRecordMapper.saveBatchWarningRecords(tdPvWarningRecordList);
		}
		// 触发风险模型生成预警处置模块的预警记录
		fetchDataPv(tdPvWarningRecordList, stationMap);

	}

	/***
	 * 每五小时获取一次最大粒度内的指数异常数据 判断五小时内数据是否符合预警规则 符合则报警并在redis中缓存 同一级别的预警记录下次不生成
	 * TdengineTimeServiceImpl计算完调用
	 */

	// @Scheduled(cron = "0 0 0/1 * * ?")
	public void healthWarningHourGF() {
		if (!openHealth) {
			return;
		}
		Date time = new Date();
//        Date date = DateUtils.dateAddHours(time, -13);
//        Calendar calendar = Calendar.getInstance();
//        calendar.set(Calendar.HOUR_OF_DAY,calendar.get(Calendar.HOUR_OF_DAY)-5);
//        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		Integer maxWaringCycle = idxBizPvWarningRuleSetMapper.getMaxWaringCycleOfHour() + AnalyseOffset;
		String format = DateUtil.format(time, "yyyy-MM-dd HH:mm:00");
		Date date = DateUtil.offsetHour(time, -8);
		date = DateUtil.offsetHour(date, 0 - maxWaringCycle);

		LambdaQueryWrapper<PvHealthIndexHour> wrapper = new LambdaQueryWrapper<>();
		// wrapper.ne(PvHealthIndexHour::getHealthLevel,"安全");
		wrapper.eq(PvHealthIndexHour::getAnalysisObjType, "测点");
		wrapper.ge(PvHealthIndexHour::getTs, date);
		Date dateMax = DateUtil.offsetHour(time, -8);
		wrapper.le(PvHealthIndexHour::getTs, dateMax);
		wrapper.orderByAsc(PvHealthIndexHour::getTs);
		List<PvHealthIndexHour> healthIndices = pvHealthIndexHourMapper.selectList(wrapper);
		List<String> collect = healthIndices.stream().map(PvHealthIndexHour::getAnalysisObjSeq)
				.collect(Collectors.toList());
		if (null == healthIndices || collect == null || collect.isEmpty()) {
			return;
		}
		LambdaQueryWrapper<IdxBizPvWarningRuleSet> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(IdxBizPvWarningRuleSet::getAnalysisType, WarningPeriodEnum.HOUR.getName());
		queryWrapper.in(IdxBizPvWarningRuleSet::getAnalysisPointId, collect);
		List<IdxBizPvWarningRuleSet> idxBizPvWarningRules = idxBizPvWarningRuleSetMapper.selectList(queryWrapper);

		Map<String, Map<String, List<PvHealthIndexHour>>> gateWayMaps = healthIndices.stream()
				.collect(Collectors.groupingBy(PvHealthIndexHour::getGatewayId,
						Collectors.groupingBy(PvHealthIndexHour::getIndexAddress)));
		List<IdxBizPvWarningRecord> idxBizPvWarningRecordList = new ArrayList<>();
		List<PvWarningRecord> tdPvWarningRecordList = new ArrayList<>();
		HashMap<String, StationBasic> stationMap = new HashMap<>();
		for (String gateWayId : gateWayMaps.keySet()) {

			LambdaQueryWrapper<StationBasic> basicLambdaQueryWrapper = new LambdaQueryWrapper<>();
			basicLambdaQueryWrapper.eq(StationBasic::getFanGatewayId, gateWayId).or().eq(StationBasic::getBoosterGatewayId, gateWayId);
			basicLambdaQueryWrapper.last("limit 1");
			StationBasic stationBasic = stationBasicMapper.selectOne(basicLambdaQueryWrapper);
			stationMap.put(gateWayId, stationBasic);

			Map<String, List<PvHealthIndexHour>> healthDataMaps = gateWayMaps.get(gateWayId);
			for (String address : healthDataMaps.keySet()) {
				List<PvHealthIndexHour> idxBizPvHealthIndices = healthDataMaps.get(address);
				List<IdxBizPvWarningRuleSet> idxBizPvWarningRuleSets = idxBizPvWarningRules.stream()
						.filter(t -> t.getAnalysisPointId().equals(idxBizPvHealthIndices.get(0).getAnalysisObjSeq()))
						.collect(Collectors.toList());
				if (ObjectUtils.isEmpty(idxBizPvWarningRuleSets)) {
					continue;
				}

				Double healthValueWarn = 0.0;
				Double healthValueRisk = 0.0;
				Double healthValueNotice = 0.0;

				int healthValueWarnCount = 0;
				int healthValueRiskCount = 0;
				int healthValueNoticeCount = 0;
				int healthValueMinCount = 0;
				int riskNum = 0;
				int warnNum = 0;
				int noticeNum = 0;

				for (IdxBizPvWarningRuleSet e : idxBizPvWarningRuleSets) {
					switch (e.getWarningName()) {
					case "警告":
						healthValueWarn = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueWarnCount = Integer.parseInt(e.getWarningCycle());
						break;
					case "危险":
						healthValueRisk = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueRiskCount = Integer.parseInt(e.getWarningCycle());
						break;
					case "注意":
						healthValueNotice = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueNoticeCount = Integer.parseInt(e.getWarningCycle());
						break;
					}

				}
				List<Double> healthIndex = idxBizPvHealthIndices.stream().map(PvHealthIndexHour::getHealthIndex)
						.collect(Collectors.toList());
//                Double finalHealthValueRisk = healthValueRisk;
//                long riskNum = healthIndex.subList(healthIndex.size()>healthValueRiskCount? (int) (healthIndex.size() - healthValueRiskCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueRisk).count();
//                Double finalHealthValueWarn = healthValueWarn;
//                long warnNum = healthIndex.subList(healthIndex.size()>healthValueWarnCount? (int) (healthIndex.size() - healthValueWarnCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueWarn).count();
//                Double finalHealthValueNotice = healthValueNotice;
//                long noticeNum = healthIndex.subList(healthIndex.size()>healthValueNoticeCount? (int) (healthIndex.size() - healthValueNoticeCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueNotice).count();
				Double finalHealthValueRisk = healthValueRisk;
				if (healthIndex.size() >= healthValueRiskCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueRiskCount,
							healthIndex.size());
					riskNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueRisk).count();
				}
				Double finalHealthValueWarn = healthValueWarn;
				if (healthIndex.size() >= healthValueWarnCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueWarnCount,
							healthIndex.size());
					warnNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueWarn).count();
				}
				Double finalHealthValueNotice = healthValueNotice;
				if (healthIndex.size() >= healthValueNoticeCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueNoticeCount,
							healthIndex.size());
					noticeNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueNotice).count();
				}
				String level = "";
				String content = "";
				String num = "";
				if (noticeNum == healthValueNoticeCount) {
					level = "注意";
					num = "" + healthValueNotice;
					content = healthValueNoticeCount + "小时";
				}
				if (warnNum == healthValueWarnCount) {

					level = "警告";
					num = "" + healthValueWarn;
					content = healthValueWarnCount + "小时";
				}
				if (riskNum == healthValueRiskCount) {
					level = "危险";
					num = "" + healthValueRisk;
					content = healthValueRiskCount + "小时";
				}
				// 库里若已存在该测点预警 不生成重复的 若新生预警等级高于历史 则生成
				LambdaQueryWrapper<PvWarningRecord> query = new LambdaQueryWrapper<>();
				query.eq(PvWarningRecord::getAnalysisPointId, idxBizPvHealthIndices.get(0).getAnalysisObjSeq());
				query.eq(PvWarningRecord::getStatus, "0");
				query.isNull(PvWarningRecord::getDisposotionDate);
				query.orderByDesc(PvWarningRecord::getRecDate);
				List<PvWarningRecord> idxBizPvWarningRecords = pvWaringRecordMapper.selectList(query);

				int flag = ObjectUtils.isEmpty(idxBizPvWarningRecords) || WarningNameEnum
						.getCode(level) > WarningNameEnum.getCode(idxBizPvWarningRecords.get(0).getWarningName()) ? 0
								: 1;
				Boolean timeFlag = format
						.equals(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getRecDate());
				if (!level.equals("") && flag == 0 && timeFlag) {
					IdxBizPvWarningRecord idxBizPvWarningRecord = new IdxBizPvWarningRecord();
					idxBizPvWarningRecord.setKks(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getKks());
					idxBizPvWarningRecord
							.setArae(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getArea());
					idxBizPvWarningRecord
							.setStation(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getStation());
					idxBizPvWarningRecord
							.setSubarray(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getSubarray());
					idxBizPvWarningRecord.setGatewayId(gateWayId);
					idxBizPvWarningRecord.setIndexAddress(address);
					idxBizPvWarningRecord.setEquipmentName(
							idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getEquipmentName());
					idxBizPvWarningRecord.setAnalysisPointId(
							idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getAnalysisObjSeq());
					idxBizPvWarningRecord.setDisposotionState("待确认");
					idxBizPvWarningRecord.setStatus("0");
					idxBizPvWarningRecord.setWarningName(level);
					idxBizPvWarningRecord
							.setCONTENT(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getPointName()
									+ "连续" + content + "健康指数≤" + num);
					idxBizPvWarningRecord.setRecDate(time);
					idxBizPvWarningRecord.setWarningPeriod(WarningPeriodEnum.HOUR.getName());
					idxBizPvWarningRecord.setManufacturer(
							idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getManufacturer());
					idxBizPvWarningRecord
							.setPointName(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getPointName());
					idxBizPvWarningRecord.setHealthIndexSeq(
							idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getHealthIndex().toString());
					idxBizPvWarningRecord.setHealthLevel(
							idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getHealthLevel());
					idxBizPvWarningRecordList.add(idxBizPvWarningRecord);
					// idxBizPvWarningRecordMapper.insert(idxBizPvWarningRecord);

					long currentTimeMillis = System.currentTimeMillis();
					long nanoTime = System.nanoTime();
					long timestamp = currentTimeMillis * 1000000 + nanoTime % 1000000;
					PvWarningRecord pvWarningRecord = new PvWarningRecord();
					BeanUtils.copyProperties(idxBizPvWarningRecord, pvWarningRecord, "disposotionDate", "recDate",
							"CONTENT");
					pvWarningRecord.setContent(idxBizPvWarningRecord.getCONTENT());
					pvWarningRecord.setRecDate(format);
					pvWarningRecord.setTs(timestamp);
					pvWarningRecord.setHealthIndex(String.format(CommonConstans.Onedecimalplaces,
							idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getHealthIndex()));
					pvWarningRecord.setOrgCode(idxBizPvHealthIndices.get(0).getOrgCode());
					tdPvWarningRecordList.add(pvWarningRecord);
				}
			}
		}
//        idxBizPvWarningRecordService.saveBatch(idxBizPvWarningRecordList);
		if (CollUtil.isNotEmpty(tdPvWarningRecordList)) {
			// tdengine插入
			log.info("==================光伏按小时产生预警数据成功", JSON.toJSONString(tdPvWarningRecordList));
			pvWaringRecordMapper.saveBatchWarningRecords(tdPvWarningRecordList);
		}
		// 触发风险模型生成预警处置模块的预警记录
		fetchDataPv(tdPvWarningRecordList, stationMap);
	}

//    @Scheduled(cron = "0 0 0/1 * * ?")
//    @Scheduled(cron = "0 0/5 * * * ?")
	public void healthWarningHourGFNew() {

		if (!openHealth) {
			return;
		}
		Date time = new Date();
//        Date date = DateUtils.dateAddHours(time, -13);
//        Calendar calendar = Calendar.getInstance();
//        calendar.set(Calendar.HOUR_OF_DAY,calendar.get(Calendar.HOUR_OF_DAY)-5);
//        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");

		List<String> gateWayIds = idxBizPvWarningRuleSetMapper.getGatewayIds();
		gateWayIds.forEach(gateWayId -> {
			new Thread(() -> {
				Integer maxWaringCycle = idxBizPvWarningRuleSetMapper.getMaxWaringCycleOfHourByGatewayId(gateWayId)
						+ AnalyseOffset;
				String format = DateUtil.format(time, "yyyy-MM-dd HH:mm:00");
				Date date = DateUtil.offsetHour(time, -8);
				date = DateUtil.offsetHour(date, 0 - maxWaringCycle);

				LambdaQueryWrapper<PvHealthIndexHour> wrapper = new LambdaQueryWrapper<>();
				// wrapper.ne(PvHealthIndexHour::getHealthLevel,"安全");
				wrapper.eq(PvHealthIndexHour::getGatewayId, gateWayId);
				wrapper.eq(PvHealthIndexHour::getAnalysisObjType, "测点");
				wrapper.ge(PvHealthIndexHour::getTs, date);
				Date dateMax = DateUtil.offsetHour(time, -8);
				wrapper.le(PvHealthIndexHour::getTs, dateMax);
				wrapper.orderByAsc(PvHealthIndexHour::getTs);
				List<PvHealthIndexHour> healthIndices = pvHealthIndexHourMapper.selectList(wrapper);
				List<String> collect = healthIndices.stream().map(PvHealthIndexHour::getAnalysisObjSeq)
						.collect(Collectors.toList());
				if (null == healthIndices) {
					return;
				}
				LambdaQueryWrapper<IdxBizPvWarningRuleSet> queryWrapper = new LambdaQueryWrapper<>();
				queryWrapper.eq(IdxBizPvWarningRuleSet::getAnalysisType, WarningPeriodEnum.HOUR.getName());
				queryWrapper.in(IdxBizPvWarningRuleSet::getAnalysisPointId, collect);
				List<IdxBizPvWarningRuleSet> idxBizPvWarningRules = idxBizPvWarningRuleSetMapper
						.selectList(queryWrapper);

				Map<String, Map<String, List<PvHealthIndexHour>>> gateWayMaps = healthIndices.stream()
						.collect(Collectors.groupingBy(PvHealthIndexHour::getGatewayId,
								Collectors.groupingBy(PvHealthIndexHour::getIndexAddress)));
				List<IdxBizPvWarningRecord> idxBizPvWarningRecordList = new ArrayList<>();
				List<PvWarningRecord> tdPvWarningRecordList = new ArrayList<>();
				HashMap<String, StationBasic> stationMap = new HashMap<>();
//            for (String gateWayId : gateWayMaps.keySet()) {

				LambdaQueryWrapper<StationBasic> basicLambdaQueryWrapper = new LambdaQueryWrapper<>();
				basicLambdaQueryWrapper.eq(StationBasic::getFanGatewayId, gateWayId).or().eq(StationBasic::getBoosterGatewayId, gateWayId);
				basicLambdaQueryWrapper.last("limit 1");
				StationBasic stationBasic = stationBasicMapper.selectOne(basicLambdaQueryWrapper);
				stationMap.put(gateWayId, stationBasic);

				Map<String, List<PvHealthIndexHour>> healthDataMaps = gateWayMaps.get(gateWayId);
				for (String address : healthDataMaps.keySet()) {
					List<PvHealthIndexHour> idxBizPvHealthIndices = healthDataMaps.get(address);
					List<IdxBizPvWarningRuleSet> idxBizPvWarningRuleSets = idxBizPvWarningRules.stream().filter(
							t -> t.getAnalysisPointId().equals(idxBizPvHealthIndices.get(0).getAnalysisObjSeq()))
							.collect(Collectors.toList());
					if (ObjectUtils.isEmpty(idxBizPvWarningRuleSets)) {
						continue;
					}

					Double healthValueWarn = 0.0;
					Double healthValueRisk = 0.0;
					Double healthValueNotice = 0.0;

					int healthValueWarnCount = 0;
					int healthValueRiskCount = 0;
					int healthValueNoticeCount = 0;
					int healthValueMinCount = 0;
					int riskNum = 0;
					int warnNum = 0;
					int noticeNum = 0;

					for (IdxBizPvWarningRuleSet e : idxBizPvWarningRuleSets) {
						switch (e.getWarningName()) {
						case "警告":
							healthValueWarn = Double.parseDouble(e.getWarningIf().substring(2));
							healthValueWarnCount = Integer.parseInt(e.getWarningCycle());
							break;
						case "危险":
							healthValueRisk = Double.parseDouble(e.getWarningIf().substring(2));
							healthValueRiskCount = Integer.parseInt(e.getWarningCycle());
							break;
						case "注意":
							healthValueNotice = Double.parseDouble(e.getWarningIf().substring(2));
							healthValueNoticeCount = Integer.parseInt(e.getWarningCycle());
							break;
						}

					}
					List<Double> healthIndex = idxBizPvHealthIndices.stream().map(PvHealthIndexHour::getHealthIndex)
							.collect(Collectors.toList());
//                Double finalHealthValueRisk = healthValueRisk;
//                long riskNum = healthIndex.subList(healthIndex.size()>healthValueRiskCount? (int) (healthIndex.size() - healthValueRiskCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueRisk).count();
//                Double finalHealthValueWarn = healthValueWarn;
//                long warnNum = healthIndex.subList(healthIndex.size()>healthValueWarnCount? (int) (healthIndex.size() - healthValueWarnCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueWarn).count();
//                Double finalHealthValueNotice = healthValueNotice;
//                long noticeNum = healthIndex.subList(healthIndex.size()>healthValueNoticeCount? (int) (healthIndex.size() - healthValueNoticeCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueNotice).count();
					Double finalHealthValueRisk = healthValueRisk;
					if (healthIndex.size() >= healthValueRiskCount) {
						List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueRiskCount,
								healthIndex.size());
						riskNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueRisk).count();
					}
					Double finalHealthValueWarn = healthValueWarn;
					if (healthIndex.size() >= healthValueWarnCount) {
						List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueWarnCount,
								healthIndex.size());
						warnNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueWarn).count();
					}
					Double finalHealthValueNotice = healthValueNotice;
					if (healthIndex.size() >= healthValueNoticeCount) {
						List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueNoticeCount,
								healthIndex.size());
						noticeNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueNotice).count();
					}
					String level = "";
					String content = "";
					String num = "";
					if (noticeNum == healthValueNoticeCount) {
						level = "注意";
						num = "" + healthValueNotice;
						content = healthValueNoticeCount + "小时";
					}
					if (warnNum == healthValueWarnCount) {

						level = "警告";
						num = "" + healthValueWarn;
						content = healthValueWarnCount + "小时";
					}
					if (riskNum == healthValueRiskCount) {
						level = "危险";
						num = "" + healthValueRisk;
						content = healthValueRiskCount + "小时";
					}
					// 库里若已存在该测点预警 不生成重复的 若新生预警等级高于历史 则生成
					LambdaQueryWrapper<PvWarningRecord> query = new LambdaQueryWrapper<>();
					query.eq(PvWarningRecord::getAnalysisPointId, idxBizPvHealthIndices.get(0).getAnalysisObjSeq());
					query.eq(PvWarningRecord::getStatus, "0");
					query.isNull(PvWarningRecord::getDisposotionDate);
					query.orderByDesc(PvWarningRecord::getRecDate);
					List<PvWarningRecord> idxBizPvWarningRecords = pvWaringRecordMapper.selectList(query);

					int flag = ObjectUtils.isEmpty(idxBizPvWarningRecords) || WarningNameEnum
							.getCode(level) > WarningNameEnum.getCode(idxBizPvWarningRecords.get(0).getWarningName())
									? 0
									: 1;
					Boolean timeFlag = format
							.equals(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getRecDate());
					if (!level.equals("") && flag == 0 && timeFlag) {
						IdxBizPvWarningRecord idxBizPvWarningRecord = new IdxBizPvWarningRecord();
						idxBizPvWarningRecord
								.setKks(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getKks());
						idxBizPvWarningRecord
								.setArae(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getArea());
						idxBizPvWarningRecord
								.setStation(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getStation());
						idxBizPvWarningRecord
								.setSubarray(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getSubarray());
						idxBizPvWarningRecord.setGatewayId(gateWayId);
						idxBizPvWarningRecord.setIndexAddress(address);
						idxBizPvWarningRecord.setEquipmentName(
								idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getEquipmentName());
						idxBizPvWarningRecord.setAnalysisPointId(
								idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getAnalysisObjSeq());
						idxBizPvWarningRecord.setDisposotionState("待确认");
						idxBizPvWarningRecord.setStatus("0");
						idxBizPvWarningRecord.setWarningName(level);
						idxBizPvWarningRecord
								.setCONTENT(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getPointName()
										+ "连续" + content + "健康指数≤" + num);
						idxBizPvWarningRecord.setRecDate(time);
						idxBizPvWarningRecord.setWarningPeriod(WarningPeriodEnum.HOUR.getName());
						idxBizPvWarningRecord.setManufacturer(
								idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getManufacturer());
						idxBizPvWarningRecord.setPointName(
								idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getPointName());
						idxBizPvWarningRecord.setHealthIndexSeq(idxBizPvHealthIndices
								.get(idxBizPvHealthIndices.size() - 1).getHealthIndex().toString());
						idxBizPvWarningRecord.setHealthLevel(
								idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getHealthLevel());
						idxBizPvWarningRecordList.add(idxBizPvWarningRecord);
						// idxBizPvWarningRecordMapper.insert(idxBizPvWarningRecord);

						long currentTimeMillis = System.currentTimeMillis();
						long nanoTime = System.nanoTime();
						long timestamp = currentTimeMillis * 1000000 + nanoTime % 1000000;
						PvWarningRecord pvWarningRecord = new PvWarningRecord();
						BeanUtils.copyProperties(idxBizPvWarningRecord, pvWarningRecord, "disposotionDate", "recDate",
								"CONTENT");
						pvWarningRecord.setContent(idxBizPvWarningRecord.getCONTENT());
						pvWarningRecord.setRecDate(format);
						pvWarningRecord.setTs(timestamp);
						pvWarningRecord.setHealthIndex(String.format(CommonConstans.Onedecimalplaces,
								idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getHealthIndex()));
						pvWarningRecord.setOrgCode(idxBizPvHealthIndices.get(0).getOrgCode());
						tdPvWarningRecordList.add(pvWarningRecord);
					}
				}
//            }
//        idxBizPvWarningRecordService.saveBatch(idxBizPvWarningRecordList);
				if (CollUtil.isNotEmpty(tdPvWarningRecordList)) {
					// tdengine插入
					log.info("==================光伏按小时产生预警数据成功", JSON.toJSONString(tdPvWarningRecordList));
					pvWaringRecordMapper.saveBatchWarningRecords(tdPvWarningRecordList);
				}
				// 触发风险模型生成预警处置模块的预警记录
				fetchDataPv(tdPvWarningRecordList, stationMap);
			}).start();
		});
	}

	/***
	 * 每三天取一次最大粒度内的指数异常数据 判断三天内数据是否符合预警规则 符合则报警并在redis中缓存 同一级别的预警记录下次不生成
	 * TdengineTimeServiceImpl计算完调用
	 */

	// @Scheduled(cron = "0 0 0 0/1 * ? ")
	public void healthWarningDayGF() {
		if (!openHealth) {
			return;
		}
//        Calendar calendar = Calendar.getInstance();
		Date time = new Date();
		// 三天 + 8小时
//        Date date = DateUtils.dateAddHours(time, -80);
//        calendar.set(Calendar.DAY_OF_MONTH,calendar.get(Calendar.DAY_OF_MONTH)-3);
//        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		Integer maxWaringCycle = idxBizPvWarningRuleSetMapper.getMaxWaringCycleOfDay() + AnalyseOffset;
		String format = DateUtil.format(time, "yyyy-MM-dd HH:mm:00");
		Date date = DateUtil.offsetHour(time, -8);
		date = DateUtil.offsetDay(date, 0 - maxWaringCycle);
		LambdaQueryWrapper<PvHealthIndexDay> wrapper = new LambdaQueryWrapper<>();
		// wrapper.ne(PvHealthIndexDay::getHealthLevel, "安全");
		wrapper.eq(PvHealthIndexDay::getAnalysisObjType, "测点");
		wrapper.ge(PvHealthIndexDay::getTs, date);
		Date dateMax = DateUtil.offsetHour(time, -8);
		wrapper.le(PvHealthIndexDay::getTs, dateMax);
		wrapper.orderByAsc(PvHealthIndexDay::getTs);
		List<PvHealthIndexDay> healthIndices = pvHealthIndexDayMapper.selectList(wrapper);

		if (null == healthIndices) {
			return;
		}
		List<String> collect = healthIndices.stream().map(PvHealthIndexDay::getAnalysisObjSeq)
				.collect(Collectors.toList());

		LambdaQueryWrapper<IdxBizPvWarningRuleSet> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(IdxBizPvWarningRuleSet::getAnalysisType, WarningPeriodEnum.DAY.getName());
		queryWrapper.in(IdxBizPvWarningRuleSet::getAnalysisPointId, collect);
		List<IdxBizPvWarningRuleSet> idxBizPvWarningRules = idxBizPvWarningRuleSetMapper.selectList(queryWrapper);
		Map<String, Map<String, List<PvHealthIndexDay>>> gateWayMaps = healthIndices.stream().collect(Collectors
				.groupingBy(PvHealthIndexDay::getGatewayId, Collectors.groupingBy(PvHealthIndexDay::getIndexAddress)));
		List<IdxBizPvWarningRecord> idxBizPvWarningRecordList = new ArrayList<>();
		List<PvWarningRecord> tdPvWarningRecordList = new ArrayList<>();
		HashMap<String, StationBasic> stationMap = new HashMap<>();
		for (String gateWayId : gateWayMaps.keySet()) {

			LambdaQueryWrapper<StationBasic> basicLambdaQueryWrapper = new LambdaQueryWrapper<>();
			basicLambdaQueryWrapper.eq(StationBasic::getFanGatewayId, gateWayId).or().eq(StationBasic::getBoosterGatewayId, gateWayId);
			basicLambdaQueryWrapper.last("limit 1");
			StationBasic stationBasic = stationBasicMapper.selectOne(basicLambdaQueryWrapper);
			stationMap.put(gateWayId, stationBasic);

			Map<String, List<PvHealthIndexDay>> healthDataMaps = gateWayMaps.get(gateWayId);
			for (String address : healthDataMaps.keySet()) {
				List<PvHealthIndexDay> idxBizPvHealthIndices = healthDataMaps.get(address);
				List<IdxBizPvWarningRuleSet> idxBizPvWarningRuleSets = idxBizPvWarningRules.stream()
						.filter(t -> t.getAnalysisPointId().equals(idxBizPvHealthIndices.get(0).getAnalysisObjSeq()))
						.collect(Collectors.toList());
				if (ObjectUtils.isEmpty(idxBizPvWarningRuleSets)) {
					continue;
				}
				Double healthValueWarn = 0.0;
				Double healthValueRisk = 0.0;
				Double healthValueNotice = 0.0;

				int healthValueWarnCount = 0;
				int healthValueRiskCount = 0;
				int healthValueNoticeCount = 0;
				int healthValueMinCount = 0;
				int riskNum = 0;
				int warnNum = 0;
				int noticeNum = 0;

				for (IdxBizPvWarningRuleSet e : idxBizPvWarningRuleSets) {
					switch (e.getWarningName()) {
					case "警告":
						healthValueWarn = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueWarnCount = Integer.parseInt(e.getWarningCycle());
						break;
					case "危险":
						healthValueRisk = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueRiskCount = Integer.parseInt(e.getWarningCycle());
						break;
					case "注意":
						healthValueNotice = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueNoticeCount = Integer.parseInt(e.getWarningCycle());
						break;
					}

				}

				List<Double> healthIndex = idxBizPvHealthIndices.stream().map(PvHealthIndexDay::getHealthIndex)
						.collect(Collectors.toList());
//                Double finalHealthValueRisk = healthValueRisk;
//                long riskNum = healthIndex.subList(healthIndex.size()>healthValueRiskCount? (int) (healthIndex.size() - healthValueRiskCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueRisk).count();
//                Double finalHealthValueWarn = healthValueWarn;
//                long warnNum = healthIndex.subList(healthIndex.size()>healthValueWarnCount? (int) (healthIndex.size() - healthValueWarnCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueWarn).count();
//                Double finalHealthValueNotice = healthValueNotice;
//                long noticeNum = healthIndex.subList(healthIndex.size()>healthValueNoticeCount? (int) (healthIndex.size() - healthValueNoticeCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueNotice).count();
				Double finalHealthValueRisk = healthValueRisk;
				if (healthIndex.size() >= healthValueRiskCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueRiskCount,
							healthIndex.size());
					riskNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueRisk).count();
				}
				Double finalHealthValueWarn = healthValueWarn;
				if (healthIndex.size() >= healthValueWarnCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueWarnCount,
							healthIndex.size());
					warnNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueWarn).count();
				}
				Double finalHealthValueNotice = healthValueNotice;
				if (healthIndex.size() >= healthValueNoticeCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueNoticeCount,
							healthIndex.size());
					noticeNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueNotice).count();
				}
				String level = "";
				String content = "";
				String num = "";

				if (noticeNum == healthValueNoticeCount) {
					// redisUtils.set(gateWayId+"_"+address+"_health_notice_day","notice");
					level = "注意";
					num = "" + healthValueNotice;
					content = healthValueNoticeCount + "天";
				}
				if (warnNum == healthValueWarnCount) {
					// redisUtils.set(gateWayId+"_"+address+"_health_warn_day","warn");
					level = "警告";
					num = "" + healthValueWarn;
					content = healthValueWarnCount + "天";
				}
				if (riskNum == healthValueRiskCount) {
					// redisUtils.set(gateWayId+"_"+address+"_health_risk_day","risk");
					level = "危险";
					num = "" + healthValueRisk;
					content = healthValueRiskCount + "天";
				}
				// 库里若已存在该测点预警 不生成重复的 若新生预警等级高于历史 则生成
				LambdaQueryWrapper<PvWarningRecord> query = new LambdaQueryWrapper<>();
				query.eq(PvWarningRecord::getAnalysisPointId, idxBizPvHealthIndices.get(0).getAnalysisObjSeq());
				query.eq(PvWarningRecord::getStatus, "0");
				query.isNull(PvWarningRecord::getDisposotionDate);
				query.orderByDesc(PvWarningRecord::getTs);
				List<PvWarningRecord> idxBizPvWarningRecords = pvWaringRecordMapper.selectList(query);

				int flag = ObjectUtils.isEmpty(idxBizPvWarningRecords) || WarningNameEnum
						.getCode(level) > WarningNameEnum.getCode(idxBizPvWarningRecords.get(0).getWarningName()) ? 0
								: 1;
				Boolean timeFlag = format
						.equals(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getRecDate());
				if (!level.equals("") && flag == 0 && timeFlag) {
					IdxBizPvWarningRecord idxBizPvWarningRecord = new IdxBizPvWarningRecord();
					idxBizPvWarningRecord.setKks(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getKks());
					idxBizPvWarningRecord
							.setArae(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getArea());
					idxBizPvWarningRecord
							.setStation(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getStation());
					idxBizPvWarningRecord
							.setSubarray(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getSubarray());
					idxBizPvWarningRecord.setGatewayId(gateWayId);
					idxBizPvWarningRecord.setIndexAddress(address);
					idxBizPvWarningRecord.setEquipmentName(
							idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getEquipmentName());
					idxBizPvWarningRecord.setAnalysisPointId(
							idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getAnalysisObjSeq());
					idxBizPvWarningRecord.setDisposotionState("待确认");
					idxBizPvWarningRecord.setStatus("0");
					idxBizPvWarningRecord.setWarningName(level);
					idxBizPvWarningRecord
							.setCONTENT(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getPointName()
									+ "连续" + content + "健康指数≤" + num);
					idxBizPvWarningRecord.setRecDate(time);
					idxBizPvWarningRecord.setWarningPeriod(WarningPeriodEnum.DAY.getName());
					idxBizPvWarningRecord.setManufacturer(
							idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getManufacturer());
					idxBizPvWarningRecord
							.setPointName(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getPointName());
					idxBizPvWarningRecord.setHealthIndexSeq(
							idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getHealthIndex().toString());
					idxBizPvWarningRecord.setHealthLevel(
							idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getHealthLevel());
					idxBizPvWarningRecordList.add(idxBizPvWarningRecord);
					// idxBizPvWarningRecordMapper.insert(idxBizPvWarningRecord);

					long currentTimeMillis = System.currentTimeMillis();
					long nanoTime = System.nanoTime();
					long timestamp = currentTimeMillis * 1000000 + nanoTime % 1000000;
					PvWarningRecord pvWarningRecord = new PvWarningRecord();
					BeanUtils.copyProperties(idxBizPvWarningRecord, pvWarningRecord, "disposotionDate", "recDate",
							"CONTENT");
					pvWarningRecord.setContent(idxBizPvWarningRecord.getCONTENT());
					pvWarningRecord.setRecDate(format);
					pvWarningRecord.setTs(timestamp);
					pvWarningRecord.setHealthIndex(String.format(CommonConstans.Onedecimalplaces,
							idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getHealthIndex()));
					pvWarningRecord.setOrgCode(idxBizPvHealthIndices.get(0).getOrgCode());
					tdPvWarningRecordList.add(pvWarningRecord);
				}
			}
		}
//        idxBizPvWarningRecordService.saveBatch(idxBizPvWarningRecordList);
		if (CollUtil.isNotEmpty(tdPvWarningRecordList)) {
			log.info("==================光伏按天产生预警数据成功", JSON.toJSONString(tdPvWarningRecordList));
			// tdengine插入
			pvWaringRecordMapper.saveBatchWarningRecords(tdPvWarningRecordList);
		}

		// 触发风险模型生成预警处置模块的预警记录
		fetchDataPv(tdPvWarningRecordList, stationMap);
	}

//    @Scheduled(cron = "0 0 0 0/1 * ? ")
	public void healthWarningDayGFNew() {
		if (!openHealth) {
			return;
		}
//        Calendar calendar = Calendar.getInstance();
		Date time = new Date();
		// 三天 + 8小时
//        Date date = DateUtils.dateAddHours(time, -80);
//        calendar.set(Calendar.DAY_OF_MONTH,calendar.get(Calendar.DAY_OF_MONTH)-3);
//        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		List<String> gateWayIds = idxBizPvWarningRuleSetMapper.getGatewayIds();
		gateWayIds.forEach(gateWayId -> {
			new Thread(() -> {
				Integer maxWaringCycle = idxBizPvWarningRuleSetMapper.getMaxWaringCycleOfDayByGatewayId(gateWayId)
						+ AnalyseOffset;
				String format = DateUtil.format(time, "yyyy-MM-dd HH:mm:00");
				Date date = DateUtil.offsetHour(time, -8);
				date = DateUtil.offsetDay(date, 0 - maxWaringCycle);
				LambdaQueryWrapper<PvHealthIndexDay> wrapper = new LambdaQueryWrapper<>();
				// wrapper.ne(PvHealthIndexDay::getHealthLevel, "安全");
				wrapper.eq(PvHealthIndexDay::getAnalysisObjType, "测点");
				wrapper.eq(PvHealthIndexDay::getGatewayId, gateWayId);
				wrapper.ge(PvHealthIndexDay::getTs, date);
				Date dateMax = DateUtil.offsetHour(time, -8);
				wrapper.le(PvHealthIndexDay::getTs, dateMax);
				wrapper.orderByAsc(PvHealthIndexDay::getTs);
				List<PvHealthIndexDay> healthIndices = pvHealthIndexDayMapper.selectList(wrapper);

				if (null == healthIndices) {
					return;
				}
				List<String> collect = healthIndices.stream().map(PvHealthIndexDay::getAnalysisObjSeq)
						.collect(Collectors.toList());

				LambdaQueryWrapper<IdxBizPvWarningRuleSet> queryWrapper = new LambdaQueryWrapper<>();
				queryWrapper.eq(IdxBizPvWarningRuleSet::getAnalysisType, WarningPeriodEnum.DAY.getName());
				queryWrapper.in(IdxBizPvWarningRuleSet::getAnalysisPointId, collect);
				List<IdxBizPvWarningRuleSet> idxBizPvWarningRules = idxBizPvWarningRuleSetMapper
						.selectList(queryWrapper);
				Map<String, Map<String, List<PvHealthIndexDay>>> gateWayMaps = healthIndices.stream()
						.collect(Collectors.groupingBy(PvHealthIndexDay::getGatewayId,
								Collectors.groupingBy(PvHealthIndexDay::getIndexAddress)));
				List<IdxBizPvWarningRecord> idxBizPvWarningRecordList = new ArrayList<>();
				List<PvWarningRecord> tdPvWarningRecordList = new ArrayList<>();
				HashMap<String, StationBasic> stationMap = new HashMap<>();
//                for (String gateWayId : gateWayMaps.keySet()) {

				LambdaQueryWrapper<StationBasic> basicLambdaQueryWrapper = new LambdaQueryWrapper<>();
				basicLambdaQueryWrapper.eq(StationBasic::getFanGatewayId, gateWayId).or().eq(StationBasic::getBoosterGatewayId, gateWayId);
				basicLambdaQueryWrapper.last("limit 1");
				StationBasic stationBasic = stationBasicMapper.selectOne(basicLambdaQueryWrapper);
				stationMap.put(gateWayId, stationBasic);

				Map<String, List<PvHealthIndexDay>> healthDataMaps = gateWayMaps.get(gateWayId);
				for (String address : healthDataMaps.keySet()) {
					List<PvHealthIndexDay> idxBizPvHealthIndices = healthDataMaps.get(address);
					List<IdxBizPvWarningRuleSet> idxBizPvWarningRuleSets = idxBizPvWarningRules.stream().filter(
							t -> t.getAnalysisPointId().equals(idxBizPvHealthIndices.get(0).getAnalysisObjSeq()))
							.collect(Collectors.toList());
					if (ObjectUtils.isEmpty(idxBizPvWarningRuleSets)) {
						continue;
					}
					Double healthValueWarn = 0.0;
					Double healthValueRisk = 0.0;
					Double healthValueNotice = 0.0;

					int healthValueWarnCount = 0;
					int healthValueRiskCount = 0;
					int healthValueNoticeCount = 0;
					int healthValueMinCount = 0;
					int riskNum = 0;
					int warnNum = 0;
					int noticeNum = 0;

					for (IdxBizPvWarningRuleSet e : idxBizPvWarningRuleSets) {
						switch (e.getWarningName()) {
						case "警告":
							healthValueWarn = Double.parseDouble(e.getWarningIf().substring(2));
							healthValueWarnCount = Integer.parseInt(e.getWarningCycle());
							break;
						case "危险":
							healthValueRisk = Double.parseDouble(e.getWarningIf().substring(2));
							healthValueRiskCount = Integer.parseInt(e.getWarningCycle());
							break;
						case "注意":
							healthValueNotice = Double.parseDouble(e.getWarningIf().substring(2));
							healthValueNoticeCount = Integer.parseInt(e.getWarningCycle());
							break;
						}

					}

					List<Double> healthIndex = idxBizPvHealthIndices.stream().map(PvHealthIndexDay::getHealthIndex)
							.collect(Collectors.toList());
//                Double finalHealthValueRisk = healthValueRisk;
//                long riskNum = healthIndex.subList(healthIndex.size()>healthValueRiskCount? (int) (healthIndex.size() - healthValueRiskCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueRisk).count();
//                Double finalHealthValueWarn = healthValueWarn;
//                long warnNum = healthIndex.subList(healthIndex.size()>healthValueWarnCount? (int) (healthIndex.size() - healthValueWarnCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueWarn).count();
//                Double finalHealthValueNotice = healthValueNotice;
//                long noticeNum = healthIndex.subList(healthIndex.size()>healthValueNoticeCount? (int) (healthIndex.size() - healthValueNoticeCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueNotice).count();
					Double finalHealthValueRisk = healthValueRisk;
					if (healthIndex.size() >= healthValueRiskCount) {
						List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueRiskCount,
								healthIndex.size());
						riskNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueRisk).count();
					}
					Double finalHealthValueWarn = healthValueWarn;
					if (healthIndex.size() >= healthValueWarnCount) {
						List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueWarnCount,
								healthIndex.size());
						warnNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueWarn).count();
					}
					Double finalHealthValueNotice = healthValueNotice;
					if (healthIndex.size() >= healthValueNoticeCount) {
						List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueNoticeCount,
								healthIndex.size());
						noticeNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueNotice).count();
					}
					String level = "";
					String content = "";
					String num = "";

					if (noticeNum == healthValueNoticeCount) {
						// redisUtils.set(gateWayId+"_"+address+"_health_notice_day","notice");
						level = "注意";
						num = "" + healthValueNotice;
						content = healthValueNoticeCount + "天";
					}
					if (warnNum == healthValueWarnCount) {
						// redisUtils.set(gateWayId+"_"+address+"_health_warn_day","warn");
						level = "警告";
						num = "" + healthValueWarn;
						content = healthValueWarnCount + "天";
					}
					if (riskNum == healthValueRiskCount) {
						// redisUtils.set(gateWayId+"_"+address+"_health_risk_day","risk");
						level = "危险";
						num = "" + healthValueRisk;
						content = healthValueRiskCount + "天";
					}
					// 库里若已存在该测点预警 不生成重复的 若新生预警等级高于历史 则生成
					LambdaQueryWrapper<PvWarningRecord> query = new LambdaQueryWrapper<>();
					query.eq(PvWarningRecord::getAnalysisPointId, idxBizPvHealthIndices.get(0).getAnalysisObjSeq());
					query.eq(PvWarningRecord::getStatus, "0");
					query.isNull(PvWarningRecord::getDisposotionDate);
					query.orderByDesc(PvWarningRecord::getTs);
					List<PvWarningRecord> idxBizPvWarningRecords = pvWaringRecordMapper.selectList(query);

					int flag = ObjectUtils.isEmpty(idxBizPvWarningRecords) || WarningNameEnum
							.getCode(level) > WarningNameEnum.getCode(idxBizPvWarningRecords.get(0).getWarningName())
									? 0
									: 1;
					Boolean timeFlag = format
							.equals(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getRecDate());
					if (!level.equals("") && flag == 0 && timeFlag) {
						IdxBizPvWarningRecord idxBizPvWarningRecord = new IdxBizPvWarningRecord();
						idxBizPvWarningRecord
								.setKks(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getKks());
						idxBizPvWarningRecord
								.setArae(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getArea());
						idxBizPvWarningRecord
								.setStation(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getStation());
						idxBizPvWarningRecord
								.setSubarray(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getSubarray());
						idxBizPvWarningRecord.setGatewayId(gateWayId);
						idxBizPvWarningRecord.setIndexAddress(address);
						idxBizPvWarningRecord.setEquipmentName(
								idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getEquipmentName());
						idxBizPvWarningRecord.setAnalysisPointId(
								idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getAnalysisObjSeq());
						idxBizPvWarningRecord.setDisposotionState("待确认");
						idxBizPvWarningRecord.setStatus("0");
						idxBizPvWarningRecord.setWarningName(level);
						idxBizPvWarningRecord
								.setCONTENT(idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getPointName()
										+ "连续" + content + "健康指数≤" + num);
						idxBizPvWarningRecord.setRecDate(time);
						idxBizPvWarningRecord.setWarningPeriod(WarningPeriodEnum.DAY.getName());
						idxBizPvWarningRecord.setManufacturer(
								idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getManufacturer());
						idxBizPvWarningRecord.setPointName(
								idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getPointName());
						idxBizPvWarningRecord.setHealthIndexSeq(idxBizPvHealthIndices
								.get(idxBizPvHealthIndices.size() - 1).getHealthIndex().toString());
						idxBizPvWarningRecord.setHealthLevel(
								idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getHealthLevel());
						idxBizPvWarningRecordList.add(idxBizPvWarningRecord);
						// idxBizPvWarningRecordMapper.insert(idxBizPvWarningRecord);

						long currentTimeMillis = System.currentTimeMillis();
						long nanoTime = System.nanoTime();
						long timestamp = currentTimeMillis * 1000000 + nanoTime % 1000000;
						PvWarningRecord pvWarningRecord = new PvWarningRecord();
						BeanUtils.copyProperties(idxBizPvWarningRecord, pvWarningRecord, "disposotionDate", "recDate",
								"CONTENT");
						pvWarningRecord.setContent(idxBizPvWarningRecord.getCONTENT());
						pvWarningRecord.setRecDate(format);
						pvWarningRecord.setTs(timestamp);
						pvWarningRecord.setHealthIndex(String.format(CommonConstans.Onedecimalplaces,
								idxBizPvHealthIndices.get(idxBizPvHealthIndices.size() - 1).getHealthIndex()));
						pvWarningRecord.setOrgCode(idxBizPvHealthIndices.get(0).getOrgCode());
						tdPvWarningRecordList.add(pvWarningRecord);
					}
				}
//                }
//        idxBizPvWarningRecordService.saveBatch(idxBizPvWarningRecordList);
				if (CollUtil.isNotEmpty(tdPvWarningRecordList)) {
					log.info("==================光伏按天产生预警数据成功", JSON.toJSONString(tdPvWarningRecordList));
					// tdengine插入
					pvWaringRecordMapper.saveBatchWarningRecords(tdPvWarningRecordList);
				}

				// 触发风险模型生成预警处置模块的预警记录
				fetchDataPv(tdPvWarningRecordList, stationMap);
			}).start();
		});

	}

	// @Scheduled(cron = "0 0 */1 * * ?")
	public void healthWarningMinute(Date time) {
		if (!openHealth) {
			return;
		}
//        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        Date time=null;
//		try {
//			time = simpleDateFormat.parse("2024-06-04 17:00:00");
//		} catch (ParseException e1) {
//			e1.printStackTrace();
//		}
		// Calendar calendar = Calendar.getInstance();
		log.info("风机---------------------预警时间----" + time);
		String format = DateUtil.format(time, "yyyy-MM-dd HH:mm:00");
//        calendar.set(Calendar.HOUR_OF_DAY,calendar.get(Calendar.HOUR_OF_DAY)-1);
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		// 用ts字段查询时需要减8小时
//        Date date = DateUtils.dateAddHours(time, -8);
		Integer maxWaringCycle = idxBizFanWarningRuleSetMapper.getMaxWaringCycleOfMinutes() + AnalyseOffset;
		Date date = DateUtil.offsetHour(time, -8);
		date = DateUtil.offsetMinute(date, 0 - (maxWaringCycle * 10));
		LambdaQueryWrapper<FanHealthIndexMoment> wrapper = new LambdaQueryWrapper<>();
		// wrapper.ne(FanHealthIndexMoment::getHealthLevel,"安全");
		wrapper.eq(FanHealthIndexMoment::getAnalysisObjType, "测点");
		wrapper.ge(FanHealthIndexMoment::getTs, date);
		Date dateMax = DateUtil.offsetHour(time, -8);
		wrapper.le(FanHealthIndexMoment::getTs, dateMax);
//        wrapper.eq(FanHealthIndexMoment::getIndexAddress, "18547");
		wrapper.orderByAsc(FanHealthIndexMoment::getTs);
		// 查询最大连续时间规则的测点对象
		List<FanHealthIndexMoment> healthIndices = fanHealthIndexMomentMapper.selectList(wrapper);

		if (ObjectUtils.isEmpty(healthIndices)) {
			return;
		}
		List<String> collect = healthIndices.stream().map(FanHealthIndexMoment::getAnalysisObjSeq)
				.collect(Collectors.toList());

		LambdaQueryWrapper<IdxBizFanWarningRuleSet> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(IdxBizFanWarningRuleSet::getAnalysisType, WarningPeriodEnum.MINUTES.getName());
		queryWrapper.in(IdxBizFanWarningRuleSet::getAnalysisPointId, collect);
		List<IdxBizFanWarningRuleSet> idxBizPvWarningRules = idxBizFanWarningRuleSetMapper.selectList(queryWrapper);

		Map<String, Map<String, List<FanHealthIndexMoment>>> gateWayMaps = healthIndices.stream()
				.collect(Collectors.groupingBy(FanHealthIndexMoment::getGatewayId,
						Collectors.groupingBy(FanHealthIndexMoment::getIndexAddress)));
		List<IdxBizFanWarningRecord> idxBizFanWarningRecordList = new ArrayList<>();
		List<FanWarningRecord> tdFanWarningRecordList = new ArrayList<>();

		HashMap<String, StationBasic> stationMap = new HashMap<>();
		for (String gateWayId : gateWayMaps.keySet()) {

			LambdaQueryWrapper<StationBasic> basicLambdaQueryWrapper = new LambdaQueryWrapper<>();
			basicLambdaQueryWrapper.eq(StationBasic::getFanGatewayId, gateWayId).or().eq(StationBasic::getBoosterGatewayId, gateWayId);
			basicLambdaQueryWrapper.last("limit 1");
			StationBasic stationBasic = stationBasicMapper.selectOne(basicLambdaQueryWrapper);
			stationMap.put(gateWayId, stationBasic);
			Map<String, List<FanHealthIndexMoment>> healthDataMaps = gateWayMaps.get(gateWayId);
			for (String address : healthDataMaps.keySet()) {
				// 获取指定测点的健康指数列表
				List<FanHealthIndexMoment> idxBizFanHealthIndices = healthDataMaps.get(address);

				List<IdxBizFanWarningRuleSet> idxBizPvWarningRuleSets = idxBizPvWarningRules.stream()
						.filter(t -> t.getAnalysisPointId().equals(idxBizFanHealthIndices.get(0).getAnalysisObjSeq()))
						.collect(Collectors.toList());

				if (ObjectUtils.isEmpty(idxBizPvWarningRuleSets)) {
					continue;
				}

				Double healthValueWarn = 0.0;
				Double healthValueRisk = 0.0;
				Double healthValueNotice = 0.0;

				int healthValueWarnCount = 0;
				int healthValueRiskCount = 0;
				int healthValueNoticeCount = 0;
				int healthValueMinCount = 0;
				int riskNum = 0;
				int warnNum = 0;
				int noticeNum = 0;

				for (IdxBizFanWarningRuleSet e : idxBizPvWarningRuleSets) {
					switch (e.getWarningName()) {
					case "警告":
						healthValueWarn = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueWarnCount = Integer.parseInt(e.getWarningCycle());
						break;
					case "危险":
						healthValueRisk = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueRiskCount = Integer.parseInt(e.getWarningCycle());
						break;
					case "注意":
						healthValueNotice = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueNoticeCount = Integer.parseInt(e.getWarningCycle());
						break;
					}

				}

				// 获取指定测点的健康指数列表
				List<Double> healthIndex = idxBizFanHealthIndices.stream().map(FanHealthIndexMoment::getHealthIndex)
						.collect(Collectors.toList());
//                Double finalHealthValueRisk = healthValueRisk;
//                long riskNum = healthIndex.subList(healthIndex.size()>healthValueRiskCount? (int) (healthIndex.size() - healthValueRiskCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueRisk).count();
//                Double finalHealthValueWarn = healthValueWarn;
//                long warnNum = healthIndex.subList(healthIndex.size()>healthValueWarnCount? (int) (healthIndex.size() - healthValueWarnCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueWarn).count();
//                Double finalHealthValueNotice = healthValueNotice;
//                long noticeNum = healthIndex.subList(healthIndex.size()>healthValueNoticeCount? (int) (healthIndex.size() - healthValueNoticeCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueNotice).count();
				Double finalHealthValueRisk = healthValueRisk;
				if (healthIndex.size() >= healthValueRiskCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueRiskCount,
							healthIndex.size());
					riskNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueRisk).count();
				}
				Double finalHealthValueWarn = healthValueWarn;
				if (healthIndex.size() >= healthValueWarnCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueWarnCount,
							healthIndex.size());
					warnNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueWarn).count();
				}
				Double finalHealthValueNotice = healthValueNotice;
				if (healthIndex.size() >= healthValueNoticeCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueNoticeCount,
							healthIndex.size());
					noticeNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueNotice).count();
				}
				String level = "";
				String content = "";
				String num = "";
				if (noticeNum == healthValueNoticeCount) {
					// redisUtils.set(gateWayId+"_"+address+"_health_notice_day","notice");
					level = "注意";
					num = "" + healthValueNotice;
					content = healthValueNoticeCount * 10 + "分钟";
				}
				if (warnNum == healthValueWarnCount) {
					// redisUtils.set(gateWayId+"_"+address+"_health_warn_day","warn");
					level = "警告";
					num = "" + healthValueWarn;
					content = healthValueWarnCount * 10 + "分钟";
				}
				if (riskNum == healthValueRiskCount) {
					// redisUtils.set(gateWayId+"_"+address+"_health_risk_day","risk");
					level = "危险";
					num = "" + healthValueRisk;
					content = healthValueRiskCount * 10 + "分钟";
				}
				// 库里若已存在该测点预警 不生成重复的 若新生预警等级高于历史 则生成
				LambdaQueryWrapper<FanWarningRecord> query = new LambdaQueryWrapper<>();
				query.eq(FanWarningRecord::getAnalysisPointId, idxBizFanHealthIndices.get(0).getAnalysisObjSeq());
				query.eq(FanWarningRecord::getStatus, "0");
				query.isNull(FanWarningRecord::getDisposotionDate);
				query.orderByDesc(FanWarningRecord::getTs);
				List<FanWarningRecord> idxBizFanWarningRecords = fanWaringRecordMapper.selectList(query);

				int flag = ObjectUtils.isEmpty(idxBizFanWarningRecords) || WarningNameEnum
						.getCode(level) > WarningNameEnum.getCode(idxBizFanWarningRecords.get(0).getWarningName()) ? 0
								: 1;
				Boolean timeFlag = format
						.equals(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getRecDate());
				if (!level.equals("") && flag == 0 && timeFlag) {
					IdxBizFanWarningRecord idxBizFanWarningRecord = new IdxBizFanWarningRecord();
					idxBizFanWarningRecord
							.setKks(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getKks());
					idxBizFanWarningRecord
							.setArae(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getArea());
					idxBizFanWarningRecord
							.setStation(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getStation());
					idxBizFanWarningRecord
							.setSubSystem(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getSubSystem());
					idxBizFanWarningRecord.setGatewayId(gateWayId);
					idxBizFanWarningRecord.setIndexAddress(address);
					idxBizFanWarningRecord.setEquipmentName(
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getEquipmentName());
					idxBizFanWarningRecord.setAnalysisPointId(
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getAnalysisObjSeq());
					idxBizFanWarningRecord.setDisposotionState("待确认");
					idxBizFanWarningRecord.setStatus("0");
					idxBizFanWarningRecord.setWarningName(level);
					idxBizFanWarningRecord
							.setCONTENT(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getPointName()
									+ "连续" + content + "健康指数≤" + num);
					idxBizFanWarningRecord.setRecDate(time);
					idxBizFanWarningRecord.setWarningPeriod(WarningPeriodEnum.MINUTES.getName());
					idxBizFanWarningRecord
							.setNumber(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getNumber());
					idxBizFanWarningRecord
							.setPointName(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getPointName());
					idxBizFanWarningRecord.setHealthIndexSeq(
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getHealthIndex().toString());
					idxBizFanWarningRecord.setHealthLevel(
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getHealthLevel());
					idxBizFanWarningRecordList.add(idxBizFanWarningRecord);
					// idxBizFanWarningRecordMapper.insert(idxBizFanWarningRecord);
					long currentTimeMillis = System.currentTimeMillis();
					long nanoTime = System.nanoTime();
					long timestamp = currentTimeMillis * 1000000 + nanoTime % 1000000;

					FanWarningRecord fanWarningRecord = new FanWarningRecord();
					BeanUtils.copyProperties(idxBizFanWarningRecord, fanWarningRecord, "disposotionDate", "recDate",
							"CONTENT");
					fanWarningRecord.setContent(idxBizFanWarningRecord.getCONTENT());
					fanWarningRecord.setRecDate(format);
					fanWarningRecord.setTs(timestamp);
					fanWarningRecord.setHealthIndex(String.format(CommonConstans.Onedecimalplaces,
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getHealthIndex()));
					fanWarningRecord.setOrgCode(idxBizFanHealthIndices.get(0).getOrgCode());
					tdFanWarningRecordList.add(fanWarningRecord);

				}
			}
		}
//        idxBizFanWarningRecordService.saveBatch(idxBizFanWarningRecordList);

		// tdengine插入
//        fanWarningRecordService.saveBatch(tdFanWarningRecordList);
		if (CollUtil.isNotEmpty(tdFanWarningRecordList)) {
			fanWaringRecordMapper.saveBatchWarningRecords(tdFanWarningRecordList);
		}
		// 触发风险模型生成预警处置模块的预警记录
		fetchDataFan(tdFanWarningRecordList, stationMap);
	}

	// @PostConstruct
	public void healthWarningMinute(Date time, String gatewayId) {
		if (!openHealth) {
			return;
		}
//        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        Date time=null;
//		try {
//			time = simpleDateFormat.parse("2024-03-14 13:50:00");
//		} catch (ParseException e1) {
//			// TODO Auto-generated catch block
//			e1.printStackTrace();
//		}
		// Calendar calendar = Calendar.getInstance();
		log.info("风机---------------------预警时间----" + time);
		String format = DateUtil.format(time, "yyyy-MM-dd HH:mm:00");
//        calendar.set(Calendar.HOUR_OF_DAY,calendar.get(Calendar.HOUR_OF_DAY)-1);
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		// 用ts字段查询时需要减8小时
//        Date date = DateUtils.dateAddHours(time, -8);
		Integer maxWaringCycle = idxBizFanWarningRuleSetMapper.getMaxWaringCycleOfMinutesByGatewayId(gatewayId)
				+ AnalyseOffset;
		Date date = DateUtil.offsetHour(time, -8);
		date = DateUtil.offsetMinute(date, 0 - (maxWaringCycle * 10));
		LambdaQueryWrapper<FanHealthIndexMoment> wrapper = new LambdaQueryWrapper<>();
		// wrapper.ne(FanHealthIndexMoment::getHealthLevel,"安全");
		wrapper.eq(FanHealthIndexMoment::getAnalysisObjType, "测点");
		wrapper.ge(FanHealthIndexMoment::getTs, date);
		wrapper.eq(FanHealthIndexMoment::getGatewayId, gatewayId);
		Date dateMax = DateUtil.offsetHour(time, -8);
		wrapper.le(FanHealthIndexMoment::getTs, dateMax);
//        wrapper.eq(FanHealthIndexMoment::getIndexAddress, "18547");
		wrapper.orderByAsc(FanHealthIndexMoment::getTs);
		// 查询最大连续时间规则的测点对象
		List<FanHealthIndexMoment> healthIndices = fanHealthIndexMomentMapper.selectList(wrapper);

		if (ObjectUtils.isEmpty(healthIndices)) {
			return;
		}
		List<String> collect = healthIndices.stream().map(FanHealthIndexMoment::getAnalysisObjSeq)
				.collect(Collectors.toList());

		LambdaQueryWrapper<IdxBizFanWarningRuleSet> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(IdxBizFanWarningRuleSet::getAnalysisType, WarningPeriodEnum.MINUTES.getName());
		queryWrapper.eq(IdxBizFanWarningRuleSet::getGatewayId, gatewayId);
		queryWrapper.in(IdxBizFanWarningRuleSet::getAnalysisPointId, collect);
		List<IdxBizFanWarningRuleSet> idxBizPvWarningRules = idxBizFanWarningRuleSetMapper.selectList(queryWrapper);

		Map<String, Map<String, List<FanHealthIndexMoment>>> gateWayMaps = healthIndices.stream()
				.collect(Collectors.groupingBy(FanHealthIndexMoment::getGatewayId,
						Collectors.groupingBy(FanHealthIndexMoment::getIndexAddress)));
		List<IdxBizFanWarningRecord> idxBizFanWarningRecordList = new ArrayList<>();
		List<FanWarningRecord> tdFanWarningRecordList = new ArrayList<>();

		HashMap<String, StationBasic> stationMap = new HashMap<>();
//        for (String gateWayId : gateWayMaps.keySet()) {

		LambdaQueryWrapper<StationBasic> basicLambdaQueryWrapper = new LambdaQueryWrapper<>();
		basicLambdaQueryWrapper.eq(StationBasic::getFanGatewayId, gatewayId).or().eq(StationBasic::getBoosterGatewayId, gatewayId);
		basicLambdaQueryWrapper.last("limit 1");
		StationBasic stationBasic = stationBasicMapper.selectOne(basicLambdaQueryWrapper);
		stationMap.put(gatewayId, stationBasic);
		Map<String, List<FanHealthIndexMoment>> healthDataMaps = gateWayMaps.get(gatewayId);
		for (String address : healthDataMaps.keySet()) {
			// 获取指定测点的健康指数列表
			List<FanHealthIndexMoment> idxBizFanHealthIndices = healthDataMaps.get(address);

			List<IdxBizFanWarningRuleSet> idxBizPvWarningRuleSets = idxBizPvWarningRules.stream()
					.filter(t -> t.getAnalysisPointId().equals(idxBizFanHealthIndices.get(0).getAnalysisObjSeq()))
					.collect(Collectors.toList());

			if (ObjectUtils.isEmpty(idxBizPvWarningRuleSets)) {
				continue;
			}

			Double healthValueWarn = 0.0;
			Double healthValueRisk = 0.0;
			Double healthValueNotice = 0.0;

			int healthValueWarnCount = 0;
			int healthValueRiskCount = 0;
			int healthValueNoticeCount = 0;
			int healthValueMinCount = 0;
			int riskNum = 0;
			int warnNum = 0;
			int noticeNum = 0;

			for (IdxBizFanWarningRuleSet e : idxBizPvWarningRuleSets) {
				switch (e.getWarningName()) {
				case "警告":
					healthValueWarn = Double.parseDouble(e.getWarningIf().substring(2));
					healthValueWarnCount = Integer.parseInt(e.getWarningCycle());
					break;
				case "危险":
					healthValueRisk = Double.parseDouble(e.getWarningIf().substring(2));
					healthValueRiskCount = Integer.parseInt(e.getWarningCycle());
					break;
				case "注意":
					healthValueNotice = Double.parseDouble(e.getWarningIf().substring(2));
					healthValueNoticeCount = Integer.parseInt(e.getWarningCycle());
					break;
				}

			}

			// 获取指定测点的健康指数列表
			List<Double> healthIndex = idxBizFanHealthIndices.stream().map(FanHealthIndexMoment::getHealthIndex)
					.collect(Collectors.toList());
//                Double finalHealthValueRisk = healthValueRisk;
//                long riskNum = healthIndex.subList(healthIndex.size()>healthValueRiskCount? (int) (healthIndex.size() - healthValueRiskCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueRisk).count();
//                Double finalHealthValueWarn = healthValueWarn;
//                long warnNum = healthIndex.subList(healthIndex.size()>healthValueWarnCount? (int) (healthIndex.size() - healthValueWarnCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueWarn).count();
//                Double finalHealthValueNotice = healthValueNotice;
//                long noticeNum = healthIndex.subList(healthIndex.size()>healthValueNoticeCount? (int) (healthIndex.size() - healthValueNoticeCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueNotice).count();
			Double finalHealthValueRisk = healthValueRisk;
			if (healthIndex.size() >= healthValueRiskCount) {
				List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueRiskCount,
						healthIndex.size());
				riskNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueRisk).count();
			}
			Double finalHealthValueWarn = healthValueWarn;
			if (healthIndex.size() >= healthValueWarnCount) {
				List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueWarnCount,
						healthIndex.size());
				warnNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueWarn).count();
			}
			Double finalHealthValueNotice = healthValueNotice;
			if (healthIndex.size() >= healthValueNoticeCount) {
				List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueNoticeCount,
						healthIndex.size());
				noticeNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueNotice).count();
			}
			String level = "";
			String content = "";
			String num = "";
			if (noticeNum == healthValueNoticeCount) {
				// redisUtils.set(gateWayId+"_"+address+"_health_notice_day","notice");
				level = "注意";
				num = "" + healthValueNotice;
				content = healthValueNoticeCount * 10 + "分钟";
			}
			if (warnNum == healthValueWarnCount) {
				// redisUtils.set(gateWayId+"_"+address+"_health_warn_day","warn");
				level = "警告";
				num = "" + healthValueWarn;
				content = healthValueWarnCount * 10 + "分钟";
			}
			if (riskNum == healthValueRiskCount) {
				// redisUtils.set(gateWayId+"_"+address+"_health_risk_day","risk");
				level = "危险";
				num = "" + healthValueRisk;
				content = healthValueRiskCount * 10 + "分钟";
			}
			// 库里若已存在该测点预警 不生成重复的 若新生预警等级高于历史 则生成
			LambdaQueryWrapper<FanWarningRecord> query = new LambdaQueryWrapper<>();
			query.eq(FanWarningRecord::getAnalysisPointId, idxBizFanHealthIndices.get(0).getAnalysisObjSeq());
			query.eq(FanWarningRecord::getStatus, "0");
			query.isNull(FanWarningRecord::getDisposotionDate);
			query.orderByDesc(FanWarningRecord::getTs);
			List<FanWarningRecord> idxBizFanWarningRecords = fanWaringRecordMapper.selectList(query);

			int flag = ObjectUtils.isEmpty(idxBizFanWarningRecords) || WarningNameEnum.getCode(level) > WarningNameEnum
					.getCode(idxBizFanWarningRecords.get(0).getWarningName()) ? 0 : 1;
			Boolean timeFlag = format
					.equals(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getRecDate());
			if (!level.equals("") && flag == 0 && timeFlag) {
				IdxBizFanWarningRecord idxBizFanWarningRecord = new IdxBizFanWarningRecord();
				idxBizFanWarningRecord.setKks(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getKks());
				idxBizFanWarningRecord.setArae(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getArea());
				idxBizFanWarningRecord
						.setStation(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getStation());
				idxBizFanWarningRecord
						.setSubSystem(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getSubSystem());
				idxBizFanWarningRecord.setGatewayId(gatewayId);
				idxBizFanWarningRecord.setIndexAddress(address);
				idxBizFanWarningRecord.setEquipmentName(
						idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getEquipmentName());
				idxBizFanWarningRecord.setAnalysisPointId(
						idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getAnalysisObjSeq());
				idxBizFanWarningRecord.setDisposotionState("待确认");
				idxBizFanWarningRecord.setStatus("0");
				idxBizFanWarningRecord.setWarningName(level);
				idxBizFanWarningRecord
						.setCONTENT(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getPointName() + "连续"
								+ content + "健康指数≤" + num);
				idxBizFanWarningRecord.setRecDate(time);
				idxBizFanWarningRecord.setWarningPeriod(WarningPeriodEnum.MINUTES.getName());
				idxBizFanWarningRecord
						.setNumber(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getNumber());
				idxBizFanWarningRecord
						.setPointName(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getPointName());
				idxBizFanWarningRecord.setHealthIndexSeq(
						idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getHealthIndex().toString());
				idxBizFanWarningRecord
						.setHealthLevel(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getHealthLevel());
				idxBizFanWarningRecordList.add(idxBizFanWarningRecord);
				// idxBizFanWarningRecordMapper.insert(idxBizFanWarningRecord);
				long currentTimeMillis = System.currentTimeMillis();
				long nanoTime = System.nanoTime();
				long timestamp = currentTimeMillis * 1000000 + nanoTime % 1000000;

				FanWarningRecord fanWarningRecord = new FanWarningRecord();
				BeanUtils.copyProperties(idxBizFanWarningRecord, fanWarningRecord, "disposotionDate", "recDate",
						"CONTENT");
				fanWarningRecord.setContent(idxBizFanWarningRecord.getCONTENT());
				fanWarningRecord.setRecDate(format);
				fanWarningRecord.setTs(timestamp);
				fanWarningRecord.setHealthIndex(String.format(CommonConstans.Onedecimalplaces,
						idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getHealthIndex()));
				fanWarningRecord.setOrgCode(idxBizFanHealthIndices.get(0).getOrgCode());
				tdFanWarningRecordList.add(fanWarningRecord);

			}
		}
//        }
//        idxBizFanWarningRecordService.saveBatch(idxBizFanWarningRecordList);

		// tdengine插入
//        fanWarningRecordService.saveBatch(tdFanWarningRecordList);
		if (CollUtil.isNotEmpty(tdFanWarningRecordList)) {
			fanWaringRecordMapper.saveBatchWarningRecords(tdFanWarningRecordList);
		}
		// 触发风险模型生成预警处置模块的预警记录
		fetchDataFan(tdFanWarningRecordList, stationMap);
	}

	/***
	 * 每五小时获取一次最大粒度内的指数异常数据 判断五小时内数据是否符合预警规则 符合则报警并在redis中缓存 同一级别的预警记录下次不生成
	 * TdengineTimeServiceImpl计算完调用
	 */

	// @Scheduled(cron = "0 0 0/1 * * ?")
	// @PostConstruct
	public void healthWarningHour() {
//        if (!openHealth) {
//            return;
//        }
		Date time = new Date();
//        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        Date time=null;
//		try {
//			time = simpleDateFormat.parse("2024-06-04 17:00:00");
//		} catch (ParseException e1) {
//			e1.printStackTrace();
//		}

		String format = DateUtil.format(time, "yyyy-MM-dd HH:00:00");
//        Date date = DateUtils.dateAddHours(time, -13);
//        Calendar calendar = Calendar.getInstance();
//        calendar.set(Calendar.HOUR_OF_DAY,calendar.get(Calendar.HOUR_OF_DAY)-5);
//        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		Integer maxWaringCycle = idxBizFanWarningRuleSetMapper.getMaxWaringCycleOfHour();
		Date date = DateUtil.offsetHour(time, -8);
		date = DateUtil.offsetHour(date, 0 - (maxWaringCycle));
		LambdaQueryWrapper<FanHealthIndexHour> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(FanHealthIndexHour::getAnalysisObjType, "测点");
		// wrapper.ne(FanHealthIndexHour::getHealthLevel, "安全");
		wrapper.ge(FanHealthIndexHour::getTs, date);
		Date dateMax = DateUtil.offsetHour(time, -8);
		wrapper.le(FanHealthIndexHour::getTs, dateMax);
		wrapper.orderByAsc(FanHealthIndexHour::getTs);
		List<FanHealthIndexHour> healthIndices = fanHealthIndexHourMapper.selectList(wrapper);
		if (ObjectUtils.isEmpty(healthIndices)) {
			return;
		}
		List<String> collect = healthIndices.stream().map(FanHealthIndexHour::getAnalysisObjSeq)
				.collect(Collectors.toList());

		LambdaQueryWrapper<IdxBizFanWarningRuleSet> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(IdxBizFanWarningRuleSet::getAnalysisType, WarningPeriodEnum.HOUR.getName());
		queryWrapper.in(IdxBizFanWarningRuleSet::getAnalysisPointId, collect);
		List<IdxBizFanWarningRuleSet> idxBizPvWarningRules = idxBizFanWarningRuleSetMapper.selectList(queryWrapper);

		Map<String, Map<String, List<FanHealthIndexHour>>> gateWayMaps = healthIndices.stream()
				.collect(Collectors.groupingBy(FanHealthIndexHour::getGatewayId,
						Collectors.groupingBy(FanHealthIndexHour::getIndexAddress)));
		List<IdxBizFanWarningRecord> idxBizFanWarningRecordList = new ArrayList<>();
		List<FanWarningRecord> tdFanWarningRecordList = new ArrayList<>();
		HashMap<String, StationBasic> stationMap = new HashMap<>();
		for (String gateWayId : gateWayMaps.keySet()) {

			LambdaQueryWrapper<StationBasic> basicLambdaQueryWrapper = new LambdaQueryWrapper<>();
			basicLambdaQueryWrapper.eq(StationBasic::getFanGatewayId, gateWayId).or().eq(StationBasic::getBoosterGatewayId, gateWayId);
			basicLambdaQueryWrapper.last("limit 1");
			StationBasic stationBasic = stationBasicMapper.selectOne(basicLambdaQueryWrapper);
			stationMap.put(gateWayId, stationBasic);

			Map<String, List<FanHealthIndexHour>> healthDataMaps = gateWayMaps.get(gateWayId);
			for (String address : healthDataMaps.keySet()) {
				// 桨叶目标位置B
//            	if(!"22046".equals(address)) 
//            	{
//            		continue;
//            	}

				List<FanHealthIndexHour> idxBizFanHealthIndices = healthDataMaps.get(address);

				List<IdxBizFanWarningRuleSet> idxBizPvWarningRuleSets = idxBizPvWarningRules.stream()
						.filter(t -> t.getAnalysisPointId().equals(idxBizFanHealthIndices.get(0).getAnalysisObjSeq()))
						.collect(Collectors.toList());

				if (ObjectUtils.isEmpty(idxBizPvWarningRuleSets)) {
					continue;
				}
				Double healthValueWarn = 0.0;
				Double healthValueRisk = 0.0;
				Double healthValueNotice = 0.0;

//                long healthValueNoticeCount = 0;
//                long healthValueRiskCount = 0;
//                long healthValueWarnCount = 0;
				int healthValueWarnCount = 0;
				int healthValueRiskCount = 0;
				int healthValueNoticeCount = 0;
				int healthValueMinCount = 0;
				int riskNum = 0;
				int warnNum = 0;
				int noticeNum = 0;

				for (IdxBizFanWarningRuleSet e : idxBizPvWarningRuleSets) {
					switch (e.getWarningName()) {
					case "警告":
						healthValueWarn = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueWarnCount = Integer.parseInt(e.getWarningCycle());
						break;
					case "危险":
						healthValueRisk = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueRiskCount = Integer.parseInt(e.getWarningCycle());
						break;
					case "注意":
						healthValueNotice = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueNoticeCount = Integer.parseInt(e.getWarningCycle());
						break;
					}

				}

				List<Double> healthIndex = idxBizFanHealthIndices.stream().map(FanHealthIndexHour::getHealthIndex)
						.collect(Collectors.toList());
//                Double finalHealthValueRisk = healthValueRisk;
//                long riskNum = healthIndex.subList(healthIndex.size()>healthValueRiskCount? (int) (healthIndex.size() - healthValueRiskCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueRisk).count();
//                Double finalHealthValueWarn = healthValueWarn;
//                long warnNum = healthIndex.subList(healthIndex.size()>healthValueWarnCount? (int) (healthIndex.size() - healthValueWarnCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueWarn).count();
//                Double finalHealthValueNotice = healthValueNotice;
//                long noticeNum = healthIndex.subList(healthIndex.size()>healthValueNoticeCount? (int) (healthIndex.size() - healthValueNoticeCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueNotice).count();
				Double finalHealthValueRisk = healthValueRisk;
				if (healthIndex.size() >= healthValueRiskCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueRiskCount,
							healthIndex.size());
					riskNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueRisk).count();
				}
				Double finalHealthValueWarn = healthValueWarn;
				if (healthIndex.size() >= healthValueWarnCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueWarnCount,
							healthIndex.size());
					warnNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueWarn).count();
				}
				Double finalHealthValueNotice = healthValueNotice;
				if (healthIndex.size() >= healthValueNoticeCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueNoticeCount,
							healthIndex.size());
					noticeNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueNotice).count();
				}
				String level = "";
				String content = "";
				String num = "";
				if (noticeNum == healthValueNoticeCount) {
					level = "注意";
					num = "" + healthValueNotice;
					content = healthValueNoticeCount + "小时";
				}
				if (warnNum == healthValueWarnCount) {

					level = "警告";
					num = "" + healthValueWarn;
					content = healthValueWarnCount + "小时";
				}
				if (riskNum == healthValueRiskCount) {
					level = "危险";
					num = "" + healthValueRisk;
					content = healthValueRiskCount + "小时";
				}
				LambdaQueryWrapper<FanWarningRecord> query = new LambdaQueryWrapper<>();
				query.eq(FanWarningRecord::getAnalysisPointId, idxBizFanHealthIndices.get(0).getAnalysisObjSeq());
				query.eq(FanWarningRecord::getStatus, "0");
				query.isNull(FanWarningRecord::getDisposotionDate);
				query.orderByDesc(FanWarningRecord::getTs);
				List<FanWarningRecord> idxBizFanWarningRecords = fanWaringRecordMapper.selectList(query);

				int flag = ObjectUtils.isEmpty(idxBizFanWarningRecords) || WarningNameEnum
						.getCode(level) > WarningNameEnum.getCode(idxBizFanWarningRecords.get(0).getWarningName()) ? 0
								: 1;
				Boolean timeFlag = format
						.equals(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getRecDate());
				if (!level.equals("") && flag == 0 && timeFlag) {
					IdxBizFanWarningRecord idxBizFanWarningRecord = new IdxBizFanWarningRecord();
					idxBizFanWarningRecord
							.setKks(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getKks());
					idxBizFanWarningRecord
							.setArae(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getArea());
					idxBizFanWarningRecord
							.setStation(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getStation());
					idxBizFanWarningRecord
							.setSubSystem(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getSubSystem());
					idxBizFanWarningRecord.setGatewayId(gateWayId);
					idxBizFanWarningRecord.setIndexAddress(address);
					idxBizFanWarningRecord.setEquipmentName(
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getEquipmentName());
					idxBizFanWarningRecord.setAnalysisPointId(
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getAnalysisObjSeq());
					idxBizFanWarningRecord.setDisposotionState("待确认");
					idxBizFanWarningRecord.setStatus("0");
					idxBizFanWarningRecord.setWarningName(level);
					idxBizFanWarningRecord
							.setCONTENT(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getPointName()
									+ "连续" + content + "健康指数≤" + num);
					idxBizFanWarningRecord.setRecDate(time);
					idxBizFanWarningRecord.setWarningPeriod(WarningPeriodEnum.HOUR.getName());
					idxBizFanWarningRecord
							.setNumber(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getNumber());
					idxBizFanWarningRecord.setHealthIndexSeq(
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getHealthIndex().toString());
					idxBizFanWarningRecord.setHealthLevel(
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getHealthLevel());
					idxBizFanWarningRecord
							.setPointName(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getPointName());
					idxBizFanWarningRecordList.add(idxBizFanWarningRecord);
					long currentTimeMillis = System.currentTimeMillis();
					long nanoTime = System.nanoTime();
					long timestamp = currentTimeMillis * 1000000 + nanoTime % 1000000;

					FanWarningRecord fanWarningRecord = new FanWarningRecord();
					BeanUtils.copyProperties(idxBizFanWarningRecord, fanWarningRecord, "disposotionDate", "recDate",
							"CONTENT");
					fanWarningRecord.setContent(idxBizFanWarningRecord.getCONTENT());
					fanWarningRecord.setRecDate(format);
					fanWarningRecord.setTs(timestamp);
					fanWarningRecord.setHealthIndex(String.format(CommonConstans.Onedecimalplaces,
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getHealthIndex()));
					fanWarningRecord.setOrgCode(idxBizFanHealthIndices.get(0).getOrgCode());
					tdFanWarningRecordList.add(fanWarningRecord);
				}
			}
		}
//        idxBizFanWarningRecordService.saveBatch(idxBizFanWarningRecordList);
		if (CollUtil.isNotEmpty(tdFanWarningRecordList)) {

			// tdengine插入
			fanWaringRecordMapper.saveBatchWarningRecords(tdFanWarningRecordList);
			// 触发风险模型生成预警处置模块的预警记录
			fetchDataFan(tdFanWarningRecordList, stationMap);
		}

	}

//    @Scheduled(cron = "0 0 0/1 * * ?")
	public void healthWarningHourNew() {
		if (!openHealth) {
			return;
		}
		Date time = new Date();
		String format = DateUtil.format(time, "yyyy-MM-dd HH:00:00");
//        Date date = DateUtils.dateAddHours(time, -13);
//        Calendar calendar = Calendar.getInstance();
//        calendar.set(Calendar.HOUR_OF_DAY,calendar.get(Calendar.HOUR_OF_DAY)-5);
//        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		List<String> gateWayIds = idxBizFanWarningRuleSetMapper.getGatewayIds();
		gateWayIds.forEach(gateWayId -> {
			new Thread(() -> {
				Integer maxWaringCycle = idxBizFanWarningRuleSetMapper.getMaxWaringCycleOfHourByGatewayId(gateWayId);
				Date date = DateUtil.offsetHour(time, -8);
				date = DateUtil.offsetHour(date, 0 - (maxWaringCycle));
				LambdaQueryWrapper<FanHealthIndexHour> wrapper = new LambdaQueryWrapper<>();
				wrapper.eq(FanHealthIndexHour::getAnalysisObjType, "测点");
				wrapper.eq(FanHealthIndexHour::getGatewayId, gateWayId);
				// wrapper.ne(FanHealthIndexHour::getHealthLevel, "安全");
				wrapper.ge(FanHealthIndexHour::getTs, date);
				Date dateMax = DateUtil.offsetHour(time, -8);
				wrapper.le(FanHealthIndexHour::getTs, dateMax);
				wrapper.orderByAsc(FanHealthIndexHour::getTs);
				List<FanHealthIndexHour> healthIndices = fanHealthIndexHourMapper.selectList(wrapper);
				if (ObjectUtils.isEmpty(healthIndices)) {
					return;
				}
				List<String> collect = healthIndices.stream().map(FanHealthIndexHour::getAnalysisObjSeq)
						.collect(Collectors.toList());

				LambdaQueryWrapper<IdxBizFanWarningRuleSet> queryWrapper = new LambdaQueryWrapper<>();
				queryWrapper.eq(IdxBizFanWarningRuleSet::getAnalysisType, WarningPeriodEnum.HOUR.getName());
				queryWrapper.in(IdxBizFanWarningRuleSet::getAnalysisPointId, collect);
				List<IdxBizFanWarningRuleSet> idxBizPvWarningRules = idxBizFanWarningRuleSetMapper
						.selectList(queryWrapper);

				Map<String, Map<String, List<FanHealthIndexHour>>> gateWayMaps = healthIndices.stream()
						.collect(Collectors.groupingBy(FanHealthIndexHour::getGatewayId,
								Collectors.groupingBy(FanHealthIndexHour::getIndexAddress)));
				List<IdxBizFanWarningRecord> idxBizFanWarningRecordList = new ArrayList<>();
				List<FanWarningRecord> tdFanWarningRecordList = new ArrayList<>();
				HashMap<String, StationBasic> stationMap = new HashMap<>();
//                for (String gateWayId : gateWayMaps.keySet()) {

				LambdaQueryWrapper<StationBasic> basicLambdaQueryWrapper = new LambdaQueryWrapper<>();
				basicLambdaQueryWrapper.eq(StationBasic::getFanGatewayId, gateWayId).or().eq(StationBasic::getBoosterGatewayId, gateWayId);
				basicLambdaQueryWrapper.last("limit 1");
				StationBasic stationBasic = stationBasicMapper.selectOne(basicLambdaQueryWrapper);
				stationMap.put(gateWayId, stationBasic);

				Map<String, List<FanHealthIndexHour>> healthDataMaps = gateWayMaps.get(gateWayId);
				for (String address : healthDataMaps.keySet()) {
					List<FanHealthIndexHour> idxBizFanHealthIndices = healthDataMaps.get(address);

					List<IdxBizFanWarningRuleSet> idxBizPvWarningRuleSets = idxBizPvWarningRules.stream().filter(
							t -> t.getAnalysisPointId().equals(idxBizFanHealthIndices.get(0).getAnalysisObjSeq()))
							.collect(Collectors.toList());

					if (ObjectUtils.isEmpty(idxBizPvWarningRuleSets)) {
						continue;
					}
					Double healthValueWarn = 0.0;
					Double healthValueRisk = 0.0;
					Double healthValueNotice = 0.0;

//                long healthValueNoticeCount = 0;
//                long healthValueRiskCount = 0;
//                long healthValueWarnCount = 0;
					int healthValueWarnCount = 0;
					int healthValueRiskCount = 0;
					int healthValueNoticeCount = 0;
					int healthValueMinCount = 0;
					int riskNum = 0;
					int warnNum = 0;
					int noticeNum = 0;

					for (IdxBizFanWarningRuleSet e : idxBizPvWarningRuleSets) {
						switch (e.getWarningName()) {
						case "警告":
							healthValueWarn = Double.parseDouble(e.getWarningIf().substring(2));
							healthValueWarnCount = Integer.parseInt(e.getWarningCycle());
							break;
						case "危险":
							healthValueRisk = Double.parseDouble(e.getWarningIf().substring(2));
							healthValueRiskCount = Integer.parseInt(e.getWarningCycle());
							break;
						case "注意":
							healthValueNotice = Double.parseDouble(e.getWarningIf().substring(2));
							healthValueNoticeCount = Integer.parseInt(e.getWarningCycle());
							break;
						}

					}

					List<Double> healthIndex = idxBizFanHealthIndices.stream().map(FanHealthIndexHour::getHealthIndex)
							.collect(Collectors.toList());
//                Double finalHealthValueRisk = healthValueRisk;
//                long riskNum = healthIndex.subList(healthIndex.size()>healthValueRiskCount? (int) (healthIndex.size() - healthValueRiskCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueRisk).count();
//                Double finalHealthValueWarn = healthValueWarn;
//                long warnNum = healthIndex.subList(healthIndex.size()>healthValueWarnCount? (int) (healthIndex.size() - healthValueWarnCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueWarn).count();
//                Double finalHealthValueNotice = healthValueNotice;
//                long noticeNum = healthIndex.subList(healthIndex.size()>healthValueNoticeCount? (int) (healthIndex.size() - healthValueNoticeCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueNotice).count();
					Double finalHealthValueRisk = healthValueRisk;
					if (healthIndex.size() >= healthValueRiskCount) {
						List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueRiskCount,
								healthIndex.size());
						riskNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueRisk).count();
					}
					Double finalHealthValueWarn = healthValueWarn;
					if (healthIndex.size() >= healthValueWarnCount) {
						List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueWarnCount,
								healthIndex.size());
						warnNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueWarn).count();
					}
					Double finalHealthValueNotice = healthValueNotice;
					if (healthIndex.size() >= healthValueNoticeCount) {
						List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueNoticeCount,
								healthIndex.size());
						noticeNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueNotice).count();
					}
					String level = "";
					String content = "";
					String num = "";
					if (noticeNum == healthValueNoticeCount) {
						level = "注意";
						num = "" + healthValueNotice;
						content = healthValueNoticeCount + "小时";
					}
					if (warnNum == healthValueWarnCount) {

						level = "警告";
						num = "" + healthValueWarn;
						content = healthValueWarnCount + "小时";
					}
					if (riskNum == healthValueRiskCount) {
						level = "危险";
						num = "" + healthValueRisk;
						content = healthValueRiskCount + "小时";
					}
					LambdaQueryWrapper<FanWarningRecord> query = new LambdaQueryWrapper<>();
					query.eq(FanWarningRecord::getAnalysisPointId, idxBizFanHealthIndices.get(0).getAnalysisObjSeq());
					query.eq(FanWarningRecord::getStatus, "0");
					query.isNull(FanWarningRecord::getDisposotionDate);
					query.orderByDesc(FanWarningRecord::getTs);
					List<FanWarningRecord> idxBizFanWarningRecords = fanWaringRecordMapper.selectList(query);

					int flag = ObjectUtils.isEmpty(idxBizFanWarningRecords) || WarningNameEnum
							.getCode(level) > WarningNameEnum.getCode(idxBizFanWarningRecords.get(0).getWarningName())
									? 0
									: 1;
					Boolean timeFlag = format
							.equals(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getRecDate());
					if (!level.equals("") && flag == 0 && timeFlag) {
						IdxBizFanWarningRecord idxBizFanWarningRecord = new IdxBizFanWarningRecord();
						idxBizFanWarningRecord
								.setKks(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getKks());
						idxBizFanWarningRecord
								.setArae(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getArea());
						idxBizFanWarningRecord
								.setStation(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getStation());
						idxBizFanWarningRecord.setSubSystem(
								idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getSubSystem());
						idxBizFanWarningRecord.setGatewayId(gateWayId);
						idxBizFanWarningRecord.setIndexAddress(address);
						idxBizFanWarningRecord.setEquipmentName(
								idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getEquipmentName());
						idxBizFanWarningRecord.setAnalysisPointId(
								idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getAnalysisObjSeq());
						idxBizFanWarningRecord.setDisposotionState("待确认");
						idxBizFanWarningRecord.setStatus("0");
						idxBizFanWarningRecord.setWarningName(level);
						idxBizFanWarningRecord
								.setCONTENT(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getPointName()
										+ "连续" + content + "健康指数≤" + num);
						idxBizFanWarningRecord.setRecDate(time);
						idxBizFanWarningRecord.setWarningPeriod(WarningPeriodEnum.HOUR.getName());
						idxBizFanWarningRecord
								.setNumber(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getNumber());
						idxBizFanWarningRecord.setHealthIndexSeq(idxBizFanHealthIndices
								.get(idxBizFanHealthIndices.size() - 1).getHealthIndex().toString());
						idxBizFanWarningRecord.setHealthLevel(
								idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getHealthLevel());
						idxBizFanWarningRecord.setPointName(
								idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getPointName());
						idxBizFanWarningRecordList.add(idxBizFanWarningRecord);
						long currentTimeMillis = System.currentTimeMillis();
						long nanoTime = System.nanoTime();
						long timestamp = currentTimeMillis * 1000000 + nanoTime % 1000000;

						FanWarningRecord fanWarningRecord = new FanWarningRecord();
						BeanUtils.copyProperties(idxBizFanWarningRecord, fanWarningRecord, "disposotionDate", "recDate",
								"CONTENT");
						fanWarningRecord.setContent(idxBizFanWarningRecord.getCONTENT());
						fanWarningRecord.setRecDate(format);
						fanWarningRecord.setTs(timestamp);
						fanWarningRecord.setHealthIndex(String.format(CommonConstans.Onedecimalplaces,
								idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getHealthIndex()));
						fanWarningRecord.setOrgCode(idxBizFanHealthIndices.get(0).getOrgCode());
						tdFanWarningRecordList.add(fanWarningRecord);
					}
				}
//                }
//        idxBizFanWarningRecordService.saveBatch(idxBizFanWarningRecordList);
				if (CollUtil.isNotEmpty(tdFanWarningRecordList)) {

					// tdengine插入
					fanWaringRecordMapper.saveBatchWarningRecords(tdFanWarningRecordList);
				}
				// 触发风险模型生成预警处置模块的预警记录
				fetchDataFan(tdFanWarningRecordList, stationMap);
			}).start();
		});

	}

	/***
	 * 每三天取一次最大粒度内的指数异常数据 判断三天内数据是否符合预警规则 符合则报警并在redis中缓存 同一级别的预警记录下次不生成
	 * TdengineTimeServiceImpl计算完调用
	 */

	// @Scheduled(cron = "0 0 0 0/1 * ? ")
	public void healthWarningDay() {
		if (!openHealth) {
			return;
		}
		Date time = new Date();
		String format = DateUtil.format(time, "yyyy-MM-dd 00:00:00");
		// 三天 + 8小时
//        Date date = DateUtils.dateAddHours(time, -80);
//        Calendar calendar = Calendar.getInstance();
//        calendar.set(Calendar.DAY_OF_MONTH,calendar.get(Calendar.DAY_OF_MONTH)-3);
//        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		Integer maxWaringCycle = idxBizFanWarningRuleSetMapper.getMaxWaringCycleOfDay();
		Date date = DateUtil.offsetHour(time, -8);
		date = DateUtil.offsetDay(date, 0 - (maxWaringCycle));

		LambdaQueryWrapper<FanHealthIndexDay> wrapper = new LambdaQueryWrapper<>();
		// wrapper.ne(FanHealthIndexDay::getHealthLevel,"安全");
		wrapper.ge(FanHealthIndexDay::getRecDate, date);
		wrapper.eq(FanHealthIndexDay::getAnalysisObjType, "测点");
		Date dateMax = DateUtil.offsetHour(time, -8);
		wrapper.le(FanHealthIndexDay::getRecDate, dateMax);
		wrapper.orderByAsc(FanHealthIndexDay::getTs);
		List<FanHealthIndexDay> healthIndices = fanHealthIndexDayMapper.selectList(wrapper);
		if (ObjectUtils.isEmpty(healthIndices)) {
			return;
		}
		List<String> collect = healthIndices.stream().map(FanHealthIndexDay::getAnalysisObjSeq)
				.collect(Collectors.toList());

		LambdaQueryWrapper<IdxBizFanWarningRuleSet> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(IdxBizFanWarningRuleSet::getAnalysisType, WarningPeriodEnum.DAY.getName());
		queryWrapper.in(IdxBizFanWarningRuleSet::getAnalysisPointId, collect);
		List<IdxBizFanWarningRuleSet> idxBizPvWarningRules = idxBizFanWarningRuleSetMapper.selectList(queryWrapper);

		Map<String, Map<String, List<FanHealthIndexDay>>> gateWayMaps = healthIndices.stream()
				.collect(Collectors.groupingBy(FanHealthIndexDay::getGatewayId,
						Collectors.groupingBy(FanHealthIndexDay::getIndexAddress)));
		List<IdxBizFanWarningRecord> idxBizFanWarningRecordList = new ArrayList<>();
		List<FanWarningRecord> tdFanWarningRecordList = new ArrayList<>();
		HashMap<String, StationBasic> stationMap = new HashMap<>();
		for (String gateWayId : gateWayMaps.keySet()) {

			LambdaQueryWrapper<StationBasic> basicLambdaQueryWrapper = new LambdaQueryWrapper<>();
			basicLambdaQueryWrapper.eq(StationBasic::getFanGatewayId, gateWayId).or().eq(StationBasic::getBoosterGatewayId, gateWayId);
			basicLambdaQueryWrapper.last("limit 1");
			StationBasic stationBasic = stationBasicMapper.selectOne(basicLambdaQueryWrapper);
			stationMap.put(gateWayId, stationBasic);

			Map<String, List<FanHealthIndexDay>> healthDataMaps = gateWayMaps.get(gateWayId);
			for (String address : healthDataMaps.keySet()) {
				List<FanHealthIndexDay> idxBizFanHealthIndices = healthDataMaps.get(address);

				List<IdxBizFanWarningRuleSet> idxBizPvWarningRuleSets = idxBizPvWarningRules.stream()
						.filter(t -> t.getAnalysisPointId().equals(idxBizFanHealthIndices.get(0).getAnalysisObjSeq()))
						.collect(Collectors.toList());

				if (ObjectUtils.isEmpty(idxBizPvWarningRuleSets)) {
					continue;
				}
				Double healthValueWarn = 0.0;
				Double healthValueRisk = 0.0;
				Double healthValueNotice = 0.0;

//                long healthValueNoticeCount = 0;
//                long healthValueWarnCount = 0;
//                long healthValueRiskCount = 0;

				int healthValueWarnCount = 0;
				int healthValueRiskCount = 0;
				int healthValueNoticeCount = 0;
				int healthValueMinCount = 0;
				int riskNum = 0;
				int warnNum = 0;
				int noticeNum = 0;

				for (IdxBizFanWarningRuleSet e : idxBizPvWarningRuleSets) {
					switch (e.getWarningName()) {
					case "警告":
						healthValueWarn = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueWarnCount = Integer.parseInt(e.getWarningCycle());
						break;
					case "危险":
						healthValueRisk = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueRiskCount = Integer.parseInt(e.getWarningCycle());
						break;
					case "注意":
						healthValueNotice = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueNoticeCount = Integer.parseInt(e.getWarningCycle());
						break;
					}

				}

				List<Double> healthIndex = idxBizFanHealthIndices.stream().map(FanHealthIndexDay::getHealthIndex)
						.collect(Collectors.toList());
//                Double finalHealthValueRisk = healthValueRisk;
//                long riskNum = healthIndex.subList(healthIndex.size()>healthValueRiskCount? (int) (healthIndex.size() - healthValueRiskCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueRisk).count();
//                Double finalHealthValueWarn = healthValueWarn;
//                long warnNum = healthIndex.subList(healthIndex.size()>healthValueWarnCount? (int) (healthIndex.size() - healthValueWarnCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueWarn).count();
//                Double finalHealthValueNotice = healthValueNotice;
//                long noticeNum = healthIndex.subList(healthIndex.size()>healthValueNoticeCount? (int) (healthIndex.size() - healthValueNoticeCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueNotice).count();
				Double finalHealthValueRisk = healthValueRisk;
				if (healthIndex.size() >= healthValueRiskCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueRiskCount,
							healthIndex.size());
					riskNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueRisk).count();
				}
				Double finalHealthValueWarn = healthValueWarn;
				if (healthIndex.size() >= healthValueWarnCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueWarnCount,
							healthIndex.size());
					warnNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueWarn).count();
				}
				Double finalHealthValueNotice = healthValueNotice;
				if (healthIndex.size() >= healthValueNoticeCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueNoticeCount,
							healthIndex.size());
					noticeNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueNotice).count();
				}
				String level = "";
				String content = "";
				String num = "";
				if (noticeNum == healthValueNoticeCount) {
					// redisUtils.set(gateWayId+"_"+address+"_health_notice_day","notice");
					level = "注意";
					num = "" + healthValueNotice;
					content = healthValueNoticeCount + "天";
				}
				if (warnNum == healthValueWarnCount) {
					// redisUtils.set(gateWayId+"_"+address+"_health_warn_day","warn");
					level = "警告";
					num = "" + healthValueWarn;
					content = healthValueWarnCount + "天";
				}
				if (riskNum == healthValueRiskCount) {
					// redisUtils.set(gateWayId+"_"+address+"_health_risk_day","risk");
					level = "危险";
					num = "" + healthValueRisk;
					content = healthValueRiskCount + "天";
				}

				LambdaQueryWrapper<FanWarningRecord> query = new LambdaQueryWrapper<>();
				query.eq(FanWarningRecord::getAnalysisPointId, idxBizFanHealthIndices.get(0).getAnalysisObjSeq());
				query.eq(FanWarningRecord::getStatus, "0");
				query.isNull(FanWarningRecord::getDisposotionDate);
				query.orderByDesc(FanWarningRecord::getTs);
				List<FanWarningRecord> idxBizFanWarningRecords = fanWaringRecordMapper.selectList(query);

				int flag = ObjectUtils.isEmpty(idxBizFanWarningRecords) || WarningNameEnum
						.getCode(level) > WarningNameEnum.getCode(idxBizFanWarningRecords.get(0).getWarningName()) ? 0
								: 1;
				Boolean timeFlag = format
						.equals(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getRecDate());
				if (!level.equals("") && flag == 0 && timeFlag) {
					IdxBizFanWarningRecord idxBizFanWarningRecord = new IdxBizFanWarningRecord();
					idxBizFanWarningRecord
							.setKks(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getKks());
					idxBizFanWarningRecord
							.setArae(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getArea());
					idxBizFanWarningRecord
							.setStation(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getStation());
					idxBizFanWarningRecord
							.setSubSystem(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getSubSystem());
					idxBizFanWarningRecord.setGatewayId(gateWayId);
					idxBizFanWarningRecord.setIndexAddress(address);
					idxBizFanWarningRecord.setEquipmentName(
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getEquipmentName());
					idxBizFanWarningRecord.setAnalysisPointId(
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getAnalysisObjSeq());
					idxBizFanWarningRecord.setDisposotionState("待确认");
					idxBizFanWarningRecord.setStatus("0");
					idxBizFanWarningRecord.setWarningName(level);
					idxBizFanWarningRecord
							.setCONTENT(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getPointName()
									+ "连续" + content + "健康指数≤" + num);
					idxBizFanWarningRecord.setRecDate(time);
					idxBizFanWarningRecord.setWarningPeriod(WarningPeriodEnum.DAY.getName());
					idxBizFanWarningRecord
							.setNumber(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getNumber());
					idxBizFanWarningRecord.setHealthIndexSeq(
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getHealthIndex().toString());
					idxBizFanWarningRecord.setHealthLevel(
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getHealthLevel());
					idxBizFanWarningRecord
							.setPointName(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getPointName());
					idxBizFanWarningRecordList.add(idxBizFanWarningRecord);

					long currentTimeMillis = System.currentTimeMillis();
					long nanoTime = System.nanoTime();
					long timestamp = currentTimeMillis * 1000000 + nanoTime % 1000000;

					FanWarningRecord fanWarningRecord = new FanWarningRecord();
					BeanUtils.copyProperties(idxBizFanWarningRecord, fanWarningRecord, "disposotionDate", "recDate",
							"CONTENT");
					fanWarningRecord.setContent(idxBizFanWarningRecord.getCONTENT());
					fanWarningRecord.setRecDate(format);
					fanWarningRecord.setTs(timestamp);
					fanWarningRecord.setHealthIndex(String.format(CommonConstans.Onedecimalplaces,
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getHealthIndex()));
					fanWarningRecord.setOrgCode(idxBizFanHealthIndices.get(0).getOrgCode());
					tdFanWarningRecordList.add(fanWarningRecord);
				}
			}
		}

//        idxBizFanWarningRecordService.saveBatch(idxBizFanWarningRecordList);
		if (CollUtil.isNotEmpty(tdFanWarningRecordList)) {

			// tdengine插入
			fanWaringRecordMapper.saveBatchWarningRecords(tdFanWarningRecordList);
		}
		// 触发风险模型生成预警处置模块的预警记录
		fetchDataFan(tdFanWarningRecordList, stationMap);
	}

//    @Scheduled(cron = "0 0 0 0/1 * ? ")
	public void healthWarningDayNew() {
		if (!openHealth) {
			return;
		}
		Date time = new Date();
		String format = DateUtil.format(time, "yyyy-MM-dd 00:00:00");
		// 三天 + 8小时
//        Date date = DateUtils.dateAddHours(time, -80);
//        Calendar calendar = Calendar.getInstance();
//        calendar.set(Calendar.DAY_OF_MONTH,calendar.get(Calendar.DAY_OF_MONTH)-3);
//        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		List<String> gatewayIds = idxBizFanWarningRuleSetMapper.getGatewayIds();
		gatewayIds.stream().forEach(gatewayId -> {
			Integer maxWaringCycle = idxBizFanWarningRuleSetMapper.getMaxWaringCycleOfDayByGatewayId(gatewayId);
			Date date = DateUtil.offsetHour(time, -8);
			date = DateUtil.offsetDay(date, 0 - (maxWaringCycle));

			LambdaQueryWrapper<FanHealthIndexDay> wrapper = new LambdaQueryWrapper<>();
			// wrapper.ne(FanHealthIndexDay::getHealthLevel,"安全");
			wrapper.ge(FanHealthIndexDay::getRecDate, date);
			wrapper.eq(FanHealthIndexDay::getAnalysisObjType, "测点");
			Date dateMax = DateUtil.offsetHour(time, -8);
			wrapper.le(FanHealthIndexDay::getRecDate, dateMax);
			wrapper.orderByAsc(FanHealthIndexDay::getTs);
			List<FanHealthIndexDay> healthIndices = fanHealthIndexDayMapper.selectList(wrapper);
			if (ObjectUtils.isEmpty(healthIndices)) {
				return;
			}
			List<String> collect = healthIndices.stream().map(FanHealthIndexDay::getAnalysisObjSeq)
					.collect(Collectors.toList());

			LambdaQueryWrapper<IdxBizFanWarningRuleSet> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.eq(IdxBizFanWarningRuleSet::getAnalysisType, WarningPeriodEnum.DAY.getName());
			queryWrapper.in(IdxBizFanWarningRuleSet::getAnalysisPointId, collect);
			List<IdxBizFanWarningRuleSet> idxBizPvWarningRules = idxBizFanWarningRuleSetMapper.selectList(queryWrapper);

			Map<String, Map<String, List<FanHealthIndexDay>>> gateWayMaps = healthIndices.stream()
					.collect(Collectors.groupingBy(FanHealthIndexDay::getGatewayId,
							Collectors.groupingBy(FanHealthIndexDay::getIndexAddress)));
			List<IdxBizFanWarningRecord> idxBizFanWarningRecordList = new ArrayList<>();
			List<FanWarningRecord> tdFanWarningRecordList = new ArrayList<>();
			HashMap<String, StationBasic> stationMap = new HashMap<>();
//            for (String gateWayId : gateWayMaps.keySet()) {

			LambdaQueryWrapper<StationBasic> basicLambdaQueryWrapper = new LambdaQueryWrapper<>();
			basicLambdaQueryWrapper.eq(StationBasic::getFanGatewayId, gatewayId).or().eq(StationBasic::getBoosterGatewayId, gatewayId);
			basicLambdaQueryWrapper.last("limit 1");
			StationBasic stationBasic = stationBasicMapper.selectOne(basicLambdaQueryWrapper);
			stationMap.put(gatewayId, stationBasic);

			Map<String, List<FanHealthIndexDay>> healthDataMaps = gateWayMaps.get(gatewayId);
			for (String address : healthDataMaps.keySet()) {
				List<FanHealthIndexDay> idxBizFanHealthIndices = healthDataMaps.get(address);

				List<IdxBizFanWarningRuleSet> idxBizPvWarningRuleSets = idxBizPvWarningRules.stream()
						.filter(t -> t.getAnalysisPointId().equals(idxBizFanHealthIndices.get(0).getAnalysisObjSeq()))
						.collect(Collectors.toList());

				if (ObjectUtils.isEmpty(idxBizPvWarningRuleSets)) {
					continue;
				}
				Double healthValueWarn = 0.0;
				Double healthValueRisk = 0.0;
				Double healthValueNotice = 0.0;

//                long healthValueNoticeCount = 0;
//                long healthValueWarnCount = 0;
//                long healthValueRiskCount = 0;

				int healthValueWarnCount = 0;
				int healthValueRiskCount = 0;
				int healthValueNoticeCount = 0;
				int healthValueMinCount = 0;
				int riskNum = 0;
				int warnNum = 0;
				int noticeNum = 0;

				for (IdxBizFanWarningRuleSet e : idxBizPvWarningRuleSets) {
					switch (e.getWarningName()) {
					case "警告":
						healthValueWarn = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueWarnCount = Integer.parseInt(e.getWarningCycle());
						break;
					case "危险":
						healthValueRisk = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueRiskCount = Integer.parseInt(e.getWarningCycle());
						break;
					case "注意":
						healthValueNotice = Double.parseDouble(e.getWarningIf().substring(2));
						healthValueNoticeCount = Integer.parseInt(e.getWarningCycle());
						break;
					}

				}

				List<Double> healthIndex = idxBizFanHealthIndices.stream().map(FanHealthIndexDay::getHealthIndex)
						.collect(Collectors.toList());
//                Double finalHealthValueRisk = healthValueRisk;
//                long riskNum = healthIndex.subList(healthIndex.size()>healthValueRiskCount? (int) (healthIndex.size() - healthValueRiskCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueRisk).count();
//                Double finalHealthValueWarn = healthValueWarn;
//                long warnNum = healthIndex.subList(healthIndex.size()>healthValueWarnCount? (int) (healthIndex.size() - healthValueWarnCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueWarn).count();
//                Double finalHealthValueNotice = healthValueNotice;
//                long noticeNum = healthIndex.subList(healthIndex.size()>healthValueNoticeCount? (int) (healthIndex.size() - healthValueNoticeCount) :0,healthIndex.size()).stream().filter(e -> e <= finalHealthValueNotice).count();
				Double finalHealthValueRisk = healthValueRisk;
				if (healthIndex.size() >= healthValueRiskCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueRiskCount,
							healthIndex.size());
					riskNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueRisk).count();
				}
				Double finalHealthValueWarn = healthValueWarn;
				if (healthIndex.size() >= healthValueWarnCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueWarnCount,
							healthIndex.size());
					warnNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueWarn).count();
				}
				Double finalHealthValueNotice = healthValueNotice;
				if (healthIndex.size() >= healthValueNoticeCount) {
					List<Double> healthIndexList = healthIndex.subList(healthIndex.size() - healthValueNoticeCount,
							healthIndex.size());
					noticeNum = (int) healthIndexList.stream().filter(e -> e <= finalHealthValueNotice).count();
				}
				String level = "";
				String content = "";
				String num = "";
				if (noticeNum == healthValueNoticeCount) {
					// redisUtils.set(gateWayId+"_"+address+"_health_notice_day","notice");
					level = "注意";
					num = "" + healthValueNotice;
					content = healthValueNoticeCount + "天";
				}
				if (warnNum == healthValueWarnCount) {
					// redisUtils.set(gateWayId+"_"+address+"_health_warn_day","warn");
					level = "警告";
					num = "" + healthValueWarn;
					content = healthValueWarnCount + "天";
				}
				if (riskNum == healthValueRiskCount) {
					// redisUtils.set(gateWayId+"_"+address+"_health_risk_day","risk");
					level = "危险";
					num = "" + healthValueRisk;
					content = healthValueRiskCount + "天";
				}

				LambdaQueryWrapper<FanWarningRecord> query = new LambdaQueryWrapper<>();
				query.eq(FanWarningRecord::getAnalysisPointId, idxBizFanHealthIndices.get(0).getAnalysisObjSeq());
				query.eq(FanWarningRecord::getStatus, "0");
				query.isNull(FanWarningRecord::getDisposotionDate);
				query.orderByDesc(FanWarningRecord::getTs);
				List<FanWarningRecord> idxBizFanWarningRecords = fanWaringRecordMapper.selectList(query);

				int flag = ObjectUtils.isEmpty(idxBizFanWarningRecords) || WarningNameEnum
						.getCode(level) > WarningNameEnum.getCode(idxBizFanWarningRecords.get(0).getWarningName()) ? 0
								: 1;
				Boolean timeFlag = format
						.equals(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getRecDate());
				if (!level.equals("") && flag == 0 && timeFlag) {
					IdxBizFanWarningRecord idxBizFanWarningRecord = new IdxBizFanWarningRecord();
					idxBizFanWarningRecord
							.setKks(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getKks());
					idxBizFanWarningRecord
							.setArae(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getArea());
					idxBizFanWarningRecord
							.setStation(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getStation());
					idxBizFanWarningRecord
							.setSubSystem(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getSubSystem());
					idxBizFanWarningRecord.setGatewayId(gatewayId);
					idxBizFanWarningRecord.setIndexAddress(address);
					idxBizFanWarningRecord.setEquipmentName(
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getEquipmentName());
					idxBizFanWarningRecord.setAnalysisPointId(
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getAnalysisObjSeq());
					idxBizFanWarningRecord.setDisposotionState("待确认");
					idxBizFanWarningRecord.setStatus("0");
					idxBizFanWarningRecord.setWarningName(level);
					idxBizFanWarningRecord
							.setCONTENT(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getPointName()
									+ "连续" + content + "健康指数≤" + num);
					idxBizFanWarningRecord.setRecDate(time);
					idxBizFanWarningRecord.setWarningPeriod(WarningPeriodEnum.DAY.getName());
					idxBizFanWarningRecord
							.setNumber(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getNumber());
					idxBizFanWarningRecord.setHealthIndexSeq(
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getHealthIndex().toString());
					idxBizFanWarningRecord.setHealthLevel(
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getHealthLevel());
					idxBizFanWarningRecord
							.setPointName(idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getPointName());
					idxBizFanWarningRecordList.add(idxBizFanWarningRecord);

					long currentTimeMillis = System.currentTimeMillis();
					long nanoTime = System.nanoTime();
					long timestamp = currentTimeMillis * 1000000 + nanoTime % 1000000;

					FanWarningRecord fanWarningRecord = new FanWarningRecord();
					BeanUtils.copyProperties(idxBizFanWarningRecord, fanWarningRecord, "disposotionDate", "recDate",
							"CONTENT");
					fanWarningRecord.setContent(idxBizFanWarningRecord.getCONTENT());
					fanWarningRecord.setRecDate(format);
					fanWarningRecord.setTs(timestamp);
					fanWarningRecord.setHealthIndex(String.format(CommonConstans.Onedecimalplaces,
							idxBizFanHealthIndices.get(idxBizFanHealthIndices.size() - 1).getHealthIndex()));
					fanWarningRecord.setOrgCode(idxBizFanHealthIndices.get(0).getOrgCode());
					tdFanWarningRecordList.add(fanWarningRecord);
				}
			}
//            }

//        idxBizFanWarningRecordService.saveBatch(idxBizFanWarningRecordList);
			if (CollUtil.isNotEmpty(tdFanWarningRecordList)) {

				// tdengine插入
				fanWaringRecordMapper.saveBatchWarningRecords(tdFanWarningRecordList);
			}
			// 触发风险模型生成预警处置模块的预警记录
			fetchDataFan(tdFanWarningRecordList, stationMap);
		});

	}

	public String getJumpUrlByInfo(String sbbm, List<JumpConfig> jumpConfigs) {
		Map<String, String> collect = jumpConfigs.stream()
				.collect(Collectors.toMap(JumpConfig::getType, JumpConfig::getUrl));
		if (StrUtil.isEmpty(sbbm)) {
			return "";
		}
		if (sbbm.indexOf("BAT") != -1) {
			return collect.get("箱变");
		} else if (sbbm.indexOf("WG") != -1) {
			return collect.get("汇流箱");
		} else if (sbbm.indexOf("WC") != -1) {
			return collect.get("逆变器");
		} else if (sbbm.length() == 12 && sbbm.indexOf("MD") != -1) {
			return collect.get("风机");
		} else if (sbbm.length() > 12 && sbbm.indexOf("MD") != -1) {
			return collect.get("风机子系统");
		} else {
			return collect.get("默认");
		}
	}

	/**
	 * 光伏 - 触发预控模型生成预警
	 *
	 * @param idxBizPvWarningRecords
	 * @return
	 */
	@Async
	public void fetchDataPv(List<PvWarningRecord> idxBizPvWarningRecords, HashMap<String, StationBasic> stationMap) {
		List<JumpConfig> jumpConfigs = jumpConfigMapper.selectList(null);
		log.info("===开始触发风险预警模型===数量为：{}", idxBizPvWarningRecords.size());
		idxBizPvWarningRecords.stream().forEach(idxBizPvWarningRecord -> {
			BizMessage bizMessage = new BizMessage();
			bizMessage.setIndexKey(INDEX_KEY_PV);
			bizMessage.setIndexValue(idxBizPvWarningRecord.getPointName());
//            bizMessage.setTraceId(idxBizPvWarningRecord.getSequenceNbr());
			RiskBizInfoVo riskBizInfoVo = new RiskBizInfoVo();
			riskBizInfoVo.setWarningObjectName(idxBizPvWarningRecord.getEquipmentName());
			riskBizInfoVo.setWarningObjectCode(idxBizPvWarningRecord.getKks());
			riskBizInfoVo
					.setSourceAttribution(stationMap.get(idxBizPvWarningRecord.getGatewayId()).getProjectOrgCode());
			riskBizInfoVo.setSourceAttributionDesc(idxBizPvWarningRecord.getStation());
			riskBizInfoVo.setWarningObjectType("equip");
			riskBizInfoVo.setWarningTime(idxBizPvWarningRecord.getRecDate());
			riskBizInfoVo.setBussId(String.valueOf(idxBizPvWarningRecord.getTs()));
			riskBizInfoVo.setWarningObjectLinkUrl(getJumpUrlByInfo(idxBizPvWarningRecord.getKks(), jumpConfigs));
			List<RiskDynamicDetailsVo> detailsVos = new ArrayList<>();
			RiskDynamicDetailsVo dynamicDetailsVo = new RiskDynamicDetailsVo();
			dynamicDetailsVo.setTabName("预警详情");

			List<TableContentVo> tabContent = new ArrayList<>();
			TableContentVo tableContentVo1 = new TableContentVo("1", "场站名称", idxBizPvWarningRecord.getStation(),
					"text");
			TableContentVo tableContentVo3 = new TableContentVo("2", "子阵", idxBizPvWarningRecord.getSubarray(), "text");
			TableContentVo tableContentVo2 = new TableContentVo("3", "设备名称", idxBizPvWarningRecord.getEquipmentName(),
					"text");
			TableContentVo tableContentVo4 = new TableContentVo("1", "分析变量", idxBizPvWarningRecord.getPointName(),
					"text");
			TableContentVo tableContentVo5 = new TableContentVo("1", "健康状态指数", idxBizPvWarningRecord.getHealthIndex(),
					"text");
			TableContentVo tableContentVo6 = new TableContentVo("1", "健康等级", idxBizPvWarningRecord.getHealthLevel(),
					"text");
			TableContentVo tableContentVo7 = new TableContentVo("1", "预警周期", idxBizPvWarningRecord.getWarningPeriod(),
					"text");
			TableContentVo tableContentVo8 = new TableContentVo("1", "预警时间", idxBizPvWarningRecord.getRecDate(),
					"text");
			TableContentVo tableContentVo10 = new TableContentVo("1", "预警等级", idxBizPvWarningRecord.getWarningName(),
					"text");
			TableContentVo tableContentVo11 = new TableContentVo("1", "预警原因", idxBizPvWarningRecord.getContent(),
					"text");
			tabContent.add(tableContentVo1);
			tabContent.add(tableContentVo2);
			tabContent.add(tableContentVo3);
			tabContent.add(tableContentVo4);
			tabContent.add(tableContentVo5);
			tabContent.add(tableContentVo6);
			tabContent.add(tableContentVo7);
			tabContent.add(tableContentVo8);
			tabContent.add(tableContentVo10);
			tabContent.add(tableContentVo11);
			dynamicDetailsVo.setTabContent(tabContent);
			detailsVos.add(dynamicDetailsVo);
			riskBizInfoVo.setDynamicDetails(detailsVos);
			bizMessage.setBizInfo(riskBizInfoVo);
			// 子系统@健康指数@预警周期
			String traceId2 = idxBizPvWarningRecord.getSubarray() + "@" + idxBizPvWarningRecord.getHealthLevel() + "@"
					+ idxBizPvWarningRecord.getWarningPeriod();
			bizMessage.setTraceId2(traceId2);
			try {
				emqKeeper.getMqttClient().publish(SMART_ANALYSE_PV + "/data/analysis",
						JSON.toJSONString(bizMessage).getBytes(StandardCharsets.UTF_8), 2, false);
			} catch (MqttException e) {
				e.printStackTrace();
			}
		});
	}

	/**
	 * 风电 - 触发预控模型生成预警
	 *
	 * @param idxBizFanWarningRecords
	 * @return
	 */
	@Async
	public void fetchDataFan(List<FanWarningRecord> idxBizFanWarningRecords, HashMap<String, StationBasic> stationMap) {
		List<JumpConfig> jumpConfigs = jumpConfigMapper.selectList(null);
		log.info("===开始触发风险预警模型===数量为：{}", idxBizFanWarningRecords.size());
		idxBizFanWarningRecords.stream().forEach(idxBizFanWarningRecord -> {
			BizMessage bizMessage = new BizMessage();
			bizMessage.setIndexKey(INDEX_KEY_FAN);
			bizMessage.setIndexValue(idxBizFanWarningRecord.getPointName());
//            bizMessage.setTraceId(idxBizFanWarningRecord.getSequenceNbr());
			RiskBizInfoVo riskBizInfoVo = new RiskBizInfoVo();
			riskBizInfoVo.setBussId(String.valueOf(idxBizFanWarningRecord.getTs()));
			riskBizInfoVo.setWarningObjectName(idxBizFanWarningRecord.getEquipmentName());
			riskBizInfoVo.setWarningObjectCode(idxBizFanWarningRecord.getKks());
			riskBizInfoVo
					.setSourceAttribution(stationMap.get(idxBizFanWarningRecord.getGatewayId()).getProjectOrgCode());
			riskBizInfoVo.setSourceAttributionDesc(idxBizFanWarningRecord.getStation());
			riskBizInfoVo.setWarningObjectType("equip");
			riskBizInfoVo.setWarningTime(idxBizFanWarningRecord.getRecDate());
			riskBizInfoVo.setWarningObjectLinkUrl(getJumpUrlByInfo(idxBizFanWarningRecord.getKks(), jumpConfigs));
			List<RiskDynamicDetailsVo> detailsVos = new ArrayList<>();
			RiskDynamicDetailsVo dynamicDetailsVo = new RiskDynamicDetailsVo();
			dynamicDetailsVo.setTabName("预警详情");
			List<TableContentVo> tabContent = new ArrayList<>();
			TableContentVo tableContentVo1 = new TableContentVo("1", "场站名称", idxBizFanWarningRecord.getStation(),
					"text");
			TableContentVo tableContentVo2 = new TableContentVo("2", "设备名称", idxBizFanWarningRecord.getEquipmentName(),
					"text");
			TableContentVo tableContentVo3 = new TableContentVo("2", "设备系统", idxBizFanWarningRecord.getSubSystem(),
					"text");
			TableContentVo tableContentVo4 = new TableContentVo("1", "分析变量", idxBizFanWarningRecord.getPointName(),
					"text");
			TableContentVo tableContentVo5 = new TableContentVo("1", "健康状态指数", idxBizFanWarningRecord.getHealthIndex(),
					"text");
			TableContentVo tableContentVo6 = new TableContentVo("1", "健康等级", idxBizFanWarningRecord.getHealthLevel(),
					"text");
			TableContentVo tableContentVo7 = new TableContentVo("1", "预警周期", idxBizFanWarningRecord.getWarningPeriod(),
					"text");
			TableContentVo tableContentVo8 = new TableContentVo("1", "预警时间", idxBizFanWarningRecord.getRecDate(),
					"text");
			TableContentVo tableContentVo10 = new TableContentVo("1", "预警等级", idxBizFanWarningRecord.getWarningName(),
					"text");
			TableContentVo tableContentVo11 = new TableContentVo("1", "预警原因", idxBizFanWarningRecord.getContent(),
					"text");
			tabContent.add(tableContentVo1);
			tabContent.add(tableContentVo2);
			tabContent.add(tableContentVo3);
			tabContent.add(tableContentVo4);
			tabContent.add(tableContentVo5);
			tabContent.add(tableContentVo6);
			tabContent.add(tableContentVo7);
			tabContent.add(tableContentVo8);
			tabContent.add(tableContentVo10);
			tabContent.add(tableContentVo11);
			dynamicDetailsVo.setTabContent(tabContent);
			detailsVos.add(dynamicDetailsVo);
			riskBizInfoVo.setDynamicDetails(detailsVos);
			bizMessage.setBizInfo(riskBizInfoVo);
			// 子系统@健康指数@预警周期
			String traceId2 = idxBizFanWarningRecord.getSubSystem() + "@" + idxBizFanWarningRecord.getHealthLevel()
					+ "@" + idxBizFanWarningRecord.getWarningPeriod();
			bizMessage.setTraceId2(traceId2);
			try {
				emqKeeper.getMqttClient().publish(SMART_ANALYSE_FAN + "/data/analysis",
						JSON.toJSONString(bizMessage).getBytes(StandardCharsets.UTF_8), 2, false);
			} catch (MqttException e) {
				e.printStackTrace();
			}
		});
	}

}
