From 9881ce0814ad642646d9b76ad2caa70a0b966036 Mon Sep 17 00:00:00 2001
From: 潘志宝 <979469083@qq.com>
Date: 星期一, 26 五月 2025 16:15:16 +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 |  312 +++++++++++++++++++++++++++------------------------
 1 files changed, 164 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..9cda6d2 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,180 @@
     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());
+                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;
                 }
-                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;
+                // 过滤掉-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