Browse Source

1、修复dataResult保存

dev
3067418132@qq.com 3 weeks ago
parent
commit
a3e2751933
  1. 12
      user-service/src/main/java/com/mh/user/mapper/DeviceInstallMapper.java
  2. 212
      user-service/src/main/java/com/mh/user/service/impl/DataResultServiceImpl.java
  3. 6
      user-service/src/main/java/com/mh/user/strategy/EleMeterStrategy.java

12
user-service/src/main/java/com/mh/user/mapper/DeviceInstallMapper.java

@ -307,12 +307,12 @@ public interface DeviceInstallMapper extends BaseMapper<DeviceInstallEntity> {
@Param("buildingId") String buildingId); @Param("buildingId") String buildingId);
//更新基表初始值 //更新基表初始值
@Update("update device_install set init_value=#{initValue} where id = #{id} ") @Update("update device_install set init_value=#{initValue} where id = #{id}")
void updateInitValue(@Param("deviceAddr") String deviceAddr, void updateInitValue(@Param("deviceAddr") String deviceAddr,
@Param("deviceType") String deviceType, @Param("deviceType") String deviceType,
@Param("buildingId") String buildingId, @Param("buildingId") String buildingId,
@Param("initValue") String initValue, @Param("initValue") String initValue,
@Param("id") Long id); @Param("id") Long id);
//查询最后一次采集时间 //查询最后一次采集时间
@Select("select last_date from device_install where device_type=#{deviceType} and device_addr=#{deviceAddr} and building_id=#{buildingId}") @Select("select last_date from device_install where device_type=#{deviceType} and device_addr=#{deviceAddr} and building_id=#{buildingId}")

212
user-service/src/main/java/com/mh/user/service/impl/DataResultServiceImpl.java

