|
@@ -299,6 +299,13 @@ public class GccHandler extends BaseDevHandler implements MqttMessageHandler {
|
|
|
*/
|
|
*/
|
|
|
private final Map<String, Map<String, String>> pendingAttrs = new ConcurrentHashMap<>();
|
|
private final Map<String, Map<String, String>> pendingAttrs = new ConcurrentHashMap<>();
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 已落库属性值内存快照(key = modelCode:objCode:attrKey):
|
|
|
|
|
+ * MQTT上报频率高但多数值无变化,落库前先与快照比对,仅变化时写库,减少MySQL压力;
|
|
|
|
|
+ * 每设备首次落库前从DB预取一次填充快照,避免重启后全量重写;快照标记key = seeded:modelCode:objCode
|
|
|
|
|
+ */
|
|
|
|
|
+ private final Map<String, String> flushedAttrCache = new ConcurrentHashMap<>();
|
|
|
|
|
+
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private IElecStoreService elecStoreService;
|
|
private IElecStoreService elecStoreService;
|
|
|
|
|
|
|
@@ -799,10 +806,21 @@ public class GccHandler extends BaseDevHandler implements MqttMessageHandler {
|
|
|
String modelCode = keys[0];
|
|
String modelCode = keys[0];
|
|
|
String objCode = keys[1];
|
|
String objCode = keys[1];
|
|
|
|
|
|
|
|
|
|
+ // 首次落库前预取DB现有值填充内存快照,之后仅变更时写库
|
|
|
|
|
+ ensureAttrCacheSeeded(modelCode, objCode);
|
|
|
|
|
+
|
|
|
for (Map.Entry<String, String> attr : entry.getValue().entrySet()) {
|
|
for (Map.Entry<String, String> attr : entry.getValue().entrySet()) {
|
|
|
|
|
+ String cacheKey = modelCode + ":" + objCode + ":" + attr.getKey();
|
|
|
|
|
+
|
|
|
|
|
+ // 值无变化不落库,减少无效REPLACE
|
|
|
|
|
+ if (StringUtils.equals(flushedAttrCache.get(cacheKey), attr.getValue())) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
try {
|
|
try {
|
|
|
objAttrValueService.mergeObjAttrValue(
|
|
objAttrValueService.mergeObjAttrValue(
|
|
|
new EmsObjAttrValue(objCode, modelCode, attr.getKey(), attr.getValue()));
|
|
new EmsObjAttrValue(objCode, modelCode, attr.getKey(), attr.getValue()));
|
|
|
|
|
+ flushedAttrCache.put(cacheKey, attr.getValue());
|
|
|
}
|
|
}
|
|
|
catch (Exception e) {
|
|
catch (Exception e) {
|
|
|
log.error("储能属性值落库失败 obj[{}] key[{}]", objCode, attr.getKey(), e);
|
|
log.error("储能属性值落库失败 obj[{}] key[{}]", objCode, attr.getKey(), e);
|
|
@@ -815,6 +833,32 @@ public class GccHandler extends BaseDevHandler implements MqttMessageHandler {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
|
|
+ * 确保设备属性内存快照已填充(每设备仅预取一次)
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param modelCode 设备模型
|
|
|
|
|
+ * @param objCode 对象代码
|
|
|
|
|
+ */
|
|
|
|
|
+ private void ensureAttrCacheSeeded(String modelCode, String objCode) {
|
|
|
|
|
+ String seedKey = "seeded:" + modelCode + ":" + objCode;
|
|
|
|
|
+ if (flushedAttrCache.containsKey(seedKey)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ List<EmsObjAttrValue> existList = objAttrValueService.selectByObjCode(modelCode, objCode);
|
|
|
|
|
+ for (EmsObjAttrValue value : existList) {
|
|
|
|
|
+ flushedAttrCache.putIfAbsent(modelCode + ":" + objCode + ":" + value.getAttrKey(),
|
|
|
|
|
+ value.getAttrValue());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (Exception e) {
|
|
|
|
|
+ log.warn("预取设备属性快照失败, 本轮全量写库, obj[{}]", objCode, e);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ flushedAttrCache.put(seedKey, "1");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
* 刷新当日充放电增量:电表当日正向/反向电能、一体机当日充电量/放电量,
|
|
* 刷新当日充放电增量:电表当日正向/反向电能、一体机当日充电量/放电量,
|
|
|
* 计算口径 = 当前累计值 - 当日零点基线快照,结果写入物模型属性值(下一周期落库)
|
|
* 计算口径 = 当前累计值 - 当日零点基线快照,结果写入物模型属性值(下一周期落库)
|
|
|
*/
|
|
*/
|