Browse Source

1、修复dataResult保存

dev
3067418132@qq.com 3 weeks ago
parent
commit
a3e2751933
  1. 2
      user-service/src/main/java/com/mh/user/mapper/DeviceInstallMapper.java
  2. 174
      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

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

@ -307,7 +307,7 @@ public interface DeviceInstallMapper extends BaseMapper<DeviceInstallEntity> {
@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,
@Param("deviceType") String deviceType,
@Param("buildingId") String buildingId,

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

@ -46,6 +46,10 @@ public class DataResultServiceImpl implements DataResultService {
private static final double ELEC_DAY_VALUE = 1000;
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
public void saveDataResult(DataResultEntity dataResultEntity) {
if (dataResultEntity == null) {
@ -63,7 +67,7 @@ public class DataResultServiceImpl implements DataResultService {
Date formattedDate = formatToFiveMinuteInterval(dataResultEntity.getCurDate());
dataResultEntity.setCurDate(formattedDate);
// 从安装表获取设备信息
// 从安装表获取设备信息(使用最新数据)
DeviceInstallEntity deviceInstallEntity = deviceInstallMapper.selectDevice(
dataResultEntity.getDeviceAddr(),
dataResultEntity.getDeviceType(),
@ -87,8 +91,31 @@ public class DataResultServiceImpl implements DataResultService {
double maxIncrement = isElectricMeter ? ELEC_MAX_INCREMENT : OTHER_MAX_INCREMENT;
dayValue = isElectricMeter ? ELEC_DAY_VALUE : OTHER_DAY_VALUE;
// 检查增量是否异常
if (dataResultEntity.getCurValue() - lastValueFromInstall > maxIncrement) {
// 检查当前值是否有效(防止0值或负值)
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={}",
dataResultEntity.getCurValue(), lastValueFromInstall, dataResultEntity.getDeviceAddr());
return;
@ -118,11 +145,14 @@ public class DataResultServiceImpl implements DataResultService {
shouldSave = validateAndSaveData(newData, calcValue, dayValue, days, true);
// if (shouldSave) {
// lastValue = newData.getLastValue();
// }
} else {
// 修改现有记录
// 修改现有记录 - 重新查询最新数据避免并发问题
DeviceInstallEntity latestDeviceInstall = deviceInstallMapper.selectDevice(
dataResultEntity.getDeviceAddr(),
dataResultEntity.getDeviceType(),
dataResultEntity.getBuildingId());
if (latestDeviceInstall != null) {
DataResultEntity existingData = dataResultMapper.selectDataResult(
curDateStr,
dataResultEntity.getDeviceAddr(),
@ -131,40 +161,65 @@ public class DataResultServiceImpl implements DataResultService {
if (existingData != null) {
double lastValue = existingData.getLastValue();
calcValue = (dataResultEntity.getCurValue() - lastValue) * ratio;
calcValue = formatDouble(calcValue);
// 验证lastValue有效性
if (lastValue <= 0) {
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(calcValue);
existingData.setCalcValue(updateCalcValue);
Date lastDate = existingData.getLastDate();
int days = (int) ExchangeStringUtil.daysBetween(formattedDate, lastDate);
shouldSave = validateAndSaveData(existingData, calcValue, dayValue, days, false);
shouldSave = validateAndSaveData(existingData, updateCalcValue, dayValue, days, false);
}
}
}
// 更新安装表中的lastValue和lastDate
// 只有在数据验证通过时才更新安装表中的lastValue和lastDate
if (shouldSave) {
deviceInstallMapper.updateLastValue(
deviceInstallEntity.getId(),
String.valueOf(dataResultEntity.getCurValue()),
currentDate);
}
// 第一次采集时初始化initValue
if (initValue == 0) {
deviceInstallMapper.updateLastValue(
deviceInstallEntity.getId(),
String.valueOf(dataResultEntity.getCurValue()),
currentDate);
// 第一次采集时初始化initValue(必须在更新lastValue成功后)
if (initValue == 0 || initValue < 0) {
deviceInstallMapper.updateInitValue(
dataResultEntity.getDeviceAddr(),
dataResultEntity.getDeviceType(),
dataResultEntity.getBuildingId(),
String.valueOf(dataResultEntity.getCurValue()),
deviceInstallEntity.getId());
logger.info("saveDataResult: initialized initValue for deviceAddr={}, initValue={}",
dataResultEntity.getDeviceAddr(), dataResultEntity.getCurValue());
}
}
} catch (Exception e) {
@ -201,12 +256,29 @@ public class DataResultServiceImpl implements DataResultService {
dataResultEntity.getBuildingId());
double lastValue;
boolean isRollover = false;
if (lastData != null) {
data.setLastDate(lastData.getCurDate());
data.setLastValue(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 {
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();
if (lastDate == null) {
lastDate = new Date();
@ -215,8 +287,32 @@ public class DataResultServiceImpl implements DataResultService {
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);
// 验证计算值(翻转时允许较大的正值)
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);
return data;
@ -231,11 +327,44 @@ public class DataResultServiceImpl implements DataResultService {
double dayValue,
int days,
boolean isNew) {
// 验证calcValue有效性
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;
}
// 检测是否为翻转情况(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 (isNew) {
dataResultMapper.saveDataResult(dataResultEntity);
@ -248,7 +377,8 @@ public class DataResultServiceImpl implements DataResultService {
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;
}

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();
if (Double.parseDouble(dataStr)-deviceInstallEntity.getLastValue()>1000 || Double.parseDouble(dataStr)-deviceInstallEntity.getLastValue()<0) {
dataStr = String.valueOf(deviceInstallEntity.getLastValue());
}
// if (Double.parseDouble(dataStr)-deviceInstallEntity.getLastValue()>1000 || Double.parseDouble(dataStr)-deviceInstallEntity.getLastValue()<0) {
// dataStr = String.valueOf(deviceInstallEntity.getLastValue());
// }
log.info("电表表号:{},电表读数:{}", deviceInstallEntity.getDeviceAddr(), dataStr);
try {
DataResultEntity dataResultEntity = new DataResultEntity();

Loading…
Cancel
Save