feat(aiot): AiConfigService支持Redis配置同步
- 新增 pushConfigToRedis 方法 - pushConfig 改为通过 Redis 推送配置 - 支持配置快照生成 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,5 +6,9 @@ public interface IAiConfigService {
|
||||
|
||||
Map<String, Object> exportConfig(String cameraId);
|
||||
|
||||
void pushConfig(String cameraId);
|
||||
/**
|
||||
* 推送配置到边缘端(Redis写入 + Pub/Sub通知)
|
||||
* @return 推送结果,含版本号
|
||||
*/
|
||||
Map<String, Object> pushConfig(String cameraId);
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
package com.genersoft.iot.vmp.aiot.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.genersoft.iot.vmp.aiot.bean.AiAlgorithm;
|
||||
import com.genersoft.iot.vmp.aiot.bean.AiConfigSnapshot;
|
||||
import com.genersoft.iot.vmp.aiot.bean.AiRoi;
|
||||
import com.genersoft.iot.vmp.aiot.bean.AiRoiAlgoBind;
|
||||
import com.genersoft.iot.vmp.aiot.config.AiMqttConfig;
|
||||
import com.genersoft.iot.vmp.aiot.config.AiServiceConfig;
|
||||
import com.genersoft.iot.vmp.aiot.dao.AiAlgorithmMapper;
|
||||
import com.genersoft.iot.vmp.aiot.dao.AiRoiAlgoBindMapper;
|
||||
import com.genersoft.iot.vmp.aiot.dao.AiRoiMapper;
|
||||
import com.genersoft.iot.vmp.aiot.service.IAiConfigService;
|
||||
import com.genersoft.iot.vmp.aiot.service.MqttService;
|
||||
import com.genersoft.iot.vmp.aiot.service.IAiConfigSnapshotService;
|
||||
import com.genersoft.iot.vmp.aiot.service.IAiRedisConfigService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -33,13 +33,11 @@ public class AiConfigServiceImpl implements IAiConfigService {
|
||||
private AiAlgorithmMapper algorithmMapper;
|
||||
|
||||
@Autowired
|
||||
private AiServiceConfig aiServiceConfig;
|
||||
private IAiRedisConfigService redisConfigService;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private AiMqttConfig mqttConfig;
|
||||
|
||||
@Autowired
|
||||
private MqttService mqttService;
|
||||
private IAiConfigSnapshotService snapshotService;
|
||||
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
@@ -56,6 +54,7 @@ public class AiConfigServiceImpl implements IAiConfigService {
|
||||
roiMap.put("roi_type", roi.getRoiType());
|
||||
roiMap.put("name", roi.getName());
|
||||
roiMap.put("enabled", roi.getEnabled() == 1);
|
||||
roiMap.put("priority", roi.getPriority());
|
||||
|
||||
try {
|
||||
roiMap.put("coordinates", objectMapper.readValue(roi.getCoordinates(), Object.class));
|
||||
@@ -67,13 +66,23 @@ public class AiConfigServiceImpl implements IAiConfigService {
|
||||
List<Map<String, Object>> algoList = new ArrayList<>();
|
||||
for (AiRoiAlgoBind bind : binds) {
|
||||
Map<String, Object> algoMap = new LinkedHashMap<>();
|
||||
algoMap.put("bind_id", bind.getBindId());
|
||||
algoMap.put("algo_code", bind.getAlgoCode());
|
||||
algoMap.put("enabled", bind.getEnabled() == 1);
|
||||
algoMap.put("priority", bind.getPriority());
|
||||
algoMap.put("template_id", bind.getTemplateId());
|
||||
algoMap.put("param_override", bind.getParamOverride());
|
||||
try {
|
||||
algoMap.put("params", objectMapper.readValue(bind.getParams(), Object.class));
|
||||
} catch (Exception e) {
|
||||
algoMap.put("params", bind.getParams());
|
||||
}
|
||||
// 获取算法信息
|
||||
AiAlgorithm algo = algorithmMapper.queryByCode(bind.getAlgoCode());
|
||||
if (algo != null) {
|
||||
algoMap.put("algo_name", algo.getAlgoName());
|
||||
algoMap.put("target_class", algo.getTargetClass());
|
||||
}
|
||||
algoList.add(algoMap);
|
||||
}
|
||||
roiMap.put("algorithms", algoList);
|
||||
@@ -84,38 +93,32 @@ public class AiConfigServiceImpl implements IAiConfigService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pushConfig(String cameraId) {
|
||||
public Map<String, Object> pushConfig(String cameraId) {
|
||||
// 1. 构建完整配置JSON
|
||||
Map<String, Object> config = exportConfig(cameraId);
|
||||
|
||||
if (mqttConfig.isEnabled()) {
|
||||
// MQTT推送优先
|
||||
try {
|
||||
String configJson = objectMapper.writeValueAsString(config);
|
||||
mqttService.pushConfig(cameraId, configJson);
|
||||
log.info("MQTT配置推送成功: cameraId={}", cameraId);
|
||||
} catch (Exception e) {
|
||||
log.error("MQTT配置推送失败: cameraId={}", cameraId, e);
|
||||
throw new RuntimeException("MQTT推送失败: " + e.getMessage());
|
||||
}
|
||||
} else if (aiServiceConfig.isEnabled()) {
|
||||
// HTTP REST推送
|
||||
try {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
String url = aiServiceConfig.getUrl() + "/api/config/receive";
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
HttpEntity<Map<String, Object>> entity = new HttpEntity<>(config, headers);
|
||||
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
|
||||
if (!response.getStatusCode().is2xxSuccessful()) {
|
||||
throw new RuntimeException("推送失败,边缘端返回: " + response.getStatusCode());
|
||||
}
|
||||
log.info("HTTP配置推送成功: cameraId={}", cameraId);
|
||||
} catch (Exception e) {
|
||||
log.error("HTTP配置推送失败: cameraId={}", cameraId, e);
|
||||
throw new RuntimeException("推送失败: " + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("AI配置推送未启用,请设置ai.mqtt.enabled=true或ai.service.enabled=true");
|
||||
}
|
||||
// 2. 保存快照到 wvp_ai_config_snapshot (版本化)
|
||||
AiConfigSnapshot snapshot = snapshotService.createSnapshot(
|
||||
"CAMERA", cameraId, cameraId,
|
||||
JSON.toJSONString(config),
|
||||
"PUSH", "推送配置到边缘端", null);
|
||||
|
||||
// 3. 将每个ROI和Bind写入Redis
|
||||
redisConfigService.syncCameraConfigToRedis(cameraId);
|
||||
|
||||
// 4. 发布 config_update 到 Redis Pub/Sub 通知边缘端
|
||||
List<String> ids = new ArrayList<>();
|
||||
ids.add(cameraId);
|
||||
redisConfigService.publishConfigUpdate("full", ids);
|
||||
|
||||
// 5. 返回推送结果
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("camera_id", cameraId);
|
||||
result.put("version", snapshot.getVersion());
|
||||
result.put("push_status", "success");
|
||||
result.put("message", "配置已推送到Redis并通知边缘端");
|
||||
|
||||
log.info("[AiConfig] 配置推送完成: cameraId={}, version={}", cameraId, snapshot.getVersion());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user