diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/EXAController.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/EXAController.java index eee1249..e68dc1b 100644 --- a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/EXAController.java +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/exa/EXAController.java @@ -26,7 +26,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Tag(name = "预警诊断系统 - EXA测点管理") +@Tag(name = "EXA - EXA") @RestController @RequestMapping("/alert/exa") @Validated diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/instant/InstantController.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/instant/InstantController.java index 553aaea..3d03702 100644 --- a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/instant/InstantController.java +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/instant/InstantController.java @@ -99,7 +99,7 @@ public class InstantController { @Operation(summary = "创建模型实例") @PreAuthorize("@ss.hasPermission('run:instant:create')") public CommonResult> createInstant(@RequestBody InstantSaveReqVO createReqVO) throws IOException { - return success(instantService.createInstant(createReqVO, null)); + return success(instantService.createInstant(createReqVO)); } @DeleteMapping("/delete") diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/instant/vo/InstantPageReqVO.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/instant/vo/InstantPageReqVO.java index 7098d13..d0f0ba9 100644 --- a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/instant/vo/InstantPageReqVO.java +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/instant/vo/InstantPageReqVO.java @@ -24,6 +24,9 @@ public class InstantPageReqVO extends PageParam { @Schema(description = "模型名称", example = "yudao") private String mpName; + @Schema(description = "算法", example = "yudao") + private String algorithmId; + @Schema(description = "运行状态", example = "yudao") private String running; diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/instant/vo/InstantSaveReqVO.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/instant/vo/InstantSaveReqVO.java index c61c480..ee12c87 100644 --- a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/instant/vo/InstantSaveReqVO.java +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/instant/vo/InstantSaveReqVO.java @@ -26,6 +26,11 @@ public class InstantSaveReqVO extends InstantInfoVO { @DiffLogField(name = "模型编号") private Long modelId; + + @Schema(description = "算法编号(1-PCA;2-ANN)", requiredMode = Schema.RequiredMode.REQUIRED,example = "1") + @DiffLogField(name = "算法编号") + private Long algorithmId; + @Schema(description = "模型实例信息", requiredMode = Schema.RequiredMode.REQUIRED,example = "1") @DiffLogField(name = "模型实例信息") @JsonIgnore diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/instant/vo/pointInfo.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/instant/vo/pointInfo.java index 5429e73..66450e1 100644 --- a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/instant/vo/pointInfo.java +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/instant/vo/pointInfo.java @@ -19,6 +19,6 @@ public class pointInfo { private String unit; @JsonProperty(value="type") - @Schema(description = "类型(输入-false;输出-true;ANN-空)", example = "yudao") - private Object type; + @Schema(description = "ANN才有的字段---类型(输入-false;输出-true)", example = "yudao") + private Boolean type; } diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/model/vo/ModelRespVO.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/model/vo/ModelRespVO.java index 5ae42fe..a5874f4 100644 --- a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/model/vo/ModelRespVO.java +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/model/vo/ModelRespVO.java @@ -32,6 +32,13 @@ public class ModelRespVO { private String unitName; + /** + * 算法id + */ + + @Schema(description = "算法id", example = "yudao") + + private String algorithmId; /** * 算法名称 */ diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/model/vo/RunModelInfoVO.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/model/vo/RunModelInfoVO.java index 92536d2..cb4a3bc 100644 --- a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/model/vo/RunModelInfoVO.java +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/model/vo/RunModelInfoVO.java @@ -31,12 +31,15 @@ public class RunModelInfoVO { /// /// /// - @JsonProperty(value="Model_info") +// @JsonProperty(value="Model_info") - public Model_info_ch_instant Model_info; +// public Model_info_ch_instant Model_info; @JsonProperty(value="limit") public double limit; + @JsonProperty(value="pre_s") + public List pre_s; + } @Data @NoArgsConstructor diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/warn/vo/AlarmLevelRespVO.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/warn/vo/AlarmLevelRespVO.java new file mode 100644 index 0000000..0735104 --- /dev/null +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/warn/vo/AlarmLevelRespVO.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.module.alert.controller.admin.warn.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "运行中心 - 预警级别分页 返回结果 VO") +@Data +public class AlarmLevelRespVO { + @Schema(description = "级别id", example = "id") + private Long alarmLevel; + + @Schema(description = "报警级别名称", example = "id") + private String alarmLevelName; + +} diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/warn/vo/AlarmTrendRespVO.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/warn/vo/AlarmTrendRespVO.java new file mode 100644 index 0000000..3cc67d4 --- /dev/null +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/warn/vo/AlarmTrendRespVO.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.alert.controller.admin.warn.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +@Data +public class AlarmTrendRespVO { + @Schema(description = "实时历史值列表", example = "id") + private List> realTimeList; + + @Schema(description = "上限值列表", example = "id") + private List> upList; + + @Schema(description = "下限值列表", example = "id") + private List> lowList; + + @Schema(description = "告警值列表", example = "id") + private List> errorList; + + @Schema(description = "所有值列表", example = "id") + List>> valueList; + + @Schema(description = "标签列表", example = "id") + List tagList; + + @Schema(description = "光字牌名称", example = "id") + private String gzpName; + + + + + + + +} diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/warn/warnController.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/warn/warnController.java index 65678f6..d68eea4 100644 --- a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/warn/warnController.java +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/controller/admin/warn/warnController.java @@ -3,13 +3,16 @@ package cn.iocoder.yudao.module.alert.controller.admin.warn; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.alert.controller.admin.exa.vo.EXAHistoryReqVO; import cn.iocoder.yudao.module.alert.controller.admin.instant.vo.InstantPageReqVO; import cn.iocoder.yudao.module.alert.controller.admin.instant.vo.InstantRespVO; import cn.iocoder.yudao.module.alert.controller.admin.instant.vo.InstantSaveReqVO; +import cn.iocoder.yudao.module.alert.controller.admin.warn.vo.AlarmTrendRespVO; import cn.iocoder.yudao.module.alert.controller.admin.warn.vo.WarnPageReqVO; import cn.iocoder.yudao.module.alert.controller.admin.warn.vo.WarnRespVO; import cn.iocoder.yudao.module.alert.controller.admin.warn.vo.WarnSaveReqVO; import cn.iocoder.yudao.module.alert.dal.dataobject.instant.InstantDO; +import cn.iocoder.yudao.module.alert.dal.dataobject.warn.AlarmLevelDO; import cn.iocoder.yudao.module.alert.dal.dataobject.warn.WarnDO; import cn.iocoder.yudao.module.alert.service.instant.InstantService; import cn.iocoder.yudao.module.alert.service.warn.WarnService; @@ -21,9 +24,12 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.Comparator; +import java.util.List; + import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Tag(name = "运行中心 - 预警") +@Tag(name = "预警中心 - 预警") @RestController @RequestMapping("/alert/warn") @Validated @@ -64,4 +70,22 @@ public class warnController { warnService.updateWarn(updateReqVO); return success(true); } + + @GetMapping("/alarmlevel/list") + @Operation(summary = "获取告警级别列表", description = "用于前端的下拉选项") + public CommonResult> getAlarmLevelList() { +// versionReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = warnService.getAlarmLevelList(); + list.sort(Comparator.comparing(AlarmLevelDO::getAlarmLevel)); + return success(list); + } + + + @GetMapping("/alarm/trend") + @Operation(summary = "获取该条告警的趋势", description = "获取该条告警的趋势") + public CommonResult getAlarmTrend(@RequestParam("id") Long id, @Valid EXAHistoryReqVO exaHistoryReqVO) { +// versionReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + AlarmTrendRespVO alarmTrendRespVO = warnService.getAlarmTrend(id, exaHistoryReqVO); + return success(alarmTrendRespVO); + } } diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/dal/dataobject/warn/AlarmLevelDO.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/dal/dataobject/warn/AlarmLevelDO.java new file mode 100644 index 0000000..753fe4a --- /dev/null +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/dal/dataobject/warn/AlarmLevelDO.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.alert.dal.dataobject.warn; + +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@TableName(value = "alarm_level_cfg", autoResultMap = true) +@KeySequence("system_role_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +public class AlarmLevelDO { + + @TableId(value="alarm_level") + private Long alarmLevel; + + private String alarmLevelName; + +} diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/dal/mysql/instant/InstantMapper.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/dal/mysql/instant/InstantMapper.java index 5d2ac6a..ac819e3 100644 --- a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/dal/mysql/instant/InstantMapper.java +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/dal/mysql/instant/InstantMapper.java @@ -20,6 +20,7 @@ public interface InstantMapper extends BaseMapperX { .eqIfPresent(InstantDO::getUnitId,reqVO.getUnit()) .eqIfPresent(InstantDO::getSystemTypeId,reqVO.getType()) .eqIfPresent(InstantDO::getSystemId,reqVO.getSystem()) + .eqIfPresent(InstantDO::getAlgorithmId,reqVO.getAlgorithmId()) .orderByAsc(InstantDO::getMpId)); } diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/dal/mysql/warn/AlarmLevelMapper.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/dal/mysql/warn/AlarmLevelMapper.java new file mode 100644 index 0000000..d9a04c6 --- /dev/null +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/dal/mysql/warn/AlarmLevelMapper.java @@ -0,0 +1,13 @@ +package cn.iocoder.yudao.module.alert.dal.mysql.warn; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.alert.dal.dataobject.warn.AlarmLevelDO; +import cn.iocoder.yudao.module.alert.dal.dataobject.warn.WarnCalcDO; +import cn.iocoder.yudao.module.alert.dal.dataobject.warn.WarnDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface AlarmLevelMapper extends BaseMapperX { + +} diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/dal/mysql/warn/WarnMapper.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/dal/mysql/warn/WarnMapper.java index a8dadc6..fa570ce 100644 --- a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/dal/mysql/warn/WarnMapper.java +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/dal/mysql/warn/WarnMapper.java @@ -41,4 +41,8 @@ public interface WarnMapper extends BaseMapperX { .apply("TIMESTAMPDIFF(SECOND, create_time, NOW()) > time_duration_threshold") .orderByAsc(WarnDO::getWarnId)); } + + default WarnDO selectByWarnId(Long warnId) { + return selectOne(WarnDO::getWarnId, warnId); + } } diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/instant/InstantService.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/instant/InstantService.java index e7e88cc..1a97116 100644 --- a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/instant/InstantService.java +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/instant/InstantService.java @@ -49,10 +49,9 @@ public interface InstantService { * 创建实例 * * @param createReqVO 创建实例信息 - * @param type 实例类型--目前用不到 * @return 实例编号 */ - List createInstant(@Valid InstantSaveReqVO createReqVO, Integer type) throws IOException; + List createInstant(@Valid InstantSaveReqVO createReqVO) throws IOException; /** * 删除实例 * diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/instant/InstantServiceImpl.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/instant/InstantServiceImpl.java index 0fadd5f..4195df4 100644 --- a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/instant/InstantServiceImpl.java +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/instant/InstantServiceImpl.java @@ -37,6 +37,7 @@ import org.springframework.transaction.annotation.Transactional; import java.io.IOException; import java.util.*; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; @@ -72,11 +73,12 @@ public class InstantServiceImpl implements InstantService { //PCA回算的http请求地址 @Value("${PCA.calcurl}") private String PCA_CALC_URL; + @Override @Transactional(rollbackFor = Exception.class) @LogRecord(type = SYSTEM_INSTANT_TYPE, subType = SYSTEM_INSTANT_CREATE_SUB_TYPE, bizNo = "{{#role.id}}", success = SYSTEM_INSTANT_CREATE_SUCCESS) - public List createInstant(InstantSaveReqVO createReqVO, Integer type) throws IOException { + public List createInstant(InstantSaveReqVO createReqVO) throws IOException { try { // 1. 校验角色 @@ -85,6 +87,7 @@ public class InstantServiceImpl implements InstantService { String modelVersion = versionMapper.selectById(createReqVO.getModelVersionId()).getVersion(); createReqVO.setModelVersion(modelVersion); + //插入除instantInfo外的所有数据,获取到id // 2. 插入到数据库-status、visible默认值 InstantTableDO instant = BeanUtils.toBean(createReqVO, InstantTableDO.class) @@ -118,7 +121,9 @@ public class InstantServiceImpl implements InstantService { inputInfoList.add(pointInfoList.get(i).getPointId()); inputNameList.add(pointInfoList.get(i).getDescription()); unitList.add(pointInfoList.get(i).getUnit()); - if (Objects.isNull(pointInfoList.get(i).getType()) || pointInfoList.get(i).getType().equals("1")) { +// 如果pointInfoList.get(i)有type字段,或者createReqVO对象中的算法是PCA就加一些重构值、时间值、偏差值 + if (pointInfoList.get(i).getType() != null || Objects.equals(createReqVO.getAlgorithmId(), "1") + || createReqVO.getAlgorithmId().equals(1L)) { //构建重构值对象 outpoint = HEAD + "M" + String.format("%04d", insertId) + String.format("%04d", i + 1) + "R"; point = new Point(); @@ -162,12 +167,6 @@ public class InstantServiceImpl implements InstantService { point.setEngUnits(pointInfoList.get(i).getUnit()); point.setItemType(5); InstantPointList.add(point); - } else { - outpoint = ""; - outPointInfoList.add(outpoint); - timePointInfoList.add(outpoint); - biasPointInfoList.add(outpoint); - faultVariablePointList.add(outpoint); } } @@ -226,6 +225,7 @@ public class InstantServiceImpl implements InstantService { String ss = exaUtils.setPoint(EXA_IP, item); resultList.add(ss); } + //插入预警表 createWarn1(instant, createReqVO); log.info("模型实例创建成功,实例ID: {}", instant.getMpId()); return resultList; @@ -239,43 +239,77 @@ public class InstantServiceImpl implements InstantService { public void createWarn1(InstantTableDO instant, InstantSaveReqVO createReqVO) { try { - //调用预警表和评估报告表的mapper - // 从instant对象获取modelid和version字段 - Long modelId = instant.getModelId(); - String version = instant.getModelVersion(); - - // 调用reportMapper获取对应记录(假设存在selectByModelIdAndVersion方法) - ReportDO report = reportMapper.selectByModelIdAndVersion(modelId, version); - - // 如果report不为空且report字段不为空,则解析为Report类 - if (report != null && StrUtil.isNotBlank(report.getReport())) { - Report reportObj = JsonUtils.parseObject(report.getReport(), Report.class); - // 此处可根据业务需求处理解析后的Report对象(如后续预警逻辑) - // 循环getInputInfo构建并插入预警记录 - for (int j = 0; j < reportObj.getAssess().size(); j++) { - - + //如果createReqVO中算法是pca,则读取评估报告从而获取上下限;如果是ANN,则直接读取modelInfo中的上下限 + if (createReqVO.getAlgorithmId() == 2) { + String modelInfoStr = versionMapper.selectById(createReqVO.getModelVersionId()).getModelInfo(); + // 解析modelInfo为RunModelInfoVO类 + RunModelInfoVO modelInfo = JsonUtils.parseObject(modelInfoStr, RunModelInfoVO.class); + // 从modelInfo中获取上下限列表(ANN的上下限是存在模型中的,PCA是存在评估报告中的) + List pre_s = modelInfo.getPara().getPre_s(); + + //createReqVO.getOutPointInfo()已经是上一步筛选好的数据,筛选条件---type=true,如果是ANN就表示是输出,PCA是全部点 + // 遍历筛选后的输出点信息 + for (Integer i = 0; i < createReqVO.getOutPointInfo().size(); i++) { WarnSaveReqVO warnSaveReqVO = new WarnSaveReqVO(); // 设置预警ID(假设insertId为当前预警主记录ID) // warn.setId(insertId); //设置实例id warnSaveReqVO.setMpId(instant.getMpId()); warnSaveReqVO.setPointOrModel("point"); - - warnSaveReqVO.setPointId(createReqVO.getInputInfo().get(reportObj.getAssess().get(j).getIndex())); - warnSaveReqVO.setPointName(createReqVO.getInputName().get(reportObj.getAssess().get(j).getIndex())); - warnSaveReqVO.setGzpName(createReqVO.getInputName().get(reportObj.getAssess().get(j).getIndex())); - warnSaveReqVO.setEquation("[" + createReqVO.getBiasPointInfo().get(reportObj.getAssess().get(j).getIndex()) + "]>UPLIMIT or [" + createReqVO.getBiasPointInfo().get(reportObj.getAssess().get(j).getIndex()) + "]UPLIMIT or [" + createReqVO.getBiasPointInfo().get(i) + "]UPLIMIT or [" + createReqVO.getBiasPointInfo().get(reportObj.getAssess().get(j).getIndex()) + "] getAlarmLevelList(); + + + /** + * 获得报警趋势 + * + * @param id 预警编号 + * @return 报警趋势 + */ + AlarmTrendRespVO getAlarmTrend(Long id, EXAHistoryReqVO exaHistoryReqVO); + } diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/warn/WarnServiceImpl.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/warn/WarnServiceImpl.java index 3e9d9b7..a9e34bf 100644 --- a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/warn/WarnServiceImpl.java +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/service/warn/WarnServiceImpl.java @@ -3,14 +3,21 @@ package cn.iocoder.yudao.module.alert.service.warn; import cn.hutool.core.collection.CollectionUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.alert.controller.admin.exa.vo.EXAHistoryReqVO; import cn.iocoder.yudao.module.alert.controller.admin.instant.vo.InstantSaveReqVO; +import cn.iocoder.yudao.module.alert.controller.admin.model.vo.ModelVersionPageReqVO; +import cn.iocoder.yudao.module.alert.controller.admin.warn.vo.AlarmTrendRespVO; import cn.iocoder.yudao.module.alert.controller.admin.warn.vo.WarnPageReqVO; import cn.iocoder.yudao.module.alert.controller.admin.warn.vo.WarnRespVO; import cn.iocoder.yudao.module.alert.controller.admin.warn.vo.WarnSaveReqVO; import cn.iocoder.yudao.module.alert.dal.dataobject.instant.InstantDO; +import cn.iocoder.yudao.module.alert.dal.dataobject.model.ModelVersionDO; +import cn.iocoder.yudao.module.alert.dal.dataobject.warn.AlarmLevelDO; import cn.iocoder.yudao.module.alert.dal.dataobject.warn.WarnDO; import cn.iocoder.yudao.module.alert.dal.dataobject.warn.WarnTableDO; +import cn.iocoder.yudao.module.alert.dal.mysql.warn.AlarmLevelMapper; import cn.iocoder.yudao.module.alert.dal.mysql.warn.WarnMapper; import cn.iocoder.yudao.module.alert.dal.mysql.warn.WarnTableMapper; import cn.iocoder.yudao.module.alert.utils.EXAUtils; @@ -28,11 +35,15 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.CacheEvict; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.RequestParam; import java.io.IOException; import java.net.URISyntaxException; import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -50,6 +61,9 @@ public class WarnServiceImpl implements WarnService { private WarnMapper warnMapper; @Resource private WarnTableMapper warnTableMapper; + + @Resource + private AlarmLevelMapper alarmLevelMapper; @Value("${EXA.ip}") private String EXA_IP; @@ -232,4 +246,101 @@ public class WarnServiceImpl implements WarnService { return warn; } + @Override + public List getAlarmLevelList() { + return alarmLevelMapper.selectList(); + } + + @Override + public AlarmTrendRespVO getAlarmTrend(Long id,EXAHistoryReqVO exaHistoryReqVO) { + try { + // 1. 查询预警配置信息 + WarnDO warnDO = warnMapper.selectByWarnId(id); + if (warnDO == null) { + throw exception(WARN_NOT_EXISTS,"未找到预警配置信息,warnId: " + id); + } + + // 2. 提取必要参数 + String point = warnDO.getPointId(); + String outpoint = warnDO.getOutputPoint(); + String uplimit = warnDO.getUplimit(); + String lowlimit = warnDO.getLowlimit(); + + EXAUtils exaUtils = new EXAUtils(); + exaHistoryReqVO.setItemName(point); + // 3. 获取历史数据 + exaHistoryReqVO.setItemName("SYG1_10BBA20ECMS501"); + exaHistoryReqVO.setStartTime("2023-10-28 17:00:00"); + exaHistoryReqVO.setEndTime("2023-10-28 23:00:00"); + exaHistoryReqVO.setInterval(60L); + List> inputData = exaUtils.getHistory(EXA_IP, exaHistoryReqVO); + List> outputData = exaUtils.getHistory(EXA_IP, exaHistoryReqVO); + // 4. 数据校验 + if (inputData.isEmpty() || outputData.isEmpty()) { + throw exception(EXA_HISTORY_IS_EMPTY,"历史数据为空,point: " + point + ", outputPoint: " + outpoint); + } + + //直接深拷贝outputData + //上限值列表 + List> upList = new ArrayList<>(outputData.size()); + for (List inner : outputData) { + upList.add(new ArrayList<>(inner)); + } + //下限值列表 + List> lowList = new ArrayList<>(outputData.size()); + for (List inner : outputData) { + lowList.add(new ArrayList<>(inner)); + } + //告警值列表 + List> errorList = new ArrayList<>(outputData.size()); + for (List inner : outputData) { + errorList.add(new ArrayList<>(inner)); + } + + // 7. 数据处理:计算上下限、误差标记 + for (int i = 0; i < outputData.size(); i++) { + List inputRow = inputData.get(i); + List outputRow = outputData.get(i); + Double inputValue = inputRow.size() > 1 ? inputRow.get(1) : null; + Double outputValue = outputRow.size() > 1 ? outputRow.get(1) : null; + // 计算上下限 + double h = (outputValue != null ? outputValue : 0) + Double.parseDouble(uplimit); + double l = (outputValue != null ? outputValue : 0) + Double.parseDouble(lowlimit); + + // ⚠️ 分别拷贝 + List upRow = new ArrayList<>(outputRow); + upRow.set(1, h); + upList.set(i, upRow); + + List lowRow = new ArrayList<>(outputRow); + lowRow.set(1, l); + lowList.set(i, lowRow); + + List errorRow = new ArrayList<>(outputRow); + + // 误差标记(1表示异常,null表示正常) + if (inputValue != null && (inputValue < l || inputValue > h)) { + errorRow.set(1, 1.0); + } else { + errorRow.set(1, null); + } + errorList.set(i, errorRow); + } + + // 8. 组装结果对象 + AlarmTrendRespVO result = new AlarmTrendRespVO(); + result.setRealTimeList(inputData); + result.setUpList(upList); + result.setLowList(lowList); + result.setErrorList(errorList); + result.setGzpName(warnDO.getGzpName() + " " + warnDO.getUnit()); + result.setValueList(Arrays.asList(inputData, upList, lowList, errorList)); + result.setTagList(Arrays.asList("实时值", "上限值", "下限值", "告警值")); + return result; + + } catch (Exception e) { + log.error("getAlarmTrend error", e); + throw exception(ALARM_TREND_FAILED, "获取告警趋势失败: " + e.getMessage()); + } + } } diff --git a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/utils/EXAUtils.java b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/utils/EXAUtils.java index ee71aa7..17e9b80 100644 --- a/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/utils/EXAUtils.java +++ b/yudao-module-alert/yudao-module-alert-biz/src/main/java/cn/iocoder/yudao/module/alert/utils/EXAUtils.java @@ -185,6 +185,7 @@ public class EXAUtils { * @param exaHistoryReqVo 传入对象,点号、开始时间、结束时间 * itemName 单点号 * @return exa列表 + * [[1698369232000,0.0],[1698369332000,0.0],[1698369432000,0.0],[1698369532000,0.0],[1698369632000,0.0],[1698369732000,0.0],[1698369832000,0.0],[1698369932000,0.0],[1698370032000,0.0],[1698370132000,0.0],[1698370232000,0.0],[1698370332000,0.0],[1698370432000,0.0],[1698370532000,0.0],[1698370632000,0.0],[1698370732000,0.0],[1698370832000,0.0],[1698370932000,0.0]] */ public List> getHistory(String exaIp, EXAHistoryReqVO req) { List> result = Collections.emptyList(); diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java index d2fc284..da6f3c0 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java @@ -177,7 +177,12 @@ public interface ErrorCodeConstants { ErrorCode CALCULATE_ERROR = new ErrorCode(3_001_002, "模型实例计算失败,失败原因:({})"); // ========== 预警模块 4-001========== - ErrorCode WARN_NOT_EXISTS = new ErrorCode(4_001_000, "预警不存在"); + ErrorCode WARN_NOT_EXISTS = new ErrorCode(4_001_000, "预警信息不存在"); + + ErrorCode ALARM_TREND_FAILED=new ErrorCode(4_001_001, "预警趋势获取失败"); + + + ErrorCode Company_NOT_EXISTS = new ErrorCode(1_002_30_000,"集团不存在"); ErrorCode Company_NAME_DUPLICATE = new ErrorCode(1_002_31_000,"集团名称已存在"); @@ -195,5 +200,6 @@ public interface ErrorCodeConstants { ErrorCode EXA_POINT_IMPORT_LIST_IS_EMPTY = new ErrorCode(6_001_000, "导入EXA测点数据不能为空!"); ErrorCode EXA_POINT_IMPORT_FAILED = new ErrorCode(6_001_001, "导入EXA测点数据失败!失败测点:({})"); ErrorCode EXA_REAL_FAILED = new ErrorCode(6_001_002, "读取EXA测点实时数据失败!失败测点:({})"); + ErrorCode EXA_HISTORY_IS_EMPTY = new ErrorCode(6_001_003, "EXA测点历史数据获取失败!"); }