From d30b3ff395fa79888db752ed7d12f5d3fbc44731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=AF=85?= <97163845@qq.com> Date: Mon, 29 Sep 2025 18:02:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=80=E6=96=B0=E7=89=88=E7=BA=A2=E5=A4=96?= =?UTF-8?q?=20=E6=94=AF=E6=8C=81=E5=A4=9A=E7=BA=BF=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sdkLog/SdkLog_1_W.log | 8 +- .../nvr/controller/CameraController.java | 4 +- .../nvr/controller/IvsCameraController.java | 47 +++- .../com/inspect/nvr/service/DahuaService.java | 5 +- .../nvr/service/impl/DahuaServiceImpl.java | 230 ++++++++++-------- .../service/impl/HikVisionServiceImpl.java | 19 +- .../service/impl/IvsCameraServiceImpl.java | 120 ++++----- .../inspect/nvr/utils/StringHexConverter.java | 3 +- .../inspect/nvr/utils/sftp/SftpFactory.java | 2 +- src/main/resources/application.yml | 4 + 10 files changed, 254 insertions(+), 188 deletions(-) diff --git a/sdkLog/SdkLog_1_W.log b/sdkLog/SdkLog_1_W.log index 699e332..3d4ca9e 100644 --- a/sdkLog/SdkLog_1_W.log +++ b/sdkLog/SdkLog_1_W.log @@ -1,4 +1,4 @@ -[2025-09-03 14:03:42.300][DBG] CCoreGlobalCtrlBase::LoadDSo, HPR_LoadDSo Succ, Path[D:/workspace/inspect-nvr/lib/zlib1.dll], hHandleRet[1681326080] -[2025-09-03 14:03:42.300][INF] The COM:HCCoreBase ver is 6.1.4.15, 2020_03_05. Async:1. -[2025-09-03 14:03:42.300][INF] The COM:Core ver is 6.1.9.47, 2022_11_11. Async:1. -[2025-09-03 14:03:42.300][INF] This HCNetSDK ver is 6.1.9.47 Ver 2022_11_11. +[2025-09-16 11:20:34.679][DBG] CCoreGlobalCtrlBase::LoadDSo, HPR_LoadDSo Succ, Path[D:/workspace/inspect-nvr/lib/zlib1.dll], hHandleRet[1841233920] +[2025-09-16 11:20:34.679][INF] The COM:HCCoreBase ver is 6.1.4.15, 2020_03_05. Async:1. +[2025-09-16 11:20:34.679][INF] The COM:Core ver is 6.1.9.47, 2022_11_11. Async:1. +[2025-09-16 11:20:34.679][INF] This HCNetSDK ver is 6.1.9.47 Ver 2022_11_11. diff --git a/src/main/java/com/inspect/nvr/controller/CameraController.java b/src/main/java/com/inspect/nvr/controller/CameraController.java index 6b9b0b2..f0f15e4 100644 --- a/src/main/java/com/inspect/nvr/controller/CameraController.java +++ b/src/main/java/com/inspect/nvr/controller/CameraController.java @@ -57,12 +57,12 @@ public class CameraController { log.info("红外开始===================================》》》》》"); TemperatureData temperatureData = null; if(0 == camera.getCameraType()){ - temperatureData = executeWithTimeout(() -> cameraService.StartRemote(camera), 5, TimeUnit.SECONDS); + temperatureData = executeWithTimeout(() -> cameraService.StartRemote(camera), 7, TimeUnit.SECONDS); // temperatureData = cameraService.StartRemote(camera); } else { temperatureData = dahuaService.StartRemote(camera); } - redisService.setCacheObject(camera.getIp() +'_'+ camera.getPresetId(), temperatureData, 200L, TimeUnit.SECONDS); + redisService.setCacheObject(camera.getIp() +'_'+ camera.getPresetId(), temperatureData, 14400L, TimeUnit.SECONDS); return temperatureData; } diff --git a/src/main/java/com/inspect/nvr/controller/IvsCameraController.java b/src/main/java/com/inspect/nvr/controller/IvsCameraController.java index 923bc03..d1205e5 100644 --- a/src/main/java/com/inspect/nvr/controller/IvsCameraController.java +++ b/src/main/java/com/inspect/nvr/controller/IvsCameraController.java @@ -1,13 +1,16 @@ package com.inspect.nvr.controller; +import com.inspect.nvr.domain.Infrared.TemperatureData; import com.inspect.nvr.domain.device.*; import com.inspect.nvr.service.IvsCameraService; +import com.inspect.nvr.utils.StringUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.InputStreamResource; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.List; @@ -17,7 +20,8 @@ public class IvsCameraController { @Resource private IvsCameraService ivsCameraService; - + private static final Object captureLock = new Object(); + private static final Object captureLock_pic = new Object(); @GetMapping("/device/ptzpresetlist/{cameraCode}/{domainCode}") public ResponseEntity ptzPresetList(@PathVariable("cameraCode") String cameraCode, @PathVariable("domainCode") String domainCode) { log.info("PTZ_PRESET_LIST cameraCode : {}, domainCode: {}", cameraCode, domainCode); @@ -29,10 +33,12 @@ public class IvsCameraController { @PostMapping({"/device/ptzcontrol"}) public ResponseEntity ptzControl(@RequestBody PtzControlParam param) { - log.info("Ptz control request param: {}", param); - return ResponseEntity - .ok() - .body(ivsCameraService.ptzControl(param)); +// synchronized (captureLock) { + log.info("Ptz control request param: {}", param); + return ResponseEntity + .ok() + .body(ivsCameraService.ptzControl(param)); +// } } @GetMapping({"/platform/platformSnapshot/{cameraCode}/{domainCode}"}) @@ -56,10 +62,31 @@ public class IvsCameraController { @GetMapping("/downloadfile") public ResponseEntity downloadFile(@RequestParam("filesessionid") String fileSessionId) { - log.info("Download File Get Stream, fileSessionId: {}", fileSessionId); - return ResponseEntity - .ok() - .body(new InputStreamResource(ivsCameraService.downloadFile(fileSessionId))); +// synchronized (captureLock_pic) { + log.info("Download File Get Stream, fileSessionId: {}", fileSessionId); + ByteArrayInputStream byteArrayInputStream = null; + //添加重试机制 + final int MAX_RETRIES = 20; // 最大重试次数 + boolean success = false; + int retryCount = 0; + while (!success && retryCount < MAX_RETRIES) { + try { + retryCount++; + log.info("第{}次尝试抓图", retryCount); + byteArrayInputStream = ivsCameraService.downloadFile(fileSessionId); + if (StringUtils.isNotNull(byteArrayInputStream)) { + success = true; + } else { + Thread.sleep(500); // 等待一秒后重试 + log.error("第{}次抓图失败", retryCount); + } + } catch (Exception e) { + log.error("第{}次抓图失败: {}", retryCount, e.getMessage()); + } + } + return ResponseEntity + .ok() + .body(new InputStreamResource(byteArrayInputStream)); +// } } - } diff --git a/src/main/java/com/inspect/nvr/service/DahuaService.java b/src/main/java/com/inspect/nvr/service/DahuaService.java index 4c27b69..db74c78 100644 --- a/src/main/java/com/inspect/nvr/service/DahuaService.java +++ b/src/main/java/com/inspect/nvr/service/DahuaService.java @@ -1,16 +1,17 @@ package com.inspect.nvr.service; +import com.inspect.nvr.daHuaCarme.jna.NetSDKLib; import com.inspect.nvr.domain.Infrared.Camera; import com.inspect.nvr.domain.Infrared.NvrInfo; import com.inspect.nvr.domain.Infrared.TemperatureData; import com.inspect.nvr.hikVision.utils.AjaxResult; - +import com.inspect.nvr.daHuaCarme.jna.NetSDKLib.LLong; import java.io.ByteArrayInputStream; public interface DahuaService { - AjaxResult login(NvrInfo nvrInfo); + LLong login(NvrInfo nvrInfo); //大华测温 TemperatureData StartRemote(Camera camera); diff --git a/src/main/java/com/inspect/nvr/service/impl/DahuaServiceImpl.java b/src/main/java/com/inspect/nvr/service/impl/DahuaServiceImpl.java index 7c2a56e..cc24244 100644 --- a/src/main/java/com/inspect/nvr/service/impl/DahuaServiceImpl.java +++ b/src/main/java/com/inspect/nvr/service/impl/DahuaServiceImpl.java @@ -18,6 +18,7 @@ import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import javax.annotation.Resource; @@ -39,21 +40,24 @@ public class DahuaServiceImpl implements DahuaService { @Resource private RedisService redisService; - private LLong m_hLoginHandle; +// private LLong m_hLoginHandle; @Autowired private fSnapReceiveCB snapReceiveCB; private static final Object captureLock = new Object(); + @Value("${mode.delayTime:3000}") + private int delayTime; /** * 登录大华设备 + * * @param nvrInfo * @return */ @Override - public AjaxResult login(NvrInfo nvrInfo) { - + public LLong login(NvrInfo nvrInfo) { + log.info("大华调用登录------------"); //入参 NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstInParam = new NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY(); // pstInParam.szIP=camera.getIp().getBytes(); @@ -71,58 +75,62 @@ public class DahuaServiceImpl implements DahuaService { //调用登录接口 // NetSDKLib.LLong m_hLoginHandle=NetSDKLib.cki - m_hLoginHandle = dhNetSDK.CLIENT_LoginWithHighLevelSecurity(pstInParam, pstOutParam); + LLong m_hLoginHandle = dhNetSDK.CLIENT_LoginWithHighLevelSecurity(pstInParam, pstOutParam); System.out.println("m_hLoginHandle : " + m_hLoginHandle); if (m_hLoginHandle.longValue() == 0) { System.out.println("登录失败"); System.out.println("大华-获取设备参数失败,错误码:" + ToolKits.getErrorCodePrint(dhNetSDK.CLIENT_GetLastError())); return null; } - redisService.setCacheObject(nvrInfo.getNvrIp() + "_m_hLoginHandle", m_hLoginHandle.longValue(), 200L, TimeUnit.SECONDS); - log.info("nvrip:{}",nvrInfo.getNvrIp()); - log.info("redis:{}",redisService.redisTemplate.opsForValue().get(nvrInfo.getNvrIp() + "_m_hLoginHandle")); - return null; +// redisService.setCacheObject(nvrInfo.getNvrIp() + "_m_hLoginHandle", m_hLoginHandle.longValue(), 200L, TimeUnit.SECONDS); +// log.info("nvrip:{}",nvrInfo.getNvrIp()); +// log.info("redis:{}",redisService.redisTemplate.opsForValue().get(nvrInfo.getNvrIp() + "_m_hLoginHandle")); + return m_hLoginHandle; } /** * 获取红外温度信息 + * * @param camera * @return */ @Override public TemperatureData StartRemote(Camera camera) { log.info("大华实时测温入口================================================="); - Object storedObj = redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle"); +// Object storedObj = redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle"); // 2. 进行空值和类型判断 - if (StringUtils.isNotNull(storedObj)) { - Long storedValue = (Long) storedObj; - m_hLoginHandle = new NetSDKLib.LLong(storedValue); - } else { - //m_hLoginHandle为空 - m_hLoginHandle = null; - } - // 3. 安全转换并创建LLong对象 - if (ObjectUtil.isEmpty(m_hLoginHandle)) { - log.info("大华摄像机登录 ip:{}",camera.getIp()); - NvrInfo nvrInfo = new NvrInfo(); - nvrInfo.setNvrIp(camera.getIp()); - nvrInfo.setServerPort(camera.getPort()); - nvrInfo.setAccount(camera.getUserName()); - nvrInfo.setPassword(camera.getPassword()); - login(nvrInfo); - m_hLoginHandle = new NetSDKLib.LLong((Long) redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle")); - log.info("相机:m_hLoginHandle" + camera.getNvrip() + "m_hLoginHandle" + m_hLoginHandle); +// if (StringUtils.isNotNull(storedObj)) { +// Long storedValue = (Long) storedObj; +// m_hLoginHandle = new NetSDKLib.LLong(storedValue); +// } else { +// //m_hLoginHandle为空 + LLong m_hLoginHandle = null; +// } +// // 3. 安全转换并创建LLong对象 +// if (ObjectUtil.isEmpty(m_hLoginHandle)) { + log.info("大华摄像机登录 ip:{}", camera.getIp()); + NvrInfo nvrInfo = new NvrInfo(); + nvrInfo.setNvrIp(camera.getIp()); + nvrInfo.setServerPort(camera.getPort()); + nvrInfo.setAccount(camera.getUserName()); + nvrInfo.setPassword(camera.getPassword()); + m_hLoginHandle = login(nvrInfo); +// m_hLoginHandle = new NetSDKLib.LLong((Long) redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle")); + if (StringUtils.isNull(m_hLoginHandle)) { + return null; } + log.info("相机:m_hLoginHandle" + camera.getNvrip() + "m_hLoginHandle" + m_hLoginHandle); +// } // 1. 初始化输入结构体 log.info("开始实时测温================================================="); - log.info("cameraip:{},PresetId:{}",camera.getIp(),camera.getPresetId()); + log.info("cameraip:{},PresetId:{}", camera.getIp(), camera.getPresetId()); NetSDKLib.NET_IN_RADIOMETRY_GETTEMPER netIn = new NetSDKLib.NET_IN_RADIOMETRY_GETTEMPER(); // 设置条件参数 netIn.stCondition.nPresetId = camera.getPresetId(); netIn.stCondition.nRuleId = 1; netIn.stCondition.nMeterType = NetSDKLib.NET_RADIOMETRY_METERTYPE.NET_RADIOMETRY_METERTYPE_AREA; - netIn.stCondition.nChannel = camera.getChannel()-1; + netIn.stCondition.nChannel = camera.getChannel() - 1; log.info("[DEBUG] 结构体参数设置完成 - " + @@ -168,24 +176,25 @@ public class DahuaServiceImpl implements DahuaService { netIn.stCondition.nRuleId ); boolean b = dhNetSDK.CLIENT_Logout(m_hLoginHandle); - if (b) { - redisService.redisTemplate.opsForValue().getOperations().delete(camera.getIp() + "_m_hLoginHandle"); - System.out.println("摄像机登出"); - } +// if (b) { +// redisService.redisTemplate.opsForValue().getOperations().delete(camera.getIp() + "_m_hLoginHandle"); + System.out.println("摄像机登出"); +// } return data; } System.out.println("大华-获取设备参数失败,错误码:" + ToolKits.getErrorCodePrint(dhNetSDK.CLIENT_GetLastError())); boolean b = dhNetSDK.CLIENT_Logout(m_hLoginHandle); - if (b) { - redisService.redisTemplate.opsForValue().getOperations().delete(camera.getIp() + "_m_hLoginHandle"); - System.out.println("摄像机登出"); - } +// if (b) { +// redisService.redisTemplate.opsForValue().getOperations().delete(camera.getIp() + "_m_hLoginHandle"); + System.out.println("摄像机登出"); +// } return null; } /** * 大华预置位跳转 + * * @param camera * @param param1 * @param param2 @@ -194,64 +203,74 @@ public class DahuaServiceImpl implements DahuaService { */ @Override public String cameraControl(Camera camera, int param1, int param2, int param3) { - Object storedObj = redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle"); - // 2. 进行空值和类型判断 - if (StringUtils.isNotNull(storedObj)) { - Long storedValue = (Long) storedObj; - m_hLoginHandle = new NetSDKLib.LLong(storedValue); - } else { - //m_hLoginHandle为空 - m_hLoginHandle = null; - } - if (ObjectUtil.isEmpty(m_hLoginHandle)) { - NvrInfo nvrInfo = new NvrInfo(); - nvrInfo.setNvrIp(camera.getIp()); - nvrInfo.setServerPort(camera.getPort()); - nvrInfo.setAccount(camera.getUserName()); - nvrInfo.setPassword(camera.getPassword()); - login(nvrInfo); - m_hLoginHandle = new NetSDKLib.LLong((Long) redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle")); - log.info("相机:m_hLoginHandle" + camera.getIp() + "m_hLoginHandle" + m_hLoginHandle); - } +// Object storedObj = redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle"); +// // 2. 进行空值和类型判断 +// if (StringUtils.isNotNull(storedObj)) { +// Long storedValue = (Long) storedObj; +// m_hLoginHandle = new NetSDKLib.LLong(storedValue); +// } else { +// //m_hLoginHandle为空 + LLong m_hLoginHandle = null; +// } +// if (ObjectUtil.isEmpty(m_hLoginHandle)) { + NvrInfo nvrInfo = new NvrInfo(); + nvrInfo.setNvrIp(camera.getIp()); + nvrInfo.setServerPort(camera.getPort()); + nvrInfo.setAccount(camera.getUserName()); + nvrInfo.setPassword(camera.getPassword()); + m_hLoginHandle = login(nvrInfo); +// m_hLoginHandle = new NetSDKLib.LLong((Long) redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle")); + log.info("相机:m_hLoginHandle" + camera.getIp() + "m_hLoginHandle" + m_hLoginHandle); +// } String ctr = "GOTO_PRESET"; boolean dResult = dhNetSDK.CLIENT_DHPTZControlEx2(m_hLoginHandle, camera.getChannel() - 1, DahuaUtils.PTZCommand(ctr), 0, camera.getPointNum(), 0, 0, null); if (!dResult) { - log.info("CLIENT_DHPTZControlEx Failed!!"+ToolKits.getErrorCodePrint(dhNetSDK.CLIENT_GetLastError())); - return "-1"; + log.info("CLIENT_DHPTZControlEx Failed!!" + ToolKits.getErrorCodePrint(dhNetSDK.CLIENT_GetLastError())); } else { log.info("CLIENT_DHPTZControlEx success"); - return "0"; } + try { + Thread.sleep(delayTime); // 等待2秒后重试 + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + boolean bTemp = dhNetSDK.CLIENT_Logout(m_hLoginHandle); +// if (bTemp) { +// redisService.redisTemplate.opsForValue().getOperations().delete(camera.getIp() + "_m_hLoginHandle"); + log.info("登出成功"); +// } + return "0"; } /** * 大华抓图 + * * @param camera * @return */ @Override public ByteArrayInputStream Picture(Camera camera) { synchronized (captureLock) { - Object storedObj = redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle"); - // 2. 进行空值和类型判断 - if (StringUtils.isNotNull(storedObj)) { - Long storedValue = (Long) storedObj; - m_hLoginHandle = new NetSDKLib.LLong(storedValue); - } else { - //m_hLoginHandle为空 - m_hLoginHandle = null; - } - if (ObjectUtil.isEmpty(m_hLoginHandle)) { - NvrInfo nvrInfo = new NvrInfo(); - nvrInfo.setNvrIp(camera.getIp()); - nvrInfo.setServerPort(camera.getPort()); - nvrInfo.setAccount(camera.getUserName()); - nvrInfo.setPassword(camera.getPassword()); - login(nvrInfo); - m_hLoginHandle = new NetSDKLib.LLong((Long) redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle")); - log.info("相机:m_hLoginHandle" + camera.getIp() + "m_hLoginHandle" + m_hLoginHandle); - } +// Object storedObj = redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle"); +// // 2. 进行空值和类型判断 +// if (StringUtils.isNotNull(storedObj)) { +// Long storedValue = (Long) storedObj; +// m_hLoginHandle = new NetSDKLib.LLong(storedValue); +// } else { +// //m_hLoginHandle为空 + LLong m_hLoginHandle = null; +// } +// if (ObjectUtil.isEmpty(m_hLoginHandle)) { + NvrInfo nvrInfo = new NvrInfo(); + nvrInfo.setNvrIp(camera.getIp()); + nvrInfo.setServerPort(camera.getPort()); + nvrInfo.setAccount(camera.getUserName()); + nvrInfo.setPassword(camera.getPassword()); + m_hLoginHandle = login(nvrInfo); +// m_hLoginHandle = new NetSDKLib.LLong((Long) redisService.redisTemplate.opsForValue().get(camera.getIp() + "_m_hLoginHandle")); + log.info("相机:m_hLoginHandle" + camera.getIp() + "m_hLoginHandle" + m_hLoginHandle); +// } // 2. 准备抓图参数 NetSDKLib.SNAP_PARAMS snapParams = new NetSDKLib.SNAP_PARAMS(); snapParams.Channel = camera.getChannel() - 1; // channel @@ -295,39 +314,40 @@ public class DahuaServiceImpl implements DahuaService { log.error("等待图片回调超时"); return null; } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - log.error("等待图片回调被中断", e); - return null; - } - // 7. 如果获取到图片数据,保存到 D:\pic 目录 - if (imageBytes[0] != null) { - try { - // 确保目录存在 - File picDir = new File("D:\\pic"); - if (!picDir.exists()) { - picDir.mkdirs(); // 如果目录不存在,创建它 - } + // 7. 如果获取到图片数据,保存到 D:\pic 目录 + if (imageBytes[0] != null) { + try { + // 确保目录存在 + File picDir = new File("D:\\pic"); + if (!picDir.exists()) { + picDir.mkdirs(); // 如果目录不存在,创建它 + } - // 生成文件名(例如:camera_ip + timestamp) - String fileName = "D:\\pic\\" + camera.getIp() + "_" + System.currentTimeMillis() + ".jpg"; + // 生成文件名(例如:camera_ip + timestamp) + String fileName = "D:\\pic\\" + camera.getIp() + "_" + System.currentTimeMillis() + ".jpg"; - // 保存图片 - FileOutputStream fos = new FileOutputStream(fileName); - fos.write(imageBytes[0]); - fos.close(); + // 保存图片 + FileOutputStream fos = new FileOutputStream(fileName); + fos.write(imageBytes[0]); + fos.close(); - log.info("图片已保存至: " + fileName); - } catch (IOException e) { - log.error("保存图片失败", e); + log.info("图片已保存至: " + fileName); + } catch (IOException e) { + log.error("保存图片失败", e); + } } - } - boolean bTemp = dhNetSDK.CLIENT_Logout(m_hLoginHandle); - if (bTemp) { - redisService.redisTemplate.opsForValue().getOperations().delete(camera.getIp() + "_m_hLoginHandle"); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + log.error("等待图片回调被中断", e); + return null; + } finally { + boolean bTemp = dhNetSDK.CLIENT_Logout(m_hLoginHandle); +// if (bTemp) { +// redisService.redisTemplate.opsForValue().getOperations().delete(camera.getIp() + "_m_hLoginHandle"); log.info("登出成功"); +// } } - return imageBytes[0] != null ? new ByteArrayInputStream(imageBytes[0]) : null; + return imageBytes[0] != null ? new ByteArrayInputStream(imageBytes[0]) : null; } // 7. 返回结果 } diff --git a/src/main/java/com/inspect/nvr/service/impl/HikVisionServiceImpl.java b/src/main/java/com/inspect/nvr/service/impl/HikVisionServiceImpl.java index eb95cdf..9225a4d 100644 --- a/src/main/java/com/inspect/nvr/service/impl/HikVisionServiceImpl.java +++ b/src/main/java/com/inspect/nvr/service/impl/HikVisionServiceImpl.java @@ -57,10 +57,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; /** * 海康威视测试服务类 @@ -208,6 +205,14 @@ public class HikVisionServiceImpl implements HikVisionService { Arrays.fill(cond.byRes2, (byte) 0); cond.write(); // 手动同步结构体到内存 CompletableFuture temperatureFuture = new CompletableFuture<>(); + // 启动看门狗(4秒超时,比get()的5秒早1秒,预留处理时间) + ScheduledExecutorService watchdog = Executors.newSingleThreadScheduledExecutor(); + watchdog.schedule(() -> { + if (!temperatureFuture.isDone()) { + log.warn("回调线程可能阻塞,看门狗强制标记超时"); + temperatureFuture.completeExceptionally(new TimeoutException("回调线程阻塞超时")); + } + }, 5, TimeUnit.SECONDS); // 3. 启动远程测温 Pointer lpInBuffer = cond.getPointer(); int dwInBufferSize = cond.size(); @@ -258,10 +263,8 @@ public class HikVisionServiceImpl implements HikVisionService { log.error("启动远程测温失败,错误码为:{},错误信息为:{}", errorCode, errorMsg); } temperatureData = temperatureFuture.get(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } catch (ExecutionException e) { - throw new RuntimeException(e); + } catch (Exception e) { + log.error("测温异常报错"); } finally { log.info("关闭实时测温result值 {}", result); //关闭实时测温 diff --git a/src/main/java/com/inspect/nvr/service/impl/IvsCameraServiceImpl.java b/src/main/java/com/inspect/nvr/service/impl/IvsCameraServiceImpl.java index 8d4bf35..b331a9b 100644 --- a/src/main/java/com/inspect/nvr/service/impl/IvsCameraServiceImpl.java +++ b/src/main/java/com/inspect/nvr/service/impl/IvsCameraServiceImpl.java @@ -43,6 +43,15 @@ public class IvsCameraServiceImpl implements IvsCameraService { @Value("${test-mode:false}") private boolean testMode; + @Value("${mode.retryTimes:3}") + private int retryTimes; + + @Value("${mode.delayTime:3000}") + private int delayTime; + + @Value("${mode.retryMode:0}") + private int retryMode; + @Resource private RedisService redisService; @@ -78,11 +87,7 @@ public class IvsCameraServiceImpl implements IvsCameraService { //跳转预置位 @Override public PtzControlResult ptzControl(PtzControlParam param) { - if (testMode) { - return PtzControlResult.builder() - .resultCode("0") - .build(); - } + PtzControlResult ptzControlResult = null; Camera camera = new Camera(); String[] splitArray = param.getAddress().split(":"); //给camera赋值 @@ -102,7 +107,7 @@ public class IvsCameraServiceImpl implements IvsCameraService { camera.setPassword(password); log.info("预置位NVR:" + ip + " channel:" + channel + " pointNum:" + pointNum + " cameraType:" + cameraType); //给camera赋值结束 - PtzControlResult ptzControlResult = ptzDetailControl(camera, cameraType); + ptzDetailControl(camera, cameraType); try { //等待5s开始调用红外 @@ -117,7 +122,16 @@ public class IvsCameraServiceImpl implements IvsCameraService { cameraHw.setUserName(splitArray[10]); cameraHw.setPassword(splitArray[11]); //获取红外温度 - retry(cameraHw,camera, cameraType); + TemperatureData temper = retry(cameraHw, camera, cameraType); + if(retryMode == 1 && StringUtils.isNull(temper)){ + ptzControlResult = PtzControlResult.builder() + .resultCode("-1") + .build(); + } else { + ptzControlResult = PtzControlResult.builder() + .resultCode("0") + .build(); + } } catch (Exception e) { // throw new RuntimeException(e); } @@ -125,15 +139,12 @@ public class IvsCameraServiceImpl implements IvsCameraService { } - public PtzControlResult ptzDetailControl(Camera camera,int cameraType) { + public PtzControlResult ptzDetailControl(Camera camera, int cameraType) { //大华预置位跳转 PtzControlResult ptzControlResult = null; if (ObjectUtil.equals(cameraType, 1)) { log.info("开始登录大华NVR 进行跳转预置位"); - String ajaxResult = dahuaService.cameraControl(camera, 0, 0, 0); - ptzControlResult = PtzControlResult.builder() - .resultCode(ajaxResult) - .build(); + dahuaService.cameraControl(camera, 0, 0, 0); } else { //海康预置位跳转 log.info("开始登录海康NVR 进行跳转预置位"); @@ -152,46 +163,51 @@ public class IvsCameraServiceImpl implements IvsCameraService { boolean gotoPreset = hcNetSDK.NET_DVR_PTZPreset_Other(lUserID, camera.getChannel(), HCNetSDK.GOTO_PRESET, camera.getPointNum()); if (!gotoPreset) { log.error("海康-获取设备预置位跳转设备参数失败,错误码:" + hcNetSDK.NET_DVR_GetLastError()); - return PtzControlResult.builder() - .resultCode("-1") - .build(); } else { log.info("海康-成功跳转到预置位!"); } - ptzControlResult = PtzControlResult.builder() - .resultCode("0") - .build(); + try { + Thread.sleep(delayTime); // 等待2秒后重试 + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } + ptzControlResult = PtzControlResult.builder() + .resultCode("0") + .build(); return ptzControlResult; } + /** * 大华红外读数多次读取 + * * @param camera * @return */ - public TemperatureData retry(Camera camera,Camera nvrCamera,int cameraType){ + public TemperatureData retry(Camera camera, Camera nvrCamera, int cameraType) { + TemperatureData temperatureData = null; //添加重试机制 - final int MAX_RETRIES = 3; // 最大重试次数 + final int MAX_RETRIES = retryTimes; // 最大重试次数 boolean success = false; int retryCount = 0; while (!success && retryCount < MAX_RETRIES) { try { retryCount++; log.info("第{}次尝试读取红外", retryCount); - TemperatureData temperatureData = cameraController.cameraHong(camera); - if(StringUtils.isNull(temperatureData)){ + temperatureData = cameraController.cameraHong(camera); + if (StringUtils.isNull(temperatureData)) { log.warn("第{}次读取红外失败", retryCount); - ptzDetailControl(nvrCamera,cameraType); - Thread.sleep(3000); // 等待2秒后重试 + ptzDetailControl(nvrCamera, cameraType); + } else { success = true; return temperatureData; } } catch (Exception e) { - log.error("第{}次抓图失败: {}", retryCount, e.getMessage()); + log.error("第{}次读取红外失败: {}", retryCount, e.getMessage()); } } - return null; + return temperatureData; } //拍照 @@ -247,7 +263,7 @@ public class IvsCameraServiceImpl implements IvsCameraService { } } String[] cameraAddressInfos = rawString.split((":")); - // 从nvr或者camera下载图片, 开发中 + // 从nvr或者camera下载图片, 开发中暂时只支持从nvr下载图片 Camera camera = new Camera(); //赋值 log.info("DOWNLOAD_FILE ip: {}, port: {}, channel: {}, pointName: {},cameraType: {}, username: {}, password: {}", @@ -284,7 +300,7 @@ public class IvsCameraServiceImpl implements IvsCameraService { lUserID = (Integer) redisService.redisTemplate.opsForValue().get(camera.getIp() + "_userId"); } HCNetSDK.NET_DVR_JPEGPARA dvrJpegpara = new HCNetSDK.NET_DVR_JPEGPARA(); - dvrJpegpara.wPicSize = 3; + dvrJpegpara.wPicSize = 0xff; dvrJpegpara.wPicQuality = 0; dvrJpegpara.write(); @@ -293,38 +309,32 @@ public class IvsCameraServiceImpl implements IvsCameraService { if (!picDir.exists()) { picDir.mkdirs(); // 如果目录不存在,创建它 } - //添加重试机制 - final int MAX_RETRIES = 5; // 最大重试次数 - boolean success = false; - int retryCount = 0; - while (!success && retryCount < MAX_RETRIES) { - try { - retryCount++; - log.info("第{}次尝试抓图", retryCount); - // 生成文件名(例如:camera_ip + timestamp) - String fileName = "D:\\pic\\" + camera.getIp() + "_" + System.currentTimeMillis() + ".jpg"; - Path tempImagePath = Paths.get(fileName); - boolean b = hcNetSDK.NET_DVR_CaptureJPEGPicture(lUserID, camera.getChannel(), dvrJpegpara, - tempImagePath.toString().getBytes("GBK")); - if (!b) { - log.error("设置设备进行抓图失败,错误码:" + hcNetSDK.NET_DVR_GetLastError()); - log.warn("第{}次抓图超时", retryCount); - } else { - //抓图成功 - InputStream inputStream = Files.newInputStream(tempImagePath); - byte[] bytes = StreamUtils.copyToByteArray(inputStream); - log.error("第{}次抓图成功: {}", retryCount); - return new ByteArrayInputStream(bytes); - } - } catch (Exception e) { - log.error("第{}次抓图失败: {}", retryCount, e.getMessage()); + try { + // 生成文件名(例如:camera_ip + timestamp) + String fileName = "D:\\pic\\" + camera.getIp() + "_" + System.currentTimeMillis() + ".jpg"; + Path tempImagePath = Paths.get(fileName); + boolean b = hcNetSDK.NET_DVR_CaptureJPEGPicture(lUserID, camera.getChannel(), dvrJpegpara, + tempImagePath.toString().getBytes("GBK")); + if (!b) { + log.error("设置设备进行抓图失败,错误码:" + hcNetSDK.NET_DVR_GetLastError()); + } else { + //抓图成功 + InputStream inputStream = Files.newInputStream(tempImagePath); + byte[] bytes = StreamUtils.copyToByteArray(inputStream); + return new ByteArrayInputStream(bytes); } + } catch (Exception e) { + log.error(e.getMessage()); + } finally { + log.info("海康抓图登出设备"); + hcNetSDK.NET_DVR_Logout(lUserID); + redisService.redisTemplate.delete(camera.getIp() + "_userId"); } - return null; } - + return null; } + public byte[] loadDefaultImage() throws IOException { ClassPathResource imgFile = new ClassPathResource("images/infrared_default.jpg"); return StreamUtils.copyToByteArray(imgFile.getInputStream()); diff --git a/src/main/java/com/inspect/nvr/utils/StringHexConverter.java b/src/main/java/com/inspect/nvr/utils/StringHexConverter.java index 942b5cb..634b655 100644 --- a/src/main/java/com/inspect/nvr/utils/StringHexConverter.java +++ b/src/main/java/com/inspect/nvr/utils/StringHexConverter.java @@ -30,7 +30,7 @@ public class StringHexConverter { // final String rawString = "3139322e3136382e312e3233313a383030303a31313a3231303a61646d696e3a323031362e682e4244"; // final String hex = fromHex(rawString); // log.info(hex); - String rawString = "192.168.12.48:8000:33:1:0:admin:sshw1234"; + String rawString = "192.168.3.12:37777:2:2:1:admin:admin123:192.168.3.70:37777:2:admin:admin123"; byte[] bytes = rawString.getBytes(StandardCharsets.UTF_8); StringBuilder hex = new StringBuilder(); for (byte b : bytes) { @@ -40,3 +40,4 @@ public class StringHexConverter { log.info(fileSessionId); } } + diff --git a/src/main/java/com/inspect/nvr/utils/sftp/SftpFactory.java b/src/main/java/com/inspect/nvr/utils/sftp/SftpFactory.java index 2848fd0..8c75642 100644 --- a/src/main/java/com/inspect/nvr/utils/sftp/SftpFactory.java +++ b/src/main/java/com/inspect/nvr/utils/sftp/SftpFactory.java @@ -31,7 +31,7 @@ public class SftpFactory { try { this.queue.add(this.connect()); } catch (IOException var2) { - ; + } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index eb4edbd..bae10ea 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -13,3 +13,7 @@ spring: +mode: + retryTimes: 5 + delayTime: 5000 + retryMode: 0 \ No newline at end of file