优化:边缘配置流程——device_id 从摄像头继承 + 取消自动推送
1. resolveDeviceId 优先从 stream_proxy.edge_device_id 获取,不再硬编码默认设备 2. 删除 save/delete/bindAlgo/unbindAlgo/updateAlgoParams 中的自动推送 3. pushConfig 时自动修正 ROI 的 device_id 为摄像头实际绑定的边缘设备 4. StreamProxyMapper 新增 selectEdgeDeviceIdByCameraCode 查询
This commit is contained in:
@@ -225,10 +225,27 @@ public class AiConfigServiceImpl implements IAiConfigService {
|
|||||||
ids.add(cameraId);
|
ids.add(cameraId);
|
||||||
redisConfigService.publishConfigUpdate("full", ids);
|
redisConfigService.publishConfigUpdate("full", ids);
|
||||||
|
|
||||||
// 5. 写入设备聚合配置 + Stream 通知(新格式,对接 Edge config_sync)
|
// 5. 从摄像头配置获取正确的 edge_device_id,修正 ROI 表中的 device_id
|
||||||
String deviceId = roiMapper.queryDeviceIdByCameraId(cameraId);
|
String correctDeviceId = streamProxyMapper.selectEdgeDeviceIdByCameraCode(cameraId);
|
||||||
|
if (correctDeviceId != null && !correctDeviceId.isEmpty()) {
|
||||||
|
List<AiRoi> rois = roiMapper.queryByCameraId(cameraId);
|
||||||
|
for (AiRoi roi : rois) {
|
||||||
|
if (!correctDeviceId.equals(roi.getDeviceId())) {
|
||||||
|
String oldDeviceId = roi.getDeviceId();
|
||||||
|
roi.setDeviceId(correctDeviceId);
|
||||||
|
roiMapper.update(roi);
|
||||||
|
log.info("[AiConfig] 修正 ROI device_id: roi={}, {} → {}",
|
||||||
|
roi.getRoiId(), oldDeviceId, correctDeviceId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 写入设备聚合配置 + Stream 通知(新格式,对接 Edge config_sync)
|
||||||
|
String deviceId = correctDeviceId;
|
||||||
|
if (deviceId == null || deviceId.isEmpty()) {
|
||||||
|
deviceId = roiMapper.queryDeviceIdByCameraId(cameraId);
|
||||||
|
}
|
||||||
if (deviceId == null || deviceId.isEmpty()) {
|
if (deviceId == null || deviceId.isEmpty()) {
|
||||||
// 回退:从 edge 设备表获取默认设备
|
|
||||||
deviceId = getDefaultDeviceId();
|
deviceId = getDefaultDeviceId();
|
||||||
log.info("[AiConfig] 摄像头 {} 未关联设备,使用默认设备: {}", cameraId, deviceId);
|
log.info("[AiConfig] 摄像头 {} 未关联设备,使用默认设备: {}", cameraId, deviceId);
|
||||||
}
|
}
|
||||||
@@ -240,10 +257,10 @@ public class AiConfigServiceImpl implements IAiConfigService {
|
|||||||
log.warn("[AiConfig] 无法确定设备ID,跳过 Redis 聚合配置推送。请先注册边缘设备或为摄像头关联 device_id");
|
log.warn("[AiConfig] 无法确定设备ID,跳过 Redis 聚合配置推送。请先注册边缘设备或为摄像头关联 device_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. 本地调试:同步到 Edge HTTP 接口(保留原 Redis 流程)
|
// 7. 本地调试:同步到 Edge HTTP 接口(保留原 Redis 流程)
|
||||||
boolean httpSyncOk = pushConfigToLocalEdge(cameraId, config);
|
boolean httpSyncOk = pushConfigToLocalEdge(cameraId, config);
|
||||||
|
|
||||||
// 7. 返回推送结果
|
// 8. 返回推送结果
|
||||||
Map<String, Object> result = new LinkedHashMap<>();
|
Map<String, Object> result = new LinkedHashMap<>();
|
||||||
result.put("camera_id", cameraId);
|
result.put("camera_id", cameraId);
|
||||||
result.put("version", snapshot.getVersion());
|
result.put("version", snapshot.getVersion());
|
||||||
|
|||||||
@@ -2,12 +2,11 @@ package com.genersoft.iot.vmp.aiot.service.impl;
|
|||||||
|
|
||||||
import com.genersoft.iot.vmp.aiot.bean.*;
|
import com.genersoft.iot.vmp.aiot.bean.*;
|
||||||
import com.genersoft.iot.vmp.aiot.dao.AiAlgorithmMapper;
|
import com.genersoft.iot.vmp.aiot.dao.AiAlgorithmMapper;
|
||||||
import com.genersoft.iot.vmp.aiot.dao.AiEdgeDeviceMapper;
|
|
||||||
import com.genersoft.iot.vmp.aiot.dao.AiRoiAlgoBindMapper;
|
import com.genersoft.iot.vmp.aiot.dao.AiRoiAlgoBindMapper;
|
||||||
import com.genersoft.iot.vmp.aiot.dao.AiRoiMapper;
|
import com.genersoft.iot.vmp.aiot.dao.AiRoiMapper;
|
||||||
import com.genersoft.iot.vmp.aiot.service.IAiConfigLogService;
|
import com.genersoft.iot.vmp.aiot.service.IAiConfigLogService;
|
||||||
import com.genersoft.iot.vmp.aiot.service.IAiRedisConfigService;
|
|
||||||
import com.genersoft.iot.vmp.aiot.service.IAiRoiService;
|
import com.genersoft.iot.vmp.aiot.service.IAiRoiService;
|
||||||
|
import com.genersoft.iot.vmp.streamProxy.dao.StreamProxyMapper;
|
||||||
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageHelper;
|
||||||
import com.github.pagehelper.PageInfo;
|
import com.github.pagehelper.PageInfo;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -36,14 +35,11 @@ public class AiRoiServiceImpl implements IAiRoiService {
|
|||||||
private AiAlgorithmMapper algorithmMapper;
|
private AiAlgorithmMapper algorithmMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private AiEdgeDeviceMapper edgeDeviceMapper;
|
private StreamProxyMapper streamProxyMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IAiConfigLogService configLogService;
|
private IAiConfigLogService configLogService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IAiRedisConfigService redisConfigService;
|
|
||||||
|
|
||||||
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -82,42 +78,27 @@ public class AiRoiServiceImpl implements IAiRoiService {
|
|||||||
roiMapper.add(roi);
|
roiMapper.add(roi);
|
||||||
configLogService.addLog("ROI", roi.getRoiId(), null, toJson(roi), null);
|
configLogService.addLog("ROI", roi.getRoiId(), null, toJson(roi), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 推送配置到 Edge(新增/更新操作)
|
|
||||||
String deviceId = roi.getDeviceId();
|
|
||||||
if (deviceId != null && !deviceId.isEmpty()) {
|
|
||||||
try {
|
|
||||||
redisConfigService.writeDeviceAggregatedConfig(deviceId, "UPDATE");
|
|
||||||
log.info("[AiRoi] {}ROI后推送配置到Edge,camera_id={}, device_id={}",
|
|
||||||
isUpdate ? "更新" : "新增", cameraId, deviceId);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("[AiRoi] {}ROI后推送配置失败,camera_id={}, device_id={}",
|
|
||||||
isUpdate ? "更新" : "新增", cameraId, deviceId, e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.warn("[AiRoi] {}ROI但device_id为空,跳过推送配置,camera_id={}",
|
|
||||||
isUpdate ? "更新" : "新增", cameraId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析 deviceId:
|
* 解析 deviceId:
|
||||||
* 1. 优先从同摄像头的已有 ROI 继承
|
* 1. 优先从摄像头配置继承 edge_device_id(stream_proxy 表)
|
||||||
* 2. 否则取系统中唯一的已注册边缘设备(单边缘场景)
|
* 2. 兼容:从同摄像头已有 ROI 继承
|
||||||
|
* 3. 不再硬编码默认值,返回 null
|
||||||
*/
|
*/
|
||||||
private String resolveDeviceId(String cameraId) {
|
private String resolveDeviceId(String cameraId) {
|
||||||
// 从同摄像头已有 ROI 继承
|
// 1. 优先从摄像头配置继承 edge_device_id
|
||||||
String deviceId = roiMapper.queryDeviceIdByCameraId(cameraId);
|
String deviceId = streamProxyMapper.selectEdgeDeviceIdByCameraCode(cameraId);
|
||||||
if (deviceId != null && !deviceId.isEmpty()) {
|
if (deviceId != null && !deviceId.isEmpty()) {
|
||||||
return deviceId;
|
return deviceId;
|
||||||
}
|
}
|
||||||
// 取系统中第一个已注册的边缘设备
|
// 2. 兼容:从同摄像头已有 ROI 继承
|
||||||
List<AiEdgeDevice> devices = edgeDeviceMapper.queryAll();
|
deviceId = roiMapper.queryDeviceIdByCameraId(cameraId);
|
||||||
if (devices != null && !devices.isEmpty()) {
|
if (deviceId != null && !deviceId.isEmpty()) {
|
||||||
log.info("[AiRoi] 使用默认边缘设备: {}", devices.get(0).getDeviceId());
|
return deviceId;
|
||||||
return devices.get(0).getDeviceId();
|
|
||||||
}
|
}
|
||||||
log.warn("[AiRoi] 无已注册边缘设备,deviceId 为空");
|
// 3. 不再硬编码默认值,返回 null
|
||||||
|
log.warn("[AiRoi] 无法解析 deviceId,cameraId={}", cameraId);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,17 +112,6 @@ public class AiRoiServiceImpl implements IAiRoiService {
|
|||||||
bindMapper.deleteByRoiId(roiId);
|
bindMapper.deleteByRoiId(roiId);
|
||||||
roiMapper.deleteByRoiId(roiId);
|
roiMapper.deleteByRoiId(roiId);
|
||||||
configLogService.addLog("ROI", roiId, toJson(old), null, null);
|
configLogService.addLog("ROI", roiId, toJson(old), null, null);
|
||||||
// 推送配置到 Edge(删除操作)
|
|
||||||
if (deviceId != null && !deviceId.isEmpty()) {
|
|
||||||
try {
|
|
||||||
redisConfigService.writeDeviceAggregatedConfig(deviceId, "UPDATE");
|
|
||||||
log.info("[AiRoi] 删除ROI后推送配置到Edge,camera_id={}, device_id={}", cameraId, deviceId);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("[AiRoi] 删除ROI后推送配置失败,camera_id={}, device_id={}", cameraId, deviceId, e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.warn("[AiRoi] 删除ROI但device_id为空,跳过推送配置,camera_id={}", cameraId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,27 +170,6 @@ public class AiRoiServiceImpl implements IAiRoiService {
|
|||||||
bind.setUpdateTime(now);
|
bind.setUpdateTime(now);
|
||||||
bindMapper.add(bind);
|
bindMapper.add(bind);
|
||||||
configLogService.addLog("BIND", bind.getBindId(), null, toJson(bind), null);
|
configLogService.addLog("BIND", bind.getBindId(), null, toJson(bind), null);
|
||||||
|
|
||||||
// 推送配置到 Edge(绑定算法)
|
|
||||||
String roiId = bind.getRoiId();
|
|
||||||
if (roiId != null) {
|
|
||||||
AiRoi roi = roiMapper.queryByRoiId(roiId);
|
|
||||||
if (roi != null) {
|
|
||||||
String deviceId = roi.getDeviceId();
|
|
||||||
if (deviceId != null && !deviceId.isEmpty()) {
|
|
||||||
try {
|
|
||||||
redisConfigService.writeDeviceAggregatedConfig(deviceId, "UPDATE");
|
|
||||||
log.info("[AiRoi] 绑定算法后推送配置到Edge,camera_id={}, device_id={}, algo={}",
|
|
||||||
roi.getCameraId(), deviceId, bind.getAlgoCode());
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("[AiRoi] 绑定算法后推送配置失败,camera_id={}, device_id={}",
|
|
||||||
roi.getCameraId(), deviceId, e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.warn("[AiRoi] 绑定算法但device_id为空,跳过推送配置,camera_id={}", roi.getCameraId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -231,25 +180,6 @@ public class AiRoiServiceImpl implements IAiRoiService {
|
|||||||
String roiId = old.getRoiId();
|
String roiId = old.getRoiId();
|
||||||
bindMapper.deleteByBindId(bindId);
|
bindMapper.deleteByBindId(bindId);
|
||||||
configLogService.addLog("BIND", bindId, toJson(old), null, null);
|
configLogService.addLog("BIND", bindId, toJson(old), null, null);
|
||||||
// 推送配置到 Edge(解绑算法)
|
|
||||||
if (roiId != null) {
|
|
||||||
AiRoi roi = roiMapper.queryByRoiId(roiId);
|
|
||||||
if (roi != null) {
|
|
||||||
String deviceId = roi.getDeviceId();
|
|
||||||
if (deviceId != null && !deviceId.isEmpty()) {
|
|
||||||
try {
|
|
||||||
redisConfigService.writeDeviceAggregatedConfig(deviceId, "UPDATE");
|
|
||||||
log.info("[AiRoi] 解绑算法后推送配置到Edge,camera_id={}, device_id={}",
|
|
||||||
roi.getCameraId(), deviceId);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("[AiRoi] 解绑算法后推送配置失败,camera_id={}, device_id={}",
|
|
||||||
roi.getCameraId(), deviceId, e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.warn("[AiRoi] 解绑算法但device_id为空,跳过推送配置,camera_id={}", roi.getCameraId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,27 +200,6 @@ public class AiRoiServiceImpl implements IAiRoiService {
|
|||||||
bind.setUpdateTime(now);
|
bind.setUpdateTime(now);
|
||||||
bindMapper.updateByBindId(bind);
|
bindMapper.updateByBindId(bind);
|
||||||
configLogService.addLog("BIND", bind.getBindId(), toJson(old), toJson(bind), null);
|
configLogService.addLog("BIND", bind.getBindId(), toJson(old), toJson(bind), null);
|
||||||
|
|
||||||
// 推送配置到 Edge(更新算法参数)
|
|
||||||
String roiId = old.getRoiId();
|
|
||||||
if (roiId != null) {
|
|
||||||
AiRoi roi = roiMapper.queryByRoiId(roiId);
|
|
||||||
if (roi != null) {
|
|
||||||
String deviceId = roi.getDeviceId();
|
|
||||||
if (deviceId != null && !deviceId.isEmpty()) {
|
|
||||||
try {
|
|
||||||
redisConfigService.writeDeviceAggregatedConfig(deviceId, "UPDATE");
|
|
||||||
log.info("[AiRoi] 更新算法参数后推送配置到Edge,camera_id={}, device_id={}, bind_id={}",
|
|
||||||
roi.getCameraId(), deviceId, bind.getBindId());
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("[AiRoi] 更新算法参数后推送配置失败,camera_id={}, device_id={}",
|
|
||||||
roi.getCameraId(), deviceId, e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.warn("[AiRoi] 更新算法参数但device_id为空,跳过推送配置,camera_id={}", roi.getCameraId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String toJson(Object obj) {
|
private String toJson(Object obj) {
|
||||||
|
|||||||
@@ -127,4 +127,10 @@ public interface StreamProxyMapper {
|
|||||||
*/
|
*/
|
||||||
@Select("SELECT camera_code, camera_name FROM wvp_stream_proxy WHERE enable = 1 ORDER BY camera_name")
|
@Select("SELECT camera_code, camera_name FROM wvp_stream_proxy WHERE enable = 1 ORDER BY camera_name")
|
||||||
List<StreamProxy> selectAllCameraOptions();
|
List<StreamProxy> selectAllCameraOptions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 camera_code 查询关联的边缘设备 ID
|
||||||
|
*/
|
||||||
|
@Select("SELECT edge_device_id FROM wvp_stream_proxy WHERE camera_code = #{cameraCode}")
|
||||||
|
String selectEdgeDeviceIdByCameraCode(@Param("cameraCode") String cameraCode);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user