| package com.ruoyi.alarm.global.service.impl; | 
|   | 
| import com.ruoyi.alarm.access.domain.ArdAlarmAccess; | 
| import com.ruoyi.alarm.access.service.IArdAlarmAccessService; | 
| import com.ruoyi.alarm.external.domain.ArdAlarmExternal; | 
| import com.ruoyi.alarm.external.service.IArdAlarmExternalService; | 
| import com.ruoyi.alarm.global.domain.GuidePriorityQueue; | 
| import com.ruoyi.alarm.global.domain.GuideTask; | 
| import com.ruoyi.alarm.radar.domain.ArdAlarmRadarFire; | 
| import com.ruoyi.alarm.radar.domain.ArdAlarmRadarMove; | 
| import com.ruoyi.alarm.radar.domain.ArdAlarmRadarPump; | 
| import com.ruoyi.alarm.radar.service.IArdAlarmRadarFireService; | 
| import com.ruoyi.alarm.radar.service.IArdAlarmRadarMoveService; | 
| import com.ruoyi.alarm.radar.service.IArdAlarmRadarPumpService; | 
| import com.ruoyi.alarm.tube.domain.ArdAlarmTube; | 
| import com.ruoyi.alarm.tube.service.IArdAlarmTubeService; | 
| import com.ruoyi.common.constant.CacheConstants; | 
| import com.ruoyi.common.core.redis.RedisCache; | 
| import com.ruoyi.common.utils.StringUtils; | 
| import com.ruoyi.common.utils.spring.SpringUtils; | 
| import com.ruoyi.device.camera.domain.ArdCameras; | 
| import com.ruoyi.device.camera.domain.CameraCmd; | 
| import com.ruoyi.device.camera.service.ICameraSdkService; | 
| import lombok.extern.slf4j.Slf4j; | 
| import org.springframework.scheduling.annotation.Async; | 
| import org.springframework.stereotype.Component; | 
|   | 
| import javax.annotation.Resource; | 
| import java.time.Duration; | 
| import java.time.Instant; | 
| import java.util.HashMap; | 
| import java.util.Map; | 
| import java.util.concurrent.*; | 
|   | 
| /** | 
|  * @Description: 队列处理器 | 
|  * @ClassName: QueueHandler | 
|  * @Author: 刘苏义 | 
|  * @Date: 2023年12月12日13:40:13 | 
|  **/ | 
| @Slf4j(topic = "guideQueue") | 
| @Component | 
| public class QueueHandler { | 
|     @Resource | 
|     private RedisCache redisCache; | 
|   | 
|     /** | 
|      * 引导任务入队 | 
|      * 刘苏义 | 
|      * 2023/6/30 8:57 | 
|      */ | 
|     public void addTaskToQueue(String cameraId, GuideTask task) { | 
|         /*通过相机ID获取引导队列,并将引导任务加入队列*/ | 
|         PriorityBlockingQueue<GuideTask> guideTaskQueue = GuidePriorityQueue.cameraQueueMap.get(cameraId); | 
|         if (StringUtils.isNull(guideTaskQueue)) { | 
|             log.debug("相机未登录,没有队列,无法入队引导"); | 
|             return; | 
|         } | 
|         log.debug("新任务入队:" + task.getAlarmId()); | 
|         guideTaskQueue.add(task); | 
|         /*获取该相机的当前执行线程-----弃用*/ | 
|         //TaskThread currentTaskThread = threadMap.get(cameraId); | 
|         ////如果队列当前线程正在运行,若入队任务优先级大于当前任务优先级,则终止当前线程 | 
|         //if (currentTaskThread != null){ | 
|         //    if (task.getPriority() > currentTaskThread.getCurrentTask().getPriority()) { | 
|         //        currentTaskThread.getThread().interrupt(); | 
|         //    } | 
|         //    if (!currentTaskThread.getThread().isAlive()) { | 
|         //        Thread newThread = createThread(cameraId, guideTaskQueue); | 
|         //        threadMap.put(cameraId, new TaskThread(newThread, task)); | 
|         //        newThread.start(); | 
|         //    } | 
|         //} | 
|         ////如果队列当前没有线程正在运行,则启动新线程 | 
|         //else { | 
|         //    Thread newThread = createThread(cameraId, guideTaskQueue); | 
|         //    threadMap.put(cameraId, new TaskThread(newThread, task)); | 
|         //    newThread.start(); | 
|         //} | 
|     } | 
|   | 
|     @Async("guideExecutor") | 
|     public void process(String cameraId) { | 
|         log.debug("CameraId:【" + cameraId + "】引导队列处理器启动成功"); | 
|         PriorityBlockingQueue<GuideTask> guideTasks = GuidePriorityQueue.cameraQueueMap.get(cameraId); | 
|         while (true) { | 
|             if (guideTasks.size() > 0) { | 
|                 //取出队列中的引导任务 | 
|                 GuideTask newTask = null; | 
|                 try { | 
|                     newTask = guideTasks.take(); | 
|                 } catch (InterruptedException e) { | 
|                     e.printStackTrace(); | 
|                 } | 
|                 log.debug("执行新任务:【" + newTask.getAlarmId() + "】"); | 
|                 log.debug("剩余任务数:【" + guideTasks.size() + "】"); | 
|                 // 异步处理任务,并获取Future | 
|                 processTask(newTask); | 
|             } | 
|             try { | 
|                 Thread.sleep(100); | 
|             } catch (InterruptedException e) { | 
|                 e.printStackTrace(); | 
|             } | 
|         } | 
|     } | 
|   | 
|     public void processTask(GuideTask guideTask) { | 
|         try { | 
|             if (!IsEnableGuide(guideTask.getCameraId())) { | 
|                 return; | 
|             } | 
|             String url = ""; | 
|             CameraCmd cmd = new CameraCmd(); | 
|             cmd.setCameraId(guideTask.getCameraId()); | 
|             cmd.setChanNo(guideTask.getChanNo()); | 
|             cmd.setTargetPosition(guideTask.getTargetPosition()); | 
|             cmd.setOperator(guideTask.getAlarmType()); | 
|             cmd.setExpired(30); | 
|             cmd.setRecordBucketName("record"); | 
|             Map<String, Double> ptzMap = new HashMap<>(); | 
|             switch (guideTask.getChanNo()) { | 
|                 case 1: | 
|                     ptzMap.put("p", guideTask.getGuidePTZ().getP1()); | 
|                     ptzMap.put("t", guideTask.getGuidePTZ().getT1()); | 
|                     ptzMap.put("z", guideTask.getGuidePTZ().getZ1()); | 
|                     break; | 
|                 case 2: | 
|                     ptzMap.put("p", guideTask.getGuidePTZ().getP2()); | 
|                     ptzMap.put("t", guideTask.getGuidePTZ().getT2()); | 
|                     ptzMap.put("z", guideTask.getGuidePTZ().getZ2()); | 
|                     break; | 
|             } | 
|             cmd.setPtzMap(ptzMap); | 
|             cmd.setRecordObjectName("alarm_" + guideTask.getAlarmId()); | 
|             ICameraSdkService cameraSdkService = SpringUtils.getBean(ICameraSdkService.class); | 
|             log.debug("开始引导"); | 
|             boolean guideRes = false; | 
|             boolean recordFlag = false; | 
|             if (cmd.getPtzMap().get("p") != null) { | 
|                 //p值存在 优先引导ptz | 
|                 guideRes = cameraSdkService.setPtz(cmd); | 
|             } else { | 
|                 guideRes = cameraSdkService.guideTargetPosition(cmd); | 
|             } | 
|             if (guideRes) { | 
|                 log.debug("引导成功"); | 
|                 cameraSdkService.controlLock(cmd);//上锁 | 
|                 cameraSdkService.recordStart(cmd);//开始录像 | 
|                 recordFlag = true; | 
|                 Instant startTime = Instant.now(); | 
|                 while (recordFlag) { | 
|                     //判断时间 | 
|                     Instant currentTime = Instant.now(); | 
|                     long elapsedSeconds = Duration.between(startTime, currentTime).getSeconds(); | 
|                     if (elapsedSeconds >= 30) { | 
|                         recordFlag = false;//达到30秒录像停止 | 
|                         url = cameraSdkService.recordStopToMinio(cmd);//停止录像返回url | 
|                     } | 
|                     if (!IsEnableGuide(guideTask.getCameraId())) { | 
|                         recordFlag = false;//相机关闭引导录像停止 | 
|                     } | 
|                     //判断队列中第一条数据的优先级是否大于当前数据的优先级 | 
|                     PriorityBlockingQueue<GuideTask> guideTasks = GuidePriorityQueue.cameraQueueMap.get(guideTask.getCameraId()); | 
|                     if (guideTasks.size() > 0) { | 
|                         GuideTask firstTask = guideTasks.peek(); | 
|                         if (firstTask.getPriority() > guideTask.getPriority()) { | 
|                             recordFlag = false;//录像停止 | 
|                         } | 
|                     } | 
|                 } | 
|                 if (StringUtils.isNotEmpty(url)) { | 
|                     switch (guideTask.getAlarmType()) { | 
|                         case "sys_tube_leak": | 
|                             ArdAlarmTube ardAlarmTube = new ArdAlarmTube(); | 
|                             ardAlarmTube.setId(guideTask.getAlarmId()); | 
|                             ardAlarmTube.setRecordUrl(url); | 
|                             IArdAlarmTubeService ardAlarmTubeService = SpringUtils.getBean(IArdAlarmTubeService.class); | 
|                             ardAlarmTubeService.updateArdAlarmTube(ardAlarmTube); | 
|                             break; | 
|                         case "sys_radar_move": | 
|                             ArdAlarmRadarMove ardAlarmRadarMove = new ArdAlarmRadarMove(); | 
|                             ardAlarmRadarMove.setId(guideTask.getAlarmId()); | 
|                             ardAlarmRadarMove.setRecordUrl(url); | 
|                             IArdAlarmRadarMoveService ardAlarmRadarMoveService = SpringUtils.getBean(IArdAlarmRadarMoveService.class); | 
|                             ardAlarmRadarMoveService.updateArdAlarmRadarMove(ardAlarmRadarMove); | 
|                             break; | 
|                         case "sys_radar_fire": | 
|                             ArdAlarmRadarFire ardAlarmRadarFire = new ArdAlarmRadarFire(); | 
|                             ardAlarmRadarFire.setId(guideTask.getAlarmId()); | 
|                             ardAlarmRadarFire.setRecordUrl(url); | 
|                             IArdAlarmRadarFireService ardAlarmRadarFireService = SpringUtils.getBean(IArdAlarmRadarFireService.class); | 
|                             ardAlarmRadarFireService.updateArdAlarmRadarFire(ardAlarmRadarFire); | 
|                             break; | 
|                         case "sys_radar_pump": | 
|                             ArdAlarmRadarPump ardAlarmRadarPump = new ArdAlarmRadarPump(); | 
|                             ardAlarmRadarPump.setId(guideTask.getAlarmId()); | 
|                             ardAlarmRadarPump.setRecordUrl(url); | 
|                             IArdAlarmRadarPumpService ardAlarmRadarPumpService = SpringUtils.getBean(IArdAlarmRadarPumpService.class); | 
|                             ardAlarmRadarPumpService.updateArdAlarmRadarPump(ardAlarmRadarPump); | 
|                             break; | 
|                         case "sys_external": | 
|                             ArdAlarmExternal ardAlarmExternal = new ArdAlarmExternal(); | 
|                             ardAlarmExternal.setId(guideTask.getAlarmId()); | 
|                             ardAlarmExternal.setRecordUrl(url); | 
|                             IArdAlarmExternalService ardAlarmExternalService = SpringUtils.getBean(IArdAlarmExternalService.class); | 
|                             ardAlarmExternalService.updateArdAlarmExternal(ardAlarmExternal); | 
|                             break; | 
|                         case "sys_access_control": | 
|                             ArdAlarmAccess ardAlarmAccess = new ArdAlarmAccess(); | 
|                             ardAlarmAccess.setId(guideTask.getAlarmId()); | 
|                             ardAlarmAccess.setRecordUrl(url); | 
|                             IArdAlarmAccessService ardAlarmAccessService = SpringUtils.getBean(IArdAlarmAccessService.class); | 
|                             ardAlarmAccessService.updateArdAlarmAccess(ardAlarmAccess); | 
|                             break; | 
|                     } | 
|                 } | 
|             } | 
|         } catch (Exception ex) { | 
|             log.info("线程任务异常:" + ex.getMessage()); | 
|         } | 
|     } | 
|   | 
|     /** | 
|      * 光电是否开启报警引导功能 | 
|      * 刘苏义 | 
|      * 2023/7/7 14:03 | 
|      */ | 
|     private Boolean IsEnableGuide(String cameraId) { | 
|         boolean enabled = false; | 
|         ArdCameras ardCameras = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + cameraId); | 
|         if (ardCameras != null) { | 
|             if (ardCameras.getCamAlarmGuideEnable().equals(1)) { | 
|                 enabled = true; | 
|             } | 
|         } | 
|         return enabled; | 
|     } | 
| } |