ard-work/src/main/java/com/ruoyi/alarm/globalAlarm/domain/GuidePriorityQueue.java
@@ -1,11 +1,12 @@ package com.ruoyi.alarm.globalAlarm.domain; import lombok.AllArgsConstructor; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.PriorityQueue; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.PriorityBlockingQueue; /** @@ -28,8 +29,8 @@ public static Comparator<GuideTask> getComparator() { Comparator<GuideTask> PriorityDescCom = Comparator.comparingInt(GuideTask::getPriority).reversed(); Comparator<GuideTask> NumDescCom = Comparator.comparingInt(GuideTask::getNum).reversed(); Comparator<GuideTask> alarmTimeAscCom = Comparator.comparing(GuideTask::getAlarmTime); Comparator<GuideTask> Comparator = PriorityDescCom.thenComparing(NumDescCom).thenComparing(alarmTimeAscCom); Comparator<GuideTask> receiveTimeAscCom = Comparator.comparing(GuideTask::getReceiveTime); Comparator<GuideTask> Comparator = PriorityDescCom.thenComparing(NumDescCom).thenComparing(receiveTimeAscCom); return Comparator; } @@ -39,9 +40,47 @@ public static void printPriorityQueue() { for (String cameraId : GuidePriorityQueue.cameraQueueMap.keySet()) { PriorityBlockingQueue<GuideTask> priorityQueue = GuidePriorityQueue.cameraQueueMap.get(cameraId); for (GuideTask task : priorityQueue) { log.info("alarmId:" + task.getAlarmId() + " alarmTime:" + task.getAlarmTime() + " priority:" + task.getPriority() + " num:" + task.getNum() + " cameraId:" + task.getCameraId()); // for (GuideTask task : priorityQueue) { // // log.info("【alarmId】" + task.getAlarmId() + "【receiveTime】" + task.getReceiveTime() // + "【priority】" + task.getPriority() + "【num】" + task.getNum() // + "【chan】" + task.getChanNum() + "【recordSn】" + task.getRecordSn() + "【cameraId】" + task.getCameraId()); // } while (priorityQueue.size() > 0) { GuideTask task = priorityQueue.poll(); log.info("【alarmId】" + task.getAlarmId() + "【receiveTime】" + task.getReceiveTime() + "【priority】" + task.getPriority() + "【num】" + task.getNum() + "【chan】" + task.getChanNum() + "【recordSn】" + task.getRecordSn() + "【cameraId】" + task.getCameraId());; } } } public static void main(String[] args) { Comparator<obj> com1 = Comparator.comparingInt(obj::getNUM1).reversed(); Comparator<obj> com2 = Comparator.comparingInt(obj::getNUM2).reversed(); Comparator<obj> com3 = Comparator.comparingInt(obj::getNUM3).reversed(); Comparator<obj> objComparator = com1.thenComparing(com2).thenComparing(com3); PriorityQueue<obj> priorityQueue = new PriorityQueue<>(objComparator); priorityQueue.add(new obj(1, 1, 65)); priorityQueue.add(new obj(1, 4, 21)); priorityQueue.add(new obj(1, 4, 33)); priorityQueue.add(new obj(1, 4, 44)); priorityQueue.add(new obj(1, 4, 51)); while (priorityQueue.size() > 0) { obj task = priorityQueue.poll(); log.info("【num1】" + task.getNUM1() + "【num2】" + task.getNUM2() + "【num3】" + task.getNUM3()); } log.info("======================================================================="); } } @Data @AllArgsConstructor class obj { Integer NUM1; Integer NUM2; Integer NUM3; } ard-work/src/main/java/com/ruoyi/alarm/globalAlarm/domain/GuideTask.java
@@ -4,6 +4,8 @@ import lombok.Data; import lombok.NoArgsConstructor; import java.util.Date; /** * @Description: 引导任务 * @ClassName: GuideTask @@ -37,16 +39,24 @@ */ Integer priority; /** * 报警时间 * 接收时间 */ String alarmTime; String receiveTime; /** * 接收时间的毫秒值 */ Integer receiveMillisecond; /** * 报警次数 */ Integer num; /** * 录像存储位置 * 录像存储位置-这里有的报警需要引导2个相机,故需要指定哪个相机录像回写到哪个字段 */ Integer recordSn; /** * 引导目标经纬度 */ double[] targetPosition; } ard-work/src/main/java/com/ruoyi/alarm/globalAlarm/service/impl/GlobalAlarmServiceImpl.java
@@ -48,8 +48,8 @@ /** * @Description: 全局报警业务 * @ClassName: globalAlarmServiceImpl * @Description: * @Author: Administrator * @Date: 2023年03月10日 11:03 * @Version: 1.0 @@ -332,6 +332,7 @@ ardAlarmTube.setColor(ardTubes.getColor()); ardAlarmTube.setPipeDiameter(ardTubes.getPipeDiameter()); ardAlarmTube.setTubeType(ardTubes.getType()); ardAlarmTube.setCreateTime(new Date()); GeoPoint geoPoint = TubeTools.CalculateCoordinates(ardTubesDetails, ardAlarmTube.getPosition()); if (StringUtils.isNotNull(geoPoint)) { ardAlarmTube.setLongitude(geoPoint.getLongitude()); @@ -342,9 +343,10 @@ int aat = ardAlarmTubeMapper.insertArdAlarmTube(ardAlarmTube); if (aat > 0) { log.debug("tube入库成功:" + ardAlarmTube); String nearbyCamera = getNearbyCamera(new double[]{ardAlarmTube.getLongitude(), ardAlarmTube.getLatitude()}); if (StringUtils.isNotEmpty(nearbyCamera)) { messagesEnqueued(nearbyCamera, ardAlarmTube.getId(), "sys_tube_leak", ardAlarmTube.getAlarmTime(), 1,1); double[] coordinate=new double[]{ardAlarmTube.getLongitude(),ardAlarmTube.getLatitude()}; String nearbyCameraId = getNearbyCamera(new double[]{ardAlarmTube.getLongitude(), ardAlarmTube.getLatitude()}); if (StringUtils.isNotEmpty(nearbyCameraId)) { messagesEnqueued(nearbyCameraId, ardAlarmTube.getId(), "sys_tube_leak",ardAlarmTube.getCreateTime(), 1,1,coordinate); } } //endregion @@ -366,11 +368,12 @@ List<ArdAlarmRadar> ardAlarmRadars = radarAlarmData.getArdAlarmRadars(); for (ArdAlarmRadar ardAlarmRadar : ardAlarmRadars) { String uuid = IdUtils.simpleUUID(); ardAlarmRadar.setId(uuid); ardAlarmRadar.setAlarmTime(radarAlarmData.getAlarmTime()); String name = ardAlarmRadar.getName() + "(" + radarAlarmData.getRadarName() + ")"; ardAlarmRadar.setName(name); ardAlarmRadar.setCreateTime(new Date()); ardAlarmRadar.setId(uuid);//报警ID ardAlarmRadar.setAlarmTime(radarAlarmData.getAlarmTime());//报警时间 String alarmpointName = ardAlarmRadar.getName();//兴趣点名称 ardAlarmRadar.setName(ardAlarmRadar.getName() + "(" + radarAlarmData.getRadarName() + ")");//报警点名称 ardAlarmRadar.setCreateTime(new Date());//接收时间 double[] coordinate=new double[]{ardAlarmRadar.getLongitude(),ardAlarmRadar.getLatitude()};//报警坐标 String alarmType = ""; switch (ardAlarmRadar.getAlarmType()) { case "运动目标检测": @@ -389,8 +392,19 @@ //获取雷达所在塔上的大光电 String cameraIdWithTower = ardAlarmRadarMapper.getCameraByRadar(radarAlarmData.getRadarId()); if (StringUtils.isNotNull(cameraIdWithTower) && StringUtils.isNotEmpty(cameraIdWithTower)) { //入队列待引导 messagesEnqueued(cameraIdWithTower, uuid, alarmType, ardAlarmRadar.getAlarmTime(), 1,1); log.info("获取到雷达塔上的光电:"+cameraIdWithTower); //如果雷达塔上有光电 messagesEnqueued(cameraIdWithTower, uuid, alarmType, ardAlarmRadar.getCreateTime(),1,1,coordinate); } //获取报警点关联的大光电 ArdAlarmpointsWell ardAlarmpointsWell = ardAlarmpointsWellMapper.selectArdAlarmpointsWellByWellId(alarmpointName); if(StringUtils.isNotNull(ardAlarmpointsWell) && StringUtils.isNotEmpty(ardAlarmpointsWell.getCameraId())) { String cameraId = ardAlarmpointsWell.getCameraId(); log.info("获取到报警点关联的光电:"+cameraId); //如果报警点关联了光电 messagesEnqueued(cameraId, uuid, alarmType,ardAlarmRadar.getCreateTime(), 1,2,coordinate); } } else { //5分钟内有引导 @@ -404,16 +418,18 @@ //获取雷达所在塔上的大光电 String cameraIdWithTower = ardAlarmRadarMapper.getCameraByRadar(radarAlarmData.getRadarId()); if (StringUtils.isNotNull(cameraIdWithTower) && StringUtils.isNotEmpty(cameraIdWithTower)) { log.info("获取到雷达塔上的光电:"+cameraIdWithTower); //如果雷达塔上有光电 messagesEnqueued(cameraIdWithTower, uuid, alarmType, ardAlarmRadar.getAlarmTime(), count,1); messagesEnqueued(cameraIdWithTower, uuid, alarmType,ardAlarmRadar.getCreateTime(), count,1,coordinate); } //获取报警点关联的大光电 ArdAlarmpointsWell ardAlarmpointsWell = ardAlarmpointsWellMapper.selectArdAlarmpointsWellByWellId(ardAlarmRadar.getName()); ArdAlarmpointsWell ardAlarmpointsWell = ardAlarmpointsWellMapper.selectArdAlarmpointsWellByWellId(alarmpointName); if(StringUtils.isNotNull(ardAlarmpointsWell) && StringUtils.isNotEmpty(ardAlarmpointsWell.getCameraId())) { String cameraId = ardAlarmpointsWell.getCameraId(); log.info("获取到报警点关联的光电:"+cameraId); //如果报警点关联了光电 messagesEnqueued(cameraId, uuid, alarmType, ardAlarmRadar.getAlarmTime(), count,1); messagesEnqueued(cameraId, uuid, alarmType,ardAlarmRadar.getCreateTime(), count,2,coordinate); } } else { //未引导未超过3次,直接入库 @@ -430,39 +446,46 @@ } } /** * 消息入队 * * cameraId 相机ID * alarmId 报警ID * alarmType 报警类型 * num 报警次数 * recordSn 录像存储位置 1-recordUrl1 2-recordUrl2 * targetPosition 报警点位置坐标 */ private void messagesEnqueued(String cameraId, String alarmId, String alarmType, Date alarmTime, Integer num, Integer recordSn) { private void messagesEnqueued(String cameraId, String alarmId, String alarmType,Date receiveTime, Integer num, Integer recordSn,double[] targetPosition) { SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); GuideTask guideTask = new GuideTask(); /*配置相机ID*/ //相机ID guideTask.setCameraId(cameraId); /*根据配置时间配置通道*/ //报警类型 guideTask.setAlarmType(alarmType); //通道(通过日夜时间研判) String dayNightTime = redisCache.getCacheObject("sys_config:dayNightTime"); Integer channel = ArdTool.getChannelBydayNightTime(dayNightTime); guideTask.setChanNum(channel); /*配置报警ID*/ //报警ID guideTask.setAlarmId(alarmId); /*配置报警时间*/ SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); guideTask.setAlarmTime(fmt.format(alarmTime)); /*配置报警优先级*/ //接收时间 guideTask.setReceiveTime(fmt.format(receiveTime)); //报警优先级(通过优先级字典) Integer priority = CamPriority.priorityMap.get(alarmType); guideTask.setPriority(priority); /*配置报警次数*/ //报警次数 guideTask.setNum(num); /*配置录像存储位置*/ //录像存储位置 guideTask.setRecordSn(recordSn); /*消息入队*/ //目标经纬度 guideTask.setTargetPosition(targetPosition); //消息入队 queueManager.addTaskToQueue(cameraId, guideTask); // PriorityBlockingQueue<GuideTask> priorityBlockingQueue = GuidePriorityQueue.cameraQueueMap.get(guideTask.getCameraId()); // priorityBlockingQueue.add(guideTask); } /** * 查找附近开启报警引导功能光电 * 获取附近开启报警引导功能光电 */ private String getNearbyCamera(double[] targetPosition) { String minDistanceCameraId = ""; @@ -493,68 +516,6 @@ } } return minDistanceCameraId; } /** * @描述 引导最近的大光电指向目标 * @参数 [cmd] * @返回值 boolean * @创建人 刘苏义 * @创建时间 2023/6/28 16:34 * @修改人和其它信息 */ private boolean guideCamera(CameraCmd cmd) { try { String dayNightTime = redisCache.getCacheObject("sys_config:dayNightTime"); String nearbyCamera = getNearbyCamera(cmd.getTargetPosition()); if (StringUtils.isNotEmpty(nearbyCamera)) { //引导光电 cmd.setCameraId(nearbyCamera); cmd.setChannelNum(ArdTool.getChannelBydayNightTime(dayNightTime)); boolean guideRes = hikClientService.guideTargetPosition(cmd); return guideRes; } else { log.debug("未查找到最近光电"); return false; } } catch ( Exception ex) { log.error("引导异常:" + ex.getMessage()); return false; } } /** * @描述 报警录像 * @参数 [cmd] * @返回值 java.lang.String * @创建人 刘苏义 * @创建时间 2023/6/28 16:33 * @修改人和其它信息 */ private String alarmToRecord(CameraCmd cmd) { String url = ""; try { log.debug("引导成功,尝试录像"); String cameraId = cmd.getCameraId(); hikClientService.controlLock(cmd);//上锁 cmd.setEnable(true);//开始录像 hikClientService.recordToMinio(cmd);//开始录像 GlobalVariable.threadMap.put(cameraId, Thread.currentThread().getName());//将相机id与当前处理线程名称绑定 Thread.sleep(cmd.getExpired() * 1000);//录像时长 String thread = GlobalVariable.threadMap.get(cameraId); String currentThread = Thread.currentThread().getName(); //判断相机绑定线程是否是当前线程,如果是,停止录像,如果不是,说明相机被其他线程抢占,不停止录像 if (thread.equals(currentThread)) { cmd.setEnable(false);//停止录像 cmd.setUploadMinio(true);//上传minio url = hikClientService.recordToMinio(cmd);//停止录像返回url } } catch (Exception ex) { log.error("录像异常:" + ex.getMessage()); } return url; } } ard-work/src/main/java/com/ruoyi/alarm/globalAlarm/service/impl/QueueManager.java
@@ -2,6 +2,8 @@ import com.ruoyi.alarm.globalAlarm.domain.GuidePriorityQueue; import com.ruoyi.alarm.globalAlarm.domain.GuideTask; import com.ruoyi.common.utils.StringUtils; import lombok.extern.slf4j.Slf4j; import org.apache.tomcat.util.threads.TaskThread; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @@ -10,6 +12,8 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.PriorityBlockingQueue; import static jdk.nashorn.internal.runtime.regexp.joni.Config.log; /** * @ClassName QueueManager @@ -20,6 +24,7 @@ */ @Component @Slf4j public class QueueManager { @Autowired @@ -57,6 +62,10 @@ public void addTaskToQueue(String cameraId, GuideTask task) { /*通过相机ID获取引导队列,并将引导任务加入队列*/ PriorityBlockingQueue<GuideTask> guideTaskQueue = GuidePriorityQueue.cameraQueueMap.get(cameraId); if(StringUtils.isNull(guideTaskQueue)) { log.info("相机未初始化成功,没有队列"); } guideTaskQueue.add(task); /*获取该相机的当前执行线程*/ TaskThread currentTaskThread = threadMap.get(cameraId); ard-work/src/main/java/com/ruoyi/alarm/globalAlarm/service/impl/QueueTaskExecutor.java
@@ -35,7 +35,12 @@ try { CameraCmd cmd = new CameraCmd(); cmd.setCameraId(guideTask.getCameraId()); cmd.setChannelNum(guideTask.getNum()); cmd.setChannelNum(guideTask.getChanNum()); cmd.setTargetPosition(guideTask.getTargetPosition()); cmd.setOperator(guideTask.getAlarmType()); cmd.setExpired(30); cmd.setRecordBucketName("record"); cmd.setRecordObjectName("alarm"); boolean guideRes = hikClientService.guideTargetPosition(cmd); if (guideRes) { hikClientService.controlLock(cmd);//上锁 ard-work/src/main/java/com/ruoyi/device/hiksdk/controller/SdkController.java
@@ -192,7 +192,15 @@ cmd.setOperator(SecurityUtils.getUserId()); return toAjax(sdk.controlLock(cmd)); } @ApiOperation("设置解锁") @PostMapping("/setPTZUnLock") @ApiOperationSupport(includeParameters = {"cmd.cameraId"}) @Log(title = "设置解锁", businessType = BusinessType.CONTROL) public @ResponseBody AjaxResult setPTZUnLock(@RequestBody CameraCmd cmd) { cmd.setOperator(SecurityUtils.getUserId()); return AjaxResult.success(sdk.controlUnLock(cmd)); } @ApiOperation("获取云台锁定信息") @PostMapping("/getPTZLockInfo") @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.channelNum"}) ard-work/src/main/java/com/ruoyi/device/hiksdk/service/IHikClientService.java
@@ -64,7 +64,8 @@ //配置锁定 boolean controlLock(CameraCmd cmd); //配置解锁 boolean controlUnLock(CameraCmd cmd); //获取云台锁定信息 int getPTZLockInfo(CameraCmd cmd); ard-work/src/main/java/com/ruoyi/device/hiksdk/service/impl/HikClientServiceImpl.java
@@ -758,6 +758,31 @@ } return true; } /** * @描述 操控解锁 * @参数 [userId, channelNum] * @返回值 boolean * @创建人 刘苏义 * @创建时间 2023/6/30 15:36 * @修改人和其它信息 */ @Override public boolean controlUnLock(CameraCmd cmd) { String cameraId = cmd.getCameraId();//申请解锁的相机 String operator = cmd.getOperator();//申请者 ArdCameras ardCameras = ardCamerasMapper.selectArdCamerasById(cameraId); if(ardCameras.getOperatorId().equals(operator)) { //如果解锁相机的当前用户是申请者,则清空该相机的过期时间 ardCameras.setOperatorExpired(null); int i = ardCamerasMapper.updateArdCameras(ardCameras); if(i>0) { log.debug(cameraId+"--解锁成功"); } } return true; } /** * @描述 获取ptz锁定信息 ard-work/src/main/resources/mapper/alarm/ArdAlarmRadarMapper.xml
@@ -96,6 +96,8 @@ <if test="createTime != null">create_time = #{createTime},</if> <if test="userId != null">user_id = #{userId},</if> <if test="deptId != null">dept_id = #{deptId},</if> <if test="recordUrl1 != null">record_url1 = #{recordUrl1},</if> <if test="recordUrl2 != null">record_url2 = #{recordUrl2},</if> <if test="guideFlag != null">guide_flag = #{guideFlag},</if> </trim> where id = #{id}