From 24996ea75ec4ca3b7d154387bfe37ec9dd387255 Mon Sep 17 00:00:00 2001 From: houzhongjian <houzhongyi@126.com> Date: 星期四, 29 五月 2025 14:40:05 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmPredictAutoAdjustConfigServiceImpl.java | 317 ++++++++++++++++++++++++++++------------------------ 1 files changed, 169 insertions(+), 148 deletions(-) diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmPredictAutoAdjustConfigServiceImpl.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmPredictAutoAdjustConfigServiceImpl.java index 3c281d2..29fe746 100644 --- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmPredictAutoAdjustConfigServiceImpl.java +++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmPredictAutoAdjustConfigServiceImpl.java @@ -60,8 +60,8 @@ } @Override - public MmPredictAutoAdjustConfigEntity getByCode(String code) { - return baseDao.selectOne("config_code",code,"is_enable",1); + public List<MmPredictAutoAdjustConfigEntity> getByCode(String code) { + return baseDao.selectList(MmPredictAutoAdjustConfigEntity::getConfigCode,code,MmPredictAutoAdjustConfigEntity::getIsEnable,1); } @Override @@ -85,164 +85,185 @@ public boolean autoAdjustByCode(String configCode,long adjustStartTime) { log.info("开始自动调整:configCode:" + configCode + ",adjustStartTime:" + new Date(adjustStartTime)); // 查询调整配置 - MmPredictAutoAdjustConfigEntity configEntity = getByCode(configCode); - if (configEntity == null) { - log.info("自动调整失败原因:configEntity为null"); + List<MmPredictAutoAdjustConfigEntity> configEntityList = getByCode(configCode); + if (CollectionUtils.isEmpty(configEntityList)) { + log.info("自动调整失败原因:configEntityList为空"); return false; } + // 根据outputId分组 + Map<String, List<MmPredictAutoAdjustConfigEntity>> outputIdMap = configEntityList.stream().collect(Collectors.groupingBy(MmPredictAutoAdjustConfigEntity::getOutputId)); + for (Map.Entry<String, List<MmPredictAutoAdjustConfigEntity>> entry : outputIdMap.entrySet()) { + String outputId = entry.getKey(); + // 查询调整用户adjustStartTime 至 adjustStartTime - 预测长度 * 预测粒度 范围的值 + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(adjustStartTime); + Date endTime = calendar.getTime(); + ItemVO item = mmPredictItemService.getItemByOutPutId(outputId); + if (item == null) { + log.info("自动调整失败原因:getItemByOutPutId为null,outputId:" + outputId); + continue; + } + calendar.add(Calendar.SECOND,item.getPredictLength() * item.getGranularity() * -1); + Date startTime = calendar.getTime(); - // 查询调整用户adjustStartTime 至 adjustStartTime - 预测长度 * 预测粒度 范围的值 - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(adjustStartTime); - Date endTime = calendar.getTime(); - ItemVO item = mmPredictItemService.getItemByOutPutId(configEntity.getOutputId()); - if (item == null) { - log.info("自动调整失败原因:getItemByOutPutId为null,outputId:" + configEntity.getOutputId()); - return false; - } - calendar.add(Calendar.SECOND,item.getPredictLength() * item.getGranularity() * -1); - Date startTime = calendar.getTime(); - ApiPointValueQueryDTO queryDTO = new ApiPointValueQueryDTO(); - ApiPointDTO pointInfo = dataPointApi.getInfoById(configEntity.getPointId()); - queryDTO.setPointNo(pointInfo.getPointNo()); - queryDTO.setEnd(endTime); - queryDTO.setStart(startTime); - List<ApiPointValueDTO> apiPointValueDTOS = dataPointApi.queryPointHistoryValue(queryDTO); - if (CollectionUtils.isEmpty(apiPointValueDTOS)) { - log.info("自动调整失败原因:测点数据长度为0。queryDTO:" + queryDTO); - return false; - } - // 过滤掉-2 - apiPointValueDTOS = apiPointValueDTOS.stream().filter(e -> !Double.valueOf(e.getV()).equals(-2.0)).collect(Collectors.toList()); - if (CollectionUtils.isEmpty(apiPointValueDTOS)) { - log.info("自动调整失败原因:过滤掉-2之后测点数据长度为0。queryDTO:" + queryDTO); - return false; - } + // 获取预测历史结果 + InfluxModelResultPOJO pojo = new InfluxModelResultPOJO(); + pojo.setType(DataTypeEnum.FLOAT_LAST_BAK.getCode()); + pojo.setOutPutId(outputId); + List<InfluxModelResultVO> influxModelResult = influxDBService.queryModelResults(pojo, new Date(adjustStartTime), new Date(adjustStartTime)); + if (CollectionUtils.isEmpty(influxModelResult)) { + log.info("自动调整失败原因:预测历史结果为空。itemNo:" + item.getItemNo() + ",itemName:" + item.getItemName() + ",outputId:" + outputId + ",time:" + adjustStartTime); + continue; + } - // 获取预测历史结果 - InfluxModelResultPOJO pojo = new InfluxModelResultPOJO(); - pojo.setType(DataTypeEnum.FLOAT_LAST.getCode()); - pojo.setOutPutId(configEntity.getOutputId()); - List<InfluxModelResultVO> influxModelResult = influxDBService.queryModelResults(pojo, new Date(adjustStartTime), new Date(adjustStartTime)); - if (CollectionUtils.isEmpty(influxModelResult)) { - log.info("自动调整失败原因:预测历史结果为空。itemNo:" + item.getItemNo() + ",itemName" + item.getItemName() + ",outputId" + configEntity.getOutputId() + ",time" + adjustStartTime); - return false; - } - - // 触发规则 - AutoAdjustTriggerRuleEnum triggerRuleEnum = AutoAdjustTriggerRuleEnum.fromCode(configEntity.getTriggerRule()); - Double adjustValue = null; - // 判断是否符合触发条件 并计算调整值 - switch (triggerRuleEnum) { - case SLOPE: - // 计算每个△t的斜率,任意一个大于触发值则认为该区间有调整 - Calendar slopeCalendar = Calendar.getInstance(); - slopeCalendar.setTime(startTime); - Date slopeStartTime = slopeCalendar.getTime(); - slopeCalendar.add(Calendar.MINUTE,configEntity.getT()); - Date slopeEndTime = slopeCalendar.getTime(); - if (slopeEndTime.after(endTime)) { - log.info("自动调整失败原因:△t设置过大,大于模型预测长度 * 预测粒度。△t:" + configEntity.getT()); - return false; + // 计算所有影响用户的最终调整值 + Double finalAdjustValue = 0.0; + for (MmPredictAutoAdjustConfigEntity configEntity : entry.getValue()) { + Double adjustValue = null; + // 查询影响用户历史值 + ApiPointValueQueryDTO queryDTO = new ApiPointValueQueryDTO(); + ApiPointDTO pointInfo = dataPointApi.getInfoById(configEntity.getPointId()); + if (pointInfo == null) { + log.info("自动调整失败原因:影响用户pointInfo为空。pointId:" + configEntity.getPointId() + "configCode:" + configEntity.getConfigCode() + "configName:" + configEntity.getConfigName()); + continue; } - while (!slopeEndTime.after(endTime)) { - //计算斜率 - //△t开始时间测点值 - Date finalSlopeStartTime = slopeStartTime; - Optional<ApiPointValueDTO> startOptional = apiPointValueDTOS.stream().filter(apiPointValueDTO -> apiPointValueDTO.getT().equals(finalSlopeStartTime)).findFirst(); - //△t结束时间测点值 - Date finalSlopeEndTime = slopeEndTime; - Optional<ApiPointValueDTO> endOptional = apiPointValueDTOS.stream().filter(e -> e.getT().equals(finalSlopeEndTime)).findFirst(); - if (startOptional.isPresent() && endOptional.isPresent()) { - ApiPointValueDTO startPointValue = startOptional.get(); - ApiPointValueDTO endPointValue = endOptional.get(); - // 计算斜率 - double slope = BigDecimal.valueOf(endPointValue.getV() - startPointValue.getV()).divide(BigDecimal.valueOf(configEntity.getT())).doubleValue(); - // 斜率大于等于触发值则进行调整 - if (Double.valueOf(Math.abs(slope)).compareTo(configEntity.getTriggerValue()) >= 0) { - // 计算调整值 并跳出循环 - adjustValue = AutoAdjustValueRuleEnum.getAdjustValue(configEntity.getAdjustValueRule(), apiPointValueDTOS); - log.info("计算调整值:" + adjustValue + ",斜率:" + slope + ",pointNo:" + pointInfo.getPointNo() + ",pointName:" + pointInfo.getPointName() + ",slopeStartTime:" + slopeStartTime + ",slopeEndTime:" + slopeEndTime); - break; + log.info("自动调整开始处理:configName:" + configEntity.getConfigName() + "影响用户:" + pointInfo.getPointName()); + queryDTO.setPointNo(pointInfo.getPointNo()); + queryDTO.setEnd(endTime); + queryDTO.setStart(startTime); + List<ApiPointValueDTO> apiPointValueDTOS = dataPointApi.queryPointHistoryValue(queryDTO); + if (CollectionUtils.isEmpty(apiPointValueDTOS)) { + log.info("影响用户[" + pointInfo.getPointName() + "]调整失败原因:测点数据长度为0。queryDTO:" + queryDTO); + continue; + } + // 过滤掉-2 + apiPointValueDTOS = apiPointValueDTOS.stream().filter(e -> !Double.valueOf(e.getV()).equals(-2.0)).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(apiPointValueDTOS)) { + log.info("影响用户调整失败原因:过滤掉-2之后测点数据长度为0。queryDTO:" + queryDTO); + continue; + } + + // 触发规则 + AutoAdjustTriggerRuleEnum triggerRuleEnum = AutoAdjustTriggerRuleEnum.fromCode(configEntity.getTriggerRule()); + // 判断是否符合触发条件 并计算调整值 + switch (triggerRuleEnum) { + case SLOPE: + // 计算每个△t的斜率,任意一个大于触发值则认为该区间有调整 + Calendar slopeCalendar = Calendar.getInstance(); + slopeCalendar.setTime(startTime); + Date slopeStartTime = slopeCalendar.getTime(); + slopeCalendar.add(Calendar.MINUTE,configEntity.getT()); + Date slopeEndTime = slopeCalendar.getTime(); + if (slopeEndTime.after(endTime)) { + log.info("影响用户[" + pointInfo.getPointName() + "]调整失败原因:△t设置过大,大于模型预测长度 * 预测粒度。△t:" + configEntity.getT()); + continue; } - log.info("斜率不满足条件,斜率:" + slope); - } - // 下一个△t - slopeStartTime = slopeCalendar.getTime(); - slopeCalendar.add(Calendar.MINUTE,configEntity.getT()); - slopeEndTime = slopeCalendar.getTime(); - } - break; - case AVERAGE_GAP: - // 计算每两个△t的平均差,任意一个大于触发值则认为该区间有调整 - Calendar averageCalendar = Calendar.getInstance(); - averageCalendar.setTime(startTime); - Date averageStartTime = averageCalendar.getTime(); - averageCalendar.add(Calendar.MINUTE,configEntity.getT()); - Date averageMiddleTime = averageCalendar.getTime(); - averageCalendar.add(Calendar.MINUTE,configEntity.getT()); - Date averageEndTime = averageCalendar.getTime(); - - if (averageEndTime.after(endTime)) { - log.info("自动调整失败原因:△t设置过大,△t*2大于模型预测长度 * 预测粒度。△t:" + configEntity.getT()); - return false; - } - while (!averageEndTime.after(endTime)) { - //计算均值差 - //前△t测点平均值 - Date finalAverageStartTime = averageStartTime; - Date finalAverageMiddleTime = averageMiddleTime; - OptionalDouble startAverage = apiPointValueDTOS.stream().filter(e -> e.getT().after(finalAverageStartTime) && !e.getT().after(finalAverageMiddleTime)).mapToDouble(ApiPointValueDTO::getV).average(); - //后△t测点平均值 - Date finalAverageEndTime = averageEndTime; - OptionalDouble endAverage = apiPointValueDTOS.stream().filter(e -> e.getT().after(finalAverageMiddleTime) && !e.getT().after(finalAverageEndTime)).mapToDouble(ApiPointValueDTO::getV).average(); - if (startAverage.isPresent() && endAverage.isPresent()) { - double averageGapValue = startAverage.getAsDouble() - endAverage.getAsDouble(); - // 均值差,大于等于触发值则进行调整 - if (Double.valueOf(Math.abs(averageGapValue)).compareTo(configEntity.getTriggerValue()) >= 0) { - // 计算调整值 并跳出循环 - adjustValue = AutoAdjustValueRuleEnum.getAdjustValue(configEntity.getAdjustValueRule(), apiPointValueDTOS); - log.info("计算调整值:" + adjustValue + ",均值差:" + averageGapValue + ",pointNo:" + pointInfo.getPointNo() + ",pointName:" + pointInfo.getPointName() + ",averageStartTime:" + averageStartTime + ",averageMiddleTime:" + averageMiddleTime + ",averageEndTime:" + averageEndTime); - break; + while (!slopeEndTime.after(endTime)) { + //计算斜率 + //△t开始时间测点值 + Date finalSlopeStartTime = slopeStartTime; + Optional<ApiPointValueDTO> startOptional = apiPointValueDTOS.stream().filter(apiPointValueDTO -> apiPointValueDTO.getT().equals(finalSlopeStartTime)).findFirst(); + //△t结束时间测点值 + Date finalSlopeEndTime = slopeEndTime; + Optional<ApiPointValueDTO> endOptional = apiPointValueDTOS.stream().filter(e -> e.getT().equals(finalSlopeEndTime)).findFirst(); + if (startOptional.isPresent() && endOptional.isPresent()) { + ApiPointValueDTO startPointValue = startOptional.get(); + ApiPointValueDTO endPointValue = endOptional.get(); + // 计算斜率 + double slope = BigDecimal.valueOf(endPointValue.getV() - startPointValue.getV()).divide(BigDecimal.valueOf(configEntity.getT())).doubleValue(); + // 斜率大于等于触发值则进行调整 + if (Double.valueOf(Math.abs(slope)).compareTo(configEntity.getTriggerValue()) >= 0) { + // 计算调整值 并跳出循环 + adjustValue = AutoAdjustValueRuleEnum.getAdjustValue(configEntity.getAdjustValueRule(), apiPointValueDTOS); + log.info("计算调整值:" + adjustValue + ",斜率:" + slope + ",pointNo:" + pointInfo.getPointNo() + ",pointName:" + pointInfo.getPointName() + ",slopeStartTime:" + slopeStartTime + ",slopeEndTime:" + slopeEndTime); + break; + } + log.info("斜率不满足条件,斜率:" + slope); + } + // 下一个△t + slopeStartTime = slopeCalendar.getTime(); + slopeCalendar.add(Calendar.MINUTE,configEntity.getT()); + slopeEndTime = slopeCalendar.getTime(); } - log.info("均值差不满足条件,均值差:" + averageGapValue); - } + break; + case AVERAGE_GAP: + // 计算每两个△t的平均差,任意一个大于触发值则认为该区间有调整 + Calendar averageCalendar = Calendar.getInstance(); + averageCalendar.setTime(startTime); + Date averageStartTime = averageCalendar.getTime(); + averageCalendar.add(Calendar.MINUTE,configEntity.getT()); + Date averageMiddleTime = averageCalendar.getTime(); + averageCalendar.add(Calendar.MINUTE,configEntity.getT()); + Date averageEndTime = averageCalendar.getTime(); - // 下一个△t - averageStartTime = averageMiddleTime; - averageMiddleTime = averageEndTime; - averageCalendar.add(Calendar.MINUTE,configEntity.getT()); - averageEndTime = averageCalendar.getTime(); + if (averageEndTime.after(endTime)) { + log.info("影响用户[" + pointInfo.getPointName() + "]调整失败原因:△t设置过大,△t*2大于模型预测长度 * 预测粒度。△t:" + configEntity.getT()); + continue; + } + while (!averageEndTime.after(endTime)) { + //计算均值差 + //前△t测点平均值 + Date finalAverageStartTime = averageStartTime; + Date finalAverageMiddleTime = averageMiddleTime; + OptionalDouble startAverage = apiPointValueDTOS.stream().filter(e -> e.getT().after(finalAverageStartTime) && !e.getT().after(finalAverageMiddleTime)).mapToDouble(ApiPointValueDTO::getV).average(); + //后△t测点平均值 + Date finalAverageEndTime = averageEndTime; + OptionalDouble endAverage = apiPointValueDTOS.stream().filter(e -> e.getT().after(finalAverageMiddleTime) && !e.getT().after(finalAverageEndTime)).mapToDouble(ApiPointValueDTO::getV).average(); + if (startAverage.isPresent() && endAverage.isPresent()) { + double averageGapValue = startAverage.getAsDouble() - endAverage.getAsDouble(); + // 均值差,大于等于触发值则进行调整 + if (Double.valueOf(Math.abs(averageGapValue)).compareTo(configEntity.getTriggerValue()) >= 0) { + // 计算调整值 并跳出循环 + adjustValue = AutoAdjustValueRuleEnum.getAdjustValue(configEntity.getAdjustValueRule(), apiPointValueDTOS); + log.info("计算调整值:" + adjustValue + ",均值差:" + averageGapValue + ",pointNo:" + pointInfo.getPointNo() + ",pointName:" + pointInfo.getPointName() + ",averageStartTime:" + averageStartTime + ",averageMiddleTime:" + averageMiddleTime + ",averageEndTime:" + averageEndTime); + break; + } + log.info("均值差不满足条件,均值差:" + averageGapValue); + } + + // 下一个△t + averageStartTime = averageMiddleTime; + averageMiddleTime = averageEndTime; + averageCalendar.add(Calendar.MINUTE,configEntity.getT()); + averageEndTime = averageCalendar.getTime(); + } + break; + default: + log.info("影响用户[" + pointInfo.getPointName() + "]调整失败原因:未知触发规则,triggerRule" + configEntity.getTriggerRule()); + continue; } - break; - default: - log.info("自动调整失败原因:未知触发规则,triggerRule" + configEntity.getTriggerRule()); - return false; - } - if (adjustValue == null) { - log.info("自动调整失败原因:未达到触发条件"); - return false; + if (adjustValue == null) { + log.info("影响用户[" + pointInfo.getPointName() + "]调整失败原因:未达到触发条件"); + continue; + } + + // 调整系数 + adjustValue = adjustValue * configEntity.getAdjustCoefficient(); + // 调整方向 + adjustValue = adjustValue * configEntity.getAdjustDirection(); + // 累加到最终调整值 + finalAdjustValue += adjustValue; + } + // 执行调整 + if (finalAdjustValue.equals(0.0)) { + log.info("自动调整失败原因:finalAdjustValue为0,outputId:" + outputId + ",configCode:" + configCode); + continue; + } + List<InfluxModelResultPOJO> lastList = new ArrayList<>(); + for (InfluxModelResultVO resultVO : influxModelResult) { + InfluxModelResultLastSimPOJO adjustPojo = new InfluxModelResultLastSimPOJO(); + // 设置新的调整值 + adjustPojo.setValue(Double.parseDouble(resultVO.getValue().toString()) + finalAdjustValue); + adjustPojo.setTimestamp(resultVO.getTimestamp()); + adjustPojo.setOutPutId(outputId); + lastList.add(adjustPojo); + } + // 相同时间直接覆盖旧值 + influxDBService.asyncWriteModelResults(lastList); + log.info("t+l自动调整。configCode:" + configCode + ",adjustValue:" + finalAdjustValue + ",itemNo:" + item.getItemNo() + ",itemName:" + item.getItemName() + ",outputId:" + outputId + ",adjustTime:" + adjustStartTime); } - // 调整系数 - adjustValue = adjustValue * configEntity.getAdjustCoefficient(); - // 调整方向 - adjustValue = adjustValue * configEntity.getAdjustDirection(); - - - List<InfluxModelResultPOJO> lastList = new ArrayList<>(); - for (InfluxModelResultVO resultVO : influxModelResult) { - InfluxModelResultLastSimPOJO adjustPojo = new InfluxModelResultLastSimPOJO(); - // 设置新的调整值 - adjustPojo.setValue(Double.parseDouble(resultVO.getValue().toString()) + adjustValue); - adjustPojo.setTimestamp(resultVO.getTimestamp()); - adjustPojo.setOutPutId(configEntity.getOutputId()); - lastList.add(adjustPojo); - } - // 相同时间直接覆盖旧值 - influxDBService.asyncWriteModelResults(lastList); - log.info("t+l自动调整。configCode:" + configCode + ",adjustValue:" + adjustValue + ",itemNo:" + item.getItemNo() + ",itemName" + item.getItemName() + ",outputId" + configEntity.getOutputId() + ",adjustTime:" + adjustStartTime); return true; } } \ No newline at end of file -- Gitblit v1.9.3