feat(ems): 重构物联网数据阈值告警功能

- 新增精确的字段级阈值检查逻辑,支持多字段设备的独立规则
- 优化异常记录的生成和去重策略,确保数据准确性
- 重构原有告警任务,提高系统性能和可维护性
- 增加设备类型和监测字段的业务规则校验
boardTest
zch 1 month ago
parent 51ffee7cc0
commit 1f7dc3452b

@ -64,8 +64,22 @@ public interface EmsRecordAlarmDataMapper
/**
*
*
* @param fiveMinutesAgo
* @param startTime
* @return
*/
public List<EmsRecordAlarmData> selectRecentAlarmData(@Param("fiveMinutesAgo") Date fiveMinutesAgo);
public List<EmsRecordAlarmData> selectRecentAlarmData(@Param("startTime") Date startTime);
/**
*
*
* @param monitorId ID
* @param cause
* @param startTime
* @param endTime
* @return
*/
public Integer checkDuplicateAlarmData(@Param("monitorId") String monitorId,
@Param("cause") String cause,
@Param("startTime") Date startTime,
@Param("endTime") Date endTime);
}

@ -124,4 +124,14 @@ public interface RecordIotenvInstantMapper
*/
public List<RecordIotenvInstant> selectLatestRecordsFromTable(@Param("tableName") String tableName,
@Param("limit") int limit);
/**
*
*
* @param tableName
* @param startTime
* @return
*/
public List<RecordIotenvInstant> selectRecentRecordsFromTable(@Param("tableName") String tableName,
@Param("startTime") java.util.Date startTime);
}

@ -64,21 +64,10 @@ public interface IEmsRecordAlarmDataService
* @param objIds
* @return
*/
public int handleExceptionsAlarmData(Long[] objIds);
int handleExceptionsAlarmData(Long[] objIds);
/**
*
*
*/
public void collectDeviceAlarmsTask();
/**
*
*/
public void exceedDnbThresholdAlarmsTask();
/**
*
*/
public void hourlyConsumptionAlarmsTask();
void checkIotenvThresholdAlarms();
}