@ -45,6 +45,10 @@ public class DataResultServiceImpl implements DataResultService {
private static final double OTHER_MAX_INCREMENT = 300; private static final double OTHER_MAX_INCREMENT = 300;
private static final double ELEC_DAY_VALUE = 1000; private static final double ELEC_DAY_VALUE = 1000;
private static final double OTHER_DAY_VALUE = 100; private static final double OTHER_DAY_VALUE = 100;
// 仪表最大值常量(用于检测翻转)
private static final double METER_MAX_VALUE = 999999.99; // 常见仪表最大值
private static final double METER_ROLLOVER_THRESHOLD = 0.1; // 翻转后新值应该很小
@Override @Override
public void saveDataResult(DataResultEntity dataResultEntity) { public void saveDataResult(DataResultEntity dataResultEntity) {
@ -63,7 +67,7 @@ public class DataResultServiceImpl implements DataResultService {
Date formattedDate = formatToFiveMinuteInterval(dataResultEntity.getCurDate()); Date formattedDate = formatToFiveMinuteInterval(dataResultEntity.getCurDate());
dataResultEntity.setCurDate(formattedDate); dataResultEntity.setCurDate(formattedDate);
// 从安装表获取设备信息 // 从安装表获取设备信息(使用最新数据)
DeviceInstallEntity deviceInstallEntity = deviceInstallMapper.selectDevice( DeviceInstallEntity deviceInstallEntity = deviceInstallMapper.selectDevice(
dataResultEntity.getDeviceAddr(), dataResultEntity.getDeviceAddr(),
dataResultEntity.getDeviceType(), dataResultEntity.getDeviceType(),
@ -87,8 +91,31 @@ public class DataResultServiceImpl implements DataResultService {
double maxIncrement = isElectricMeter ? ELEC_MAX_INCREMENT : OTHER_MAX_INCREMENT; double maxIncrement = isElectricMeter ? ELEC_MAX_INCREMENT : OTHER_MAX_INCREMENT;
dayValue = isElectricMeter ? ELEC_DAY_VALUE : OTHER_DAY_VALUE; dayValue = isElectricMeter ? ELEC_DAY_VALUE : OTHER_DAY_VALUE;
// 检查增量是否异常 // 检查当前值是否有效(防止0值或负值)
if (dataResultEntity.getCurValue() - lastValueFromInstall > maxIncrement) { if (dataResultEntity.getCurValue() <= 0) {
logger.warn("saveDataResult: curValue is invalid (<=0), skip. curValue={}, deviceAddr={}",
dataResultEntity.getCurValue(), dataResultEntity.getDeviceAddr());
return;
}
// 检测仪表翻转(rollover):从最大值归零重新计数
boolean isRollover = false;
if (lastValueFromInstall > 0 && dataResultEntity.getCurValue() < lastValueFromInstall) {
// 判断是否为正常翻转:旧值接近最大值,新值很小
if (lastValueFromInstall >= (METER_MAX_VALUE * 0.9) && dataResultEntity.getCurValue() <= METER_ROLLOVER_THRESHOLD) {
isRollover = true;
logger.info("saveDataResult: detected meter rollover. lastValue={}, curValue={}, deviceAddr={}",
lastValueFromInstall, dataResultEntity.getCurValue(), dataResultEntity.getDeviceAddr());
} else {
// 非翻转情况,视为异常数据回退
logger.warn("saveDataResult: curValue less than lastValue (not rollover), skip. curValue={}, lastValue={}, deviceAddr={}",
dataResultEntity.getCurValue(), lastValueFromInstall, dataResultEntity.getDeviceAddr());
return;
}
}
// 检查增量是否异常(翻转时跳过此检查)
if (!isRollover && lastValueFromInstall > 0 && (dataResultEntity.getCurValue() - lastValueFromInstall) > maxIncrement) {
logger.info("saveDataResult: increment too large, skip. curValue={}, lastValue={}, deviceAddr={}", logger.info("saveDataResult: increment too large, skip. curValue={}, lastValue={}, deviceAddr={}",
dataResultEntity.getCurValue(), lastValueFromInstall, dataResultEntity.getDeviceAddr()); dataResultEntity.getCurValue(), lastValueFromInstall, dataResultEntity.getDeviceAddr());
return; return;
@ -118,53 +145,81 @@ public class DataResultServiceImpl implements DataResultService {
shouldSave = validateAndSaveData(newData, calcValue, dayValue, days, true); shouldSave = validateAndSaveData(newData, calcValue, dayValue, days, true);
// if (shouldSave) {
// lastValue = newData.getLastValue();
// }
} else { } else {
// 修改现有记录 // 修改现有记录 - 重新查询最新数据避免并发问题
DataResultEntity existingData = dataResultMapper.selectDataResult( DeviceInstallEntity latestDeviceInstall = deviceInstallMapper.selectDevice(
curDateStr,
dataResultEntity.getDeviceAddr(), dataResultEntity.getDeviceAddr(),
dataResultEntity.getDeviceType(), dataResultEntity.getDeviceType(),
dataResultEntity.getBuildingId()); dataResultEntity.getBuildingId());
if (existingData != null) { if (latestDeviceInstall != null) {
double lastValue = existingData.getLastValue(); DataResultEntity existingData = dataResultMapper.selectDataResult(
calcValue = (dataResultEntity.getCurValue() - lastValue) * ratio; curDateStr,
calcValue = formatDouble(calcValue); dataResultEntity.getDeviceAddr(),
dataResultEntity.getDeviceType(),
existingData.setCurDate(formattedDate); dataResultEntity.getBuildingId());
existingData.setCurValue(dataResultEntity.getCurValue());
existingData.setCalcValue(calcValue); if (existingData != null) {
double lastValue = existingData.getLastValue();
Date lastDate = existingData.getLastDate();
int days = (int) ExchangeStringUtil.daysBetween(formattedDate, lastDate); // 验证lastValue有效性
if (lastValue <= 0) {
shouldSave = validateAndSaveData(existingData, calcValue, dayValue, days, false); logger.warn("saveDataResult: existing lastValue is invalid, use device install lastValue. lastValue={}, deviceAddr={}",
lastValue, dataResultEntity.getDeviceAddr());
lastValue = latestDeviceInstall.getLastValue();
}
// 检测是否为仪表翻转
boolean isUpdateRollover = false;
if (dataResultEntity.getCurValue() < lastValue && lastValue >= (METER_MAX_VALUE * 0.9)) {
isUpdateRollover = true;
logger.info("saveDataResult: detected rollover in update. curValue={}, lastValue={}, deviceAddr={}",
dataResultEntity.getCurValue(), lastValue, dataResultEntity.getDeviceAddr());
}
double updateCalcValue;
if (isUpdateRollover) {
// 翻转情况:计算值 = (最大值 - 上次值 + 当前值) * 倍率
updateCalcValue = (METER_MAX_VALUE - lastValue + dataResultEntity.getCurValue()) * ratio;
logger.info("saveDataResult: calculated rollover value in update. ({} - {} + {}) * {} = {}",
METER_MAX_VALUE, lastValue, dataResultEntity.getCurValue(), ratio, updateCalcValue);
} else {
// 正常情况:计算值 = (当前值 - 上次值) * 倍率
updateCalcValue = (dataResultEntity.getCurValue() - lastValue) * ratio;
}
updateCalcValue = formatDouble(updateCalcValue);
existingData.setCurDate(formattedDate);
existingData.setCurValue(dataResultEntity.getCurValue());
existingData.setCalcValue(updateCalcValue);
Date lastDate = existingData.getLastDate();
int days = (int) ExchangeStringUtil.daysBetween(formattedDate, lastDate);
shouldSave = validateAndSaveData(existingData, updateCalcValue, dayValue, days, false);
}
} }
} }
// 更新安装表中的lastValue和lastDate // 只有在数据验证通过时才更新安装表中的lastValue和lastDate
if (shouldSave) { if (shouldSave) {
deviceInstallMapper.updateLastValue( deviceInstallMapper.updateLastValue(
deviceInstallEntity.getId(), deviceInstallEntity.getId(),
String.valueOf(dataResultEntity.getCurValue()), String.valueOf(dataResultEntity.getCurValue()),
currentDate); currentDate);
}
// 第一次采集时初始化initValue(必须在更新lastValue成功后)
// 第一次采集时初始化initValue if (initValue == 0 || initValue < 0) {
if (initValue == 0) { deviceInstallMapper.updateInitValue(
deviceInstallMapper.updateLastValue( dataResultEntity.getDeviceAddr(),
deviceInstallEntity.getId(), dataResultEntity.getDeviceType(),
String.valueOf(dataResultEntity.getCurValue()), dataResultEntity.getBuildingId(),
currentDate); String.valueOf(dataResultEntity.getCurValue()),
deviceInstallMapper.updateInitValue( deviceInstallEntity.getId());
dataResultEntity.getDeviceAddr(), logger.info("saveDataResult: initialized initValue for deviceAddr={}, initValue={}",
dataResultEntity.getDeviceType(), dataResultEntity.getDeviceAddr(), dataResultEntity.getCurValue());
dataResultEntity.getBuildingId(), }
String.valueOf(dataResultEntity.getCurValue()),
deviceInstallEntity.getId());
} }
} catch (Exception e) { } catch (Exception e) {
@ -201,12 +256,29 @@ public class DataResultServiceImpl implements DataResultService {
dataResultEntity.getBuildingId()); dataResultEntity.getBuildingId());
double lastValue; double lastValue;
boolean isRollover = false;
if (lastData != null) { if (lastData != null) {
data.setLastDate(lastData.getCurDate()); data.setLastDate(lastData.getCurDate());
data.setLastValue(lastData.getCurValue()); data.setLastValue(lastData.getCurValue());
lastValue = lastData.getCurValue(); lastValue = lastData.getCurValue();
// 验证lastValue的有效性
if (lastValue <= 0) {
logger.warn("createNewDataResult: lastData has invalid lastValue={}, use device install value",
lastValue);
lastValue = deviceInstallEntity.getLastValue();
}
} else { } else {
lastValue = deviceInstallEntity.getLastValue(); lastValue = deviceInstallEntity.getLastValue();
// 如果deviceInstall的lastValue也无效,使用当前值作为初始值
if (lastValue <= 0) {
logger.info("createNewDataResult: device install lastValue is invalid, use curValue as initial. curValue={}, deviceAddr={}",
dataResultEntity.getCurValue(), dataResultEntity.getDeviceAddr());
lastValue = dataResultEntity.getCurValue();
}
Date lastDate = deviceInstallEntity.getLastDate(); Date lastDate = deviceInstallEntity.getLastDate();
if (lastDate == null) { if (lastDate == null) {
lastDate = new Date(); lastDate = new Date();
@ -215,8 +287,32 @@ public class DataResultServiceImpl implements DataResultService {
data.setLastValue(lastValue); data.setLastValue(lastValue);
} }
double calcValue = (dataResultEntity.getCurValue() - lastValue) * ratio; // 检测是否为仪表翻转(当前值 < 上次值)
if (dataResultEntity.getCurValue() < lastValue && lastValue >= (METER_MAX_VALUE * 0.9)) {
isRollover = true;
logger.info("createNewDataResult: detected rollover in calculation. curValue={}, lastValue={}, deviceAddr={}",
dataResultEntity.getCurValue(), lastValue, dataResultEntity.getDeviceAddr());
}
double calcValue;
if (isRollover) {
// 翻转情况:计算值 = (最大值 - 上次值 + 当前值) * 倍率
calcValue = (METER_MAX_VALUE - lastValue + dataResultEntity.getCurValue()) * ratio;
logger.info("createNewDataResult: calculated rollover value. ({} - {} + {}) * {} = {}",
METER_MAX_VALUE, lastValue, dataResultEntity.getCurValue(), ratio, calcValue);
} else {
// 正常情况:计算值 = (当前值 - 上次值) * 倍率
calcValue = (dataResultEntity.getCurValue() - lastValue) * ratio;
}
calcValue = formatDouble(calcValue); calcValue = formatDouble(calcValue);
// 验证计算值(翻转时允许较大的正值)
if (calcValue < 0) {
logger.warn("createNewDataResult: calcValue is negative after calculation. curValue={}, lastValue={}, ratio={}, calcValue={}, isRollover={}",
dataResultEntity.getCurValue(), lastValue, ratio, calcValue, isRollover);
}
data.setCalcValue(calcValue); data.setCalcValue(calcValue);
return data; return data;
@ -231,11 +327,44 @@ public class DataResultServiceImpl implements DataResultService {
double dayValue, double dayValue,
int days, int days,
boolean isNew) { boolean isNew) {
// 验证calcValue有效性
if (calcValue < 0) { if (calcValue < 0) {
logger.warn("calcValue is negative: {}", calcValue); logger.warn("validateAndSaveData: calcValue is negative: {}, deviceAddr={}",
calcValue, dataResultEntity.getDeviceAddr());
return false;
}
// 验证curValue有效性
if (dataResultEntity.getCurValue() <= 0) {
logger.warn("validateAndSaveData: curValue is invalid: {}, deviceAddr={}",
dataResultEntity.getCurValue(), dataResultEntity.getDeviceAddr());
return false; return false;
} }
// 检测是否为翻转情况(calcValue可能很大)
boolean isRollover = calcValue > dayValue * 10; // 如果计算值超过日值的10倍,可能是翻转
if (isRollover) {
// 翻转情况:只要calcValue为正且合理,就允许保存
// 这里假设翻转后的用量不会超过30天的正常用量
double maxRolloverValue = dayValue * 30;
if (calcValue <= maxRolloverValue) {
if (isNew) {
dataResultMapper.saveDataResult(dataResultEntity);
} else {
dataResultMapper.updateDataResult(dataResultEntity);
}
logger.info("validateAndSaveData: saved rollover data. calcValue={}, dayValue={}, deviceAddr={}",
calcValue, dayValue, dataResultEntity.getDeviceAddr());
return true;
} else {
logger.warn("validateAndSaveData: rollover calcValue too large: calcValue={}, maxValue={}, deviceAddr={}",
calcValue, maxRolloverValue, dataResultEntity.getDeviceAddr());
return false;
}
}
// 正常情况的验证逻辑
if (calcValue <= dayValue) { if (calcValue <= dayValue) {
if (isNew) { if (isNew) {
dataResultMapper.saveDataResult(dataResultEntity); dataResultMapper.saveDataResult(dataResultEntity);
@ -248,7 +377,8 @@ public class DataResultServiceImpl implements DataResultService {
return true; return true;
} }
logger.warn("calcValue exceeds dayValue: calcValue={}, dayValue={}, days={}", calcValue, dayValue, days); logger.warn("validateAndSaveData: calcValue exceeds dayValue: calcValue={}, dayValue={}, days={}, deviceAddr={}",
calcValue, dayValue, days, dataResultEntity.getDeviceAddr());
return false; return false;
} }

6
user-service/src/main/java/com/mh/user/strategy/EleMeterStrategy.java

@ -179,9 +179,9 @@ public class EleMeterStrategy implements DeviceStrategy {
// 将数值按指定小数位数格式化 // 将数值按指定小数位数格式化
dataStr = originalValue.divide(power, 2, RoundingMode.HALF_UP).toString(); dataStr = originalValue.divide(power, 2, RoundingMode.HALF_UP).toString();
if (Double.parseDouble(dataStr)-deviceInstallEntity.getLastValue()>1000 || Double.parseDouble(dataStr)-deviceInstallEntity.getLastValue()<0) { // if (Double.parseDouble(dataStr)-deviceInstallEntity.getLastValue()>1000 || Double.parseDouble(dataStr)-deviceInstallEntity.getLastValue()<0) {
dataStr = String.valueOf(deviceInstallEntity.getLastValue()); // dataStr = String.valueOf(deviceInstallEntity.getLastValue());
} // }
log.info("电表表号:{},电表读数:{}", deviceInstallEntity.getDeviceAddr(), dataStr); log.info("电表表号:{},电表读数:{}", deviceInstallEntity.getDeviceAddr(), dataStr);
try { try {
DataResultEntity dataResultEntity = new DataResultEntity(); DataResultEntity dataResultEntity = new DataResultEntity();

Loading…
Cancel
Save