fix: 盐度设置,功能优化,打印日志。
This commit is contained in:
@@ -2100,16 +2100,23 @@ public class IotController extends BaseController {
|
|||||||
|
|
||||||
private boolean cachePendingSolarSalinity(Device device, Double salinityCompensation) {
|
private boolean cachePendingSolarSalinity(Device device, Double salinityCompensation) {
|
||||||
try {
|
try {
|
||||||
String key = DeviceDataHandler.PENDING_SOLAR_SALINITY_KEY_PREFIX + device.getSerialNum();
|
|
||||||
Map<String, Object> cacheValue = new java.util.HashMap<>();
|
Map<String, Object> cacheValue = new java.util.HashMap<>();
|
||||||
cacheValue.put("deviceId", device.getId());
|
cacheValue.put("deviceId", device.getId());
|
||||||
cacheValue.put("iotId", device.getIotId());
|
cacheValue.put("iotId", device.getIotId());
|
||||||
cacheValue.put("serialNum", device.getSerialNum());
|
cacheValue.put("serialNum", device.getSerialNum());
|
||||||
cacheValue.put("salinityCompensation", salinityCompensation);
|
cacheValue.put("salinityCompensation", salinityCompensation);
|
||||||
cacheValue.put("updatedAt", System.currentTimeMillis());
|
cacheValue.put("updatedAt", System.currentTimeMillis());
|
||||||
com.intc.common.redis.utils.RedisUtils.setCacheObject(key, cn.hutool.json.JSONUtil.toJsonStr(cacheValue), Duration.ofDays(7));
|
String cacheJson = cn.hutool.json.JSONUtil.toJsonStr(cacheValue);
|
||||||
log.info("太阳能网控盐度已缓存,等待上线补发: deviceId={}, serialNum={}, salinityCompensation={}",
|
java.util.List<String> cacheKeys = buildPendingSolarSalinityKeys(device);
|
||||||
device.getId(), device.getSerialNum(), salinityCompensation);
|
if (cacheKeys.isEmpty()) {
|
||||||
|
log.warn("太阳能网控盐度缓存失败: deviceId={}, serialNum和iotId均为空", device.getId());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (String key : cacheKeys) {
|
||||||
|
com.intc.common.redis.utils.RedisUtils.setCacheObject(key, cacheJson, Duration.ofDays(7));
|
||||||
|
}
|
||||||
|
log.info("太阳能网控盐度已缓存,等待上线补发: deviceId={}, serialNum={}, iotId={}, cacheKeys={}, salinityCompensation={}",
|
||||||
|
device.getId(), device.getSerialNum(), device.getIotId(), cacheKeys, salinityCompensation);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("缓存太阳能网控盐度失败: deviceId={}, serialNum={}, err={}",
|
log.error("缓存太阳能网控盐度失败: deviceId={}, serialNum={}, err={}",
|
||||||
@@ -2133,6 +2140,23 @@ public class IotController extends BaseController {
|
|||||||
com.intc.common.redis.utils.RedisUtils.deleteObject(DeviceDataHandler.PENDING_SOLAR_SALINITY_KEY_PREFIX + serialNum);
|
com.intc.common.redis.utils.RedisUtils.deleteObject(DeviceDataHandler.PENDING_SOLAR_SALINITY_KEY_PREFIX + serialNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private java.util.List<String> buildPendingSolarSalinityKeys(Device device) {
|
||||||
|
java.util.List<String> keys = new java.util.ArrayList<>();
|
||||||
|
addPendingSolarSalinityKey(keys, device.getSerialNum());
|
||||||
|
addPendingSolarSalinityKey(keys, device.getIotId());
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPendingSolarSalinityKey(java.util.List<String> keys, String cacheName) {
|
||||||
|
if (cacheName == null || cacheName.isBlank()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String key = DeviceDataHandler.PENDING_SOLAR_SALINITY_KEY_PREFIX + cacheName;
|
||||||
|
if (!keys.contains(key)) {
|
||||||
|
keys.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改设备输入电压类型
|
* 修改设备输入电压类型
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ import java.util.Map;
|
|||||||
public class DeviceDataHandler {
|
public class DeviceDataHandler {
|
||||||
|
|
||||||
public static final String PENDING_SOLAR_SALINITY_KEY_PREFIX = "device:pending:solar:salinity:";
|
public static final String PENDING_SOLAR_SALINITY_KEY_PREFIX = "device:pending:solar:salinity:";
|
||||||
|
private static final int DEVICE_TYPE_SOLAR_CONTROLLER = 3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TDengine 服务,用于存储设备时序数据
|
* TDengine 服务,用于存储设备时序数据
|
||||||
@@ -240,6 +241,12 @@ public class DeviceDataHandler {
|
|||||||
handleSensorErrorCode(deviceName, params);
|
handleSensorErrorCode(deviceName, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 太阳能网控在线窗口很短,先处理盐度设定值,再尽快补发缓存盐度。
|
||||||
|
// if (params != null) {
|
||||||
|
// handleSalinitySet(deviceName, params);
|
||||||
|
// }
|
||||||
|
// flushPendingSolarSalinity(deviceName, "属性上报");
|
||||||
|
|
||||||
if (params != null && params.size() > 0) {
|
if (params != null && params.size() > 0) {
|
||||||
try {
|
try {
|
||||||
// 如果是控制器,需要区分处理
|
// 如果是控制器,需要区分处理
|
||||||
@@ -298,11 +305,6 @@ public class DeviceDataHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理 salinitySet(盐度补偿设定值):同步到设备表,不入 TDengine
|
|
||||||
if (params != null) {
|
|
||||||
handleSalinitySet(deviceName, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查是否触发报警
|
// 检查是否触发报警
|
||||||
if (params != null && sensorData != null) {
|
if (params != null && sensorData != null) {
|
||||||
checkAndTriggerAlarm(productKey, deviceName, sensorData);
|
checkAndTriggerAlarm(productKey, deviceName, sensorData);
|
||||||
@@ -957,22 +959,33 @@ public class DeviceDataHandler {
|
|||||||
log.info("[离线告警] 设备已上线,取消离线告警: {}", deviceName);
|
log.info("[离线告警] 设备已上线,取消离线告警: {}", deviceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
flushPendingSolarSalinity(deviceName);
|
flushPendingSolarSalinity(deviceName, "生命周期上线");
|
||||||
|
|
||||||
// 同步更新 Device.warnCode,清除离线和休眠标志位
|
// 同步更新 Device.warnCode,清除离线和休眠标志位
|
||||||
setDeviceWarnCodeBit(deviceName, DefineDeviceWarnCode.DeviceOffline, false);
|
setDeviceWarnCodeBit(deviceName, DefineDeviceWarnCode.DeviceOffline, false);
|
||||||
setDeviceWarnCodeBit(deviceName, DefineDeviceWarnCode.DeviceSleeping, false);
|
setDeviceWarnCodeBit(deviceName, DefineDeviceWarnCode.DeviceSleeping, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void flushPendingSolarSalinity(String deviceName) {
|
private void flushPendingSolarSalinity(String deviceName, String trigger) {
|
||||||
String redisKey = PENDING_SOLAR_SALINITY_KEY_PREFIX + deviceName;
|
Device device = findDeviceByOnlineName(deviceName);
|
||||||
Object rawPending = RedisUtils.getCacheObject(redisKey);
|
if (device == null) {
|
||||||
if (rawPending == null) {
|
log.debug("[太阳能盐度] 上线设备未绑定,跳过补发: deviceName={}", deviceName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!Integer.valueOf(DEVICE_TYPE_SOLAR_CONTROLLER).equals(device.getDeviceType())) {
|
||||||
|
log.debug("[太阳能盐度] 非太阳能网控设备,跳过补发: deviceName={}, deviceId={}, deviceType={}",
|
||||||
|
deviceName, device.getId(), device.getDeviceType());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
JSONObject pending = JSONUtil.parseObj(rawPending);
|
PendingSolarSalinity pendingSalinity = findPendingSolarSalinity(deviceName, device);
|
||||||
|
if (pendingSalinity == null) {
|
||||||
|
logNoPendingSolarSalinity(trigger, deviceName, device);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject pending = JSONUtil.parseObj(pendingSalinity.rawPending);
|
||||||
Double salinityCompensation = pending.getDouble("salinityCompensation");
|
Double salinityCompensation = pending.getDouble("salinityCompensation");
|
||||||
String iotId = pending.getStr("iotId");
|
String iotId = pending.getStr("iotId");
|
||||||
Long deviceId = pending.getLong("deviceId");
|
Long deviceId = pending.getLong("deviceId");
|
||||||
@@ -981,12 +994,15 @@ public class DeviceDataHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.info("[太阳能盐度] 太阳能网控{},准备补发缓存盐度: deviceName={}, cacheKey={}, deviceId={}, salinityCompensation={}",
|
||||||
|
trigger, deviceName, pendingSalinity.redisKey, deviceId, salinityCompensation);
|
||||||
|
|
||||||
Map<String, Object> properties = new HashMap<>();
|
Map<String, Object> properties = new HashMap<>();
|
||||||
properties.put("salinitySet", salinityCompensation);
|
properties.put("salinitySet", salinityCompensation);
|
||||||
boolean success = iotCloudService.setProperty(iotId, properties, true, 2);
|
boolean success = iotCloudService.setProperty(iotId, properties, true, 2);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
log.warn("[太阳能盐度] 上线补发失败,保留缓存: deviceName={}, deviceId={}, salinityCompensation={}",
|
log.warn("[太阳能盐度] {}补发失败,保留缓存: deviceName={}, deviceId={}, salinityCompensation={}",
|
||||||
deviceName, deviceId, salinityCompensation);
|
trigger, deviceName, deviceId, salinityCompensation);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -995,15 +1011,92 @@ public class DeviceDataHandler {
|
|||||||
updateDevice.setSalinityCompensation(salinityCompensation);
|
updateDevice.setSalinityCompensation(salinityCompensation);
|
||||||
int updated = deviceMapper.updateById(updateDevice);
|
int updated = deviceMapper.updateById(updateDevice);
|
||||||
if (updated > 0) {
|
if (updated > 0) {
|
||||||
RedisUtils.deleteObject(redisKey);
|
clearPendingSolarSalinity(deviceName, device, pendingSalinity.redisKey);
|
||||||
log.info("[太阳能盐度] 上线补发成功并清除缓存: deviceName={}, deviceId={}, salinityCompensation={}",
|
log.info("[太阳能盐度] {}补发成功并清除缓存: deviceName={}, cacheKey={}, deviceId={}, salinityCompensation={}",
|
||||||
deviceName, deviceId, salinityCompensation);
|
trigger, deviceName, pendingSalinity.redisKey, deviceId, salinityCompensation);
|
||||||
} else {
|
} else {
|
||||||
log.warn("[太阳能盐度] 上线补发成功但设备表更新失败,保留缓存以便重试: deviceName={}, deviceId={}",
|
log.warn("[太阳能盐度] {}补发成功但设备表更新失败,保留缓存以便重试: deviceName={}, deviceId={}",
|
||||||
deviceName, deviceId);
|
trigger, deviceName, deviceId);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("[太阳能盐度] 上线补发异常: deviceName={}, err={}", deviceName, e.getMessage(), e);
|
log.error("[太阳能盐度] {}补发异常: deviceName={}, err={}", trigger, deviceName, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Device findDeviceByOnlineName(String deviceName) {
|
||||||
|
if (StrUtil.isBlank(deviceName)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return deviceMapper.selectOne(
|
||||||
|
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Device>()
|
||||||
|
.and(wrapper -> wrapper
|
||||||
|
.eq(Device::getSerialNum, deviceName)
|
||||||
|
.or()
|
||||||
|
.eq(Device::getIotId, deviceName)
|
||||||
|
)
|
||||||
|
.select(Device::getId, Device::getIotId, Device::getSerialNum, Device::getDeviceType)
|
||||||
|
.last("LIMIT 1")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PendingSolarSalinity findPendingSolarSalinity(String deviceName, Device device) {
|
||||||
|
List<String> cacheNames = new java.util.ArrayList<>();
|
||||||
|
addCacheName(cacheNames, deviceName);
|
||||||
|
addCacheName(cacheNames, device.getSerialNum());
|
||||||
|
addCacheName(cacheNames, device.getIotId());
|
||||||
|
|
||||||
|
for (String cacheName : cacheNames) {
|
||||||
|
String redisKey = PENDING_SOLAR_SALINITY_KEY_PREFIX + cacheName;
|
||||||
|
Object rawPending = RedisUtils.getCacheObject(redisKey);
|
||||||
|
if (rawPending != null) {
|
||||||
|
return new PendingSolarSalinity(redisKey, rawPending);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasPendingSolarSalinity(String deviceName, Device device) {
|
||||||
|
return findPendingSolarSalinity(deviceName, device) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logNoPendingSolarSalinity(String trigger, String deviceName, Device device) {
|
||||||
|
if ("生命周期上线".equals(trigger)) {
|
||||||
|
log.info("[太阳能盐度] 太阳能网控{},未找到待补发缓存: deviceName={}, deviceId={}, serialNum={}, iotId={}",
|
||||||
|
trigger, deviceName, device.getId(), device.getSerialNum(), device.getIotId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log.debug("[太阳能盐度] 太阳能网控{},未找到待补发缓存: deviceName={}, deviceId={}, serialNum={}, iotId={}",
|
||||||
|
trigger, deviceName, device.getId(), device.getSerialNum(), device.getIotId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addCacheName(List<String> cacheNames, String cacheName) {
|
||||||
|
if (StrUtil.isBlank(cacheName) || cacheNames.contains(cacheName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cacheNames.add(cacheName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearPendingSolarSalinity(String deviceName, Device device, String matchedRedisKey) {
|
||||||
|
RedisUtils.deleteObject(matchedRedisKey);
|
||||||
|
deletePendingSolarSalinityByName(deviceName);
|
||||||
|
deletePendingSolarSalinityByName(device.getSerialNum());
|
||||||
|
deletePendingSolarSalinityByName(device.getIotId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deletePendingSolarSalinityByName(String cacheName) {
|
||||||
|
if (StrUtil.isBlank(cacheName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RedisUtils.deleteObject(PENDING_SOLAR_SALINITY_KEY_PREFIX + cacheName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class PendingSolarSalinity {
|
||||||
|
private final String redisKey;
|
||||||
|
private final Object rawPending;
|
||||||
|
|
||||||
|
private PendingSolarSalinity(String redisKey, Object rawPending) {
|
||||||
|
this.redisKey = redisKey;
|
||||||
|
this.rawPending = rawPending;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2677,6 +2770,11 @@ public class DeviceDataHandler {
|
|||||||
log.debug("设备不存在,无法更新盐度补偿设定值: {}", deviceName);
|
log.debug("设备不存在,无法更新盐度补偿设定值: {}", deviceName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (hasPendingSolarSalinity(deviceName, device)) {
|
||||||
|
log.debug("[太阳能盐度] 存在待补发盐度,跳过设备旧salinitySet同步: deviceName={}, reportSalinitySet={}",
|
||||||
|
deviceName, salinitySet);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Device updateDevice = new Device();
|
Device updateDevice = new Device();
|
||||||
updateDevice.setId(device.getId());
|
updateDevice.setId(device.getId());
|
||||||
updateDevice.setSalinityCompensation(salinitySet);
|
updateDevice.setSalinityCompensation(salinitySet);
|
||||||
|
|||||||
Reference in New Issue
Block a user