@ -1,25 +1,22 @@
package com.os.ems.record.service.impl;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import com.os.common.utils.DateUtils;
import com.os.common.utils.StringUtils;
import com.os.ems.base.domain.EmsBaseCollectDeviceInfo;
import com.os.ems.base.domain.EmsBaseMonitorThreshold;
import com.os.ems.base.mapper.EmsBaseCollectDeviceInfoMapper;
import com.os.ems.base.mapper.EmsBaseMonitorThresholdMapper;
import com.os.ems.base.domain.EmsBaseEnergyType;
import com.os.ems.base.domain.EmsBaseMonitorInfo;
import com.os.ems.base.mapper.EmsBaseEnergyTypeMapper;
import com.os.ems.base.mapper.EmsBaseMonitorInfoMapper;
import com.os.ems.record.domain.EmsRecordAlarmRule;
import com.os.ems.record.domain.EmsRecordDnbInstant;
import com.os.ems.record.domain.RecordIotenvInstant;
import com.os.ems.record.mapper.EmsRecordAlarmRuleMapper;
import com.os.ems.record.mapper.EmsRecordDnbInstantMapper;
import com.os.ems.report.domain.EmsReportPointDnb;
import com.os.ems.report.mapper.EmsReportPointDnbMapper;
import com.os.ems.record.mapper.RecordIotenvInstantMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import com.os.ems.record.mapper.EmsRecordAlarmDataMapper;
import com.os.ems.record.domain.EmsRecordAlarmData;
@ -42,16 +39,38 @@ public class EmsRecordAlarmDataServiceImpl implements IEmsRecordAlarmDataService
private EmsRecordAlarmRuleMapper emsRecordAlarmRuleMapper;
@Autowired
private EmsBaseCollectDeviceInfoMapper emsBaseCollectDeviceInfoMapper;
private RecordIotenvInstantMapper recordIotenvInstantMapper;
@Autowired
private EmsRecordDnbInstantMapper emsRecordDnbInstantMapper;
private EmsBaseMonitorInfoMapper emsBaseMonitorInfoMapper;
@Autowired
private EmsBaseMonitorThresholdMapper emsBaseMonitorThresholdMapper;
private EmsBaseEnergyTypeMapper emsBaseEnergyTypeMapper;
@Autowired
private EmsReportPointDnbMapper emsReportPointDnbMapper;
/**
*
*
*/
private static final Map<Long, String> MONITOR_FIELD_TO_DB_FIELD = new HashMap<>();
private static final Map<Long, String> MONITOR_FIELD_TO_DESC = new HashMap<>();
static {
// 字典值 -> 数据库字段名映射
MONITOR_FIELD_TO_DB_FIELD.put(0L, "temperature"); // 温度
MONITOR_FIELD_TO_DB_FIELD.put(1L, "humidity"); // 湿度
MONITOR_FIELD_TO_DB_FIELD.put(2L, "vibration_speed"); // 振动-速度(mm/s)
MONITOR_FIELD_TO_DB_FIELD.put(3L, "vibration_displacement"); // 振动-位移(um)
MONITOR_FIELD_TO_DB_FIELD.put(4L, "vibration_acceleration"); // 振动-加速度(g)
MONITOR_FIELD_TO_DB_FIELD.put(5L, "vibration_temp"); // 振动-温度(℃)
// 字典值 -> 中文描述映射用于异常记录的cause字段
MONITOR_FIELD_TO_DESC.put(0L, "温度");
MONITOR_FIELD_TO_DESC.put(1L, "湿度");
MONITOR_FIELD_TO_DESC.put(2L, "振动-速度(mm/s)");
MONITOR_FIELD_TO_DESC.put(3L, "振动-位移(um)");
MONITOR_FIELD_TO_DESC.put(4L, "振动-加速度(g)");
MONITOR_FIELD_TO_DESC.put(5L, "振动-温度(℃)");
}
/**
*
@ -141,172 +160,279 @@ public class EmsRecordAlarmDataServiceImpl implements IEmsRecordAlarmDataService
}
/**
*
*
*
*
*
* 1. monitor_field
* 2. 4
* 3. cause使
* 4. monitor_idmonitor_code
* 5.
*/
public void collectDeviceAlarmsTask() {
long minuteValue = 1000 * 60;
Date date = new Date();
EmsRecordAlarmRule alarmRule = new EmsRecordAlarmRule();
alarmRule.setTriggerRule(1L);
List<EmsRecordAlarmRule> alarmRules = emsRecordAlarmRuleMapper.selectEmsRecordAlarmRuleList(alarmRule);
if (alarmRules.size() > 0) {
minuteValue = alarmRules.get(0).getDeviceOfflineTime() * minuteValue;
} else {
return;
}
@Scheduled(cron = "0 */1 * * * ?") // 每分钟执行一次
@Override
public void checkIotenvThresholdAlarms() {
try {
// 1. 获取当天的分表名
SimpleDateFormat tableFormat = new SimpleDateFormat("yyyyMMdd");
String tableName = "record_iotenv_instant_" + tableFormat.format(new Date());
// 检查表是否存在
if (!checkTableExists(tableName)) {
System.out.println("当天分表不存在: " + tableName);
return;
}
// 2. 查询所有启用的告警规则trigger_rule=0 超过阈值)
EmsRecordAlarmRule queryRule = new EmsRecordAlarmRule();
queryRule.setTriggerRule(0L); // 0表示超过阈值
List<EmsRecordAlarmRule> alarmRules = emsRecordAlarmRuleMapper.selectEmsRecordAlarmRuleList(queryRule);
if (alarmRules.isEmpty()) {
System.out.println("没有启用的阈值告警规则");
return;
}
// 3. 按设备编码分组告警规则,每个设备可能有多个字段的规则
// 注意monitor_id字段存储的实际是monitor_code值与采集数据分表的monitorId保持一致
Map<String, List<EmsRecordAlarmRule>> rulesByMonitor = alarmRules.stream()
.filter(rule -> StringUtils.isNotEmpty(rule.getMonitorId()))
.collect(Collectors.groupingBy(EmsRecordAlarmRule::getMonitorId));
// 4. 只查询最近2分钟的数据确保每分钟执行时不重复处理
Date twoMinutesAgo = new Date(System.currentTimeMillis() - 2 * 60 * 1000);
List<RecordIotenvInstant> recentRecords = recordIotenvInstantMapper.selectRecentRecordsFromTable(tableName, twoMinutesAgo);
if (recentRecords.isEmpty()) {
System.out.println("当天分表最近2分钟无新数据: " + tableName);
return;
}
EmsBaseCollectDeviceInfo collectDeviceInfo = new EmsBaseCollectDeviceInfo();
collectDeviceInfo.setIsFlag("1");
List<EmsBaseCollectDeviceInfo> deviceInfoList = emsBaseCollectDeviceInfoMapper.selectEmsBaseCollectDeviceInfoList(collectDeviceInfo);
if (deviceInfoList.size() > 0) {
EmsRecordAlarmData recordAlarmData = new EmsRecordAlarmData();
recordAlarmData.setAlarmType(1L);
recordAlarmData.setAlarmStatus(1L);
List<EmsRecordAlarmData> alarmDataList = emsRecordAlarmDataMapper.selectEmsRecordAlarmDataList(recordAlarmData);
List<String> collectDeviceIdList = alarmDataList.stream().map(EmsRecordAlarmData::getCollectDeviceId).collect(Collectors.toList());
for (EmsBaseCollectDeviceInfo deviceInfo : deviceInfoList) {
if (collectDeviceIdList.contains(deviceInfo.getCollectDeviceId())) {
// 5. 获取所有相关设备信息(用于验证设备类型,确保规则合理性)
// 这里需要按monitor_code查询因为rulesByMonitor的key是monitor_code
Set<String> monitorCodes = rulesByMonitor.keySet();
List<EmsBaseMonitorInfo> monitorInfos = emsBaseMonitorInfoMapper.selectMonitorInfoByCodes(new ArrayList<>(monitorCodes));
Map<String, EmsBaseMonitorInfo> monitorInfoMap = monitorInfos.stream()
.collect(Collectors.toMap(EmsBaseMonitorInfo::getMonitorCode, m -> m));
// 6. 处理每条记录,基于精确的字段规则进行阈值检查
List<EmsRecordAlarmData> candidateAlarms = new ArrayList<>();
for (RecordIotenvInstant record : recentRecords) {
String monitorId = record.getMonitorId(); // 采集数据中的monitorId实际是monitor_code
List<EmsRecordAlarmRule> rules = rulesByMonitor.get(monitorId);
if (rules == null || rules.isEmpty()) {
continue;
}
if ((deviceInfo.getUpdateTime().getTime() + minuteValue) < date.getTime()) {
EmsRecordAlarmData alarmData = new EmsRecordAlarmData();
alarmData.setCollectDeviceId(deviceInfo.getCollectDeviceId());
alarmData.setCollectTime(new Date());
alarmData.setAlarmType(1L);
alarmData.setAlarmStatus(1L);
alarmData.setAlarmData("设备离线已超过" + alarmRules.get(0).getDeviceOfflineTime() + "分钟");
this.insertEmsRecordAlarmData(alarmData);
EmsBaseMonitorInfo monitorInfo = monitorInfoMap.get(monitorId);
if (monitorInfo == null) {
continue;
}
// 7. 遍历该设备的所有规则,每个规则对应一个具体的监测字段
for (EmsRecordAlarmRule rule : rules) {
// 检查规则的基本有效性
if (rule.getTriggerValue() == null || rule.getMonitorField() == null) {
continue;
}
// 验证监测字段是否符合设备类型(可选的业务校验)
if (!isValidMonitorFieldForDeviceType(rule.getMonitorField(), monitorInfo.getMonitorType())) {
System.out.println("警告:设备类型与监测字段不匹配 - 设备:" + monitorId +
", 设备类型:" + monitorInfo.getMonitorType() +
", 监测字段:" + rule.getMonitorField());
continue;
}
// 8. 根据规则的monitor_field精确检查对应的数据字段
BigDecimal threshold = rule.getTriggerValue();
BigDecimal actualValue = getFieldValue(record, rule.getMonitorField());
// 9. 阈值比较:实际值 > 阈值时触发异常
if (actualValue != null && actualValue.compareTo(threshold) > 0) {
EmsRecordAlarmData alarmData = createAlarmData(record, rule, actualValue.toString());
candidateAlarms.add(alarmData);
System.out.println("检测到阈值超标 - 设备:" + monitorId +
", 字段:" + MONITOR_FIELD_TO_DESC.get(rule.getMonitorField()) +
", 实际值:" + actualValue +
", 阈值:" + threshold +
", 采集时间:" + record.getCollectTime());
}
}
}
// 10. 使用严格的去重逻辑插入异常数据
if (!candidateAlarms.isEmpty()) {
int insertedCount = insertAlarmDataWithStrictDuplicateCheck(candidateAlarms);
System.out.println("严格去重后实际插入异常数据: " + insertedCount + " 条");
} else {
System.out.println("未检测到异常数据");
}
} catch (Exception e) {
System.err.println("阈值检查定时任务执行异常: " + e.getMessage());
e.printStackTrace();
}
}
/**
*
*
*
*
* @param record
* @param monitorField 01湿2-
* @return null
*/
public void exceedDnbThresholdAlarmsTask() {
EmsBaseMonitorThreshold monitorThreshold = new EmsBaseMonitorThreshold();
monitorThreshold.setMonitorType(2L);
List<EmsBaseMonitorThreshold> thresholdList = emsBaseMonitorThresholdMapper.selectEmsBaseMonitorThresholdList(monitorThreshold);
EmsRecordDnbInstant dnbInstant = new EmsRecordDnbInstant();
List<EmsRecordDnbInstant> dnbInstantList = emsRecordDnbInstantMapper.selectEmsRecordDnbInstantList(dnbInstant);
Map<String, String> thresholdMap = compareThresholdAndRecord(thresholdList, dnbInstantList);
//防止多次存入异常数据
EmsRecordAlarmData recordAlarmData = new EmsRecordAlarmData();
recordAlarmData.setAlarmType(0L);
recordAlarmData.setAlarmStatus(1L);
List<EmsRecordAlarmData> alarmDataList = emsRecordAlarmDataMapper.selectEmsRecordAlarmDataList(recordAlarmData);
List<String> monitorIdList = alarmDataList.stream().map(EmsRecordAlarmData::getMonitorId).collect(Collectors.toList());
for (String monitorId : thresholdMap.keySet()) {
if (monitorIdList.contains(monitorId)) {
continue;
}
EmsRecordAlarmData alarmData = new EmsRecordAlarmData();
alarmData.setMonitorId(monitorId);
alarmData.setCollectTime(new Date());
alarmData.setAlarmType(0L);
alarmData.setAlarmStatus(1L);
alarmData.setAlarmData(thresholdMap.get(monitorId));
this.insertEmsRecordAlarmData(alarmData);
private BigDecimal getFieldValue(RecordIotenvInstant record, Long monitorField) {
switch (monitorField.intValue()) {
case 0: // 温度
return record.getTemperature();
case 1: // 湿度
return record.getHumidity();
case 2: // 振动-速度(mm/s)
return record.getVibrationSpeed();
case 3: // 振动-位移(um)
return record.getVibrationDisplacement();
case 4: // 振动-加速度(g)
return record.getVibrationAcceleration();
case 5: // 振动-温度(℃)
return record.getVibrationTemp();
default:
System.out.println("未知的监测字段: " + monitorField);
return null;
}
}
/**
*
*
* @param baseDnbThresholds
* @param recordDnbInstants
* @return
*
*
*
* @param monitorField
* @param monitorType
* @return
*/
public Map<String, String> compareThresholdAndRecord(List<EmsBaseMonitorThreshold> baseDnbThresholds, List<EmsRecordDnbInstant> recordDnbInstants) {
Map<String, String> resultMap = new HashMap<>();
for (EmsRecordDnbInstant recordDnbInstant : recordDnbInstants) {
String monitorCode = recordDnbInstant.getMonitorCode();
EmsBaseMonitorThreshold baseDnbThreshold = null;
for (EmsBaseMonitorThreshold threshold : baseDnbThresholds) {
if (threshold.getMonitorCode().equals(monitorCode)) {
baseDnbThreshold = threshold;
break;
}
}
if (baseDnbThreshold != null) {
String reason = compare(recordDnbInstant, baseDnbThreshold);
if (reason != null) {
resultMap.put(monitorCode, reason);
}
}
private boolean isValidMonitorFieldForDeviceType(Long monitorField, Long monitorType) {
if (monitorField == null || monitorType == null) {
return false;
}
return resultMap;
}
private String compare(EmsRecordDnbInstant recordDnbInstant, EmsBaseMonitorThreshold baseDnbThreshold) {
if (StringUtils.isNull(recordDnbInstant.getIA())) {
return null;
// 温湿度设备(6)应该只能选择温度(0)或湿度(1)
if (monitorType == 6L) {
return monitorField == 0L || monitorField == 1L;
}
BigDecimal zero = new BigDecimal("0.00");
if (recordDnbInstant.getVA().compareTo(zero) == 0 || recordDnbInstant.getVB().compareTo(zero) == 0
|| recordDnbInstant.getVC().compareTo(zero) == 0) {
return "缺项报警";
// 振动设备(10)应该只能选择振动相关字段(2,3,4,5)
if (monitorType == 10L) {
return monitorField >= 2L && monitorField <= 5L;
}
if (recordDnbInstant.getIA().compareTo(baseDnbThreshold.getiAMax()) > 0) {
return "超过A相电流最大值";
// 纯温度设备(5)只能选择温度(0)
if (monitorType == 5L) {
return monitorField == 0L;
}
if (recordDnbInstant.getIB().compareTo(baseDnbThreshold.getiBMax()) > 0) {
return "超过B相电流最大值";
}
if (recordDnbInstant.getIC().compareTo(baseDnbThreshold.getiCMax()) > 0) {
return "超过C相电流最大值";
}
if (recordDnbInstant.getVA().compareTo(baseDnbThreshold.getvAMax()) > 0) {
return "超过A相电压最大值";
}
if (recordDnbInstant.getVB().compareTo(baseDnbThreshold.getvBMax()) > 0) {
return "超过B相电压最大值";
}
if (recordDnbInstant.getVC().compareTo(baseDnbThreshold.getvCMax()) > 0) {
return "超过C相电压最大值";
}
if (recordDnbInstant.getIA().compareTo(baseDnbThreshold.getiAMin()) < 0) {
return "小于A相电流最小值";
}
if (recordDnbInstant.getIB().compareTo(baseDnbThreshold.getiBMin()) < 0) {
return "小于B相电流最小值";
}
if (recordDnbInstant.getIC().compareTo(baseDnbThreshold.getiCMin()) < 0) {
return "小于C相电流最小值";
}
if (recordDnbInstant.getVA().compareTo(baseDnbThreshold.getvAMin()) < 0) {
return "小于A相电压最小值";
}
if (recordDnbInstant.getVB().compareTo(baseDnbThreshold.getvBMin()) < 0) {
return "小于B相电压最小值";
}
if (recordDnbInstant.getVC().compareTo(baseDnbThreshold.getvCMin()) < 0) {
return "小于C相电压最小值";
}
return null;
// 其他设备类型暂不支持字段级规则
return false;
}
/**
*
*
* 使cause
*
* @param record
* @param rule
* @param actualValue
* @return
*/
public void hourlyConsumptionAlarmsTask() {
EmsBaseMonitorThreshold monitorThreshold = new EmsBaseMonitorThreshold();
monitorThreshold.setMonitorType(2L);
List<EmsBaseMonitorThreshold> thresholdList = emsBaseMonitorThresholdMapper.selectEmsBaseMonitorThresholdList(monitorThreshold);
for (EmsBaseMonitorThreshold threshold : thresholdList) {
BigDecimal consumption = threshold.getHourConsumption();
if (consumption.equals(new BigDecimal(0))){
continue;
}
EmsReportPointDnb reportPointDnb = new EmsReportPointDnb();
reportPointDnb.setMonitorCode(threshold.getMonitorCode());
List<EmsReportPointDnb> dnbList = emsReportPointDnbMapper.selectEmsReportPointDnbList(reportPointDnb);
}
private EmsRecordAlarmData createAlarmData(RecordIotenvInstant record, EmsRecordAlarmRule rule, String actualValue) {
EmsRecordAlarmData alarmData = new EmsRecordAlarmData();
alarmData.setMonitorId(record.getMonitorId());
alarmData.setCollectTime(record.getCollectTime());
alarmData.setAlarmType(0L); // 0表示超过阈值
alarmData.setAlarmStatus(1L); // 1表示未处理
alarmData.setAlarmData(actualValue); // 记录实际超标数值
// 使用字典描述作为异常原因,更加友好
String fieldDesc = MONITOR_FIELD_TO_DESC.get(rule.getMonitorField());
alarmData.setCause(fieldDesc != null ? fieldDesc : "未知字段");
alarmData.setCreateTime(new Date());
return alarmData;
}
/**
* 使
* 30
*
*
* @param alarmDataList
* @return
*/
private int insertAlarmDataWithStrictDuplicateCheck(List<EmsRecordAlarmData> alarmDataList) {
int insertedCount = 0;
// 30分钟去重窗口前后各15分钟
long fifteenMinutesInMs = 15 * 60 * 1000;
for (EmsRecordAlarmData alarmData : alarmDataList) {
try {
// 为每条异常数据检查是否已存在重复记录
Date collectTime = alarmData.getCollectTime();
if (collectTime == null) {
continue; // 跳过没有采集时间的数据
}
// 构建30分钟的时间窗口
Date startTime = new Date(collectTime.getTime() - fifteenMinutesInMs);
Date endTime = new Date(collectTime.getTime() + fifteenMinutesInMs);
// 查询数据库是否已存在相同的异常记录
Integer existingCount = emsRecordAlarmDataMapper.checkDuplicateAlarmData(
alarmData.getMonitorId(),
alarmData.getCause(),
startTime,
endTime
);
// 如果不存在重复记录,则插入
if (existingCount == null || existingCount == 0) {
int result = insertEmsRecordAlarmData(alarmData);
if (result > 0) {
insertedCount++;
System.out.println("成功插入异常数据 - 设备:" + alarmData.getMonitorId() +
", 原因:" + alarmData.getCause() +
", 采集时间:" + alarmData.getCollectTime() +
", 数值:" + alarmData.getAlarmData());
}
} else {
System.out.println("跳过重复异常数据 - 设备:" + alarmData.getMonitorId() +
", 原因:" + alarmData.getCause() +
", 采集时间:" + alarmData.getCollectTime() +
", 30分钟内已存在 " + existingCount + " 条相同记录");
}
} catch (Exception e) {
System.err.println("插入异常数据时发生错误: " + e.getMessage());
e.printStackTrace();
}
}
return insertedCount;
}
/**
*
*
* @param tableName
* @return
*/
private boolean checkTableExists(String tableName) {
Map<String, Object> params = new HashMap<>();
params.put("tableName", tableName);
Integer count = recordIotenvInstantMapper.checkTableExists(params);
return count != null && count > 0;
}
}

@ -12,6 +12,8 @@ import com.os.common.constant.HttpStatus;
import com.os.common.core.page.TableDataInfo;
import com.os.common.exception.ServiceException;
import com.os.common.utils.bean.BeanUtils;
import com.os.ems.base.domain.EmsBaseMonitorInfo;
import com.os.ems.base.mapper.EmsBaseMonitorInfoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.os.ems.record.mapper.RecordIotenvInstantMapper;
@ -30,6 +32,9 @@ public class RecordIotenvInstantServiceImpl implements IRecordIotenvInstantServi
@Autowired
private RecordIotenvInstantMapper recordIotenvInstantMapper;
@Autowired
private EmsBaseMonitorInfoMapper emsBaseMonitorInfoMapper;
/**
*
*
@ -203,6 +208,18 @@ public class RecordIotenvInstantServiceImpl implements IRecordIotenvInstantServi
int offset = (pageNum - 1) * pageSize;
// 执行分页查询
List<RecordIotenvInstant> list = recordIotenvInstantMapper.selectFromTablesWithPage(tableNames, recordIotenvInstant, offset, pageSize);
//获取设备列表根据monitorId查询设备名称
// EmsBaseMonitorInfo baseMonitorInfo = new EmsBaseMonitorInfo();
// List<EmsBaseMonitorInfo> baseMonitorInfos = emsBaseMonitorInfoMapper.selectEmsBaseMonitorInfoList(baseMonitorInfo);
// // 将baseMonitorInfos中的monitorName字段添加到list中
// for (RecordIotenvInstant iotenvInstant : list) {
// for (EmsBaseMonitorInfo monitorInfo : baseMonitorInfos) {
// if (iotenvInstant.getMonitorId().equals(monitorInfo.getMonitorCode())){
// iotenvInstant.setMonitorName(monitorInfo.getMonitorName());
// }
// }
// }
TableDataInfo rspData = new TableDataInfo();
rspData.setCode(HttpStatus.SUCCESS);

@ -160,6 +160,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
FROM ems_record_alarm_data rad
WHERE rad.alarm_status = 1
AND rad.alarm_type = 0
AND rad.create_time >= #{fiveMinutesAgo}
AND rad.create_time >= #{startTime}
</select>
<!-- 检查特定条件的异常数据是否已存在(精确去重) -->
<select id="checkDuplicateAlarmData" resultType="java.lang.Integer">
SELECT COUNT(*)
FROM ems_record_alarm_data
WHERE monitor_id = #{monitorId}
AND cause = #{cause}
AND alarm_type = 0
AND alarm_status = 1
AND collect_time BETWEEN #{startTime} AND #{endTime}
</select>
</mapper>

@ -219,7 +219,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
t.collectTime, t.recodeTime,
ebmi.monitor_name
FROM ${tableName} t
left join ems_base_monitor_info ebmi on t.monitorId = ebmi.obj_id
left join ems_base_monitor_info ebmi on t.monitorId = ebmi.monitor_code
<where>
<if test="recordIotenvInstant.monitorId != null and recordIotenvInstant.monitorId != ''"> and monitorId = #{recordIotenvInstant.monitorId}</if>
<if test="recordIotenvInstant.temperature != null "> and temperature = #{recordIotenvInstant.temperature}</if>
@ -306,4 +306,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
LIMIT #{limit}
</select>
<!-- 从指定表查询指定时间之后的记录 -->
<select id="selectRecentRecordsFromTable" resultMap="RecordIotenvInstantResult">
SELECT objid, monitorId, temperature, humidity, illuminance, noise, concentration,
vibration_speed, vibration_displacement, vibration_acceleration, vibration_temp,
collectTime, recodeTime
FROM ${tableName}
WHERE recodeTime >= #{startTime}
ORDER BY recodeTime DESC
</select>
</mapper>
Loading…
Cancel
Save